You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jl...@apache.org on 2022/05/03 12:22:12 UTC

svn commit: r1900504 [20/22] - in /geronimo/specs/trunk: ./ geronimo-activation_2.0_spec/ geronimo-activation_2.0_spec/src/ geronimo-activation_2.0_spec/src/main/ geronimo-activation_2.0_spec/src/main/java/ geronimo-activation_2.0_spec/src/main/java/ja...

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMessageTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMessageTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMessageTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMessageTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,494 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Properties;
+
+import jakarta.activation.CommandMap;
+import jakarta.activation.MailcapCommandMap;
+import jakarta.mail.Address;
+import jakarta.mail.Message;
+import jakarta.mail.MessagingException;
+import jakarta.mail.Session;
+
+import jakarta.mail.*;
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MimeMessageTest extends TestCase {
+    private CommandMap defaultMap;
+    private Session session;
+
+    public void testWriteTo() throws MessagingException, IOException {
+        final MimeMessage msg = new MimeMessage(session);
+        msg.setSender(new InternetAddress("foo"));
+        msg.setHeader("foo", "bar");
+        final MimeMultipart mp = new MimeMultipart();
+        final MimeBodyPart part1 = new MimeBodyPart();
+        part1.setHeader("foo", "bar");
+        part1.setContent("Hello World", "text/plain");
+        mp.addBodyPart(part1);
+        final MimeBodyPart part2 = new MimeBodyPart();
+        part2.setContent("Hello Again", "text/plain");
+        mp.addBodyPart(part2);
+        msg.setContent(mp);
+
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        msg.writeTo(out);
+
+        final InputStream in = new ByteArrayInputStream(out.toByteArray());
+
+        MimeMessage newMessage = new MimeMessage(session, in);
+
+        assertEquals(((InternetAddress)newMessage.getSender()).getAddress(), "foo");
+
+        final String[] headers = newMessage.getHeader("foo");
+        assertTrue(headers.length == 1);
+        assertEquals(headers[0], "bar");
+
+
+        newMessage = new MimeMessage(msg);
+
+        assertEquals(((InternetAddress)newMessage.getSender()).getAddress(), "foo");
+        assertEquals(newMessage.getHeader("foo")[0], "bar");
+    }
+
+
+    public void testFrom() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        final InternetAddress user = new InternetAddress("geronimo-user@apache.org");
+
+        msg.setSender(dev);
+
+        Address[] from = msg.getFrom();
+        assertTrue(from.length == 1);
+        assertEquals(from[0], dev);
+
+        msg.setFrom(user);
+        from = msg.getFrom();
+        assertTrue(from.length == 1);
+        assertEquals(from[0], user);
+
+        msg.addFrom(new Address[] { dev });
+        from = msg.getFrom();
+        assertTrue(from.length == 2);
+        assertEquals(from[0], user);
+        assertEquals(from[1], dev);
+
+        msg.setFrom();
+        final InternetAddress local = InternetAddress.getLocalAddress(session);
+        from = msg.getFrom();
+
+        assertTrue(from.length == 1);
+        assertEquals(local, from[0]);
+
+        msg.setFrom((Address) null);
+        from = msg.getFrom();
+
+        assertTrue(from.length == 1);
+        assertEquals(dev, from[0]);
+
+        msg.setSender(null);
+        from = msg.getFrom();
+        assertNull(from);
+    }
+
+
+    public void testSender() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        final InternetAddress user = new InternetAddress("geronimo-user@apache.org");
+
+        msg.setSender(dev);
+
+        final Address[] from = msg.getFrom();
+        assertTrue(from.length == 1);
+        assertEquals(from[0], dev);
+
+        assertEquals(msg.getSender(), dev);
+
+        msg.setSender(null);
+        assertNull(msg.getSender());
+    }
+    
+    public void testJavaMail15GetSession() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+        assertTrue(session == msg.getSession());
+        
+        final MimeMessage msg2 = new MimeMessage((Session) null);
+        assertTrue(null == msg2.getSession());
+    }
+    
+    public void testJava15From() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+        
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        final InternetAddress user = new InternetAddress("geronimo-user@apache.org");
+
+        
+        msg.setFrom("geronimo-dev@apache.org,geronimo-user@apache.org");
+
+        Address[] from = msg.getFrom();
+        assertTrue(from.length == 2);
+        assertEquals(from[0], dev);
+        assertEquals(from[1], user);
+        
+        msg.setFrom("test@apache.org");
+        
+        from = msg.getFrom();
+        assertTrue(from.length == 1);
+        assertEquals(from[0], new InternetAddress("test@apache.org"));
+    }
+
+    public void testGetAllRecipients() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        final InternetAddress user = new InternetAddress("geronimo-user@apache.org");
+        final InternetAddress user1 = new InternetAddress("geronimo-user1@apache.org");
+        final InternetAddress user2 = new InternetAddress("geronimo-user2@apache.org");
+        final NewsAddress group = new NewsAddress("comp.lang.rexx");
+
+        Address[] recipients = msg.getAllRecipients();
+        assertNull(recipients);
+
+        msg.setRecipients(Message.RecipientType.TO, new Address[] { dev });
+
+        recipients = msg.getAllRecipients();
+        assertTrue(recipients.length == 1);
+        assertEquals(recipients[0], dev);
+
+        msg.addRecipients(Message.RecipientType.BCC, new Address[] { user });
+
+        recipients = msg.getAllRecipients();
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+
+        msg.addRecipients(Message.RecipientType.CC, new Address[] { user1, user2} );
+
+        recipients = msg.getAllRecipients();
+        assertTrue(recipients.length == 4);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user1);
+        assertEquals(recipients[2], user2);
+        assertEquals(recipients[3], user);
+
+
+        msg.addRecipients(MimeMessage.RecipientType.NEWSGROUPS, new Address[] { group } );
+
+        recipients = msg.getAllRecipients();
+        assertTrue(recipients.length == 5);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user1);
+        assertEquals(recipients[2], user2);
+        assertEquals(recipients[3], user);
+        assertEquals(recipients[4], group);
+
+        msg.setRecipients(Message.RecipientType.CC, (String)null);
+
+        recipients = msg.getAllRecipients();
+
+        assertTrue(recipients.length == 3);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+        assertEquals(recipients[2], group);
+    }
+
+    public void testGetRecipients() throws MessagingException {
+        doRecipientTest(Message.RecipientType.TO);
+        doRecipientTest(Message.RecipientType.CC);
+        doRecipientTest(Message.RecipientType.BCC);
+        doNewsgroupRecipientTest(MimeMessage.RecipientType.NEWSGROUPS);
+    }
+
+    private void doRecipientTest(final Message.RecipientType type) throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        final InternetAddress user = new InternetAddress("geronimo-user@apache.org");
+
+        Address[] recipients = msg.getRecipients(type);
+        assertNull(recipients);
+
+        msg.setRecipients(type, "geronimo-dev@apache.org");
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 1);
+        assertEquals(recipients[0], dev);
+
+        msg.addRecipients(type, "geronimo-user@apache.org");
+
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+
+        msg.setRecipients(type, (String)null);
+
+        recipients = msg.getRecipients(type);
+        assertNull(recipients);
+
+        msg.setRecipients(type, new Address[] { dev });
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 1);
+        assertEquals(recipients[0], dev);
+
+        msg.addRecipients(type, new Address[] { user });
+
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+
+        msg.setRecipients(type, (Address[])null);
+
+        recipients = msg.getRecipients(type);
+        assertNull(recipients);
+
+        msg.setRecipients(type, new Address[] { dev, user });
+
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+    }
+
+
+    private void doNewsgroupRecipientTest(final Message.RecipientType type) throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final Address dev = new NewsAddress("geronimo-dev");
+        final Address user = new NewsAddress("geronimo-user");
+
+        Address[] recipients = msg.getRecipients(type);
+        assertNull(recipients);
+
+        msg.setRecipients(type, "geronimo-dev");
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 1);
+        assertEquals(recipients[0], dev);
+
+        msg.addRecipients(type, "geronimo-user");
+
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+
+        msg.setRecipients(type, (String)null);
+
+        recipients = msg.getRecipients(type);
+        assertNull(recipients);
+
+        msg.setRecipients(type, new Address[] { dev });
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 1);
+        assertEquals(recipients[0], dev);
+
+        msg.addRecipients(type, new Address[] { user });
+
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+
+        msg.setRecipients(type, (Address[])null);
+
+        recipients = msg.getRecipients(type);
+        assertNull(recipients);
+
+        msg.setRecipients(type, new Address[] { dev, user });
+
+        recipients = msg.getRecipients(type);
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+    }
+
+    public void testReplyTo() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        final InternetAddress user = new InternetAddress("geronimo-user@apache.org");
+
+        msg.setReplyTo(new Address[] { dev });
+
+        Address[] recipients = msg.getReplyTo();
+        assertTrue(recipients.length == 1);
+        assertEquals(recipients[0], dev);
+
+        msg.setReplyTo(new Address[] { dev, user });
+
+        recipients = msg.getReplyTo();
+        assertTrue(recipients.length == 2);
+        assertEquals(recipients[0], dev);
+        assertEquals(recipients[1], user);
+
+        msg.setReplyTo(null);
+
+        recipients = msg.getReplyTo();
+        assertNull(recipients);
+    }
+    
+    public void testJavaMail15Reply() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        
+        msg.setFrom("test@apache.org");
+        msg.setRecipient(Message.RecipientType.TO, dev);
+
+        final Message replyMsg = msg.reply(true, true);
+        assertNotNull(replyMsg);
+        assertTrue(msg.isSet(Flags.Flag.ANSWERED));
+        assertEquals(new InternetAddress("test@apache.org"), replyMsg.getRecipients(Message.RecipientType.TO)[0]);
+    }
+    
+    public void testJavaMail15Reply2() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+        final InternetAddress dev = new InternetAddress("geronimo-dev@apache.org");
+        
+        msg.setFrom("test@apache.org");
+        msg.setRecipient(Message.RecipientType.TO, dev);
+
+        final Message replyMsg = msg.reply(false, false);
+        assertNotNull(replyMsg);
+        assertFalse(msg.isSet(Flags.Flag.ANSWERED));
+        assertEquals(new InternetAddress("test@apache.org"), replyMsg.getRecipients(Message.RecipientType.TO)[0]);
+    }
+
+
+    public void testSetSubject() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final String simpleSubject = "Yada, yada";
+
+        final String complexSubject = "Yada, yada\u0081";
+
+        final String mungedSubject = "Yada, yada\u003F";
+
+        msg.setSubject(simpleSubject);
+        assertEquals(msg.getSubject(), simpleSubject);
+
+        msg.setSubject(complexSubject, "UTF-8");
+        assertEquals(msg.getSubject(), complexSubject);
+
+        msg.setSubject(null);
+        assertNull(msg.getSubject());
+    }
+
+
+    public void testSetDescription() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+
+        final String simpleSubject = "Yada, yada";
+
+        final String complexSubject = "Yada, yada\u0081";
+
+        final String mungedSubject = "Yada, yada\u003F";
+
+        msg.setDescription(simpleSubject);
+        assertEquals(msg.getDescription(), simpleSubject);
+
+        msg.setDescription(complexSubject, "UTF-8");
+        assertEquals(msg.getDescription(), complexSubject);
+
+        msg.setDescription(null);
+        assertNull(msg.getDescription());
+    }
+
+
+    public void testGetContentType() throws MessagingException {
+        final MimeMessage msg = new MimeMessage(session);
+        assertEquals(msg.getContentType(), "text/plain");
+
+        msg.setHeader("Content-Type", "text/xml");
+        assertEquals(msg.getContentType(), "text/xml");
+    }
+
+
+    public void testSetText() throws MessagingException {
+        MimeMessage msg = new MimeMessage(session);
+
+        msg.setText("Yada, yada");
+        msg.saveChanges();
+        ContentType type = new ContentType(msg.getContentType());
+        assertTrue(type.match("text/plain"));
+
+        msg = new MimeMessage(session);
+        msg.setText("Yada, yada", "UTF-8");
+        msg.saveChanges();
+        type = new ContentType(msg.getContentType());
+        assertTrue(type.match("text/plain"));
+        assertEquals(type.getParameter("charset"), "UTF-8");
+
+        msg = new MimeMessage(session);
+        msg.setText("Yada, yada", "UTF-8", "xml");
+        msg.saveChanges();
+        type = new ContentType(msg.getContentType());
+        assertTrue(type.match("text/xml"));
+        assertEquals(type.getParameter("charset"), "UTF-8");
+    }
+
+    public void testAddDateinUpdateHeaders() throws MessagingException, ParseException {
+        final MimeMessage msg = new MimeMessage(session);
+        msg.updateHeaders();
+
+        final String[] dateHeader = msg.getHeader("Date");
+        assertNotNull(dateHeader);
+        assertEquals(1, dateHeader.length);
+
+        final Date date = new MailDateFormat().parse(dateHeader[0]);
+        final Date now = new Date();
+
+        // this should be within 5 seconds
+        assertTrue((now.getTime() - date.getTime()) < 5000);
+    }
+
+
+    @Override
+    protected void setUp() throws Exception {
+        defaultMap = CommandMap.getDefaultCommandMap();
+        final MailcapCommandMap myMap = new MailcapCommandMap();
+        myMap.addMailcap("text/plain;;    x-java-content-handler=" + MimeMultipartTest.DummyTextHandler.class.getName());
+        myMap.addMailcap("multipart/*;;    x-java-content-handler=" + MimeMultipartTest.DummyMultipartHandler.class.getName());
+        CommandMap.setDefaultCommandMap(myMap);
+        final Properties props = new Properties();
+        props.put("mail.user", "tester");
+        props.put("mail.host", "apache.org");
+
+        session = Session.getInstance(props);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        CommandMap.setDefaultCommandMap(defaultMap);
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMultipartTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMultipartTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMultipartTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeMultipartTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Properties;
+
+import jakarta.activation.*;
+import jakarta.mail.BodyPart;
+import jakarta.mail.Message;
+import jakarta.mail.MessagingException;
+import jakarta.mail.Session;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MimeMultipartTest extends TestCase {
+    private CommandMap defaultMap;
+
+    public void testWriteTo() throws MessagingException, IOException, Exception {
+        writeToSetUp();
+
+        final MimeMultipart mp = new MimeMultipart();
+        final MimeBodyPart part1 = new MimeBodyPart();
+        part1.setHeader("foo", "bar");
+        part1.setContent("Hello World", "text/plain");
+        mp.addBodyPart(part1);
+        final MimeBodyPart part2 = new MimeBodyPart();
+        part2.setContent("Hello Again", "text/plain");
+        mp.addBodyPart(part2);
+        //mp.writeTo(System.out);
+
+        writeToTearDown();
+    }
+
+    public void testPreamble() throws MessagingException, IOException {
+        final Properties props = new Properties();
+        final Session session = Session.getDefaultInstance(props);
+        session.setDebug(true);
+        final MimeMessage message = new MimeMessage(session);
+        message.setFrom(new InternetAddress("rickmcg@gmail.com"));
+        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("rick@us.ibm.com"));
+        message.setSubject("test subject");
+
+        final BodyPart messageBodyPart1 = new MimeBodyPart();
+        messageBodyPart1.setHeader("Content-Type", "text/xml");
+        messageBodyPart1.setHeader("Content-Transfer-Encoding", "binary");
+        messageBodyPart1.setText("This is a test");
+
+        final MimeMultipart multipart = new MimeMultipart();
+        multipart.addBodyPart(messageBodyPart1);
+        multipart.setPreamble("This is a preamble");
+
+        assertEquals("This is a preamble", multipart.getPreamble());
+
+        message.setContent(multipart);
+
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        message.writeTo(out);
+        //out.writeTo(System.out);
+
+        final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+
+        final MimeMessage newMessage = new MimeMessage(session, in);
+        assertEquals("This is a preamble\r\n", ((MimeMultipart)newMessage.getContent()).getPreamble());
+    }
+
+    public void testMIMEWriting() throws IOException, MessagingException {
+        final File basedir = new File(System.getProperty("basedir", "."));
+        final File testInput = new File(basedir, "src/test/resources/wmtom.bin");
+        final FileInputStream inStream = new FileInputStream(testInput);
+        final Properties props = new Properties();
+        final Session session = Session
+                .getInstance(props, null);
+        final MimeMessage mimeMessage = new MimeMessage(session, inStream);
+        final DataHandler dh = mimeMessage.getDataHandler();
+        final MimeMultipart multiPart = new MimeMultipart(dh.getDataSource());
+        final MimeBodyPart mimeBodyPart0 = (MimeBodyPart) multiPart.getBodyPart(0);
+        final Object object0 = mimeBodyPart0.getContent();
+        assertNotNull(object0);
+        final MimeBodyPart mimeBodyPart1 = (MimeBodyPart) multiPart.getBodyPart(1);
+        final Object object1 = mimeBodyPart1.getContent();
+        assertNotNull(object1);
+        assertEquals(multiPart.getCount(), 2);
+    }
+    
+    public void testJavaMail15NewConstrucor() throws IOException, MessagingException {
+        final File basedir = new File(System.getProperty("basedir", "."));
+        final File testInput = new File(basedir, "src/test/resources/wmtom.bin");
+        final BodyPart[] bps = new BodyPart[2]; 
+        bps[0] = new MimeBodyPart(new FileInputStream(testInput));
+        bps[1] = new MimeBodyPart(new FileInputStream(testInput));
+        final MimeMultipart multiPart = new MimeMultipart(bps);
+        final MimeBodyPart mimeBodyPart0 = (MimeBodyPart) multiPart.getBodyPart(0);
+        final Object object0 = mimeBodyPart0.getContent();
+        assertNotNull(object0);
+        final MimeBodyPart mimeBodyPart1 = (MimeBodyPart) multiPart.getBodyPart(1);
+        final Object object1 = mimeBodyPart1.getContent();
+        assertNotNull(object1);
+        assertEquals(multiPart.getCount(), 2);
+        assertTrue(multiPart.getContentType().startsWith("multipart/mixed"));
+    }
+    
+    public void testJavaMail15NewConstrucor2() throws IOException, MessagingException {
+        final File basedir = new File(System.getProperty("basedir", "."));
+        final File testInput = new File(basedir, "src/test/resources/wmtom.bin");
+        final BodyPart[] bps = new BodyPart[2]; 
+        bps[0] = new MimeBodyPart(new FileInputStream(testInput));
+        bps[1] = new MimeBodyPart(new FileInputStream(testInput));
+        final MimeMultipart multiPart = new MimeMultipart("alternative",bps);
+        final MimeBodyPart mimeBodyPart0 = (MimeBodyPart) multiPart.getBodyPart(0);
+        final Object object0 = mimeBodyPart0.getContent();
+        assertNotNull(object0);
+        final MimeBodyPart mimeBodyPart1 = (MimeBodyPart) multiPart.getBodyPart(1);
+        final Object object1 = mimeBodyPart1.getContent();
+        assertNotNull(object1);
+        assertEquals(multiPart.getCount(), 2);
+        assertTrue(multiPart.getContentType().startsWith("multipart/alternative"));
+    }
+    
+    public void testJavaMail15CachedContent() throws IOException, MessagingException {
+    	final File basedir = new File(System.getProperty("basedir", "."));
+    	final InputStream source = new FileInputStream(new File(basedir, "src/test/resources/multipart_msg_normal.eml"));
+    	final MimeMessage message = new MimeMessage(null, source);
+		message.saveChanges();
+		assertEquals("Sample message", message.getSubject());	
+		assertTrue(message.getContent() instanceof MimeMultipart);
+		assertNotNull(message.cachedContent);
+		final MimeMultipart mmp = (MimeMultipart) message.getContent();
+		assertTrue(message.cachedContent == mmp);
+		final MimeBodyPart bp = (MimeBodyPart) mmp.getBodyPart(0);
+		final String c = (String) bp.getContent();
+		assertNotNull(c);
+		assertNull(bp.cachedContent);
+		message.setDataHandler(new DataHandler("","text/plain"));
+		assertNull(message.cachedContent);
+    }
+    
+    public void testJavaMail15MultipartParsingNormal() throws IOException, MessagingException {
+    	try {
+			setMultipartSystemPropsToDefault();
+			checkMultipartParsing("multipart_msg_normal.eml", 2);
+			setMultipartSystemProps(false, false, true, true);
+			checkMultipartParsing("multipart_msg_normal.eml", 2);
+		} finally{
+			setMultipartSystemPropsToDefault();
+		}
+		
+    }
+    
+    public void testJavaMail15MultipartParsingEmpty() throws IOException, MessagingException {
+    	
+    	/*
+    	 *  When writing out such a MimeMultipart, a single empty part will be
+  		 *	included.  When reading such a multipart, a MimeMultipart will be created
+  		 *	with no body parts.
+    	 */
+    	
+    	try {
+	    	setMultipartSystemPropsToDefault();
+	    	checkMultipartParsing("multipart_msg_empty.eml",-1); //-1 indicates expected exception
+	    	MimeMultipart mmp0 = new MimeMultipart();
+	    	ByteArrayOutputStream out = new ByteArrayOutputStream();
+	    	try {
+				mmp0.writeTo(out);
+				fail("MessagingException excpected");
+			} catch (final MessagingException e) {
+				//expected
+			}
+	    	
+	    	setMultipartSystemProps(false, false, true, true);
+	    	
+	    	mmp0 = new MimeMultipart();
+	    	out = new ByteArrayOutputStream();
+			mmp0.writeTo(out);
+			assertTrue(out.toString().startsWith("--"));
+	    	
+	    	final MimeMultipart mmp = checkMultipartParsing("multipart_msg_empty.eml",0);
+	    	out = new ByteArrayOutputStream();
+	    	mmp.writeTo(out);
+	    	assertTrue(out.toString().startsWith("--simple"));
+	    	
+    	} finally{
+			setMultipartSystemPropsToDefault();
+		}
+    }
+    
+    public void testJavaMail1MultipartParsingMissingBoundaryParameter() throws IOException, MessagingException {
+    	try {
+	    	setMultipartSystemPropsToDefault();
+	    	checkMultipartParsing("multipart_msg_missing_boundary_param.eml",2);
+	    	setMultipartSystemProps(false, false, false, true);
+	    	checkMultipartParsing("multipart_msg_missing_boundary_param.eml",-1);
+    	} finally{
+			setMultipartSystemPropsToDefault();
+		}
+    }
+    
+    public void testJavaMail1MultipartParsingMissingEndBoundary() throws IOException, MessagingException {
+    	try {
+	    	setMultipartSystemPropsToDefault();
+	    	setMultipartSystemProps(true, false, false, false);
+	    	checkMultipartParsing("multipart_msg_missing_end_boundary.eml",1);
+	    	setMultipartSystemProps(false, false, false, false);
+	    	checkMultipartParsing("multipart_msg_missing_end_boundary.eml",-1);
+    	} finally{
+			setMultipartSystemPropsToDefault();
+		}
+    }
+    
+    public void testJavaMail15MultipartParsingWrongBoundary() throws IOException, MessagingException {
+    	try {
+	    	setMultipartSystemPropsToDefault();
+	    	checkMultipartParsing("multipart_msg_wrong_boundary_param.eml",-1);
+	    	setMultipartSystemProps(false, false, true, true);
+	    	checkMultipartParsing("multipart_msg_wrong_boundary_param.eml",2);
+    	} finally{
+			setMultipartSystemPropsToDefault();
+		}
+    }
+    
+    protected void setMultipartSystemPropsToDefault() {
+    	setMultipartSystemProps(true, true, false, false);
+    }
+    
+    protected void setMultipartSystemProps(final boolean ignoremissingendboundary, final boolean ignoremissingboundaryparameter, final boolean ignoreexistingboundaryparameter, final boolean allowempty) {
+    	System.setProperty("mail.mime.multipart.ignoremissingendboundary", String.valueOf(ignoremissingendboundary));
+    	System.setProperty("mail.mime.multipart.ignoremissingboundaryparameter", String.valueOf(ignoremissingboundaryparameter));
+    	System.setProperty("mail.mime.multipart.ignoreexistingboundaryparameter", String.valueOf(ignoreexistingboundaryparameter));
+    	System.setProperty("mail.mime.multipart.allowempty", String.valueOf(allowempty));
+    }
+    
+    protected MimeMultipart checkMultipartParsing(final String filename, final int count) throws IOException, MessagingException {
+    	final File basedir = new File(System.getProperty("basedir", "."));
+    	final InputStream source = new FileInputStream(new File(basedir, "src/test/resources/"+filename));
+    	final MimeMessage message = new MimeMessage(null, source);
+    	try {
+			//message.saveChanges();
+			assertTrue(message.getContent() instanceof MimeMultipart);
+			final MimeMultipart mmp = (MimeMultipart) message.getContent();
+			assertEquals(count, mmp.getCount());
+			return mmp;
+		} catch (final MessagingException e) {
+			if(count > -1) {
+				fail(e.toString());
+			}
+		}
+    	
+    	return null;
+    }
+
+    protected void writeToSetUp() throws Exception {
+        defaultMap = CommandMap.getDefaultCommandMap();
+        final MailcapCommandMap myMap = new MailcapCommandMap();
+        myMap.addMailcap("text/plain;;    x-java-content-handler=" + DummyTextHandler.class.getName());
+        myMap.addMailcap("multipart/*;;    x-java-content-handler=" + DummyMultipartHandler.class.getName());
+        CommandMap.setDefaultCommandMap(myMap);
+    }
+
+    protected void writeToTearDown() throws Exception {
+        CommandMap.setDefaultCommandMap(defaultMap);
+    }
+
+    public static class DummyTextHandler implements DataContentHandler {
+        public ActivationDataFlavor[] getTransferDataFlavors() {
+            return new ActivationDataFlavor[0];  //To change body of implemented methods use File | Settings | File Templates.
+        }
+
+        public Object getTransferData(final ActivationDataFlavor df, final DataSource ds) throws IOException {
+            return null;  //To change body of implemented methods use File | Settings | File Templates.
+        }
+
+        public Object getContent(final DataSource ds) throws IOException {
+            return null;  //To change body of implemented methods use File | Settings | File Templates.
+        }
+
+        public void writeTo(final Object obj, final String mimeType, final OutputStream os) throws IOException {
+            os.write(((String)obj).getBytes("ISO8859-1"));
+        }
+    }
+
+    public static class DummyMultipartHandler implements DataContentHandler {
+        public ActivationDataFlavor[] getTransferDataFlavors() {
+            throw new UnsupportedOperationException();
+        }
+
+        public Object getTransferData(final ActivationDataFlavor df, final DataSource ds) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public Object getContent(final DataSource ds) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public void writeTo(final Object obj, final String mimeType, final OutputStream os) throws IOException {
+            final MimeMultipart mp = (MimeMultipart) obj;
+            try {
+                mp.writeTo(os);
+            } catch (final MessagingException e) {
+                throw (IOException) new IOException(e.getMessage()).initCause(e);
+            }
+        }
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Properties;
+
+import jakarta.activation.DataHandler;
+import jakarta.activation.DataSource;
+import jakarta.mail.Session;
+
+import junit.framework.TestCase;
+
+import org.apache.geronimo.mail.util.Base64;
+
+public class MimeTest extends TestCase {
+
+    public void testWriteRead() throws Exception {
+        System.setProperty("mail.mime.decodefilename", "true");
+
+        final Session session = Session.getDefaultInstance(new Properties(), null);
+        final MimeMessage mime = new MimeMessage(session);
+        final MimeMultipart parts = new MimeMultipart("related; type=\"text/xml\"; start=\"<xml>\"");
+        final MimeBodyPart xmlPart = new MimeBodyPart();
+        xmlPart.setContentID("<xml>");
+        xmlPart.setDataHandler(new DataHandler(new ByteArrayDataSource("<hello/>".getBytes(), "text/xml")));
+        parts.addBodyPart(xmlPart);
+        final MimeBodyPart jpegPart = new MimeBodyPart();
+        jpegPart.setContentID("<jpeg>");
+        final String filename = "filename";
+        final String encodedFilename = "=?UTF-8?B?" + new String(Base64.encode(filename.getBytes()), "ISO8859-1") + "?=";
+        jpegPart.setFileName(encodedFilename);
+        jpegPart.setDataHandler(new DataHandler(new ByteArrayDataSource(new byte[] { 0, 1, 2, 3, 4, 5 }, "image/jpeg")));
+        parts.addBodyPart(jpegPart);
+        mime.setContent(parts);
+        mime.setHeader("Content-Type", parts.getContentType());
+
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        mime.writeTo(baos);
+
+        final MimeMessage mime2 = new MimeMessage(session, new ByteArrayInputStream(baos.toByteArray()));
+        assertTrue(mime2.getContent() instanceof MimeMultipart);
+        final MimeMultipart parts2 = (MimeMultipart) mime2.getContent();
+        assertEquals(mime.getContentType(), mime2.getContentType());
+        assertEquals(parts.getCount(), parts2.getCount());
+        assertTrue(parts2.getBodyPart(0) instanceof MimeBodyPart);
+        assertTrue(parts2.getBodyPart(1) instanceof MimeBodyPart);
+
+        final MimeBodyPart xmlPart2 = (MimeBodyPart) parts2.getBodyPart(0);
+        assertEquals(xmlPart.getContentID(), xmlPart2.getContentID());
+        final ByteArrayOutputStream xmlBaos = new ByteArrayOutputStream();
+        copyInputStream(xmlPart.getDataHandler().getInputStream(), xmlBaos);
+        final ByteArrayOutputStream xmlBaos2 = new ByteArrayOutputStream();
+        copyInputStream(xmlPart2.getDataHandler().getInputStream(), xmlBaos2);
+        assertEquals(xmlBaos.toString(), xmlBaos2.toString());
+
+        final MimeBodyPart jpegPart2 = (MimeBodyPart) parts2.getBodyPart(1);
+        assertEquals(jpegPart.getContentID(), jpegPart2.getContentID());
+        assertEquals(jpegPart.getFileName(), jpegPart2.getDataHandler().getName());
+        assertEquals(filename, jpegPart2.getDataHandler().getName());
+        final ByteArrayOutputStream jpegBaos = new ByteArrayOutputStream();
+        copyInputStream(jpegPart.getDataHandler().getInputStream(), jpegBaos);
+        final ByteArrayOutputStream jpegBaos2 = new ByteArrayOutputStream();
+        copyInputStream(jpegPart2.getDataHandler().getInputStream(), jpegBaos2);
+        assertEquals(jpegBaos.toString(), jpegBaos2.toString());
+    }
+
+    public static class ByteArrayDataSource implements DataSource {
+        private final byte[] data;
+        private final String type;
+        private String name = "unused";
+
+        public ByteArrayDataSource(final byte[] data, final String type) {
+            this.data = data;
+            this.type = type;
+        }
+
+        public InputStream getInputStream() throws IOException {
+            if (data == null) {
+				throw new IOException("no data");
+			}
+            return new ByteArrayInputStream(data);
+        }
+
+        public OutputStream getOutputStream() throws IOException {
+            throw new IOException("getOutputStream() not supported");
+        }
+
+        public String getContentType() {
+            return type;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(final String name) {
+            this.name = name;
+        }
+    }
+
+    public static void copyInputStream(final InputStream in, final OutputStream out) throws IOException {
+        final byte[] buffer = new byte[1024];
+        int len;
+        while ((len = in.read(buffer)) >= 0) {
+            out.write(buffer, 0, len);
+        }
+        in.close();
+        out.close();
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeUtilityTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeUtilityTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeUtilityTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/MimeUtilityTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import jakarta.mail.util.ByteArrayDataSource;
+
+import junit.framework.TestCase;
+
+public class MimeUtilityTest extends TestCase {
+
+    private final byte[] encodeBytes = new byte[] { 32, 104, -61, -87, 33, 32, -61, -96, -61, -88, -61, -76, 117, 32, 33, 33, 33 };
+
+    public void testEncodeDecode() throws Exception {
+
+        final byte [] data = new byte[256];
+        for (int i = 0; i < data.length; i++) {
+            data[i] = (byte)i;
+        }
+
+        // different lengths test boundary conditions
+        doEncodingTest(data, 256, "uuencode");
+        doEncodingTest(data, 255, "uuencode");
+        doEncodingTest(data, 254, "uuencode");
+
+        doEncodingTest(data, 256, "binary");
+        doEncodingTest(data, 256, "7bit");
+        doEncodingTest(data, 256, "8bit");
+        doEncodingTest(data, 256, "base64");
+        doEncodingTest(data, 255, "base64");
+        doEncodingTest(data, 254, "base64");
+
+        doEncodingTest(data, 256, "x-uuencode");
+        doEncodingTest(data, 256, "x-uue");
+        doEncodingTest(data, 256, "quoted-printable");
+        doEncodingTest(data, 255, "quoted-printable");
+        doEncodingTest(data, 254, "quoted-printable");
+    }
+
+
+    public void testFoldUnfold() throws Exception {
+        doFoldTest(0, "This is a short string", "This is a short string");
+        doFoldTest(0, "The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog.",
+            "The quick brown fox jumped over the lazy dog. The quick brown fox jumped\r\n over the lazy dog. The quick brown fox jumped over the lazy dog.");
+        doFoldTest(50, "The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog.",
+            "The quick brown fox jumped\r\n over the lazy dog. The quick brown fox jumped over the lazy dog. The quick\r\n brown fox jumped over the lazy dog.");
+        doFoldTest(20, "======================================================================================================================= break should be here",
+            "=======================================================================================================================\r\n break should be here");
+    }
+
+
+    public void doEncodingTest(final byte[] data, final int length, final String encoding) throws Exception {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final OutputStream encoder = MimeUtility.encode(out, encoding);
+
+        encoder.write(data, 0, length);
+        encoder.flush();
+
+        final byte[] encodedData = out.toByteArray();
+
+        final ByteArrayInputStream in = new ByteArrayInputStream(encodedData);
+
+        final InputStream decoder = MimeUtility.decode(in, encoding);
+
+        final byte[] decodedData = new byte[length];
+
+        final int count = decoder.read(decodedData);
+
+        assertEquals(length, count);
+
+        for (int i = 0; i < length; i++) {
+            assertEquals(data[i], decodedData[i]);
+        }
+    }
+
+
+    public void doFoldTest(final int used, final String source, final String folded) throws Exception {
+        final String newFolded = MimeUtility.fold(used, source);
+        final String newUnfolded = MimeUtility.unfold(newFolded);
+
+        assertEquals(folded, newFolded);
+        assertEquals(source, newUnfolded);
+    }
+
+
+    public void testEncodeWord() throws Exception {
+        assertEquals("abc", MimeUtility.encodeWord("abc"));
+
+        final String encodeString = new String(encodeBytes, "UTF-8");
+        // default code page dependent, hard to directly test the encoded results
+        // The following disabled because it will not succeed on all locales because the
+        // code points used in the test string won't round trip properly for all code pages.
+        // assertEquals(encodeString, MimeUtility.decodeWord(MimeUtility.encodeWord(encodeString)));
+
+        String encoded = MimeUtility.encodeWord(encodeString, "UTF-8", "Q");
+        assertEquals("=?UTF-8?Q?_h=C3=A9!_=C3=A0=C3=A8=C3=B4u_!!!?=", encoded);
+        assertEquals(encodeString, MimeUtility.decodeWord(encoded));
+
+        encoded = MimeUtility.encodeWord(encodeString, "UTF-8", "B");
+        assertEquals("=?UTF-8?B?IGjDqSEgw6DDqMO0dSAhISE=?=", encoded);
+        assertEquals(encodeString, MimeUtility.decodeWord(encoded));
+    }
+
+
+    public void testEncodeText() throws Exception {
+        assertEquals("abc", MimeUtility.encodeWord("abc"));
+
+        final String encodeString = new String(encodeBytes, "UTF-8");
+        // default code page dependent, hard to directly test the encoded results
+        // The following disabled because it will not succeed on all locales because the
+        // code points used in the test string won't round trip properly for all code pages.
+        // assertEquals(encodeString, MimeUtility.decodeText(MimeUtility.encodeText(encodeString)));
+
+        String encoded = MimeUtility.encodeText(encodeString, "UTF-8", "Q");
+        assertEquals("=?UTF-8?Q?_h=C3=A9!_=C3=A0=C3=A8=C3=B4u_!!!?=", encoded);
+        assertEquals(encodeString, MimeUtility.decodeText(encoded));
+
+        encoded = MimeUtility.encodeText(encodeString, "UTF-8", "B");
+        assertEquals("=?UTF-8?B?IGjDqSEgw6DDqMO0dSAhISE=?=", encoded);
+        assertEquals(encodeString, MimeUtility.decodeText(encoded));
+        
+        // this has multiple byte characters and is longer than the 76 character grouping, so this 
+        // hits a lot of different boundary conditions 
+        final String subject = "\u03a0\u03a1\u03a2\u03a3\u03a4\u03a5\u03a6\u03a7 \u03a8\u03a9\u03aa\u03ab \u03ac\u03ad\u03ae\u03af\u03b0 \u03b1\u03b2\u03b3\u03b4\u03b5 \u03b6\u03b7\u03b8\u03b9\u03ba \u03bb\u03bc\u03bd\u03be\u03bf\u03c0 \u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7 \u03c8\u03c9\u03ca\u03cb\u03cd\u03ce \u03cf\u03d0\u03d1\u03d2";
+        encoded = MimeUtility.encodeText(subject, "utf-8", "Q"); 
+        assertEquals(subject, MimeUtility.decodeText(encoded));
+        
+        encoded = MimeUtility.encodeText(subject, "utf-8", "B"); 
+        assertEquals(subject, MimeUtility.decodeText(encoded));
+    }
+
+
+    public void testGetEncoding() throws Exception {
+        ByteArrayDataSource source = new ByteArrayDataSource(new byte[] { 'a', 'b', 'c'}, "text/plain");
+
+        assertEquals("7bit", MimeUtility.getEncoding(source));
+
+        source = new ByteArrayDataSource(new byte[] { 'a', 'b', (byte)0x81}, "text/plain");
+
+        assertEquals("quoted-printable", MimeUtility.getEncoding(source));
+
+        source = new ByteArrayDataSource(new byte[] { 'a', (byte)0x82, (byte)0x81}, "text/plain");
+
+        assertEquals("base64", MimeUtility.getEncoding(source));
+
+
+        source = new ByteArrayDataSource(new byte[] { 'a', 'b', 'c'}, "application/binary");
+
+        assertEquals("7bit", MimeUtility.getEncoding(source));
+
+        source = new ByteArrayDataSource(new byte[] { 'a', 'b', (byte)0x81}, "application/binary");
+
+        assertEquals("base64", MimeUtility.getEncoding(source));
+
+        source = new ByteArrayDataSource(new byte[] { 'a', (byte)0x82, (byte)0x81}, "application/binary");
+
+        assertEquals("base64", MimeUtility.getEncoding(source));
+    }
+
+
+    public void testQuote() throws Exception {
+        assertEquals("abc", MimeUtility.quote("abc", "&*%"));
+        assertEquals("\"abc&\"", MimeUtility.quote("abc&", "&*%"));
+        assertEquals("\"abc\\\"\"", MimeUtility.quote("abc\"", "&*%"));
+        assertEquals("\"abc\\\\\"", MimeUtility.quote("abc\\", "&*%"));
+        assertEquals("\"abc\\\r\"", MimeUtility.quote("abc\r", "&*%"));
+        assertEquals("\"abc\\\n\"", MimeUtility.quote("abc\n", "&*%"));
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/NewsAddressTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/NewsAddressTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/NewsAddressTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/NewsAddressTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NewsAddressTest extends TestCase {
+    public void testNewsAddress() throws AddressException {
+        final NewsAddress na = new NewsAddress("geronimo-dev", "news.apache.org");
+        assertEquals("geronimo-dev", na.getNewsgroup());
+        assertEquals("news.apache.org", na.getHost());
+        assertEquals("news", na.getType());
+        assertEquals("geronimo-dev", na.toString());
+        final NewsAddress[] nas =
+            NewsAddress.parse(
+                "geronimo-dev@news.apache.org, geronimo-user@news.apache.org");
+        assertEquals(2, nas.length);
+        assertEquals("geronimo-dev", nas[0].getNewsgroup());
+        assertEquals("news.apache.org", nas[0].getHost());
+        assertEquals("geronimo-user", nas[1].getNewsgroup());
+        assertEquals("news.apache.org", nas[1].getHost());
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/ParameterListTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/ParameterListTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/ParameterListTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/ParameterListTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ParameterListTest extends TestCase {
+    public ParameterListTest(final String arg0) {
+        super(arg0);
+    }
+    public void testParameters() throws ParseException {
+        final ParameterList list =
+            new ParameterList(";thing=value;thong=vulue;thung=git");
+        assertEquals("value", list.get("thing"));
+        assertEquals("vulue", list.get("thong"));
+        assertEquals("git", list.get("thung"));
+    }
+
+    public void testQuotedParameter() throws ParseException {
+        final ParameterList list = new ParameterList(";foo=one;bar=\"two\"");
+        assertEquals("one", list.get("foo"));
+        assertEquals("two", list.get("bar"));
+    }
+    
+    public void testQuotedParameterSet() throws ParseException {
+        final ParameterList list = new ParameterList();
+        list.set("foo", "one");
+        list.set("bar", "\"two\"");
+        assertEquals("one", list.get("foo"));
+        assertEquals("\"two\"", list.get("bar"));
+    }
+    
+    public void testMultisegmentParameter() throws ParseException {
+        final ParameterList list = new ParameterList(";foo*0=one;foo*1=\"two\"");
+        assertEquals("onetwo", list.get("foo"));
+    }
+
+    public void testMultisegmentParameterSet() throws ParseException {
+        final ParameterList list = new ParameterList();
+        list.set("foo*0", "one");
+        list.set("foo*1", "\"two\"");
+        list.combineSegments();
+        assertEquals("one\"two\"", list.get("foo"));
+    }
+    
+    public void testMultisegmentParameterMoreSet() throws ParseException {
+        final ParameterList list = new ParameterList();
+        list.set("foo*0", "one");
+        list.set("foo*1", "two");
+        list.set("foo*2", "three");
+        list.set("bar", "four");
+        list.set("test2*0", "seven");
+        list.set("test*1", "six");
+        list.set("test*0", "five");
+        list.combineSegments();
+        assertEquals("onetwothree", list.get("foo"));
+        assertEquals("four", list.get("bar"));
+        assertEquals("fivesix", list.get("test"));
+        assertEquals("seven", list.get("test2"));
+    }
+    
+    public void testMultisegmentParameterMore() throws ParseException {
+        final ParameterList list = new ParameterList(";foo*0=one;foo*1=two;foo*2=three;bar=four;test2*0=seven;test*1=six;test*0=five");
+        assertEquals("onetwothree", list.get("foo"));
+        assertEquals("four", list.get("bar"));
+        assertEquals("fivesix", list.get("test"));
+        assertEquals("seven", list.get("test2"));
+    }
+    
+    public void testMultisegmentParameterEncodedMore() throws ParseException {
+        final String value = " '*% abc \u0081\u0082\r\n\t";
+        final String encodedTest = "UTF-8''%20%27%2A%25%20abc%20%C2%81%C2%82%0D%0A%09";
+        final ParameterList list = new ParameterList(";foo*0=one;foo*1=two;foo*2*="+encodedTest+";bar=four;test2*0=seven;test*1=six;test*0=five");
+        assertEquals("onetwo"+value, list.get("foo"));
+        assertEquals("four", list.get("bar"));
+        assertEquals("fivesix", list.get("test"));
+        assertEquals("seven", list.get("test2"));
+    }
+    
+    public void testMultisegmentParameterEncodedMoreFail() throws ParseException {
+        //final String value = " '*% abc \u0081\u0082\r\n\t";
+        final String encodedTest = "UTF-8''%20%27%2A%25%20abc%20%C2%81%C2%82%0D%0A%09";
+        final ParameterList list = new ParameterList(";foo*0=one;foo*1=two;foo*2="+encodedTest+";bar=four;test2*0=seven;test*1=six;test*0=five");
+        assertEquals("onetwo"+encodedTest, list.get("foo"));
+        assertEquals("four", list.get("bar"));
+        assertEquals("fivesix", list.get("test"));
+        assertEquals("seven", list.get("test2"));
+    }
+    
+    public void testMultisegmentParameterMoreMixedEncodedSet() throws ParseException {
+        
+        final String value = " '*% abc \u0081\u0082\r\n\t";
+        final String encodedTest = "UTF-8''%20%27%2A%25%20abc%20%C2%81%C2%82%0D%0A%09";
+        
+        final ParameterList list = new ParameterList();
+        list.set("foo*0", "one");
+        list.set("foo*1", "two");
+        list.set("foo*2*", encodedTest, "UTF-8");
+        list.set("bar", "four");
+        list.set("test2*0", "seven");
+        list.set("test*1", "six");
+        list.set("test*0", "five");
+        list.set("test3*", encodedTest, "UTF-8");
+        list.combineSegments();
+        assertEquals("onetwo"+value, list.get("foo"));
+        assertEquals("four", list.get("bar"));
+        assertEquals("fivesix", list.get("test"));
+        assertEquals("seven", list.get("test2"));
+        //assertEquals(value, list.get("test3"));
+    }
+    
+    public void emptyParameter() throws ParseException {
+        final ParameterList list = new ParameterList("");
+        assertEquals(0, list.size());
+    }
+    
+    public void testEncodeDecode() throws Exception {
+
+        //since JavaMail 1.5 encodeparameters/decodeparameters are enabled by default
+        //System.setProperty("mail.mime.encodeparameters", "true");
+        //System.setProperty("mail.mime.decodeparameters", "true");
+
+        final String value = " '*% abc \u0081\u0082\r\n\t";
+        final String encodedTest = "; one*=UTF-8''%20%27%2A%25%20abc%20%C2%81%C2%82%0D%0A%09";
+
+        final ParameterList list = new ParameterList();
+        list.set("one", value, "UTF-8");
+
+        assertEquals(value, list.get("one"));
+
+        final String encoded = list.toString();
+
+        assertEquals(encoded, encodedTest);
+
+        final ParameterList list2 = new ParameterList(encoded);
+        assertEquals(value, list.get("one"));
+        assertEquals(list2.toString(), encodedTest);
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/PreencodedMimeBodyPartTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/PreencodedMimeBodyPartTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/PreencodedMimeBodyPartTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/internet/PreencodedMimeBodyPartTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.internet;
+
+import java.io.ByteArrayOutputStream;
+
+import jakarta.mail.MessagingException;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PreencodedMimeBodyPartTest extends TestCase {
+
+     public void testEncoding() throws Exception {
+         final PreencodedMimeBodyPart part = new PreencodedMimeBodyPart("base64");
+         assertEquals("base64", part.getEncoding());
+     }
+
+     public void testUpdateHeaders() throws Exception {
+         final TestBodyPart part = new TestBodyPart("base64");
+
+         part.updateHeaders();
+
+         assertEquals("base64", part.getHeader("Content-Transfer-Encoding", null));
+     }
+
+     public void testWriteTo() throws Exception {
+         final PreencodedMimeBodyPart part = new PreencodedMimeBodyPart("binary");
+
+         final byte[] content = new byte[] { 81, 82, 83, 84, 85, 86 };
+
+         part.setContent(new String(content, "UTF-8"), "text/plain; charset=\"UTF-8\"");
+
+         final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+         part.writeTo(out);
+
+         final byte[] data = out.toByteArray();
+
+         // we need to scan forward to the actual content and verify it has been written without additional
+         // encoding.  Our marker is a "crlfcrlf" sequence.
+
+
+         for (int i = 0; i < data.length; i++) {
+             if (data[i] == '\r') {
+                 if (data[i + 1] == '\n' && data[i + 2] == '\r' && data[i + 3] == '\n') {
+                     for (int j = 0; j < content.length; j++) {
+                         assertEquals(data[i + 4 + j], content[j]);
+                     }
+
+                 }
+             }
+         }
+     }
+
+
+     public class TestBodyPart extends PreencodedMimeBodyPart {
+
+         public TestBodyPart(final String encoding) {
+             super(encoding);
+         }
+
+         @Override
+        public void updateHeaders() throws MessagingException {
+             super.updateHeaders();
+         }
+     }
+}
+
+

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/ByteArrayDataSourceTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/ByteArrayDataSourceTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/ByteArrayDataSourceTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/ByteArrayDataSourceTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ByteArrayDataSourceTest extends TestCase {
+    public ByteArrayDataSourceTest(final String arg0) {
+        super(arg0);
+    }
+
+    public void testByteArray() throws Exception {
+        doDataSourceTest(new ByteArrayDataSource("0123456789", "text/plain"), "text/plain");
+        doDataSourceTest(new ByteArrayDataSource("0123456789".getBytes(), "text/xml"), "text/xml");
+        final ByteArrayInputStream in = new ByteArrayInputStream("0123456789".getBytes());
+
+        doDataSourceTest(new ByteArrayDataSource(in, "text/html"), "text/html");
+
+        try {
+            final ByteArrayDataSource source = new ByteArrayDataSource("01234567890", "text/plain");
+            source.getOutputStream();
+            fail();
+        } catch (final IOException e) {
+        }
+
+        final ByteArrayDataSource source = new ByteArrayDataSource("01234567890", "text/plain");
+        assertEquals(source.getName(), "");
+
+        source.setName("fred");
+        assertEquals(source.getName(), "fred");
+    }
+
+
+    private void doDataSourceTest(final ByteArrayDataSource source, final String type) throws Exception {
+        assertEquals(type, source.getContentType());
+
+        final InputStream in = source.getInputStream();
+        final byte[] bytes = new byte[10];
+
+        final int count = in.read(bytes);
+
+        assertEquals(count, bytes.length);
+        assertEquals("0123456789", new String(bytes));
+    }
+}
+

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedByteArrayInputStreamTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedByteArrayInputStreamTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedByteArrayInputStreamTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedByteArrayInputStreamTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.util;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SharedByteArrayInputStreamTest extends TestCase {
+    private final String testString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    private final byte[] testData = testString.getBytes();
+
+
+
+    public SharedByteArrayInputStreamTest(final String arg0) {
+        super(arg0);
+    }
+
+    public void testInput() throws Exception {
+        final SharedByteArrayInputStream in = new SharedByteArrayInputStream(testData);
+
+        assertEquals(in.read(), '0');
+
+        assertEquals(in.getPosition(), 1);
+
+        final byte[] bytes = new byte[10];
+
+        assertEquals(in.read(bytes), 10);
+        assertEquals(new String(bytes), "123456789a");
+        assertEquals(in.getPosition(), 11);
+
+        assertEquals(in.read(bytes, 5, 5), 5);
+        assertEquals(new String(bytes), "12345bcdef");
+        assertEquals(in.getPosition(), 16);
+
+        assertEquals(in.skip(5), 5);
+        assertEquals(in.getPosition(), 21);
+        assertEquals(in.read(), 'l');
+
+        while (in.read() != 'Z') {
+        }
+
+        assertEquals(in.read(), -1);
+    }
+
+
+    public void testNewStream() throws Exception {
+        final SharedByteArrayInputStream in = new SharedByteArrayInputStream(testData);
+
+        final SharedByteArrayInputStream sub = (SharedByteArrayInputStream)in.newStream(10, 10 + 26);
+
+        assertEquals(sub.getPosition(), 0);
+
+        assertEquals(in.read(), '0');
+        assertEquals(sub.read(), 'a');
+
+        sub.skip(1);
+        assertEquals(sub.getPosition(), 2);
+
+        while (sub.read() != 'z') {
+        }
+
+        assertEquals(sub.read(), -1);
+
+        final SharedByteArrayInputStream sub2 = (SharedByteArrayInputStream)sub.newStream(5, 10);
+
+        assertEquals(sub2.getPosition(), 0);
+        assertEquals(sub2.read(), 'f');
+    }
+}

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/java/jakarta/mail/util/SharedFileInputStreamTest.java Tue May  3 12:22:08 2022
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package jakarta.mail.util;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SharedFileInputStreamTest extends TestCase {
+
+    File basedir = new File(System.getProperty("basedir", "."));
+    File testInput = new File(basedir, "src/test/resources/test.dat");
+
+    public SharedFileInputStreamTest(final String arg0) {
+        super(arg0);
+    }
+
+    public void testInput() throws Exception {
+        doTestInput(new SharedFileInputStream(testInput));
+        doTestInput(new SharedFileInputStream(testInput.getPath()));
+
+        doTestInput(new SharedFileInputStream(testInput, 16));
+        doTestInput(new SharedFileInputStream(testInput.getPath(), 16));
+    }
+
+
+    public void doTestInput(final SharedFileInputStream in) throws Exception {
+        assertEquals(in.read(), '0');
+
+        assertEquals(in.getPosition(), 1);
+
+        final byte[] bytes = new byte[10];
+
+        assertEquals(in.read(bytes), 10);
+        assertEquals(new String(bytes), "123456789a");
+        assertEquals(in.getPosition(), 11);
+
+        assertEquals(in.read(bytes, 5, 5), 5);
+        assertEquals(new String(bytes), "12345bcdef");
+        assertEquals(in.getPosition(), 16);
+
+        assertEquals(in.skip(5), 5);
+        assertEquals(in.getPosition(), 21);
+        assertEquals(in.read(), 'l');
+
+        while (in.read() != '\n' ) {
+        }
+
+        assertEquals(in.read(), -1);
+
+        in.close();
+    }
+
+
+    public void testNewStream() throws Exception {
+        final SharedFileInputStream in = new SharedFileInputStream(testInput);
+
+        final SharedFileInputStream sub = (SharedFileInputStream)in.newStream(10, 10 + 26);
+
+        assertEquals(sub.getPosition(), 0);
+
+        assertEquals(in.read(), '0');
+        assertEquals(sub.read(), 'a');
+
+        sub.skip(1);
+        assertEquals(sub.getPosition(), 2);
+
+        while (sub.read() != 'z') {
+        }
+
+        assertEquals(sub.read(), -1);
+
+        final SharedFileInputStream sub2 = (SharedFileInputStream)sub.newStream(5, 10);
+
+        sub.close();    // should not close in or sub2
+
+        assertEquals(sub2.getPosition(), 0);
+        assertEquals(sub2.read(), 'f');
+
+        assertEquals(in.read(), '1');   // should still work
+
+        sub2.close();
+
+        assertEquals(in.read(), '2');   // should still work
+
+        in.close();
+    }
+
+
+    public void testMark() throws Exception {
+        doMarkTest(new SharedFileInputStream(testInput, 10));
+
+        final SharedFileInputStream in = new SharedFileInputStream(testInput, 10);
+
+        final SharedFileInputStream sub = (SharedFileInputStream)in.newStream(5, -1);
+        doMarkTest(sub);
+    }
+
+
+    private void doMarkTest(final SharedFileInputStream in) throws Exception {
+         assertTrue(in.markSupported());
+
+         final byte[] buffer = new byte[60];
+
+         in.read();
+         in.read();
+         in.mark(50);
+
+         final int markSpot = in.read();
+
+         in.read(buffer, 0, 20);
+
+         in.reset();
+
+         assertEquals(markSpot, in.read());
+         in.read(buffer, 0, 40);
+         in.reset();
+         assertEquals(markSpot, in.read());
+
+         in.read(buffer, 0, 51);
+
+         try {
+             in.reset();
+             fail();
+         } catch (final IOException e) {
+         }
+    }
+}
+

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_empty.eml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_empty.eml?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_empty.eml (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_empty.eml Tue May  3 12:22:08 2022
@@ -0,0 +1,8 @@
+From: Nathaniel Borenstein <ns...@bellcore.com> 
+To:  Ned Freed <ne...@innosoft.com> 
+Subject: Sample message 
+MIME-Version: 1.0 
+Content-type: multipart/mixed;
+              boundary="simple boundary"
+
+no body parts
\ No newline at end of file

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_boundary_param.eml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_boundary_param.eml?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_boundary_param.eml (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_boundary_param.eml Tue May  3 12:22:08 2022
@@ -0,0 +1,21 @@
+From: Nathaniel Borenstein <ns...@bellcore.com>
+To:  Ned Freed <ne...@innosoft.com>
+Subject: Sample message
+MIME-Version: 1.0
+Content-type: multipart/mixed
+
+This is the preamble.  It is to be ignored, though it
+is a handy place for mail composers to include an
+explanatory note to non-MIME compliant readers.
+--simple boundary
+
+This is implicitly typed plain ASCII text.
+It does NOT end with a linebreak.
+--simple boundary
+Content-type: text/plain; charset=us-ascii
+
+This is explicitly typed plain ASCII text.
+It DOES end with a linebreak.
+
+--simple boundary--
+This is the epilogue.  It is also to be ignored.
\ No newline at end of file

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_end_boundary.eml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_end_boundary.eml?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_end_boundary.eml (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_missing_end_boundary.eml Tue May  3 12:22:08 2022
@@ -0,0 +1,10 @@
+From: Nathaniel Borenstein <ns...@bellcore.com>
+To:  Ned Freed <ne...@innosoft.com>
+Subject: Sample message
+MIME-Version: 1.0
+Content-type: multipart/mixed;
+              boundary=123456789
+
+--123456789
+
+This is implicitly typed plain ASCII text.

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_normal.eml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_normal.eml?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_normal.eml (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_normal.eml Tue May  3 12:22:08 2022
@@ -0,0 +1,22 @@
+From: Nathaniel Borenstein <ns...@bellcore.com>
+To:  Ned Freed <ne...@innosoft.com>
+Subject: Sample message
+MIME-Version: 1.0
+Content-type: multipart/mixed;
+              boundary="simple boundary"
+
+This is the preamble.  It is to be ignored, though it
+is a handy place for mail composers to include an
+explanatory note to non-MIME compliant readers.
+--simple boundary
+
+This is implicitly typed plain ASCII text.
+It does NOT end with a linebreak.
+--simple boundary
+Content-type: text/plain; charset=us-ascii
+
+This is explicitly typed plain ASCII text.
+It DOES end with a linebreak.
+
+--simple boundary--
+This is the epilogue.  It is also to be ignored.
\ No newline at end of file

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_wrong_boundary_param.eml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_wrong_boundary_param.eml?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_wrong_boundary_param.eml (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/multipart_msg_wrong_boundary_param.eml Tue May  3 12:22:08 2022
@@ -0,0 +1,22 @@
+From: Nathaniel Borenstein <ns...@bellcore.com>
+To:  Ned Freed <ne...@innosoft.com>
+Subject: Sample message
+MIME-Version: 1.0
+Content-type: multipart/mixed;
+              boundary="wrong stuff"
+
+This is the preamble.  It is to be ignored, though it
+is a handy place for mail composers to include an
+explanatory note to non-MIME compliant readers.
+--simple boundary
+
+This is implicitly typed plain ASCII text.
+It does NOT end with a linebreak.
+--simple boundary
+Content-type: text/plain; charset=us-ascii
+
+This is explicitly typed plain ASCII text.
+It DOES end with a linebreak.
+
+--simple boundary--
+This is the epilogue.  It is also to be ignored.
\ No newline at end of file

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/test.dat
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/test.dat?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/test.dat (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/test.dat Tue May  3 12:22:08 2022
@@ -0,0 +1 @@
+0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/wmtom.bin
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/wmtom.bin?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/wmtom.bin (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/src/test/resources/wmtom.bin Tue May  3 12:22:08 2022
@@ -0,0 +1,21 @@
+----MIMEBoundary258DE2D105298B756D
+content-type:application/xop+xml; charset=utf-8; type="application/soap+xml"
+content-transfer-encoding:binary
+content-id:<0....@apache.org>
+
+<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Header><wsa:To xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://localhost:8070/axis2/services/MTOMService/mtomSample</wsa:To></soapenv:Header><soapenv:Body><x:EchoTest xmlns:x="http://example.org/mtom/data"><x:Data><xop:Include href="cid:1.BBFC8D48A21258EBBD@apache.org" xmlns:xop="http://www.w3.org/2004/08/xop/include"></xop:Include></x:Data><x:Data><xop:Include href="cid:2.CB365E36E21BD6491A@apache.org" xmlns:xop="http://www.w3.org/2004/08/xop/include"></xop:Include></x:Data></x:EchoTest></soapenv:Body></soapenv:Envelope>
+----MIMEBoundary258DE2D105298B756D
+content-id:<11...@apache.org>
+content-type:application/octet-stream
+content-transfer-encoding:binary
+
+saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda 
+
+----MIMEBoundary258DE2D105298B756D
+content-id:<2....@apache.org>
+content-type:application/octet-stream
+content-transfer-encoding:binary
+
+saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda saminda 
+
+----MIMEBoundary258DE2D105298B756D--

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/default.address.map
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/default.address.map?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/default.address.map (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/default.address.map Tue May  3 12:22:08 2022
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##  http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied.  See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 438769 $ $Date: 2006-08-30 21:03:44 -0700 (Wed, 30 Aug 2006) $
+##
+
+# only the single mapping for smtp is defined.
+rfc822=smtp
+
+

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/jakartamail.charset.map
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/jakartamail.charset.map?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/jakartamail.charset.map (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/jakartamail.charset.map Tue May  3 12:22:08 2022
@@ -0,0 +1,87 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##  http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied.  See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 438769 $ $Date: 2006-08-30 21:03:44 -0700 (Wed, 30 Aug 2006) $
+##
+
+### Character set mapping table loaded and used by the MimeUtility class.
+
+### java character sets to MIME character set map.  This must be the first table.
+
+8859_1		ISO-8859-1
+iso8859_1	ISO-8859-1
+ISO8859_1	ISO-8859-1
+
+8859_2		ISO-8859-2
+iso8859_2	ISO-8859-2
+ISO8859_2	ISO-8859-2
+
+8859_3		ISO-8859-3
+iso8859_3	ISO-8859-3
+ISO8859_3	ISO-8859-3
+
+8859_4		ISO-8859-4
+iso8859_4	ISO-8859-4
+ISO8859_4	ISO-8859-4
+
+8859_5		ISO-8859-5
+iso8859_5	ISO-8859-5
+ISO8859_5	ISO-8859-5
+
+8859_6		ISO-8859-6
+iso8859_6	ISO-8859-6
+ISO8859_6	ISO-8859-6
+
+8859_7		ISO-8859-7
+iso8859_7	ISO-8859-7
+ISO8859_7	ISO-8859-7
+
+8859_8		ISO-8859-8
+iso8859_8	ISO-8859-8
+ISO8859_8	ISO-8859-8
+
+8859_9		ISO-8859-9
+iso8859_9	ISO-8859-9
+ISO8859_9	ISO-8859-9
+
+SJIS		Shift_JIS
+MS932		Shift_JIS
+JIS		ISO-2022-JP
+ISO2022JP	ISO-2022-JP
+EUC_JP		euc-jp
+KOI8_R		koi8-r
+EUC_CN		euc-cn
+EUC_TW		euc-tw
+EUC_KR		euc-kr
+
+--Table terminator.  The "--" at the beginning and end are required --
+
+#### MIME to java character set map
+
+iso-2022-cn     ISO2022CN
+iso-2022-kr     ISO2022KR
+utf-8           UTF8
+utf8		UTF8
+ja_jp.iso2022-7 ISO2022JP
+ja_jp.eucjp     EUCJIS
+euc-kr          KSC5601
+euckr           KSC5601
+us-ascii        ISO-8859-1
+x-us-ascii      ISO-8859-1

Added: geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/mailcap
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/mailcap?rev=1900504&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/mailcap (added)
+++ geronimo/specs/trunk/geronimo-jakartamail_2.1_spec/target/classes/META-INF/mailcap Tue May  3 12:22:08 2022
@@ -0,0 +1,28 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##  http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied.  See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 438769 $ $Date: 2006-08-30 21:03:44 -0700 (Wed, 30 Aug 2006) $
+##
+
+text/plain;;		x-java-content-handler=org.apache.geronimo.mail.handlers.TextHandler
+text/xml;;		x-java-content-handler=org.apache.geronimo.mail.handlers.XMLHandler
+text/html;;		x-java-content-handler=org.apache.geronimo.mail.handlers.HtmlHandler
+message/rfc822;;	x-java-content-handler=org.apache.geronimo.mail.handlers.MessageHandler
+multipart/*;;		x-java-content-handler=org.apache.geronimo.mail.handlers.MultipartHandler; x-java-fallback-entry=true