diff --git a/geronimo-javamail_1.5/.travis.yml b/geronimo-javamail_1.5/.travis.yml
new file mode 100644
index 0000000..ca8fc8c
--- /dev/null
+++ b/geronimo-javamail_1.5/.travis.yml
@@ -0,0 +1,8 @@
+language: java
+
+jdk:
+  - openjdk6
+  - openjdk7
+  - oraclejdk7
+  - oraclejdk8
+  
diff --git a/geronimo-javamail_1.5/LICENSE b/geronimo-javamail_1.5/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/geronimo-javamail_1.5/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/geronimo-javamail_1.5/NOTICE b/geronimo-javamail_1.5/NOTICE
new file mode 100644
index 0000000..e288221
--- /dev/null
+++ b/geronimo-javamail_1.5/NOTICE
@@ -0,0 +1,8 @@
+
+Geronimo JavaMail 1.5
+Copyright 2003-2016 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/geronimo-javamail_1.5/README.txt b/geronimo-javamail_1.5/README.txt
new file mode 100644
index 0000000..cad0219
--- /dev/null
+++ b/geronimo-javamail_1.5/README.txt
@@ -0,0 +1,19 @@
+
+Building
+========
+
+To build you will need:
+
+ * J2SE SDK 1.5+ (http://java.sun.com/j2se/1.5/)
+ * Maven 2.0.7+ (http://maven.apache.org)
+
+To build all changes incrementally:
+
+    mvn install
+
+To perform clean builds, which are sometimes needed after some changes to the
+source tree:
+
+    mvn clean install
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml
new file mode 100644
index 0000000..2aed314
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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: 1704994 $ $Date: 2015-09-24 01:38:16 -0400 (Thu, 24 Sep 2015) $ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.javamail</groupId>
+        <artifactId>geronimo-javamail_1.5</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>geronimo-javamail_1.5_mail</artifactId>
+    <packaging>bundle</packaging>
+    <name>Geronimo JavaMail 1.5 :: Mail</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.javamail</groupId>
+            <artifactId>geronimo-javamail_1.5_provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-javamail_1.5_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-activation_1.1_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-osgi-locator</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <!-- NOTE:  The shade build step is an important step in getting the bundle
+                     built correctly.  This step copies all of the OSGI-INF/services and META-INF/*
+                     resources into the local build target, and then the bundle plugin merges those
+                     resources with the class files pulled from the dependency jars to create the
+                     final result.  Without this extra step, only the class files make it into the
+                     final bundle.-->
+
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <artifactSet>
+                                <includes>
+                                    <include>org.apache.geronimo.specs:geronimo-javamail_1.5_spec</include>
+                                    <include>org.apache.geronimo.javamail:geronimo-javamail_1.5_provider</include>
+                                    <include>${project.groupId}:${project.artifactId}</include>
+                                </includes>
+                            </artifactSet>
+                            <filters>
+                                <filter>
+                                    <artifact>org.apache.geronimo.specs:geronimo-javamail_1.5_spec</artifact>
+                                    <!-- All of the class files need to be excluded to avoid bnd errors about split packages -->
+                                    <excludes>
+                                        <exclude>javax/**</exclude>
+                                        <exclude>org/apache/geronimo/mail/*.class</exclude>
+                                        <exclude>org/apache/geronimo/osgi/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.javamail:geronimo-javamail_1.5_provider</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/javamail/**</exclude>
+                                        <exclude>org/apache/geronimo/osgi/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
+                            <createDependencyReducedPom>true</createDependencyReducedPom>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${project.groupId}.${project.artifactId};singleton=true</Bundle-SymbolicName>
+                        <Specification-Title>JSR-919 Javamail API 1.5 merged bundle</Specification-Title>
+                        <Specification-Vendor>Sun Microsystems, Inc.</Specification-Vendor>
+                        <Specification-Version>1.5</Specification-Version>
+                        <Private-Package>
+                            org.apache.geronimo.osgi.locator,
+                            org.apache.geronimo.mail,
+                            org.apache.geronimo.mail.util,
+                            org.apache.geronimo.javamail.util,
+                            org.apache.geronimo.javamail.authentication
+                        </Private-Package>
+                        <Export-Package>
+                            javax.mail*;version=1.5,
+                            org.apache.geronimo.javamail.handlers*;version=1.5,
+                            org.apache.geronimo.javamail.store*;version=1.5,
+                            org.apache.geronimo.javamail.transport*;version=1.5,
+                            org.apache.geronimo.mail.handlers*;version=1.5,
+                        </Export-Package>
+                        <Import-Package>
+                            javax.activation,
+                            javax.net,
+                            javax.mail*,
+                            javax.imageio*;resolution:="optional",
+                            javax.net.ssl*;resolution:="optional",
+                            javax.security.sasl*;resolution:="optional",
+                            javax.security.auth.callback*;resolution:="optional",
+                            org.apache.geronimo.osgi.registry.api;resolution:="optional",
+                            *
+                        </Import-Package>
+                        <Bundle-Activator>org.apache.geronimo.mail.Activator</Bundle-Activator>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml
new file mode 100644
index 0000000..251ed2b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $ -->
+
+<project name="${project.name}">
+    
+    <body>
+        
+        ${parentProject}
+        
+        ${modules}
+        
+        ${reports}
+        
+    </body>
+
+</project>
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml
new file mode 100644
index 0000000..c9cccf5
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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: 1704994 $ $Date: 2014-07-20 09:36:35 +0200 (So, 20. Jul 2014) 
+    $ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.javamail</groupId>
+        <artifactId>geronimo-javamail_1.5</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>geronimo-javamail_1.5_provider</artifactId>
+    <packaging>bundle</packaging>
+    <name>Geronimo JavaMail 1.5 :: Provider</name>
+
+    <properties>
+        <james.version>3.0-beta4</james.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-activation_1.1_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-javamail_1.5_spec</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>apache-mime4j-core</artifactId>
+                    <groupId>org.apache.james</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-imap-processor</artifactId>
+            <version>0.3</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-protocols-pop3</artifactId>
+            <version>${james.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-protocols-imap4</artifactId>
+            <version>${james.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-protocols-smtp</artifactId>
+            <version>${james.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <version>0.5</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <version>0.5</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-protocols-library</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <version>${james.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-protocols-library</artifactId>
+            <scope>test</scope>
+            <version>${james.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-filesystem-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <version>${james.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-data-library</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <version>${james.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-data-library</artifactId>
+            <scope>test</scope>
+            <version>${james.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-data-file</artifactId>
+            <version>${james.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-queue-file</artifactId>
+            <version>${james.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-data-file</artifactId>
+            <version>${james.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-queue-file</artifactId>
+            <version>${james.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-queue-api</artifactId>
+            <version>${james.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-data-api</artifactId>
+            <version>${james.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>mail</artifactId>
+                    <groupId>javax.mail</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>1.7.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> 
+            <version>1.3.1</version> <scope>test</scope> </dependency> -->
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${project.groupId}.${project.artifactId};singleton=true</Bundle-SymbolicName>
+                        <Specification-Title>JSR-919 Javamail API 1.5
+                            provider bundle</Specification-Title>
+                        <Specification-Vendor>Sun Microsystems, Inc.</Specification-Vendor>
+                        <Specification-Version>1.5</Specification-Version>
+                        <Private-Package>
+                            org.apache.geronimo.javamail.util,
+                            org.apache.geronimo.javamail.authentication
+                        </Private-Package>
+                        <Export-Package>
+                            org.apache.geronimo.javamail.store*;version=1.5,
+                            org.apache.geronimo.javamail.transport*;version=1.5,
+                            org.apache.geronimo.javamail.handlers*;version=1.5
+                        </Export-Package>
+                        <Import-Package>
+                            javax.activation,
+                            javax.net,
+                            javax.mail*,
+                            org.apache.geronimo.mail.util,
+                            javax.imageio*;resolution:="optional",
+                            javax.net.ssl*;resolution:="optional",
+                            javax.security.sasl*;resolution:="optional",
+                            javax.security.auth.callback*;resolution:="optional",
+                            org.apache.geronimo.mail.james.mime4j.codec
+                        </Import-Package>
+                    </instructions>
+                    <unpackBundle>true</unpackBundle>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java
new file mode 100644
index 0000000..c4341c7
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java
@@ -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 org.apache.geronimo.javamail.authentication;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+
+public class AuthenticatorFactory {
+    // the list of authentication mechanisms we have direct support for.  Others come from
+    // SASL, if it's available.
+
+    public static final String AUTHENTICATION_PLAIN = "PLAIN";
+    public static final String AUTHENTICATION_LOGIN = "LOGIN";
+    public static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
+    public static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
+
+    static public ClientAuthenticator getAuthenticator(ProtocolProperties props, List mechanisms, String host, String username, String password, String authId, String realm)
+    {
+        // if the authorization id isn't given, then this is the same as the logged in user name.
+        if (authId == null) {
+            authId = username;
+        }
+
+        // if SASL is enabled, try getting a SASL authenticator first
+        if (props.getBooleanProperty("sasl.enable", false)) {
+            // we need to convert the mechanisms map into an array of strings for SASL.
+            String [] mechs = (String [])mechanisms.toArray(new String[mechanisms.size()]);
+
+            try {
+                // need to try to load this using reflection since it has references to
+                // the SASL API.  That's only available with 1.5 or later.
+                Class authenticatorClass = Class.forName("org.apache.geronimo.javamail.authentication.SASLAuthenticator");
+                Constructor c = authenticatorClass.getConstructor(new Class[] {
+                    (new String[0]).getClass(),
+                    Properties.class,
+                    String.class,
+                    String.class,
+                    String.class,
+                    String.class,
+                    String.class,
+                    String.class
+                });
+
+                Object[] args = { mechs, props.getProperties(), props.getProtocol(), host, realm, authId, username, password };
+
+                return (ClientAuthenticator)c.newInstance(args);
+            } catch (Throwable e) {
+                // Any exception is likely because we're running on 1.4 and can't use the Sasl API.
+                // just ignore and use our fallback implementations.
+            }
+        }
+
+        // now go through the progression of mechanisms we support, from the
+        // most secure to the least secure.
+
+        if (mechanisms.contains(AUTHENTICATION_DIGESTMD5)) {
+            return new DigestMD5Authenticator(host, username, password, realm);
+        } else if (mechanisms.contains(AUTHENTICATION_CRAMMD5)) {
+            return new CramMD5Authenticator(username, password);
+        } else if (mechanisms.contains(AUTHENTICATION_LOGIN)) {
+            return new LoginAuthenticator(username, password);
+        } else if (mechanisms.contains(AUTHENTICATION_PLAIN)) {
+            return new PlainAuthenticator(authId, username, password);
+        } else {
+            // can't find a mechanism we support in common
+            return null;
+        }
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java
new file mode 100644
index 0000000..0404d36
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java
@@ -0,0 +1,86 @@
+/*
+ * 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 org.apache.geronimo.javamail.authentication;
+
+import javax.mail.MessagingException;
+
+/**
+ * Simplified version of the Java 5 SaslClient interface. This is used to
+ * implement a javamail authentication framework that mimics the Sasl framework
+ * on a 1.4.2 JVM. Only the methods required by the Javamail code are
+ * implemented here, but it should be a simple migration to the fuller SASL
+ * interface.
+ */
+public interface ClientAuthenticator {
+    /**
+     * Evaluate a challenge and return a response that can be sent back to the
+     * server. Bot the challenge information and the response information are
+     * "raw data", minus any special encodings used by the transport. For
+     * example, SMTP DIGEST-MD5 authentication protocol passes information as
+     * Base64 encoded strings. That encoding must be removed before calling
+     * evaluateChallenge() and the resulting respose must be Base64 encoced
+     * before transmission to the server.
+     * 
+     * It is the authenticator's responsibility to keep track of the state of
+     * the evaluations. That is, if the authentication process requires multiple
+     * challenge/response cycles, then the authenticator needs to keep track of
+     * context of the challenges.
+     * 
+     * @param challenge
+     *            The challenge data.
+     * 
+     * @return An appropriate response for the challenge data.
+     */
+
+    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException;
+
+    /**
+     * Indicates that the authenticator has data that should be sent when the
+     * authentication process is initiated. For example, the SMTP PLAIN
+     * authentication sends userid/password without waiting for a challenge
+     * response.
+     * 
+     * If this method returns true, then the initial response is retrieved using
+     * evaluateChallenge() passing null for the challenge information.
+     * 
+     * @return True if the challenge/response process starts with an initial
+     *         response on the client side.
+     */
+    public boolean hasInitialResponse();
+
+    /**
+     * Indicates whether the client believes the challenge/response sequence is
+     * now complete.
+     * 
+     * @return true if the client has evaluated what it believes to be the last
+     *         challenge, false if there are additional stages to evaluate.
+     */
+
+    public boolean isComplete();
+
+    /**
+     * Return the mechanism name implemented by this authenticator.
+     * 
+     * @return The string name of the authentication mechanism. This name should
+     *         match the names commonly used by the mail servers (e.g., "PLAIN",
+     *         "LOGIN", "DIGEST-MD5", etc.).
+     */
+    public String getMechanismName();
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
new file mode 100644
index 0000000..91a6425
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
@@ -0,0 +1,175 @@
+/*
+ * 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 org.apache.geronimo.javamail.authentication;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.mail.util.Hex;
+
+public class CramMD5Authenticator implements ClientAuthenticator {
+
+    // the user we're authenticating
+    protected String username;
+
+    // the user's password (the "shared secret")
+    protected String password;
+
+    // indicates whether we've gone through the entire challenge process.
+    protected boolean complete = false;
+
+    /**
+     * Main constructor.
+     *
+     * @param username
+     *            The login user name.
+     * @param password
+     *            The login password.
+     */
+    public CramMD5Authenticator(String username, String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    /**
+     * Respond to the hasInitialResponse query. This mechanism does not have an
+     * initial response.
+     *
+     * @return Always returns false.
+     */
+    public boolean hasInitialResponse() {
+        return false;
+    }
+
+    /**
+     * Indicate whether the challenge/response process is complete.
+     *
+     * @return True if the last challenge has been processed, false otherwise.
+     */
+    public boolean isComplete() {
+        return complete;
+    }
+
+    /**
+     * Retrieve the authenticator mechanism name.
+     *
+     * @return Always returns the string "CRAM-MD5"
+     */
+    public String getMechanismName() {
+        return "CRAM-MD5";
+    }
+
+    /**
+     * Evaluate a CRAM-MD5 login challenge, returning the a result string that
+     * should satisfy the clallenge.
+     *
+     * @param challenge
+     *            The decoded challenge data, as a byte array.
+     *
+     * @return A formatted challege response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
+        // we create the challenge from the userid and password information (the
+        // "shared secret").
+        byte[] passBytes;
+
+        try {
+            // get the password in an UTF-8 encoding to create the token
+            passBytes = password.getBytes("UTF-8");
+            // compute the password digest using the key
+            byte[] digest = computeCramDigest(passBytes, challenge);
+
+            // create a unified string using the user name and the hex encoded
+            // digest
+            String responseString = username + " " + new String(Hex.encode(digest), "ISO8859-1");
+            complete = true;
+            return responseString.getBytes("ISO8859-1");
+        } catch (UnsupportedEncodingException e) {
+            // got an error, fail this
+            throw new MessagingException("Invalid character encodings");
+        }
+
+    }
+
+    /**
+     * Compute a CRAM digest using the hmac_md5 algorithm. See the description
+     * of RFC 2104 for algorithm details.
+     *
+     * @param key
+     *            The key (K) for the calculation.
+     * @param input
+     *            The encrypted text value.
+     *
+     * @return The computed digest, as a byte array value.
+     * @exception NoSuchAlgorithmException
+     */
+    protected byte[] computeCramDigest(byte[] key, byte[] input) throws MessagingException {
+        // CRAM digests are computed using the MD5 algorithm.
+        MessageDigest digest;
+        try {
+            digest = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e) {
+            throw new MessagingException("Unable to access MD5 message digest", e);
+        }
+
+        // if the key is longer than 64 bytes, then we get a digest of the key
+        // and use that instead.
+        // this is required by RFC 2104.
+        if (key.length > 64) {
+            digest.update(key);
+            key = digest.digest();
+        }
+
+        // now we create two 64 bit padding keys, initialized with the key
+        // information.
+        byte[] ipad = new byte[64];
+        byte[] opad = new byte[64];
+
+        System.arraycopy(key, 0, ipad, 0, key.length);
+        System.arraycopy(key, 0, opad, 0, key.length);
+
+        // and these versions are munged by XORing with "magic" values.
+
+        for (int i = 0; i < 64; i++) {
+            ipad[i] ^= 0x36;
+            opad[i] ^= 0x5c;
+        }
+
+        // now there are a pair of MD5 operations performed, and inner and an
+        // outer. The spec defines this as
+        // H(K XOR opad, H(K XOR ipad, text)), where H is the MD5 operation.
+
+        // inner operation
+        digest.reset();
+        digest.update(ipad);
+        digest.update(input); // this appends the text to the pad
+        byte[] md5digest = digest.digest();
+
+        // outer operation
+        digest.reset();
+        digest.update(opad);
+        digest.update(md5digest);
+        return digest.digest(); // final result
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
new file mode 100644
index 0000000..0272b24
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
@@ -0,0 +1,628 @@
+/*
+ * 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 org.apache.geronimo.javamail.authentication;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+
+import javax.mail.AuthenticationFailedException;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.mail.util.Base64;
+import org.apache.geronimo.mail.util.Hex;
+
+/**
+ * Process a DIGEST-MD5 authentication, using the challenge/response mechanisms.
+ */
+public class DigestMD5Authenticator implements ClientAuthenticator {
+
+    protected static final int AUTHENTICATE_CLIENT = 0;
+
+    protected static final int AUTHENTICATE_SERVER = 1;
+
+    protected static final int AUTHENTICATION_COMPLETE = 2;
+
+    // the host server name
+    protected String host;
+
+    // the user we're authenticating
+    protected String username;
+
+    // the user's password (the "shared secret")
+    protected String password;
+
+    // the target login realm
+    protected String realm;
+
+    // our message digest for processing the challenges.
+    MessageDigest digest;
+
+    // the string we send to the server on the first challenge.
+    protected String clientResponse;
+
+    // the response back from an authentication challenge.
+    protected String authenticationResponse = null;
+
+    // our list of realms received from the server (normally just one).
+    protected ArrayList realms;
+
+    // the nonce value sent from the server
+    protected String nonce;
+
+    // indicates whether we've gone through the entire challenge process.
+    protected int stage = AUTHENTICATE_CLIENT;
+
+    /**
+     * Main constructor.
+     *
+     * @param host
+     *            The server host name.
+     * @param username
+     *            The login user name.
+     * @param password
+     *            The login password.
+     * @param realm
+     *            The target login realm (can be null).
+     */
+    public DigestMD5Authenticator(String host, String username, String password, String realm) {
+        this.host = host;
+        this.username = username;
+        this.password = password;
+        this.realm = realm;
+    }
+
+    /**
+     * Respond to the hasInitialResponse query. This mechanism does not have an
+     * initial response.
+     *
+     * @return Always returns false.
+     */
+    public boolean hasInitialResponse() {
+        return false;
+    }
+
+    /**
+     * Indicate whether the challenge/response process is complete.
+     *
+     * @return True if the last challenge has been processed, false otherwise.
+     */
+    public boolean isComplete() {
+        return stage == AUTHENTICATION_COMPLETE;
+    }
+
+    /**
+     * Retrieve the authenticator mechanism name.
+     *
+     * @return Always returns the string "DIGEST-MD5"
+     */
+    public String getMechanismName() {
+        return "DIGEST-MD5";
+    }
+
+    /**
+     * Evaluate a DIGEST-MD5 login challenge, returning the a result string that
+     * should satisfy the clallenge.
+     *
+     * @param challenge
+     *            The decoded challenge data, as a string.
+     *
+     * @return A formatted challege response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
+
+        // DIGEST-MD5 authentication goes in two stages. First state involves us
+        // validating with the
+        // server, the second stage is the server validating with us, using the
+        // shared secret.
+        switch (stage) {
+        // stage one of the process.
+        case AUTHENTICATE_CLIENT: {
+            // get the response and advance the processing stage.
+            byte[] response = authenticateClient(challenge);
+            stage = AUTHENTICATE_SERVER;
+            return response;
+        }
+
+        // stage two of the process.
+        case AUTHENTICATE_SERVER: {
+            // get the response and advance the processing stage to completed.
+            byte[] response = authenticateServer(challenge);
+            stage = AUTHENTICATION_COMPLETE;
+            return response;
+        }
+
+        // should never happen.
+        default:
+            throw new MessagingException("Invalid LOGIN challenge");
+        }
+    }
+
+    /**
+     * Evaluate a DIGEST-MD5 login server authentication challenge, returning
+     * the a result string that should satisfy the clallenge.
+     *
+     * @param challenge
+     *            The decoded challenge data, as a string.
+     *
+     * @return A formatted challege response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] authenticateServer(byte[] challenge) throws MessagingException {
+        // parse the challenge string and validate.
+        if (!parseChallenge(challenge)) {
+            return null;
+        }
+
+        try {
+            // like all of the client validation steps, the following is order
+            // critical.
+            // first add in the URI information.
+            digest.update((":smtp/" + host).getBytes("US-ASCII"));
+            // now mix in the response we sent originally
+            String responseString = clientResponse + new String(Hex.encode(digest.digest()), "US-ASCII");
+            digest.update(responseString.getBytes("US-ASCII"));
+
+            // now convert that into a hex encoded string.
+            String validationText = new String(Hex.encode(digest.digest()), "US-ASCII");
+
+            // if everything went well, this calculated value should match what
+            // we got back from the server.
+            // our response back is just a null string....
+            if (validationText.equals(authenticationResponse)) {
+                return new byte[0];
+            }
+            throw new AuthenticationFailedException("Invalid DIGEST-MD5 response from server");
+        } catch (UnsupportedEncodingException e) {
+            throw new MessagingException("Invalid character encodings");
+        }
+
+    }
+
+    /**
+     * Evaluate a DIGEST-MD5 login client authentication challenge, returning
+     * the a result string that should satisfy the clallenge.
+     *
+     * @param challenge
+     *            The decoded challenge data, as a string.
+     *
+     * @return A formatted challege response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] authenticateClient(byte[] challenge) throws MessagingException {
+        // parse the challenge string and validate.
+        if (!parseChallenge(challenge)) {
+            return null;
+        }
+
+        SecureRandom randomGenerator;
+        // before doing anything, make sure we can get the required crypto
+        // support.
+        try {
+            randomGenerator = new SecureRandom();
+            digest = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e) {
+            throw new MessagingException("Unable to access cryptography libraries");
+        }
+
+        // if not configured for a realm, take the first realm from the list, if
+        // any
+        if (realm == null) {
+            // if not handed any realms, just use the host name.
+            if (realms.isEmpty()) {
+                realm = host;
+            } else {
+                // pretty arbitrary at this point, so just use the first one.
+                realm = (String) realms.get(0);
+            }
+        }
+
+        // use secure random to generate a collection of bytes. that is our
+        // cnonce value.
+        byte[] cnonceBytes = new byte[32];
+
+        randomGenerator.nextBytes(cnonceBytes);
+
+        try {
+            // and get this as a base64 encoded string.
+            String cnonce = new String(Base64.encode(cnonceBytes), "US-ASCII");
+
+            // Now the digest computation part. This gets a bit tricky, and must be
+            // done in strict order.
+            // this identifies where we're logging into.
+            String idString = username + ":" + realm + ":" + password;
+            // we get a digest for this string, then use the digest for the
+            // first stage
+            // of the next digest operation.
+            digest.update(digest.digest(idString.getBytes("US-ASCII")));
+
+            // now we add the nonce strings to the digest.
+            String nonceString = ":" + nonce + ":" + cnonce;
+            digest.update(nonceString.getBytes("US-ASCII"));
+
+            // hex encode this digest, and add on the string values
+            // NB, we only support "auth" for the quality of protection value
+            // (qop). We save this in an
+            // instance variable because we'll need this to validate the
+            // response back from the server.
+            clientResponse = new String(Hex.encode(digest.digest()), "US-ASCII") + ":" + nonce + ":00000001:" + cnonce + ":auth:";
+
+            // now we add in identification values to the hash.
+            String authString = "AUTHENTICATE:smtp/" + host;
+            digest.update(authString.getBytes("US-ASCII"));
+
+            // this gets added on to the client response
+            String responseString = clientResponse + new String(Hex.encode(digest.digest()), "US-ASCII");
+            // and this gets fed back into the digest
+            digest.update(responseString.getBytes("US-ASCII"));
+
+            // and FINALLY, the challege digest is hex encoded for sending back
+            // to the server (whew).
+            String challengeResponse = new String(Hex.encode(digest.digest()), "US-ASCII");
+
+            // now finally build the keyword/value part of the challenge
+            // response. These can be
+            // in any order.
+            StringBuffer response = new StringBuffer();
+
+            response.append("username=\"");
+            response.append(username);
+            response.append("\"");
+
+            response.append(",realm=\"");
+            response.append(realm);
+            response.append("\"");
+
+            // we only support auth qop values, and the nonce-count (nc) is
+            // always 1.
+            response.append(",qop=auth");
+            response.append(",nc=00000001");
+
+            response.append(",nonce=\"");
+            response.append(nonce);
+            response.append("\"");
+
+            response.append(",cnonce=\"");
+            response.append(cnonce);
+            response.append("\"");
+
+            response.append(",digest-uri=\"smtp/");
+            response.append(host);
+            response.append("\"");
+
+            response.append(",response=");
+            response.append(challengeResponse);
+
+            return response.toString().getBytes("US-ASCII");
+
+        } catch (UnsupportedEncodingException e) {
+            throw new MessagingException("Invalid character encodings");
+        }
+    }
+
+    /**
+     * Parse the challege string, pulling out information required for our
+     * challenge response.
+     *
+     * @param challenge
+     *            The challenge data.
+     *
+     * @return true if there were no errors parsing the string, false otherwise.
+     * @exception MessagingException
+     */
+    protected boolean parseChallenge(byte[] challenge) throws MessagingException {
+        realms = new ArrayList();
+
+        DigestParser parser = null;
+        try {
+            parser = new DigestParser(new String(challenge, "US-ASCII"));
+        } catch (UnsupportedEncodingException ex) {
+        }
+
+        // parse the entire string...but we ignore everything but the options we
+        // support.
+        while (parser.hasMore()) {
+            NameValuePair pair = parser.parseNameValuePair();
+
+            String name = pair.name;
+
+            // realm to add to our list?
+            if (name.equalsIgnoreCase("realm")) {
+                realms.add(pair.value);
+            }
+            // we need the nonce to evaluate the client challenge.
+            else if (name.equalsIgnoreCase("nonce")) {
+                nonce = pair.value;
+            }
+            // rspauth is the challenge replay back, which allows us to validate
+            // that server is also legit.
+            else if (name.equalsIgnoreCase("rspauth")) {
+                authenticationResponse = pair.value;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Inner class for parsing a DIGEST-MD5 challenge string, which is composed
+     * of "name=value" pairs, separated by "," characters.
+     */
+    class DigestParser {
+        // the challenge we're parsing
+        String challenge;
+
+        // length of the challenge
+        int length;
+
+        // current parsing position
+        int position;
+
+        /**
+         * Normal constructor.
+         *
+         * @param challenge
+         *            The challenge string to be parsed.
+         */
+        public DigestParser(String challenge) {
+            this.challenge = challenge;
+            this.length = challenge.length();
+            position = 0;
+        }
+
+        /**
+         * Test if there are more values to parse.
+         *
+         * @return true if we've not reached the end of the challenge string,
+         *         false if the challenge has been completely consumed.
+         */
+        private boolean hasMore() {
+            return position < length;
+        }
+
+        /**
+         * Return the character at the current parsing position.
+         *
+         * @return The string character for the current parse position.
+         */
+        private char currentChar() {
+            return challenge.charAt(position);
+        }
+
+        /**
+         * step forward to the next character position.
+         */
+        private void nextChar() {
+            position++;
+        }
+
+        /**
+         * Skip over any white space characters in the challenge string.
+         */
+        private void skipSpaces() {
+            while (position < length && Character.isWhitespace(currentChar())) {
+                position++;
+            }
+        }
+
+        /**
+         * Parse a quoted string used with a name/value pair, accounting for
+         * escape characters embedded within the string.
+         *
+         * @return The string value of the character string.
+         */
+        private String parseQuotedValue() {
+            // we're here because we found the starting double quote. Step over
+            // it and parse to the closing
+            // one.
+            nextChar();
+
+            StringBuffer value = new StringBuffer();
+
+            while (hasMore()) {
+                char ch = currentChar();
+
+                // is this an escape char?
+                if (ch == '\\') {
+                    // step past this, and grab the following character
+                    nextChar();
+                    // we have an invalid quoted string....
+                    if (!hasMore()) {
+                        return null;
+                    }
+                    value.append(currentChar());
+                }
+                // end of the string?
+                else if (ch == '"') {
+                    // step over this so the caller doesn't process it.
+                    nextChar();
+                    // return the constructed string.
+                    return value.toString();
+                } else {
+                    // step over the character and contine with the next
+                    // characteer1
+                    value.append(ch);
+                }
+                nextChar();
+            }
+            /* fell off the end without finding a closing quote! */
+            return null;
+        }
+
+        /**
+         * Parse a token value used with a name/value pair.
+         *
+         * @return The string value of the token. Returns null if nothing is
+         *         found up to the separater.
+         */
+        private String parseTokenValue() {
+
+            StringBuffer value = new StringBuffer();
+
+            while (hasMore()) {
+                char ch = currentChar();
+                switch (ch) {
+                // process the token separators.
+                case ' ':
+                case '\t':
+                case '(':
+                case ')':
+                case '<':
+                case '>':
+                case '@':
+                case ',':
+                case ';':
+                case ':':
+                case '\\':
+                case '"':
+                case '/':
+                case '[':
+                case ']':
+                case '?':
+                case '=':
+                case '{':
+                case '}':
+                    // no token characters found? this is bad.
+                    if (value.length() == 0) {
+                        return null;
+                    }
+                    // return the accumulated characters.
+                    return value.toString();
+
+                default:
+                    // is this a control character? That's a delimiter (likely
+                    // invalid for the next step,
+                    // but it is a token terminator.
+                    if (ch < 32 || ch > 127) {
+                        // no token characters found? this is bad.
+                        if (value.length() == 0) {
+                            return null;
+                        }
+                        // return the accumulated characters.
+                        return value.toString();
+                    }
+                    value.append(ch);
+                    break;
+                }
+                // step to the next character.
+                nextChar();
+            }
+            // no token characters found? this is bad.
+            if (value.length() == 0) {
+                return null;
+            }
+            // return the accumulated characters.
+            return value.toString();
+        }
+
+        /**
+         * Parse out a name token of a name/value pair.
+         *
+         * @return The string value of the name.
+         */
+        private String parseName() {
+            // skip to the value start
+            skipSpaces();
+
+            // the name is a token.
+            return parseTokenValue();
+        }
+
+        /**
+         * Parse out a a value of a name/value pair.
+         *
+         * @return The string value associated with the name.
+         */
+        private String parseValue() {
+            // skip to the value start
+            skipSpaces();
+
+            // start of a quoted string?
+            if (currentChar() == '"') {
+                // parse it out as a string.
+                return parseQuotedValue();
+            }
+            // the value must be a token.
+            return parseTokenValue();
+        }
+
+        /**
+         * Parse a name/value pair in an DIGEST-MD5 string.
+         *
+         * @return A NameValuePair object containing the two parts of the value.
+         * @exception MessagingException
+         */
+        public NameValuePair parseNameValuePair() throws MessagingException {
+            // get the name token
+            String name = parseName();
+            if (name == null) {
+                throw new MessagingException("Name syntax error");
+            }
+
+            // the name should be followed by an "=" sign
+            if (!hasMore() || currentChar() != '=') {
+                throw new MessagingException("Name/value pair syntax error");
+            }
+
+            // step over the equals
+            nextChar();
+
+            // now get the value part
+            String value = parseValue();
+            if (value == null) {
+                throw new MessagingException("Name/value pair syntax error");
+            }
+
+            // skip forward to the terminator, which should either be the end of
+            // the line or a ","
+            skipSpaces();
+            // all that work, only to have a syntax error at the end (sigh)
+            if (hasMore()) {
+                if (currentChar() != ',') {
+                    throw new MessagingException("Name/value pair syntax error");
+                }
+                // step over, and make sure we position ourselves at either the
+                // end or the first
+                // real character for parsing the next name/value pair.
+                nextChar();
+                skipSpaces();
+            }
+            return new NameValuePair(name, value);
+        }
+    }
+
+    /**
+     * Simple inner class to represent a name/value pair.
+     */
+    public class NameValuePair {
+        public String name;
+
+        public String value;
+
+        NameValuePair(String name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java
new file mode 100644
index 0000000..9c52f62
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java
@@ -0,0 +1,140 @@
+/*
+ * 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 org.apache.geronimo.javamail.authentication;
+
+import java.io.UnsupportedEncodingException;
+
+import javax.mail.MessagingException;
+
+public class LoginAuthenticator implements ClientAuthenticator {
+
+    // constants for the authentication stages
+    protected static final int USERNAME = 0;
+
+    protected static final int PASSWORD = 1;
+
+    protected static final int COMPLETE = 2;
+
+    // the user we're authenticating
+    protected String username;
+
+    // the user's password (the "shared secret")
+    protected String password;
+
+    // indicates whether we've gone through the entire challenge process.
+    protected int stage = USERNAME;
+
+    /**
+     * Main constructor.
+     * 
+     * @param username
+     *            The login user name.
+     * @param password
+     *            The login password.
+     */
+    public LoginAuthenticator(String username, String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    /**
+     * Respond to the hasInitialResponse query. This mechanism does not have an
+     * initial response.
+     * 
+     * @return Always returns false;
+     */
+    public boolean hasInitialResponse() {
+        return false;
+    }
+
+    /**
+     * Indicate whether the challenge/response process is complete.
+     * 
+     * @return True if the last challenge has been processed, false otherwise.
+     */
+    public boolean isComplete() {
+        return stage == COMPLETE;
+    }
+
+    /**
+     * Retrieve the authenticator mechanism name.
+     * 
+     * @return Always returns the string "LOGIN"
+     */
+    public String getMechanismName() {
+        return "LOGIN";
+    }
+
+    /**
+     * Evaluate a PLAIN login challenge, returning the a result string that
+     * should satisfy the clallenge.
+     * 
+     * @param challenge
+     *            The decoded challenge data, as a byte array
+     * 
+     * @return A formatted challege response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
+
+        // process the correct stage for the challenge
+        switch (stage) {
+        // should never happen
+        case COMPLETE:
+            throw new MessagingException("Invalid LOGIN challenge");
+
+        case USERNAME: {
+            byte[] userBytes;
+
+            try {
+                // get the username and password in an UTF-8 encoding to create
+                // the token
+                userBytes = username.getBytes("UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                // got an error, fail this (this should never happen).
+                throw new MessagingException("Invalid encoding");
+            }
+
+            // next time through we're looking for a password.
+            stage = PASSWORD;
+            // the user bytes are the entire challenge respose.
+            return userBytes;
+        }
+
+        case PASSWORD: {
+            byte[] passBytes;
+
+            try {
+                // get the username and password in an UTF-8 encoding to create
+                // the token
+                passBytes = password.getBytes("UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                // got an error, fail this (this should never happen).
+                throw new MessagingException("Invalid encoding");
+            }
+            // we're finished
+            stage = COMPLETE;
+            return passBytes;
+        }
+        }
+        // should never get here.
+        throw new MessagingException("Invalid LOGIN challenge");
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java
new file mode 100644
index 0000000..dd1e704
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java
@@ -0,0 +1,126 @@
+/*
+ * 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 org.apache.geronimo.javamail.authentication;
+
+import java.io.UnsupportedEncodingException;
+
+import javax.mail.MessagingException;
+
+//Implements RFC 4616 PLAIN SASL mechanism
+//See also RFC 3501, section 6.2.2"
+//an RFC 2595, section 6"
+public class PlainAuthenticator implements ClientAuthenticator {
+
+    // the sasl authzid we're authenticating
+    protected String authzid;
+
+    // the user we're authenticating
+    protected String username;
+
+    // the user's password (the "shared secret")
+    protected String password;
+
+    // indicates whether we've gone through the entire challenge process.
+    protected boolean complete = false;
+
+    /**
+     * Main constructor.
+     *
+     * @param authzid
+     *            SASL authenticationid (optional)
+     * @param username
+     *            The login user name.
+     * @param password
+     *            The login password.
+     */
+    public PlainAuthenticator(String authzid, String username, String password) {
+        this.authzid = authzid;
+        this.username = username;
+        this.password = password;
+    }
+
+     /**
+      * Constructor without authzid
+      *
+      * @param username
+      *            The login user name.
+      * @param password
+      *            The login password.
+      */
+     public PlainAuthenticator(String username, String password) {
+         this(null, username, password);
+     }
+
+    /**
+     * Respond to the hasInitialResponse query. This mechanism does have an
+     * initial response, which is the entire challenge sequence.
+     * 
+     * @return Always returns true.
+     */
+    public boolean hasInitialResponse() {
+        return true;
+    }
+
+    /**
+     * Indicate whether the challenge/response process is complete.
+     * 
+     * @return True if the last challenge has been processed, false otherwise.
+     */
+    public boolean isComplete() {
+        return complete;
+    }
+
+    /**
+     * Retrieve the authenticator mechanism name.
+     * 
+     * @return Always returns the string "PLAIN"
+     */
+    public String getMechanismName() {
+        return "PLAIN";
+    }
+
+    /**
+     * Evaluate a PLAIN login challenge, returning the a result string that
+     * should satisfy the challenge.
+     * 
+     * @param challenge
+     *            For PLAIN Authentication there is no challenge (so this is unused)
+     * 
+     * @return A formatted challenge response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
+        try {
+
+            String result = "\0"+username+"\0"+password;
+
+            if(authzid != null && authzid.length() > 0) {
+                result = authzid+result;
+            }
+
+            complete = true;
+            return result.getBytes("UTF-8");
+
+        } catch (UnsupportedEncodingException e) {
+            // got an error, fail this
+            throw new MessagingException("Invalid encoding");
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java
new file mode 100644
index 0000000..9b22442
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java
@@ -0,0 +1,174 @@
+/*
+ * 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 org.apache.geronimo.javamail.authentication;
+
+import java.io.UnsupportedEncodingException ;
+import java.util.Map;        
+import java.util.Properties; 
+
+import javax.mail.MessagingException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.sasl.Sasl; 
+import javax.security.sasl.SaslClient; 
+import javax.security.sasl.SaslException; 
+import javax.security.sasl.RealmCallback; 
+import javax.security.sasl.RealmChoiceCallback; 
+
+public class SASLAuthenticator implements ClientAuthenticator, CallbackHandler {
+    // The realm we're authenticating within 
+    protected String realm; 
+    // the user we're authenticating
+    protected String username;
+    // the user's password (the "shared secret")
+    protected String password;
+    // the authenticator we're proxying 
+    protected SaslClient authenticator; 
+
+    protected boolean complete = false;
+
+    /**
+     * Main constructor.
+     * 
+     * @param username
+     *            The login user name.
+     * @param password
+     *            The login password.
+     */
+    public SASLAuthenticator(String[] mechanisms, Properties properties, String protocol, String host, String realm, 
+            String authorizationID, String username, String password) throws MessagingException {
+        this.realm = realm; 
+        this.username = username;
+        this.password = password;
+        try {
+            authenticator = Sasl.createSaslClient(mechanisms, authorizationID, protocol, host, (Map)properties, 
+                this); 
+        } catch (SaslException e) {
+        } 
+    }
+    
+    
+    /**
+     * Respond to the hasInitialResponse query. We defer this to the Sasl client.  
+     * 
+     * @return The SaslClient response to the same query. 
+     */
+    public boolean hasInitialResponse() {
+        return authenticator.hasInitialResponse(); 
+    }
+
+    /**
+     * Indicate whether the challenge/response process is complete.
+     * 
+     * @return True if the last challenge has been processed, false otherwise.
+     */
+    public boolean isComplete() {
+        return authenticator.hasInitialResponse(); 
+    }
+
+    /**
+     * Retrieve the authenticator mechanism name.
+     * 
+     * @return Always returns the string "PLAIN"
+     */
+    public String getMechanismName() {
+        // the authenticator selects this for us. 
+        return authenticator.getMechanismName(); 
+    }
+
+    /**
+     * Evaluate a login challenge, returning the a result string that
+     * should satisfy the clallenge.  This is forwarded to the 
+     * SaslClient, which will use the CallBackHandler to retrieve the 
+     * information it needs for the given protocol. 
+     * 
+     * @param challenge
+     *            The decoded challenge data, as byte array.
+     * 
+     * @return A formatted challege response, as an array of bytes.
+     * @exception MessagingException
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
+        // for an initial response challenge, there's no challenge date.  The SASL 
+        // client still expects a byte array argument. 
+        if (challenge == null) {
+            challenge = new byte[0];
+        }
+        
+        try {
+            return authenticator.evaluateChallenge(challenge);
+        } catch (SaslException e) {
+            // got an error, fail this
+            throw new MessagingException("Error performing SASL validation", e);
+        }
+    }
+    
+    public void handle(Callback[] callBacks) {
+        for (int i = 0; i < callBacks.length; i++) {
+            Callback callBack = callBacks[i]; 
+            // requesting the user name 
+            if (callBack instanceof NameCallback) {
+                ((NameCallback)callBack).setName(username); 
+            }
+            // need the password 
+            else if (callBack instanceof PasswordCallback) {
+                ((PasswordCallback)callBack).setPassword(password.toCharArray()); 
+            }
+            // direct request for the realm information 
+            else if (callBack instanceof RealmCallback) {
+                RealmCallback realmCallback = (RealmCallback)callBack; 
+                // we might not have a realm, so use the default from the 
+                // callback item 
+                if (realm == null) {
+                    realmCallback.setText(realmCallback.getDefaultText()); 
+                }
+                else { 
+                    realmCallback.setText(realm); 
+                }
+            }
+            // asked to select the realm information from a list 
+            else if (callBack instanceof RealmChoiceCallback) {
+                RealmChoiceCallback realmCallback = (RealmChoiceCallback)callBack; 
+                // if we don't have a realm, just tell it to use the default 
+                if (realm == null) {
+                    realmCallback.setSelectedIndex(realmCallback.getDefaultChoice()); 
+                }
+                else {
+                    // locate our configured one in the list 
+                    String[] choices = realmCallback.getChoices(); 
+
+                    for (int j = 0; j < choices.length; j++) {
+                        // set the index to any match and get out of here. 
+                        if (choices[j].equals(realm)) {
+                            realmCallback.setSelectedIndex(j); 
+                            break; 
+                        }
+                    }
+                    // NB:  If there was no match, we don't set anything.  
+                    // this should cause an authentication failure. 
+                }
+            }
+        }
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java
new file mode 100644
index 0000000..d0d202a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java
@@ -0,0 +1,91 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.datatransfer.DataFlavor;  
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import javax.activation.ActivationDataFlavor; 
+import javax.activation.DataContentHandler;
+import javax.activation.DataSource;
+import javax.activation.UnsupportedDataTypeException;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageInputStream;
+
+/**
+ * @version $Rev: 1127882 $ $Date: 2011-05-26 08:17:57 -0400 (Thu, 26 May 2011) $
+ */
+public class AbstractImageHandler implements DataContentHandler {
+    private final ActivationDataFlavor flavour;
+
+    public AbstractImageHandler(ActivationDataFlavor flavour) {
+        this.flavour = flavour;
+    }
+
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[]{flavour};
+    }
+
+    public Object getTransferData(DataFlavor dataFlavor, DataSource dataSource) throws UnsupportedFlavorException, IOException {
+        return flavour.equals(dataFlavor) ? getContent(dataSource) : null;
+    }
+
+    public Object getContent(DataSource ds) throws IOException {
+        Iterator i = ImageIO.getImageReadersByMIMEType(flavour.getMimeType());
+        if (!i.hasNext()) {
+            throw new UnsupportedDataTypeException("Unknown image type " + flavour.getMimeType());
+        }
+        ImageReader reader = (ImageReader) i.next();
+        ImageInputStream iis = ImageIO.createImageInputStream(ds.getInputStream());
+        reader.setInput(iis);
+        return reader.read(0);
+    }
+
+    public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
+        Iterator i = ImageIO.getImageWritersByMIMEType(flavour.getMimeType());
+        if (!i.hasNext()) {
+            throw new UnsupportedDataTypeException("Unknown image type " + flavour.getMimeType());
+        }
+        ImageWriter writer = (ImageWriter) i.next();
+        writer.setOutput(ImageIO.createImageOutputStream(os));
+
+        if (obj instanceof RenderedImage) {
+            writer.write((RenderedImage) obj);
+        } else if (obj instanceof BufferedImage) {
+            BufferedImage buffered = (BufferedImage) obj;
+            writer.write(new IIOImage(buffered.getRaster(), null, null));
+        } else if (obj instanceof Image) {
+            Image image = (Image) obj;
+            BufferedImage buffered = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
+            Graphics2D graphics = buffered.createGraphics();
+            graphics.drawImage(image, 0, 0, null, null);
+            writer.write(new IIOImage(buffered.getRaster(), null, null));
+        } else {
+            throw new UnsupportedDataTypeException("Unknown image type " + obj.getClass().getName());
+        }
+        os.flush();
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java
new file mode 100644
index 0000000..52afca7
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java
@@ -0,0 +1,134 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import javax.activation.DataContentHandler;
+import javax.activation.DataSource;
+
+import javax.mail.internet.ContentType; 
+import javax.mail.internet.MimeUtility;
+
+/**
+ * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
+ */
+public class AbstractTextHandler implements DataContentHandler {
+    private final DataFlavor flavour;
+
+    public AbstractTextHandler(DataFlavor flavour) {
+        this.flavour = flavour;
+    }
+
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[] {flavour};
+    }
+
+    public Object getTransferData(DataFlavor dataFlavor, DataSource dataSource) throws UnsupportedFlavorException, IOException {
+        return flavour.equals(dataFlavor) ? getContent(dataSource) : null;
+    }
+
+    /**
+     * Read the content from the DataSource and transform 
+     * it into a text object (String). 
+     * 
+     * @param ds     The source DataSource.
+     * 
+     * @return The content object. 
+     * @exception IOException
+     */
+    public Object getContent(DataSource ds) throws IOException {
+        InputStream is = ds.getInputStream(); 
+        InputStreamReader reader;
+        // process any encoding to make sure the chars get transformed into the 
+        // correct byte types. 
+        try {
+            String charset = getCharSet(ds.getContentType());
+            reader = new InputStreamReader(is, charset);
+        } catch (Exception ex) {
+            throw new UnsupportedEncodingException(ex.toString());
+        }
+        StringBuffer result = new StringBuffer(1024);
+        char[] buffer = new char[32768];
+        int count;
+        while ((count = reader.read(buffer)) > 0) {
+            result.append(buffer, 0, count);
+        }
+        return result.toString();
+    }
+
+    
+    /**
+     * Write an object of "our" type out to the provided 
+     * output stream.  The content type might modify the 
+     * result based on the content type parameters. 
+     * 
+     * @param object The object to write.
+     * @param contentType
+     *               The content mime type, including parameters.
+     * @param outputstream
+     *               The target output stream.
+     * 
+     * @throws IOException
+     */
+    public void writeTo(Object o, String contentType, OutputStream outputstream) throws IOException {
+        String s;
+        if (o instanceof String) {
+            s = (String) o;
+        } else if (o != null) {
+            s = o.toString();
+        } else {
+            return;
+        }
+        // process any encoding to make sure the chars get transformed into the 
+        // correct byte types. 
+        OutputStreamWriter writer;
+        try {
+            String charset = getCharSet(contentType);
+            writer = new OutputStreamWriter(outputstream, charset);
+        } catch (Exception ex) {
+            ex.printStackTrace(); 
+            throw new UnsupportedEncodingException(ex.toString());
+        }
+        writer.write(s);
+        writer.flush();
+    }
+    
+
+    /**
+     * get the character set from content type
+     * @param contentType
+     * @return
+     * @throws ParseException
+     */
+    protected String getCharSet(String contentType) throws Exception {
+        ContentType type = new ContentType(contentType);
+        String charset = type.getParameter("charset");
+        if (charset == null) {
+            charset = "us-ascii";
+        }
+        return MimeUtility.javaCharset(charset);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java
new file mode 100644
index 0000000..6cc4d76
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java
@@ -0,0 +1,29 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.Image;
+import javax.activation.ActivationDataFlavor;
+
+/**
+ * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
+ */
+public class ImageGifHandler extends AbstractImageHandler {
+    public ImageGifHandler() {
+        super(new ActivationDataFlavor(Image.class, "image/gif", "GIF Image"));
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java
new file mode 100644
index 0000000..c3623c8
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java
@@ -0,0 +1,29 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.Image;
+import javax.activation.ActivationDataFlavor;
+
+/**
+ * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
+ */
+public class ImageJpegHandler extends AbstractImageHandler {
+    public ImageJpegHandler() {
+        super(new ActivationDataFlavor(Image.class, "image/jpeg", "JPEG Image"));
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java
new file mode 100644
index 0000000..015953d
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java
@@ -0,0 +1,65 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.activation.ActivationDataFlavor;
+import javax.activation.DataContentHandler;
+import javax.activation.DataSource;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMultipart;
+
+/**
+ * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
+ */
+public class MultipartHandler implements DataContentHandler {
+    private final DataFlavor flavour;
+
+    public MultipartHandler() {
+        flavour = new ActivationDataFlavor(MimeMultipart.class, "multipart/mixed", "Multipart MIME");
+    }
+
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[]{flavour};
+    }
+
+    public Object getTransferData(DataFlavor df, DataSource ds) throws UnsupportedFlavorException, IOException {
+        return flavour.equals(df) ? getContent(ds) : null;
+    }
+
+    public Object getContent(DataSource ds) throws IOException {
+        try {
+            return new MimeMultipart(ds);
+        } catch (MessagingException e) {
+            throw (IOException) new IOException(e.getMessage()).initCause(e);
+        }
+    }
+
+    public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
+        if (obj instanceof MimeMultipart) {
+            MimeMultipart mp = (MimeMultipart) obj;
+            try {
+                mp.writeTo(os);
+            } catch (MessagingException e) {
+                throw (IOException) new IOException(e.getMessage()).initCause(e);
+            }
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java
new file mode 100644
index 0000000..1df03d3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java
@@ -0,0 +1,120 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+import javax.activation.ActivationDataFlavor;
+import javax.activation.DataContentHandler;
+import javax.activation.DataSource;
+import javax.mail.Message;
+import javax.mail.MessageAware;
+import javax.mail.MessageContext;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+
+/**
+ * Content handler for RFC-822 compliant messages.
+ * @version $Rev: 824701 $ $Date: 2009-10-13 07:25:59 -0400 (Tue, 13 Oct 2009) $
+ */
+public class RFC822MessageHandler implements DataContentHandler {
+    // the data flavor defines what this looks like, and is fixed once the
+    // handler is instantiated
+    protected final DataFlavor flavour;
+
+    public RFC822MessageHandler() {
+        flavour = new ActivationDataFlavor(Message.class, "message/rfc822", "Message");
+    }
+
+    /**
+     * Return all of the flavors processed by this handler.  This
+     * is just the singleton flavor.
+     *
+     * @return An array of the transfer flavors supported by this handler.
+     */
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[] { flavour };
+    }
+
+    /**
+     * Retrieve the transfer data from the data source, but
+     * only if the requested flavor matches what we support.
+     *
+     * @param df     The requested data flavor.
+     * @param ds     The source DataSource.
+     *
+     * @return The extracted content object, or null if there is a
+     *         mismatch of flavors.
+     * @exception UnsupportedFlavorException
+     * @exception IOException
+     */
+    public Object getTransferData(DataFlavor df, DataSource ds) throws UnsupportedFlavorException, IOException {
+        return flavour.equals(df) ? getContent(ds) : null;
+    }
+
+    /**
+     * Extract the RFC822 Message content from a DataSource.
+     *
+     * @param ds     The source data source.
+     *
+     * @return An extracted MimeMessage object.
+     * @exception IOException
+     */
+    public Object getContent(DataSource ds) throws IOException {
+        try {
+            // creating a MimeMessage instance requires a session.  If the DataSource
+            // is a MessageAware one, we can get the session information from the MessageContext.
+            // This is generally the case, but if it is not available, then just retrieve
+            // the default instance and use it.
+            if (ds instanceof MessageAware) {
+                MessageContext context = ((MessageAware)ds).getMessageContext();
+                return new MimeMessage(context.getSession(), ds.getInputStream());
+            }
+            else {
+                return new MimeMessage(Session.getDefaultInstance(new Properties(), null), ds.getInputStream());
+            }
+        } catch (MessagingException e) {
+            throw (IOException) new IOException(e.getMessage()).initCause(e);
+        }
+    }
+
+    /**
+     * Write an RFC 822 message object out to an output stream.
+     *
+     * @param obj      The source message object.
+     * @param mimeType The target mimetype
+     * @param os       The target output stream.
+     *
+     * @exception IOException
+     */
+    public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
+        // we only handle message instances here
+        if (obj instanceof Message) {
+            Message message = (Message) obj;
+            try {
+                message.writeTo(os);
+            } catch (MessagingException e) {
+                throw (IOException) new IOException(e.getMessage()).initCause(e);
+            }
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java
new file mode 100644
index 0000000..59a802e
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java
@@ -0,0 +1,29 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import javax.activation.ActivationDataFlavor;
+
+
+/**
+ * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
+ */
+public class TextHtmlHandler extends AbstractTextHandler {
+    public TextHtmlHandler() {
+        super(new ActivationDataFlavor(String.class, "text/html", "HTML Text"));
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java
new file mode 100644
index 0000000..c2c3b97
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java
@@ -0,0 +1,29 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import javax.activation.ActivationDataFlavor;
+
+
+/**
+ * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
+ */
+public class TextPlainHandler extends AbstractTextHandler {
+    public TextPlainHandler() {
+        super(new ActivationDataFlavor(String.class, "text/plain", "Plain Text"));
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java
new file mode 100644
index 0000000..2fdb9d3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java
@@ -0,0 +1,29 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import javax.activation.ActivationDataFlavor;
+
+
+/**
+ * @version $Rev: 579145 $ $Date: 2007-09-25 05:16:58 -0400 (Tue, 25 Sep 2007) $
+ */
+public class TextXmlHandler extends AbstractTextHandler {
+    public TextXmlHandler() {
+        super(new ActivationDataFlavor(String.class, "text/xml", "XML Text"));
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java
new file mode 100644
index 0000000..ba9a179
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java
@@ -0,0 +1,93 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+/**
+ * A named access control list for IMAP resources.  
+ */
+public class ACL implements Cloneable {
+    /**
+     * The name of the resource this ACL applies to.
+     */
+    private String name; 
+    /**
+     * The rights associated with this resource.
+     */
+    private Rights rights;
+    
+    /**
+     * Create an ACL for a resource.  The ACL will have an empty Rights set.
+     * 
+     * @param name   The name of the resource.
+     */
+    public ACL(String name) {
+        this.name = name; 
+        this.rights = new Rights(); 
+    }
+    
+    /**
+     * Create a named ACL instance with an initial Rights set.
+     * 
+     * @param name   The name of the resouce this ACL applies to.
+     * @param rights The Rights associated with this resource.
+     */
+    public ACL(String name, Rights rights) {
+        this.name = name; 
+        this.rights = rights;  
+    }
+    
+    /**
+     * Get the ACL name.
+     * 
+     * @return The string name of the ACL.
+     */
+    public String getName() {
+        return name; 
+    }
+    
+    /**
+     * Get the Rights associated with this ACL.
+     * 
+     * @return The Rights set supported for this resource.
+     */
+    public Rights getRights() {
+        return rights; 
+    }
+    
+    /**
+     * Set a new set of Rights for this ACL instance.
+     * 
+     * @param rights The new Rights set.
+     */
+    public void setRights(Rights rights) {
+        this.rights = rights;         
+    }
+    
+    
+    /**
+     * Creates and returns a copy of this object. 
+     * 
+     * @return A cloned copy of this object.  This is a deep 
+     *         copy, given that a new Rights set is also created.
+     * @exception CloneNotSupportedException
+     */
+    protected Object clone() throws CloneNotSupportedException {
+        return new ACL(name, new Rights(rights)); 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java
new file mode 100644
index 0000000..03fc82e
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java
@@ -0,0 +1,125 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import javax.activation.DataHandler;
+
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
+
+/**
+ * A nested message attachement inside of another 
+ * IMAP message.  This is a less-functional version 
+ * of the top-level message.
+ */
+public class IMAPAttachedMessage extends IMAPMessage {
+    // the parent enclosing message.
+    protected IMAPMessage parent;
+
+    /**
+     * Constructor for an attached message part.
+     * 
+     * @param parent   The parent message (outer-most message).
+     * @param section  The section identifier for this embedded part
+     *                 in IMAP section format.  This will identify
+     *                 the part hierarchy used to locate this part within
+     *                 the message.
+     * @param envelope The Envelope that describes this part.
+     * @param bodyStructure
+     *                 The Body structure element that describes this part.
+     */
+    public IMAPAttachedMessage(IMAPMessage parent, String section, IMAPEnvelope envelope, IMAPBodyStructure bodyStructure) {
+        super((IMAPFolder)parent.getFolder(), parent.store, parent.getMessageNumber(), parent.sequenceNumber);
+        this.parent = parent;
+        // sets the subset we're looking for 
+        this.section = section;
+        // the envelope and body structure are loaded from the server by the parent 
+        this.envelope = envelope;
+        this.bodyStructure = bodyStructure;
+    }
+
+    /**
+     * Check if this message is still valid.  This is 
+     * delegated to the outer-most message.
+     * 
+     * @exception MessagingException
+     */
+    protected void checkValidity() throws MessagingException {
+        parent.checkValidity();
+    }
+
+    /**
+     * Check if the outer-most message has been expunged.
+     * 
+     * @return true if the message has been expunged.
+     */
+    public boolean isExpunged() {
+        return parent.isExpunged();
+    }
+
+    /**
+     * Get the size of this message part.
+     * 
+     * @return The estimate size of this message part, in bytes.
+     */
+    public int getSize() {
+        return bodyStructure.bodySize;
+    }
+
+    
+    /**
+     * Return a copy the flags associated with this message.
+     *
+     * @return a copy of the flags for this message
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public Flags getFlags() throws MessagingException {
+        return parent.getFlags(); 
+    }
+
+
+    /**
+     * Check whether the supplied flag is set.
+     * The default implementation checks the flags returned by {@link #getFlags()}.
+     *
+     * @param flag the flags to check for
+     * @return true if the flags is set
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public boolean isSet(Flags.Flag flag) throws MessagingException {
+        // load the flags, if needed 
+        return parent.isSet(flag); 
+    }
+
+    /**
+     * Set or clear a flag value.
+     *
+     * @param flags  The set of flags to effect.
+     * @param set    The value to set the flag to (true or false).
+     *
+     * @exception MessagingException
+     */
+    public void setFlags(Flags flag, boolean set) throws MessagingException {
+        throw new MethodNotSupportedException("Flags cannot be set on message attachements"); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java
new file mode 100644
index 0000000..62b7fd7
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java
@@ -0,0 +1,2393 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import javax.mail.*;
+import javax.mail.event.ConnectionEvent;
+import javax.mail.event.FolderEvent;
+import javax.mail.event.MessageChangedEvent;
+import javax.mail.search.FlagTerm;
+import javax.mail.search.SearchTerm;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchDataItem;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchResponse;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPFlags;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPListResponse;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPMailboxStatus;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPSizeResponse;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPUid;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponse;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponseHandler;
+
+/**
+ * The base IMAP implementation of the javax.mail.Folder
+ * This is a base class for both the Root IMAP server and each IMAP group folder.
+ * @see javax.mail.Folder
+ *
+ * @version $Rev: 761642 $
+ */
+public class IMAPFolder extends Folder implements UIDFolder, IMAPUntaggedResponseHandler {
+
+    /**
+     * Special profile item used for fetching SIZE and HEADER information.
+     * These items are extensions that Sun has added to their IMAPFolder immplementation.
+     * We're supporting the same set.
+     */
+    public static class FetchProfileItem extends FetchProfile.Item {
+        public static final FetchProfileItem HEADERS = new FetchProfileItem("HEADERS");
+        public static final FetchProfileItem SIZE = new FetchProfileItem("SIZE");
+
+        protected FetchProfileItem(String name) {
+            super(name);
+        }
+    }
+
+    // marker that we don't know the separator yet for this folder.
+    // This occurs when we obtain a folder reference from the
+    // default folder.  At that point, we've not queried the
+    // server for specifics yet.
+    static final protected char UNDETERMINED = 0;
+
+    // our attached session
+    protected Session session;
+    // retrieved messages, mapped by sequence number.
+    protected Map messageCache;
+    // mappings of UIDs to retrieved messages.
+    protected Map uidCache;
+
+    // the separator the server indicates is used as the hierarchy separator
+    protected char separator;
+    // the "full" name of the folder.  This is the fully qualified path name for the folder returned by
+    // the IMAP server.  Elements of the hierarchy are delimited by "separator" characters.
+    protected String fullname;
+    // the name of this folder.  The is the last element of the fully qualified name.
+    protected String name;
+    // the folder open state
+	protected boolean folderOpen = false;
+    // the type information on what the folder can hold
+    protected int folderType;
+    // the subscription status
+    protected boolean subscribed = false;
+
+    // the message identifier ticker, used to assign message numbers.
+    protected int nextMessageID = 1;
+    // the current count of messages in our cache.
+    protected int maxSequenceNumber = 0;
+    // the reported count of new messages (updated as a result of untagged message resposes)
+    protected int recentMessages = -1;
+    // the reported count of unseen messages
+    protected int unseenMessages = 0;
+    // the uidValidity value reported back from the server
+    protected long uidValidity = 0;
+    // the uidNext value reported back from the server
+    protected long uidNext = 0;
+    // the persistent flags we save in the store
+    protected Flags permanentFlags;
+    // the settable flags the server reports back to us
+    protected Flags availableFlags;
+    // Our cached status information.  We will only hold this for the timeout interval.
+    protected IMAPMailboxStatus cachedStatus;
+    // Folder information retrieved from the server.  Good info here indicates the
+    // folder exists.
+    protected IMAPListResponse listInfo;
+    // the configured status cache timeout value.
+    protected long statusCacheTimeout;
+    // the last time we took a status snap shot.
+    protected long lastStatusTimeStamp;
+    // Our current connection.  We get one of these when opened, and release it when closed.
+    // We do this because for any folder (and message) operations, the folder must be selected on
+    // the connection.
+    // Note, however, that there are operations which will require us to borrow a connection
+    // temporarily because we need to touch the server when the folder is not open.  In those
+    // cases, we grab a connection, then immediately return it to the pool.
+    protected IMAPConnection currentConnection;
+
+
+
+    /**
+     * Super class constructor the base IMAPFolder class.
+     *
+     * @param store     The javamail store this folder is attached to.
+     * @param fullname  The fully qualified name of this folder.
+     * @param separator The separtor character used to delimit the different
+     *                  levels of the folder hierarchy.  This is used to
+     *                  decompose the full name into smaller parts and
+     *                  create the names of subfolders.
+     */
+	protected IMAPFolder(IMAPStore store, String fullname, char separator) {
+		super(store);
+		this.session = store.getSession();
+        this.fullname = fullname;
+        this.separator = separator;
+        // get the status timeout value from the folder.
+        statusCacheTimeout = store.statusCacheTimeout;
+	}
+
+    /**
+     * Retrieve the folder name.  This is the simple folder
+     * name at the its hiearchy level.  This can be invoked when the folder is closed.
+     *
+     * @return The folder's name.
+     */
+	public String getName() {
+        // At the time we create the folder, we might not know the separator character yet.
+        // Because of this we need to delay creating the name element until
+        // it's required.
+        if (name == null) {
+            // extract the name from the full name
+            int lastLevel = -1;
+            try {
+                lastLevel = fullname.lastIndexOf(getSeparator());
+            } catch (MessagingException e) {
+                // not likely to occur, but the link could go down before we
+                // get this.  Just assume a failure to locate the character
+                // occurred.
+            }
+            if (lastLevel == -1) {
+                name = fullname;
+            }
+            else {
+                name = fullname.substring(lastLevel + 1);
+            }
+        }
+        return name;
+	}
+
+    /**
+     * Retrieve the folder's full name (including hierarchy information).
+     * This can be invoked when the folder is closed.
+     *
+     * @return The full name value.
+     */
+	public String getFullName() {
+        return fullname;
+	}
+
+
+
+    /**
+     * Return the parent for this folder; if the folder is at the root of a heirarchy
+     * this returns null.
+     * This can be invoked when the folder is closed.
+     *
+     * @return this folder's parent
+     * @throws MessagingException
+     */
+	public Folder getParent() throws MessagingException {
+        // NB:  We need to use the method form because the separator
+        // might not have been retrieved from the server yet.
+        char separator = getSeparator();
+        // we don't hold a reference to the parent folder, as that would pin the instance in memory
+        // as long as any any leaf item in the hierarchy is still open.
+        int lastLevel = fullname.lastIndexOf(separator);
+        // no parent folder?  Get the root one from the Store.
+        if (lastLevel == -1) {
+            return ((IMAPStore)store).getDefaultFolder();
+        }
+        else {
+            // create a folder for the parent.
+            return new IMAPFolder((IMAPStore)store, fullname.substring(0, lastLevel), separator);
+        }
+	}
+
+
+    /**
+     * Check to see if this folder physically exists in the store.
+     * This can be invoked when the folder is closed.
+     *
+     * @return true if the folder really exists
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public synchronized boolean exists() throws MessagingException {
+        IMAPConnection connection = getConnection();
+        try {
+            return checkExistance(connection);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Internal routine for checking existance using an
+     * already obtained connection.  Used for situations
+     * where the list information needs updating but
+     * we'd end up acquiring a new connection because
+     * the folder isn't open yet.
+     *
+     * @param connection The connection to use.
+     *
+     * @return true if the folder exists, false for non-existence.
+     * @exception MessagingException
+     */
+    private boolean checkExistance(IMAPConnection connection) throws MessagingException {
+        // get the list response for this folder.
+        List responses = connection.list("", fullname);
+        // NB, this grabs the latest information and updates
+        // the type information also.  Note also that we need to
+        // use the mailbox name, not the full name.  This is so
+        // the namespace folders will return the correct response.
+        listInfo = findListResponse(responses, getMailBoxName());
+
+        if (listInfo == null) {
+            return false;
+        }
+
+        // update the type information from the status.
+        folderType = 0;
+        if (!listInfo.noinferiors) {
+            folderType |= HOLDS_FOLDERS;
+        }
+        if (!listInfo.noselect) {
+            folderType |= HOLDS_MESSAGES;
+        }
+
+        // also update the separator information.  This will allow
+        // use to skip a call later
+        separator = listInfo.separator;
+        // this can be omitted in the response, so assume a default
+        if (separator == '\0') {
+            separator = '/';
+        }
+
+        // updated ok, so it must be there.
+        return true;
+    }
+
+
+
+    /**
+     * Return a list of folders from this Folder's namespace that match the supplied pattern.
+     * Patterns may contain the following wildcards:
+     * <ul><li>'%' which matches any characater except hierarchy delimiters</li>
+     * <li>'*' which matches any character including hierarchy delimiters</li>
+     * </ul>
+     * This can be invoked when the folder is closed.
+     *
+     * @param pattern the pattern to search for
+     *
+     * @return a possibly empty array containing Folders that matched the pattern
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public synchronized Folder[] list(String pattern) throws MessagingException {
+        // go filter the folders based on the pattern.  The server does most of the
+        // heavy lifting on the pattern matching.
+        return filterFolders(pattern, false);
+    }
+
+
+    /**
+     * Return a list of folders to which the user is subscribed and which match the supplied pattern.
+     * If the store does not support the concept of subscription then this should match against
+     * all folders; the default implementation of this method achieves this by defaulting to the
+     * {@link #list(String)} method.
+     *
+     * @param pattern the pattern to search for
+     *
+     * @return a possibly empty array containing subscribed Folders that matched the pattern
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public synchronized Folder[] listSubscribed(String pattern) throws MessagingException {
+        // go filter the folders based on the pattern.  The server does most of the
+        // heavy lifting on the pattern matching.
+        return filterFolders(pattern, true);
+    }
+
+
+    /**
+     * Return the character used by this folder's Store to separate path components.
+     *
+     * @return the name separater character
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized char getSeparator() throws MessagingException {
+        // not determined yet, we need to ask the server for the information
+        if (separator == UNDETERMINED) {
+            IMAPConnection connection = getConnection();
+            try {
+                List responses = connection.list("", fullname);
+                IMAPListResponse info = findListResponse(responses, fullname);
+
+                // if we didn't get any hits, then we just assume a reasonable default.
+                if (info == null) {
+                    separator = '/';
+                }
+                else {
+                    separator = info.separator;
+                    // this can be omitted in the response, so assume a default
+                    if (separator == '\0') {
+                        separator = '/';
+                    }
+                }
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+        return separator;
+	}
+
+
+    /**
+     * Return whether this folder can hold just messages or also
+     * subfolders.
+     *
+     * @return The combination of Folder.HOLDS_MESSAGES and Folder.HOLDS_FOLDERS, depending
+     * on the folder capabilities.
+     * @exception MessagingException
+     */
+	public int getType() throws MessagingException {
+        // checking the validity will update the type information
+        // if it succeeds.
+        checkFolderValidity();
+		return folderType;
+	}
+
+
+    /**
+     * Create a new folder capable of containing subfolder and/or messages as
+     * determined by the type parameter. Any hierarchy defined by the folder
+     * name will be recursively created.
+     * If the folder was sucessfully created, a {@link FolderEvent#CREATED CREATED FolderEvent}
+     * is sent to all FolderListeners registered with this Folder or with the Store.
+     *
+     * @param newType the type, indicating if this folder should contain subfolders, messages or both
+     *
+     * @return true if the folder was sucessfully created
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+	public synchronized boolean create(int newType) throws MessagingException {
+        IMAPConnection connection = getConnection();
+        try {
+
+            // by default, just create using the fullname.
+            String newPath = fullname;
+
+            // if this folder is expected to only hold additional folders, we need to
+            // add a separator on to the end when we create this.
+            if ((newType & HOLDS_MESSAGES) == 0) {
+                newPath = fullname + separator;
+            }
+            try {
+                // go create this
+                connection.createMailbox(newPath);
+                // verify this exists...also updates some of the status
+                boolean reallyCreated = checkExistance(connection);
+                // broadcast a creation event.
+                notifyFolderListeners(FolderEvent.CREATED);
+                return reallyCreated;
+            } catch (MessagingException e) {
+                //TODO add folder level debug logging.
+            }
+            // we have a failure
+            return false;
+        } finally {
+            releaseConnection(connection);
+        }
+	}
+
+
+    /**
+     * Return the subscription status of this folder.
+     *
+     * @return true if the folder is marked as subscribed, false for
+     *         unsubscribed.
+     */
+    public synchronized boolean isSubscribed() {
+        try {
+            IMAPConnection connection = getConnection();
+            try {
+                // get the lsub response for this folder.
+                List responses = connection.listSubscribed("", fullname);
+
+                IMAPListResponse response = findListResponse(responses, fullname);
+                if (response == null) {
+                    return false;
+                }
+                else {
+                    // a NOSELECT flag response indicates the mailbox is no longer
+                    // selectable, so it's also no longer subscribed to.
+                    return !response.noselect;
+                }
+            } finally {
+                releaseConnection(connection);
+            }
+        } catch (MessagingException e) {
+            // Can't override to throw a MessagingException on this method, so
+            // just swallow any exceptions and assume false is the answer.
+        }
+        return false;
+    }
+
+
+    /**
+     * Set or clear the subscription status of a file.
+     *
+     * @param flag
+     *            The new subscription state.
+     */
+    public synchronized void setSubscribed(boolean flag) throws MessagingException {
+        IMAPConnection connection = getConnection();
+        try {
+            if (flag) {
+                connection.subscribe(fullname);
+            }
+            else {
+                connection.unsubscribe(fullname);
+            }
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Check to see if this Folder conatins messages with the {@link Flag.RECENT} flag set.
+     * This can be used when the folder is closed to perform a light-weight check for new mail;
+     * to perform an incremental check for new mail the folder must be opened.
+     *
+     * @return true if the Store has recent messages
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized boolean hasNewMessages() throws MessagingException {
+        // the folder must exist for this to work.
+        checkFolderValidity();
+
+        // get the freshest status information.
+        refreshStatus(true);
+        // return the indicator from the message state.
+        return recentMessages > 0;
+	}
+
+    /**
+     * Get the Folder determined by the supplied name; if the name is relative
+     * then it is interpreted relative to this folder. This does not check that
+     * the named folder actually exists.
+     *
+     * @param name the name of the folder to return
+     * @return the named folder
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        // this must be a real, valid folder to hold a subfolder
+        checkFolderValidity();
+        if (!holdsFolders()) {
+            throw new MessagingException("Folder " + fullname + " cannot hold subfolders");
+        }
+        // our separator does not get determined until we ping the server for it.  We
+        // might need to do that now, so we need to use the getSeparator() method to retrieve this.
+        char separator = getSeparator();
+
+        return new IMAPFolder((IMAPStore)store, fullname + separator + name, separator);
+    }
+
+
+    /**
+     * Delete this folder and possibly any subfolders. This operation can only be
+     * performed on a closed folder.
+     * If recurse is true, then all subfolders are deleted first, then any messages in
+     * this folder are removed and it is finally deleted; {@link FolderEvent#DELETED}
+     * events are sent as appropriate.
+     * If recurse is false, then the behaviour depends on the folder type and store
+     * implementation as followd:
+     * <ul>
+     * <li>If the folder can only conrain messages, then all messages are removed and
+     * then the folder is deleted; a {@link FolderEvent#DELETED} event is sent.</li>
+     * <li>If the folder can onlu contain subfolders, then if it is empty it will be
+     * deleted and a {@link FolderEvent#DELETED} event is sent; if the folder is not
+     * empty then the delete fails and this method returns false.</li>
+     * <li>If the folder can contain both subfolders and messages, then if the folder
+     * does not contain any subfolders, any messages are deleted, the folder itself
+     * is deleted and a {@link FolderEvent#DELETED} event is sent; if the folder does
+     * contain subfolders then the implementation may choose from the following three
+     * behaviors:
+     * <ol>
+     * <li>it may return false indicting the operation failed</li>
+     * <li>it may remove all messages within the folder, send a {@link FolderEvent#DELETED}
+     * event, and then return true to indicate the delete was performed. Note this does
+     * not delete the folder itself and the {@link #exists()} operation for this folder
+     * will return true</li>
+     * <li>it may remove all messages within the folder as per the previous option; in
+     * addition it may change the type of the Folder to only HOLDS_FOLDERS indictaing
+     * that messages may no longer be added</li>
+     * </li>
+     * </ul>
+     * FolderEvents are sent to all listeners registered with this folder or
+     * with the Store.
+     *
+     * @param recurse whether subfolders should be recursively deleted as well
+     * @return true if the delete operation succeeds
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized boolean delete(boolean recurse) throws MessagingException {
+        // we must be in the closed state.
+        checkClosed();
+
+        // if recursive, get the list of subfolders and delete them first.
+        if (recurse) {
+
+            Folder[] subfolders = list();
+            for (int i = 0; i < subfolders.length; i++) {
+                // this is a recursive delete also
+                subfolders[i].delete(true);
+            }
+        }
+
+        IMAPConnection connection = getConnection();
+        try {
+            // delete this one now.
+            connection.deleteMailbox(fullname);
+            // this folder no longer exists on the server.
+            listInfo = null;
+
+            // notify interested parties about the deletion.
+            notifyFolderListeners(FolderEvent.DELETED);
+            return true;
+
+        } catch (MessagingException e) {
+            // ignored
+        } finally {
+            releaseConnection(connection);
+        }
+        return false;
+	}
+
+
+    /**
+     * Rename this folder; the folder must be closed.
+     * If the rename is successfull, a {@link FolderEvent#RENAMED} event is sent to
+     * all listeners registered with this folder or with the store.
+     *
+     * @param newName the new name for this folder
+     * @return true if the rename succeeded
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized boolean renameTo(Folder f) throws MessagingException {
+        // we must be in the closed state.
+        checkClosed();
+        // but we must also exist
+        checkFolderValidity();
+
+        IMAPConnection connection = getConnection();
+        try {
+            // delete this one now.
+            connection.renameMailbox(fullname, f.getFullName());
+            // we renamed, so get a fresh set of status
+            refreshStatus(false);
+
+            // notify interested parties about the deletion.
+            notifyFolderRenamedListeners(f);
+            return true;
+        } catch (MessagingException e) {
+            // ignored
+        } finally {
+            releaseConnection(connection);
+        }
+        return false;
+	}
+
+
+    /**
+     * Open this folder; the folder must be able to contain messages and
+     * must currently be closed. If the folder is opened successfully then
+     * a {@link ConnectionEvent#OPENED} event is sent to listeners registered
+     * with this Folder.
+     * <p/>
+     * Whether the Store allows multiple connections or if it allows multiple
+     * writers is implementation defined.
+     *
+     * @param mode READ_ONLY or READ_WRITE
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized void open(int mode) throws MessagingException {
+
+        // we use a synchronized block rather than use a synchronized method so that we
+        // can notify the event listeners while not holding the lock.
+        synchronized(this) {
+            // can only be performed on a closed folder
+            checkClosed();
+            // ask the store to kindly hook us up with a connection.
+            // We're going to hang on to this until we're closed, so store it in
+            // the Folder field.  We need to make sure our mailbox is selected while
+            // we're working things.
+            currentConnection = ((IMAPStore)store).getFolderConnection(this);
+            // we need to make ourselves a handler of unsolicited responses
+            currentConnection.addResponseHandler(this);
+            // record our open mode
+            this.mode = mode;
+
+
+            try {
+                // try to open, which gives us a lot of initial mailbox state.
+                IMAPMailboxStatus status = currentConnection.openMailbox(fullname, mode == Folder.READ_ONLY);
+
+                // not available in the requested mode?
+                if (status.mode != mode) {
+                    // trying to open READ_WRITE and this isn't available?
+                    if (mode == READ_WRITE) {
+                        throw new ReadOnlyFolderException(this, "Cannot open READ_ONLY folder in READ_WRITE mode");
+                    }
+                }
+
+                // save this status and when we got it for later updating.
+                cachedStatus = status;
+                // mark when we got this
+                lastStatusTimeStamp = System.currentTimeMillis();
+
+                // now copy the status information over and flip over the open sign.
+                this.mode = status.mode;
+                maxSequenceNumber = status.messages;
+                recentMessages = status.recentMessages;
+                uidValidity = status.uidValidity;
+                uidNext = status.uidNext;
+
+                availableFlags = status.availableFlags;
+                permanentFlags = status.permanentFlags;
+
+                // create a our caches.  These are empty initially
+                messageCache = new HashMap();
+                uidCache = new HashMap();
+
+                // we're open for business folks!
+                folderOpen = true;
+                notifyConnectionListeners(ConnectionEvent.OPENED);
+            } finally {
+                // NB:  this doesn't really release this, but it does drive
+                // the processing of any unsolicited responses.
+                releaseConnection(currentConnection);
+            }
+        }
+	}
+
+
+    /**
+     * Close this folder; it must already be open.
+     * A  @link ConnectionEvent#CLOSED} event is sent to all listeners registered
+     {*
+     * with this folder.
+     *
+     * @param expunge whether to expunge all deleted messages
+     * @throws MessagingException if there was a problem accessing the store; the folder is still closed
+     */
+	public synchronized void close(boolean expunge) throws MessagingException {
+		// Can only be performed on an open folder
+		checkOpen();
+        cleanupFolder(expunge, false);
+	}
+
+
+    /**
+     * Do folder cleanup.  This is used both for normal
+     * close operations, and adnormal closes where the
+     * server has sent us a BYE message.
+     *
+     * @param expunge Indicates whether open messages should be expunged.
+     * @param disconnected
+     *                The disconnected flag.  If true, the server has cut
+     *                us off, which means our connection can not be returned
+     *                to the connection pool.
+     *
+     * @exception MessagingException
+     */
+    protected void cleanupFolder(boolean expunge, boolean disconnected) throws MessagingException {
+		folderOpen = false;
+        uidCache = null;
+        messageCache = null;
+        // if we have a connection active at the moment
+        if (currentConnection != null) {
+            // was this a forced disconnect by the server?
+            if (disconnected) {
+                currentConnection.setClosed();
+            }
+            else {
+                // The CLOSE operation depends on what mode was used to select the mailbox.
+                // If we're open in READ-WRITE mode, we used a SELECT operation.  When CLOSE
+                // is issued, any deleted messages will be expunged.  If we've been asked not
+                // to expunge the messages, we have a problem.  The solution is to reselect the
+                // mailbox using EXAMINE, which will not expunge messages when closed.
+                if (mode == READ_WRITE && !expunge) {
+                    // we can ignore the result...we're just switching modes.
+                    currentConnection.openMailbox(fullname, true);
+                }
+
+                // have this close the selected mailbox
+                currentConnection.closeMailbox();
+            }
+            currentConnection.removeResponseHandler(this);
+            // we need to release the connection to the Store once we're closed
+            ((IMAPStore)store).releaseFolderConnection(this, currentConnection);
+            currentConnection = null;
+        }
+		notifyConnectionListeners(ConnectionEvent.CLOSED);
+    }
+
+
+    /**
+     * Tests the open status of the folder.
+     *
+     * @return true if the folder is open, false otherwise.
+     */
+	public boolean isOpen() {
+		return folderOpen;
+	}
+
+    /**
+     * Get the permanentFlags
+     *
+     * @return The set of permanent flags we support (only SEEN).
+     */
+	public synchronized Flags getPermanentFlags() {
+        if (permanentFlags != null) {
+            // we need a copy of our master set.
+            return new Flags(permanentFlags);
+        }
+        else {
+            // a null return is expected if not there.
+            return null;
+        }
+	}
+
+
+    /**
+     * Return the number of messages this folder contains.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     *
+     * @return the number of messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized int getMessageCount() throws MessagingException {
+        checkFolderValidity();
+
+        // if we haven't opened the folder yet, we might not have good status information.
+        // go request some, which updates the folder fields also.
+        refreshStatus(false);
+		return maxSequenceNumber;
+	}
+
+    /**
+     * Return the numbew of messages in this folder that have the {@link Flag.RECENT} flag set.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     * The default implmentation of this method iterates over all messages
+     * in the folder; subclasses should override if possible to provide a more
+     * efficient implementation.
+     *
+     * NB:  This is an override of the default Folder implementation, which
+     * examines each of the messages in the folder.  IMAP has more efficient
+     * mechanisms for grabbing the information.
+     *
+     * @return the number of new messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public synchronized int getNewMessageCount() throws MessagingException {
+        // the folder must be a real one for this to work.
+        checkFolderValidity();
+        // now get current status from the folder
+        refreshStatus(false);
+        // this should be current now.
+        return recentMessages;
+    }
+
+
+
+    /**
+     * Return the number of messages in this folder that do not have the {@link Flag.SEEN} flag set.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     * The default implmentation of this method iterates over all messages
+     * in the folder; subclasses should override if possible to provide a more
+     * efficient implementation.
+     *
+     * NB:  This is an override of the default Folder implementation, which
+     * examines each of the messages in the folder.  IMAP has more efficient
+     * mechanisms for grabbing the information.
+     *
+     * @return the number of new messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized int getUnreadMessageCount() throws MessagingException {
+        checkFolderValidity();
+        // if we haven't opened the folder yet, we might not have good status information.
+        // go request some, which updates the folder fields also.
+        if (!folderOpen) {
+            refreshStatus(false);
+        }
+        else {
+            // if we have an open connection, then search the folder for any messages
+            // marked UNSEEN.
+
+            // UNSEEN is a false test on SEEN using the search criteria.
+            SearchTerm criteria = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
+
+            // ask the store to kindly hook us up with a connection.
+            IMAPConnection connection = getConnection();
+            try {
+                // search using the connection directly rather than calling our search() method so we don't
+                // need to instantiate each of the matched messages.  We're really only interested in the count
+                // right now.
+                int[] matches = connection.searchMailbox(criteria);
+                // update the unseen count.
+                unseenMessages = matches == null ? 0 : matches.length;
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+        // return our current message count.
+		return unseenMessages;
+	}
+
+
+
+    /**
+     * Return the number of messages in this folder that have the {@link Flag.DELETED} flag set.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     * The default implmentation of this method iterates over all messages
+     * in the folder; subclasses should override if possible to provide a more
+     * efficient implementation.
+     *
+     * @return the number of new messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized int getDeletedMessageCount() throws MessagingException {
+        checkFolderValidity();
+
+        // if we haven't opened the folder yet, we might not have good status information.
+        // go request some, which updates the folder fields also.
+        if (!folderOpen) {
+            // the status update doesn't return deleted messages.  These can only be obtained by
+            // searching an open folder.  Just return a bail-out response
+            return -1;
+        }
+        else {
+            // if we have an open connection, then search the folder for any messages
+            // marked DELETED.
+
+            // UNSEEN is a false test on SEEN using the search criteria.
+            SearchTerm criteria = new FlagTerm(new Flags(Flags.Flag.DELETED), true);
+
+            // ask the store to kindly hook us up with a connection.
+            IMAPConnection connection = getConnection();
+            try {
+                // search using the connection directly rather than calling our search() method so we don't
+                // need to instantiate each of the matched messages.  We're really only interested in the count
+                // right now.
+                int[] matches = connection.searchMailbox(criteria);
+                return matches == null ? 0 : matches.length;
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+	}
+
+
+    /**
+     * Retrieve the message with the specified index in this Folder;
+     * messages indices start at 1 not zero.
+     * Clients should note that the index for a specific message may change
+     * if the folder is expunged; {@link Message} objects should be used as
+     * references instead.
+     *
+     * @param msgNum The message sequence number of the target message.
+     *
+     * @return the message
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public synchronized Message getMessage(int msgNum) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        // Check the validity of the message number.  This may require pinging the server to
+        // see if there are new messages in the folder.
+        checkMessageValidity(msgNum);
+        // create the mapping key for this
+        Integer messageKey = new Integer(msgNum);
+        // ok, if the message number is within range, we should have this in the
+        // messages list.  Just return the element.
+        Message message = (Message)messageCache.get(messageKey);
+        // if not in the cache, create a dummy add it in.  The message body will be
+        // retrieved on demand
+        if (message == null) {
+            message = new IMAPMessage(this, ((IMAPStore)store), nextMessageID++, msgNum);
+            messageCache.put(messageKey, message);
+        }
+        return message;
+    }
+
+
+    /**
+     * Retrieve a range of messages for this folder.
+     * messages indices start at 1 not zero.
+     *
+     * @param start  Index of the first message to fetch, inclusive.
+     * @param end    Index of the last message to fetch, inclusive.
+     *
+     * @return An array of the fetched messages.
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public synchronized Message[] getMessages(int start, int end) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        Message[] messageRange = new Message[end - start + 1];
+
+        for (int i = 0; i < messageRange.length; i++) {
+            // NB:  getMessage() requires values that are origin 1, so there's
+            // no need to adjust the value by other than the start position.
+            messageRange[i] = getMessage(start + i);
+        }
+        return messageRange;
+    }
+
+
+    /**
+     * Append the supplied messages to this folder. A {@link MessageCountEvent} is sent
+     * to all listeners registered with this folder when all messages have been appended.
+     * If the array contains a previously expunged message, it must be re-appended to the Store
+     * and implementations must not abort this operation.
+     *
+     * @param msgs   The array of messages to append to the folder.
+     *
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+	public synchronized void appendMessages(Message[] msgs) throws MessagingException {
+        checkFolderValidity();
+        for (int i = 0; i < msgs.length; i++) {
+            Message msg = msgs[i];
+
+            appendMessage(msg);
+        }
+	}
+
+    /**
+     * Hint to the store to prefetch information on the supplied messages.
+     * Subclasses should override this method to provide an efficient implementation;
+     * the default implementation in this class simply returns.
+     *
+     * @param messages messages for which information should be fetched
+     * @param profile  the information to fetch
+     * @throws MessagingException if there was a problem accessing the store
+     * @see FetchProfile
+     */
+    public void fetch(Message[] messages, FetchProfile profile) throws MessagingException {
+
+        // we might already have the information being requested, so ask each of the
+        // messages in the list to evaluate itself against the profile.  We'll only ask
+        // the server to send information that's required.
+        List fetchSet = new ArrayList();
+
+        for (int i = 0; i < messages.length; i++) {
+            Message msg = messages[i];
+            // the message is missing some of the information still.  Keep this in the list.
+            // even if the message is only missing one piece of information, we still fetch everything.
+            if (((IMAPMessage)msg).evaluateFetch(profile)) {
+                fetchSet.add(msg);
+            }
+        }
+
+        // we've got everything already, no sense bothering the server
+        if (fetchSet.isEmpty()) {
+            return;
+        }
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+        try {
+            // ok, from this point onward, we don't want any threads messing with the
+            // message cache.  A single processed EXPUNGE could make for a very bad day
+            synchronized(this) {
+                // get the message set for this
+                String messageSet = generateMessageSet(fetchSet);
+                // fetch all of the responses
+                List responses = connection.fetch(messageSet, profile);
+
+                // IMPORTANT:  We must do our updates while synchronized to keep the
+                // cache from getting updated underneath us.   This includes
+                // not releasing the connection until we're done to delay processing any
+                // pending expunge responses.
+                for (int i = 0; i < responses.size(); i++) {
+                    IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
+                    Message msg = getMessage(response.getSequenceNumber());
+                    // Belt and Braces.  This should never be false.
+                    if (msg != null) {
+                        // have the message apply this to itself.
+                        ((IMAPMessage)msg).updateMessageInformation(response);
+                    }
+                }
+            }
+        } finally {
+            releaseConnection(connection);
+        }
+        return;
+    }
+
+    /**
+     * Set flags on the messages to the supplied value; all messages must belong to this folder.
+     * This method may be overridden by subclasses that can optimize the setting
+     * of flags on multiple messages at once; the default implementation simply calls
+     * {@link Message#setFlags(Flags, boolean)} for each supplied messages.
+     *
+     * @param messages whose flags should be set
+     * @param flags    the set of flags to modify
+     * @param set      Indicates whether the flags should be set or cleared.
+     *
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public void setFlags(Message[] messages, Flags flags, boolean set) throws MessagingException {
+        // this is a list of messages for the change broadcast after the update
+        List updatedMessages = new ArrayList();
+
+        synchronized(this) {
+            // the folder must be open and writeable.
+            checkOpenReadWrite();
+
+            // now make sure these are settable flags.
+            if (!availableFlags.contains(flags))
+            {
+                throw new MessagingException("The IMAP server does not support changing of this flag set");
+            }
+
+            // turn this into a set of message numbers
+            String messageSet = generateMessageSet(messages);
+            // if all of the messages have been expunged, nothing to do.
+            if (messageSet == null) {
+                return;
+            }
+            // ask the store to kindly hook us up with a connection.
+            IMAPConnection connection = getConnection();
+
+            try {
+                // and have the connection set this
+                List responses = connection.setFlags(messageSet, flags, set);
+                // retrieve each of the messages from our cache, and do the flag update.
+                // we need to keep the list so we can broadcast a change update event
+                // when we're finished.
+                for (int i = 0; i < responses.size(); i++) {
+                    IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
+
+                    // get the updated message and update the internal state.
+                    Message message = getMessage(response.sequenceNumber);
+                    // this shouldn't happen, but it might have been expunged too.
+                    if (message != null) {
+                        ((IMAPMessage)message).updateMessageInformation(response);
+                        updatedMessages.add(message);
+                    }
+                }
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+
+        // ok, we're no longer holding the lock.  Now go broadcast the update for each
+        // of the affected messages.
+        for (int i = 0; i < updatedMessages.size(); i++) {
+            Message message = (Message)updatedMessages.get(i);
+            notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, message);
+        }
+    }
+
+
+    /**
+     * Set flags on a range of messages to the supplied value.
+     * This method may be overridden by subclasses that can optimize the setting
+     * of flags on multiple messages at once; the default implementation simply
+     * gets each message and then calls {@link Message#setFlags(Flags, boolean)}.
+     *
+     * @param start  first message end set
+     * @param end    last message end set
+     * @param flags  the set of flags end modify
+     * @param value  Indicates whether the flags should be set or cleared.
+     *
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public synchronized void setFlags(int start, int end, Flags flags, boolean value) throws MessagingException {
+        Message[] msgs = new Message[end - start + 1];
+
+        for (int i = start; i <= end; i++) {
+            msgs[i] = getMessage(i);
+        }
+        // go do a bulk set operation on these messages
+        setFlags(msgs, flags, value);
+    }
+
+    /**
+     * Set flags on a set of messages to the supplied value.
+     * This method may be overridden by subclasses that can optimize the setting
+     * of flags on multiple messages at once; the default implementation simply
+     * gets each message and then calls {@link Message#setFlags(Flags, boolean)}.
+     *
+     * @param ids    the indexes of the messages to set
+     * @param flags  the set of flags end modify
+     * @param value  Indicates whether the flags should be set or cleared.
+     *
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+    public synchronized void setFlags(int ids[], Flags flags, boolean value) throws MessagingException {
+        Message[] msgs = new Message[ids.length];
+
+        for (int i = 0; i <ids.length; i++) {
+            msgs[i] = getMessage(ids[i]);
+        }
+        // go do a bulk set operation on these messages
+        setFlags(msgs, flags, value);
+    }
+
+
+    /**
+     * Copy the specified messages to another folder.
+     * The default implementation simply appends the supplied messages to the
+     * target folder using {@link #appendMessages(Message[])}.
+     * @param messages the messages to copy
+     * @param folder the folder to copy to
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public synchronized void copyMessages(Message[] messages, Folder folder) throws MessagingException {
+        // the default implementation just appends the messages to the target.  If
+        // we're copying between two folders of the same store, we can get the server to
+        // do most of the work for us without needing to fetch all of the message data.
+        // If we're dealing with two different Store instances, we need to do this the
+        // hardway.
+        if (getStore() != folder.getStore()) {
+            super.copyMessages(messages, folder);
+            return;
+        }
+
+        // turn this into a set of message numbers
+        String messageSet = generateMessageSet(messages);
+        // if all of the messages have been expunged, nothing to do.
+        if (messageSet == null) {
+            return;
+        }
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // ask the server to copy this information over to the other mailbox.
+            connection.copyMessages(messageSet, folder.getFullName());
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+
+    /**
+     * Permanently delete all supplied messages that have the DELETED flag set from the Store.
+     * The original message indices of all messages actually deleted are returned and a
+     * {@link MessageCountEvent} event is sent to all listeners with this folder. The expunge
+     * may cause the indices of all messaged that remain in the folder to change.
+     *
+     * @return the original indices of messages that were actually deleted
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public synchronized Message[] expunge() throws MessagingException {
+        // must be open to do this.
+        checkOpen();
+        // and changes need to be allowed
+        checkReadWrite();
+
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+        List expunges = null;
+
+        try {
+            // send the expunge notification.  This operation results in "nn EXPUNGE" responses getting returned
+            // for each expunged messages.  These will be dispatched to our response handler, which will process
+            // the expunge operation.  We could process this directly, but we may have received asynchronous
+            // expunge messages that also marked messages as expunged.
+            expunges = connection.expungeMailbox();
+        } finally {
+            releaseConnection(connection);
+        }
+
+        // we get one EXPUNGE message for each message that's expunged.  They MUST be processed in
+        // order, as the message sequence numbers represent a relative position that takes into account
+        // previous expunge operations.  For example, if message sequence numbers 5, 6, and 7 are
+        // expunged, we receive 3 expunge messages, all indicating that message 5 has been expunged.
+        Message[] messages = new Message[expunges.size()];
+
+        // now we need to protect the internal structures
+        synchronized (this) {
+            // expunge all of the messages from the message cache.  This keeps the sequence
+            // numbers up to-date.
+            for (int i = 0; i < expunges.size(); i++) {
+                IMAPSizeResponse response = (IMAPSizeResponse)expunges.get(i);
+                messages[i] = expungeMessage(response.getSize());
+            }
+        }
+        // if we have messages that have been removed, broadcast the notification.
+        if (messages.length > 0) {
+            notifyMessageRemovedListeners(true, messages);
+        }
+
+        // note, we're expected to return an array in all cases, even if the expunged count was zero.
+        return messages;
+	}
+
+
+
+    /**
+     * Search the supplied messages for those that match the supplied criteria;
+     * messages must belong to this folder.
+     * The default implementation iterates through the messages, returning those
+     * whose {@link Message#match(javax.mail.search.SearchTerm)} method returns true;
+     * subclasses may provide a more efficient implementation.
+     *
+     * @param term the search criteria
+     * @param messages the messages to search
+     * @return an array containing messages that match the criteria
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public synchronized Message[] search(SearchTerm term) throws MessagingException {
+        // only allowed on open folders
+        checkOpen();
+
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // just search everything
+            int[] messageNumbers = connection.searchMailbox(term);
+            return resolveMessages(messageNumbers);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+
+    /**
+     * Search the supplied messages for those that match the supplied criteria;
+     * messages must belong to this folder.
+     * The default implementation iterates through the messages, returning those
+     * whose {@link Message#match(javax.mail.search.SearchTerm)} method returns true;
+     * subclasses may provide a more efficient implementation.
+     *
+     * @param term the search criteria
+     * @param messages the messages to search
+     * @return an array containing messages that match the criteria
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public synchronized Message[] search(SearchTerm term, Message[] messages) throws MessagingException {
+        // only allowed on open folders
+        checkOpen();
+
+        // turn this into a string specifier for these messages.  We'll weed out the expunged messages first.
+        String messageSet = generateMessageSet(messages);
+
+        // If we have no "live" messages to search, just return now.  We're required to return a non-null
+        // value, so give an empy array back.
+        if (messageSet == null) {
+            return new Message[0];
+        }
+
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+
+            // now go do the search.
+            int[] messageNumbers = connection.searchMailbox(messageSet, term);
+            return resolveMessages(messageNumbers);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Get the UID validity value for this Folder.
+     *
+     * @return The current UID validity value, as a long.
+     * @exception MessagingException
+     */
+    public synchronized long getUIDValidity() throws MessagingException
+    {
+        // get the latest status to make sure we have the
+        // most current.
+        refreshStatus(true);
+        return uidValidity;
+    }
+
+    /**
+     * Retrieve a message using the UID rather than the
+     * message sequence number.  Returns null if the message
+     * doesn't exist.
+     *
+     * @param uid    The target UID.
+     *
+     * @return the Message object.  Returns null if the message does
+     *         not exist.
+     * @exception MessagingException
+     */
+    public synchronized Message getMessageByUID(long uid) throws MessagingException
+    {
+        // only allowed on open folders
+        checkOpen();
+
+        Long key = new Long(uid);
+        // first check to see if we have a cached value for this
+        synchronized(messageCache) {
+            Message msg = (Message)uidCache.get(key);
+            if (msg != null) {
+                return msg;
+            }
+        }
+
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // locate the message identifier
+            IMAPUid imapuid = connection.getSequenceNumberForUid(uid);
+            // if nothing is returned, the message doesn't exist
+            if (imapuid == null) {
+                return null;
+            }
+
+
+            // retrieve the actual message object and place this in the UID cache
+            return retrieveMessageByUid(key, imapuid.messageNumber);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Get a series of messages using a UID range.  The
+     * special value LASTUID can be used to mark the
+     * last available message.
+     *
+     * @param start  The start of the UID range.
+     * @param end    The end of the UID range.  The special value
+     *               LASTUID can be used to request all messages up
+     *               to the last UID.
+     *
+     * @return An array containing all of the messages in the
+     *         range.
+     * @exception MessagingException
+     */
+    public synchronized Message[] getMessagesByUID(long start, long end) throws MessagingException
+    {
+        // only allowed on open folders
+        checkOpen();
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // locate the message identifier
+            List uids = connection.getSequenceNumbersForUids(start, end);
+            Message[] msgs = new Message[uids.size()];
+
+            // fill in each of the messages based on the returned value
+            for (int i = 0; i < msgs.length; i++) {
+                IMAPUid uid = (IMAPUid)uids.get(i);
+                msgs[i] = retrieveMessageByUid(new Long(uid.uid), uid.messageNumber);
+            }
+
+            return msgs;
+        } finally {
+            releaseConnection(connection);
+        }
+
+
+    }
+
+    /**
+     * Retrieve a set of messages by explicit UIDs.  If
+     * any message in the list does not exist, null
+     * will be returned for the corresponding item.
+     *
+     * @param ids    An array of UID values to be retrieved.
+     *
+     * @return An array of Message items the same size as the ids
+     *         argument array.  This array will contain null
+     *         entries for any UIDs that do not exist.
+     * @exception MessagingException
+     */
+    public synchronized Message[] getMessagesByUID(long[] ids) throws MessagingException
+    {
+        // only allowed on open folders
+        checkOpen();
+
+        Message[] msgs = new Message[ids.length];
+
+        for (int i = 0; i < msgs.length; i++) {
+            msgs[i] = getMessageByUID(ids[i]);
+        }
+
+        return msgs;
+    }
+
+    /**
+     * Retrieve the UID for a message from this Folder.
+     * The argument Message MUST belong to this Folder
+     * instance, otherwise a NoSuchElementException will
+     * be thrown.
+     *
+     * @param message The target message.
+     *
+     * @return The UID associated with this message.
+     * @exception MessagingException
+     */
+    public synchronized long getUID(Message message) throws MessagingException
+    {
+        // verify this actually is in this folder.
+        checkMessageFolder(message);
+        IMAPMessage msg = (IMAPMessage)message;
+
+        // we might already know this bit of information
+        if (msg.getUID() != -1) {
+            return msg.getUID();
+        }
+
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // locate the message identifier
+            IMAPUid imapuid = connection.getUidForSequenceNumber(msg.getMessageNumber());
+            // if nothing is returned, the message doesn't exist
+            if (imapuid == null) {
+                return -1;
+            }
+            // cache this information now that we've gotten it.
+            addToUidCache(new Long(imapuid.uid), getMessage(imapuid.messageNumber));
+            // return the UID information.
+            return imapuid.uid;
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Retrieve a message from a UID/message mapping.
+     *
+     * @param key       The UID key used for the mapping.
+     * @param msgNumber The message sequence number.
+     *
+     * @return The Message object corresponding to the message.
+     * @exception MessagingException
+     */
+    protected synchronized Message retrieveMessageByUid(Long key, int msgNumber) throws MessagingException
+    {
+        synchronized (messageCache) {
+            // first check the cache...this might have already been added.
+            Message msg = (Message)uidCache.get(key);
+            if (msg != null) {
+                return msg;
+            }
+
+            // retrieve the message by sequence number
+            msg = getMessage(msgNumber);
+            // add this to our UID mapping cache.
+            addToUidCache(key, msg);
+            return msg;
+        }
+    }
+
+
+    /**
+     * Add a message to the UID mapping cache, ensuring that
+     * the UID value is updated.
+     *
+     * @param key    The UID key.
+     * @param msg    The message to add.
+     */
+    protected void addToUidCache(Long key, Message msg) {
+        synchronized (messageCache) {
+            ((IMAPMessage)msg).setUID(key.longValue());
+            uidCache.put(key, msg);
+        }
+    }
+
+
+    /**
+     * Append a single message to the IMAP Folder.
+     *
+     * @param msg    The message to append.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void appendMessage(Message msg) throws MessagingException
+    {
+        // sort out the dates.  If no received date, use the sent date.
+        Date date = msg.getReceivedDate();
+        if (date == null) {
+            date = msg.getSentDate();
+        }
+
+        Flags flags = msg.getFlags();
+
+        // convert the message into an array of bytes we can attach as a literal.
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        try {
+            msg.writeTo(out);
+        } catch (IOException e) {
+        }
+
+        // now issue the append command
+        IMAPConnection connection = getConnection();
+        try {
+            connection.appendMessage(getFullName(), date, flags, out.toByteArray());
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     * Retrieve the list of matching groups from the IMAP server using the LIST
+     * or LSUB command. The server does the wildcard matching for us.
+     *
+     * @param pattern
+     *            The pattern string (in wildmat format) used to match.
+     *
+     * @return An array of folders for the matching groups.
+     */
+    protected synchronized Folder[] filterFolders(String pattern, boolean subscribed) throws MessagingException {
+        IMAPConnection connection = getConnection();
+        // this is used to filter out our own folder from the search
+        String root = fullname + getSeparator();
+
+        List responses = null;
+        try {
+
+
+            if (subscribed) {
+                // get the lsub response for this folder.
+                responses = connection.listSubscribed(root, pattern);
+            }
+            else {
+                // grab using the LIST command.
+                responses = connection.list(root, pattern);
+            }
+        } finally {
+            releaseConnection(connection);
+        }
+
+        List folders = new ArrayList();
+
+        for (int i = 0; i < responses.size(); i++) {
+            IMAPListResponse response = (IMAPListResponse)responses.get(i);
+            // if a full wildcard is specified, the root folder can be returned too.  Make sure we
+            // filter that one out.
+            if (!response.mailboxName.equals(root)) {
+                IMAPFolder folder = new IMAPFolder((IMAPStore)store, response.mailboxName, response.separator);
+                folders.add(folder);
+            }
+        }
+
+        // convert into an array and return
+        return (Folder[])folders.toArray(new Folder[folders.size()]);
+    }
+
+
+    /**
+     * Test if a folder can hold sub folders.
+     *
+     * @return True if the folder is allowed to have subfolders.
+     */
+    protected synchronized boolean holdsFolders() throws MessagingException {
+        checkFolderValidity();
+        return (folderType & HOLDS_FOLDERS) != 0;
+    }
+
+
+    /**
+     * Validate that a target message number is considered valid
+     * by the IMAP server.  If outside of the range we currently
+     * are a ware of, we'll ping the IMAP server to see if there
+     * have been any updates.
+     *
+     * @param messageNumber
+     *               The message number we're checking.
+     *
+     * @exception MessagingException
+     */
+    protected void checkMessageValidity(int messageNumber) throws MessagingException {
+        // lower range for a message is 1.
+        if (messageNumber < 1) {
+            throw new MessagingException("Invalid message number for IMAP folder: " + messageNumber);
+        }
+        // if within our current known range, we'll accept this
+        if (messageNumber <= maxSequenceNumber) {
+            return;
+        }
+
+        IMAPConnection connection = getConnection();
+
+        synchronized (this) {
+            try {
+                // ping the server to see if there's any updates to process.  The updates are handled
+                // by the response handlers.
+                connection.updateMailboxStatus();
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+
+        // still out of range?
+        if (messageNumber > maxSequenceNumber) {
+            throw new MessagingException("Message " + messageNumber + " does not exist on server");
+        }
+    }
+
+
+	/**
+	 * Below is a list of convenience methods that avoid repeated checking for a
+	 * value and throwing an exception
+	 */
+
+    /**
+     * Ensure the folder is open.  Throws a MessagingException
+     * if not in the correct state for the operation.
+     *
+     * @exception IllegalStateException
+     */
+    protected void checkOpen() throws IllegalStateException {
+		if (!folderOpen){
+		    throw new IllegalStateException("Folder is not Open");
+		}
+    }
+
+    /**
+     * Ensure the folder is not open for operations
+     * that require the folder to be closed.
+     *
+     * @exception IllegalStateException
+     */
+    protected void checkClosed() throws IllegalStateException {
+		if (folderOpen){
+		    throw new IllegalStateException("Folder is Open");
+		}
+    }
+
+    /**
+     * Ensure that the folder is open for read/write mode before doing
+     * an operation that would make a change.
+     *
+     * @exception IllegalStateException
+     */
+    protected void checkReadWrite() throws IllegalStateException {
+        if (mode != READ_WRITE) {
+		    throw new IllegalStateException("Folder is opened READY_ONLY");
+        }
+    }
+
+
+    /**
+     * Check that the folder is open and in read/write mode.
+     *
+     * @exception IllegalStateException
+     */
+    protected void checkOpenReadWrite() throws IllegalStateException {
+        checkOpen();
+        checkReadWrite();
+    }
+
+
+
+    /**
+     * Notify the message changed listeners that a
+     * message contained in the folder has been updated.
+     *
+     * @param type   The type of update made to the message.
+     * @param m      The message that was updated.
+     *
+     * @see javax.mail.Folder#notifyMessageChangedListeners(int, javax.mail.Message)
+     */
+    public void notifyMessageChangedListeners(int type, Message m) {
+    	super.notifyMessageChangedListeners(type, m);
+    }
+
+
+    /**
+     * Retrieve the connection attached to this folder.  Throws an
+     * exception if we don't have an active connection.
+     *
+     * @return The current connection object.
+     * @exception MessagingException
+     */
+    protected synchronized IMAPConnection getConnection() throws MessagingException {
+        // don't have an open connection yet?  Just request a pool connection.
+        if (currentConnection == null) {
+            // request a connection from the central store.
+            IMAPConnection connection = ((IMAPStore)store).getFolderConnection(this);
+            // we need to make ourselves a handler of unsolicited responses
+            connection.addResponseHandler(this);
+            return connection;
+        }
+        // we have a connection for our use.  Just return it.
+        return currentConnection;
+    }
+
+
+    /**
+     * Release our connection back to the Store.
+     *
+     * @param connection The connection to release.
+     *
+     * @exception MessagingException
+     */
+    protected void releaseConnection(IMAPConnection connection) throws MessagingException {
+        // This is a bit of a pain.  We need to delay processing of the
+        // unsolicited responses until after each user of the connection has
+        // finished processing the expected responses.  We need to do this because
+        // the unsolicited responses may include EXPUNGED messages.  The EXPUNGED
+        // messages will alter the message sequence numbers for the messages in the
+        // cache.  Processing the EXPUNGED messages too early will result in
+        // updates getting applied to the wrong message instances.  So, as a result,
+        // we delay that stage of the processing until all expected responses have
+        // been handled.
+
+        // process any pending messages before returning.
+        connection.processPendingResponses();
+        // if no cached connection or this is somehow different from the cached one, just
+        // return it.
+        if (currentConnection == null || connection != currentConnection) {
+            connection.removeResponseHandler(this);
+            ((IMAPStore)store).releaseFolderConnection(this, connection);
+        }
+        // if we're open, then we don't have to worry about returning this connection
+        // to the Store.  This is set up perfectly for our use right now.
+    }
+
+
+    /**
+     * Obtain a connection object for a Message attached to this Folder.  This
+     * will be the Folder's connection, which is only available if the Folder
+     * is currently open.
+     *
+     * @return The connection object for the Message instance to use.
+     * @exception MessagingException
+     */
+    synchronized IMAPConnection getMessageConnection() throws MessagingException {
+        // if we're not open, the messages can't communicate either
+        if (currentConnection == null) {
+            throw new FolderClosedException(this, "No Folder connections available");
+        }
+        // return the current Folder connection.  At this point, we'll be sharing the
+        // connection between the Folder and the Message (and potentially, other messages).  The
+        // command operations on the connection are synchronized so only a single command can be
+        // issued at one time.
+        return currentConnection;
+    }
+
+
+    /**
+     * Release the connection object back to the Folder instance.
+     *
+     * @param connection The connection being released.
+     *
+     * @exception MessagingException
+     */
+    void releaseMessageConnection(IMAPConnection connection) throws MessagingException {
+        // release it back to ourselves...this will drive unsolicited message processing.
+        releaseConnection(connection);
+    }
+
+
+    /**
+     * Refresh the status information on this folder.
+     *
+     * @param force  Force a status refresh always.
+     *
+     * @exception MessagingException
+     */
+    protected void refreshStatus(boolean force) throws MessagingException {
+        // first check that any cached status we've received has gotten a little moldy.
+        if (cachedStatus != null) {
+            // if not forcing, check the time out.
+            if (!force) {
+                if (statusCacheTimeout > 0) {
+                    long age = System.currentTimeMillis() - lastStatusTimeStamp;
+                    if (age < statusCacheTimeout) {
+                        return;
+                    }
+                }
+            }
+            // make sure the stale information is cleared out.
+            cachedStatus = null;
+        }
+
+        IMAPConnection connection = getConnection();
+        try {
+            // ping the server for the list information for this folder
+            cachedStatus = connection.getMailboxStatus(fullname);
+            // mark when we got this
+            lastStatusTimeStamp = System.currentTimeMillis();
+        } finally {
+            releaseConnection(connection);
+        }
+
+        // refresh the internal state from the message information
+        maxSequenceNumber = cachedStatus.messages;
+        recentMessages = cachedStatus.recentMessages;
+        unseenMessages = cachedStatus.unseenMessages;
+        uidValidity = cachedStatus.uidValidity;
+    }
+
+
+    /**
+     * Process an EXPUNGE response for a message, removing the
+     * message from the message cache.
+     *
+     * @param sequenceNumber
+     *               The sequence number for the expunged message.
+     *
+     * @return The Message object corresponding to this expunged
+     *         message.
+     * @exception MessagingException
+     */
+    protected synchronized Message expungeMessage(int sequenceNumber) throws MessagingException {
+
+        // first process the expunged message.  We need to return a Message instance, so
+        // force this to be added to the cache
+        IMAPMessage expungedMessage = (IMAPMessage)getMessage(sequenceNumber);
+        // mark the message as expunged.
+        expungedMessage.setExpunged(true);
+        // have we retrieved a UID for this message?  If we have, then it's in the UID cache and
+        // needs removal from there also
+        long uid = ((IMAPMessage)expungedMessage).getUID();
+        if (uid >= 0) {
+            uidCache.remove(new Long(uid));
+        }
+        // because we need to jigger the keys of some of these, we had better have a working
+        // copy.
+        Map newCache = new HashMap();
+
+        // now process each message in the cache, making adjustments as necessary
+        Iterator i = messageCache.keySet().iterator();
+
+        while (i.hasNext()) {
+            Integer key = (Integer)i.next();
+            int index = key.intValue();
+            // if before the expunged message, just copy over to the
+            // new cache
+            if (index < sequenceNumber) {
+                newCache.put(key, messageCache.get(key));
+            }
+            // after the expunged message...we need to adjust this
+            else if (index > sequenceNumber) {
+                // retrieve the message using the current position,
+                // adjust the message sequence number, and add to the new
+                // message cache under the new key value
+                IMAPMessage message = (IMAPMessage)messageCache.get(key);
+                message.setSequenceNumber(index - 1);
+                newCache.put(new Integer(index - 1), message);
+            }
+            else {
+                // the expunged message.  We don't move this over to the new
+                // cache, and we've already done all processing of that message that's
+                // required
+            }
+        }
+
+        // replace the old cache now that everything has been adjusted
+        messageCache = newCache;
+
+        // adjust the message count downward
+        maxSequenceNumber--;
+        return expungedMessage;
+    }
+
+
+    /**
+     * Resolve an array of message numbers into an array of the
+     * referenced messages.
+     *
+     * @param messageNumbers
+     *               The array of message numbers (can be null).
+     *
+     * @return An array of Message[] containing the resolved messages from
+     *         the list.  Returns a zero-length array if there are no
+     *         messages to resolve.
+     * @exception MessagingException
+     */
+    protected Message[] resolveMessages(int[] messageNumbers) throws MessagingException {
+        // the connection search returns a null pointer if nothing was found, just convert this into a
+        // null array.
+        if (messageNumbers == null) {
+            return new Message[0];
+        }
+
+        Message[] messages = new Message[messageNumbers.length];
+
+        // retrieve each of the message numbers in turn.
+        for (int i = 0; i < messageNumbers.length; i++) {
+            messages[i] = getMessage(messageNumbers[i]);
+        }
+
+        return messages;
+    }
+
+    /**
+     * Generate a message set string from a List of messages rather than an
+     * array.
+     *
+     * @param messages The List of messages.
+     *
+     * @return The evaluated message set string.
+     * @exception MessagingException
+     */
+    protected String generateMessageSet(List messages) throws MessagingException {
+        Message[] msgs = (Message[])messages.toArray(new Message[messages.size()]);
+        return generateMessageSet(msgs);
+    }
+
+
+    /**
+     * Take an array of messages and generate a String <message set>
+     * argument as specified by RFC 2060.  The message set argument
+     * is a comma-separated list of message number ranges.  A
+     * single element range is just one number.  A longer range is
+     * a pair of numbers separated by a ":".  The generated string
+     * should not have any blanks.  This will attempt to locate
+     * consequetive ranges of message numbers, but will only do this
+     * for messages that are already ordered in the array (i.e., we
+     * don't try to sort).  Expunged messages are excluded from the
+     * search, since they don't exist anymore.  A valid search string
+     * will look something like this:
+     *
+     *    "3,6:10,15,21:35"
+     *
+     * @param messages The array of messages we generate from.
+     *
+     * @return A string formatted version of these message identifiers that
+     *         can be used on an IMAP command.
+     */
+    protected String generateMessageSet(Message[] messages) throws MessagingException {
+        StringBuffer set = new StringBuffer();
+
+        for (int i = 0; i < messages.length; i++) {
+            // first scan the list looking for a "live" message.
+            IMAPMessage start = (IMAPMessage)messages[i];
+            if (!start.isExpunged()) {
+
+                // we can go ahead and add this to the list now.  If we find this is the start of a
+                // range, we'll tack on the ":end" bit once we find the last message in the range.
+                if (set.length() != 0) {
+                    // only append the comma if not the first element of the list
+                    set.append(',');
+                }
+
+                // append the first number.  NOTE:  We append this directly rather than
+                // use appendInteger(), which appends it using atom rules.
+                set.append(Integer.toString(start.getSequenceNumber()));
+
+                // ok, we have a live one.  Now scan the list from here looking for the end of
+                // a range of consequetive messages.
+                int endIndex = -1; ;
+                // get the number we're checking against.
+                int previousSequence = start.getSequenceNumber();
+                for (int j = i + 1; j < messages.length; j++) {
+                    IMAPMessage message = (IMAPMessage)messages[j];
+                    if (!message.isExpunged()) {
+                        // still consequetive?
+                        if (message.getSequenceNumber() == previousSequence + 1) {
+                            // step this for the next check.
+                            previousSequence++;
+                            // record this as the current end of the range.
+                            endIndex = j;
+                        }
+                        else {
+                            // found a non-consequetive one, stop here
+                            break;
+                        }
+                    }
+                }
+
+                // have a range end point?  Add the range specifier and step the loop index point
+                // to skip over this
+                if (endIndex != -1) {
+                    // pick up the scan at the next location
+                    i = endIndex;
+
+                    set.append(':');
+                    set.append(Integer.toString(((IMAPMessage)messages[endIndex]).getSequenceNumber()));
+                }
+            }
+        }
+
+        // return null for an empty list. This is possible because either an empty array has been handed to
+        // us or all of the messages in the array have been expunged.
+        if (set.length() == 0) {
+            return null;
+        }
+        return set.toString();
+    }
+
+    /**
+     * Verify that this folder exists on the server before
+     * performning an operation that requires a valid
+     * Folder instance.
+     *
+     * @exception MessagingException
+     */
+    protected void checkFolderValidity() throws MessagingException {
+        // if we are holding a current listinfo response, then
+        // we have chached existance information.  In that case,
+        // all of our status is presumed up-to-date and we can go
+        // with that.  If we don't have the information, then we
+        // ping the server for it.
+        if (listInfo == null && !exists()) {
+            throw new FolderNotFoundException(this, "Folder " + fullname + " not found on server");
+        }
+    }
+
+
+    /**
+     * Check if a Message is properly within the target
+     * folder.
+     *
+     * @param msg    The message we're checking.
+     *
+     * @exception MessagingException
+     */
+    protected void checkMessageFolder(Message msg) throws MessagingException {
+        if (msg.getFolder() != this) {
+            throw new NoSuchElementException("Message is not within the target Folder");
+        }
+    }
+
+
+    /**
+     * Search a list of LIST responses for one containing information
+     * for a particular mailbox name.
+     *
+     * @param responses The list of responses.
+     * @param name      The desired mailbox name.
+     *
+     * @return The IMAPListResponse information for the requested name.
+     */
+    protected IMAPListResponse findListResponse(List responses, String name) {
+        for (int i = 0; i < responses.size(); i++) {
+            IMAPListResponse response = (IMAPListResponse)responses.get(i);
+            if (response.mailboxName.equals(name)) {
+                return response;
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Protected class intended for subclass overrides.  For normal folders,
+     * the mailbox name is fullname.  For Namespace root folders, the mailbox
+     * name is the prefix + separator.
+     *
+     * @return The string name to use as the mailbox name for exists() and issubscribed()
+     *         calls.
+     */
+    protected String getMailBoxName() {
+        return fullname;
+    }
+
+    /**
+     * Handle an unsolicited response from the server.  Most unsolicited responses
+     * are replies to specific commands sent to the server.  The remainder must
+     * be handled by the Store or the Folder using the connection.  These are
+     * critical to handle, as events such as expunged messages will alter the
+     * sequence numbers of the live messages.  We need to keep things in sync.
+     *
+     * @param response The UntaggedResponse to process.
+     *
+     * @return true if we handled this response and no further handling is required.  false
+     *         means this one wasn't one of ours.
+     */
+    public boolean handleResponse(IMAPUntaggedResponse response) {
+        // "you've got mail".  The message count has been updated.  There
+        // are two posibilities.  Either there really are new messages, or
+        // this is an update following an expunge.  If there are new messages,
+        // we need to update the message cache and broadcast the change to
+        // any listeners.
+        if (response.isKeyword("EXISTS")) {
+            // we need to update our cache, and also retrieve the new messages and
+            // send them out in a broadcast update.
+            int oldCount = maxSequenceNumber;
+            maxSequenceNumber = ((IMAPSizeResponse)response).getSize();
+            // has the size grown?  We have to send the "you've got mail" announcement.
+            if (oldCount < maxSequenceNumber) {
+                try {
+                    Message[] messages = getMessages(oldCount + 1, maxSequenceNumber);
+                    notifyMessageAddedListeners(messages);
+                } catch (MessagingException e) {
+                    // should never happen in this context
+                }
+            }
+            return true;
+        }
+        // "you had mail".  A message was expunged from the server.  This MUST
+        // be processed immediately, as any subsequent expunge messages will
+        // shift the message numbers as a result of previous messages getting
+        // removed.  We need to keep our internal cache in sync with the server.
+        else if (response.isKeyword("EXPUNGE")) {
+            int messageNumber = ((IMAPSizeResponse)response).getSize();
+            try {
+                Message message = expungeMessage(messageNumber);
+
+                // broadcast the message update.
+                notifyMessageRemovedListeners(false, new Message[] {message});
+            } catch (MessagingException e) {
+            }
+            // we handled this one.
+            return true;
+        }
+        // just an update of recently arrived stuff?  Just update the field.
+        else if (response.isKeyword("RECENT")) {
+            recentMessages = ((IMAPSizeResponse)response).getSize();
+            return true;
+        }
+        // The spec is not particularly clear what types of unsolicited
+        // FETCH response can be sent.  The only one that is specifically
+        // spelled out is flag updates.  If this is one of those, then
+        // handle it.
+        else if (response.isKeyword("FETCH")) {
+            IMAPFetchResponse fetch = (IMAPFetchResponse)response;
+            IMAPFlags flags = (IMAPFlags)fetch.getDataItem(IMAPFetchDataItem.FLAGS);
+            // if this is a flags response, get the message and update
+            if (flags != null) {
+                try {
+                    // get the updated message and update the internal state.
+                    IMAPMessage message = (IMAPMessage)getMessage(fetch.sequenceNumber);
+                    // this shouldn't happen, but it might have been expunged too.
+                    if (message != null) {
+                        message.updateMessageInformation(fetch);
+                    }
+                    notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, message);
+                } catch (MessagingException e) {
+                }
+                return true;
+            }
+        }
+        // this is a BYE response on our connection.  This forces us to close, but
+        // when we return the connection, the pool needs to get rid of it.
+        else if (response.isKeyword("BYE")) {
+            // this is essentially a close event.  We need to clean everything up
+            // and make sure our connection is not returned to the general pool.
+            try {
+                cleanupFolder(false, true);
+            } catch (MessagingException e) {
+            }
+            return true;
+        }
+
+        // not a response the folder knows how to deal with.
+        return false;
+    }
+
+// The following set of methods are extensions that exist in the Sun implementation.  They
+// match the Sun version in intent, but are not 100% compatible because the Sun implementation
+// uses com.sun.* class instances as opposed to the org.apache.geronimo.* classes.
+
+
+
+    /**
+     *   Remove an entry from the access control list for this folder.
+     *
+     * @param acl    The ACL element to remove.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void removeACL(ACL acl) throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            connection.removeACLRights(fullname, acl);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     *   Add an entry to the access control list for this folder.
+     *
+     * @param acl    The new ACL to add.
+     */
+    public synchronized void addACL(ACL acl) throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            connection.setACLRights(fullname, acl);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     * Add Rights to a given ACL entry.
+     *
+     * @param acl    The target ACL to update.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void addRights(ACL acl) throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            connection.addACLRights(fullname, acl);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     * Remove ACL Rights from a folder.
+     *
+     * @param acl    The ACL describing the Rights to remove.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void removeRights(ACL acl) throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            connection.removeACLRights(fullname, acl);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     *   List the rights associated with a given name.
+     *
+     * @param name   The user name for the Rights.
+     *
+     * @return The set of Rights associated with the user name.
+     * @exception MessagingException
+     */
+    public synchronized Rights[] listRights(String name) throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            return connection.listACLRights(fullname, name);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     *   List the rights for the currently authenticated user.
+     *
+     * @return The set of Rights for the current user.
+     * @exception MessagingException
+     */
+    public synchronized Rights myRights() throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            return connection.getMyRights(fullname);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Get the quota values assigned to the current folder.
+     *
+     * @return The Quota information for the folder.
+     * @exception MessagingException
+     */
+    public synchronized Quota[] getQuota() throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            return connection.fetchQuotaRoot(fullname);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Set the quota value for a quota root
+     *
+     * @param quota  The new quota information to set.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void setQuota(Quota quota) throws MessagingException {
+        // ask the store to kindly hook us up with a connection.
+        IMAPConnection connection = getConnection();
+
+        try {
+            // the connection does the heavy lifting
+            connection.setQuota(quota);
+        } finally {
+            releaseConnection(connection);
+        }
+    }
+
+    /**
+     * Get the set of attributes defined for the folder
+     * as the set of capabilities returned when the folder
+     * was opened.
+     *
+     * @return The set of attributes associated with the folder.
+     * @exception MessagingException
+     */
+    public synchronized String[] getAttributes() throws MessagingException {
+        // if we don't have the LIST command information for this folder yet,
+        // call exists() to force this to be updated so we can return.
+        if (listInfo == null) {
+            // return a null reference if this is not valid.
+            if (!exists()) {
+                return null;
+            }
+        }
+        // return a copy of the attributes array.
+        return (String[])listInfo.attributes.clone();
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
new file mode 100644
index 0000000..44cfb45
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
@@ -0,0 +1,1300 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.activation.DataHandler;
+
+import javax.mail.Address;
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Header;
+import javax.mail.IllegalWriteException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MessageRemovedException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.UIDFolder;
+import javax.mail.event.MessageChangedEvent;
+
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MailDateFormat;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeUtility;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPBody;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchDataItem;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchResponse;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPInternalDate;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPInternetHeader;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPMessageSize;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPUid;
+import org.apache.geronimo.javamail.util.MailConnection;
+
+/**
+ * IMAP implementation of javax.mail.internet.MimeMessage
+ *
+ * Only the most basic information is given and
+ * Message objects created here is a light-weight reference to the actual Message
+ * As per the JavaMail spec items from the actual message will get filled up on demand
+ *
+ * If some other items are obtained from the server as a result of one call, then the other
+ * details are also processed and filled in. For ex if RETR is called then header information
+ * will also be processed in addition to the content
+ *
+ * @version $Rev: 946314 $ $Date: 2010-05-19 14:01:55 -0400 (Wed, 19 May 2010) $
+ */
+public class IMAPMessage extends MimeMessage {
+
+    private static final byte[] CRLF = new byte[]{'\r', '\n'};
+
+    // the Store we're stored in (which manages the connection and other stuff).
+    protected IMAPStore store;
+
+    // the IMAP server sequence number (potentially updated during the life of this message object).
+    protected int sequenceNumber;
+    // the IMAP uid value;
+    protected long uid = -1;
+    // the section identifier.  This is only really used for nested messages.  The toplevel version
+    // will be null, and each nested message will set the appropriate part identifier
+    protected String section;
+    // the loaded message envelope (delayed until needed)
+    protected IMAPEnvelope envelope;
+    // the body structure information (also lazy loaded).
+    protected IMAPBodyStructure bodyStructure;
+    // the IMAP INTERNALDATE value.
+    protected Date receivedDate;
+    // the size item, which is maintained separately from the body structure
+    // as it can be retrieved without getting the body structure
+    protected int size;
+    // turned on once we've requested the entire header set.
+    protected boolean allHeadersRetrieved = false;
+    // singleton date formatter for this class.
+    static protected MailDateFormat dateFormat = new MailDateFormat();
+
+
+    /**
+     * Contruct an IMAPMessage instance.
+     *
+     * @param folder   The hosting folder for the message.
+     * @param store    The Store owning the article (and folder).
+     * @param msgnum   The article message number.  This is assigned by the Folder, and is unique
+     *                 for each message in the folder.  The message numbers are only valid
+     *                 as long as the Folder is open.
+     * @param sequenceNumber The IMAP server manages messages by sequence number, which is subject to
+     *                 change whenever messages are expunged.  This is the server retrieval number
+     *                 of the message, which needs to be synchronized with status updates
+     *                 sent from the server.
+     *
+     * @exception MessagingException
+     */
+	IMAPMessage(IMAPFolder folder, IMAPStore store, int msgnum, int sequenceNumber) {
+		super(folder, msgnum);
+        this.sequenceNumber = sequenceNumber;
+		this.store = store;
+        // The default constructor creates an empty Flags item.  We need to clear this out so we
+        // know if the flags need to be fetched from the server when requested.
+        flags = null;
+        // make sure this is a totally fresh set of headers.  We'll fill things in as we retrieve them.
+        headers = new InternetHeaders();
+	}
+
+
+    /**
+     * Override for the Message class setExpunged() method to allow
+     * us to do additional cleanup for expunged messages.
+     *
+     * @param value  The new expunge setting.
+     */
+    public void setExpunged(boolean value) {
+        // super class handles most of the details
+        super.setExpunged(value);
+        // if we're now expunged, this removes us from the server message sequencing scheme, so
+        // we need to invalidate the sequence number.
+        if (isExpunged()) {
+            sequenceNumber = -1;
+        }
+    }
+
+
+    /**
+     * Return a copy the flags associated with this message.
+     *
+     * @return a copy of the flags for this message
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public synchronized Flags getFlags() throws MessagingException {
+        // load the flags, if needed
+        loadFlags();
+        return super.getFlags();
+    }
+
+
+    /**
+     * Check whether the supplied flag is set.
+     * The default implementation checks the flags returned by {@link #getFlags()}.
+     *
+     * @param flag the flags to check for
+     * @return true if the flags is set
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public synchronized boolean isSet(Flags.Flag flag) throws MessagingException {
+        // load the flags, if needed
+        loadFlags();
+        return super.isSet(flag);
+    }
+
+    /**
+     * Set or clear a flag value.
+     *
+     * @param flags  The set of flags to effect.
+     * @param set    The value to set the flag to (true or false).
+     *
+     * @exception MessagingException
+     */
+    public synchronized void setFlags(Flags flag, boolean set) throws MessagingException {
+        // make sure this is in a valid state.
+        checkValidity();
+
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        synchronized (folder) {
+            IMAPConnection connection = getConnection();
+
+            try {
+                // set the flags for this item and update the
+                // internal state with the new values returned from the
+                // server.
+                flags = connection.setFlags(sequenceNumber, flag, set);
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+    }
+
+
+    /**
+     * Return an InputStream instance for accessing the
+     * message content.
+     *
+     * @return An InputStream instance for accessing the content
+     *         (body) of the message.
+     * @exception MessagingException
+     * @see javax.mail.internet.MimeMessage#getContentStream()
+     */
+	protected InputStream getContentStream() throws MessagingException {
+
+        // no content loaded yet?
+        if (content == null) {
+            // make sure we're still valid
+            checkValidity();
+            // make sure the content is fully loaded
+            loadContent();
+        }
+
+        // allow the super class to handle creating it from the loaded content.
+        return super.getContentStream();
+	}
+
+
+    /**
+     * Write out the byte data to the provided output stream.
+     *
+     * @param out    The target stream.
+     *
+     * @exception IOException
+     * @exception MessagingException
+     */
+    public void writeTo(OutputStream out) throws IOException, MessagingException {
+        // no content loaded yet?
+        if (content == null) {
+            // make sure we're still valid
+            checkValidity();
+            // make sure the content is fully loaded
+            loadContent();
+        }
+
+        loadHeaders();
+
+        Enumeration e = headers.getAllHeaderLines();
+        while(e.hasMoreElements()) {
+            String line = (String)e.nextElement();
+            out.write(line.getBytes("ISO8859-1"));
+            out.write(CRLF);
+        }
+        out.write(CRLF);
+        out.write(CRLF);
+        out.write(content);
+    }
+
+	/******************************************************************
+	 * Following is a set of methods that deal with information in the
+	 * envelope.  These methods ensure the enveloper is loaded and
+     * retrieve the information.
+	 ********************************************************************/
+
+
+    /**
+     * Get the message "From" addresses.  This looks first at the
+     * "From" headers, and no "From" header is found, the "Sender"
+     * header is checked.  Returns null if not found.
+     *
+     * @return An array of addresses identifying the message from target.  Returns
+     *         null if this is not resolveable from the headers.
+     * @exception MessagingException
+     */
+    public Address[] getFrom() throws MessagingException {
+        // make sure we've retrieved the envelope information.
+        loadEnvelope();
+        // make sure we return a copy of the array so this can't be changed.
+        Address[] addresses = envelope.from;
+        if (addresses == null) {
+            return null;
+        }
+        return (Address[])addresses.clone();
+    }
+
+
+    /**
+     * Return the "Sender" header as an address.
+     *
+     * @return the "Sender" header as an address, or null if not present
+     * @throws MessagingException if there was a problem parsing the header
+     */
+    public Address getSender() throws MessagingException {
+        // make sure we've retrieved the envelope information.
+        loadEnvelope();
+        // make sure we return a copy of the array so this can't be changed.
+        Address[] addresses = envelope.sender;
+        if (addresses == null) {
+            return null;
+        }
+        // There's only a single sender, despite IMAP potentially returning a list
+        return addresses[0];
+    }
+
+    /**
+     * Gets the recipients by type.  Returns null if there are no
+     * headers of the specified type.  Acceptable RecipientTypes are:
+     *
+     *   javax.mail.Message.RecipientType.TO
+     *   javax.mail.Message.RecipientType.CC
+     *   javax.mail.Message.RecipientType.BCC
+     *   javax.mail.internet.MimeMessage.RecipientType.NEWSGROUPS
+     *
+     * @param type   The message RecipientType identifier.
+     *
+     * @return The array of addresses for the specified recipient types.
+     * @exception MessagingException
+     */
+    public Address[] getRecipients(Message.RecipientType type) throws MessagingException {
+        // make sure we've retrieved the envelope information.
+        loadEnvelope();
+        Address[] addresses = null;
+
+        if (type == Message.RecipientType.TO) {
+            addresses = envelope.to;
+        }
+        else if (type == Message.RecipientType.CC) {
+            addresses = envelope.cc;
+        }
+        else if (type == Message.RecipientType.BCC) {
+            addresses = envelope.bcc;
+        }
+        else {
+            // this could be a newsgroup type, which will tickle the message headers.
+            return super.getRecipients(type);
+        }
+        // make sure we return a copy of the array so this can't be changed.
+        if (addresses == null) {
+            return null;
+        }
+        return (Address[])addresses.clone();
+    }
+
+    /**
+     * Get the ReplyTo address information.  The headers are parsed
+     * using the "mail.mime.address.strict" setting.  If the "Reply-To" header does
+     * not have any addresses, then the value of the "From" field is used.
+     *
+     * @return An array of addresses obtained from parsing the header.
+     * @exception MessagingException
+     */
+    public Address[] getReplyTo() throws MessagingException {
+        // make sure we've retrieved the envelope information.
+        loadEnvelope();
+        // make sure we return a copy of the array so this can't be changed.
+        Address[] addresses = envelope.replyTo;
+        if (addresses == null) {
+            return null;
+        }
+        return (Address[])addresses.clone();
+    }
+
+    /**
+     * Returns the value of the "Subject" header.  If the subject
+     * is encoded as an RFC 2047 value, the value is decoded before
+     * return.  If decoding fails, the raw string value is
+     * returned.
+     *
+     * @return The String value of the subject field.
+     * @exception MessagingException
+     */
+    public String getSubject() throws MessagingException {
+        // make sure we've retrieved the envelope information.
+        loadEnvelope();
+
+        if (envelope.subject == null) {
+            return null;
+        }
+        // the subject could be encoded.  If there is a decoding error,
+        // return the raw subject string.
+        try {
+            return MimeUtility.decodeText(envelope.subject);
+        } catch (UnsupportedEncodingException e) {
+            return envelope.subject;
+        }
+    }
+
+    /**
+     * Get the value of the "Date" header field.  Returns null if
+     * if the field is absent or the date is not in a parseable format.
+     *
+     * @return A Date object parsed according to RFC 822.
+     * @exception MessagingException
+     */
+    public Date getSentDate() throws MessagingException {
+        // make sure we've retrieved the envelope information.
+        loadEnvelope();
+        // just return that directly
+        return envelope.date;
+    }
+
+
+    /**
+     * Get the message received date.
+     *
+     * @return Always returns the formatted INTERNALDATE, if available.
+     * @exception MessagingException
+     */
+    public Date getReceivedDate() throws MessagingException {
+        loadEnvelope();
+        return receivedDate;
+    }
+
+
+    /**
+     * Retrieve the size of the message content.  The content will
+     * be retrieved from the server, if necessary.
+     *
+     * @return The size of the content.
+     * @exception MessagingException
+     */
+	public int getSize() throws MessagingException {
+        // make sure we've retrieved the envelope information.  We load the
+        // size when we retrieve that.
+        loadEnvelope();
+        return size;
+	}
+
+
+    /**
+     * Get a line count for the IMAP message.  This is potentially
+     * stored in the Lines article header.  If not there, we return
+     * a default of -1.
+     *
+     * @return The header line count estimate, or -1 if not retrieveable.
+     * @exception MessagingException
+     */
+    public int getLineCount() throws MessagingException {
+        loadBodyStructure();
+        return bodyStructure.lines;
+    }
+
+    /**
+     * Return the IMAP in reply to information (retrieved with the
+     * ENVELOPE).
+     *
+     * @return The in reply to String value, if available.
+     * @exception MessagingException
+     */
+    public String getInReplyTo() throws MessagingException {
+        loadEnvelope();
+        return envelope.inReplyTo;
+    }
+
+    /**
+     * Returns the current content type (defined in the "Content-Type"
+     * header.  If not available, "text/plain" is the default.
+     *
+     * @return The String name of the message content type.
+     * @exception MessagingException
+     */
+    public String getContentType() throws MessagingException {
+        loadBodyStructure();
+        return bodyStructure.mimeType.toString();
+    }
+
+
+    /**
+     * Tests to see if this message has a mime-type match with the
+     * given type name.
+     *
+     * @param type   The tested type name.
+     *
+     * @return If this is a type match on the primary and secondare portion of the types.
+     * @exception MessagingException
+     */
+    public boolean isMimeType(String type) throws MessagingException {
+        loadBodyStructure();
+        return bodyStructure.mimeType.match(type);
+    }
+
+    /**
+     * Retrieve the message "Content-Disposition" header field.
+     * This value represents how the part should be represented to
+     * the user.
+     *
+     * @return The string value of the Content-Disposition field.
+     * @exception MessagingException
+     */
+    public String getDisposition() throws MessagingException {
+        loadBodyStructure();
+        if (bodyStructure.disposition != null) {
+            return bodyStructure.disposition.getDisposition();
+        }
+        return null;
+    }
+
+    /**
+     * Decode the Content-Transfer-Encoding header to determine
+     * the transfer encoding type.
+     *
+     * @return The string name of the required encoding.
+     * @exception MessagingException
+     */
+    public String getEncoding() throws MessagingException {
+        loadBodyStructure();
+        return bodyStructure.transferEncoding;
+    }
+
+    /**
+     * Retrieve the value of the "Content-ID" header.  Returns null
+     * if the header does not exist.
+     *
+     * @return The current header value or null.
+     * @exception MessagingException
+     */
+    public String getContentID() throws MessagingException {
+        loadBodyStructure();
+        return bodyStructure.contentID;
+    }
+
+    public String getContentMD5() throws MessagingException {
+        loadBodyStructure();
+        return bodyStructure.md5Hash;
+    }
+
+
+    public String getDescription() throws MessagingException {
+        loadBodyStructure();
+
+        if (bodyStructure.contentDescription == null) {
+            return null;
+        }
+        // the subject could be encoded.  If there is a decoding error,
+        // return the raw subject string.
+        try {
+            return MimeUtility.decodeText(bodyStructure.contentDescription);
+        } catch (UnsupportedEncodingException e) {
+            return bodyStructure.contentDescription;
+        }
+    }
+
+    /**
+     * Return the content languages associated with this
+     * message.
+     *
+     * @return
+     * @exception MessagingException
+     */
+    public String[] getContentLanguage() throws MessagingException {
+        loadBodyStructure();
+
+        if (!bodyStructure.languages.isEmpty()) {
+            return (String[])bodyStructure.languages.toArray(new String[bodyStructure.languages.size()]);
+        }
+        return null;
+    }
+
+    public String getMessageID() throws MessagingException {
+        loadEnvelope();
+        return envelope.messageID;
+    }
+
+    public void setFrom(Address address) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void addFrom(Address[] address) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setSender(Address address) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setRecipients(Message.RecipientType type, Address[] addresses) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setRecipients(Message.RecipientType type, String address) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void addRecipients(Message.RecipientType type, Address[] address) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setReplyTo(Address[] address) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setSubject(String subject) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setSubject(String subject, String charset) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setSentDate(Date sent) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setDisposition(String disposition) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setContentID(String cid) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setContentMD5(String md5) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setDescription(String description) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setDescription(String description, String charset) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setContentLanguage(String[] languages) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+
+	/******************************************************************
+	 * Following is a set of methods that deal with headers
+	 * These methods are just overrides on the superclass methods to
+     * allow lazy loading of the header information.
+	 ********************************************************************/
+
+	public String[] getHeader(String name) throws MessagingException {
+        loadHeaders();
+		return headers.getHeader(name);
+	}
+
+	public String getHeader(String name, String delimiter) throws MessagingException {
+        loadHeaders();
+		return headers.getHeader(name, delimiter);
+	}
+
+	public Enumeration getAllHeaders() throws MessagingException {
+        loadHeaders();
+		return headers.getAllHeaders();
+	}
+
+	public Enumeration getMatchingHeaders(String[] names)  throws MessagingException {
+        loadHeaders();
+		return headers.getMatchingHeaders(names);
+	}
+
+	public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
+        loadHeaders();
+		return headers.getNonMatchingHeaders(names);
+	}
+
+	public Enumeration getAllHeaderLines() throws MessagingException {
+        loadHeaders();
+		return headers.getAllHeaderLines();
+	}
+
+	public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+		return headers.getMatchingHeaderLines(names);
+	}
+
+	public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+		return headers.getNonMatchingHeaderLines(names);
+	}
+
+    // the following are overrides for header modification methods.  These messages are read only,
+    // so the headers cannot be modified.
+    public void addHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+
+    public void removeHeader(String name) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void addHeaderLine(String line) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+	/**
+	 * We cannot modify these messages
+	 */
+	public void saveChanges() throws MessagingException {
+		throw new IllegalWriteException("IMAP messages are read-only");
+	}
+
+
+    /**
+     * Utility method for synchronizing IMAP envelope information and
+     * the message headers.
+     *
+     * @param header    The target header name.
+     * @param addresses The update addresses.
+     */
+    protected void updateHeader(String header, InternetAddress[] addresses) throws MessagingException {
+        if (addresses != null) {
+            headers.addHeader(header, InternetAddress.toString(addresses));
+        }
+    }
+
+    /**
+     * Utility method for synchronizing IMAP envelope information and
+     * the message headers.
+     *
+     * @param header    The target header name.
+     * @param address   The update address.
+     */
+    protected void updateHeader(String header, Address address) throws MessagingException {
+        if (address != null) {
+            headers.setHeader(header, address.toString());
+        }
+    }
+
+    /**
+     * Utility method for synchronizing IMAP envelope information and
+     * the message headers.
+     *
+     * @param header    The target header name.
+     * @param value     The update value.
+     */
+    protected void updateHeader(String header, String value) throws MessagingException {
+        if (value != null) {
+            headers.setHeader(header, value);
+        }
+    }
+
+
+    /**
+     * Create the DataHandler object for this message.
+     *
+     * @return The DataHandler object that processes the content set for this
+     *         message.
+     * @exception MessagingException
+     */
+    public synchronized DataHandler getDataHandler() throws MessagingException {
+        // check the validity and make sure we have the body structure information.
+        checkValidity();
+        loadBodyStructure();
+        if (dh == null) {
+            // are we working with a multipart message here?
+            if (bodyStructure.isMultipart()) {
+                dh = new DataHandler(new IMAPMultipartDataSource(this, this, section, bodyStructure));
+                return dh;
+            }
+            else if (bodyStructure.isAttachedMessage()) {
+                dh = new DataHandler(new IMAPAttachedMessage(this, section, bodyStructure.nestedEnvelope, bodyStructure.nestedBody),
+                     bodyStructure.mimeType.toString());
+                return dh;
+            }
+        }
+
+        // single part messages get handled the normal way.
+        return super.getDataHandler();
+    }
+
+    public void setDataHandler(DataHandler content) throws MessagingException {
+        throw new IllegalWriteException("IMAP body parts are read-only");
+    }
+
+    /**
+     * Update the message headers from an input stream.
+     *
+     * @param in     The InputStream source for the header information.
+     *
+     * @exception MessagingException
+     */
+    public void updateHeaders(InputStream in) throws MessagingException {
+        // wrap a stream around the reply data and read as headers.
+        headers = new InternetHeaders(in);
+        allHeadersRetrieved = true;
+    }
+
+    /**
+     * Load the flag set for this message from the server.
+     *
+     * @exception MessagingeException
+     */
+    public void loadFlags() throws MessagingException {
+        // make sure this is in a valid state.
+        checkValidity();
+        // if the flags are already loaded, nothing to do
+        if (flags != null) {
+            return;
+        }
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        synchronized (folder) {
+            IMAPConnection connection = getConnection();
+
+            try {
+                // fetch the flags for this item.
+                flags = connection.fetchFlags(sequenceNumber);
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+    }
+
+
+    /**
+     * Retrieve the message raw message headers from the IMAP server, synchronizing with the existing header set.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void loadHeaders() throws MessagingException {
+        // don't retrieve if already loaded.
+        if (allHeadersRetrieved) {
+            return;
+        }
+
+        // make sure this is in a valid state.
+        checkValidity();
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        synchronized (folder) {
+            IMAPConnection connection = getConnection();
+
+            try {
+                // get the headers and set
+                headers = connection.fetchHeaders(sequenceNumber, section);
+                // we have the entire header set, not just a subset.
+                allHeadersRetrieved = true;
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+    }
+
+
+    /**
+     * Retrieve the message envelope from the IMAP server, synchronizing the headers with the
+     * information.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void loadEnvelope() throws MessagingException {
+        // don't retrieve if already loaded.
+        if (envelope != null) {
+            return;
+        }
+
+        // make sure this is in a valid state.
+        checkValidity();
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        synchronized (folder) {
+            IMAPConnection connection = getConnection();
+            try {
+                // fetch the envelope information for this
+                List fetches = connection.fetchEnvelope(sequenceNumber);
+                // now process all of the fetch responses before releasing the folder lock.
+                // it's possible that an unsolicited update on another thread might try to
+                // make an update, causing a potential deadlock.
+                for (int i = 0; i < fetches.size(); i++) {
+                    // get the returned data items from each of the fetch responses
+                    // and process.
+                    IMAPFetchResponse fetch = (IMAPFetchResponse)fetches.get(i);
+                    // update the internal info
+                    updateMessageInformation(fetch);
+                }
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+    }
+
+
+    /**
+     * Retrieve the message envelope from the IMAP server, synchronizing the headers with the
+     * information.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void updateEnvelope(IMAPEnvelope envelope) throws MessagingException {
+        // set the envelope item
+        this.envelope = envelope;
+
+        // copy header type information from the envelope into the headers.
+        updateHeader("From", envelope.from);
+        if (envelope.sender != null) {
+            // we can only have a single sender, even though the envelope theoretically supports more.
+            updateHeader("Sender", envelope.sender[0]);
+        }
+        updateHeader("To", envelope.to);
+        updateHeader("Cc", envelope.cc);
+        updateHeader("Bcc", envelope.bcc);
+        updateHeader("Reply-To", envelope.replyTo);
+        // NB:  This is already in encoded form, if needed.
+        updateHeader("Subject", envelope.subject);
+        updateHeader("Message-ID", envelope.messageID);
+    }
+
+
+    /**
+     * Retrieve the BODYSTRUCTURE information from the IMAP server.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void loadBodyStructure() throws MessagingException {
+        // don't retrieve if already loaded.
+        if (bodyStructure != null) {
+            return;
+        }
+
+        // make sure this is in a valid state.
+        checkValidity();
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        synchronized (folder) {
+            IMAPConnection connection = getConnection();
+            try {
+                // fetch the envelope information for this
+                bodyStructure = connection.fetchBodyStructure(sequenceNumber);
+                // go update all of the information
+            } finally {
+                releaseConnection(connection);
+            }
+
+            // update this before we release the folder lock so we can avoid
+            // deadlock.
+            updateBodyStructure(bodyStructure);
+        }
+    }
+
+
+    /**
+     * Update the BODYSTRUCTURE information from the IMAP server.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void updateBodyStructure(IMAPBodyStructure structure) throws MessagingException {
+        // save the reference.
+        bodyStructure = structure;
+        // now update various headers with the information from the body structure
+
+        // now update header information with the body structure data.
+        if (bodyStructure.lines != -1) {
+            updateHeader("Lines", Integer.toString(bodyStructure.lines));
+        }
+
+        // languages are a little more complicated
+        if (bodyStructure.languages != null) {
+            // this is a duplicate of what happens in the super class, but
+            // the superclass methods call setHeader(), which we override and
+            // throw an exception for.  We need to set the headers ourselves.
+            if (bodyStructure.languages.size() == 1) {
+                updateHeader("Content-Language", (String)bodyStructure.languages.get(0));
+            }
+            else {
+                StringBuffer buf = new StringBuffer(bodyStructure.languages.size() * 20);
+                buf.append(bodyStructure.languages.get(0));
+                for (int i = 1; i < bodyStructure.languages.size(); i++) {
+                    buf.append(',').append(bodyStructure.languages.get(i));
+                }
+                updateHeader("Content-Language", buf.toString());
+            }
+        }
+
+        updateHeader("Content-Type", bodyStructure.mimeType.toString());
+        if (bodyStructure.disposition != null) {
+            updateHeader("Content-Disposition", bodyStructure.disposition.toString());
+        }
+
+        updateHeader("Content-Transfer-Encoding", bodyStructure.transferEncoding);
+        updateHeader("Content-ID", bodyStructure.contentID);
+        // NB:  This is already in encoded form, if needed.
+        updateHeader("Content-Description", bodyStructure.contentDescription);
+    }
+
+
+    /**
+     * Load the message content into the Message object.
+     *
+     * @exception MessagingException
+     */
+    protected void loadContent() throws MessagingException {
+        // if we've loaded this already, just return
+        if (content != null) {
+            return;
+        }
+
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        synchronized (folder) {
+            IMAPConnection connection = getConnection();
+            try {
+                // load the content from the server.
+                content = connection.fetchContent(getSequenceNumber(), section);
+            } finally {
+                releaseConnection(connection);
+            }
+        }
+    }
+
+
+    /**
+     * Retrieve the sequence number assigned to this message.
+     *
+     * @return The messages assigned sequence number.  This maps back to the server's assigned number for
+     * this message.
+     */
+    int getSequenceNumber() {
+        return sequenceNumber;
+    }
+
+    /**
+     * Set the sequence number for the message.  This
+     * is updated whenever messages get expunged from
+     * the folder.
+     *
+     * @param s      The new sequence number.
+     */
+    void setSequenceNumber(int s) {
+        sequenceNumber = s;
+    }
+
+
+    /**
+     * Retrieve the message UID value.
+     *
+     * @return The assigned UID value, if we have the information.
+     */
+    long getUID() {
+        return uid;
+    }
+
+    /**
+     * Set the message UID value.
+     *
+     * @param uid    The new UID value.
+     */
+    void setUID(long uid) {
+        this.uid = uid;
+    }
+
+
+    /**
+     * get the current connection pool attached to the folder.  We need
+     * to do this dynamically, to A) ensure we're only accessing an
+     * currently open folder, and B) to make sure we're using the
+     * correct connection attached to the folder.
+     *
+     * @return A connection attached to the hosting folder.
+     */
+    protected IMAPConnection getConnection() throws MessagingException {
+        // the folder owns everything.
+        return ((IMAPFolder)folder).getMessageConnection();
+    }
+
+    /**
+     * Release the connection back to the Folder after performing an operation
+     * that requires a connection.
+     *
+     * @param connection The previously acquired connection.
+     */
+    protected void releaseConnection(IMAPConnection connection) throws MessagingException {
+        // the folder owns everything.
+        ((IMAPFolder)folder).releaseMessageConnection(connection);
+    }
+
+
+    /**
+     * Check the validity of the current message.  This ensures that
+     * A) the folder is currently open, B) that the message has not
+     * been expunged (after getting the latest status from the server).
+     *
+     * @exception MessagingException
+     */
+    protected void checkValidity() throws MessagingException {
+        checkValidity(false);
+    }
+
+
+    /**
+     * Check the validity of the current message.  This ensures that
+     * A) the folder is currently open, B) that the message has not
+     * been expunged (after getting the latest status from the server).
+     *
+     * @exception MessagingException
+     */
+    protected void checkValidity(boolean update) throws MessagingException {
+        // we need to ensure that we're the only ones with access to the folder's
+        // message cache any time we need to talk to the server.  This needs to be
+        // held until after we release the connection so that any pending EXPUNGE
+        // untagged responses are processed before the next time the folder connection is
+        // used.
+        if (update) {
+            synchronized (folder) {
+                // have the connection update the folder status.  This might result in this message
+                // changing its state to expunged.  It might also result in an exception if the
+                // folder has been closed.
+                IMAPConnection connection = getConnection();
+
+                try {
+                    connection.updateMailboxStatus();
+                } finally {
+                    // this will force any expunged messages to be processed before we release
+                    // the lock.
+                    releaseConnection(connection);
+                }
+            }
+        }
+
+        // now see if we've been expunged, this is a bad op on the message.
+        if (isExpunged()) {
+            throw new MessageRemovedException("Illegal opertion on a deleted message");
+        }
+    }
+
+
+    /**
+     * Evaluate whether this message requires any of the information
+     * in a FetchProfile to be fetched from the server.  If the messages
+     * already contains the information in the profile, it returns false.
+     * This allows IMAPFolder to optimize fetch() requests to just the
+     * messages that are missing any of the requested information.
+     *
+     * NOTE:  If any of the items in the profile are missing, then this
+     * message will be updated with ALL of the items.
+     *
+     * @param profile The FetchProfile indicating the information that should be prefetched.
+     *
+     * @return true if any of the profile information requires fetching.  false if this
+     *         message already contains the given information.
+     */
+    protected boolean evaluateFetch(FetchProfile profile) {
+        // the fetch profile can contain a number of different item types.  Validate
+        // whether we need any of these and return true on the first mismatch.
+
+        // the UID is a common fetch request, put it first.
+        if (profile.contains(UIDFolder.FetchProfileItem.UID) && uid == -1) {
+            return true;
+        }
+        if (profile.contains(FetchProfile.Item.ENVELOPE) && envelope == null) {
+            return true;
+        }
+        if (profile.contains(FetchProfile.Item.FLAGS) && flags == null) {
+            return true;
+        }
+        if (profile.contains(FetchProfile.Item.CONTENT_INFO) && bodyStructure == null) {
+            return true;
+        }
+        // The following profile items are our implementation of items that the
+        // Sun IMAPFolder implementation supports.
+        if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS) && !allHeadersRetrieved) {
+            return true;
+        }
+        if (profile.contains(IMAPFolder.FetchProfileItem.SIZE) && bodyStructure.bodySize < 0) {
+            return true;
+        }
+        // last bit after checking each of the information types is to see if
+        // particular headers have been requested and whether those are on the
+        // set we do have loaded.
+        String [] requestedHeaders = profile.getHeaderNames();
+
+        // ok, any missing header in the list is enough to force us to request the
+        // information.
+        for (int i = 0; i < requestedHeaders.length; i++) {
+            if (headers.getHeader(requestedHeaders[i]) == null) {
+                return true;
+            }
+        }
+        // this message, at least, does not need anything fetched.
+        return false;
+    }
+
+    /**
+     * Update a message instance with information retrieved via an IMAP FETCH
+     * command.  The command response for this message may contain multiple pieces
+     * that we need to process.
+     *
+     * @param response The response line, which may contain multiple data items.
+     *
+     * @exception MessagingException
+     */
+    void updateMessageInformation(IMAPFetchResponse response) throws MessagingException {
+        // get the list of data items associated with this response.  We can have
+        // a large number of items returned in a single update.
+        List items = response.getDataItems();
+
+        for (int i = 0; i < items.size(); i++) {
+            IMAPFetchDataItem item = (IMAPFetchDataItem)items.get(i);
+
+            switch (item.getType()) {
+                // if the envelope has been requested, we'll end up with all of these items.
+                case IMAPFetchDataItem.ENVELOPE:
+                    // update the envelope and map the envelope items into the headers.
+                    updateEnvelope((IMAPEnvelope)item);
+                    break;
+                case IMAPFetchDataItem.INTERNALDATE:
+                    receivedDate = ((IMAPInternalDate)item).getDate();;
+                    break;
+                case IMAPFetchDataItem.SIZE:
+                    size = ((IMAPMessageSize)item).size;
+                    break;
+                case IMAPFetchDataItem.UID:
+                    uid = ((IMAPUid)item).uid;
+                    // make sure the folder knows about the UID update.
+                    ((IMAPFolder)folder).addToUidCache(new Long(uid), this);
+                    break;
+                case IMAPFetchDataItem.BODYSTRUCTURE:
+                    updateBodyStructure((IMAPBodyStructure)item);
+                    break;
+                    // a partial or full header update
+                case IMAPFetchDataItem.HEADER:
+                {
+                    // if we've fetched the complete set, then replace what we have
+                    IMAPInternetHeader h = (IMAPInternetHeader)item;
+                    if (h.isComplete()) {
+                        // we've got a complete header set now.
+                        this.headers = h.headers;
+                        allHeadersRetrieved = true;
+                    }
+                    else {
+                        // need to merge the requested headers in with
+                        // our existing set.  We need to be careful, since we
+                        // don't want to add duplicates.
+                        mergeHeaders(h.headers);
+                    }
+                }
+                default:
+            }
+        }
+    }
+
+
+    /**
+     * Merge a subset of the requested headers with our existing partial set.
+     * The new set will contain all headers requested from the server, plus
+     * any of our existing headers that were not included in the retrieved set.
+     *
+     * @param newHeaders The retrieved set of headers.
+     */
+    protected synchronized void mergeHeaders(InternetHeaders newHeaders) {
+        // This is sort of tricky to manage.  The input headers object is a fresh set
+        // retrieved from the server, but it's a subset of the headers.  Our existing set
+        // might not be complete, but it may contain duplicates of information in the
+        // retrieved set, plus headers that are not in the retrieved set.  To keep from
+        // adding duplicates, we'll only add headers that are not in the retrieved set to
+        // that set.
+
+        // start by running through the list of headers
+        Enumeration e = headers.getAllHeaders();
+
+        while (e.hasMoreElements()) {
+            Header header = (Header)e.nextElement();
+            // if there are no headers with this name in the new set, then
+            // we can add this.  Note that to add the header, we need to
+            // retrieve all instances by this name and add them as a unit.
+            // When we hit one of the duplicates again with the enumeration,
+            // we'll skip it then because the merge target will have everything.
+            if (newHeaders.getHeader(header.getName()) == null) {
+                // get all occurrences of this name and stuff them into the
+                // new list
+                String name = header.getName();
+                String[] a = headers.getHeader(name);
+                for (int i = 0; i < a.length; i++) {
+                    newHeaders.addHeader(name, a[i]);
+                }
+            }
+        }
+        // and replace the current header set
+        headers = newHeaders;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java
new file mode 100644
index 0000000..9370451
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java
@@ -0,0 +1,359 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+
+import javax.activation.DataHandler;
+import javax.mail.IllegalWriteException;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeUtility;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
+import org.apache.geronimo.mail.util.SessionUtil;
+
+
+public class IMAPMimeBodyPart extends MimeBodyPart {
+    // the message we're part of
+    protected IMAPMessage message;
+    // the retrieved BODYSTRUCTURE information for this part.
+    protected IMAPBodyStructure bodyStructure;
+    // the section identifier.  This will be in a format such as 1.2.3, which 
+    // would refer to the "third part contained in the second part of the first part"...
+    // got all that?  There will be a quiz at the end of class :-)
+    protected String section;
+    // flag to indicate whether the body part headers have been loaded.
+    boolean headersLoaded = false;
+
+    /**
+     * Create an instance of a MimeBodyPart within an 
+     * IMAP message.
+     * 
+     * @param message The parent Message instance containing this part.
+     * @param bodyStructure
+     *                The IMAPBodyStructure information describing the part.
+     * @param section The numeric section identifier string for this part.
+     *                This is a hierarchical set of numbers describing
+     *                how to navigate to the message part on the IMAP
+     *                server.  For example, "2.1.3" would be the third
+     *                subpart of the first subpart of the second main
+     *                message part.
+     */
+    public IMAPMimeBodyPart(IMAPMessage message, IMAPBodyStructure bodyStructure, String section) {
+        super();
+        this.message = message;
+        this.bodyStructure = bodyStructure;
+        this.section = section;
+    }
+
+
+    /**
+     * Get the size of the message part.
+     * 
+     * @return The size information returned in the IMAP body structure.
+     * @exception MessagingException
+     */
+    public int getSize() throws MessagingException {
+        return bodyStructure.bodySize;
+    }
+
+    /**
+     * Get the estimated line count for the body part.
+     * 
+     * @return The line count information returned by the IMAP 
+     *         server.
+     * @exception MessagingException
+     */
+    public int getLineCount() throws MessagingException {
+        return bodyStructure.lines;
+    }
+
+    /**
+     * Get the content type for the body part.
+     * 
+     * @return The mimetype for the body part, in string format.
+     * @exception MessagingException
+     */
+    public String getContentType() throws MessagingException {
+        return bodyStructure.mimeType.toString();
+    }
+
+    /**
+     * Test if the body part is of a particular MIME type.
+     * 
+     * @param type   The string MIME-type name.  A wild card * can be
+     *               specified for the subpart type.
+     * 
+     * @return true if the body part matches the give MIME-type.
+     * @exception MessagingException
+     */
+    public boolean isMimeType(String type) throws MessagingException {
+        return bodyStructure.mimeType.match(type);
+    }
+
+    /**
+     * Retrieve the disposition information about this 
+     * body part.
+     * 
+     * @return The disposition information, as a string value.
+     * @exception MessagingException
+     */
+    public String getDisposition() throws MessagingException {
+        return bodyStructure.disposition.getDisposition();
+    }
+
+    /**
+     * Set the disposition information.  The IMAP message 
+     * is read-only, so this is an error.
+     * 
+     * @param disposition
+     *               The disposition string.
+     * 
+     * @exception MessagingException
+     */
+    public void setDisposition(String disposition) throws MessagingException {
+        throw new IllegalWriteException("IMAP message parts are read-only");
+    }
+
+    public String getEncoding() throws MessagingException {
+        return bodyStructure.transferEncoding;
+    }
+
+    public String getContentID() throws MessagingException {
+        return bodyStructure.contentID;
+    }
+
+    public void setContentID(String id) throws MessagingException {
+        throw new IllegalWriteException("IMAP message parts are read-only");
+    }
+
+    public String getContentMD5() throws MessagingException {
+        return bodyStructure.md5Hash;
+    }
+
+    public void setContentMD5(String id) throws MessagingException {
+        throw new IllegalWriteException("IMAP message parts are read-only");
+    }
+
+    public String getDescription() throws MessagingException {
+        String description = bodyStructure.contentDescription;
+        if (description != null) {
+            try {
+                // this could be both folded and encoded.  Return this to usable form.
+                return MimeUtility.decodeText(MimeUtility.unfold(description));
+            } catch (UnsupportedEncodingException e) {
+                // ignore
+            }
+        }
+        // return the raw version for any errors (this might be null also)
+        return description;
+    }
+
+    public void setDescription(String d, String charset) throws MessagingException {
+        throw new IllegalWriteException("IMAP message parts are read-only");
+    }
+
+    public String getFileName() throws MessagingException {
+        String filename = bodyStructure.disposition.getParameter("filename");
+        if (filename == null) {
+            filename = bodyStructure.mimeType.getParameter("name");
+        }
+        
+        // if we have a name, we might need to decode this if an additional property is set.
+        if (filename != null && SessionUtil.getBooleanProperty(MIME_DECODEFILENAME, false)) {
+            try {
+                filename = MimeUtility.decodeText(filename);
+            } catch (UnsupportedEncodingException e) {
+                throw new MessagingException("Unable to decode filename", e);
+            }
+        }
+        
+        return filename;
+    }
+
+    public void setFileName(String name) throws MessagingException {
+        throw new IllegalWriteException("IMAP message parts are read-only");
+    }
+
+    protected InputStream getContentStream() throws MessagingException {
+
+        // no content loaded yet?
+        if (content == null) {
+            // make sure we're still valid
+            message.checkValidity();
+            // make sure the content is fully loaded
+            loadContent();
+        }
+
+        // allow the super class to handle creating it from the loaded content.
+        return super.getContentStream();
+    }
+
+
+    /**
+     * Create the DataHandler object for this message.
+     *
+     * @return The DataHandler object that processes the content set for this
+     *         message.
+     * @exception MessagingException
+     */
+    public synchronized DataHandler getDataHandler() throws MessagingException {
+        if (dh == null) {                                                
+            // are we working with a multipart message here?
+            if (bodyStructure.isMultipart()) {
+                dh = new DataHandler(new IMAPMultipartDataSource(message, this, section, bodyStructure));
+                return dh;
+            }
+            else if (bodyStructure.isAttachedMessage()) {
+                dh = new DataHandler(new IMAPAttachedMessage(message, section, bodyStructure.nestedEnvelope, 
+                    bodyStructure.nestedBody), bodyStructure.mimeType.toString());
+                return dh;
+            }
+        }
+
+        // single part messages get handled the normal way.
+        return super.getDataHandler();
+    }
+
+    public void setDataHandler(DataHandler content) throws MessagingException {
+        throw new IllegalWriteException("IMAP body parts are read-only");
+    }
+
+    public void setContent(Object o, String type) throws MessagingException {
+        throw new IllegalWriteException("IMAP body parts are read-only");
+    }
+
+    public void setContent(Multipart mp) throws MessagingException {
+        throw new IllegalWriteException("IMAP body parts are read-only");
+    }
+
+
+	/******************************************************************
+	 * Following is a set of methods that deal with headers
+	 * These methods are just overrides on the superclass methods to
+     * allow lazy loading of the header information.
+	 ********************************************************************/
+
+	public String[] getHeader(String name) throws MessagingException {
+        loadHeaders();
+		return headers.getHeader(name);
+	}
+
+	public String getHeader(String name, String delimiter) throws MessagingException {
+        loadHeaders();
+		return headers.getHeader(name, delimiter);
+	}
+
+	public Enumeration getAllHeaders() throws MessagingException {
+        loadHeaders();
+		return headers.getAllHeaders();
+	}
+
+	public Enumeration getMatchingHeaders(String[] names)  throws MessagingException {
+        loadHeaders();
+		return headers.getMatchingHeaders(names);
+	}
+
+	public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
+        loadHeaders();
+		return headers.getNonMatchingHeaders(names);
+	}
+
+	public Enumeration getAllHeaderLines() throws MessagingException {
+        loadHeaders();
+		return headers.getAllHeaderLines();
+	}
+
+	public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+		return headers.getMatchingHeaderLines(names);
+	}
+
+	public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+		return headers.getNonMatchingHeaderLines(names);
+	}
+
+    // the following are overrides for header modification methods.  These messages are read only,
+    // so the headers cannot be modified.
+    public void addHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void setHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+
+    public void removeHeader(String name) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    public void addHeaderLine(String line) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+
+    /**
+     * Load the mime part headers into this body part.
+     *
+     * @exception MessagingException
+     */
+    protected synchronized void loadHeaders() throws MessagingException {
+        // have them already?  Super..
+        if (headers != null) {
+            return;
+        }
+                           
+        IMAPConnection connection = message.getConnection();
+        try {
+            // this asks for the MIME subsection of the given section piece.
+            headers = connection.fetchHeaders(message.getSequenceNumber(), section);
+        } finally {    
+            message.releaseConnection(connection);
+        }
+
+    }
+
+
+    /**
+     * Load the message content into the BodyPart object.
+     *
+     * @exception MessagingException
+     */
+    protected void loadContent() throws MessagingException {
+        // if we've loaded this already, just return
+        if (content != null) {
+            return;
+        }
+        
+        IMAPConnection connection = message.getConnection();
+        try {
+            // load the content from the server. 
+            content = connection.fetchContent(message.getSequenceNumber(), section); 
+        } finally {
+            message.releaseConnection(connection); 
+        }
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java
new file mode 100644
index 0000000..30c2515
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java
@@ -0,0 +1,56 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
+import javax.mail.MultipartDataSource;
+
+import javax.mail.internet.MimePart;
+import javax.mail.internet.MimePartDataSource;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
+
+public class IMAPMultipartDataSource extends MimePartDataSource implements MultipartDataSource {
+    // the list of parts
+    protected BodyPart[] parts;
+
+    IMAPMultipartDataSource(IMAPMessage message, MimePart parent, String section, IMAPBodyStructure bodyStructure) {
+        super(parent);
+
+        parts = new BodyPart[bodyStructure.parts.length];
+        
+        // We're either created from the parent message, in which case we're the top level 
+        // of the hierarchy, or we're created from a nested message, so we need to apply the 
+        // parent numbering prefix. 
+        String sectionBase = section == null ? "" : section + "."; 
+
+        for (int i = 0; i < parts.length; i++) {
+            // create a section id.  This is either the count (origin zero) or a subpart of the previous section.
+            parts[i] = new IMAPMimeBodyPart(message, (IMAPBodyStructure)bodyStructure.parts[i], sectionBase + (i + 1));
+        }
+    }
+
+    public int getCount() {
+        return parts.length;
+    }
+
+    public BodyPart getBodyPart(int index) throws MessagingException {
+        return parts[index];
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java
new file mode 100644
index 0000000..3349830
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java
@@ -0,0 +1,51 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespace;
+
+/**
+ * An override of the base IMAPFolder class for folders representing namespace roots. 
+ * @see javax.mail.Folder
+ *
+ * @version $Rev: 594520 $
+ */
+public class IMAPNamespaceFolder extends IMAPFolder {
+    
+    IMAPNamespaceFolder(IMAPStore store, IMAPNamespace namespace) {
+        // initialize with the namespace information 
+        super(store, namespace.prefix, namespace.separator); 
+    }
+    
+    
+    /**
+     * Override of the default IMAPFolder method to provide the mailbox name 
+     * as the prefix + delimiter. 
+     * 
+     * @return The string name to use as the mailbox name for exists() and issubscribed() 
+     *         calls.
+     */
+    protected String getMailBoxName() {
+        // no delimiter is a possibility, so 
+        // we need to check.  
+        if (separator == '\0') {
+            return fullname;
+        }
+        return fullname + separator; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java
new file mode 100644
index 0000000..dce9420
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java
@@ -0,0 +1,131 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import javax.mail.Folder; 
+import javax.mail.Message; 
+import javax.mail.MessagingException; 
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Store; 
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure; 
+
+/**
+ * An IMAP folder instance for the root of IMAP folder tree.  This has 
+ * some of the folder operations disabled. 
+ */
+public class IMAPRootFolder extends IMAPFolder {
+    
+    /**
+     * Create a default IMAPRootFolder attached to a specific Store instance.
+     * 
+     * @param store  The Store instance this is the root for.
+     */
+    public IMAPRootFolder(IMAPStore store) {
+        // create a folder with a null string name and the default separator. 
+        super(store, "", '/'); 
+        // this only holds folders 
+        folderType = HOLDS_FOLDERS; 
+    }
+
+    /**
+     * Get the Folder determined by the supplied name; if the name is relative
+     * then it is interpreted relative to this folder. This does not check that
+     * the named folder actually exists.
+     *
+     * @param name the name of the folder to return
+     * @return the named folder
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        // The root folder is a dummy one.  Any getFolder() request starting 
+        // at the root will use the request name for the full name.  The separator 
+        // used in that folder's namespace will be determined when the folder is 
+        // first opened. 
+        return new IMAPFolder((IMAPStore)store, name, UNDETERMINED);
+    }
+    
+    
+    public Folder getParent() {
+        // we never have a parent folder 
+        return null; 
+    }
+    
+    
+    public boolean exists() throws MessagingException {
+        // this always exists 
+        return true; 
+    }
+    
+    public boolean hasNewMessages() {
+        // we don't really exist, so the answer is always false. 
+        return false; 
+    }
+    
+    
+    public int getMessagesCount() {
+        // we don't really exist, so the answer is always 0; 
+        return 0; 
+    }
+    
+    
+    public int getNewMessagesCount() {
+        // we don't really exist, so the answer is always 0; 
+        return 0; 
+    }
+    
+    
+    public int getUnreadMessagesCount() {
+        // we don't really exist, so the answer is always 0; 
+        return 0; 
+    }
+    
+    
+    public int getDeletedMessagesCount() {
+        // we don't really exist, so the answer is always 0; 
+        return 0; 
+    }
+    
+    
+	public boolean create(int newType) throws MessagingException {
+        throw new MethodNotSupportedException("Default IMAP folder cannot be created"); 
+    }
+    
+    public boolean delete(boolean recurse) throws MessagingException {
+        throw new MethodNotSupportedException("Default IMAP folder cannot be deleted"); 
+    }
+    
+    
+    public boolean rename(boolean recurse) throws MessagingException {
+        throw new MethodNotSupportedException("Default IMAP folder cannot be renamed"); 
+    }
+    
+    
+    public void appendMessages(Message[] msgs) throws MessagingException {
+        throw new MethodNotSupportedException("Messages cannot be appended to Default IMAP folder"); 
+    }
+    
+    
+    public Message[] expunge() throws MessagingException {
+        throw new MethodNotSupportedException("Messages cannot be expunged from Default IMAP folder"); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java
new file mode 100644
index 0000000..110f3c3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java
@@ -0,0 +1,42 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import javax.mail.Session;
+import javax.mail.URLName;
+
+/**
+ * IMAP implementation of javax.mail.Store for SSL connections. 
+ *
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+public class IMAPSSLStore extends IMAPStore {
+    /**
+     * Construct an IMAPSSLStore item.
+     *
+     * @param session The owning javamail Session.
+     * @param urlName The Store urlName, which can contain server target information.
+     */
+	public IMAPSSLStore(Session session, URLName urlName) {
+        // we're the imaps protocol, our default connection port is 993, and we must use
+        // an SSL connection for the initial hookup 
+		super(session, urlName, "imaps", true, DEFAULT_IMAP_SSL_PORT);
+	}
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java
new file mode 100644
index 0000000..215557b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java
@@ -0,0 +1,614 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.mail.AuthenticationFailedException;
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+import javax.mail.Quota;
+import javax.mail.QuotaAwareStore;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+import javax.mail.event.StoreEvent; 
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPConnectionPool; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPOkResponse; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespaceResponse; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespace; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPServerStatusResponse; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponse; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponseHandler; 
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+
+/**
+ * IMAP implementation of javax.mail.Store
+ * POP protocol spec is implemented in
+ * org.apache.geronimo.javamail.store.pop3.IMAPConnection
+ *
+ * @version $Rev: 707037 $ $Date: 2008-10-22 07:34:53 -0400 (Wed, 22 Oct 2008) $
+ */
+
+public class IMAPStore extends Store implements QuotaAwareStore, IMAPUntaggedResponseHandler {
+    // the default connection ports for secure and non-secure variations
+    protected static final int DEFAULT_IMAP_PORT = 143;
+    protected static final int DEFAULT_IMAP_SSL_PORT = 993;
+    
+    protected static final String MAIL_STATUS_TIMEOUT = "statuscacheimeout";
+    protected static final int DEFAULT_STATUS_TIMEOUT = 1000; 
+    
+    // our accessor for protocol properties and the holder of 
+    // protocol-specific information 
+    protected ProtocolProperties props; 
+
+    // the connection pool we use for access 
+	protected IMAPConnectionPool connectionPool;
+
+    // the root folder
+    protected IMAPRootFolder root;
+
+    // the list of open folders (which also represents an open connection).
+    protected List openFolders = new LinkedList();
+
+    // our session provided debug output stream.
+    protected PrintStream debugStream;
+    // the debug flag 
+    protected boolean debug; 
+    // until we're connected, we're closed 
+    boolean closedForBusiness = true; 
+    // The timeout value for our status cache 
+    long statusCacheTimeout = 0; 
+
+    /**
+     * Construct an IMAPStore item.
+     *
+     * @param session The owning javamail Session.
+     * @param urlName The Store urlName, which can contain server target information.
+     */
+	public IMAPStore(Session session, URLName urlName) {
+        // we're the imap protocol, our default connection port is 119, and don't use 
+        // an SSL connection for the initial hookup 
+		this(session, urlName, "imap", false, DEFAULT_IMAP_PORT);
+	}
+                                                          
+    /**
+     * Protected common constructor used by both the IMAPStore and the IMAPSSLStore
+     * to initialize the Store instance. 
+     * 
+     * @param session  The Session we're attached to.
+     * @param urlName  The urlName.
+     * @param protocol The protocol name.
+     * @param sslConnection
+     *                 The sslConnection flag.
+     * @param defaultPort
+     *                 The default connection port.
+     */
+    protected IMAPStore(Session session, URLName urlName, String protocol, boolean sslConnection, int defaultPort) {
+        super(session, urlName); 
+        // create the protocol property holder.  This gives an abstraction over the different 
+        // flavors of the protocol. 
+        props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
+        
+        // get the status timeout value for the folders. 
+        statusCacheTimeout = props.getIntProperty(MAIL_STATUS_TIMEOUT, DEFAULT_STATUS_TIMEOUT);
+
+        // get our debug settings
+        debugStream = session.getDebugOut();
+        debug = session.getDebug(); 
+        
+        // create a connection pool we can retrieve connections from 
+        connectionPool = new IMAPConnectionPool(this, props); 
+    }
+    
+    
+    /**
+     * Attempt the protocol-specific connection; subclasses should override this to establish
+     * a connection in the appropriate manner.
+     * 
+     * This method should return true if the connection was established.
+     * It may return false to cause the {@link #connect(String, int, String, String)} method to
+     * reattempt the connection after trying to obtain user and password information from the user.
+     * Alternatively it may throw a AuthenticatedFailedException to abandon the conection attempt.
+     * 
+     * @param host     The target host name of the service.
+     * @param port     The connection port for the service.
+     * @param user     The user name used for the connection.
+     * @param password The password used for the connection.
+     * 
+     * @return true if a connection was established, false if there was authentication 
+     *         error with the connection.
+     * @throws AuthenticationFailedException
+     *                if authentication fails
+     * @throws MessagingException
+     *                for other failures
+     */
+	protected synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        if (debug) {
+            debugOut("Connecting to server " + host + ":" + port + " for user " + username);
+        }
+
+        // the connection pool handles all of the details here. 
+        if (connectionPool.protocolConnect(host, port, username, password)) 
+        {
+            // the store is now open 
+            closedForBusiness = false; 
+            return true; 
+        }
+        return false; 
+	}
+
+
+    /**
+     * Close this service and terminate its physical connection.
+     * The default implementation simply calls setConnected(false) and then
+     * sends a CLOSED event to all registered ConnectionListeners.
+     * Subclasses overriding this method should still ensure it is closed; they should
+     * also ensure that it is called if the connection is closed automatically, for
+     * for example in a finalizer.
+     *
+     *@throws MessagingException if there were errors closing; the connection is still closed
+     */
+	public synchronized void close() throws MessagingException{
+        // if already closed, nothing to do. 
+        if (closedForBusiness) {
+            return; 
+        }
+        
+        // close the folders first, then shut down the Store. 
+        closeOpenFolders();
+        
+        connectionPool.close(); 
+        connectionPool = null; 
+
+		// make sure we do the superclass close operation first so 
+        // notification events get broadcast properly. 
+		super.close();
+	}
+
+
+    /**
+     * Return a Folder object that represents the root of the namespace for the current user.
+     *
+     * Note that in some store configurations (such as IMAP4) the root folder might
+     * not be the INBOX folder.
+     *
+     * @return the root Folder
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public Folder getDefaultFolder() throws MessagingException {
+		checkConnectionStatus();
+        // if no root yet, create a root folder instance. 
+        if (root == null) {
+            return new IMAPRootFolder(this);
+        }
+        return root;
+	}
+
+    /**
+     * Return the Folder corresponding to the given name.
+     * The folder might not physically exist; the {@link Folder#exists()} method can be used
+     * to determine if it is real.
+     * 
+     * @param name   the name of the Folder to return
+     * 
+     * @return the corresponding folder
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+	public Folder getFolder(String name) throws MessagingException {
+        return getDefaultFolder().getFolder(name);
+	}
+
+    
+    /**
+     * Return the folder identified by the URLName; the URLName must refer to this Store.
+     * Implementations may use the {@link URLName#getFile()} method to determined the folder name.
+     * 
+     * @param url
+     * 
+     * @return the corresponding folder
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+	public Folder getFolder(URLName url) throws MessagingException {
+        return getDefaultFolder().getFolder(url.getFile());
+	}
+
+    
+    /**
+     * Return the root folders of the personal namespace belonging to the current user.
+     *
+     * The default implementation simply returns an array containing the folder returned by {@link #getDefaultFolder()}.
+     * @return the root folders of the user's peronal namespaces
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder[] getPersonalNamespaces() throws MessagingException {
+        IMAPNamespaceResponse namespaces = getNamespaces(); 
+        
+        // if nothing is returned, then use the API-defined default for this 
+        if (namespaces.personalNamespaces.size() == 0) {
+            return super.getPersonalNamespaces(); 
+        }
+        
+        // convert the list into an array of Folders. 
+        return getNamespaceFolders(namespaces.personalNamespaces); 
+    }
+    
+    
+    /**
+     * Return the root folders of the personal namespaces belonging to the supplied user.
+     *
+     * The default implementation simply returns an empty array.
+     *
+     * @param user the user whose namespaces should be returned
+     * @return the root folders of the given user's peronal namespaces
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder[] getUserNamespaces(String user) throws MessagingException {
+        IMAPNamespaceResponse namespaces = getNamespaces(); 
+        
+        // if nothing is returned, then use the API-defined default for this 
+        if (namespaces.otherUserNamespaces == null || namespaces.otherUserNamespaces.isEmpty()) {
+            return super.getUserNamespaces(user); 
+        }
+        
+        // convert the list into an array of Folders. 
+        return getNamespaceFolders(namespaces.otherUserNamespaces); 
+    }
+
+    
+    /**
+     * Return the root folders of namespaces that are intended to be shared between users.
+     *
+     * The default implementation simply returns an empty array.
+     * @return the root folders of all shared namespaces
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder[] getSharedNamespaces() throws MessagingException {
+        IMAPNamespaceResponse namespaces = getNamespaces(); 
+        
+        // if nothing is returned, then use the API-defined default for this 
+        if (namespaces.sharedNamespaces == null || namespaces.sharedNamespaces.isEmpty()) {
+            return super.getSharedNamespaces(); 
+        }
+        
+        // convert the list into an array of Folders. 
+        return getNamespaceFolders(namespaces.sharedNamespaces); 
+    }
+    
+    
+    /**
+     * Get the quotas for the specified root element.
+     *
+     * @param root   The root name for the quota information.
+     *
+     * @return An array of Quota objects defined for the root.
+     * @throws MessagingException if the quotas cannot be retrieved
+     */
+    public Quota[] getQuota(String root) throws javax.mail.MessagingException {
+        // get our private connection for access 
+        IMAPConnection connection = getStoreConnection(); 
+        try {
+            // request the namespace information from the server 
+            return connection.fetchQuota(root); 
+        } finally {
+            releaseStoreConnection(connection); 
+        }
+    }
+
+    /**
+     * Set a quota item.  The root contained in the Quota item identifies
+     * the quota target.
+     *
+     * @param quota  The source quota item.
+     * @throws MessagingException if the quota cannot be set
+     */
+    public void setQuota(Quota quota) throws javax.mail.MessagingException {
+        // get our private connection for access 
+        IMAPConnection connection = getStoreConnection(); 
+        try {
+            // request the namespace information from the server 
+            connection.setQuota(quota); 
+        } finally {
+            releaseStoreConnection(connection); 
+        }
+    }
+
+    /**
+     * Verify that the server is in a connected state before 
+     * performing operations that required that status. 
+     * 
+     * @exception MessagingException
+     */
+	private void checkConnectionStatus() throws MessagingException {
+        // we just check the connection status with the superclass.  This 
+        // tells us we've gotten a connection.  We don't want to do the 
+        // complete connection checks that require pinging the server. 
+		if (!super.isConnected()){
+		    throw new MessagingException("Not connected ");
+	    }
+	}
+
+
+    /**
+     * Test to see if we're still connected.  This will ping the server
+     * to see if we're still alive.
+     *
+     * @return true if we have a live, active culture, false otherwise.
+     */
+    public synchronized boolean isConnected() {
+        // check if we're in a presumed connected state.  If not, we don't really have a connection
+        // to check on.
+        if (!super.isConnected()) {
+            return false;
+        }
+        
+        try {
+            IMAPConnection connection = getStoreConnection(); 
+            try {
+                // check with the connecition to see if it's still alive. 
+                // we use a zero timeout value to force it to check. 
+                return connection.isAlive(0);
+            } finally {
+                releaseStoreConnection(connection); 
+            }
+        } catch (MessagingException e) {
+            return false; 
+        }
+        
+    }
+
+    /**
+     * Internal debug output routine.
+     *
+     * @param value  The string value to output.
+     */
+    void debugOut(String message) {
+        debugStream.println("IMAPStore DEBUG: " + message);
+    }
+
+    /**
+     * Internal debugging routine for reporting exceptions.
+     *
+     * @param message A message associated with the exception context.
+     * @param e       The received exception.
+     */
+    void debugOut(String message, Throwable e) {
+        debugOut("Received exception -> " + message);
+        debugOut("Exception message -> " + e.getMessage());
+        e.printStackTrace(debugStream);
+    }
+
+
+    /**
+     * Retrieve the server connection created by this store.
+     *
+     * @return The active connection object.
+     */
+    protected IMAPConnection getStoreConnection() throws MessagingException {
+        return connectionPool.getStoreConnection(); 
+    }
+    
+    protected void releaseStoreConnection(IMAPConnection connection) throws MessagingException {
+        // This is a bit of a pain.  We need to delay processing of the 
+        // unsolicited responses until after each user of the connection has 
+        // finished processing the expected responses.  We need to do this because 
+        // the unsolicited responses may include EXPUNGED messages.  The EXPUNGED 
+        // messages will alter the message sequence numbers for the messages in the 
+        // cache.  Processing the EXPUNGED messages too early will result in 
+        // updates getting applied to the wrong message instances.  So, as a result, 
+        // we delay that stage of the processing until all expected responses have 
+        // been handled.  
+        
+        // process any pending messages before returning. 
+        connection.processPendingResponses(); 
+        // return this to the connectin pool 
+        connectionPool.releaseStoreConnection(connection); 
+    }
+    
+    synchronized IMAPConnection getFolderConnection(IMAPFolder folder) throws MessagingException {
+        IMAPConnection connection = connectionPool.getFolderConnection(); 
+        openFolders.add(folder);
+        return connection; 
+    }
+    
+    
+    synchronized void releaseFolderConnection(IMAPFolder folder, IMAPConnection connection) throws MessagingException {
+        openFolders.remove(folder); 
+        // return this to the connectin pool 
+        // NB:  It is assumed that the Folder has already triggered handling of 
+        // unsolicited responses on this connection before returning it. 
+        connectionPool.releaseFolderConnection(connection); 
+    }
+
+
+    /**
+     * Retrieve the Session object this Store is operating under.
+     *
+     * @return The attached Session instance.
+     */
+    Session getSession() {
+        return session;
+    }
+    
+    /**
+     * Close all open folders.  We have a small problem here with a race condition.  There's no safe, single
+     * synchronization point for us to block creation of new folders while we're closing.  So we make a copy of
+     * the folders list, close all of those folders, and keep repeating until we're done.
+     */
+    protected void closeOpenFolders() {
+        // we're no longer accepting additional opens.  Any folders that open after this point will get an
+        // exception trying to get a connection.
+        closedForBusiness = true;
+
+        while (true) {
+            List folders = null;
+
+            // grab our lock, copy the open folders reference, and null this out.  Once we see a null
+            // open folders ref, we're done closing.
+            synchronized(connectionPool) {
+                folders = openFolders;
+                openFolders = new LinkedList();
+            }
+
+            // null folder, we're done
+            if (folders.isEmpty()) {
+                return;
+            }
+            // now close each of the open folders.
+            for (int i = 0; i < folders.size(); i++) {
+                IMAPFolder folder = (IMAPFolder)folders.get(i);
+                try {
+                    folder.close(false);
+                } catch (MessagingException e) {
+                }
+            }
+        }
+    }
+    
+    /**
+     * Get the namespace information from the IMAP server.
+     * 
+     * @return An IMAPNamespaceResponse with the namespace information. 
+     * @exception MessagingException
+     */
+    protected IMAPNamespaceResponse getNamespaces() throws MessagingException {
+        // get our private connection for access 
+        IMAPConnection connection = getStoreConnection(); 
+        try {
+            // request the namespace information from the server 
+            return connection.getNamespaces(); 
+        } finally {
+            releaseStoreConnection(connection); 
+        }
+    }
+    
+    
+    /**
+     * Convert a List of IMAPNamespace definitions into an array of Folder 
+     * instances. 
+     * 
+     * @param namespaces The namespace List
+     * 
+     * @return An array of the same size as the namespace list containing a Folder 
+     *         instance for each defined namespace.
+     * @exception MessagingException
+     */
+    protected Folder[] getNamespaceFolders(List namespaces) throws MessagingException {
+        Folder[] folders = new Folder[namespaces.size()]; 
+        
+        // convert each of these to a Folder instance. 
+        for (int i = 0; i < namespaces.size(); i++) {
+            IMAPNamespace namespace = (IMAPNamespace)namespaces.get(i); 
+            folders[i] = new IMAPNamespaceFolder(this, namespace); 
+        }
+        return folders; 
+    }
+    
+    
+    /**
+     * Test if this connection has a given capability. 
+     * 
+     * @param capability The capability name.
+     * 
+     * @return true if this capability is in the list, false for a mismatch. 
+     */
+    public boolean hasCapability(String capability) {
+        return connectionPool.hasCapability(capability); 
+    }
+    
+    
+    /**
+     * Handle an unsolicited response from the server.  Most unsolicited responses 
+     * are replies to specific commands sent to the server.  The remainder must 
+     * be handled by the Store or the Folder using the connection.  These are 
+     * critical to handle, as events such as expunged messages will alter the 
+     * sequence numbers of the live messages.  We need to keep things in sync.
+     * 
+     * @param response The UntaggedResponse to process.
+     * 
+     * @return true if we handled this response and no further handling is required.  false
+     *         means this one wasn't one of ours.
+     */
+    public boolean handleResponse(IMAPUntaggedResponse response) {
+        // Some sort of ALERT response from the server?
+        // we need to broadcast this to any of the listeners 
+        if (response.isKeyword("ALERT")) {
+            notifyStoreListeners(StoreEvent.ALERT, ((IMAPOkResponse)response).getMessage()); 
+            return true; 
+        }
+        // potentially some sort of unsolicited OK notice.  This is also an event. 
+        else if (response.isKeyword("OK")) {
+            String message = ((IMAPOkResponse)response).getMessage(); 
+            if (message.length() > 0) {
+                notifyStoreListeners(StoreEvent.NOTICE, message); 
+            }
+            return true; 
+        }
+        // potentially some sort of unsolicited notice.  This is also an event. 
+        else if (response.isKeyword("BAD") || response.isKeyword("NO")) {
+            String message = ((IMAPServerStatusResponse)response).getMessage(); 
+            if (message.length() > 0) {
+                notifyStoreListeners(StoreEvent.NOTICE, message); 
+            }
+            return true; 
+        }
+        // this is a BYE response on our connection.  Folders should be handling the 
+        // BYE events on their connections, so we should only be seeing this if 
+        // it's on the store connection.  
+        else if (response.isKeyword("BYE")) {
+            // this is essentially a close event.  We need to clean everything up 
+            try {
+                close();                
+            } catch (MessagingException e) {
+            }
+            return true; 
+        }
+        return false; 
+    }
+    
+    /**
+     * Finalizer to perform IMAPStore() cleanup when 
+     * no longer in use. 
+     * 
+     * @exception Throwable
+     */
+    protected void finalize() throws Throwable {
+        super.finalize(); 
+        close(); 
+    }
+    
+    /**
+     * Retrieve the protocol properties for the Store. 
+     * 
+     * @return The protocol properties bundle. 
+     */
+    ProtocolProperties getProperties() {
+        return props; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java
new file mode 100644
index 0000000..c08ef0f
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java
@@ -0,0 +1,303 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Represents a set of rights associated with a user to manipulate the 
+ * IMAP Store.
+ */
+public class Rights implements Cloneable {
+    
+    /**
+     * An individual right for IMAP Store manipulation.
+     */
+    public static final class Right {
+        // The set of created stores.  The getInstance() method ensures 
+        // that each right is a singleton object. 
+        static private Map rights = new HashMap();
+        
+        /**
+         * lookup (mailbox is visible to LIST/LSUB commands)
+         */
+        public static final Right LOOKUP = getInstance('l'); 
+        /**
+         * read (SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
+         *        SEARCH, COPY from mailbox)
+         */
+        public static final Right READ = getInstance('r'); 
+        /**
+         * keep seen/unseen information across sessions (STORE SEEN flag)
+         */
+        public static final Right KEEP_SEEN = getInstance('s'); 
+        /**
+         * write (STORE flags other than SEEN and DELETED)
+         */
+        public static final Right WRITE = getInstance('w'); 
+        /**
+         * insert (perform APPEND, COPY into mailbox)
+         */
+        public static final Right INSERT = getInstance('i'); 
+        /**
+         * post (send mail to submission address for mailbox,
+         *        not enforced by IMAP4 itself)
+         */
+        public static final Right POST = getInstance('p'); 
+        /**
+         * create (CREATE new sub-mailboxes in any implementation-defined
+         *        hierarchy)
+         */
+        public static final Right CREATE = getInstance('c'); 
+        /**
+         * delete (STORE DELETED flag, perform EXPUNGE)
+         */
+        public static final Right DELETE = getInstance('d'); 
+        /**
+         * administer (perform SETACL)
+         */
+        public static final Right ADMINISTER = getInstance('a'); 
+        
+        // the actual right definition 
+        String right; 
+        
+        /**
+         * Private constructor for an individual Right.  Used by getInstance().
+         * 
+         * @param right  The String name of the right (a single character).
+         */
+        private Right(String right) {
+            this.right = right; 
+        }
+        
+        /**
+         * Get an instance for a right from the single character right value.  The
+         * returned instance will be a singleton for that character value.
+         * 
+         * @param right  The right character value.
+         * 
+         * @return A Right instance that's the mapping for the character value.
+         */
+        public static synchronized Right getInstance(char right) {
+            String name = String.valueOf(right); 
+            Right instance = (Right)rights.get(name); 
+            if (instance == null) {
+                instance = new Right(name); 
+                rights.put(name, instance); 
+            }
+            return instance; 
+        }
+        
+        /**
+         * Return the string value of the Right.  The string value is the character 
+         * used to create the Right with newInstance().
+         * 
+         * @return The string representation of the Right.
+         */
+        public String toString() {
+            return right; 
+        }
+    }
+    
+    /**
+     * The set of Rights contained in this instance.  This is a TreeSet so that
+     * we can create the string value more consistently.
+     */
+    private SortedSet rights = new TreeSet(new RightComparator()); 
+    
+    /**
+     * Construct an empty set of Rights.
+     */
+    public Rights() {
+    }
+    
+    /**
+     * Construct a Rights set from a single Right instance.
+     * 
+     * @param right  The source Right.
+     */
+    public Rights(Right right) {
+        rights.add(right); 
+    }
+    
+    /**
+     * Construct a set of rights from an existing Rights set.  This will copy 
+     * the rights values.
+     * 
+     * @param list   The source Rights instance.
+     */
+    public Rights(Rights list) {
+        add(list); 
+        Rights[] otherRights = list.getRights(); 
+        for (int i = 0; i < otherRights.length; i++) {
+            rights.add(otherRights[i]); 
+        }
+    }
+    
+    /**
+     * Construct a Rights et from a character string.  Each character in the
+     * string represents an individual Right.
+     * 
+     * @param list   The source set of rights.
+     */
+    public Rights(String list) {
+        for (int i = 0; i < list.length(); i++) {
+            rights.add(Right.getInstance(list.charAt(i))); 
+        }
+    }
+    
+    /**
+     * Add a single Right to the set.
+     * 
+     * @param right  The new Right.  If the Rigtht is already part of the Set, this is a nop.
+     */
+    public void add(Right right) {
+        rights.add(right); 
+    }
+    
+    /**
+     * Merge a Rights set with this set.  Duplicates are eliminated.
+     * 
+     * @param list   The source for the added Rights.
+     */
+    public void add(Rights list) {
+        Rights[] otherRights = list.getRights(); 
+        for (int i = 0; i < otherRights.length; i++) {
+            rights.add(otherRights[i]); 
+        }
+    }
+    
+    /**
+     * Clone a set of Rights.
+     */
+    public Object clone() {
+        return new Rights(this); 
+    }
+    
+    /**
+     * Test if a Rights set contains a given Right.
+     * 
+     * @param right  The Right instance to test.
+     * 
+     * @return true if the Right exists in the Set, false otherwise.
+     */
+    public boolean contains(Right right) {
+        return rights.contains(right); 
+    }
+    
+    /**
+     * Test if this Rights set contains all of the Rights contained in another
+     * set.
+     * 
+     * @param list   The source Rights set for the test.
+     * 
+     * @return true if all of the Rights in the source set exist in the target set.
+     */
+    public boolean contains(Rights list) {
+        return rights.containsAll(list.rights); 
+    }
+    
+    /**
+     * Test if two Rights sets are equivalent.
+     * 
+     * @param list   The source rights set.
+     * 
+     * @return true if both Rigths sets contain the same Rights values.
+     */
+    public boolean equals(Rights list) {
+        return rights.equals(list.rights); 
+    }
+    
+    /**
+     * Get an array of Rights contained in the set.
+     * 
+     * @return An array of Rights[] values.
+     */
+    public Rights[] getRights() {
+        Rights[] list = new Rights[rights.size()]; 
+        return (Rights[])rights.toArray(list); 
+    }
+    
+    /**
+     * Compute a hashCode for the Rights set.
+     * 
+     * @return The computed hashCode.
+     */
+    public int hashCode() {
+        return rights.hashCode(); 
+    }
+    
+    /**
+     * Remove a Right from the set.
+     * 
+     * @param right  The single Right to remove.
+     */
+    public void remove(Right right) {
+        rights.remove(right); 
+    }
+    
+    /**
+     * Remove a set of rights from the set.
+     * 
+     * @param list   The list of rights to be removed.
+     */
+    public void remove(Rights list) {
+        rights.removeAll(list.rights); 
+    }
+    
+    /**
+     * Return a string value for the Rights set.  The string value is the 
+     * concatenation of the single-character Rights names. 
+     * 
+     * @return The string representation of this Rights set. 
+     */
+    public String toString() {
+        StringBuffer buff = new StringBuffer(); 
+        Iterator i = rights.iterator(); 
+        while (i.hasNext()) {
+            buff.append(i.next().toString()); 
+        }
+        return buff.toString(); 
+    }
+    
+    class RightComparator implements Comparator {
+        /**
+         * Perform a sort comparison to order two Right objects.
+         * The sort is performed using the string value. 
+         * 
+         * @param o1     The left comparator
+         * @param o2     The right comparator.
+         * 
+         * @return 0 if the two items have equal ordering, -1 if the 
+         *         left item is lower, 1 if the left item is greater.
+         */
+        public int compare(Object o1, Object o2) {
+            // compare on the string value 
+            String left = o1.toString(); 
+            return left.compareTo(o2.toString()); 
+        }
+    }
+    
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java
new file mode 100644
index 0000000..46ed792
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java
@@ -0,0 +1,52 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.ACL;
+import org.apache.geronimo.javamail.store.imap.Rights;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPACLResponse extends IMAPUntaggedResponse {
+    public String mailbox; 
+    public ACL[] acls; 
+    
+    public IMAPACLResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("ACL",  data); 
+        
+        mailbox = source.readEncodedString();
+        List temp = new ArrayList(); 
+        
+        while (source.hasMore()) {
+            String name = source.readString(); 
+            String rights = source.readString(); 
+            temp.add(new ACL(name, new Rights(rights))); 
+        }
+        
+        acls = new ACL[temp.size()]; 
+        acls = (ACL[])temp.toArray(acls); 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java
new file mode 100644
index 0000000..9efe633
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java
@@ -0,0 +1,78 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.mail.MessagingException;
+
+
+/**
+ * The full body content of a message.
+ */
+public class IMAPBody extends IMAPFetchBodyPart {
+    // the body content data
+    byte[] content = null;
+
+    /**
+     * Construct a top-level MessageText data item. 
+     * 
+     * @param data   The data for the Message Text     
+     * 
+     * @exception MessagingException
+     */
+    public IMAPBody(byte[] data) throws MessagingException {
+        this(new IMAPBodySection(IMAPBodySection.BODY), data);
+    }
+    
+    /**
+     * Create a Message Text instance. 
+     * 
+     * @param section The section information.  This may include substring information if this
+     *                was just a partical fetch.
+     * @param data    The message content data.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPBody(IMAPBodySection section, byte[] data) throws MessagingException {
+        super(BODY, section);
+        // save the content 
+        content = data; 
+    }
+
+
+    /**
+     * Get the part content as a byte array.
+     *
+     * @return The part content as a byte array.
+     */
+    public byte[] getContent() {
+        return content;
+    }
+
+    /**
+     * Get an input stream for reading the part content.
+     *
+     * @return An ByteArrayInputStream sourced to the part content.
+     */
+    public InputStream getInputStream() {
+        return new ByteArrayInputStream(content);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java
new file mode 100644
index 0000000..cb2dc35
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java
@@ -0,0 +1,273 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.util.ResponseFormatException; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Class to represent a FETCH response BODY segment qualifier.  The qualifier is 
+ * of the form "BODY[<section>]<<partial>>".  The optional section qualifier is 
+ * a "." separated part specifiers.  A part specifier is either a number, or 
+ * one of the tokens HEADER, HEADER.FIELD, HEADER.FIELD.NOT, MIME, and TEXT.  
+ * The partial specification is in the form "<start.length>". 
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPBodySection {
+    // the section type qualifiers 
+    static public final int BODY = 0; 
+    static public final int HEADERS = 1; 
+    static public final int HEADERSUBSET = 2; 
+    static public final int MIME = 3;
+    static public final int TEXT = 4; 
+    
+    // the optional part number 
+    public String partNumber = "1"; 
+    // the string name of the section 
+    public String sectionName = ""; 
+    // the section qualifier 
+    public int section; 
+    // the starting substring position 
+    public int start = -1; 
+    // the substring length (requested)
+    public int length = -1; 
+    // the list of any explicit header names 
+    public List headers = null; 
+    
+    /**
+     * Construct a simple-toplevel BodySection tag.
+     * 
+     * @param section The section identifier.
+     */
+    public IMAPBodySection(int section) {
+        this.section = section; 
+        partNumber = "1"; 
+        start = -1; 
+        length = -1; 
+    }
+    
+    /**
+     * construct a BodySegment descriptor from the FETCH returned name. 
+     * 
+     * @param name   The name code, which may be encoded with a section identifier and
+     *               substring qualifiers.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPBodySection(IMAPResponseTokenizer source) throws MessagingException {
+        
+        // this could be just "BODY" alone.  
+        if (!source.peek(false, true).isType('[')) {
+            // complete body, all other fields take default  
+            section = BODY;             
+            return; 
+        }
+        
+        // now we need to scan along this, building up the pieces as we go. 
+        // NOTE:  The section identifiers use "[", "]", "." as delimiters, which 
+        // are normally acceptable in ATOM names.  We need to use the expanded 
+        // delimiter set to parse these tokens off. 
+        Token token = source.next(false, true); 
+        // the first token was the "[", now step to the next token in line. 
+        token = source.next(false, true); 
+        
+        if (token.isType(Token.NUMERIC)) {
+            token = parsePartNumber(token, source); 
+        }
+        
+        // have a potential name here?
+        if (token.isType(Token.ATOM)) {
+            token = parseSectionName(token, source); 
+        }
+        
+        // the HEADER.FIELD and HEADER.FIELD.NOT section types 
+        // are followed by a list of header names. 
+        if (token.isType('(')) {
+            token = parseHeaderList(source); 
+        }
+        
+        // ok, in theory, our current token should be a ']'
+        if (!token.isType(']')) {
+            throw new ResponseFormatException("Invalid section identifier on FETCH response"); 
+        }
+        
+        // do we have a substring qualifier?
+        // that needs to be stripped off too 
+        parseSubstringValues(source); 
+        
+        // now fill in the type information 
+        if (sectionName.equals("")) {
+            section = BODY; 
+        }
+        else if (sectionName.equals("HEADER")) {
+            section = HEADERS; 
+        }
+        else if (sectionName.equals("HEADER.FIELDS")) {
+            section = HEADERSUBSET; 
+        }
+        else if (sectionName.equals("HEADER.FIELDS.NOT")) {
+            section = HEADERSUBSET; 
+        }
+        else if (sectionName.equals("TEXT")) {
+            section = TEXT; 
+        }
+        else if (sectionName.equals("MIME")) {
+            section = MIME; 
+        }
+    }
+    
+    
+    /**
+     * Strip the part number off of a BODY section identifier.  The part number 
+     * is a series of "." separated tokens.  So "BODY[3.2.1]" would be the BODY for 
+     * section 3.2.1 of a multipart message.  The section may also have a qualifier
+     * name on the end.  "BODY[3.2.1.HEADER}" would be the HEADERS for that 
+     * body section.  The return value is the name of the section, which can 
+     * be a "" or the the section qualifier (e.g., "HEADER"). 
+     * 
+     * @param name   The section name.
+     * 
+     * @return The remainder of the section name after the numeric part number has 
+     *         been removed.
+     */
+    private Token parsePartNumber(Token token, IMAPResponseTokenizer source) throws MessagingException {
+        StringBuffer part = new StringBuffer(token.getValue()); 
+        // NB:  We're still parsing with the expanded delimiter set 
+        token = source.next(false, true); 
+        
+        while (true) {
+            // Not a period?  We've reached the end of the section number, 
+            // finalize the part number and let the caller figure out what 
+            // to do from here.  
+            if (!token.isType('.')) {
+                partNumber = part.toString(); 
+                return token; 
+            }
+            // might have another number section 
+            else {
+                // step to the next token 
+                token = source.next(false, true); 
+                // another section number piece?
+                if (token.isType(Token.NUMERIC)) {
+                    // add this to the collection, and continue 
+                    part.append('.'); 
+                    part.append(token.getValue()); 
+                    token = source.next(false, true); 
+                }
+                else  {
+                    partNumber = part.toString(); 
+                    // this is likely the start of the section name 
+                    return token; 
+                }
+            }
+        }
+    }
+    
+    
+    /**
+     * Parse the section name, if any, in a BODY section qualifier.  The 
+     * section name may stand alone within the body section (e.g., 
+     * "BODY[HEADERS]" or follow the section number (e.g., 
+     * "BODY[1.2.3.HEADERS.FIELDS.NOT]".  
+     * 
+     * @param token  The first token of the name sequence.
+     * @param source The source tokenizer.
+     * 
+     * @return The first non-name token in the response. 
+     */
+    private Token parseSectionName(Token token, IMAPResponseTokenizer source) throws MessagingException {
+        StringBuffer part = new StringBuffer(token.getValue()); 
+        // NB:  We're still parsing with the expanded delimiter set 
+        token = source.next(false, true); 
+        
+        while (true) {
+            // Not a period?  We've reached the end of the section number, 
+            // finalize the part number and let the caller figure out what 
+            // to do from here.  
+            if (!token.isType('.')) {
+                sectionName = part.toString(); 
+                return token; 
+            }
+            // might have another number section 
+            else {
+                // add this to the collection, and continue 
+                part.append('.'); 
+                part.append(source.readString()); 
+                token = source.next(false, true); 
+            }
+        }
+    }
+    
+    
+    /**
+     * Parse a header list that may follow the HEADER.FIELD or HEADER.FIELD.NOT
+     * name qualifier.  This is a list of string values enclosed in parens.
+     * 
+     * @param source The source tokenizer.
+     * 
+     * @return The next token in the response (which should be the section terminator, ']')
+     * @exception MessagingException
+     */
+    private Token parseHeaderList(IMAPResponseTokenizer source) throws MessagingException {
+        headers = new ArrayList();
+        
+        // normal parsing rules going on here 
+        while (source.notListEnd()) {
+            String value = source.readString();
+            headers.add(value);
+        }
+        // step over the closing paren 
+        source.next(); 
+        // NB, back to the expanded token rules again 
+        return source.next(false, true); 
+    }
+    
+    
+    /**
+     * Parse off the substring values following the section identifier, if 
+     * any.  If present, they will be in the format "<start.len>".  
+     * 
+     * @param source The source tokenizer.
+     * 
+     * @exception MessagingException
+     */
+    private void parseSubstringValues(IMAPResponseTokenizer source) throws MessagingException {
+        // We rarely have one of these, so it's a quick out 
+        if (!source.peek(false, true).isType('<')) {
+            return; 
+        }
+        // step over the angle bracket. 
+        source.next(false, true); 
+        // pull out the start information 
+        start = source.next(false, true).getInteger(); 
+        // step over the period 
+        source.next(false, true);         
+        // now the length bit                  
+        length = source.next(false, true).getInteger(); 
+        // and consume the closing angle bracket 
+        source.next(false, true); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java
new file mode 100644
index 0000000..80cf50e
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java
@@ -0,0 +1,228 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.ContentDisposition;
+import javax.mail.internet.ContentType;
+
+import org.apache.geronimo.javamail.util.ResponseFormatException;
+
+
+public class IMAPBodyStructure extends IMAPFetchDataItem {
+
+    // the MIME type information
+    public ContentType mimeType = new ContentType();
+    // the content disposition info
+    public ContentDisposition disposition = null;
+    // the message ID
+    public String contentID;
+    public String contentDescription;
+    public String transferEncoding;
+    // size of the message 
+    public int bodySize;
+    // number of lines, which only applies to text types.
+    public int lines = -1;
+
+    // "parts is parts".  If this is a multipart message, we have a body structure item for each subpart.
+    public IMAPBodyStructure[] parts;
+    // optional dispostiion parameters
+    public Map dispositionParameters;
+    // language parameters
+    public List languages;
+    // the MD5 hash
+    public String md5Hash;
+
+    // references to nested message information.
+    public IMAPEnvelope nestedEnvelope;
+    public IMAPBodyStructure nestedBody;
+
+
+    public IMAPBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
+        super(BODYSTRUCTURE);
+        parseBodyStructure(source);
+    }
+
+
+    protected void parseBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
+        // the body structure needs to start with a left paren
+        source.checkLeftParen();
+
+        // if we start with a parentized item, we have a multipart content type.  We need to
+        // recurse on each of those as appropriate
+        if (source.peek().getType() == '(') {
+            parseMultipartBodyStructure(source);
+        }
+        else {
+            parseSinglepartBodyStructure(source);
+        }
+    }
+
+
+    protected void parseMultipartBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
+        mimeType.setPrimaryType("multipart");
+        ArrayList partList = new ArrayList();
+
+        do {
+            // parse the subpiece (which might also be a multipart).
+            IMAPBodyStructure part = new IMAPBodyStructure(source);
+            partList.add(part);
+            // we keep doing this as long as we seen parenthized items.
+        } while (source.peek().getType() == '(');
+        
+        parts = (IMAPBodyStructure[])partList.toArray(new IMAPBodyStructure[partList.size()]); 
+
+        // get the subtype (required)
+        mimeType.setSubType(source.readString());
+
+        // if the next token is the list terminator, we're done.  Otherwise, we need to read extension
+        // data.
+        if (source.checkListEnd()) {
+            return;
+        }
+        // read the content parameter information and copy into the ContentType.
+        mimeType.setParameterList(source.readParameterList());
+
+        // more optional stuff
+        if (source.checkListEnd()) {
+            return;
+        }
+
+        // go parse the extensions that are common to both single- and multi-part messages.
+        parseMessageExtensions(source);
+    }
+
+
+    protected void parseSinglepartBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
+        // get the primary and secondary types.
+        mimeType.setPrimaryType(source.readString());
+        mimeType.setSubType(source.readString());
+
+        // read the parameters associated with the content type.
+        mimeType.setParameterList(source.readParameterList());
+
+        // now a bunch of string value parameters
+        contentID = source.readStringOrNil();
+        contentDescription = source.readStringOrNil();
+        transferEncoding = source.readStringOrNil();
+        bodySize = source.readInteger();
+
+        // is this an embedded message type?  Embedded messages include envelope and body structure
+        // information for the embedded message next.
+        if (mimeType.match("message/rfc822")) {
+            // parse the nested information
+            nestedEnvelope = new IMAPEnvelope(source);
+            nestedBody = new IMAPBodyStructure(source);
+            lines = source.readInteger();
+        }
+        // text types include a line count
+        else if (mimeType.match("text/*")) {
+            lines = source.readInteger();
+        }
+
+        // now the optional extension data.  All of these are optional, but must be in the specified order.
+        if (source.checkListEnd()) {
+            return;
+        }
+
+        md5Hash = source.readString();
+
+        // go parse the extensions that are common to both single- and multi-part messages.
+        parseMessageExtensions(source);
+    }
+
+    /**
+     * Parse common message extension information shared between
+     * single part and multi part messages.
+     *
+     * @param source The source tokenizer..
+     */
+    protected void parseMessageExtensions(IMAPResponseTokenizer source) throws MessagingException {
+
+        // now the optional extension data.  All of these are optional, but must be in the specified order.
+        if (source.checkListEnd()) {
+            return;
+        }
+
+        disposition = new ContentDisposition();
+        // now the dispostion.  This is a string, followed by a parameter list.
+        if (source.peek(true).getType() == '(') {
+            source.checkLeftParen();
+            disposition.setDisposition(source.readString());
+            disposition.setParameterList(source.readParameterList());
+            source.checkRightParen();
+        } else if (source.peek(true) == IMAPResponseTokenizer.NIL) {
+            source.next();
+        } else {
+            throw new ResponseFormatException("Expecting NIL or '(' in response");
+        }
+
+        // once more
+        if (source.checkListEnd()) {
+            return;
+        }
+        // read the language info.
+        languages = source.readStringList();
+        // next is the body location information.  The Javamail APIs don't really expose that, so
+        // we'll just skip over that.
+
+        // once more
+        if (source.checkListEnd()) {
+            return;
+        }
+        // read the location info.
+        source.readStringList();
+
+        // we don't recognize any other forms of extension, so just skip over these.
+        while (source.notListEnd()) {
+            source.skipExtensionItem();
+        }
+
+        // step over the closing paren
+        source.next();
+    }
+
+
+    /**
+     * Tests if a body structure is for a multipart body.
+     *
+     * @return true if this is a multipart body part, false for a single part.
+     */
+    public boolean isMultipart() {
+        return parts != null;
+    }
+    
+    
+    /**
+     * Test if this body structure represents an attached message.  If it's a
+     * message, this will be a single part of MIME type message/rfc822. 
+     * 
+     * @return True if this is a nested message type, false for either a multipart or 
+     *         a single part of another type.
+     */
+    public boolean isAttachedMessage() {
+        return !isMultipart() && mimeType.match("message/rfc822"); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java
new file mode 100644
index 0000000..c0012ea
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java
@@ -0,0 +1,90 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
+
+/**
+ * Util class to represent a CAPABILITY response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPCapabilityResponse extends IMAPUntaggedResponse {
+    // the advertised capabilities 
+    protected Map capabilities = new HashMap(); 
+    // the authentication mechanisms.  The order is important with 
+    // the authentications, as we a) want to process these in the 
+    // order presented, and b) need to convert them into String arrays 
+    // for Sasl API calls. 
+    protected List authentications = new ArrayList(); 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPCapabilityResponse(IMAPResponseTokenizer source, byte [] response) throws MessagingException {
+        super("CAPABILITY", response); 
+        
+        // parse each of the capability tokens.  We're using the default RFC822 parsing rules,
+        // which does not consider "=" to be a delimiter token, so all "AUTH=" capabilities will
+        // come through as a single token.
+        while (source.hasMore()) {
+            // the capabilities are always ATOMs. 
+            String value = source.readAtom().toUpperCase(); 
+            // is this an authentication option?
+            if (value.startsWith("AUTH=")) {
+                // parse off the mechanism that fillows the "=", and add this to the supported list.
+                String mechanism = value.substring(5);
+                authentications.add(mechanism);
+            }
+            else {
+                // just add this to the capabilities map.
+                capabilities.put(value, value);
+            }
+        }
+    }
+    
+
+    /**
+     * Return the capability map for the server.
+     * 
+     * @return A map of the capability items.
+     */
+    public Map getCapabilities() {
+        return capabilities;
+    }
+    
+    /**
+     * Retrieve the map of the server-supported authentication
+     * mechanisms.
+     * 
+     * @return 
+     */
+    public List getAuthentications() {
+        return authentications;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
new file mode 100644
index 0000000..d49b513
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
@@ -0,0 +1,1477 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Vector;
+
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Quota;
+import javax.mail.UIDFolder;
+
+import javax.mail.search.AddressTerm;
+import javax.mail.search.AndTerm;
+import javax.mail.search.BodyTerm;
+import javax.mail.search.ComparisonTerm;
+import javax.mail.search.DateTerm;
+import javax.mail.search.FlagTerm;
+import javax.mail.search.FromTerm;
+import javax.mail.search.FromStringTerm;
+import javax.mail.search.HeaderTerm;
+import javax.mail.search.MessageIDTerm;
+import javax.mail.search.MessageNumberTerm;
+import javax.mail.search.NotTerm;
+import javax.mail.search.OrTerm;
+import javax.mail.search.ReceivedDateTerm;
+import javax.mail.search.RecipientTerm;
+import javax.mail.search.RecipientStringTerm;
+import javax.mail.search.SearchException;
+import javax.mail.search.SearchTerm;
+import javax.mail.search.SentDateTerm;
+import javax.mail.search.SizeTerm;
+import javax.mail.search.StringTerm;
+import javax.mail.search.SubjectTerm;
+
+import org.apache.geronimo.javamail.store.imap.ACL;
+import org.apache.geronimo.javamail.store.imap.IMAPFolder;
+import org.apache.geronimo.javamail.store.imap.Rights;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
+
+import org.apache.geronimo.javamail.util.CommandFailedException;
+
+
+/**
+ * Utility class for building up what might be complex arguments
+ * to a command.  This includes the ability to directly write out
+ * binary arrays of data and have them constructed as IMAP
+ * literals.
+ */
+public class IMAPCommand {
+
+    // digits table for encoding IMAP modified Base64.  Note that this differs
+    // from "normal" base 64 by using ',' instead of '/' for the last digit.
+    public static final char[] encodingTable = {
+        'A', 'B', 'C', 'D', 'E', 'F', 'G',
+        'H', 'I', 'J', 'K', 'L', 'M', 'N',
+        'O', 'P', 'Q', 'R', 'S', 'T', 'U',
+        'V', 'W', 'X', 'Y', 'Z',
+        'a', 'b', 'c', 'd', 'e', 'f', 'g',
+        'h', 'i', 'j', 'k', 'l', 'm', 'n',
+        'o', 'p', 'q', 'r', 's', 't', 'u',
+        'v', 'w', 'x', 'y', 'z',
+        '0', '1', '2', '3', '4', '5', '6',
+        '7', '8', '9',
+        '+', ','
+    };
+
+    protected boolean needWhiteSpace = false;
+
+    // our utility writer stream
+    protected DataOutputStream out;
+    // the real output target
+    protected ByteArrayOutputStream sink;
+    // our command segment set.  If the command contains literals, then the literal
+    // data must be sent after receiving an continue response back from the server.
+    protected List segments = null;
+    // the append tag for the response
+    protected String tag;
+
+    // our counter used to generate command tags.
+    static protected int tagCounter = 0;
+
+    /**
+     * Create an empty command.
+     */
+    public IMAPCommand() {
+        try {
+            sink = new ByteArrayOutputStream();
+            out = new DataOutputStream(sink);
+
+            // write the tag data at the beginning of the command.
+            out.writeBytes(getTag());
+            // need a blank separator
+            out.write(' ');
+        } catch (IOException e ) {
+        }
+    }
+
+    /**
+     * Create a command with an initial command string.
+     *
+     * @param command The command string used to start this command.
+     */
+    public IMAPCommand(String command) {
+        this();
+        append(command);
+    }
+
+    public String getTag() {
+        if (tag == null) {
+            // the tag needs to be non-numeric, so tack a convenient alpha character on the front.
+            tag = "a" + tagCounter++;
+        }
+        return tag;
+    }
+
+
+    /**
+     * Save the current segment of the command we've accumulated.  This
+     * generally occurs because we have a literal element in the command
+     * that's going to require a continuation response from the server before
+     * we can send it.
+     */
+    private void saveCurrentSegment()
+    {
+        try {
+            out.flush();     // make sure everything is written
+                             // get the data so far and reset the sink
+            byte[] segment = sink.toByteArray();
+            sink.reset();
+            // most commands don't have segments, so don't create the list until we do.
+            if (segments == null) {
+                segments = new ArrayList();
+            }
+            // ok, we need to issue this command as a conversation.
+            segments.add(segment);
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Write all of the command data to the stream.  This includes the
+     * leading tag data.
+     *
+     * @param outStream
+     * @param connection
+     *
+     * @exception IOException
+     * @exception MessagingException
+     */
+    public void writeTo(OutputStream outStream, IMAPConnection connection) throws IOException, MessagingException
+    {
+
+        // just a simple, single string-encoded command?
+        if (segments == null) {
+            // make sure the output stream is flushed
+            out.flush();
+            // just copy the command data to the output stream
+            sink.writeTo(outStream);
+            // we need to end the command with a CRLF sequence.
+            outStream.write('\r');
+            outStream.write('\n');
+        }
+        // multiple-segment mode, which means we need to deal with continuation responses at
+        // each of the literal boundaries.
+        else {
+            // at this point, we have a list of command pieces that must be written out, then a
+            // continuation response checked for after each write.  Once each of these pieces is
+            // written out, we still have command stuff pending in the out stream, which we'll tack
+            // on to the end.
+            for (int i = 0; i < segments.size(); i++) {
+                outStream.write((byte [])segments.get(i));
+                // now wait for a response from the connection.  We should be getting a
+                // continuation response back (and might have also received some asynchronous
+                // replies, which we'll leave in the queue for now.  If we get some status back
+                // other than than a continue, we've got an error in our command somewhere.
+                IMAPTaggedResponse response = connection.receiveResponse();
+                if (!response.isContinuation()) {
+                    throw new CommandFailedException("Error response received on a IMAP continued command:  " + response);
+                }
+            }
+            out.flush();
+            // all leading segments written with the appropriate continuation received in reply.
+            // just copy the command data to the output stream
+            sink.writeTo(outStream);
+            // we need to end the command with a CRLF sequence.
+            outStream.write('\r');
+            outStream.write('\n');
+        }
+    }
+
+
+    /**
+     * Directly append a value to the buffer without attempting
+     * to insert whitespace or figure out any format encodings.
+     *
+     * @param value  The value to append.
+     */
+    public void append(String value) {
+        try {
+            // add the bytes direcly
+            out.writeBytes(value);
+            // assume we're needing whitespace after this (pretty much unknown).
+            needWhiteSpace = true;
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Append a string value to a command buffer.  This sorts out
+     * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
+     * or ATOM).
+     *
+     * @param target The target buffer for appending the string.
+     * @param value  The value to append.
+     */
+    public void appendString(String value) {
+        try {
+            // work off the byte values
+            appendString(value.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
+    }
+
+
+    /**
+     * Append a string value to a command buffer.  This always appends as
+     * a QUOTEDSTRING
+     *
+     * @param value  The value to append.
+     */
+    public void appendQuotedString(String value) {
+        try {
+            // work off the byte values
+            appendQuotedString(value.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
+    }
+
+
+    /**
+     * Append a string value to a command buffer, with encoding.  This sorts out
+     * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
+     * or ATOM).
+     *
+     * @param target The target buffer for appending the string.
+     * @param value  The value to append.
+     */
+    public void appendEncodedString(String value) {
+        // encode first.
+        value = encode(value);
+        try {
+            // work off the byte values
+            appendString(value.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
+    }
+
+
+    /**
+     * Encode a string using the modified UTF-7 encoding.
+     *
+     * @param original The original string.
+     *
+     * @return The original string encoded with modified UTF-7 encoding.
+     */
+    public String encode(String original) {
+
+        // buffer for encoding sections of data
+        byte[] buffer = new byte[4];
+        int bufferCount = 0;
+
+        StringBuffer result = new StringBuffer();
+
+        // state flag for the type of section we're in.
+        boolean encoding = false;
+
+        for (int i = 0; i < original.length(); i++) {
+            char ch = original.charAt(i);
+
+            // processing an encoded section?
+            if (encoding) {
+                // is this a printable character?
+                if (ch > 31 && ch < 127) {
+                    // encode anything in the buffer
+                    encode(buffer, bufferCount, result);
+                    // add the section terminator char
+                    result.append('-');
+                    encoding = false;
+                    // we now fall through to the printable character section.
+                }
+                // still an unprintable
+                else {
+                    // add this char to the working buffer?
+                    buffer[++bufferCount] = (byte)(ch >> 8);
+                    buffer[++bufferCount] = (byte)(ch & 0xff);
+                    // if we have enough to encode something, do it now.
+                    if (bufferCount >= 3) {
+                        bufferCount = encode(buffer, bufferCount, result);
+                    }
+                    // go back to the top of the loop.
+                    continue;
+                }
+            }
+            // is this the special printable?
+            if (ch == '&') {
+                // this is the special null escape sequence
+                result.append('&');
+                result.append('-');
+            }
+            // is this a printable character?
+            else if (ch > 31 && ch < 127) {
+                // just add to the result
+                result.append(ch);
+            }
+            else {
+                // write the escape character
+                result.append('&');
+
+                // non-printable ASCII character, we need to switch modes
+                // both bytes of this character need to be encoded.  Each
+                // encoded digit will basically be a "character-and-a-half".
+                buffer[0] = (byte)(ch >> 8);
+                buffer[1] = (byte)(ch & 0xff);
+                bufferCount = 2;
+                encoding = true;
+            }
+        }
+        // were we in a non-printable section at the end?
+        if (encoding) {
+            // take care of any remaining characters
+            encode(buffer, bufferCount, result);
+            // add the section terminator char
+            result.append('-');
+        }
+        // convert the encoded string.
+        return result.toString();
+    }
+
+
+    /**
+     * Encode a single buffer of characters.  This buffer will have
+     * between 0 and 4 bytes to encode.
+     *
+     * @param buffer The buffer to encode.
+     * @param count  The number of characters in the buffer.
+     * @param result The accumulator for appending the result.
+     *
+     * @return The remaining number of bytes remaining in the buffer (return 0
+     *         unless the count was 4 at the beginning).
+     */
+    protected static int encode(byte[] buffer, int count, StringBuffer result) {
+        byte b1 = 0;
+        byte b2 = 0;
+        byte b3 = 0;
+
+        // different processing based on how much we have in the buffer
+        switch (count) {
+            // ended at a boundary.  This is cool, not much to do.
+            case 0:
+                // no residual in the buffer
+                return 0;
+
+            // just a single left over byte from the last encoding op.
+            case 1:
+                b1 = buffer[0];
+                result.append(encodingTable[(b1 >>> 2) & 0x3f]);
+                result.append(encodingTable[(b1 << 4) & 0x30]);
+                return 0;
+
+            // one complete char to encode
+            case 2:
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append(encodingTable[(b1 >>> 2) & 0x3f]);
+                result.append(encodingTable[((b1 << 4) & 0x30) + ((b2 >>>4) & 0x0f)]);
+                result.append(encodingTable[((b2 << 2) & (0x3c))]);
+                return 0;
+
+            // at least a full triplet of bytes to encode
+            case 3:
+            case 4:
+                b1 = buffer[0];
+                b2 = buffer[1];
+                b3 = buffer[2];
+                result.append(encodingTable[(b1 >>> 2) & 0x3f]);
+                result.append(encodingTable[((b1 << 4) & 0x30) + ((b2 >>>4) & 0x0f)]);
+                result.append(encodingTable[((b2 << 2) & 0x3c) + ((b3 >>> 6) & 0x03)]);
+                result.append(encodingTable[b3 & 0x3f]);
+
+                // if we have more than the triplet, we need to move the extra one into the first
+                // position and return the residual indicator
+                if (count == 4) {
+                    buffer[0] = buffer[4];
+                    return 1;
+                }
+                return 0;
+        }
+        return 0;
+    }
+
+
+    /**
+     * Append a string value to a command buffer.  This sorts out
+     * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
+     * or ATOM).
+     *
+     * @param target The target buffer for appending the string.
+     * @param value  The value to append.
+     */
+    public void appendString(String value, String charset) throws MessagingException {
+        if (charset == null) {
+            try {
+                // work off the byte values
+                appendString(value.getBytes("ISO8859-1"));
+            } catch (UnsupportedEncodingException e) {
+            }
+        }
+        else {
+            try {
+                // use the charset to extract the bytes
+                appendString(value.getBytes(charset));
+                throw new MessagingException("Invalid text encoding");
+            } catch (UnsupportedEncodingException e) {
+            }
+        }
+    }
+
+
+    /**
+     * Append a value in a byte array to a command buffer.  This sorts out
+     * what form the string needs to be appended in (LITERAL, QUOTEDSTRING,
+     * or ATOM).
+     *
+     * @param target The target buffer for appending the string.
+     * @param value  The value to append.
+     */
+    public void appendString(byte[] value) {
+        // sort out how we need to append this
+        switch (IMAPResponseTokenizer.getEncoding(value)) {
+            case Token.LITERAL:
+                appendLiteral(value);
+                break;
+            case Token.QUOTEDSTRING:
+                appendQuotedString(value);
+                break;
+            case Token.ATOM:
+                appendAtom(value);
+                break;
+        }
+    }
+
+
+    /**
+     * Append an integer value to the command, converting
+     * the integer into string form.
+     *
+     * @param value  The value to append.
+     */
+    public void appendInteger(int value) {
+        appendAtom(Integer.toString(value));
+    }
+
+
+    /**
+     * Append a long value to the command, converting
+     * the integer into string form.
+     *
+     * @param value  The value to append.
+     */
+    public void appendLong(long value) {
+        appendAtom(Long.toString(value));
+    }
+
+
+    /**
+     * Append an atom value to the command.  Atoms are directly
+     * appended without using literal encodings.
+     *
+     * @param value  The value to append.
+     */
+    public void appendAtom(String value) {
+        try {
+            appendAtom(value.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
+    }
+
+
+
+    /**
+     * Append an atom to the command buffer.  Atoms are directly
+     * appended without using literal encodings.  White space is
+     * accounted for with the append operation.
+     *
+     * @param value  The value to append.
+     */
+    public void appendAtom(byte[] value) {
+        try {
+            // give a token separator
+            conditionalWhitespace();
+            // ATOMs are easy
+            out.write(value);
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Append an IMAP literal values to the command.
+     * literals are written using a header with the length
+     * specified, followed by a CRLF sequence, followed
+     * by the literal data.
+     *
+     * @param value  The literal data to write.
+     */
+    public void appendLiteral(byte[] value) {
+        try {
+            appendLiteralHeader(value.length);
+            out.write(value);
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * Add a literal header to the buffer.  The literal
+     * header is the literal length enclosed in a
+     * "{n}" pair, followed by a CRLF sequence.
+     *
+     * @param size   The size of the literal value.
+     */
+    protected void appendLiteralHeader(int size) {
+        try {
+            conditionalWhitespace();
+            out.writeByte('{');
+            out.writeBytes(Integer.toString(size));
+            out.writeBytes("}\r\n");
+            // the IMAP client is required to send literal data to the server by
+            // writing the command up to the header, then waiting for a continuation
+            // response to send the rest.
+            saveCurrentSegment();
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Append literal data to the command where the
+     * literal sourcd is a ByteArrayOutputStream.
+     *
+     * @param value  The source of the literal data.
+     */
+    public void appendLiteral(ByteArrayOutputStream value) {
+        try {
+            appendLiteralHeader(value.size());
+            // have this output stream write directly into our stream
+            value.writeTo(out);
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * Write out a string of literal data, taking into
+     * account the need to escape both '"' and '\'
+     * characters.
+     *
+     * @param value  The bytes of the string to write.
+     */
+    public void appendQuotedString(byte[] value) {
+        try {
+            conditionalWhitespace();
+            out.writeByte('"');
+
+            // look for chars requiring escaping
+            for (int i = 0; i < value.length; i++) {
+                byte ch = value[i];
+
+                if (ch == '"' || ch == '\\') {
+                    out.writeByte('\\');
+                }
+                out.writeByte(ch);
+            }
+
+            out.writeByte('"');
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * Mark the start of a list value being written to
+     * the command.  A list is a sequences of different
+     * tokens enclosed in "(" ")" pairs.  Lists can
+     * be nested.
+     */
+    public void startList() {
+        try {
+            conditionalWhitespace();
+            out.writeByte('(');
+            needWhiteSpace = false;
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * Write out the end of the list.
+     */
+    public void endList() {
+        try {
+            out.writeByte(')');
+            needWhiteSpace = true;
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Add a whitespace character to the command if the
+     * previous token was a type that required a
+     * white space character to mark the boundary.
+     */
+    protected void conditionalWhitespace() {
+        try {
+            if (needWhiteSpace) {
+                out.writeByte(' ');
+            }
+            // all callers of this are writing a token that will need white space following, so turn this on
+            // every time we're called.
+            needWhiteSpace = true;
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Append a body section specification to a command string.  Body
+     * section specifications are of the form "[section]<start.count>".
+     *
+     * @param section  The section numeric identifier.
+     * @param partName The name of the body section we want (e.g. "TEST", "HEADERS").
+     */
+    public void appendBodySection(String section, String partName) {
+        try {
+            // we sometimes get called from the top level
+            if (section == null) {
+                appendBodySection(partName);
+                return;
+            }
+
+            out.writeByte('[');
+            out.writeBytes(section);
+            if (partName != null) {
+                out.writeByte('.');
+                out.writeBytes(partName);
+            }
+            out.writeByte(']');
+            needWhiteSpace = true;
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Append a body section specification to a command string.  Body
+     * section specifications are of the form "[section]".
+     *
+     * @param partName The partname we require.
+     */
+    public void appendBodySection(String partName) {
+        try {
+            out.writeByte('[');
+            out.writeBytes(partName);
+            out.writeByte(']');
+            needWhiteSpace = true;
+        } catch (IOException e) {
+        }
+    }
+
+
+    /**
+     * Append a set of flags to a command buffer.
+     *
+     * @param flags  The flag set to append.
+     */
+    public void appendFlags(Flags flags) {
+        startList();
+
+        Flags.Flag[] systemFlags = flags.getSystemFlags();
+
+        // process each of the system flag names
+        for (int i = 0; i < systemFlags.length; i++) {
+            Flags.Flag flag = systemFlags[i];
+
+            if (flag == Flags.Flag.ANSWERED) {
+                appendAtom("\\Answered");
+            }
+            else if (flag == Flags.Flag.DELETED) {
+                appendAtom("\\Deleted");
+            }
+            else if (flag == Flags.Flag.DRAFT) {
+                appendAtom("\\Draft");
+            }
+            else if (flag == Flags.Flag.FLAGGED) {
+                appendAtom("\\Flagged");
+            }
+            else if (flag == Flags.Flag.RECENT) {
+                appendAtom("\\Recent");
+            }
+            else if (flag == Flags.Flag.SEEN) {
+                appendAtom("\\Seen");
+            }
+        }
+
+        // now process the user flags, which just get appended as is.
+        String[] userFlags = flags.getUserFlags();
+
+        for (int i = 0; i < userFlags.length; i++) {
+            appendAtom(userFlags[i]);
+        }
+
+        // close the list off
+        endList();
+    }
+
+
+    /**
+     * Format a date into the form required for IMAP commands.
+     *
+     * @param d      The source Date.
+     */
+    public void appendDate(Date d) {
+        // get a formatter to create IMAP dates.  Use the US locale, as the dates are not localized.
+        IMAPDateFormat formatter = new IMAPDateFormat();
+        // date_time strings need to be done as quoted strings because they contain blanks.
+        appendString(formatter.format(d));
+    }
+
+
+    /**
+     * Format a date into the form required for IMAP search commands.
+     *
+     * @param d      The source Date.
+     */
+    public void appendSearchDate(Date d) {
+        // get a formatter to create IMAP dates.  Use the US locale, as the dates are not localized.
+        IMAPSearchDateFormat formatter = new IMAPSearchDateFormat();
+        // date_time strings need to be done as quoted strings because they contain blanks.
+        appendString(formatter.format(d));
+    }
+
+
+    /**
+     * append an IMAP search sequence from a SearchTerm.  SearchTerms
+     * terms can be complex sets of terms in a tree form, so this
+     * may involve some recursion to completely translate.
+     *
+     * @param term    The search term we're processing.
+     * @param charset The charset we need to use when generating the sequence.
+     *
+     * @exception MessagingException
+     */
+    public void appendSearchTerm(SearchTerm term, String charset) throws MessagingException {
+        // we need to do this manually, by inspecting the term object against the various SearchTerm types
+        // defined by the javamail spec.
+
+        // Flag searches are used internally by other operations, so this is a good one to check first.
+        if (term instanceof FlagTerm) {
+            appendFlag((FlagTerm)term, charset);
+        }
+        // after that, I'm not sure there's any optimal order to these.  Let's start with the conditional
+        // modifiers (AND, OR, NOT), then just hit each of the header types
+        else if (term instanceof AndTerm) {
+            appendAnd((AndTerm)term, charset);
+        }
+        else if (term instanceof OrTerm) {
+            appendOr((OrTerm)term, charset);
+        }
+        else if (term instanceof NotTerm) {
+            appendNot((NotTerm)term, charset);
+        }
+        // multiple forms of From: search
+        else if (term instanceof FromTerm) {
+            appendFrom((FromTerm)term, charset);
+        }
+        else if (term instanceof FromStringTerm) {
+            appendFrom((FromStringTerm)term, charset);
+        }
+        else if (term instanceof HeaderTerm) {
+            appendHeader((HeaderTerm)term, charset);
+        }
+        else if (term instanceof RecipientTerm) {
+            appendRecipient((RecipientTerm)term, charset);
+        }
+        else if (term instanceof RecipientStringTerm) {
+            appendRecipient((RecipientStringTerm)term, charset);
+        }
+        else if (term instanceof SubjectTerm) {
+            appendSubject((SubjectTerm)term, charset);
+        }
+        else if (term instanceof BodyTerm) {
+            appendBody((BodyTerm)term, charset);
+        }
+        else if (term instanceof SizeTerm) {
+            appendSize((SizeTerm)term, charset);
+        }
+        else if (term instanceof SentDateTerm) {
+            appendSentDate((SentDateTerm)term, charset);
+        }
+        else if (term instanceof ReceivedDateTerm) {
+            appendReceivedDate((ReceivedDateTerm)term, charset);
+        }
+        else if (term instanceof MessageIDTerm) {
+            appendMessageID((MessageIDTerm)term, charset);
+        }
+        else {
+            // don't know what this is
+            throw new SearchException("Unsupported search type");
+        }
+    }
+
+    /**
+     * append IMAP search term information from a FlagTerm item.
+     *
+     * @param term    The source FlagTerm
+     * @param charset target charset for the search information (can be null).
+     * @param out     The target command buffer.
+     */
+    protected void appendFlag(FlagTerm term, String charset) {
+        // decide which one we need to test for
+        boolean set = term.getTestSet();
+
+        Flags flags = term.getFlags();
+        Flags.Flag[] systemFlags = flags.getSystemFlags();
+
+        String[] userFlags = flags.getUserFlags();
+
+        // empty search term?  not sure if this is an error.  The default search implementation would
+        // not consider this an error, so we'll just ignore this.
+        if (systemFlags.length == 0 && userFlags.length == 0) {
+            return;
+        }
+
+        if (set) {
+            for (int i = 0; i < systemFlags.length; i++) {
+                Flags.Flag flag = systemFlags[i];
+
+                if (flag == Flags.Flag.ANSWERED) {
+                    appendAtom("ANSWERED");
+                }
+                else if (flag == Flags.Flag.DELETED) {
+                    appendAtom("DELETED");
+                }
+                else if (flag == Flags.Flag.DRAFT) {
+                    appendAtom("DRAFT");
+                }
+                else if (flag == Flags.Flag.FLAGGED) {
+                    appendAtom("FLAGGED");
+                }
+                else if (flag == Flags.Flag.RECENT) {
+                    appendAtom("RECENT");
+                }
+                else if (flag == Flags.Flag.SEEN) {
+                    appendAtom("SEEN");
+                }
+            }
+        }
+        else {
+            for (int i = 0; i < systemFlags.length; i++) {
+                Flags.Flag flag = systemFlags[i];
+
+                if (flag == Flags.Flag.ANSWERED) {
+                    appendAtom("UNANSWERED");
+                }
+                else if (flag == Flags.Flag.DELETED) {
+                    appendAtom("UNDELETED");
+                }
+                else if (flag == Flags.Flag.DRAFT) {
+                    appendAtom("UNDRAFT");
+                }
+                else if (flag == Flags.Flag.FLAGGED) {
+                    appendAtom("UNFLAGGED");
+                }
+                else if (flag == Flags.Flag.RECENT) {
+                    // not UNRECENT?
+                    appendAtom("OLD");
+                }
+                else if (flag == Flags.Flag.SEEN) {
+                    appendAtom("UNSEEN");
+                }
+            }
+        }
+
+
+        // User flags are done as either "KEYWORD name" or "UNKEYWORD name"
+        for (int i = 0; i < userFlags.length; i++) {
+            appendAtom(set ? "KEYWORD" : "UNKEYWORD");
+            appendAtom(userFlags[i]);
+        }
+    }
+
+
+    /**
+     * append IMAP search term information from an AndTerm item.
+     *
+     * @param term    The source AndTerm
+     * @param charset target charset for the search information (can be null).
+     * @param out     The target command buffer.
+     */
+    protected void appendAnd(AndTerm term, String charset) throws MessagingException {
+        // ANDs are pretty easy.  Just append all of the terms directly to the
+        // command as is.
+
+        SearchTerm[] terms = term.getTerms();
+
+        for (int i = 0; i < terms.length; i++) {
+            appendSearchTerm(terms[i], charset);
+        }
+    }
+
+
+    /**
+     * append IMAP search term information from an OrTerm item.
+     *
+     * @param term    The source OrTerm
+     * @param charset target charset for the search information (can be null).
+     * @param out     The target command buffer.
+     */
+    protected void appendOr(OrTerm term, String charset) throws MessagingException {
+        SearchTerm[] terms = term.getTerms();
+
+        // OrTerms are a bit of a pain to translate to IMAP semantics.  The IMAP OR operation only allows 2
+        // search keys, while OrTerms can have n keys (including, it appears, just one!  If we have more than
+        // 2, it's easiest to convert this into a tree of OR keys and let things generate that way.  The
+        // resulting IMAP operation would be OR (key1) (OR (key2) (key3))
+
+        // silly rabbit...somebody doesn't know how to use OR
+        if (terms.length == 1) {
+            // just append the singleton in place without the OR operation.
+            appendSearchTerm(terms[0], charset);
+            return;
+        }
+
+        // is this a more complex operation?
+        if (terms.length > 2) {
+            // have to chain these together (shazbat).
+            SearchTerm current = terms[0];
+
+            for (int i = 1; i < terms.length; i++) {
+                current = new OrTerm(current, terms[i]);
+            }
+
+            // replace the term array with the newly generated top array
+            terms = ((OrTerm)current).getTerms();
+        }
+
+        // we're going to generate this with parenthetical search keys, even if it is just a simple term.
+        appendAtom("OR");
+        startList();
+        // generated OR argument 1
+        appendSearchTerm(terms[0], charset);
+        endList();
+        startList();
+        // generated OR argument 2
+        appendSearchTerm(terms[0], charset);
+        // and the closing parens
+        endList();
+    }
+
+
+    /**
+     * append IMAP search term information from a NotTerm item.
+     *
+     * @param term    The source NotTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendNot(NotTerm term, String charset) throws MessagingException {
+        // we're goint to generate this with parenthetical search keys, even if it is just a simple term.
+        appendAtom("NOT");
+        startList();
+        // generated the NOT expression
+        appendSearchTerm(term.getTerm(), charset);
+        // and the closing parens
+        endList();
+    }
+
+
+    /**
+     * append IMAP search term information from a FromTerm item.
+     *
+     * @param term    The source FromTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendFrom(FromTerm term, String charset) throws MessagingException {
+        appendAtom("FROM");
+        // this may require encoding
+        appendString(term.getAddress().toString(), charset);
+    }
+
+
+    /**
+     * append IMAP search term information from a FromStringTerm item.
+     *
+     * @param term    The source FromStringTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendFrom(FromStringTerm term, String charset) throws MessagingException {
+        appendAtom("FROM");
+        // this may require encoding
+        appendString(term.getPattern(), charset);
+    }
+
+
+    /**
+     * append IMAP search term information from a RecipientTerm item.
+     *
+     * @param term    The source RecipientTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendRecipient(RecipientTerm term, String charset) throws MessagingException {
+        appendAtom(recipientType(term.getRecipientType()));
+        // this may require encoding
+        appendString(term.getAddress().toString(), charset);
+    }
+
+
+    /**
+     * append IMAP search term information from a RecipientStringTerm item.
+     *
+     * @param term    The source RecipientStringTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendRecipient(RecipientStringTerm term, String charset) throws MessagingException {
+        appendAtom(recipientType(term.getRecipientType()));
+        // this may require encoding
+        appendString(term.getPattern(), charset);
+    }
+
+
+    /**
+     * Translate a recipient type into it's string name equivalent.
+     *
+     * @param type   The source recipient type
+     *
+     * @return A string name matching the recipient type.
+     */
+    protected String recipientType(Message.RecipientType type) throws MessagingException {
+        if (type == Message.RecipientType.TO) {
+            return "TO";
+        }
+        if (type == Message.RecipientType.CC) {
+            return "CC";
+        }
+        if (type == Message.RecipientType.BCC) {
+            return "BCC";
+        }
+
+        throw new SearchException("Unsupported RecipientType");
+    }
+
+
+    /**
+     * append IMAP search term information from a HeaderTerm item.
+     *
+     * @param term    The source HeaderTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendHeader(HeaderTerm term, String charset) throws MessagingException {
+        appendAtom("HEADER");
+        appendString(term.getHeaderName());
+        appendString(term.getPattern(), charset);
+    }
+
+
+
+    /**
+     * append IMAP search term information from a SubjectTerm item.
+     *
+     * @param term    The source SubjectTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendSubject(SubjectTerm term, String charset) throws MessagingException {
+        appendAtom("SUBJECT");
+        appendString(term.getPattern(), charset);
+    }
+
+
+    /**
+     * append IMAP search term information from a BodyTerm item.
+     *
+     * @param term    The source BodyTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendBody(BodyTerm term, String charset) throws MessagingException {
+        appendAtom("BODY");
+        appendString(term.getPattern(), charset);
+    }
+
+
+    /**
+     * append IMAP search term information from a SizeTerm item.
+     *
+     * @param term    The source SizeTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendSize(SizeTerm term, String charset) throws MessagingException {
+
+        // these comparisons can be a real pain.  IMAP only supports LARGER and SMALLER.  So comparisons
+        // other than GT and LT have to be composed of complex sequences of these.  For example, an EQ
+        // comparison becomes NOT LARGER size NOT SMALLER size
+
+        if (term.getComparison() == ComparisonTerm.GT) {
+            appendAtom("LARGER");
+            appendInteger(term.getNumber());
+        }
+        else if (term.getComparison() == ComparisonTerm.LT) {
+            appendAtom("SMALLER");
+            appendInteger(term.getNumber());
+        }
+        else if (term.getComparison() == ComparisonTerm.EQ) {
+            appendAtom("NOT");
+            appendAtom("LARGER");
+            appendInteger(term.getNumber());
+
+            appendAtom("NOT");
+            appendAtom("SMALLER");
+            // it's just right <g>
+            appendInteger(term.getNumber());
+        }
+        else if (term.getComparison() == ComparisonTerm.NE) {
+            // this needs to be an OR comparison
+            appendAtom("OR");
+            appendAtom("LARGER");
+            appendInteger(term.getNumber());
+
+            appendAtom("SMALLER");
+            appendInteger(term.getNumber());
+        }
+        else if (term.getComparison() == ComparisonTerm.LE) {
+            // just the inverse of LARGER
+            appendAtom("NOT");
+            appendAtom("LARGER");
+            appendInteger(term.getNumber());
+        }
+        else if (term.getComparison() == ComparisonTerm.GE) {
+            // and the reverse.
+            appendAtom("NOT");
+            appendAtom("SMALLER");
+            appendInteger(term.getNumber());
+        }
+    }
+
+
+    /**
+     * append IMAP search term information from a MessageIDTerm item.
+     *
+     * @param term    The source MessageIDTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendMessageID(MessageIDTerm term, String charset) throws MessagingException {
+
+        // not directly supported by IMAP, but we can compare on the header information.
+        appendAtom("HEADER");
+        appendString("Message-ID");
+        appendString(term.getPattern(), charset);
+    }
+
+
+    /**
+     * append IMAP search term information from a SendDateTerm item.
+     *
+     * @param term    The source SendDateTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendSentDate(SentDateTerm term, String charset) throws MessagingException {
+        Date date = term.getDate();
+
+        switch (term.getComparison()) {
+            case ComparisonTerm.EQ:
+                appendAtom("SENTON");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.LT:
+                appendAtom("SENTBEFORE");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.GT:
+                appendAtom("SENTSINCE");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.GE:
+                appendAtom("OR");
+                appendAtom("SENTSINCE");
+                appendSearchDate(date);
+                appendAtom("SENTON");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.LE:
+                appendAtom("OR");
+                appendAtom("SENTBEFORE");
+                appendSearchDate(date);
+                appendAtom("SENTON");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.NE:
+                appendAtom("NOT");
+                appendAtom("SENTON");
+                appendSearchDate(date);
+                break;
+            default:
+                throw new SearchException("Unsupported date comparison type");
+        }
+    }
+
+
+    /**
+     * append IMAP search term information from a ReceivedDateTerm item.
+     *
+     * @param term    The source ReceivedDateTerm
+     * @param charset target charset for the search information (can be null).
+     */
+    protected void appendReceivedDate(ReceivedDateTerm term, String charset) throws MessagingException {
+        Date date = term.getDate();
+
+        switch (term.getComparison()) {
+            case ComparisonTerm.EQ:
+                appendAtom("ON");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.LT:
+                appendAtom("BEFORE");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.GT:
+                appendAtom("SINCE");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.GE:
+                appendAtom("OR");
+                appendAtom("SINCE");
+                appendSearchDate(date);
+                appendAtom("ON");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.LE:
+                appendAtom("OR");
+                appendAtom("BEFORE");
+                appendSearchDate(date);
+                appendAtom("ON");
+                appendSearchDate(date);
+                break;
+            case ComparisonTerm.NE:
+                appendAtom("NOT");
+                appendAtom("ON");
+                appendSearchDate(date);
+                break;
+            default:
+                throw new SearchException("Unsupported date comparison type");
+        }
+    }
+
+
+    /**
+     * Run the tree of search terms, checking for problems with
+     * the terms that may require specifying a CHARSET modifier
+     * on a SEARCH command sent to the server.
+     *
+     * @param term   The term to check.
+     *
+     * @return True if there are 7-bit problems, false if the terms contain
+     *         only 7-bit ASCII characters.
+     */
+    static public boolean checkSearchEncoding(SearchTerm term) {
+        // StringTerm is the basis of most of the string-valued terms, and are most important ones to check.
+        if (term instanceof StringTerm) {
+            return checkStringEncoding(((StringTerm)term).getPattern());
+        }
+        // Address terms are basically string terms also, but we need to check the string value of the
+        // addresses, since that's what we're sending along.  This covers a lot of the TO/FROM, etc. searches.
+        else if (term instanceof AddressTerm) {
+            return checkStringEncoding(((AddressTerm)term).getAddress().toString());
+        }
+        // the NOT contains a term itself, so recurse on that.  The NOT does not directly have string values
+        // to check.
+        else if (term instanceof NotTerm) {
+            return checkSearchEncoding(((NotTerm)term).getTerm());
+        }
+        // AND terms and OR terms have lists of subterms that must be checked.
+        else if (term instanceof AndTerm) {
+            return checkSearchEncoding(((AndTerm)term).getTerms());
+        }
+        else if (term instanceof OrTerm) {
+            return checkSearchEncoding(((OrTerm)term).getTerms());
+        }
+
+        // non of the other term types (FlagTerm, SentDateTerm, etc.) pose a problem, so we'll give them
+        // a free pass.
+        return false;
+    }
+
+
+    /**
+     * Run an array of search term items to check each one for ASCII
+     * encoding problems.
+     *
+     * @param terms  The array of terms to check.
+     *
+     * @return True if any of the search terms contains a 7-bit ASCII problem,
+     *         false otherwise.
+     */
+    static public boolean checkSearchEncoding(SearchTerm[] terms) {
+        for (int i = 0; i < terms.length; i++) {
+            if (checkSearchEncoding(terms[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * Check a string to see if this can be processed using just
+     * 7-bit ASCII.
+     *
+     * @param s      The string to check
+     *
+     * @return true if the string contains characters outside the 7-bit ascii range,
+     *         false otherwise.
+     */
+    static public boolean checkStringEncoding(String s) {
+        for (int i = 0; i < s.length(); i++) {
+            // any value greater that 0x7f is a problem char.  We're not worried about
+            // lower ctl chars (chars < 32) since those are still expressible in 7-bit.
+            if (s.charAt(i) > 127) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Append a FetchProfile information to an IMAPCommand
+     * that's to be issued.
+     *
+     * @param profile The fetch profile we're using.
+     *
+     * @exception MessagingException
+     */
+    public void appendFetchProfile(FetchProfile profile) throws MessagingException {
+        // the fetch profile items are a parenthtical list passed on a
+        // FETCH command.
+        startList();
+        if (profile.contains(UIDFolder.FetchProfileItem.UID)) {
+            appendAtom("UID");
+        }
+        if (profile.contains(FetchProfile.Item.ENVELOPE)) {
+            // fetching the envelope involves several items
+            appendAtom("ENVELOPE");
+            appendAtom("INTERNALDATE");
+            appendAtom("RFC822.SIZE");
+        }
+        if (profile.contains(FetchProfile.Item.FLAGS)) {
+            appendAtom("FLAGS");
+        }
+        if (profile.contains(FetchProfile.Item.CONTENT_INFO)) {
+            appendAtom("BODYSTRUCTURE");
+        }
+        if (profile.contains(IMAPFolder.FetchProfileItem.SIZE)) {
+            appendAtom("RFC822.SIZE");
+        }
+        // There are two choices here, that are sort of redundant.
+        // if all headers have been requested, there's no point in
+        // adding any specifically requested one.
+        if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS)) {
+            appendAtom("BODY.PEEK[HEADER]");
+        }
+        else {
+            String[] headers = profile.getHeaderNames();
+            // have an actual list to retrieve?  need to craft this as a sublist
+            // of identified fields.
+            if (headers.length > 0) {
+                appendAtom("BODY.PEEK[HEADER.FIELDS]");
+                startList();
+                for (int i = 0; i < headers.length; i++) {
+                    appendAtom(headers[i]);
+                }
+                endList();
+            }
+        }
+        // end the list.
+        endList();
+    }
+
+
+    /**
+     * Append an ACL value to a command.  The ACL is the writes string name,
+     * followed by the rights value.  This version uses no +/- modifier.
+     *
+     * @param acl    The ACL to append.
+     */
+    public void appendACL(ACL acl) {
+        appendACL(acl, null);
+    }
+
+    /**
+     * Append an ACL value to a command.  The ACL is the writes string name,
+     * followed by the rights value.  A +/- modifier can be added to the
+     * // result.
+     *
+     * @param acl      The ACL to append.
+     * @param modifier The modifer string (can be null).
+     */
+    public void appendACL(ACL acl, String modifier) {
+        appendString(acl.getName());
+        String rights = acl.getRights().toString();
+
+        if (modifier != null) {
+            rights = modifier + rights;
+        }
+        appendString(rights);
+    }
+
+
+    /**
+     * Append a quota specification to an IMAP command.
+     *
+     * @param quota  The quota value to append.
+     */
+    public void appendQuota(Quota quota) {
+        appendString(quota.quotaRoot);
+        startList();
+        for (int i = 0; i < quota.resources.length; i++) {
+            appendQuotaResource(quota.resources[i]);
+        }
+        endList();
+    }
+
+    /**
+     * Append a Quota.Resource element to an IMAP command.  This converts as
+     * the resoure name, the usage value and limit value).
+     *
+     * @param resource The resource element we're appending.
+     */
+    public void appendQuotaResource(Quota.Resource resource) {
+        appendAtom(resource.name);
+        // NB:  For command purposes, only the limit is used.
+        appendLong(resource.limit);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
new file mode 100644
index 0000000..9922c68
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
@@ -0,0 +1,1992 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.mail.Address;
+import javax.mail.AuthenticationFailedException;
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Quota;
+import javax.mail.Session;
+import javax.mail.UIDFolder;
+import javax.mail.URLName;
+
+import javax.mail.internet.InternetHeaders;
+
+import javax.mail.search.SearchTerm;
+
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
+import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
+import org.apache.geronimo.javamail.authentication.LoginAuthenticator;
+import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
+import org.apache.geronimo.javamail.store.imap.ACL;
+import org.apache.geronimo.javamail.store.imap.Rights;
+
+import org.apache.geronimo.javamail.util.CommandFailedException;
+import org.apache.geronimo.javamail.util.InvalidCommandException;
+import org.apache.geronimo.javamail.util.MailConnection;
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+import org.apache.geronimo.javamail.util.TraceInputStream;
+import org.apache.geronimo.javamail.util.TraceOutputStream;
+import org.apache.geronimo.mail.util.Base64;
+
+/**
+ * Simple implementation of IMAP transport.  Just does plain RFC977-ish
+ * delivery.
+ * <p/>
+ * There is no way to indicate failure for a given recipient (it's possible to have a
+ * recipient address rejected).  The sun impl throws exceptions even if others successful),
+ * but maybe we do a different way...
+ * <p/>
+ *
+ * @version $Rev: 1641706 $ $Date: 2014-11-25 16:39:49 -0500 (Tue, 25 Nov 2014) $
+ */
+public class IMAPConnection extends MailConnection {
+
+    protected static final String CAPABILITY_LOGIN_DISABLED = "LOGINDISABLED";
+
+    // The connection pool we're a member of.  This keeps holds most of the
+    // connnection parameter information for us.
+    protected IMAPConnectionPool pool;
+
+    // special input stream for reading individual response lines.
+    protected IMAPResponseStream reader;
+
+    // connection pool connections.
+    protected long lastAccess = 0;
+    // our handlers for any untagged responses
+    protected LinkedList responseHandlers = new LinkedList();
+    // the list of queued untagged responses.
+    protected List queuedResponses = new LinkedList();
+    // this is set on if we had a forced disconnect situation from
+    // the server.
+    protected boolean closed = false;
+
+    /**
+     * Normal constructor for an IMAPConnection() object.
+     *
+     * @param props  The protocol properties abstraction containing our
+     *               property modifiers.
+     * @param pool
+     */
+    public IMAPConnection(ProtocolProperties props, IMAPConnectionPool pool) {
+        super(props);
+        this.pool = pool;
+    }
+
+
+    /**
+     * Connect to the server and do the initial handshaking.
+     *
+     * @exception MessagingException
+     */
+    public boolean protocolConnect(String host, int port, String authid, String realm, String username, String password) throws MessagingException {
+        this.serverHost = host;
+        this.serverPort = port;
+        this.realm = realm;
+        this.authid = authid;
+        this.username = username;
+        this.password = password;
+
+        boolean preAuthorized = false;
+
+        try {
+            // create socket and connect to server.
+            getConnection();
+
+            // we need to ask the server what its capabilities are.  This can be done
+            // before we login.
+            getCapability();
+            // do a preauthoriziation check.
+            if (extractResponse("PREAUTH") != null) {
+                preAuthorized = true;
+            }
+
+            // make sure we process these now
+            processPendingResponses();
+            
+            boolean requireTLS = props.getBooleanProperty(MAIL_STARTTLS_REQUIRED, false);
+            boolean enableTLS = props.getBooleanProperty(MAIL_STARTTLS_ENABLE, false);
+            boolean serverSupportsTLS = hasCapability(CAPABILITY_STARTTLS);
+
+            // if we're not already using an SSL connection, and we have permission to issue STARTTLS or its even required
+            // try to setup a SSL connection
+            if (!sslConnection && (enableTLS || requireTLS)) {
+                
+                //if the server does not support TLS check if its required.
+                //If true then throw an error, if not establish a non SSL connection
+                if(requireTLS && !serverSupportsTLS) {
+                    throw new MessagingException("Server doesn't support required transport level security");
+                } else if (serverSupportsTLS){
+                    // tell the server of our intention to start a TLS session
+                    sendSimpleCommand("STARTTLS");
+    
+                    // The connection is then handled by the superclass level.
+                    getConnectedTLSSocket();
+    
+                    // create the special reader for pulling the responses.
+                    reader = new IMAPResponseStream(inputStream);
+    
+                    // the IMAP spec states that the capability response is independent of login state or
+                    // user, but I'm not sure I believe that to be the case.  It doesn't hurt to refresh
+                    // the information again after establishing a secure connection.
+                    getCapability();
+                    // and we need to repeat this check.
+                    if (extractResponse("PREAUTH") != null) {
+                        preAuthorized = true;
+                    }
+                } else {
+                    if (debug) {
+                        debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
+                    }
+                }
+                
+            }
+
+            // damn, no login required.
+            if (preAuthorized) {
+                return true;
+            }
+
+            // go login with the server
+            return login();
+        } catch (IOException e) {
+            if (debug) {
+                debugOut("I/O exception establishing connection", e);
+            }
+            throw new MessagingException("Connection error", e);
+        }
+        finally {
+            // make sure the queue is cleared
+            processPendingResponses();
+        }
+    }
+
+    /**
+     * Update the last access time for the connection.
+     */
+    protected void updateLastAccess() {
+        lastAccess = System.currentTimeMillis();
+    }
+
+    /**
+     * Test if the connection has been sitting idle for longer than
+     * the set timeout period.
+     *
+     * @param timeout The allowed "freshness" interval.
+     *
+     * @return True if the connection has been active within the required
+     *         interval, false if it has been sitting idle for too long.
+     */
+    public boolean isStale(long timeout) {
+        return (System.currentTimeMillis() - lastAccess) > timeout;
+    }
+
+
+    /**
+     * Close the connection.  On completion, we'll be disconnected from
+     * the server and unable to send more data.
+     *
+     * @exception MessagingException
+     */
+    public void close() throws MessagingException {
+        // if we're already closed, get outta here.
+        if (socket == null) {
+            return;
+        }
+        try {
+            // say goodbye
+            logout();
+        } finally {
+            // and close up the connection.  We do this in a finally block to make sure the connection
+            // is shut down even if quit gets an error.
+            closeServerConnection();
+            // get rid of our response processor too.
+            reader = null;
+        }
+    }
+
+
+    /**
+     * Create a transport connection object and connect it to the
+     * target server.
+     *
+     * @exception MessagingException
+     */
+    protected void getConnection() throws IOException, MessagingException
+    {
+        // do all of the non-protocol specific set up.  This will get our socket established
+        // and ready use.
+        super.getConnection();
+        // create the special reader for pulling the responses.
+        reader = new IMAPResponseStream(inputStream);
+
+        // set the initial access time stamp
+        updateLastAccess();
+    }
+
+
+    /**
+     * Process a simple command/response sequence between the
+     * client and the server.  These are commands where the
+     * client is expecting them to "just work", and also will not
+     * directly process the reply information.  Unsolicited untagged
+     * responses are dispatched to handlers, and a MessagingException
+     * will be thrown for any non-OK responses from the server.
+     *
+     * @param data   The command data we're writing out.
+     *
+     * @exception MessagingException
+     */
+    public void sendSimpleCommand(String data) throws MessagingException {
+        // create a command object and issue the command with that.
+        IMAPCommand command = new IMAPCommand(data);
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Process a simple command/response sequence between the
+     * client and the server.  These are commands where the
+     * client is expecting them to "just work", and also will not
+     * directly process the reply information.  Unsolicited untagged
+     * responses are dispatched to handlers, and a MessagingException
+     * will be thrown for any non-OK responses from the server.
+     *
+     * @param data   The command data we're writing out.
+     *
+     * @exception MessagingException
+     */
+    public void sendSimpleCommand(IMAPCommand data) throws MessagingException {
+        // the command sending process will raise exceptions for bad responses....
+        // we just need to send the command and forget about it.
+        sendCommand(data);
+    }
+
+
+    /**
+     * Sends a  command down the socket, returning the server response.
+     *
+     * @param data   The String form of the command.
+     *
+     * @return The tagged response information that terminates the command interaction.
+     * @exception MessagingException
+     */
+    public IMAPTaggedResponse sendCommand(String data) throws MessagingException {
+        IMAPCommand command = new IMAPCommand(data);
+        return sendCommand(command);
+    }
+
+
+    /**
+     * Sends a  command down the socket, returning the server response.
+     *
+     * @param data   An IMAPCommand object with the prepared command information.
+     *
+     * @return The tagged (or continuation) response information that terminates the
+     *         command response sequence.
+     * @exception MessagingException
+     */
+    public synchronized IMAPTaggedResponse sendCommand(IMAPCommand data) throws MessagingException {
+        // check first
+        checkConnected();
+        try {
+            // have the command write the command data.  This also prepends a tag.
+            data.writeTo(outputStream, this);
+            outputStream.flush();
+            // update the activity timestamp
+            updateLastAccess();
+            // get the received response
+            return receiveResponse();
+        } catch (IOException e) {
+            throw new MessagingException(e.toString(), e);
+        }
+    }
+
+
+    /**
+     * Sends a  message down the socket and terminates with the
+     * appropriate CRLF
+     *
+     * @param data   The string data to send.
+     *
+     * @return An IMAPTaggedResponse item returned from the server.
+     * @exception MessagingException
+     */
+    public IMAPTaggedResponse sendLine(String data) throws MessagingException {
+        try {
+            return sendLine(data.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+            // should never happen
+            return null;
+        }
+    }
+
+
+    /**
+     * Sends a  message down the socket and terminates with the
+     * appropriate CRLF
+     *
+     * @param data   The array of data to send to the server.
+     *
+     * @return The response item returned from the IMAP server.
+     * @exception MessagingException
+     */
+    public IMAPTaggedResponse sendLine(byte[] data) throws MessagingException {
+        return sendLine(data, 0, data.length);
+    }
+
+
+    /**
+     * Sends a  message down the socket and terminates with the
+     * appropriate CRLF
+     *
+     * @param data   The source data array.
+     * @param offset The offset within the data array.
+     * @param length The length of data to send.
+     *
+     * @return The response line returned from the IMAP server.
+     * @exception MessagingException
+     */
+    public synchronized IMAPTaggedResponse sendLine(byte[] data, int offset, int length) throws MessagingException {
+        // check first
+        checkConnected();
+
+        try {
+            outputStream.write(data, offset, length);
+            outputStream.write(CR);
+            outputStream.write(LF);
+            outputStream.flush();
+            // update the activity timestamp
+            updateLastAccess();
+            return receiveResponse();
+        } catch (IOException e) {
+            throw new MessagingException(e.toString(), e);
+        }
+    }
+
+
+    /**
+     * Get a reply line for an IMAP command.
+     *
+     * @return An IMAP reply object from the stream.
+     */
+    public IMAPTaggedResponse receiveResponse() throws MessagingException {
+        while (true) {
+            // read and parse a response from the server.
+            IMAPResponse response = reader.readResponse();
+            // The response set is terminated by either a continuation response or a
+            // tagged response (we only have a single command active at one time).
+            if (response instanceof IMAPTaggedResponse) {
+                // update the access time stamp for later timeout processing.
+                updateLastAccess();
+                IMAPTaggedResponse tagged = (IMAPTaggedResponse)response;
+                // we turn these into exceptions here, which means the issuer doesn't have to
+                // worry about checking status.
+                if (tagged.isBAD()) {
+                    throw new InvalidCommandException("Unexpected command IMAP command error");
+                }
+                else if (tagged.isNO()) {
+                    throw new CommandFailedException("Unexpected error executing IMAP command");
+                }
+                return tagged;
+            }
+            else {
+                // all other unsolicited responses are either async status updates or
+                // additional elements of a command we just sent.  These will be processed
+                // either during processing of the command response, or at the end of the
+                // current command processing.
+                queuePendingResponse((IMAPUntaggedResponse)response);
+            }
+        }
+    }
+
+
+    /**
+     * Get the servers capabilities from the wire....
+     */
+    public void getCapability() throws MessagingException {
+        sendCommand("CAPABILITY");
+        // get the capabilities from the response.
+        IMAPCapabilityResponse response = (IMAPCapabilityResponse)extractResponse("CAPABILITY");
+        capabilities = response.getCapabilities();
+        authentications = response.getAuthentications();
+    }
+
+    /**
+     * Logs out from the server.
+     */
+    public void logout() throws MessagingException {
+        // We can just send the command and generally ignore the
+        // status response.
+        sendCommand("LOGOUT");
+    }
+
+    /**
+     * Deselect a mailbox when a folder returns a connection.
+     *
+     * @exception MessagingException
+     */
+    public void closeMailbox() throws MessagingException {
+        // We can just send the command and generally ignore the
+        // status response.
+        sendCommand("CLOSE");
+    }
+
+
+    /**
+     * Authenticate with the server, if necessary (or possible).
+     *
+     * @return true if we were able to authenticate correctly, false for authentication failures.
+     * @exception MessagingException
+     */
+    protected boolean login() throws MessagingException
+    {
+        // if no username or password, fail this immediately.
+        // the base connect property should resolve a username/password combo for us and
+        // try again.
+        if (username == null || password == null) {
+            return false;
+        }
+
+        // are we permitted to use SASL mechanisms?
+        if (props.getBooleanProperty(MAIL_SASL_ENABLE, false)) {
+            // we might be enable for SASL, but the client and the server might
+            // not have any supported mechanisms in common.  Try again with another
+            // mechanism.
+            if (processSaslAuthentication()) {
+                return true;
+            }
+        }
+
+        // see if we're allowed to try plain.
+        if (!props.getBooleanProperty(MAIL_PLAIN_DISABLE, false) && supportsMechanism(AUTHENTICATION_PLAIN)) {
+            return processPlainAuthentication();
+        }
+
+        // see if we're allowed to try login.
+        if (!props.getBooleanProperty(MAIL_LOGIN_DISABLE, false) && supportsMechanism(AUTHENTICATION_LOGIN)) {
+            // no authzid capability with this authentication method.
+            return processLoginAuthentication();
+        }
+
+        // the server can choose to disable the LOGIN command.  If not disabled, try
+        // using LOGIN rather than AUTHENTICATE.
+        if (!hasCapability(CAPABILITY_LOGIN_DISABLED)) {
+            return processLogin();
+        }
+
+        throw new MessagingException("No supported LOGIN methods enabled");
+    }
+
+
+    /**
+     * Process SASL-type authentication.
+     *
+     * @return Returns true if the server support a SASL authentication mechanism and
+     * accepted reponse challenges.
+     * @exception MessagingException
+     */
+    protected boolean processSaslAuthentication() throws MessagingException {
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
+        if (authenticator == null) {
+            return false;
+        }
+
+        // go process the login.
+        return processLogin(authenticator);
+    }
+
+    protected ClientAuthenticator getSaslAuthenticator() {
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
+    }
+
+    /**
+     * Process SASL-type PLAIN authentication.
+     *
+     * @return Returns true if the login is accepted.
+     * @exception MessagingException
+     */
+    protected boolean processPlainAuthentication() throws MessagingException {
+        // go process the login.
+        return processLogin(new PlainAuthenticator(authid, username, password));
+    }
+
+
+    /**
+     * Process SASL-type LOGIN authentication.
+     *
+     * @return Returns true if the login is accepted.
+     * @exception MessagingException
+     */
+    protected boolean processLoginAuthentication() throws MessagingException {
+        // go process the login.
+        return processLogin(new LoginAuthenticator(username, password));
+    }
+
+
+    /**
+     * Process a LOGIN using the LOGIN command instead of AUTHENTICATE.
+     *
+     * @return true if the command succeeded, false for any authentication failures.
+     * @exception MessagingException
+     */
+    protected boolean processLogin() throws MessagingException {
+        // arguments are "LOGIN userid password"
+        IMAPCommand command = new IMAPCommand("LOGIN");
+        command.appendAtom(username);
+        command.appendAtom(password);
+
+        // go issue the command
+        try {
+            sendCommand(command);
+        } catch (CommandFailedException e) {
+            // we'll get a NO response for a rejected login
+            return false;
+        }
+        // seemed to work ok....
+        return true;
+    }
+
+
+    /**
+     * Process a login using the provided authenticator object.
+     *
+     * NB:  This method is synchronized because we have a multi-step process going on
+     * here.  No other commands should be sent to the server until we complete.
+     *
+     * @return Returns true if the server support a SASL authentication mechanism and
+     * accepted reponse challenges.
+     * @exception MessagingException
+     */
+    protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
+        if (debug) {
+            debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
+        }
+
+        IMAPCommand command = new IMAPCommand("AUTHENTICATE");
+        // and tell the server which mechanism we're using.
+        command.appendAtom(authenticator.getMechanismName());
+        // send the command now
+
+        try {
+            IMAPTaggedResponse response = sendCommand(command);
+
+            // now process the challenge sequence.  We get a 235 response back when the server accepts the
+            // authentication, and a 334 indicates we have an additional challenge.
+            while (true) {
+                // this should be a continuation reply, if things are still good.
+                if (response.isContinuation()) {
+                    // we're passed back a challenge value, Base64 encoded.
+                    byte[] challenge = response.decodeChallengeResponse();
+
+                    // have the authenticator evaluate and send back the encoded response.
+                    response = sendLine(Base64.encode(authenticator.evaluateChallenge(challenge)));
+                }
+                else {
+                    // there are only two choices here, OK or a continuation.  OK means
+                    // we've passed muster and are in.
+                    return true;
+                }
+            }
+        } catch (CommandFailedException e ) {
+            // a failure at any point in this process will result in a "NO" response.
+            // That causes an exception to get thrown, so just fail the login
+            // if we get one.
+            return false;
+        }
+    }
+
+
+    /**
+     * Return the server host for this connection.
+     *
+     * @return The String name of the server host.
+     */
+    public String getHost() {
+        return serverHost;
+    }
+
+
+    /**
+     * Attach a handler for untagged responses to this connection.
+     *
+     * @param h      The new untagged response handler.
+     */
+    public synchronized void addResponseHandler(IMAPUntaggedResponseHandler h) {
+        responseHandlers.add(h);
+    }
+
+
+    /**
+     * Remove a response handler from the connection.
+     *
+     * @param h      The handler to remove.
+     */
+    public synchronized void removeResponseHandler(IMAPUntaggedResponseHandler h) {
+        responseHandlers.remove(h);
+    }
+
+
+    /**
+     * Add a response to the pending untagged response queue.
+     *
+     * @param response The response to add.
+     */
+    public synchronized void queuePendingResponse(IMAPUntaggedResponse response) {
+        queuedResponses.add(response);
+    }
+
+    /**
+     * Process any untagged responses in the queue.  This will clear out
+     * the queue, and send each response to the registered
+     * untagged response handlers.
+     */
+    public void processPendingResponses() throws MessagingException {
+        List pendingResponses = null;
+        List handlerList = null;
+
+        synchronized(this) {
+            if (queuedResponses.isEmpty()) {
+                return;
+            }
+            pendingResponses = queuedResponses;
+            queuedResponses = new LinkedList();
+            // get a copy of the response handlers so we can
+            // release the connection lock before broadcasting
+            handlerList = (List)responseHandlers.clone();
+        }
+
+        for (int i = 0; i < pendingResponses.size(); i++) {
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)pendingResponses.get(i);
+            for (int j = 0; j < handlerList.size(); j++) {
+                // broadcast to each handler.  If a handler returns true, then it
+                // handled whatever this message required and we should skip sending
+                // it to other handlers.
+                IMAPUntaggedResponseHandler h = (IMAPUntaggedResponseHandler)handlerList.get(j);
+                if (h.handleResponse(response)) {
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Extract a single response from the pending queue that
+     * match a give keyword type.  All matching responses
+     * are removed from the pending queue.
+     *
+     * @param type   The string name of the keyword.
+     *
+     * @return A List of all matching queued responses.
+     */
+    public IMAPUntaggedResponse extractResponse(String type) {
+        Iterator i = queuedResponses.iterator();
+        while (i.hasNext()) {
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
+            // if this is of the target type, move it to the response set.
+            if (response.isKeyword(type)) {
+                i.remove();
+                return response;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Extract all responses from the pending queue that
+     * match a give keyword type.  All matching responses
+     * are removed from the pending queue.
+     *
+     * @param type   The string name of the keyword.
+     *
+     * @return A List of all matching queued responses.
+     */
+    public List extractResponses(String type) {
+        List responses = new ArrayList();
+
+        Iterator i = queuedResponses.iterator();
+        while (i.hasNext()) {
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
+            // if this is of the target type, move it to the response set.
+            if (response.isKeyword(type)) {
+                i.remove();
+                responses.add(response);
+            }
+        }
+        return responses;
+    }
+
+
+    /**
+     * Extract all responses from the pending queue that
+     * are "FETCH" responses for a given message number.  All matching responses
+     * are removed from the pending queue.
+     *
+     * @param type   The string name of the keyword.
+     *
+     * @return A List of all matching queued responses.
+     */
+    public List extractFetchResponses(int sequenceNumber) {
+        List responses = new ArrayList();
+
+        Iterator i = queuedResponses.iterator();
+        while (i.hasNext()) {
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
+            // if this is of the target type, move it to the response set.
+            if (response.isKeyword("FETCH")) {
+                IMAPFetchResponse fetch = (IMAPFetchResponse)response;
+                // a response for the correct message number?
+                if (fetch.sequenceNumber == sequenceNumber) {
+                    // pluck these from the list and add to the response set.
+                    i.remove();
+                    responses.add(response);
+                }
+            }
+        }
+        return responses;
+    }
+
+    /**
+     * Extract a fetch response data item from the queued elements.
+     *
+     * @param sequenceNumber
+     *               The message number we're interested in.  Fetch responses for other messages
+     *               will be skipped.
+     * @param type   The type of body element we need. It is assumed that only one item for
+     *               the given message number will exist in the queue.  The located item will
+     *               be returned, and that fetch response will be removed from the pending queue.
+     *
+     * @return The target data item, or null if a match is not found.
+     */
+    protected IMAPFetchDataItem extractFetchDataItem(long sequenceNumber, int type)
+    {
+        Iterator i = queuedResponses.iterator();
+        while (i.hasNext()) {
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
+            // if this is of the target type, move it to the response set.
+            if (response.isKeyword("FETCH")) {
+                IMAPFetchResponse fetch = (IMAPFetchResponse)response;
+                // a response for the correct message number?
+                if (fetch.sequenceNumber == sequenceNumber) {
+                    // does this response have the item we're looking for?
+                    IMAPFetchDataItem item = fetch.getDataItem(type);
+                    if (item != null) {
+                        // remove this from the pending queue and return the
+                        // located item
+                        i.remove();
+                        return item;
+                    }
+                }
+            }
+        }
+        // not located, sorry
+        return null;
+    }
+
+    /**
+     * Extract a all fetch responses that contain a given data item.
+     *
+     * @param type   The type of body element we need. It is assumed that only one item for
+     *               the given message number will exist in the queue.  The located item will
+     *               be returned, and that fetch response will be removed from the pending queue.
+     *
+     * @return A List of all matching Fetch responses.
+     */
+    protected List extractFetchDataItems(int type)
+    {
+        Iterator i = queuedResponses.iterator();
+        List items = new ArrayList();
+
+        while (i.hasNext()) {
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
+            // if this is of the target type, move it to the response set.
+            if (response.isKeyword("FETCH")) {
+                IMAPFetchResponse fetch = (IMAPFetchResponse)response;
+                // does this response have the item we're looking for?
+                IMAPFetchDataItem item = fetch.getDataItem(type);
+                if (item != null) {
+                    // remove this from the pending queue and return the
+                    // located item
+                    i.remove();
+                    // we want the fetch response, not the data item, because
+                    // we're going to require the message sequence number information
+                    // too.
+                    items.add(fetch);
+                }
+            }
+        }
+        // return whatever we have.
+        return items;
+    }
+
+    /**
+     * Make sure we have the latest status information available.  We
+     * retreive this by sending a NOOP command to the server, and
+     * processing any untagged responses we get back.
+     */
+    public void updateMailboxStatus() throws MessagingException {
+        sendSimpleCommand("NOOP");
+    }
+
+
+    /**
+     * check to see if this connection is truely alive.
+     *
+     * @param timeout The timeout value to control how often we ping
+     *                the server to see if we're still good.
+     *
+     * @return true if the server is responding to requests, false for any
+     *         connection errors.  This will also update the folder status
+     *         by processing returned unsolicited messages.
+     */
+    public synchronized boolean isAlive(long timeout) {
+        long lastUsed = System.currentTimeMillis() - lastAccess;
+        if (lastUsed < timeout) {
+            return true;
+        }
+
+        try {
+            sendSimpleCommand("NOOP");
+            return true;
+        } catch (MessagingException e) {
+            // the NOOP command will throw a MessagingException if we get anything
+            // other than an OK response back from the server.
+        }
+        return false;
+    }
+
+
+    /**
+     * Issue a fetch command to retrieve the message ENVELOPE structure.
+     *
+     * @param sequenceNumber The sequence number of the message.
+     *
+     * @return The IMAPResponse item containing the ENVELOPE information.
+     */
+    public synchronized List fetchEnvelope(int sequenceNumber) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.startList();
+        command.appendAtom("ENVELOPE INTERNALDATE RFC822.SIZE");
+        command.endList();
+
+        // we want all of the envelope information about the message, which involves multiple FETCH chunks.
+        sendCommand(command);
+        // these are fairly involved sets, so the caller needs to handle these.
+        // we just return all of the FETCH results matching the target message number.
+        return extractFetchResponses(sequenceNumber);
+    }
+
+    /**
+     * Issue a FETCH command to retrieve the message BODYSTRUCTURE structure.
+     *
+     * @param sequenceNumber The sequence number of the message.
+     *
+     * @return The IMAPBodyStructure item for the message.
+     *         All other untagged responses are queued for processing.
+     */
+    public synchronized IMAPBodyStructure fetchBodyStructure(int sequenceNumber) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.startList();
+        command.appendAtom("BODYSTRUCTURE");
+        command.endList();
+
+        // we want all of the envelope information about the message, which involves multiple FETCH chunks.
+        sendCommand(command);
+        // locate the response from this
+        IMAPBodyStructure bodyStructure = (IMAPBodyStructure)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.BODYSTRUCTURE);
+
+        if (bodyStructure == null) {
+            throw new MessagingException("No BODYSTRUCTURE information received from IMAP server");
+        }
+        // and return the body structure directly.
+        return bodyStructure;
+    }
+
+
+    /**
+     * Issue a FETCH command to retrieve the message RFC822.HEADERS structure containing the message headers (using PEEK).
+     *
+     * @param sequenceNumber The sequence number of the message.
+     *
+     * @return The IMAPRFC822Headers item for the message.
+     *         All other untagged responses are queued for processing.
+     */
+    public synchronized InternetHeaders fetchHeaders(int sequenceNumber, String part) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.startList();
+        command.appendAtom("BODY.PEEK");
+        command.appendBodySection(part, "HEADER");
+        command.endList();
+
+        // we want all of the envelope information about the message, which involves multiple FETCH chunks.
+        sendCommand(command);
+        IMAPInternetHeader header = (IMAPInternetHeader)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.HEADER);
+
+        if (header == null) {
+            throw new MessagingException("No HEADER information received from IMAP server");
+        }
+        // and return the body structure directly.
+        return header.headers;
+    }
+
+
+    /**
+     * Issue a FETCH command to retrieve the message text
+     *
+     * @param sequenceNumber The sequence number of the message.
+     *
+     * @return The IMAPMessageText item for the message.
+     *         All other untagged responses are queued for processing.
+     */
+    public synchronized IMAPMessageText fetchText(int sequenceNumber) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.startList();
+        command.appendAtom("BODY.PEEK");
+        command.appendBodySection("TEXT");
+        command.endList();
+
+        // we want all of the envelope information about the message, which involves multiple FETCH chunks.
+        sendCommand(command);
+        IMAPMessageText text = (IMAPMessageText)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.TEXT);
+
+        if (text == null) {
+            throw new MessagingException("No TEXT information received from IMAP server");
+        }
+        // and return the body structure directly.
+        return text;
+    }
+
+
+    /**
+     * Issue a FETCH command to retrieve the message text
+     *
+     * @param sequenceNumber The sequence number of the message.
+     *
+     * @return The IMAPMessageText item for the message.
+     *         All other untagged responses are queued for processing.
+     */
+    public synchronized IMAPMessageText fetchBodyPartText(int sequenceNumber, String section) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.startList();
+        command.appendAtom("BODY.PEEK");
+        command.appendBodySection(section, "TEXT");
+        command.endList();
+
+        // we want all of the envelope information about the message, which involves multiple FETCH chunks.
+        sendCommand(command);
+        IMAPMessageText text = (IMAPMessageText)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.TEXT);
+
+        if (text == null) {
+            throw new MessagingException("No TEXT information received from IMAP server");
+        }
+        // and return the body structure directly.
+        return text;
+    }
+
+
+    /**
+     * Issue a FETCH command to retrieve the entire message body in one shot.
+     * This may also be used to fetch an embedded message part as a unit.
+     *
+     * @param sequenceNumber
+     *                The sequence number of the message.
+     * @param section The section number to fetch.  If null, the entire body of the message
+     *                is retrieved.
+     *
+     * @return The IMAPBody item for the message.
+     *         All other untagged responses are queued for processing.
+     * @exception MessagingException
+     */
+    public synchronized IMAPBody fetchBody(int sequenceNumber, String section) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.startList();
+        command.appendAtom("BODY.PEEK");
+        // no part name here, only the section identifier.  This will fetch
+        // the entire body, with all of the bits in place.
+        command.appendBodySection(section, null);
+        command.endList();
+
+        // we want all of the envelope information about the message, which involves multiple FETCH chunks.
+        sendCommand(command);
+        IMAPBody body = (IMAPBody)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.BODY);
+
+        if (body == null) {
+            throw new MessagingException("No BODY information received from IMAP server");
+        }
+        // and return the body structure directly.
+        return body;
+    }
+
+
+    /**
+     * Fetch the message content.  This sorts out which method should be used
+     * based on the server capability.
+     *
+     * @param sequenceNumber
+     *               The sequence number of the target message.
+     *
+     * @return The byte[] content information.
+     * @exception MessagingException
+     */
+    public byte[] fetchContent(int sequenceNumber) throws MessagingException {
+        // fetch the text item and return the data
+        IMAPMessageText text = fetchText(sequenceNumber);
+        return text.getContent();
+    }
+
+
+    /**
+     * Fetch the message content.  This sorts out which method should be used
+     * based on the server capability.
+     *
+     * @param sequenceNumber
+     *               The sequence number of the target message.
+     *
+     * @return The byte[] content information.
+     * @exception MessagingException
+     */
+    public byte[] fetchContent(int sequenceNumber, String section) throws MessagingException {
+        if (section == null) {
+            IMAPMessageText text = fetchText(sequenceNumber);
+            return text.getContent();
+        } else {
+            IMAPBody body = fetchBody(sequenceNumber, section);
+            return body.getContent();
+        }
+    }
+
+
+    /**
+     * Send an LIST command to the IMAP server, returning all LIST
+     * response information.
+     *
+     * @param mailbox The reference mailbox name sent on the command.
+     * @param pattern The match pattern used on the name.
+     *
+     * @return A List of all LIST response information sent back from the server.
+     */
+    public synchronized List list(String mailbox, String pattern) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("LIST");
+
+        // construct the command, encoding the tokens as required by the content.
+        command.appendEncodedString(mailbox);
+        command.appendEncodedString(pattern);
+
+        sendCommand(command);
+
+        // pull out the ones we're interested in
+        return extractResponses("LIST");
+    }
+
+
+    /**
+     * Send an LSUB command to the IMAP server, returning all LSUB
+     * response information.
+     *
+     * @param mailbox The reference mailbox name sent on the command.
+     * @param pattern The match pattern used on the name.
+     *
+     * @return A List of all LSUB response information sent back from the server.
+     */
+    public List listSubscribed(String mailbox, String pattern) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("LSUB");
+
+        // construct the command, encoding the tokens as required by the content.
+        command.appendEncodedString(mailbox);
+        command.appendEncodedString(pattern);
+
+        sendCommand(command);
+        // pull out the ones we're interested in
+        return extractResponses("LSUB");
+    }
+
+
+    /**
+     * Subscribe to a give mailbox.
+     *
+     * @param mailbox The desired mailbox name.
+     *
+     * @exception MessagingException
+     */
+    public void subscribe(String mailbox) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("SUBSCRIBE");
+        // add on the encoded mailbox name, as the appropriate token type.
+        command.appendEncodedString(mailbox);
+
+        // send this, and ignore the response.
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Unsubscribe from a mailbox.
+     *
+     * @param mailbox The mailbox to remove.
+     *
+     * @exception MessagingException
+     */
+    public void unsubscribe(String mailbox) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("UNSUBSCRIBE");
+        // add on the encoded mailbox name, as the appropriate token type.
+        command.appendEncodedString(mailbox);
+
+        // send this, and ignore the response.
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Create a mailbox.
+     *
+     * @param mailbox The desired new mailbox name (fully qualified);
+     *
+     * @exception MessagingException
+     */
+    public void createMailbox(String mailbox) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("CREATE");
+        // add on the encoded mailbox name, as the appropriate token type.
+        command.appendEncodedString(mailbox);
+
+        // send this, and ignore the response.
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Delete a mailbox.
+     *
+     * @param mailbox The target mailbox name (fully qualified);
+     *
+     * @exception MessagingException
+     */
+    public void deleteMailbox(String mailbox) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("DELETE");
+        // add on the encoded mailbox name, as the appropriate token type.
+        command.appendEncodedString(mailbox);
+
+        // send this, and ignore the response.
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Rename a mailbox.
+     *
+     * @param mailbox The target mailbox name (fully qualified);
+     *
+     * @exception MessagingException
+     */
+    public void renameMailbox(String oldName, String newName) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("RENAME");
+        // add on the encoded mailbox name, as the appropriate token type.
+        command.appendEncodedString(oldName);
+        command.appendEncodedString(newName);
+
+        // send this, and ignore the response.
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Retrieve a complete set of status items for a mailbox.
+     *
+     * @param mailbox The mailbox name.
+     *
+     * @return An IMAPMailboxStatus item filled in with the STATUS responses.
+     * @exception MessagingException
+     */
+    public synchronized IMAPMailboxStatus getMailboxStatus(String mailbox) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("STATUS");
+
+        // construct the command, encoding the tokens as required by the content.
+        command.appendEncodedString(mailbox);
+        // request all of the status items
+        command.append(" (MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)");
+
+        sendCommand(command);
+
+        // now harvest each of the respon
+        IMAPMailboxStatus status = new IMAPMailboxStatus();
+        status.mergeSizeResponses(extractResponses("EXISTS"));
+        status.mergeSizeResponses(extractResponses("RECENT"));
+        status.mergeOkResponses(extractResponses("UIDNEXT"));
+        status.mergeOkResponses(extractResponses("UIDVALIDITY"));
+        status.mergeOkResponses(extractResponses("UNSEEN"));
+        status.mergeStatus((IMAPStatusResponse)extractResponse("STATUS"));
+        status.mergeStatus((IMAPPermanentFlagsResponse)extractResponse("PERMANENTFLAGS"));
+
+        return status;
+    }
+
+
+    /**
+     * Select a mailbox, returning the accumulated status information
+     * about the mailbox returned with the response.
+     *
+     * @param mailbox  The desired mailbox name.
+     * @param readOnly The open mode.  If readOnly is true, the mailbox is opened
+     *                 using EXAMINE rather than SELECT.
+     *
+     * @return A status object containing the mailbox particulars.
+     * @exception MessagingException
+     */
+    public synchronized IMAPMailboxStatus openMailbox(String mailbox, boolean readOnly) throws MessagingException {
+        IMAPCommand command = new IMAPCommand();
+
+        // if readOnly is required, we use EXAMINE to switch to the mailbox rather than SELECT.
+        // This returns the same response information, but the mailbox will not accept update operations.
+        if (readOnly) {
+            command.appendAtom("EXAMINE");
+        }
+        else {
+            command.appendAtom("SELECT");
+        }
+
+        // construct the command, encoding the tokens as required by the content.
+        command.appendEncodedString(mailbox);
+
+        // issue the select
+        IMAPTaggedResponse response = sendCommand(command);
+
+        IMAPMailboxStatus status = new IMAPMailboxStatus();
+        // set the mode to the requested open mode.
+        status.mode = readOnly ? Folder.READ_ONLY : Folder.READ_WRITE;
+
+        // the server might disagree on the mode, so check to see if
+        // it's telling us READ-ONLY.
+        if (response.hasStatus("READ-ONLY")) {
+            status.mode = Folder.READ_ONLY;
+        }
+
+        // some of these are required, some are optional.
+        status.mergeFlags((IMAPFlagsResponse)extractResponse("FLAGS"));
+        status.mergeStatus((IMAPSizeResponse)extractResponse("EXISTS"));
+        status.mergeStatus((IMAPSizeResponse)extractResponse("RECENT"));
+        status.mergeStatus((IMAPOkResponse)extractResponse("UIDVALIDITY"));
+        status.mergeStatus((IMAPOkResponse)extractResponse("UNSEEN"));
+        status.mergeStatus((IMAPPermanentFlagsResponse)extractResponse("PERMANENTFLAGS"));
+        // mine the response for status information about the selected mailbox.
+        return status;
+    }
+
+
+    /**
+     * Tells the IMAP server to expunge messages marked for deletion.
+     * The server will send us an untagged EXPUNGE message back for
+     * each deleted message.  For explicit expunges we request, we'll
+     * grabbed the untagged responses here, rather than force them to
+     * be handled as pending responses.  The caller will handle the
+     * updates directly.
+     *
+     * @exception MessagingException
+     */
+    public synchronized List expungeMailbox() throws MessagingException {
+        // send the message, and make sure we got an OK response
+        sendCommand("EXPUNGE");
+        // extract all of the expunged responses and return.
+        return extractResponses("EXPUNGED");
+    }
+
+    public int[] searchMailbox(SearchTerm term) throws MessagingException {
+        return searchMailbox("ALL", term);
+    }
+
+    /**
+     * Send a search to the IMAP server using the specified
+     * messages selector and search term.  This figures out what
+     * to do with CHARSET on the SEARCH command.
+     *
+     * @param messages The list of messages (comma-separated numbers or "ALL").
+     * @param term     The desired search criteria
+     *
+     * @return Returns an int[] array of message numbers for all matched messages.
+     * @exception MessagingException
+     */
+    public int[] searchMailbox(String messages, SearchTerm term) throws MessagingException {
+        // don't use a charset by default, but we need to look at the data to see if we have a problem.
+        String charset = null;
+
+        if (IMAPCommand.checkSearchEncoding(term)) {
+            // not sure exactly how to decide what to use here.  Two immediate possibilities come to mind,
+            // UTF-8 or the MimeUtility.getDefaultJavaCharset() value.  Running a small test against the
+            // Sun impl shows them sending a CHARSET value of UTF-8, so that sounds like the winner.  I don't
+            // believe there's anything in the CAPABILITY response that would tell us what to use.
+            charset = "UTF-8";
+        }
+
+        return searchMailbox(messages, term, charset);
+    }
+
+    /**
+     * Send a search to the IMAP server using the specified
+     * messages selector and search term.
+     *
+     * @param messages The list of messages (comma-separated numbers or "ALL").
+     * @param charset  The charset specifier to send to the server.  If null, then
+     *                 the CHARSET keyword is omitted.
+     * @param term     The desired search criteria
+     *
+     * @return Returns an int[] array of message numbers for all matched messages.
+     * @exception MessagingException
+     */
+    public synchronized int[] searchMailbox(String messages, SearchTerm term, String charset) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("SEARCH");
+
+        // if we have an explicit charset to use, append that.
+        if (charset != null) {
+            command.appendAtom("CHARSET");
+            command.appendAtom(charset);
+        }
+
+        // now go through the process of translating the javamail SearchTerm objects into
+        // the IMAP command sequence.  The SearchTerm sequence may be a complex tree of comparison terms,
+        // so this is not a simple process.
+        command.appendSearchTerm(term, charset);
+        // need to append the message set
+        command.appendAtom(messages);
+
+        // now issue the composed command.
+        sendCommand(command);
+
+        // get the list of search responses
+        IMAPSearchResponse hits = (IMAPSearchResponse)extractResponse("SEARCH");
+        // and return the message hits
+        return hits.messageNumbers;
+    }
+
+
+    /**
+     * Append a message to a mailbox, given the direct message data.
+     *
+     * @param mailbox The target mailbox name.
+     * @param messageFlags
+     *                The initial flag set for the appended message.
+     * @param messageDate
+     *                The received date the message is created with,
+     * @param messageData
+     *                The RFC822 Message data stored on the server.
+     *
+     * @exception MessagingException
+     */
+    public void appendMessage(String mailbox, Date messageDate, Flags messageFlags, byte[] messageData) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("APPEND");
+
+        // the mailbox is encoded.
+        command.appendEncodedString(mailbox);
+
+        if (messageFlags != null) {
+            // the flags are pulled from an existing object.  We can set most flag values, but the servers
+            // reserve RECENT for themselves.  We need to force that one off.
+            messageFlags.remove(Flags.Flag.RECENT);
+            // and add the flag list to the commmand.
+            command.appendFlags(messageFlags);
+        }
+
+        if (messageDate != null) {
+            command.appendDate(messageDate);
+        }
+
+        // this gets appended as a literal.
+        command.appendLiteral(messageData);
+        // just send this as a simple command...we don't deal with the response other than to verifiy
+        // it was ok.
+        sendSimpleCommand(command);
+    }
+
+    /**
+     * Fetch the flag set for a given message sequence number.
+     *
+     * @param sequenceNumber
+     *               The message sequence number.
+     *
+     * @return The Flags defined for this message.
+     * @exception MessagingException
+     */
+    public synchronized Flags fetchFlags(int sequenceNumber) throws MessagingException {
+        // we want just the flag item here.
+        sendCommand("FETCH " + String.valueOf(sequenceNumber) + " (FLAGS)");
+        // get the return data item, and get the flags from within it
+        IMAPFlags flags = (IMAPFlags)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.FLAGS);
+        return flags.flags;
+    }
+
+
+    /**
+     * Set the flags for a range of messages.
+     *
+     * @param messageSet The set of message numbers.
+     * @param flags      The new flag settings.
+     * @param set        true if the flags should be set, false for a clear operation.
+     *
+     * @return A list containing all of the responses with the new flag values.
+     * @exception MessagingException
+     */
+    public synchronized List setFlags(String messageSet, Flags flags, boolean set) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("STORE");
+        command.appendAtom(messageSet);
+        // the command varies depending on whether this is a set or clear operation
+        if (set) {
+            command.appendAtom("+FLAGS");
+        }
+        else {
+            command.appendAtom("-FLAGS");
+        }
+
+        // append the flag set
+        command.appendFlags(flags);
+
+        // we want just the flag item here.
+        sendCommand(command);
+        // we should have a FETCH response for each of the updated messages.  Return this
+        // response, and update the message numbers.
+        return extractFetchDataItems(IMAPFetchDataItem.FLAGS);
+    }
+
+
+    /**
+     * Set the flags for a single message.
+     *
+     * @param sequenceNumber
+     *               The sequence number of target message.
+     * @param flags  The new flag settings.
+     * @param set    true if the flags should be set, false for a clear operation.
+     *
+     * @exception MessagingException
+     */
+    public synchronized Flags setFlags(int sequenceNumber, Flags flags, boolean set) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("STORE");
+        command.appendInteger(sequenceNumber);
+        // the command varies depending on whether this is a set or clear operation
+        if (set) {
+            command.appendAtom("+FLAGS");
+        }
+        else {
+            command.appendAtom("-FLAGS");
+        }
+
+        // append the flag set
+        command.appendFlags(flags);
+
+        // we want just the flag item here.
+        sendCommand(command);
+        // get the return data item, and get the flags from within it
+        IMAPFlags flagResponse = (IMAPFlags)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.FLAGS);
+        return flagResponse.flags;
+    }
+
+
+    /**
+     * Copy a range of messages to a target mailbox.
+     *
+     * @param messageSet The set of message numbers.
+     * @param target     The target mailbox name.
+     *
+     * @exception MessagingException
+     */
+    public void copyMessages(String messageSet, String target) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("COPY");
+        // the auth command initiates the handshaking.
+        command.appendAtom(messageSet);
+        // the mailbox is encoded.
+        command.appendEncodedString(target);
+        // just send this as a simple command...we don't deal with the response other than to verifiy
+        // it was ok.
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Fetch the message number for a give UID.
+     *
+     * @param uid    The target UID
+     *
+     * @return An IMAPUid object containing the mapping information.
+     */
+    public synchronized IMAPUid getSequenceNumberForUid(long uid) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("UID FETCH");
+        command.appendLong(uid);
+        command.appendAtom("(UID)");
+
+        // this situation is a little strange, so it deserves a little explanation.
+        // We need the message sequence number for this message from a UID value.
+        // we're going to send a UID FETCH command, requesting the UID value back.
+        // That seems strange, but the * nnnn FETCH response for the request will
+        // be tagged with the message sequence number.  THAT'S the information we
+        // really want, and it will be included in the IMAPUid object.
+
+        sendCommand(command);
+        // ok, now we need to search through these looking for a FETCH response with a UID element.
+        List responses = extractResponses("FETCH");
+
+        // we're looking for a fetch response with a UID data item with the UID information
+        // inside of it.
+        for (int i = 0; i < responses.size(); i++) {
+            IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
+            IMAPUid item = (IMAPUid)response.getDataItem(IMAPFetchDataItem.UID);
+            // is this the response we're looking for?  The information we
+            // need is the message number returned with the response, which is
+            // also contained in the UID item.
+            if (item != null && item.uid == uid) {
+                return item;
+            }
+            // not one meant for us, add it back to the pending queue.
+            queuePendingResponse(response);
+        }
+        // didn't find this one
+        return null;
+    }
+
+
+    /**
+     * Fetch the message numbers for a consequetive range
+     * of UIDs.
+     *
+     * @param start  The start of the range.
+     * @param end    The end of the uid range.
+     *
+     * @return A list of UID objects containing the mappings.
+     */
+    public synchronized List getSequenceNumbersForUids(long start, long end) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("UID FETCH");
+        // send the request for the range "start:end" so we can fetch all of the info
+        // at once.
+        command.appendLong(start);
+        command.append(":");
+        // not the special range marker?  Just append the
+        // number.  The LASTUID value needs to be "*" on the command.
+        if (end != UIDFolder.LASTUID) {
+            command.appendLong(end);
+        }
+        else {
+            command.append("*");
+        }
+        command.appendAtom("(UID)");
+
+        // this situation is a little strange, so it deserves a little explanation.
+        // We need the message sequence number for this message from a UID value.
+        // we're going to send a UID FETCH command, requesting the UID value back.
+        // That seems strange, but the * nnnn FETCH response for the request will
+        // be tagged with the message sequence number.  THAT'S the information we
+        // really want, and it will be included in the IMAPUid object.
+
+        sendCommand(command);
+        // ok, now we need to search through these looking for a FETCH response with a UID element.
+        List responses = extractResponses("FETCH");
+
+        List uids = new ArrayList((int)(end - start + 1));
+
+        // we're looking for a fetch response with a UID data item with the UID information
+        // inside of it.
+        for (int i = 0; i < responses.size(); i++) {
+            IMAPFetchResponse response = (IMAPFetchResponse)responses.get(i);
+            IMAPUid item = (IMAPUid)response.getDataItem(IMAPFetchDataItem.UID);
+            // is this the response we're looking for?  The information we
+            // need is the message number returned with the response, which is
+            // also contained in the UID item.
+            if (item != null) {
+                uids.add(item);
+            }
+            else {
+                // not one meant for us, add it back to the pending queue.
+                queuePendingResponse(response);
+            }
+        }
+        // return the list of uids we located.
+        return uids;
+    }
+
+
+    /**
+     * Fetch the UID value for a target message number
+     *
+     * @param sequenceNumber
+     *               The target message number.
+     *
+     * @return An IMAPUid object containing the mapping information.
+     */
+    public synchronized IMAPUid getUidForSequenceNumber(int sequenceNumber) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendInteger(sequenceNumber);
+        command.appendAtom("(UID)");
+
+        // similar to the other fetches, but without the strange bit.  We're starting
+        // with the message number in this case.
+
+        sendCommand(command);
+
+        // ok, now we need to search through these looking for a FETCH response with a UID element.
+        return (IMAPUid)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.UID);
+    }
+
+
+    /**
+     * Retrieve the user name space info from the server.
+     *
+     * @return An IMAPNamespace response item with the information.  If the server
+     *         doesn't support the namespace extension, an empty one is returned.
+     */
+    public synchronized IMAPNamespaceResponse getNamespaces() throws MessagingException {
+        // if no namespace capability, then return an empty
+        // response, which will trigger the default behavior.
+        if (!hasCapability("NAMESPACE")) {
+            return new IMAPNamespaceResponse();
+        }
+        // no arguments on this command, so just send an hope it works.
+        sendCommand("NAMESPACE");
+
+        // this should be here, since it's a required response when the
+        // command worked.  Just extract, and return.
+        return (IMAPNamespaceResponse)extractResponse("NAMESPACE");
+    }
+
+
+    /**
+     * Prefetch message information based on the request profile.  We'll return
+     * all of the fetch information to the requesting Folder, which will sort
+     * out what goes where.
+     *
+     * @param messageSet The set of message numbers we need to fetch.
+     * @param profile    The profile of the required information.
+     *
+     * @return All FETCH responses resulting from the command.
+     * @exception MessagingException
+     */
+    public synchronized List fetch(String messageSet, FetchProfile profile) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("FETCH");
+        command.appendAtom(messageSet);
+        // this is the set of items to append
+        command.appendFetchProfile(profile);
+
+        // now send the fetch command, which will likely send back a lot of "FETCH" responses.
+        // Suck all of those reponses out of the queue and send them back for processing.
+        sendCommand(command);
+        // we can have a large number of messages here, so just grab all of the fetches
+        // we get back, and let the Folder sort out who gets what.
+        return extractResponses("FETCH");
+    }
+
+
+    /**
+     * Set the ACL rights for a mailbox.  This replaces
+     * any existing ACLs defined.
+     *
+     * @param mailbox The target mailbox.
+     * @param acl     The new ACL to be used for the mailbox.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void setACLRights(String mailbox, ACL acl) throws MessagingException {
+        IMAPCommand command = new IMAPCommand("SETACL");
+        command.appendEncodedString(mailbox);
+
+        command.appendACL(acl);
+
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Add a set of ACL rights to a mailbox.
+     *
+     * @param mailbox The mailbox to alter.
+     * @param acl     The ACL to add.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void addACLRights(String mailbox, ACL acl) throws MessagingException {
+        if (!hasCapability("ACL")) {
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("SETACL");
+        command.appendEncodedString(mailbox);
+
+        command.appendACL(acl, "+");
+
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Remove an ACL from a given mailbox.
+     *
+     * @param mailbox The mailbox to alter.
+     * @param acl     The particular ACL to revoke.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void removeACLRights(String mailbox, ACL acl) throws MessagingException {
+        if (!hasCapability("ACL")) {
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("SETACL");
+        command.appendEncodedString(mailbox);
+
+        command.appendACL(acl, "-");
+
+        sendSimpleCommand(command);
+    }
+
+
+    /**
+     * Get the ACL rights assigned to a given mailbox.
+     *
+     * @param mailbox The target mailbox.
+     *
+     * @return The an array of ACL items describing the access
+     *         rights to the mailbox.
+     * @exception MessagingException
+     */
+    public synchronized ACL[] getACLRights(String mailbox) throws MessagingException {
+        if (!hasCapability("ACL")) {
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("GETACL");
+        command.appendEncodedString(mailbox);
+
+        // now send the GETACL command, which will return a single ACL untagged response.
+        sendCommand(command);
+        // there should be just a single ACL response back from this command.
+        IMAPACLResponse response = (IMAPACLResponse)extractResponse("ACL");
+        return response.acls;
+    }
+
+
+    /**
+     * Get the current user's ACL rights to a given mailbox.
+     *
+     * @param mailbox The target mailbox.
+     *
+     * @return The Rights associated with this mailbox.
+     * @exception MessagingException
+     */
+    public synchronized Rights getMyRights(String mailbox) throws MessagingException {
+        if (!hasCapability("ACL")) {
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("MYRIGHTS");
+        command.appendEncodedString(mailbox);
+
+        // now send the MYRIGHTS command, which will return a single MYRIGHTS untagged response.
+        sendCommand(command);
+        // there should be just a single MYRIGHTS response back from this command.
+        IMAPMyRightsResponse response = (IMAPMyRightsResponse)extractResponse("MYRIGHTS");
+        return response.rights;
+    }
+
+
+    /**
+     * List the ACL rights that a particular user has
+     * to a mailbox.
+     *
+     * @param mailbox The target mailbox.
+     * @param name    The user we're querying.
+     *
+     * @return An array of rights the use has to this mailbox.
+     * @exception MessagingException
+     */
+    public synchronized Rights[] listACLRights(String mailbox, String name) throws MessagingException {
+        if (!hasCapability("ACL")) {
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("LISTRIGHTS");
+        command.appendEncodedString(mailbox);
+        command.appendString(name);
+
+        // now send the GETACL command, which will return a single ACL untagged response.
+        sendCommand(command);
+        // there should be just a single ACL response back from this command.
+        IMAPListRightsResponse response = (IMAPListRightsResponse)extractResponse("LISTRIGHTS");
+        return response.rights;
+    }
+
+
+    /**
+     * Delete an ACL item for a given user name from
+     * a target mailbox.
+     *
+     * @param mailbox The mailbox we're altering.
+     * @param name    The user name.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void deleteACL(String mailbox, String name) throws MessagingException {
+        if (!hasCapability("ACL")) {
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("DELETEACL");
+        command.appendEncodedString(mailbox);
+        command.appendString(name);
+
+        // just send the command.  No response to handle.
+        sendSimpleCommand(command);
+    }
+
+    /**
+     * Fetch the quota root information for a target mailbox.
+     *
+     * @param mailbox The mailbox of interest.
+     *
+     * @return An array of quotas describing all of the quota roots
+     *         that apply to the target mailbox.
+     * @exception MessagingException
+     */
+    public synchronized Quota[] fetchQuotaRoot(String mailbox) throws MessagingException {
+        if (!hasCapability("QUOTA")) {
+            throw new MethodNotSupportedException("QUOTA not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("GETQUOTAROOT");
+        command.appendEncodedString(mailbox);
+
+        // This will return a single QUOTAROOT response, plust a series of QUOTA responses for
+        // each root names in the first response.
+        sendCommand(command);
+        // we don't really need this, but pull it from the response queue anyway.
+        extractResponse("QUOTAROOT");
+
+        // now get the real meat of the matter
+        List responses = extractResponses("QUOTA");
+
+        // now copy all of the returned quota items into the response array.
+        Quota[] quotas = new Quota[responses.size()];
+        for (int i = 0; i < quotas.length; i++) {
+            IMAPQuotaResponse q = (IMAPQuotaResponse)responses.get(i);
+            quotas[i] = q.quota;
+        }
+
+        return quotas;
+    }
+
+    /**
+     * Fetch QUOTA information from a named QUOTE root.
+     *
+     * @param root   The target root name.
+     *
+     * @return An array of Quota items associated with that root name.
+     * @exception MessagingException
+     */
+    public synchronized Quota[] fetchQuota(String root) throws MessagingException {
+        if (!hasCapability("QUOTA")) {
+            throw new MethodNotSupportedException("QUOTA not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("GETQUOTA");
+        command.appendString(root);
+
+        // This will return a single QUOTAROOT response, plust a series of QUOTA responses for
+        // each root names in the first response.
+        sendCommand(command);
+
+        // now get the real meat of the matter
+        List responses = extractResponses("QUOTA");
+
+        // now copy all of the returned quota items into the response array.
+        Quota[] quotas = new Quota[responses.size()];
+        for (int i = 0; i < quotas.length; i++) {
+            IMAPQuotaResponse q = (IMAPQuotaResponse)responses.get(i);
+            quotas[i] = q.quota;
+        }
+
+        return quotas;
+    }
+
+    /**
+     * Set a Quota item for the currently accessed
+     * userid/folder resource.
+     *
+     * @param quota  The new QUOTA information.
+     *
+     * @exception MessagingException
+     */
+    public synchronized void setQuota(Quota quota) throws MessagingException {
+        if (!hasCapability("QUOTA")) {
+            throw new MethodNotSupportedException("QUOTA not available from this IMAP server");
+        }
+        IMAPCommand command = new IMAPCommand("GETQUOTA");
+        // this gets appended as a list of resource values
+        command.appendQuota(quota);
+
+        // This will return a single QUOTAROOT response, plust a series of QUOTA responses for
+        // each root names in the first response.
+        sendCommand(command);
+        // we don't really need this, but pull it from the response queue anyway.
+        extractResponses("QUOTA");
+    }
+
+
+    /**
+     * Test if this connection has a given capability.
+     *
+     * @param capability The capability name.
+     *
+     * @return true if this capability is in the list, false for a mismatch.
+     */
+    public boolean hasCapability(String capability) {
+        if (capabilities == null) {
+            return false;
+        }
+        return capabilities.containsKey(capability);
+    }
+
+    /**
+     * Tag this connection as having been closed by the
+     * server.  This will not be returned to the
+     * connection pool.
+     */
+    public void setClosed() {
+        closed = true;
+    }
+
+    /**
+     * Test if the connnection has been forcibly closed.
+     *
+     * @return True if the server disconnected the connection.
+     */
+    public boolean isClosed() {
+        return closed;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java
new file mode 100644
index 0000000..f89619c
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java
@@ -0,0 +1,589 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.mail.MessagingException; 
+import javax.mail.Session;
+import javax.mail.Store;
+
+import javax.mail.StoreClosedException;
+
+import org.apache.geronimo.javamail.store.imap.IMAPStore; 
+import org.apache.geronimo.javamail.util.ProtocolProperties; 
+
+public class IMAPConnectionPool {
+
+    protected static final String MAIL_PORT = "port";
+    protected static final String MAIL_POOL_SIZE = "connectionpoolsize";
+    protected static final String MAIL_POOL_TIMEOUT = "connectionpooltimeout";
+    protected static final String MAIL_SEPARATE_STORE_CONNECTION = "separatestoreconnection";
+    
+    protected static final String MAIL_SASL_REALM = "sasl.realm"; 
+    protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid"; 
+
+    // 45 seconds, by default.
+    protected static final int DEFAULT_POOL_TIMEOUT = 45000;
+    protected static final String DEFAULT_MAIL_HOST = "localhost";
+    
+    protected static final int MAX_CONNECTION_RETRIES = 3; 
+    protected static final int MAX_POOL_WAIT = 500; 
+
+
+    // Our hosting Store instance
+    protected IMAPStore store;
+    // our Protocol abstraction 
+    protected ProtocolProperties props; 
+    // our list of created connections
+    protected List poolConnections = new ArrayList();
+    // our list of available connections 
+    protected List availableConnections = new ArrayList();
+    
+    // the dedicated Store connection (if we're configured that way)
+    protected IMAPConnection storeConnection = null;
+    
+    // our dedicated Store connection attribute
+    protected boolean dedicatedStoreConnection;
+    // the size of our connection pool (by default, we only keep a single connection in the pool)
+    protected int poolSize = 1;
+    // the connection timeout property
+    protected long poolTimeout;
+    // our debug flag
+    protected boolean debug;
+
+    // the target host
+    protected String host;
+    // the target server port.
+    protected int port;
+    // the username we connect with
+    protected String username;
+    // the authentication password.
+    protected String password;
+    // the SASL realm name 
+    protected String realm; 
+    // the authorization id.  With IMAP, it's possible to 
+    // log on with another's authorization. 
+    protected String authid; 
+    // Turned on when the store is closed for business. 
+    protected boolean closed = false; 
+    // the connection capabilities map
+    protected Map capabilities; 
+
+    /**
+     * Create a connection pool associated with a give IMAPStore instance.  The
+     * connection pool manages handing out connections for both the Store and
+     * Folder and Message usage.
+     * 
+     * Depending on the session properties, the Store may be given a dedicated
+     * connection, or will share connections with the Folders.  Connections may
+     * be requested from either the Store or Folders.  Messages must request
+     * their connections from their hosting Folder, and only one connection is
+     * allowed per folder.
+     * 
+     * @param store  The Store we're creating the pool for.
+     * @param props  The property bundle that defines protocol properties
+     *               that alter the connection behavior.
+     */
+    public IMAPConnectionPool(IMAPStore store, ProtocolProperties props) {
+        this.store = store;
+        this.props = props; 
+
+        // get the pool size.  By default, we just use a single connection that's 
+        // shared among Store and all of the Folders.  Since most apps that use 
+        // javamail tend to be single-threaded, this generally poses no great hardship. 
+        poolSize = props.getIntProperty(MAIL_POOL_SIZE, 1);
+        // get the timeout property.  Default is 45 seconds.
+        poolTimeout = props.getIntProperty(MAIL_POOL_TIMEOUT, DEFAULT_POOL_TIMEOUT);
+        // we can create a dedicated connection over and above the pool set that's 
+        // reserved for the Store instance to use. 
+        dedicatedStoreConnection = props.getBooleanProperty(MAIL_SEPARATE_STORE_CONNECTION, false);
+        // if we have a dedicated pool connection, we allocated that from the pool.  Add this to 
+        // the total pool size so we don't find ourselves stuck if the pool size is 1. 
+        if (dedicatedStoreConnection) {
+            poolSize++; 
+        }
+    }
+
+
+    /**
+     * Manage the initial connection to the IMAP server.  This is the first 
+     * point where we obtain the information needed to make an actual server 
+     * connection.  Like the Store protocolConnect method, we return false 
+     * if there's any sort of authentication difficulties. 
+     * 
+     * @param host     The host of the IMAP server.
+     * @param port     The IMAP server connection port.
+     * @param user     The connection user name.
+     * @param password The connection password.
+     * 
+     * @return True if we were able to connect and authenticate correctly. 
+     * @exception MessagingException
+     */
+    public synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        // NOTE:  We don't check for the username/password being null at this point.  It's possible that 
+        // the server will send back a PREAUTH response, which means we don't need to go through login 
+        // processing.  We'll need to check the capabilities response after we make the connection to decide 
+        // if logging in is necesssary. 
+        
+        // save this for subsequent connections.  All pool connections will use this info.
+        // if the port is defaulted, then see if we have something configured in the session.
+        // if not configured, we just use the default default.
+        if (port == -1) {
+            // check for a property and fall back on the default if it's not set.
+            port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
+            // it's possible that -1 might have been explicitly set, so one last check. 
+            if (port == -1) {
+                port = props.getDefaultPort(); 
+            }
+        }
+    	
+    	// Before we do anything, let's make sure that we succesfully received a host
+    	if ( host == null ) {
+    		host = DEFAULT_MAIL_HOST;
+    	}
+        
+        this.host = host;
+        this.port = port;
+        this.username = username;
+        this.password = password;
+        
+        // make sure we have the realm information 
+        realm = props.getProperty(MAIL_SASL_REALM); 
+        // get an authzid value, if we have one.  The default is to use the username.
+        authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
+
+        // go create a connection and just add it to the pool.  If there is an authenticaton error, 
+        // return the connect failure, and we may end up trying again. 
+        IMAPConnection connection = createPoolConnection(); 
+        if (connection == null) {
+            return false; 
+        }
+        // save the capabilities map from the first connection. 
+        capabilities = connection.getCapabilities(); 
+        // if we're using a dedicated store connection, remove this from the pool and
+        // reserve it for the store.
+        if (dedicatedStoreConnection)  
+        {  
+            storeConnection = connection;
+            // make sure this is hooked up to the store. 
+            connection.addResponseHandler(store); 
+        }
+        else {
+            // just put this back in the pool.  It's ready for anybody to use now. 
+            synchronized(this) {
+                availableConnections.add(connection); 
+            }
+        }
+        // we're connection, authenticated, and ready to go. 
+        return true; 
+    }
+
+    /**
+     * Creates an authenticated pool connection and adds it to
+     * the connection pool.  If there is an existing connection
+     * already in the pool, this returns without creating a new
+     * connection.
+     *
+     * @exception MessagingException
+     */
+    protected IMAPConnection createPoolConnection() throws MessagingException {
+        IMAPConnection connection = new IMAPConnection(props, this);
+        if (!connection.protocolConnect(host, port, authid, realm, username, password)) {
+            // we only add live connections to the pool.  Sever the connections and 
+            // allow it to go free. 
+            connection.closeServerConnection(); 
+            return null; 
+        }
+        
+        // add this to the master list.  We do NOT add this to the 
+        // available queue because we're handing this out. 
+        synchronized(this) {
+            // uh oh, we closed up shop while we were doing this...clean it up a 
+            // get out of here 
+            if (closed) {
+                connection.close(); 
+                throw new StoreClosedException(store, "No Store connections available"); 
+            }
+            
+            poolConnections.add(connection);
+        }
+        // return that connection 
+        return connection; 
+    }
+
+
+    /**
+     * Get a connection from the pool.  We try to retrieve a live
+     * connection, but we test the connection's liveness before
+     * returning one.  If we don't have a viable connection in
+     * the pool, we'll create a new one.  The returned connection
+     * will be in the authenticated state already.
+     *
+     * @return An IMAPConnection object that is connected to the server.
+     */
+    protected IMAPConnection getConnection() throws MessagingException {
+        int retryCount = 0; 
+        
+        // To keep us from falling into a futile failure loop, we'll only allow 
+        // a set number of connection failures. 
+        while (retryCount < MAX_CONNECTION_RETRIES) {
+            // first try for an already created one.  If this returns 
+            // null, then we'll probably have to make a new one. 
+            IMAPConnection connection = getPoolConnection(); 
+            // cool, we got one, the hard part is done.  
+            if (connection != null) {
+                return connection; 
+            }
+            // ok, create a new one.  This *should* work, but the server might 
+            // have gone down, or other problem may occur. If we have a problem, 
+            // retry the entire process...but only for a bit.  No sense 
+            // being stubborn about it. 
+            connection = createPoolConnection(); 
+            if (connection != null) {
+                return connection; 
+            }
+            // step the retry count 
+            retryCount++; 
+        }
+        
+        throw new MessagingException("Unable to get connection to IMAP server"); 
+    }
+    
+    /**
+     * Obtain a connection from the existing connection pool.  If none are 
+     * available, and we've reached the connection pool limit, we'll wait for 
+     * some other thread to return one.  It generally doesn't take too long, as 
+     * they're usually only held for the time required to execute a single 
+     * command.   If we're not at the pool limit, return null, which will signal 
+     * the caller to go ahead and create a new connection outside of the 
+     * lock. 
+     * 
+     * @return Either an active connection instance, or null if the caller should go 
+     *         ahead and try to create a new connection.
+     * @exception MessagingException
+     */
+    protected synchronized IMAPConnection getPoolConnection() throws MessagingException {
+        // if the pool is closed, we can't process this 
+        if (closed) {
+            throw new StoreClosedException(store, "No Store connections available"); 
+        }
+        
+        // we'll retry this a few times if the connection pool is full, but 
+        // after that, we'll just create a new connection. 
+        for (int i = 0; i < MAX_CONNECTION_RETRIES; i++) {
+            Iterator it = availableConnections.iterator(); 
+            while (it.hasNext()) {
+                IMAPConnection connection = (IMAPConnection)it.next(); 
+                // live or dead, we're going to remove this from the 
+                // available list. 
+                it.remove(); 
+                if (connection.isAlive(poolTimeout)) {
+                    // return the connection to the requestor 
+                    return connection; 
+                }
+                else {
+                    // remove this from the pool...it's toast. 
+                    poolConnections.remove(connection); 
+                    // make sure this cleans up after itself. 
+                    connection.closeServerConnection(); 
+                }
+            }
+
+            // we've not found something usable in the pool.  Now see if 
+            // we're allowed to add another connection, or must just wait for 
+            // someone else to return one. 
+
+            if (poolConnections.size() >= poolSize) {
+                // check to see if we've been told to shutdown before waiting
+                if (closed) {
+                    throw new StoreClosedException(store, "No Store connections available"); 
+                }
+                // we need to wait for somebody to return a connection 
+                // once woken up, we'll spin around and try to snag one from 
+                // the pool again.
+                try {
+                    wait(MAX_POOL_WAIT);
+                } catch (InterruptedException e) {
+                }
+                
+                // check to see if we've been told to shutdown while we waited
+                if (closed) {
+                    throw new StoreClosedException(store, "No Store connections available"); 
+                }
+            }
+            else {
+                // exit out and create a new connection.  Since 
+                // we're going to be outside the synchronized block, it's possible 
+                // we'll go over our pool limit.  We'll take care of that when connections start 
+                // getting returned. 
+                return null; 
+            }
+        }
+        // we've hit the maximum number of retries...just create a new connection. 
+        return null; 
+    }
+    
+    /**
+     * Return a connection to the connection pool.
+     * 
+     * @param connection The connection getting returned.
+     * 
+     * @exception MessagingException
+     */
+    protected void returnPoolConnection(IMAPConnection connection) throws MessagingException
+    {
+        synchronized(this) {
+            // If we're still within the bounds of our connection pool, 
+            // just add this to the active list and send out a notification 
+            // in case somebody else is waiting for the connection. 
+            if (availableConnections.size() < poolSize) {
+                availableConnections.add(connection); 
+                notify(); 
+                return; 
+            }
+            // remove this from the connection pool...we have too many. 
+            poolConnections.remove(connection); 
+        }
+        // the additional cleanup occurs outside the synchronized block 
+        connection.close(); 
+    }
+    
+    /**
+     * Release a closed connection.
+     * 
+     * @param connection The connection getting released.
+     * 
+     * @exception MessagingException
+     */
+    protected void releasePoolConnection(IMAPConnection connection) throws MessagingException
+    {
+        synchronized(this) {
+            // remove this from the connection pool...it's no longer usable. 
+            poolConnections.remove(connection); 
+        }
+        // the additional cleanup occurs outside the synchronized block 
+        connection.close(); 
+    }
+
+
+    /**
+     * Get a connection for the Store.  This will be either a
+     * dedicated connection object, or one from the pool, depending
+     * on the mail.imap.separatestoreconnection property.
+     *
+     * @return An authenticated connection object.
+     */
+    public synchronized IMAPConnection getStoreConnection() throws MessagingException {  
+        if (closed) {
+            throw new StoreClosedException(store, "No Store connections available"); 
+        }
+        // if we have a dedicated connection created, return it.
+        if (storeConnection != null) {
+            return storeConnection;
+        }
+        else {
+            IMAPConnection connection = getConnection();
+            // add the store as a response handler while it has it. 
+            connection.addResponseHandler(store); 
+            return connection; 
+        }
+    }
+
+
+    /**
+     * Return the Store connection to the connection pool.  If we have a dedicated
+     * store connection, this is simple.  Otherwise, the connection goes back 
+     * into the general connection pool.
+     * 
+     * @param connection The connection getting returned.
+     */
+    public synchronized void releaseStoreConnection(IMAPConnection connection) throws MessagingException {
+        // have a server disconnect situation?
+        if (connection.isClosed()) {
+            // we no longer have a dedicated store connection.  
+            // we need to return to the pool from now on. 
+            storeConnection = null; 
+            // throw this away. 
+            releasePoolConnection(connection); 
+        }
+        else {
+            // if we have a dedicated connection, nothing to do really.  Otherwise, 
+            // return this connection to the pool. 
+            if (storeConnection == null) {
+                // unhook the store from the connection. 
+                connection.removeResponseHandler(store); 
+                returnPoolConnection(connection); 
+            }
+        }
+    }
+
+
+    /**
+     * Get a connection for Folder.  
+     *
+     * @return An authenticated connection object.
+     */
+    public IMAPConnection getFolderConnection() throws MessagingException {  
+        // just get a connection from the pool 
+        return getConnection(); 
+    }
+
+
+    /**
+     * Return a Folder connection to the connection pool.  
+     * 
+     * @param connection The connection getting returned.
+     */
+    public void releaseFolderConnection(IMAPConnection connection) throws MessagingException {
+        // potentially, the server may have decided to shut us down.  
+        // In that case, the connection is no longer usable, so we need 
+        // to remove it from the list of available ones. 
+        if (!connection.isClosed()) {
+            // back into the pool with yee, matey....arrggghhh
+            returnPoolConnection(connection); 
+        }
+        else {
+            // can't return this one to the pool.  It's been stomped on 
+            releasePoolConnection(connection); 
+        }
+    }
+    
+    
+    /**
+     * Close the entire connection pool. 
+     * 
+     * @exception MessagingException
+     */
+    public synchronized void close() throws MessagingException {
+        // first close each of the connections.  This also closes the 
+        // store connection. 
+        for (int i = 0; i < poolConnections.size(); i++) {
+            IMAPConnection connection = (IMAPConnection)poolConnections.get(i);
+            connection.close(); 
+        }
+        // clear the pool 
+        poolConnections.clear(); 
+        availableConnections.clear(); 
+        storeConnection = null; 
+        // turn out the lights, hang the closed sign on the wall. 
+        closed = true; 
+    }
+
+
+    /**
+     * Flush any connections from the pool that have not been used
+     * for at least the connection pool timeout interval.
+     */
+    protected synchronized void closeStaleConnections() {
+        Iterator i = poolConnections.iterator();
+
+        while (i.hasNext()) {
+            IMAPConnection connection = (IMAPConnection)i.next();
+            // if this connection is a stale one, remove it from the pool
+            // and close it out.
+            if (connection.isStale(poolTimeout)) {
+                i.remove();
+                try {
+                    connection.close();
+                } catch (MessagingException e) {
+                    // ignored.  we're just closing connections that are probably timed out anyway, so errors
+                    // on those shouldn't have an effect on the real operation we're dealing with.
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Return a connection back to the connection pool.  If we're not
+     * over our limit, the connection is kept around.  Otherwise, it's
+     * given a nice burial.
+     *
+     * @param connection The returned connection.
+     */
+    protected synchronized void releaseConnection(IMAPConnection connection) {
+        // before adding this to the pool, close any stale connections we may
+        // have.  The connection we're adding is quite likely to be a fresh one,
+        // so we should cache that one if we can.
+        closeStaleConnections();
+        // still over the limit?
+        if (poolConnections.size() + 1 > poolSize) {
+            try {
+                // close this out and forget we ever saw it.
+                connection.close();
+            } catch (MessagingException e) {
+                // ignore....this is a non-critical problem if this fails now.
+            }
+        }
+        else {
+            // listen to alerts on this connection, and put it back in the pool.
+            poolConnections.add(connection);
+        }
+    }
+
+    /**
+     * Cleanup time.  Sever and cleanup all of the pool connection
+     * objects, including the special Store connection, if we have one.
+     */
+    protected synchronized void freeAllConnections() {
+        for (int i = 0; i < poolConnections.size(); i++) {
+            IMAPConnection connection = (IMAPConnection)poolConnections.get(i);
+            try {
+                // close this out and forget we ever saw it.
+                connection.close();
+            } catch (MessagingException e) {
+                // ignore....this is a non-critical problem if this fails now.
+            }
+        }
+        // everybody, out of the pool!
+        poolConnections.clear();
+
+        // don't forget the special store connection, if we have one.
+        if (storeConnection != null) {
+            try {
+                // close this out and forget we ever saw it.
+                storeConnection.close();
+            } catch (MessagingException e) {
+                // ignore....this is a non-critical problem if this fails now.
+            }
+            storeConnection = null;
+        }
+    }
+    
+    
+    /**
+     * Test if this connection has a given capability. 
+     * 
+     * @param capability The capability name.
+     * 
+     * @return true if this capability is in the list, false for a mismatch. 
+     */
+    public boolean hasCapability(String capability) {
+        if (capabilities == null) {
+            return false; 
+        }
+        return capabilities.containsKey(capability); 
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java
new file mode 100644
index 0000000..32ea079
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java
@@ -0,0 +1,42 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a continuation response from an IMAP server. 
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPContinuationResponse extends IMAPTaggedResponse {
+    /**
+     * Create a continuation object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    protected IMAPContinuationResponse(byte [] response) {
+        super(response); 
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java
new file mode 100644
index 0000000..c2e947e
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java
@@ -0,0 +1,72 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Formats ths date as specified by
+ * draft-ietf-drums-msg-fmt-08 dated January 26, 2000
+ * which supercedes RFC822.
+ * <p/>
+ * <p/>
+ * The format used is <code>EEE, d MMM yyyy HH:mm:ss Z</code> and
+ * locale is always US-ASCII.
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPDateFormat extends SimpleDateFormat {
+    public IMAPDateFormat() {
+        super("dd-MMM-yyyy HH:mm:ss Z", Locale.US);
+    }
+    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) {
+        StringBuffer result = super.format(date, buffer, position);
+        // The RFC 2060 requires that the day in the date be formatted with either 2 digits
+        // or one digit.  Our format specifies 2 digits, which pads with leading
+        // zeros.  We need to check for this and whack it if it's there
+        if (result.charAt(0) == '0') {
+            result.deleteCharAt(0); 
+        }
+        return result;
+    }
+
+    /**
+     * The calendar cannot be set
+     * @param calendar
+     * @throws UnsupportedOperationException
+     */
+    public void setCalendar(Calendar calendar) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The format cannot be set
+     * @param format
+     * @throws UnsupportedOperationException
+     */
+    public void setNumberFormat(NumberFormat format) {
+        throw new UnsupportedOperationException();
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java
new file mode 100644
index 0000000..37b8a3f
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java
@@ -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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.Date;
+
+import javax.mail.MessagingException;
+
+import javax.mail.internet.InternetAddress;
+
+
+public class IMAPEnvelope extends IMAPFetchDataItem {
+    // the following are various fields from the FETCH ENVELOPE structure.  These
+    // should be self-explanitory.
+    public Date date;
+    public String subject;
+    public InternetAddress[] from;
+    public InternetAddress[] sender;
+    public InternetAddress[] replyTo;
+    public InternetAddress[] to;
+    public InternetAddress[] cc;
+    public InternetAddress[] bcc;
+
+    public String inReplyTo;
+    public String messageID;
+
+
+    /**
+     * Parse an IMAP FETCH ENVELOPE response into the component pieces.
+     * 
+     * @param source The tokenizer for the response we're processing.
+     */
+    public IMAPEnvelope(IMAPResponseTokenizer source) throws MessagingException {
+        super(ENVELOPE);
+
+        // these should all be a parenthetical list 
+        source.checkLeftParen(); 
+        // the following fields are all positional
+        // The envelope date is defined in the spec as being an "nstring" value, which 
+        // means it is either a string value or NIL.  
+        date = source.readDateOrNil(); 
+        subject = source.readStringOrNil();
+        from = source.readAddressList();
+        sender = source.readAddressList();
+        replyTo = source.readAddressList();
+        to = source.readAddressList();
+        cc = source.readAddressList();
+        bcc = source.readAddressList();
+        inReplyTo = source.readStringOrNil();
+        messageID = source.readStringOrNil();
+
+        // make sure we have a correct close on the field.
+        source.checkRightParen();
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java
new file mode 100644
index 0000000..ec17870
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java
@@ -0,0 +1,76 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+public class IMAPFetchBodyPart extends IMAPFetchDataItem {
+    // the parse body section information. 
+    protected IMAPBodySection section; 
+
+    /**
+     * Construct a base BODY section subpiece.
+     * 
+     * @param type    The fundamental type of the body section.  This will be either BODY, TEXT,
+     *                or HEADER, depending on the subclass.
+     * @param section The section information.  This will contain the section numbering information,
+     *                the section name, and and substring information if this was a partial fetch
+     *                request.
+     */
+    public IMAPFetchBodyPart(int type, IMAPBodySection section) {
+        super(type); 
+        this.section = section; 
+    }
+    
+    /**
+     * Get the part number information associated with this request.
+     * 
+     * @return The string form of the part number. 
+     */
+    public String getPartNumber() {
+        return section.partNumber;
+    }
+    
+    /**
+     * Get the section type information.  This is the qualifier that appears
+     * within the "[]" of the body sections.
+     * 
+     * @return The numeric identifier for the type from the IMAPBodySection.
+     */
+    public int getSectionType() {
+        return section.section; 
+    }
+    
+    /**
+     * Get the substring start location.  
+     * 
+     * @return The start location for the substring.  Returns -1 if this is not a partial 
+     *         fetch.
+     */
+    public int getSubstringStart() {
+        return section.start; 
+    }
+    
+    /**
+     * Returns the length of the substring section.  
+     * 
+     * @return The length of the substring section.  Returns -1 if this was not a partial 
+     *         fetch.
+     */
+    public int getSubstringLength() {
+        return section.length; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java
new file mode 100644
index 0000000..6d15af3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java
@@ -0,0 +1,61 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.internet.MailDateFormat;
+
+public class IMAPFetchDataItem {
+    public static final int FETCH = 0;
+    public static final int ENVELOPE = 1;
+    public static final int BODY = 2;
+    public static final int BODYSTRUCTURE = 3;
+    public static final int INTERNALDATE = 4;
+    public static final int SIZE = 5;
+    public static final int UID = 6;
+    public static final int TEXT = 7;
+    public static final int HEADER = 8;
+    public static final int FLAGS = 9;
+
+    // the type of the FETCH response item.
+    protected int type;
+
+    public IMAPFetchDataItem(int type) {
+        this.type = type;
+    }
+
+    /**
+     * Get the type of the FetchResponse.
+     *
+     * @return The type indicator.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Test if this fetch response is of the correct type.
+     *
+     * @param t      The type to test against.
+     *
+     * @return True if the Fetch response contains the requested type information.
+     */
+    public boolean isType(int t) {
+        return type == t;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java
new file mode 100644
index 0000000..c556665
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java
@@ -0,0 +1,161 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a composite FETCH response from an IMAP server.  The
+ * response may have information about multiple message dataItems.
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPFetchResponse extends IMAPUntaggedResponse {
+    // parsed sections within the FETCH response structure 
+    protected List dataItems = new ArrayList();
+    // the message number to which this applies 
+    public int sequenceNumber; 
+
+    public IMAPFetchResponse(int sequenceNumber, byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("FETCH", data);
+        
+        this.sequenceNumber = sequenceNumber; 
+
+        // fetch responses are a list, even if there is just a single member.
+        source.checkLeftParen();
+
+        // loop until we find the list end.
+        while (source.notListEnd()) {
+            // the response names are coded as ATOMS.  The BODY one's use a special 
+            // syntax, so we need to use the expanded delimiter set to pull this out. 
+            String itemName = source.readAtom(true).toUpperCase();
+
+            if (itemName.equals("ENVELOPE")) {
+                dataItems.add(new IMAPEnvelope(source));
+            }
+            else if (itemName.equals("BODYSTRUCTURE")) {
+                dataItems.add(new IMAPBodyStructure(source));
+            }
+            else if (itemName.equals("FLAGS")) {
+                dataItems.add(new IMAPFlags(source));
+            }
+            else if (itemName.equals("INTERNALDATE")) {
+                dataItems.add(new IMAPInternalDate(source));
+            }
+            else if (itemName.equals("UID")) {
+                dataItems.add(new IMAPUid(sequenceNumber, source));
+            }
+            else if (itemName.equals("RFC822")) {
+                // all of the RFC822 items are of form 
+                // "RFC822.name".  We used the expanded parse above because 
+                // the BODY names include some complicated bits.  If we got one 
+                // of the RFC822 sections, then parse the rest of the name using 
+                // the old rules, which will pull in the rest of the name from the period. 
+                itemName = source.readAtom(false).toUpperCase();
+                if (itemName.equals(".SIZE")) {
+                    dataItems.add(new IMAPMessageSize(source));
+                }
+                else if (itemName.equals(".HEADER")) {
+                    dataItems.add(new IMAPInternetHeader(source.readByteArray()));
+                }
+                else if (itemName.equals(".TEXT")) {
+                    dataItems.add(new IMAPMessageText(source.readByteArray()));
+                }
+            }
+            // this is just the body alone. Specific body segments 
+            // have a more complex naming structure.  Believe it or  
+            // not, 
+            else if (itemName.equals("BODY")) {
+                // time to go parse out the section information from the 
+                // name.  
+                IMAPBodySection section = new IMAPBodySection(source); 
+                
+                switch (section.section) {
+                    case IMAPBodySection.BODY:
+                        // a "full body cast".  Just grab the binary data 
+                        dataItems.add(new IMAPBody(section, source.readByteArray())); 
+                        break; 
+                        
+                    case IMAPBodySection.HEADERS:
+                    case IMAPBodySection.HEADERSUBSET:
+                    case IMAPBodySection.MIME:
+                        // these 3 are all variations of a header request
+                        dataItems.add(new IMAPInternetHeader(section, source.readByteArray())); 
+                        break; 
+                        
+                    case IMAPBodySection.TEXT:
+                        // just the text portion of the body 
+                        // a "full body cast".  Just grab the binary data 
+                        dataItems.add(new IMAPMessageText(section, source.readByteArray())); 
+                        break; 
+                }
+            }
+        }
+        // swallow the terminating right paren
+        source.checkRightParen(); 
+    }
+    
+    /**
+     * Retrieve the sequence number for the FETCH item. 
+     * 
+     * @return The message sequence number this FETCH applies to. 
+     */
+    public int getSequenceNumber() {
+        return sequenceNumber; 
+    }
+
+    /**
+     * Get the section count.
+     *
+     * @return The number of sections in the response.
+     */
+    public int getCount() {
+        return dataItems.size();
+    }
+
+    /**
+     * Get the complete set of response dataItems.
+     *
+     * @return The List of IMAPFetchResponse values.
+     */
+    public List getDataItems() {
+        return dataItems;
+    }
+
+
+    /**
+     * Fetch a particular response type from the response dataItems.
+     *
+     * @param type   The target FETCH type.
+     *
+     * @return The first IMAPFetchDataItem item that matches the response type.
+     */
+    public IMAPFetchDataItem getDataItem(int type) {
+        for (int i = 0; i < dataItems.size(); i ++) {
+            IMAPFetchDataItem item = (IMAPFetchDataItem)dataItems.get(i);
+            if (item.isType(type)) {
+                return item;
+            }
+        }
+        return null;
+    }
+    
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java
new file mode 100644
index 0000000..21f025a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java
@@ -0,0 +1,40 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+import javax.mail.Flags;
+
+
+/**
+ * A fetched FLAGS value returned on a FETCH response.
+ */
+public class IMAPFlags extends IMAPFetchDataItem {
+
+    public Flags flags;
+
+    public IMAPFlags(IMAPResponseTokenizer source) throws MessagingException {
+        super(FLAGS);
+
+        // parse the list of flag values and merge each one into the flag set
+        flags = source.readFlagList(); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java
new file mode 100644
index 0000000..ce55057
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java
@@ -0,0 +1,48 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+import javax.mail.Flags;
+
+import java.util.List;
+
+/**
+ * A parsed FLAGS untagged response.
+ */
+public class IMAPFlagsResponse extends IMAPUntaggedResponse {
+
+    protected Flags flags = new Flags();
+
+    public IMAPFlagsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("FLAGS", data);
+        
+        // read the flags from the response tokenizer. 
+        flags = source.readFlagList(); 
+    }
+
+    /**
+     * Get the parsed flags value.
+     *
+     * @return The accumulated flags setting.
+     */
+    public Flags getFlags() {
+        return flags;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java
new file mode 100644
index 0000000..ce0e088
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java
@@ -0,0 +1,45 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.Date;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.util.ResponseFormatException; 
+
+public class IMAPInternalDate extends IMAPFetchDataItem {
+    // the parsed date.
+    protected Date date;
+
+    public IMAPInternalDate(IMAPResponseTokenizer source) throws MessagingException {
+        super(INTERNALDATE);
+        // read the date from the stream 
+        date = source.readDate(); 
+    }
+
+    /**
+     * Retrieved the parsed internal date object.
+     *
+     * @return The parsed Date object.
+     */
+    public Date getDate() {
+        return date;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java
new file mode 100644
index 0000000..09fde92
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java
@@ -0,0 +1,66 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayInputStream;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetHeaders; 
+
+public class IMAPInternetHeader extends IMAPFetchBodyPart {
+    // the parsed headers
+    public InternetHeaders headers; 
+    
+    /**
+     * Construct a top-level HEADER data item. 
+     * 
+     * @param data   The data for the InternetHeaders.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPInternetHeader(byte[] data) throws MessagingException {
+        this(new IMAPBodySection(IMAPBodySection.HEADERS), data);
+    }
+    
+
+    /**
+     * Construct a HEADER request data item.
+     * 
+     * @param section  The Section identifier information.
+     * @param data     The raw data for the internet headers.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPInternetHeader(IMAPBodySection section, byte[] data) throws MessagingException {
+        super(HEADER, section);
+        
+        // and convert these into real headers 
+        ByteArrayInputStream in = new ByteArrayInputStream(data); 
+        headers = new InternetHeaders(in); 
+    }
+    
+    /**
+     * Test if this is a complete header fetch, or just a partial list fetch.
+     * 
+     * @return 
+     */
+    public boolean isComplete() {
+        return section.section == IMAPBodySection.HEADERS;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java
new file mode 100644
index 0000000..9a7befd
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java
@@ -0,0 +1,92 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a list response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+
+public class IMAPListResponse extends IMAPUntaggedResponse {
+    // parsed flag responses
+    public boolean noinferiors = false;
+    public boolean noselect = false;
+    public boolean marked = false;
+    public boolean unmarked = false;
+
+    // the name separator character
+    public char separator;
+    // the mail box name
+    public String mailboxName;
+    // this is for support of the get attributes command
+    public String[] attributes;
+
+    /**
+     * Construct a LIST response item.  This can be either 
+     * a response from a LIST command or an LSUB command, 
+     * and will be tagged accordingly.
+     * 
+     * @param type   The type of resonse (LIST or LSUB).
+     * @param data   The raw response data.
+     * @param source The tokenizer source.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPListResponse(String type, byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super(type, data); 
+
+        // parse the list of flag values
+        List flags = source.readSystemNameList(); 
+        
+        // copy this into the attributes array. 
+        attributes = new String[flags.size()]; 
+        attributes = (String[])flags.toArray(attributes); 
+
+        for (int i = 0; i < flags.size(); i++) {
+            String flag = ((String)flags.get(i));
+
+            if (flag.equalsIgnoreCase("\\Marked")) {
+                marked = true;
+            }
+            else if (flag.equalsIgnoreCase("\\Unmarked")) {
+                unmarked = true;
+            }
+            else if (flag.equalsIgnoreCase("\\Noselect")) {
+                noselect = true;
+            }
+            else if (flag.equalsIgnoreCase("\\Noinferiors")) {
+                noinferiors = true;
+            }
+        }
+
+        // set a default sep value 
+        separator = '\0';    
+        // get the separator and name tokens
+        String separatorString = source.readQuotedStringOrNil();
+        if (separatorString != null && separatorString.length() == 1) {
+            separator = separatorString.charAt(0); 
+        }
+        mailboxName = source.readEncodedString();
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java
new file mode 100644
index 0000000..27fb4d7
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java
@@ -0,0 +1,51 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException; 
+
+import org.apache.geronimo.javamail.store.imap.Rights; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPListRightsResponse extends IMAPUntaggedResponse {
+    public String mailbox; 
+    public String name; 
+    public Rights[] rights; 
+    
+    public IMAPListRightsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("LISTRIGHTS",  data); 
+        
+        mailbox = source.readEncodedString();
+        name = source.readString(); 
+        List acls = new ArrayList(); 
+        
+        while (source.hasMore()) {
+            acls.add(new Rights(source.readString())); 
+        }
+        
+        rights = new Rights[acls.size()]; 
+        acls.toArray(rights); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java
new file mode 100644
index 0000000..d5a9827
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java
@@ -0,0 +1,37 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+/**
+ * Util class to represent a status response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+
+public class IMAPMailboxResponse {
+    // count/message number parameter from the response.
+    public int count;
+    // the name of the status code
+    public String name;
+
+    public IMAPMailboxResponse(int count, String name) {
+        this.count = count;
+        this.name = name;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java
new file mode 100644
index 0000000..bf1b712
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java
@@ -0,0 +1,188 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
+
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPMailboxStatus {
+    // the set of available flag values for this mailbox
+    public Flags availableFlags = null;
+    // the permanent flags for this mailbox.
+    public Flags permanentFlags = null;
+    // the open mode flags
+    public int mode = Folder.READ_WRITE;
+
+    // number of messages in the box
+    public int messages = -1;
+    // the number of newly added messages
+    public int recentMessages = -1;
+    // the number of unseen messages
+    public int unseenMessages = -1;
+
+    // the next UID for this mailbox
+    public long uidNext = -1L;
+    // the UID validity item
+    public long uidValidity = -1L;
+
+    public IMAPMailboxStatus() {
+    }
+
+
+    /**
+     * Merge information from a server status message.  These
+     * messages are in the form "* NAME args".  We only handle
+     * STATUS and FLAGS messages here.
+     *
+     * @param source The parsed status message.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPStatusResponse source) throws MessagingException {
+        // update any of the values that have changed since the last. 
+        if (source.messages != -1) {
+            messages = source.messages; 
+        }
+        if (source.uidNext != -1L) {
+            uidNext = source.uidNext; 
+        }
+        if (source.uidValidity != -1L) {
+            uidValidity = source.uidValidity; 
+        }
+        if (source.recentMessages != -1) {
+            recentMessages = source.recentMessages; 
+        }
+        if (source.unseenMessages != -1) {
+            unseenMessages = source.unseenMessages; 
+        }
+    }
+    
+    /**
+     * Merge in the FLAGS response from an EXAMINE or 
+     * SELECT mailbox command.
+     * 
+     * @param response The returned FLAGS item.
+     * 
+     * @exception MessagingException
+     */
+    public void mergeFlags(IMAPFlagsResponse response) throws MessagingException {
+        if (response != null) {
+            availableFlags = response.getFlags(); 
+        }
+    }
+    
+    
+    public void mergeSizeResponses(List responses) throws MessagingException  
+      {  
+        for (int i = 0; i < responses.size(); i++) {
+            mergeStatus((IMAPSizeResponse)responses.get(i)); 
+        }
+    }
+    
+    
+    public void mergeOkResponses(List responses) throws MessagingException {
+        for (int i = 0; i < responses.size(); i++) {
+            mergeStatus((IMAPOkResponse)responses.get(i)); 
+        }
+    }
+
+    
+    /**
+     * Gather mailbox status information from mailbox status
+     * messages.  These messages come in as untagged messages in the
+     * form "* nnn NAME".
+     *
+     * @param source The parse message information.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPSizeResponse source) throws MessagingException {
+        if (source != null) {
+            String name = source.getKeyword(); 
+
+            // untagged exists response
+            if (source.isKeyword("EXISTS")) {
+                messages = source.getSize();
+            }
+            // untagged resent response
+            else if (source.isKeyword("RECENT")) {
+                recentMessages = source.getSize();
+            }
+        }
+    }
+
+    
+
+    
+    /**
+     * Gather mailbox status information from mailbox status
+     * messages.  These messages come in as untagged messages in the
+     * form "* OK [NAME args]".
+     *
+     * @param source The parse message information.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPOkResponse source) throws MessagingException {
+        if (source != null) {
+            String name = source.getKeyword(); 
+
+            // untagged UIDVALIDITY response 
+            if (source.isKeyword("UIDVALIDITY")) {
+                List arguments = source.getStatus(); 
+                uidValidity = ((Token)arguments.get(0)).getLong(); 
+            }
+            // untagged UIDNEXT response 
+            if (source.isKeyword("UIDNEXT")) {
+                List arguments = source.getStatus(); 
+                uidNext = ((Token)arguments.get(0)).getLong(); 
+            }
+            // untagged unseen response
+            else if (source.isKeyword("UNSEEN")) {
+                List arguments = source.getStatus(); 
+                uidValidity = ((Token)arguments.get(0)).getInteger(); 
+            }
+        }
+    }
+
+    
+    /**
+     * Gather mailbox status information from mailbox status
+     * messages.  These messages come in as untagged messages in the
+     * form "* OK [NAME args]".
+     *
+     * @param source The parse message information.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPPermanentFlagsResponse source) throws MessagingException {
+        if (source != null) {
+            // this is already parsed.          
+            permanentFlags = source.flags; 
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java
new file mode 100644
index 0000000..5d3cf81
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java
@@ -0,0 +1,33 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPMessageSize extends IMAPFetchDataItem {
+    // the size information 
+    public int size;         
+
+    public IMAPMessageSize(IMAPResponseTokenizer source) throws MessagingException {
+        super(SIZE);
+
+        // the size is just a single integer 
+        size = source.readInteger();  
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java
new file mode 100644
index 0000000..f72bdb0
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java
@@ -0,0 +1,52 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPMessageText extends IMAPFetchBodyPart {
+    // the header data
+    protected byte[] data;
+
+    /**
+     * Construct a top-level TEXT data item. 
+     * 
+     * @param data   The data for the message text.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPMessageText(byte[] data) throws MessagingException {
+        this(new IMAPBodySection(IMAPBodySection.TEXT), data);
+    }
+    
+    
+    public IMAPMessageText(IMAPBodySection section, byte[] data) throws MessagingException {
+        super(TEXT, section);
+        this.data = data; 
+    }
+    
+    /**
+     * Retrieved the header data.
+     *
+     * @return The header data.
+     */
+    public byte[] getContent() {
+        return data;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java
new file mode 100644
index 0000000..fdb3209
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java
@@ -0,0 +1,38 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.Rights;
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPMyRightsResponse extends IMAPUntaggedResponse {
+    public String mailbox; 
+    public Rights rights; 
+    
+    public IMAPMyRightsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("MYRIGHTS", data); 
+        
+        mailbox = source.readEncodedString();
+        rights = new Rights(source.readString());
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java
new file mode 100644
index 0000000..603837a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java
@@ -0,0 +1,49 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a NAMESPACE response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+
+public class IMAPNamespace {
+    // the namespace prefix 
+    public String prefix; 
+    // the namespace hierarchy delimiter
+    public char separator = '\0'; 
+    
+    public IMAPNamespace(IMAPResponseTokenizer source) throws MessagingException {
+        source.checkLeftParen(); 
+        // read the two that make up the response and ...
+        prefix = source.readString(); 
+        String delim = source.readString(); 
+        // if the delimiter is not a null string, grab the first character. 
+        if (delim.length() != 0) {
+            separator = delim.charAt(0); 
+        }
+        source.checkRightParen(); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java
new file mode 100644
index 0000000..866b6e6
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java
@@ -0,0 +1,98 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+import org.apache.geronimo.javamail.util.ResponseFormatException; 
+
+/**
+ * Util class to represent a NAMESPACE response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+
+public class IMAPNamespaceResponse extends IMAPUntaggedResponse {
+    // the personal namespaces defined 
+    public List personalNamespaces; 
+    // the other use name spaces this user has access to. 
+    public List otherUserNamespaces; 
+    // the list of shared namespaces 
+    public List sharedNamespaces; 
+    
+    // construct a default IMAPNamespace response for return when the server doesn't support this. 
+    public IMAPNamespaceResponse() 
+    {
+        super("NAMESPACE", null); 
+        // fill in default lists to simplify processing 
+        personalNamespaces = Collections.EMPTY_LIST; 
+        otherUserNamespaces = Collections.EMPTY_LIST; 
+        sharedNamespaces = Collections.EMPTY_LIST; 
+    }
+
+    /**
+     * Construct a LIST response item.  This can be either 
+     * a response from a LIST command or an LSUB command, 
+     * and will be tagged accordingly.
+     * 
+     * @param type   The type of resonse (LIST or LSUB).
+     * @param data   The raw response data.
+     * @param source The tokenizer source.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPNamespaceResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("NAMESPACE", data); 
+        // the namespace response is a set of 3 items, which will be either NIL or a "list of lists".  
+        // if the item exists, then there will be a set of list parens, with 1 or more subitems inside. 
+        // Each of the subitems will consist of a namespace prefix and the hierarchy delimiter for that 
+        // particular namespace. 
+        personalNamespaces = parseNamespace(source); 
+        otherUserNamespaces = parseNamespace(source); 
+        sharedNamespaces = parseNamespace(source); 
+    }
+    
+    private List parseNamespace(IMAPResponseTokenizer source) throws MessagingException {
+        Token token = source.next(true); 
+        // is this token the NIL token?
+        if (token.getType() == Token.NIL) {
+            // no items at this position. 
+            return null; 
+        }
+        if (token.getType() != '(') {
+            throw new ResponseFormatException("Missing '(' in response");
+        }
+        
+        // ok, we're processing a namespace list.  Create a list and populate it with IMAPNamespace 
+        // items. 
+        
+        List namespaces = new ArrayList(); 
+        
+        while (source.notListEnd()) {
+            namespaces.add(new IMAPNamespace(source)); 
+        }
+        // this should always pass, since it terminated the loop 
+        source.checkRightParen(); 
+        return namespaces; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java
new file mode 100644
index 0000000..9554ea8
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java
@@ -0,0 +1,78 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPOkResponse extends IMAPUntaggedResponse {
+    // the response status value 
+    protected List status; 
+    // any message following the response 
+    protected String message; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPOkResponse(String keyword, List status, String message, byte [] response) {
+        super(keyword, response); 
+        this.status = status; 
+        this.message = message; 
+    }
+    
+    /**
+     * Get the response code included with the OK 
+     * response. 
+     * 
+     * @return The string name of the response code.
+     */
+    public String getResponseCode() {
+        return getKeyword(); 
+    }
+
+    /**
+     * Return the status argument values associated with
+     * this status response.
+     * 
+     * @return The status value information, as a list of tokens.
+     */
+    public List getStatus() {
+        return status; 
+    }
+    
+    /**
+     * Get any trailing message associated with this 
+     * status response. 
+     * 
+     * @return 
+     */
+    public String getMessage() {
+        return message; 
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java
new file mode 100644
index 0000000..a85f491
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java
@@ -0,0 +1,42 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPPermanentFlagsResponse extends IMAPUntaggedResponse {
+    // the response flags value  
+    public Flags flags;     
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPPermanentFlagsResponse(byte [] response, IMAPResponseTokenizer source) throws MessagingException {
+        super("PERMANENTFLAGS", response); 
+        flags = source.readFlagList(); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java
new file mode 100644
index 0000000..8ea5698
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java
@@ -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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList; 
+import java.util.List;
+
+import javax.mail.MessagingException;
+import javax.mail.Quota;
+
+/**
+ * Util class to represent a list response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+
+public class IMAPQuotaResponse extends IMAPUntaggedResponse {
+    // the returned quota item 
+    public Quota quota; 
+
+    /**
+     * Construct a LIST response item.  This can be either 
+     * a response from a LIST command or an LSUB command, 
+     * and will be tagged accordingly.
+     * 
+     * @param type   The type of resonse (LIST or LSUB).
+     * @param data   The raw response data.
+     * @param source The tokenizer source.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPQuotaResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("QUOTA", data); 
+
+        // first token is the root name, which can be either an atom or a string. 
+        String tokenName = source.readString(); 
+        
+        // create a quota item for this 
+        quota = new Quota(tokenName); 
+        
+        source.checkLeftParen(); 
+        
+        List resources = new ArrayList(); 
+        
+        while (source.notListEnd()) {
+            // quotas are returned as a set of triplets.  The first element is the 
+            // resource name, followed by the current usage and the limit value. 
+            Quota.Resource resource = new Quota.Resource(source.readAtom(), source.readLong(), source.readLong()); 
+            resources.add(resource); 
+        }
+        
+        quota.resources = (Quota.Resource[])resources.toArray(new Quota.Resource[resources.size()]); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java
new file mode 100644
index 0000000..44d564f
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java
@@ -0,0 +1,57 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a list response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+
+public class IMAPQuotaRootResponse extends IMAPUntaggedResponse {
+    // the mailbox this applies to 
+    public String mailbox; 
+    // The list of quota roots 
+    public List roots; 
+    
+
+    /**
+     * Construct a LIST response item.  This can be either 
+     * a response from a LIST command or an LSUB command, 
+     * and will be tagged accordingly.
+     * 
+     * @param type   The type of resonse (LIST or LSUB).
+     * @param data   The raw response data.
+     * @param source The tokenizer source.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPQuotaRootResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("QUOTAROOT", data); 
+
+        // first token is the mailbox 
+        mailbox = source.readEncodedString(); 
+        // get the root name list as the remainder of the command. 
+        roots = source.readStrings(); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java
new file mode 100644
index 0000000..7180402
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java
@@ -0,0 +1,72 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.io.UnsupportedEncodingException;
+
+import javax.mail.MessagingException;
+
+/**
+ * Base class for all response messages.                      
+ *
+ * @version $Rev: 947075 $ $Date: 2010-05-21 13:12:20 -0400 (Fri, 21 May 2010) $
+ */
+public class IMAPResponse {
+    // The original (raw) response data
+    protected byte[] response;
+
+    /**
+     * Create a response object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    protected IMAPResponse(byte [] response) {
+        // set this as the current message and parse.
+        this.response = response;
+    }
+    
+    /**
+     * Retrieve the raw response line data for this 
+     * response message.  Normally, this will be a complete
+     * single line response, unless there are quoted 
+     * literals in the response data containing octet
+     * data. 
+     * 
+     * @return The byte array containing the response information.
+     */
+    public byte[] getResponseData() {
+        return response; 
+    }
+
+    /**
+     * Return the response message as a string value.  
+     * This is intended for debugging purposes only.  The 
+     * response data might contain octet data that 
+     * might not convert to character data appropriately. 
+     * 
+     * @return The string version of the response. 
+     */
+    public String toString() {
+        try {
+            return new String(response, "US-ASCII");
+        } catch (UnsupportedEncodingException e) {
+        }
+        return new String(response);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
new file mode 100644
index 0000000..cd28d54
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
@@ -0,0 +1,138 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Simple extension to the ByteArrayOutputStream to allow inspection
+ * of the data while it is being accumulated.
+ */
+public class IMAPResponseBuffer extends ByteArrayOutputStream {
+
+    public IMAPResponseBuffer() {
+        super();
+    }
+
+
+    /**
+     * Read a character from the byte array output stream buffer
+     * at the give position.
+     *
+     * @param index  The requested index.
+     *
+     * @return The byte at the target index, or -1 if the index is out of
+     *         bounds.
+     */
+    public int read(int index) {
+        if (index >= size()) {
+            return -1;
+        }
+        return buf[index];
+    }
+
+    /**
+     * Read a buffer of data from the output stream's accumulator
+     * buffer.  This will copy the data into a target byte arrain.
+     *
+     * @param buffer The target byte array for returning the data.
+     * @param offset The offset of the source data within the output stream buffer.
+     * @param length The desired length.
+     *
+     * @return The count of bytes transferred into the buffer.
+     */
+    public int read(byte[] buffer, int offset, int length) {
+
+        int available = size() - offset;
+        length = Math.min(length, available);
+        // nothing to return?   quit now.
+        if (length <= 0) {
+            return 0;
+        }
+        System.arraycopy(buf, offset, buffer, 0, length);
+        return length;
+    }
+
+    /**
+     * Search backwards through the buffer for a given byte.
+     *
+     * @param target The search character.
+     *
+     * @return The index relative to the buffer start of the given byte.
+     *         Returns -1 if not found.
+     */
+    public int lastIndex(byte target) {
+        for (int i = size() - 1; i > 0; i--) {
+            if (buf[i] == target) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Return the last byte written to the output stream.  Returns
+     * -1 if the stream is empty.
+     *
+     * @return The last byte written (or -1 if the stream is empty).
+     */
+    public int lastByte() {
+        if (size() > 0) {
+            return buf[size() - 1];
+        }
+        return -1;
+    }
+
+
+    /**
+     * Retrieve an IMAP literal length value from the buffer.  We
+     * have a literal length value IFF the last characters written
+     * to the buffer have the form "{nnnn}".  This returns the
+     * integer value of the info inside the curly braces.  Returns -1
+     * if a valid literal length is not found.
+     *
+     * @return A literal length value, or -1 if we don't have a literal
+     *         signature at the end.
+     */
+    public int getLiteralLength() {
+        // was the last byte before the line break the close of the literal length?
+        if (lastByte() == '}') {
+            // locate the length start
+            int literalStart = lastIndex((byte)'{');
+            // no matching start, this can't be a literal.
+            if (literalStart == -1) {
+                return -1;
+            }
+
+            try {
+                String lenString = new String(buf, literalStart + 1, size() - (literalStart + 2), "US-ASCII");
+                try {
+                    return Integer.parseInt(lenString);
+                } catch (NumberFormatException e) {
+                }
+            } catch (UnsupportedEncodingException ex) {
+                // should never happen
+            }
+        }
+        // not a literal
+        return -1;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
new file mode 100644
index 0000000..420934a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
@@ -0,0 +1,405 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+import javax.mail.event.FolderEvent;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
+import org.apache.geronimo.javamail.util.ConnectionException;
+
+public class IMAPResponseStream {
+    protected final int BUFFER_SIZE = 1024;
+
+    // our source input stream
+    protected InputStream in;
+    // The response buffer
+    IMAPResponseBuffer out;
+    // the buffer array
+    protected byte[] buffer = new byte[BUFFER_SIZE];
+    // the current buffer position
+    int position;
+    // the current buffer read length
+    int length;
+
+    public IMAPResponseStream(InputStream in) {
+        this.in = in;
+        out = new IMAPResponseBuffer();
+    }
+
+    public int read() throws IOException {
+        // if we can't read any more, that's an EOF condition.
+        if (!fillBufferIfNeeded()) {
+            return -1;
+        }
+        // just grab the next character
+        return buffer[position++];
+    }
+
+    protected boolean fillBufferIfNeeded() throws IOException {
+        // used up all of the data in the buffer?
+        if (position >= length) {
+            int readLength = 0;
+            // a read from a network connection can return 0 bytes,
+            // so we need to be prepared to handle a spin loop.
+            while (readLength == 0) {
+                readLength = in.read(buffer, 0, buffer.length);
+            }
+            // we may have hit the EOF.  Indicate the read failure
+            if (readLength == -1) {
+                return false;
+            }
+            // set our new buffer positions.
+            position = 0;
+            length = readLength;
+        }
+        return true;
+    }
+
+
+    /**
+     * Read a single response line from the input stream, returning
+     * a parsed and processed response line.
+     *
+     * @return A parsed IMAPResponse item using the response data.
+     * @exception MessagingException
+     */
+    public IMAPResponse readResponse() throws MessagingException
+      {
+        // reset our accumulator
+        out.reset();
+        // now read a buffer of data
+        byte[] data = readData();
+
+        // and create a tokenizer for parsing this down.
+        IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(data);
+        // get the first token.
+        Token token = tokenizer.next();
+
+        int type = token.getType();
+
+        // a continuation response.  This will terminate a response set.
+        if (type == Token.CONTINUATION) {
+            return new IMAPContinuationResponse(data);
+        }
+        // unsolicited response.  There are multiple forms of these, which might actually be
+        // part of the response for the last issued command.
+        else if (type == Token.UNTAGGED) {
+            // step to the next token, which will give us the type
+            token = tokenizer.next();
+            // if the token is numeric, then this is a size response in the
+            // form "* nn type"
+            if (token.isType(Token.NUMERIC)) {
+                int size = token.getInteger();
+
+                token = tokenizer.next();
+
+                String keyword = token.getValue();
+
+                // FETCH responses require fairly complicated parsing.  Other
+                // size/message updates are fairly generic.
+                if (keyword.equals("FETCH")) {
+                    return new IMAPFetchResponse(size, data, tokenizer);
+                }
+                return new IMAPSizeResponse(keyword, size, data);
+            }
+
+            // this needs to be an ATOM type, which will tell us what format this untagged
+            // response is in.  There are many different untagged formats, some general, some
+            // specific to particular command types.
+            if (token.getType() != Token.ATOM) {
+                try {
+                    throw new MessagingException("Unknown server response: " + new String(data, "ISO8859-1"));
+                } catch (UnsupportedEncodingException e) {
+                    throw new MessagingException("Unknown server response: " + new String(data));
+                }
+            }
+
+            String keyword = token.getValue();
+            // many response are in the form "* OK [keyword value] message".
+            if (keyword.equals("OK")) {
+                return parseUntaggedOkResponse(data, tokenizer);
+            }
+            // preauth status response
+            else if (keyword.equals("PREAUTH")) {
+                return new IMAPServerStatusResponse("PREAUTH", tokenizer.getRemainder(), data);
+            }
+            // preauth status response
+            else if (keyword.equals("BYE")) {
+                return new IMAPServerStatusResponse("BYE", tokenizer.getRemainder(), data);
+            }
+            else if (keyword.equals("BAD")) {
+                // these are generally ignored.
+                return new IMAPServerStatusResponse("BAD", tokenizer.getRemainder(), data);
+            }
+            else if (keyword.equals("NO")) {
+                // these are generally ignored.
+                return new IMAPServerStatusResponse("NO", tokenizer.getRemainder(), data);
+            }
+            // a complex CAPABILITY response
+            else if (keyword.equals("CAPABILITY")) {
+                return new IMAPCapabilityResponse(tokenizer, data);
+            }
+            // a complex LIST response
+            else if (keyword.equals("LIST")) {
+                return new IMAPListResponse("LIST", data, tokenizer);
+            }
+            // a complex FLAGS response
+            else if (keyword.equals("FLAGS")) {
+                // parse this into a flags set.
+                return new IMAPFlagsResponse(data, tokenizer);
+            }
+            // a complex LSUB response (identical in format to LIST)
+            else if (keyword.equals("LSUB")) {
+                return new IMAPListResponse("LSUB", data, tokenizer);
+            }
+            // a STATUS response, which will contain a list of elements
+            else if (keyword.equals("STATUS")) {
+                return new IMAPStatusResponse(data, tokenizer);
+            }
+            // SEARCH requests return an variable length list of message matches.
+            else if (keyword.equals("SEARCH")) {
+                return new IMAPSearchResponse(data, tokenizer);
+            }
+            // ACL requests return an variable length list of ACL values .
+            else if (keyword.equals("ACL")) {
+                return new IMAPACLResponse(data, tokenizer);
+            }
+            // LISTRIGHTS requests return a variable length list of RIGHTS values .
+            else if (keyword.equals("LISTRIGHTS")) {
+                return new IMAPListRightsResponse(data, tokenizer);
+            }
+            // MYRIGHTS requests return a list of user rights for a mailbox name.
+            else if (keyword.equals("MYRIGHTS")) {
+                return new IMAPMyRightsResponse(data, tokenizer);
+            }
+            // QUOTAROOT requests return a list of mailbox quota root names
+            else if (keyword.equals("QUOTAROOT")) {
+                return new IMAPQuotaRootResponse(data, tokenizer);
+            }
+            // QUOTA requests return a list of quota values for a root name
+            else if (keyword.equals("QUOTA")) {
+                return new IMAPQuotaResponse(data, tokenizer);
+            }
+            else if (keyword.equals("NAMESPACE")) {
+                return new IMAPNamespaceResponse(data, tokenizer);
+            }
+        }
+        // begins with a word, this should be the tagged response from the last command.
+        else if (type == Token.ATOM) {
+            String tag = token.getValue();
+            token = tokenizer.next();
+            String status = token.getValue();
+            //handle plain authentication gracefully, see GERONIMO-6526
+            if("+".equals(tag) && status == null) {
+            	return new IMAPContinuationResponse(data);
+            }                      
+            // primary information in one of these is the status field, which hopefully
+            // is 'OK'
+            return new IMAPTaggedResponse(tag, status, tokenizer.getRemainder(), data);
+        }
+        try {
+            throw new MessagingException("Unknown server response: " + new String(data, "ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+            throw new MessagingException("Unknown server response: " + new String(data));
+        }
+    }
+
+    /**
+     * Parse an unsolicited OK status response.  These
+     * responses are of the form:
+     *
+     * * OK [keyword arguments ...] message
+     *
+     * The part in the brackets are optional, but
+     * most OK messages will have some sort of update.
+     *
+     * @param data      The raw message data
+     * @param tokenizer The tokenizer being used for this message.
+     *
+     * @return An IMAPResponse instance for this message.
+     */
+    private IMAPResponse parseUntaggedOkResponse(byte [] data, IMAPResponseTokenizer tokenizer) throws MessagingException {
+        Token token = tokenizer.peek();
+        // we might have an optional value here
+        if (token.getType() != '[') {
+            // this has no tagging item, so there's nothing to be processed
+            // later.
+            return new IMAPOkResponse("OK", null, tokenizer.getRemainder(), data);
+        }
+        // skip over the "[" token
+        tokenizer.next();
+        token = tokenizer.next();
+        String keyword = token.getValue();
+
+        // Permanent flags gets special handling
+        if (keyword.equals("PERMANENTFLAGS")) {
+            return new IMAPPermanentFlagsResponse(data, tokenizer);
+        }
+
+        ArrayList arguments = new ArrayList();
+
+        // strip off all of the argument tokens until the "]" list terminator.
+        token = tokenizer.next();
+        while (token.getType() != ']') {
+            arguments.add(token);
+            token = tokenizer.next();
+        }
+        // this has a tagged keyword and arguments that will be processed later.
+        return new IMAPOkResponse(keyword, arguments, tokenizer.getRemainder(), data);
+    }
+
+
+    /**
+     * Read a "line" of server response data.  An individual line
+     * may span multiple line breaks, depending on syntax implications.
+     *
+     * @return
+     * @exception MessagingException
+     */
+    public byte[] readData() throws MessagingException {
+        // reset out buffer accumulator
+        out.reset();
+        // read until the end of the response into our buffer.
+        readBuffer();
+        // get the accumulated data.
+        return out.toByteArray();
+    }
+
+    /**
+     * Read a buffer of data.  This accumulates the data into a
+     * ByteArrayOutputStream, terminating the processing at a line
+     * break.  This also handles line breaks that are the result
+     * of literal continuations in the stream.
+     *
+     * @exception MessagingException
+     * @exception IOException
+     */
+    public void readBuffer() throws MessagingException {
+        while (true) {
+            int ch = nextByte();
+            // potential end of line?  Check the next character, and if it is an end of line,
+            // we need to do literal processing.
+            if (ch == '\r') {
+                int next = nextByte();
+                if (next == '\n') {
+                    // had a line break, which might be part of a literal marker.  Check for the signature,
+                    // and if we found it, continue with the next line.  In any case, we're done with processing here.
+                    checkLiteral();
+                    return;
+                }
+            }
+            // write this to the buffer.
+            out.write(ch);
+        }
+    }
+
+
+    /**
+     * Check the line just read to see if we're processing a line
+     * with a literal value.  Literals are encoded as "{length}\r\n",
+     * so if we've read up to the line break, we can check to see
+     * if we need to continue reading.
+     *
+     * If a literal marker is found, we read that many characters
+     * from the reader without looking for line breaks.  Once we've
+     * read the literal data, we just read the rest of the line
+     * as normal (which might also end with a literal marker).
+     *
+     * @exception MessagingException
+     */
+    public void checkLiteral() throws MessagingException {
+        try {
+            // see if we have a literal length signature at the end.
+            int length = out.getLiteralLength();
+
+            // -1 means no literal length, so we're done reading this particular response.
+            if (length == -1) {
+                return;
+            }
+
+            // we need to write out the literal line break marker.
+            out.write('\r');
+            out.write('\n');
+
+            // have something we're supposed to read for the literal?
+            if (length > 0) {
+                byte[] bytes = new byte[length];
+
+                int offset = 0;
+
+                // The InputStream can return less than the requested length if it needs to block.
+                // This may take a couple iterations to get everything, particularly if it's long.
+                while (length > 0) {
+                    int read = -1;
+                    try {
+                        read = in.read(bytes, offset, length);
+                    } catch (IOException e) {
+                        throw new MessagingException("Unexpected read error on server connection", e);
+                    }
+                    // premature EOF we can't ignore.
+                    if (read == -1) {
+                        throw new MessagingException("Unexpected end of stream");
+                    }
+                    length -= read;
+                    offset += read;
+                }
+
+                // write this out to the output stream.
+                out.write(bytes);
+            }
+            // Now that we have the literal data, we need to read the rest of the response line (which might contain
+            // additional literals).  Just recurse on the line reading logic.
+            readBuffer();
+        } catch (IOException e) {
+            e.printStackTrace();
+            // this is a byte array output stream...should never happen
+        }
+    }
+
+
+    /**
+     * Get the next byte from the input stream, handling read errors
+     * and EOF conditions as MessagingExceptions.
+     *
+     * @return The next byte read from the stream.
+     * @exception MessagingException
+     */
+    protected int nextByte() throws MessagingException {
+        try {
+            int next = in.read();
+            if (next == -1) {
+                throw new MessagingException("Read error on IMAP server connection");
+            }
+            return next;
+        } catch (IOException e) {
+            throw new MessagingException("Unexpected error on server stream", e);
+        }
+    }
+
+
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
new file mode 100644
index 0000000..9a5f5c9
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
@@ -0,0 +1,1469 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MailDateFormat;
+import javax.mail.internet.ParameterList;
+
+import org.apache.geronimo.javamail.util.ResponseFormatException;
+
+/**
+ * @version $Rev: 953638 $ $Date: 2010-06-11 06:09:00 -0400 (Fri, 11 Jun 2010) $
+ */
+public class IMAPResponseTokenizer {
+    /*
+     * set up the decoding table.
+     */
+    protected static final byte[] decodingTable = new byte[256];
+
+    protected static void initializeDecodingTable()
+    {
+        for (int i = 0; i < IMAPCommand.encodingTable.length; i++)
+        {
+            decodingTable[IMAPCommand.encodingTable[i]] = (byte)i;
+        }
+    }
+
+
+    static {
+        initializeDecodingTable();
+    }
+
+    // a singleton formatter for header dates.
+    protected static MailDateFormat dateParser = new MailDateFormat();
+
+
+    public static class Token {
+        // Constant values from J2SE 1.4 API Docs (Constant values)
+        public static final int ATOM = -1;
+        public static final int QUOTEDSTRING = -2;
+        public static final int LITERAL = -3;
+        public static final int NUMERIC = -4;
+        public static final int EOF = -5;
+        public static final int NIL = -6;
+        // special single character markers
+        public static final int CONTINUATION = '+';
+        public static final int UNTAGGED = '*';
+
+        /**
+         * The type indicator.  This will be either a specific type, represented by
+         * a negative number, or the actual character value.
+         */
+        private int type;
+        /**
+         * The String value associated with this token.  All tokens have a String value,
+         * except for the EOF and NIL tokens.
+         */
+        private String value;
+
+        public Token(int type, String value) {
+            this.type = type;
+            this.value = value;
+        }
+
+        public int getType() {
+            return type;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public boolean isType(int type) {
+            return this.type == type;
+        }
+
+        /**
+         * Return the token as an integer value.  If this can't convert, an exception is
+         * thrown.
+         *
+         * @return The integer value of the token.
+         * @exception ResponseFormatException
+         */
+        public int getInteger() throws MessagingException {
+            if (value != null) {
+                try {
+                    return Integer.parseInt(value);
+                } catch (NumberFormatException e) {
+                }
+            }
+
+            throw new ResponseFormatException("Number value expected in response; fount: " + value);
+        }
+
+        /**
+         * Return the token as a long value.  If it can't convert, an exception is
+         * thrown.
+         *
+         * @return The token as a long value.
+         * @exception ResponseFormatException
+         */
+        public long getLong() throws MessagingException {
+            if (value != null) {
+                try {
+                    return Long.parseLong(value);
+                } catch (NumberFormatException e) {
+                }
+            }
+            throw new ResponseFormatException("Number value expected in response; fount: " + value);
+        }
+
+        /**
+         * Handy debugging toString() method for token.
+         *
+         * @return The string value of the token.
+         */
+        public String toString() {
+            if (type == NIL) {
+                return "NIL";
+            }
+            else if (type == EOF) {
+                return "EOF";
+            }
+
+            if (value == null) {
+                return "";
+            }
+            return value;
+        }
+    }
+
+    public static final Token EOF = new Token(Token.EOF, null);
+    public static final Token NIL = new Token(Token.NIL, null);
+
+    private static final String WHITE = " \t\n\r";
+    // The list of delimiter characters we process when
+    // handling parsing of ATOMs.
+    private static final String atomDelimiters = "(){}%*\"\\" + WHITE;
+    // this set of tokens is a slighly expanded set used for
+    // specific response parsing.  When dealing with Body
+    // section names, there are sub pieces to the name delimited
+    // by "[", "]", ".", "<", ">" and SPACE, so reading these using
+    // a superset of the ATOM processing makes for easier parsing.
+    private static final String tokenDelimiters = "<>[].(){}%*\"\\" + WHITE;
+
+    // the response data read from the connection
+    private byte[] response;
+    // current parsing position
+    private int pos;
+
+    public IMAPResponseTokenizer(byte [] response) {
+        this.response = response;
+    }
+
+    /**
+     * Get the remainder of the response as a string.
+     *
+     * @return A string representing the remainder of the response.
+     */
+    public String getRemainder() {
+        // make sure we're still in range
+        if (pos >= response.length) {
+            return "";
+        }
+
+        try {
+            return new String(response, pos, response.length - pos, "ISO8859-1");
+        } catch (UnsupportedEncodingException e) {
+            return null; 
+        }
+    }
+
+
+    public Token next() throws MessagingException {
+        return next(false);
+    }
+
+    public Token next(boolean nilAllowed) throws MessagingException {
+        return readToken(nilAllowed, false);
+    }
+
+    public Token next(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
+        return readToken(nilAllowed, expandedDelimiters);
+    }
+
+    public Token peek() throws MessagingException {
+        return peek(false, false);
+    }
+
+    public Token peek(boolean nilAllowed) throws MessagingException {
+        return peek(nilAllowed, false);
+    }
+
+    public Token peek(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
+        int start = pos;
+        try {
+            return readToken(nilAllowed, expandedDelimiters);
+        } finally {
+            pos = start;
+        }
+    }
+
+    /**
+     * Read an ATOM token from the parsed response.
+     *
+     * @return A token containing the value of the atom token.
+     */
+    private Token readAtomicToken(String delimiters) {
+        // skip to next delimiter
+        int start = pos;
+        while (++pos < response.length) {
+            // break on the first non-atom character.
+            byte ch = response[pos];
+            if (delimiters.indexOf(response[pos]) != -1 || ch < 32 || ch >= 127) {
+                break;
+            }
+        }
+
+        try {
+            // Numeric tokens we store as a different type.
+            String value = new String(response, start, pos - start, "ISO8859-1");
+            try {
+                int intValue = Integer.parseInt(value);
+                return new Token(Token.NUMERIC, value);
+            } catch (NumberFormatException e) {
+            }
+            return new Token(Token.ATOM, value);
+        } catch (UnsupportedEncodingException e) {
+            return null; 
+        }
+    }
+
+    /**
+     * Read the next token from the response.
+     *
+     * @return The next token from the response.  White space is skipped, and comment
+     *         tokens are also skipped if indicated.
+     * @exception ResponseFormatException
+     */
+    private Token readToken(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
+        String delimiters = expandedDelimiters ? tokenDelimiters : atomDelimiters;
+
+        if (pos >= response.length) {
+            return EOF;
+        } else {
+            byte ch = response[pos];
+            if (ch == '\"') {
+                return readQuotedString();
+            // beginning of a length-specified literal?
+            } else if (ch == '{') {
+                return readLiteral();
+            // white space, eat this and find a real token.
+            } else if (WHITE.indexOf(ch) != -1) {
+                eatWhiteSpace();
+                return readToken(nilAllowed, expandedDelimiters);
+            // either a CTL or special.  These characters have a self-defining token type.
+            } else if (ch < 32 || ch >= 127 || delimiters.indexOf(ch) != -1) {
+                pos++;
+                return new Token((int)ch, String.valueOf((char)ch));
+            } else {
+                // start of an atom, parse it off.
+                Token token = readAtomicToken(delimiters);
+                // now, if we've been asked to look at NIL tokens, check to see if it is one,
+                // and return that instead of the ATOM.
+                if (nilAllowed) {
+                    if (token.getValue().equalsIgnoreCase("NIL")) {
+                        return NIL;
+                    }
+                }
+                return token;
+            }
+        }
+    }
+
+    /**
+     * Read the next token from the response, returning it as a byte array value.
+     *
+     * @return The next token from the response.  White space is skipped, and comment
+     *         tokens are also skipped if indicated.
+     * @exception ResponseFormatException
+     */
+    private byte[] readData(boolean nilAllowed) throws MessagingException {
+        if (pos >= response.length) {
+            return null;
+        } else {
+            byte ch = response[pos];
+            if (ch == '\"') {
+                return readQuotedStringData();
+            // beginning of a length-specified literal?
+            } else if (ch == '{') {
+                return readLiteralData();
+            // white space, eat this and find a real token.
+            } else if (WHITE.indexOf(ch) != -1) {
+                eatWhiteSpace();
+                return readData(nilAllowed);
+            // either a CTL or special.  These characters have a self-defining token type.
+            } else if (ch < 32 || ch >= 127 || atomDelimiters.indexOf(ch) != -1) {
+                throw new ResponseFormatException("Invalid string value: " + ch);
+            } else {
+                // only process this if we're allowing NIL as an option.
+                if (nilAllowed) {
+                    // start of an atom, parse it off.
+                    Token token = next(true);
+                    if (token.isType(Token.NIL)) {
+                        return null;
+                    }
+                    // invalid token type.
+                    throw new ResponseFormatException("Invalid string value: " + token.getValue());
+                }
+                // invalid token type.
+                throw new ResponseFormatException("Invalid string value: " + ch);
+            }
+        }
+    }
+
+    /**
+     * Extract a substring from the response string and apply any
+     * escaping/folding rules to the string.
+     *
+     * @param start  The starting offset in the response.
+     * @param end    The response end offset + 1.
+     *
+     * @return The processed string value.
+     * @exception ResponseFormatException
+     */
+    private byte[] getEscapedValue(int start, int end) throws MessagingException {
+        ByteArrayOutputStream value = new ByteArrayOutputStream();
+
+        for (int i = start; i < end; i++) {
+            byte ch = response[i];
+            // is this an escape character?
+            if (ch == '\\') {
+                i++;
+                if (i == end) {
+                    throw new ResponseFormatException("Invalid escape character");
+                }
+                value.write(response[i]);
+            }
+            // line breaks are ignored, except for naked '\n' characters, which are consider
+            // parts of linear whitespace.
+            else if (ch == '\r') {
+                // see if this is a CRLF sequence, and skip the second if it is.
+                if (i < end - 1 && response[i + 1] == '\n') {
+                    i++;
+                }
+            }
+            else {
+                // just append the ch value.
+                value.write(ch);
+            }
+        }
+        return value.toByteArray();
+    }
+
+    /**
+     * Parse out a quoted string from the response, applying escaping
+     * rules to the value.
+     *
+     * @return The QUOTEDSTRING token with the value.
+     * @exception ResponseFormatException
+     */
+    private Token readQuotedString() throws MessagingException {
+        try {
+            String value = new String(readQuotedStringData(), "ISO8859-1");
+            return new Token(Token.QUOTEDSTRING, value);
+        } catch (UnsupportedEncodingException e) {
+            return null; 
+        }
+    }
+
+    /**
+     * Parse out a quoted string from the response, applying escaping
+     * rules to the value.
+     *
+     * @return The byte array with the resulting string bytes.
+     * @exception ResponseFormatException
+     */
+    private byte[] readQuotedStringData() throws MessagingException {
+        int start = pos + 1;
+        boolean requiresEscaping = false;
+
+        // skip to end of comment/string
+        while (++pos < response.length) {
+            byte ch = response[pos];
+            if (ch == '"') {
+                byte[] value;
+                if (requiresEscaping) {
+                    value = getEscapedValue(start, pos);
+                }
+                else {
+                    value = subarray(start, pos);
+                }
+                // step over the delimiter for all cases.
+                pos++;
+                return value;
+            }
+            else if (ch == '\\') {
+                pos++;
+                requiresEscaping = true;
+            }
+            // we need to process line breaks also
+            else if (ch == '\r') {
+                requiresEscaping = true;
+            }
+        }
+
+        throw new ResponseFormatException("Missing '\"'");
+    }
+
+
+    /**
+     * Parse out a literal string from the response, using the length
+     * encoded before the listeral.
+     *
+     * @return The LITERAL token with the value.
+     * @exception ResponseFormatException
+     */
+    protected Token readLiteral() throws MessagingException {
+        try {
+            String value = new String(readLiteralData(), "ISO8859-1");
+            return new Token(Token.LITERAL, value);
+        } catch (UnsupportedEncodingException e) {
+            return null; 
+        }
+    }
+
+
+    /**
+     * Parse out a literal string from the response, using the length
+     * encoded before the listeral.
+     *
+     * @return The byte[] array with the value.
+     * @exception ResponseFormatException
+     */
+    protected byte[] readLiteralData() throws MessagingException {
+        int lengthStart = pos + 1;
+
+        // see if we have a close marker.
+        int lengthEnd = indexOf("}\r\n", lengthStart);
+        if (lengthEnd == -1) {
+            throw new ResponseFormatException("Missing terminator on literal length");
+        }
+
+        int count = 0;
+        try {
+            count = Integer.parseInt(substring(lengthStart, lengthEnd));
+        } catch (NumberFormatException e) {
+            throw new ResponseFormatException("Invalid literal length " + substring(lengthStart, lengthEnd));
+        }
+
+        // step over the length
+        pos = lengthEnd + 3;
+
+        // too long?
+        if (pos + count > response.length) {
+            throw new ResponseFormatException("Invalid literal length: " + count);
+        }
+
+        byte[] value = subarray(pos, pos + count);
+        pos += count;
+
+        return value;
+    }
+
+
+    /**
+     * Extract a substring from the response buffer.
+     *
+     * @param start  The starting offset.
+     * @param end    The end offset (+ 1).
+     *
+     * @return A String extracted from the buffer.
+     */
+    protected String substring(int start, int end ) {
+        try {
+            return new String(response, start, end - start, "ISO8859-1");
+        } catch (UnsupportedEncodingException e) {
+            return null; 
+        }
+    }
+
+
+    /**
+     * Extract a subarray from the response buffer.
+     *
+     * @param start  The starting offset.
+     * @param end    The end offset (+ 1).
+     *
+     * @return A byte array string extracted rom the buffer.
+     */
+    protected byte[] subarray(int start, int end ) {
+        byte[] result = new byte[end - start];
+        System.arraycopy(response, start, result, 0, end - start);
+        return result;
+    }
+
+
+    /**
+     * Test if the bytes in the response buffer match a given
+     * string value.
+     *
+     * @param position The compare position.
+     * @param needle   The needle string we're testing for.
+     *
+     * @return True if the bytes match the needle value, false for any
+     *         mismatch.
+     */
+    public boolean match(int position, String needle) {
+        int length = needle.length();
+
+        if (response.length - position < length) {
+            return false;
+        }
+
+        for (int i = 0; i < length; i++) {
+            if (response[position + i ] != needle.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * Search for a given string starting from the current position
+     * cursor.
+     *
+     * @param needle The search string.
+     *
+     * @return The index of a match (in absolute byte position in the
+     *         response buffer).
+     */
+    public int indexOf(String needle) {
+        return indexOf(needle, pos);
+    }
+
+    /**
+     * Search for a string in the response buffer starting from the
+     * indicated position.
+     *
+     * @param needle   The search string.
+     * @param position The starting buffer position.
+     *
+     * @return The index of the match position.  Returns -1 for no match.
+     */
+    public int indexOf(String needle, int position) {
+        // get the last possible match position
+        int last = response.length - needle.length();
+        // no match possible
+        if (last < position) {
+            return -1;
+        }
+
+        for (int i = position; i <= last; i++) {
+            if (match(i, needle)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+
+
+    /**
+     * Skip white space in the token string.
+     */
+    private void eatWhiteSpace() {
+        // skip to end of whitespace
+        while (++pos < response.length
+                && WHITE.indexOf(response[pos]) != -1)
+            ;
+    }
+
+
+    /**
+     * Ensure that the next token in the parsed response is a
+     * '(' character.
+     *
+     * @exception ResponseFormatException
+     */
+    public void checkLeftParen() throws MessagingException {
+        Token token = next();
+        if (token.getType() != '(') {
+            throw new ResponseFormatException("Missing '(' in response");
+        }
+    }
+
+
+    /**
+     * Ensure that the next token in the parsed response is a
+     * ')' character.
+     *
+     * @exception ResponseFormatException
+     */
+    public void checkRightParen() throws MessagingException {
+        Token token = next();
+        if (token.getType() != ')') {
+            throw new ResponseFormatException("Missing ')' in response");
+        }
+    }
+
+
+    /**
+     * Read a string-valued token from the response.  A string
+     * valued token can be either a quoted string, a literal value,
+     * or an atom.  Any other token type is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readString() throws MessagingException {
+        Token token = next(true);
+        int type = token.getType();
+        if (type == Token.NIL) {
+            return null;
+        }
+        if (type != Token.ATOM && type != Token.QUOTEDSTRING && type != Token.LITERAL && type != Token.NUMERIC) {
+            throw new ResponseFormatException("String token expected in response: " + token.getValue());
+        }
+        return token.getValue();
+    }
+
+
+    /**
+     * Read an encoded string-valued token from the response.  A string
+     * valued token can be either a quoted string, a literal value,
+     * or an atom.  Any other token type is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readEncodedString() throws MessagingException {
+        String value = readString();
+        return decode(value);
+    }
+
+
+    /**
+     * Decode a Base 64 encoded string value.
+     *
+     * @param original The original encoded string.
+     *
+     * @return The decoded string.
+     * @exception MessagingException
+     */
+    public String decode(String original) throws MessagingException {
+        StringBuffer result = new StringBuffer();
+
+        for (int i = 0; i < original.length(); i++) {
+            char ch = original.charAt(i);
+
+            if (ch == '&') {
+                i = decode(original, i, result);
+            }
+            else {
+                result.append(ch);
+            }
+        }
+
+        return result.toString();
+    }
+
+
+    /**
+     * Decode a section of an encoded string value.
+     *
+     * @param original The original source string.
+     * @param index    The current working index.
+     * @param result   The StringBuffer used for the decoded result.
+     *
+     * @return The new index for the decoding operation.
+     * @exception MessagingException
+     */
+    public static int decode(String original, int index, StringBuffer result) throws MessagingException {
+        // look for the section terminator
+        int terminator = original.indexOf('-', index);
+
+        // unmatched?
+        if (terminator == -1) {
+            throw new MessagingException("Invalid UTF-7 encoded string");
+        }
+
+        // is this just an escaped "&"?
+        if (terminator == index + 1) {
+            // append and skip over this.
+            result.append('&');
+            return index + 2;
+        }
+
+        // step over the starting char
+        index++;
+
+        int chars = terminator - index;
+        int quads = chars / 4;
+        int residual = chars % 4;
+
+        // buffer for decoded characters
+        byte[] buffer = new byte[4];
+        int bufferCount = 0;
+
+        // process each of the full triplet pairs
+        for (int i = 0; i < quads; i++) {
+            byte b1 = decodingTable[original.charAt(index++) & 0xff];
+            byte b2 = decodingTable[original.charAt(index++) & 0xff];
+            byte b3 = decodingTable[original.charAt(index++) & 0xff];
+            byte b4 = decodingTable[original.charAt(index++) & 0xff];
+
+            buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
+            buffer[bufferCount++] = (byte)((b2 << 4) | (b3 >> 2));
+            buffer[bufferCount++] = (byte)((b3 << 6) | b4);
+
+            // we've written 3 bytes to the buffer, but we might have a residual from a previous
+            // iteration to deal with.
+            if (bufferCount == 4) {
+                // two complete chars here
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                b1 = buffer[2];
+                b2 = buffer[3];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                bufferCount = 0;
+            }
+            else {
+                // we need to save the 3rd byte for the next go around
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                buffer[0] = buffer[2];
+                bufferCount = 1;
+            }
+        }
+
+        // properly encoded, we should have an even number of bytes left.
+
+        switch (residual) {
+            // no residual...so we better not have an extra in the buffer
+            case 0:
+                // this is invalid...we have an odd number of bytes so far,
+                if (bufferCount == 1) {
+                    throw new MessagingException("Invalid UTF-7 encoded string");
+                }
+            // one byte left.  This shouldn't be valid.  We need at least 2 bytes to
+            // encode one unprintable char.
+            case 1:
+                throw new MessagingException("Invalid UTF-7 encoded string");
+
+            // ok, we have two bytes left, which can only encode a single byte.  We must have
+            // a dangling unhandled char.
+            case 2:
+            {
+                if (bufferCount != 1) {
+                    throw new MessagingException("Invalid UTF-7 encoded string");
+                }
+                byte b1 = decodingTable[original.charAt(index++) & 0xff];
+                byte b2 = decodingTable[original.charAt(index++) & 0xff];
+                buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
+
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                break;
+            }
+
+            // we have 2 encoded chars.  In this situation, we can't have a leftover.
+            case 3:
+            {
+                // this is invalid...we have an odd number of bytes so far,
+                if (bufferCount == 1) {
+                    throw new MessagingException("Invalid UTF-7 encoded string");
+                }
+                byte b1 = decodingTable[original.charAt(index++) & 0xff];
+                byte b2 = decodingTable[original.charAt(index++) & 0xff];
+                byte b3 = decodingTable[original.charAt(index++) & 0xff];
+
+                buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
+                buffer[bufferCount++] = (byte)((b2 << 4) | (b3 >> 2));
+
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                break;
+            }
+        }
+
+        // return the new scan location
+        return terminator + 1;
+    }
+
+    /**
+     * Read a string-valued token from the response, verifying this is an ATOM token.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readAtom() throws MessagingException {
+        return readAtom(false);
+    }
+
+
+    /**
+     * Read a string-valued token from the response, verifying this is an ATOM token.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readAtom(boolean expandedDelimiters) throws MessagingException {
+        Token token = next(false, expandedDelimiters);
+        int type = token.getType();
+
+        if (type != Token.ATOM) {
+            throw new ResponseFormatException("ATOM token expected in response: " + token.getValue());
+        }
+        return token.getValue();
+    }
+
+
+    /**
+     * Read a number-valued token from the response.  This must be an ATOM
+     * token.
+     *
+     * @return The integer value of the source token.
+     * @exception ResponseFormatException
+     */
+    public int readInteger() throws MessagingException {
+        Token token = next();
+        return token.getInteger();
+    }
+
+
+    /**
+     * Read a number-valued token from the response.  This must be an ATOM
+     * token.
+     *
+     * @return The long value of the source token.
+     * @exception ResponseFormatException
+     */
+    public int readLong() throws MessagingException {
+        Token token = next();
+        return token.getInteger();
+    }
+
+
+    /**
+     * Read a string-valued token from the response.  A string
+     * valued token can be either a quoted string, a literal value,
+     * or an atom.  Any other token type is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readStringOrNil() throws MessagingException {
+        // we need to recognize the NIL token.
+        Token token = next(true);
+        int type = token.getType();
+
+        if (type != Token.ATOM && type != Token.QUOTEDSTRING && type != Token.LITERAL && type != Token.NIL) {
+            throw new ResponseFormatException("String token or NIL expected in response: " + token.getValue());
+        }
+        // this returns null if the token is the NIL token.
+        return token.getValue();
+    }
+
+
+    /**
+     * Read a quoted string-valued token from the response.
+     * Any other token type other than NIL is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    protected String readQuotedStringOrNil() throws MessagingException {
+        // we need to recognize the NIL token.
+        Token token = next(true);
+        int type = token.getType();
+
+        if (type != Token.QUOTEDSTRING && type != Token.NIL) {
+            throw new ResponseFormatException("String token or NIL expected in response");
+        }
+        // this returns null if the token is the NIL token.
+        return token.getValue();
+    }
+
+
+    /**
+     * Read a date from a response string.  This is expected to be in
+     * Internet Date format, but there's a lot of variation implemented
+     * out there.  If we're unable to format this correctly, we'll
+     * just return null.
+     *
+     * @return A Date object created from the source date.
+     */
+    public Date readDate() throws MessagingException {
+        String value = readString();
+
+        try {
+            return dateParser.parse(value);
+        } catch (Exception e) {
+            // we're just skipping over this, so return null
+            return null;
+        }
+    }
+
+
+    /**
+     * Read a date from a response string.  This is expected to be in
+     * Internet Date format, but there's a lot of variation implemented
+     * out there.  If we're unable to format this correctly, we'll
+     * just return null.
+     *
+     * @return A Date object created from the source date.
+     */
+    public Date readDateOrNil() throws MessagingException {
+        String value = readStringOrNil();
+        // this might be optional
+        if (value == null) {
+            return null;
+        }
+
+        try {
+            return dateParser.parse(value);
+        } catch (Exception e) {
+            // we're just skipping over this, so return null
+            return null;
+        }
+    }
+
+    /**
+     * Read an internet address from a Fetch response.  The
+     * addresses are returned as a set of string tokens in the
+     * order "personal list mailbox host".  Any of these tokens
+     * can be NIL.
+     *
+     * The address may also be the start of a group list, which
+     * is indicated by the host being NIL.  If we have found the
+     * start of a group, then we need to parse multiple elements
+     * until we find the group end marker (indicated by both the
+     * mailbox and the host being NIL), and create a group
+     * InternetAddress instance from this.
+     *
+     * @return An InternetAddress instance parsed from the
+     *         element.
+     * @exception ResponseFormatException
+     */
+    public InternetAddress readAddress() throws MessagingException {
+        // we recurse, expecting a null response back for sublists.
+        if (peek().getType() != '(') {
+            return null;
+        }
+
+        // must start with a paren
+        checkLeftParen();
+
+        // personal information
+        String personal = readStringOrNil();
+        // the domain routine information.
+        String routing = readStringOrNil();
+        // the target mailbox
+        String mailbox = readStringOrNil();
+        // and finally the host
+        String host = readStringOrNil();
+        // and validate the closing paren
+        checkRightParen();
+
+        // if this is a real address, we need to compose
+        if (host != null) {
+            StringBuffer address = new StringBuffer();
+            if (routing != null) {
+                address.append(routing);
+                address.append(':');
+            }
+            address.append(mailbox);
+            address.append('@');
+            address.append(host);
+
+            try {
+                return new InternetAddress(address.toString(), personal);
+            } catch (UnsupportedEncodingException e) {
+                throw new ResponseFormatException("Invalid Internet address format");
+            }
+        }
+        else {
+            // we're going to recurse on this.  If the mailbox is null (the group name), this is the group item
+            // terminator.
+            if (mailbox == null) {
+                return null;
+            }
+
+            StringBuffer groupAddress = new StringBuffer();
+
+            groupAddress.append(mailbox);
+            groupAddress.append(':');
+            int count = 0;
+
+            while (true) {
+                // now recurse until we hit the end of the list
+                InternetAddress member = readAddress();
+                if (member == null) {
+                    groupAddress.append(';');
+
+                    try {
+                        return new InternetAddress(groupAddress.toString(), personal);
+                    } catch (UnsupportedEncodingException e) {
+                        throw new ResponseFormatException("Invalid Internet address format");
+                    }
+                }
+                else {
+                    if (count != 0) {
+                        groupAddress.append(',');
+                    }
+                    groupAddress.append(member.toString());
+                    count++;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Parse out a list of addresses.  This list of addresses is
+     * surrounded by parentheses, and each address is also
+     * parenthized (SP?).
+     *
+     * @return An array of the parsed addresses.
+     * @exception ResponseFormatException
+     */
+    public InternetAddress[] readAddressList() throws MessagingException {
+        // must start with a paren, but can be NIL also.
+        Token token = next(true);
+        int type = token.getType();
+
+        // either of these results in a null address.  The caller determines based on
+        // context whether this was optional or not.
+        if (type == Token.NIL) {
+            return null;
+        }
+        // non-nil address and no paren.  This is a syntax error.
+        else if (type != '(') {
+            throw new ResponseFormatException("Missing '(' in response");
+        }
+
+        List addresses = new ArrayList();
+
+        // we have a list, now parse it.
+        while (notListEnd()) {
+            // go read the next address.  If we had an address, add to the list.
+            // an address ITEM cannot be NIL inside the parens.
+            InternetAddress address = readAddress();
+            addresses.add(address);
+        }
+        // we need to skip over the peeked token.
+        checkRightParen();
+        return (InternetAddress[])addresses.toArray(new InternetAddress[addresses.size()]);
+    }
+
+
+    /**
+     * Check to see if we're at the end of a parenthized list
+     * without advancing the parsing pointer.  If we are at the
+     * end, then this will step over the closing paren.
+     *
+     * @return True if the next token is a closing list paren, false otherwise.
+     * @exception ResponseFormatException
+     */
+    public boolean checkListEnd() throws MessagingException {
+        Token token = peek(true);
+        if (token.getType() == ')') {
+            // step over this token.
+            next();
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Reads a string item which can be encoded either as a single
+     * string-valued token or a parenthized list of string tokens.
+     *
+     * @return A List containing all of the strings.
+     * @exception ResponseFormatException
+     */
+    public List readStringList() throws MessagingException {
+        Token token = peek(true);
+
+        if (token.getType() == '(') {
+            List list = new ArrayList();
+
+            next();
+
+            while (notListEnd()) {
+                String value = readString();
+                // this can be NIL, technically
+                if (value != null) {
+                    list.add(value);
+                }
+            }
+            // step over the closing paren
+            next();
+
+            return list;
+        }
+        else if (token != NIL) {
+            List list = new ArrayList();
+
+            // just a single string value.
+            String value = readString();
+            // this can be NIL, technically
+            if (value != null) {
+                list.add(value);
+            }
+
+            return list;
+        } else {
+            next();
+        }
+        return null;
+    }
+
+
+    /**
+     * Reads all remaining tokens and returns them as a list of strings.
+     * NIL values are not supported.
+     *
+     * @return A List containing all of the strings.
+     * @exception ResponseFormatException
+     */
+    public List readStrings() throws MessagingException {
+        List list = new ArrayList();
+
+        while (hasMore()) {
+            String value = readString();
+            list.add(value);
+        }
+        return list;
+    }
+
+
+    /**
+     * Skip over an extension item.  This may be either a string
+     * token or a parenthized item (with potential nesting).
+     *
+     * At the point where this is called, we're looking for a closing
+     * ')', but we know it is not that.  An EOF is an error, however,
+     */
+    public void skipExtensionItem() throws MessagingException {
+        Token token = next();
+        int type = token.getType();
+
+        // list form?  Scan to find the correct list closure.
+        if (type == '(') {
+            skipNestedValue();
+        }
+        // found an EOF?  Big problem
+        else if (type == Token.EOF) {
+            throw new ResponseFormatException("Missing ')'");
+        }
+    }
+
+    /**
+     * Skip over a parenthized value that we're not interested in.
+     * These lists may contain nested sublists, so we need to
+     * handle the nesting properly.
+     */
+    public void skipNestedValue() throws MessagingException {
+        Token token = next();
+
+        while (true) {
+            int type = token.getType();
+            // list terminator?
+            if (type == ')') {
+                return;
+            }
+            // unexpected end of the tokens.
+            else if (type == Token.EOF) {
+                throw new ResponseFormatException("Missing ')'");
+            }
+            // encountered a nested list?
+            else if (type == '(') {
+                // recurse and finish this list.
+                skipNestedValue();
+            }
+            // we're just skipping the token.
+            token = next();
+        }
+    }
+
+    /**
+     * Get the next token and verify that it's of the expected type
+     * for the context.
+     *
+     * @param type   The type of token we're expecting.
+     */
+    public void checkToken(int type) throws MessagingException {
+        Token token = next();
+        if (token.getType() != type) {
+            throw new ResponseFormatException("Unexpected token: " + token.getValue());
+        }
+    }
+
+
+    /**
+     * Read the next token as binary data.  The next token can be a literal, a quoted string, or
+     * the token NIL (which returns a null result).  Any other token throws a ResponseFormatException.
+     *
+     * @return A byte array representing the rest of the response data.
+     */
+    public byte[] readByteArray() throws MessagingException {
+        return readData(true);
+    }
+
+
+    /**
+     * Determine what type of token encoding needs to be
+     * used for a string value.
+     *
+     * @param value  The string to test.
+     *
+     * @return Either Token.ATOM, Token.QUOTEDSTRING, or
+     *         Token.LITERAL, depending on the characters contained
+     *         in the value.
+     */
+    static public int getEncoding(byte[] value) {
+
+        // a null string always needs to be represented as a quoted literal.
+        if (value.length == 0) {
+            return Token.QUOTEDSTRING;
+        }
+
+        for (int i = 0; i < value.length; i++) {
+            int ch = value[i];
+            // make sure the sign extension is eliminated
+            ch = ch & 0xff;
+            // check first for any characters that would
+            // disqualify a quoted string
+            // NULL
+            if (ch == 0x00) {
+                return Token.LITERAL;
+            }
+            // non-7bit ASCII
+            if (ch > 0x7F) {
+                return Token.LITERAL;
+            }
+            // carriage return
+            if (ch == '\r') {
+                return Token.LITERAL;
+            }
+            // linefeed
+            if (ch == '\n') {
+                return Token.LITERAL;
+            }
+            // now check for ATOM disqualifiers
+            if (atomDelimiters.indexOf(ch) != -1) {
+                return Token.QUOTEDSTRING;
+            }
+            // CTL character.  We've already eliminated the high characters
+            if (ch < 0x20) {
+                return Token.QUOTEDSTRING;
+            }
+        }
+        // this can be an ATOM token
+        return Token.ATOM;
+    }
+
+
+    /**
+     * Read a ContentType or ContentDisposition parameter
+     * list from an IMAP command response.
+     *
+     * @return A ParameterList instance containing the parameters.
+     * @exception MessagingException
+     */
+    public ParameterList readParameterList() throws MessagingException {
+        ParameterList params = new ParameterList();
+
+        // read the tokens, taking NIL into account.
+        Token token = next(true, false);
+
+        // just return an empty list if this is NIL
+        if (token.isType(token.NIL)) {
+            return params;
+        }
+
+        // these are pairs of strings for each parameter value
+        while (notListEnd()) {
+            String name = readString();
+            String value = readString();
+            params.set(name, value);
+        }
+        // we need to consume the list terminator
+        checkRightParen();
+        return params;
+    }
+
+
+    /**
+     * Test if we have more data in the response buffer.
+     *
+     * @return true if there are more tokens to process.  false if
+     *         we've reached the end of the stream.
+     */
+    public boolean hasMore() throws MessagingException {
+        // we need to eat any white space that might be in the stream.
+        eatWhiteSpace();
+        return pos < response.length;
+    }
+
+
+    /**
+     * Tests if we've reached the end of a parenthetical
+     * list in our parsing stream.
+     *
+     * @return true if the next token will be a ')'.  false if the
+     *         next token is anything else.
+     * @exception MessagingException
+     */
+    public boolean notListEnd() throws MessagingException {
+        return peek().getType() != ')';
+    }
+
+    /**
+     * Read a list of Flag values from an IMAP response,
+     * returning a Flags instance containing the appropriate
+     * pieces.
+     *
+     * @return A Flags instance with the flag values.
+     * @exception MessagingException
+     */
+    public Flags readFlagList() throws MessagingException {
+        Flags flags = new Flags();
+
+        // this should be a list here
+        checkLeftParen();
+
+        // run through the flag list
+        while (notListEnd()) {
+            // the flags are a bit of a pain.  The flag names include "\" in the name, which
+            // is not a character allowed in an atom.  This requires a bit of customized parsing
+            // to handle this.
+            Token token = next();
+            // flags can be specified as just atom tokens, so allow this as a user flag.
+            if (token.isType(token.ATOM)) {
+                // append the atom as a raw name
+                flags.add(token.getValue());
+            }
+            // all of the system flags start with a '\' followed by
+            // an atom.  They also can be extension flags.  IMAP has a special
+            // case of "\*" that we need to check for.
+            else if (token.isType('\\')) {
+                token = next();
+                // the next token is the real bit we need to process.
+                if (token.isType('*')) {
+                    // this indicates USER flags are allowed.
+                    flags.add(Flags.Flag.USER);
+                }
+                // if this is an atom name, handle as a system flag
+                else if (token.isType(Token.ATOM)) {
+                    String name = token.getValue();
+                    if (name.equalsIgnoreCase("Seen")) {
+                        flags.add(Flags.Flag.SEEN);
+                    }
+                    else if (name.equalsIgnoreCase("RECENT")) {
+                        flags.add(Flags.Flag.RECENT);
+                    }
+                    else if (name.equalsIgnoreCase("DELETED")) {
+                        flags.add(Flags.Flag.DELETED);
+                    }
+                    else if (name.equalsIgnoreCase("ANSWERED")) {
+                        flags.add(Flags.Flag.ANSWERED);
+                    }
+                    else if (name.equalsIgnoreCase("DRAFT")) {
+                        flags.add(Flags.Flag.DRAFT);
+                    }
+                    else if (name.equalsIgnoreCase("FLAGGED")) {
+                        flags.add(Flags.Flag.FLAGGED);
+                    }
+                    else {
+                        // this is a server defined flag....just add the name with the
+                        // flag thingy prepended.
+                        flags.add("\\" + name);
+                    }
+                }
+                else {
+                    throw new MessagingException("Invalid Flag: " + token.getValue());
+                }
+            }
+            else {
+                throw new MessagingException("Invalid Flag: " + token.getValue());
+            }
+        }
+
+        // step over this for good practice.
+        checkRightParen();
+
+        return flags;
+    }
+
+
+    /**
+     * Read a list of Flag values from an IMAP response,
+     * returning a Flags instance containing the appropriate
+     * pieces.
+     *
+     * @return A Flags instance with the flag values.
+     * @exception MessagingException
+     */
+    public List readSystemNameList() throws MessagingException {
+        List flags = new ArrayList();
+
+        // this should be a list here
+        checkLeftParen();
+
+        // run through the flag list
+        while (notListEnd()) {
+            // the flags are a bit of a pain.  The flag names include "\" in the name, which
+            // is not a character allowed in an atom.  This requires a bit of customized parsing
+            // to handle this.
+            Token token = next();
+            // all of the system flags start with a '\' followed by
+            // an atom.  They also can be extension flags.  IMAP has a special
+            // case of "\*" that we need to check for.
+            if (token.isType('\\')) {
+                token = next();
+                // if this is an atom name, handle as a system flag
+                if (token.isType(Token.ATOM)) {
+                    // add the token value to the list WITH the
+                    // flag indicator included.  The attributes method returns
+                    // these flag indicators, so we need to include it.
+                    flags.add("\\" + token.getValue());
+                }
+                else {
+                    throw new MessagingException("Invalid Flag: " + token.getValue());
+                }
+            }
+            else {
+                throw new MessagingException("Invalid Flag: " + token.getValue());
+            }
+        }
+
+        // step over this for good practice.
+        checkRightParen();
+
+        return flags;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
new file mode 100644
index 0000000..abeaf9c
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
@@ -0,0 +1,69 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Formats ths date in the form used by the javamail IMAP SEARCH command, 
+ * <p/>
+ * The format used is <code>d MMM yyyy</code> and  locale is always US-ASCII.
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPSearchDateFormat extends SimpleDateFormat {
+    public IMAPSearchDateFormat() {
+        super("dd-MMM-yyyy", Locale.US);
+    }
+    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) {
+        StringBuffer result = super.format(date, buffer, position);
+        // The RFC 2060 requires that the day in the date be formatted with either 2 digits
+        // or one digit.  Our format specifies 2 digits, which pads with leading
+        // zeros.  We need to check for this and whack it if it's there
+        if (result.charAt(0) == '0') {
+            result.deleteCharAt(0); 
+        }
+        return result;
+    }
+
+    /**
+     * The calendar cannot be set
+     * @param calendar
+     * @throws UnsupportedOperationException
+     */
+    public void setCalendar(Calendar calendar) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The format cannot be set
+     * @param format
+     * @throws UnsupportedOperationException
+     */
+    public void setNumberFormat(NumberFormat format) {
+        throw new UnsupportedOperationException();
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
new file mode 100644
index 0000000..1afeb84
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
@@ -0,0 +1,53 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPSearchResponse extends IMAPUntaggedResponse {
+    public int[] messageNumbers; 
+    
+    public IMAPSearchResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("SEARCH",  data); 
+        
+        Token token = source.next(); 
+        List tokens = new ArrayList();
+        
+        // just accumulate the list of tokens first 
+        while (token.getType() != Token.EOF) {
+            tokens.add(token); 
+            token = source.next(); 
+        }
+        
+        messageNumbers = new int[tokens.size()]; 
+        
+        // now parse these into numbers 
+        for (int i = 0; i < messageNumbers.length; i++) {
+            token = (Token)tokens.get(i); 
+            messageNumbers[i] = token.getInteger(); 
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
new file mode 100644
index 0000000..60a3141
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
@@ -0,0 +1,50 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPServerStatusResponse extends IMAPUntaggedResponse {
+    // any message following the response 
+    protected String message; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPServerStatusResponse(String keyword, String message, byte [] response) {
+        super(keyword, response); 
+        this.message = message; 
+    }
+    
+    /**
+     * Get any trailing message associated with this 
+     * status response. 
+     * 
+     * @return 
+     */
+    public String getMessage() {
+        return message; 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
new file mode 100644
index 0000000..e2d3a41
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
@@ -0,0 +1,50 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a server size response.
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPSizeResponse extends IMAPUntaggedResponse {
+    // the associated size 
+    protected int size; 
+
+    /**
+     * Create a size response item.
+     * 
+     * @param keyword  The KEYWORD item associated with the size.
+     * @param size     The size value.
+     * @param response The raw response data.
+     */
+    public IMAPSizeResponse(String keyword, int size, byte [] response) {
+        super(keyword, response); 
+        this.size = size; 
+    }
+    
+    public int getSize() {
+        return size; 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
new file mode 100644
index 0000000..053a2db
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
@@ -0,0 +1,82 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPStatusResponse extends IMAPUntaggedResponse {
+    // the mail box name 
+    public String mailbox; 
+    // number of messages in the box
+    public int messages = -1;
+    // number of recent messages 
+    public int recentMessages = -1; 
+    // the number of unseen messages
+    public int unseenMessages = -1;
+    // the next UID for this mailbox
+    public long uidNext = -1L;
+    // the UID validity item
+    public long uidValidity = -1L;
+
+    public IMAPStatusResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("STATUS",  data); 
+        
+        // the mail box name is supposed to be encoded, so decode it now.
+        mailbox = source.readEncodedString();
+
+        // parse the list of flag values
+        List flags = source.readStringList();
+        if (flags == null) {
+            return;
+        }
+
+        for (int i = 0; i < flags.size(); i += 2) {
+            String field = ((String)flags.get(i)).toUpperCase();
+            String stringValue = ((String)flags.get(i + 1)); 
+            long value; 
+            try {
+                value = Long.parseLong(stringValue); 
+            } catch (NumberFormatException e) {
+                throw new MessagingException("Invalid IMAP Status response", e); 
+            }
+                
+
+            if (field.equals("MESSAGES")) {
+                messages = (int)value; 
+            }
+            else if (field.equals("RECENT")) {
+                recentMessages = (int)value;
+            }
+            else if (field.equals("UIDNEXT")) {
+                uidNext = value;
+            }
+            else if (field.equals("UIDVALIDITY")) {
+                uidValidity = value; 
+            }
+            else if (field.equals("UNSEEN")) {
+                unseenMessages = (int)value; 
+            }
+        }
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
new file mode 100644
index 0000000..a31eb89
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
@@ -0,0 +1,161 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.mail.util.Base64;
+
+/**
+ * Util class to represent a response from a IMAP server
+ *
+ * @version $Rev: 1633281 $ $Date: 2014-10-21 02:29:50 -0400 (Tue, 21 Oct 2014) $
+ */
+public class IMAPTaggedResponse extends IMAPResponse {
+
+    // the reply state
+    protected String status;
+    // the tag associated with a reply.
+    protected String tag;
+    // the message associated with the completion response 
+    protected String message;
+
+    /**
+     * Create a command completion response for a 
+     * submitted command.  The tag prefix identifies 
+     * the command this response is for. 
+     * 
+     * @param tag      The command tag value.
+     * @param status   The Status response (OK, BAD, or NO).
+     * @param message  The remainder of the response, as a string.
+     * @param response The response data used to create the reply object.
+     */
+    public IMAPTaggedResponse(String tag, String status, String message, byte [] response) {
+        super(response); 
+        this.tag = tag; 
+        this.status = status;
+        this.message = message; 
+    }
+
+
+    /**
+     * Create a continuation response for a 
+     * submitted command.  
+     * 
+     * @param response The response data used to create the reply object.
+     */
+    public IMAPTaggedResponse(byte [] response) {
+        super(response); 
+        this.tag = "";  
+        this.status = "CONTINUATION";
+        this.message = message; 
+    }
+
+    /**
+     * Test if the response code was "OK".
+     *
+     * @return True if the response status was OK, false for any other status.
+     */
+    public boolean isOK() {
+        return status.equals("OK");
+    }
+
+    /**
+     * Test for an error return from a command.
+     *
+     * @return True if the response status was BAD.
+     */
+    public boolean isBAD() {
+        return status.equals("BAD"); 
+    }
+
+    /**
+     * Test for an error return from a command.
+     *
+     * @return True if the response status was NO.
+     */
+    public boolean isNO() {
+        return status.equals("NO"); 
+    }
+    
+    /**
+     * Get the message included on the tagged response. 
+     * 
+     * @return The String message data. 
+     */
+    public String getMessage() {
+        return message; 
+    }
+    
+    /**
+     * Decode the message portion of a continuation challenge response.
+     * 
+     * @return The byte array containing the decoded data. 
+     */
+    public byte[] decodeChallengeResponse() 
+    {
+        // we're passed back a challenge value, Base64 encoded.  Decode that portion of the 
+        // response data. 
+    	
+    	//handle plain authentication gracefully, see GERONIMO-6526
+    	if(response.length <= 2){
+    		return null;
+    	}
+    	
+        return Base64.decode(response, 2, response.length - 2);
+    }
+    
+    
+    /**
+     * Test if this is a continuation response. 
+     * 
+     * @return True if this a continuation.  false for a normal tagged response. 
+     */
+    public boolean isContinuation() {
+        return status.equals("CONTINUATION"); 
+    }
+    
+    
+    /**
+     * Test if the untagged response includes a given 
+     * status indicator.  Mostly used for checking 
+     * READ-ONLY or READ-WRITE status after selecting a 
+     * mail box.
+     * 
+     * @param name   The status name to check.
+     * 
+     * @return true if this is found in the "[" "]" delimited
+     *         section of the response message.
+     */
+    public boolean hasStatus(String name) {
+        // see if we have the status bits at all 
+        int statusStart = message.indexOf('['); 
+        if (statusStart == -1) {
+            return false; 
+        }
+        
+        int statusEnd = message.indexOf(']'); 
+        String statusString = message.substring(statusStart, statusEnd).toUpperCase(); 
+        // just search for the status token. 
+        return statusString.indexOf(name) != -1; 
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
new file mode 100644
index 0000000..45137ee
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
@@ -0,0 +1,36 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPUid extends IMAPFetchDataItem {
+    // the returned uid
+    public long uid;
+    // the returned sequence number for the message 
+    public int messageNumber; 
+
+    public IMAPUid(int messageNumber, IMAPResponseTokenizer source) throws MessagingException {
+        super(UID);
+        // just read the number pairs 
+        this.messageNumber = messageNumber;
+        uid = source.readLong();
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
new file mode 100644
index 0000000..8674f3a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
@@ -0,0 +1,67 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev: 594520 $ $Date: 2007-11-13 07:57:39 -0500 (Tue, 13 Nov 2007) $
+ */
+public class IMAPUntaggedResponse extends IMAPResponse {
+    // the response key word 
+    protected String keyword; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPUntaggedResponse(String keyword, byte [] response) {
+        super(response); 
+        this.keyword = keyword; 
+    }
+
+    /**
+     * Return the KEYWORD that identifies the type 
+     * of this untagged response.
+     * 
+     * @return The identifying keyword.
+     */
+    public String getKeyword() {
+        return keyword; 
+    }
+    
+    
+    /**
+     * Test if an untagged response is of a given 
+     * keyword type.
+     * 
+     * @param keyword The test keyword.
+     * 
+     * @return True if this is a type match, false for mismatches.
+     */
+    public boolean isKeyword(String keyword) {
+        return this.keyword.equals(keyword); 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
new file mode 100644
index 0000000..1a6812a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
@@ -0,0 +1,34 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.imap.connection;
+
+public interface IMAPUntaggedResponseHandler {
+    /**
+     * Handle an unsolicited untagged response receive back from a command.  This 
+     * will be any responses left over after the command has cherry picked the 
+     * bits that are relevent to the command just issued.  It is important 
+     * that the unsolicited response be reacted to in order to keep the message 
+     * caches in sync. 
+     * 
+     * @param response The response to handle.
+     * 
+     * @return true if the handle took care of the response and it should not be sent 
+     *         to additional handlers.  false if broadcasting of the response should continue.
+     */
+    public boolean handleResponse(IMAPUntaggedResponse response);
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java
new file mode 100644
index 0000000..a38d0a1
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java
@@ -0,0 +1,449 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.IllegalWriteException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Session;
+import javax.mail.event.ConnectionEvent;
+
+import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
+
+/**
+ * The base NNTP implementation of the javax.mail.Folder This is a base class
+ * for both the Root NNTP server and each NNTP group folder.
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 437941 $
+ */
+public class NNTPFolder extends Folder {
+
+    // our active connection.
+    protected NNTPConnection connection;
+
+    // our attached session
+    protected Session session;
+
+    // the name of this folder (either the name of the server for the root or
+    // the news group name).
+    protected String name;
+
+    // the "full" name of the folder. For the root folder, this is the name
+    // returned by the connection
+    // welcome string. Otherwise, this is the same as the name.
+    protected String fullName;
+
+    // the parent folder. For the root folder, this is null. For a group folder,
+    // this is the root.
+    protected Folder parent;
+
+    // the folder open state
+    protected boolean folderOpen = false;
+
+    // the folder message count. For the root folder, this is always 0.
+    protected int messageCount = 0;
+
+    // the persistent flags we save in the store (basically just the SEEN flag).
+    protected Flags permanentFlags;
+
+    /**
+     * Super class constructor the base NNTPFolder class.
+     * 
+     * @param store
+     *            The javamail store this folder is attached to.
+     */
+    protected NNTPFolder(NNTPStore store) {
+        super(store);
+        // get the active connection from the store...all commands are sent
+        // there
+        this.connection = store.getConnection();
+        this.session = store.getSession();
+
+        // set up our permanent flags bit.
+        permanentFlags = new Flags();
+        permanentFlags.add(Flags.Flag.SEEN);
+    }
+
+    /**
+     * Retrieve the folder name.
+     * 
+     * @return The folder's name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Retrieve the folder's full name (including hierarchy information). NNTP
+     * folders are flat, so the full name is generally the same as the name.
+     * 
+     * @return The full name value.
+     */
+    public String getFullName() {
+        return fullName;
+    }
+
+    /**
+     * Returns the parent folder for this folder. Returns null if this is the
+     * root folder.
+     */
+    public Folder getParent() throws MessagingException {
+        return parent;
+    }
+
+    /**
+     * Indicated whether the folder "exists" or not. Existance in this context
+     * indicates that the group still exists on the server.
+     * 
+     * @return
+     * @exception MessagingException
+     */
+    public boolean exists() throws MessagingException {
+        // by default, return true. This is really only the case for the root.
+        // The group folder will
+        // need to override this.
+        return true;
+    }
+
+    /**
+     * List the subfolders. For group folders, this is a meaningless so we throw
+     * a MethodNotSupportedException.
+     * 
+     * @param pattern
+     *            The folder pattern string.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public Folder[] list(String pattern) throws MessagingException {
+        throw new MethodNotSupportedException("NNTP group folders cannot contain sub folders");
+    }
+
+    /**
+     * Retrieve the list of subscribed folders that match the given pattern
+     * string.
+     * 
+     * @param pattern
+     *            The pattern string used for the matching
+     * 
+     * @return An array of matching folders from the subscribed list.
+     */
+    public Folder[] listSubscribed(String pattern) throws MessagingException {
+        throw new MethodNotSupportedException("NNTP group folders cannot contain sub folders");
+    }
+
+    /**
+     * No sub folders, hence there is no notion of a seperator. We return a null
+     * character (consistent with what Sun returns for POP3 folders).
+     */
+    public char getSeparator() throws MessagingException {
+        return '\0';
+    }
+
+    /**
+     * Return whether this folder can hold just messages or also subfolders.
+     * Only the root folder can hold other folders, so it will need to override.
+     * 
+     * @return Either Folder.HOLDS_MESSAGES or Folder.HOLDS_FOLDERS.
+     * @exception MessagingException
+     */
+    public int getType() throws MessagingException {
+        return HOLDS_MESSAGES;
+    }
+
+    /**
+     * Create a new folder. NNTP folders are read only, so this is a nop.
+     * 
+     * @param type
+     *            The type of folder.
+     * 
+     * @return Not support, throws an exception.
+     * @exception MessagingException
+     */
+    public boolean create(int type) throws MessagingException {
+        throw new MethodNotSupportedException("Sub folders cannot be created in NNTP");
+    }
+
+    /**
+     * Check for new messages. We always return false for the root folder. The
+     * group folders will need to override.
+     * 
+     * @return Always returns false.
+     * @exception MessagingException
+     */
+    public boolean hasNewMessages() throws MessagingException {
+        return false;
+    }
+
+    /**
+     * Get a named subfolder from this folder. This only has meaning from the
+     * root NNTP folder.
+     * 
+     * @param name
+     *            The requested name.
+     * 
+     * @return If the folder exists, returns a Folder object representing the
+     *         named folder.
+     * @exception MessagingException
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        throw new MethodNotSupportedException("NNTP Group folders do not support sub folders");
+    }
+
+    /**
+     * Delete a folder. This is not supported for NNTP.
+     * 
+     * @param recurse
+     *            The recusion flag.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public boolean delete(boolean recurse) throws MessagingException {
+        throw new MethodNotSupportedException("Deleting of NNTP folders is not supported");
+    }
+
+    /**
+     * Rename a folder. Not supported for NNTP folders.
+     * 
+     * @param f
+     *            The new folder specifying the rename location.
+     * 
+     * @return
+     * @exception MessagingException
+     */
+    public boolean renameTo(Folder f) throws MessagingException {
+        throw new MethodNotSupportedException("Renaming of NNTP folders is not supported.");
+    }
+
+    /**
+     * @see javax.mail.Folder#open(int)
+     */
+    public void open(int mode) throws MessagingException {
+
+        // we don't support READ_WRITE mode, so don't allow opening in that
+        // mode.
+        if (mode == READ_WRITE) {
+            throw new IllegalWriteException("Newsgroup folders cannot be opened read/write");
+        }
+
+        // an only be performed on a closed folder
+        checkClosed();
+
+        this.mode = mode;
+
+        // perform folder type-specific open actions.
+        openFolder();
+
+        folderOpen = true;
+
+        notifyConnectionListeners(ConnectionEvent.OPENED);
+    }
+
+    /**
+     * Perform folder type-specific open actions. The default action is to do
+     * nothing.
+     * 
+     * @exception MessagingException
+     */
+    protected void openFolder() throws MessagingException {
+    }
+
+    /**
+     * Peform folder type-specific close actions. The default action is to do
+     * nothing.
+     * 
+     * @exception MessagingException
+     */
+    protected void closeFolder() throws MessagingException {
+    }
+
+    /**
+     * Close the folder. Cleans up resources, potentially expunges messages
+     * marked for deletion, and sends an event notification.
+     * 
+     * @param expunge
+     *            The expunge flag, which is ignored for NNTP folders.
+     * 
+     * @exception MessagingException
+     */
+    public void close(boolean expunge) throws MessagingException {
+        // Can only be performed on an open folder
+        checkOpen();
+
+        // give the subclasses an opportunity to do some cleanup
+        closeFolder();
+
+        folderOpen = false;
+        notifyConnectionListeners(ConnectionEvent.CLOSED);
+    }
+
+    /**
+     * Tests the open status of the folder.
+     * 
+     * @return true if the folder is open, false otherwise.
+     */
+    public boolean isOpen() {
+        return folderOpen;
+    }
+
+    /**
+     * Get the permanentFlags
+     * 
+     * @return The set of permanent flags we support (only SEEN).
+     */
+    public Flags getPermanentFlags() {
+        // we need a copy of our master set.
+        return new Flags(permanentFlags);
+    }
+
+    /**
+     * Get the count of messages in this folder.
+     * 
+     * @return The message count.
+     * @exception MessagingException
+     */
+    public int getMessageCount() throws MessagingException {
+        return messageCount;
+    }
+
+    /**
+     * Checks wether the message is in cache, if not will create a new message
+     * object and return it.
+     * 
+     * @see javax.mail.Folder#getMessage(int)
+     */
+    public Message getMessage(int msgNum) throws MessagingException {
+        // for the base, we just throw an exception.
+        throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
+    }
+
+    /**
+     * Append messages to a folder. NNTP folders are read only, so this is not
+     * supported.
+     * 
+     * @param msgs
+     *            The list of messages to append.
+     * 
+     * @exception MessagingException
+     */
+    public void appendMessages(Message[] msgs) throws MessagingException {
+        throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
+
+    }
+
+    /**
+     * Expunge messages marked for deletion and return a list of the Messages.
+     * Not supported for NNTP.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public Message[] expunge() throws MessagingException {
+        throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
+    }
+
+    /**
+     * Below is a list of convenience methods that avoid repeated checking for a
+     * value and throwing an exception
+     */
+
+    /** Ensure the folder is open */
+    protected void checkOpen() throws IllegalStateException {
+        if (!folderOpen) {
+            throw new IllegalStateException("Folder is not Open");
+        }
+    }
+
+    /** Ensure the folder is not open */
+    protected void checkClosed() throws IllegalStateException {
+        if (folderOpen) {
+            throw new IllegalStateException("Folder is Open");
+        }
+    }
+
+    /**
+     * @see javax.mail.Folder#notifyMessageChangedListeners(int,
+     *      javax.mail.Message)
+     * 
+     * this method is protected and cannot be used outside of Folder, therefore
+     * had to explicitly expose it via a method in NNTPFolder, so that
+     * NNTPMessage has access to it
+     * 
+     * Bad design on the part of the Java Mail API.
+     */
+    public void notifyMessageChangedListeners(int type, Message m) {
+        super.notifyMessageChangedListeners(type, m);
+    }
+
+    /**
+     * Retrieve the subscribed status for a folder. This default implementation
+     * just returns false (which is true for the root folder).
+     * 
+     * @return Always returns true.
+     */
+    public boolean isSubscribed() {
+        return false;
+    }
+
+    /**
+     * Set the subscribed status for a folder.
+     * 
+     * @param flag
+     *            The new subscribed status.
+     * 
+     * @exception MessagingException
+     */
+    public void setSubscribed(boolean flag) throws MessagingException {
+        throw new MessagingException("Root NNTP folder cannot be subscribed to");
+    }
+
+    /**
+     * Test if a given article number is marked as SEEN.
+     * 
+     * @param article
+     *            The target article number.
+     * 
+     * @return The articles current seen status.
+     */
+    public boolean isSeen(int article) {
+        return false;
+    }
+
+    /**
+     * Set the SEEN status for an article.
+     * 
+     * @param article
+     *            The target article.
+     * @param flag
+     *            The new seen setting.
+     * 
+     * @exception MessagingException
+     */
+    public void setSeen(int article, boolean flag) throws MessagingException {
+        throw new MessagingException("Root NNTP folder does not contain articles");
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java
new file mode 100644
index 0000000..bb24800
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java
@@ -0,0 +1,391 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.mail.FetchProfile;
+import javax.mail.FolderNotFoundException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
+import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
+
+/**
+ * The NNTP implementation of the javax.mail.Folder Note that only INBOX is
+ * supported in NNTP
+ * <p>
+ * <url>http://www.faqs.org/rfcs/rfc1939.html</url>
+ * </p>
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 686231 $ $Date: 2008-08-15 10:24:20 -0400 (Fri, 15 Aug 2008) $
+ */
+public class NNTPGroupFolder extends NNTPFolder {
+
+    // holders for status information returned by the GROUP command.
+    protected int firstArticle = -1;
+
+    protected int lastArticle = -1;
+
+    // retrieved articles, mapped by article number.
+    Map articles;
+
+    // information stored in the newsrc group.
+    NNTPNewsrcGroup groupInfo;
+
+    /**
+     * Construct a "real" folder representing an NNTP news group.
+     * 
+     * @param parent
+     *            The parent root folder.
+     * @param store
+     *            The Store this folder is attached to.
+     * @param name
+     *            The folder name.
+     * @param groupInfo
+     *            The newsrc group information attached to the newsrc database.
+     *            This contains subscription and article "SEEN" information.
+     */
+    protected NNTPGroupFolder(NNTPRootFolder parent, NNTPStore store, String name, NNTPNewsrcGroup groupInfo) {
+        super(store);
+        // the name and the full name are the same.
+        this.name = name;
+        this.fullName = name;
+        // set the parent appropriately.
+        this.parent = parent = parent;
+        this.groupInfo = groupInfo;
+    }
+
+    /**
+     * Ping the server and update the group count, first, and last information.
+     * 
+     * @exception MessagingException
+     */
+    private void updateGroupStats() throws MessagingException {
+        // ask the server for information about the group. This is a one-line
+        // reponse with status on
+        // the group, if it exists.
+        NNTPReply reply = connection.sendCommand("GROUP " + name);
+
+        // explicitly not there?
+        if (reply.getCode() == NNTPReply.NO_SUCH_NEWSGROUP) {
+            throw new FolderNotFoundException(this, "Folder does not exist on server: " + reply);
+        } else if (reply.getCode() != NNTPReply.GROUP_SELECTED) {
+            throw new MessagingException("Error requesting group information: " + reply);
+        }
+
+        // we've gotten back a good response, now parse out the group specifics
+        // from the
+        // status response.
+
+        StringTokenizer tokenizer = new StringTokenizer(reply.getMessage());
+
+        // we should have a least 3 tokens here, in the order "count first
+        // last".
+
+        // article count
+        if (tokenizer.hasMoreTokens()) {
+            String count = tokenizer.nextToken();
+            try {
+                messageCount = Integer.parseInt(count);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        // first article number
+        if (tokenizer.hasMoreTokens()) {
+            String first = tokenizer.nextToken();
+            try {
+                firstArticle = Integer.parseInt(first);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        // last article number.
+        if (tokenizer.hasMoreTokens()) {
+            String last = tokenizer.nextToken();
+            try {
+                lastArticle = Integer.parseInt(last);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Test to see if this folder actually exists. This pings the server for
+     * information about the GROUP and updates the article count and index
+     * information.
+     * 
+     * @return true if the newsgroup exists on the server, false otherwise.
+     * @exception MessagingException
+     */
+    public boolean exists() throws MessagingException {
+
+        try {
+            // update the group statistics. If the folder doesn't exist, we'll
+            // get an exception that we
+            // can turn into a false reply.
+            updateGroupStats();
+            // updated ok, so it must be there.
+            return true;
+        } catch (FolderNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Ping the NNTP server to check if a newsgroup has any new messages.
+     * 
+     * @return True if the server has new articles from the last time we
+     *         checked. Also returns true if this is the first time we've
+     *         checked.
+     * @exception MessagingException
+     */
+    public boolean hasNewMessages() throws MessagingException {
+        int oldLast = lastArticle;
+        updateGroupStats();
+
+        return lastArticle > oldLast;
+    }
+
+    /**
+     * Open the folder for use. This retrieves article count information from
+     * the server.
+     * 
+     * @exception MessagingException
+     */
+    protected void openFolder() throws MessagingException {
+        // update the group specifics, especially the message count.
+        updateGroupStats();
+
+        // get a cache for retrieved articles
+        articles = new HashMap();
+    }
+
+    /**
+     * Close the folder, which also clears out the article caches.
+     * 
+     * @exception MessagingException
+     */
+    public void closeFolder() throws MessagingException {
+        // get ride of any retrieve articles, and flip over the open for
+        // business sign.
+        articles = null;
+    }
+
+    /**
+     * Checks wether the message is in cache, if not will create a new message
+     * object and return it.
+     * 
+     * @see javax.mail.Folder#getMessage(int)
+     */
+    public Message getMessage(int msgNum) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+
+        // get an object form to look up in the retrieve messages list (oh how I
+        // wish there was
+        // something like Map that could use integer keys directly!).
+        Integer key = new Integer(msgNum);
+        NNTPMessage message = (NNTPMessage) articles.get(key);
+        if (message != null) {
+            // piece of cake!
+            return message;
+        }
+
+        // we need to suck a message down from the server.
+        // but first, make sure the group is still valid.
+        updateGroupStats();
+
+        // just send a STAT command to this message. Right now, all we want is
+        // existance proof. We'll
+        // retrieve the other bits when requested.
+        NNTPReply reply = connection.sendCommand("STAT " + Integer.toString(msgNum));
+        if (reply.getCode() != NNTPReply.REQUEST_TEXT_SEPARATELY) {
+            throw new MessagingException("Error retrieving article from NNTP server: " + reply);
+        }
+
+        // we need to parse out the message id.
+        String response = reply.getMessage();
+
+        int idStart = response.indexOf('<');
+        int idEnd = response.indexOf('>');
+
+        // NB:  The "<" and ">" delimiters are required elements of the message id, not just 
+        // delimiters for the sake of the command.  We need to keep these around 
+        message = new NNTPMessage(this, (NNTPStore) store, msgNum, response.substring(idStart, idEnd + 1));
+
+        // add this to the article cache.
+        articles.put(key, message);
+
+        return message;
+    }
+
+    /**
+     * Retrieve all articles in the group.
+     * 
+     * @return An array of all messages in the group.
+     */
+    public Message[] getMessages() throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        
+        // we're going to try first with XHDR, which will allow us to retrieve
+        // everything in one shot. If that
+        // fails, we'll fall back on issing STAT commands for the entire article
+        // range.
+        NNTPReply reply = connection.sendCommand("XHDR Message-ID " + Integer.toString(firstArticle) + "-"
+                + Integer.toString(lastArticle), NNTPReply.HEAD_FOLLOWS);
+
+        List messages = new ArrayList();
+
+        if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
+            List lines = reply.getData();
+
+            for (int i = 0; i < lines.size(); i++) {
+                String line = (String) lines.get(i);
+
+                try {
+                    int pos = line.indexOf(' ');
+                    int articleID = Integer.parseInt(line.substring(0, pos));
+                    String messageID = line.substring(pos + 1);
+                    Integer key = new Integer(articleID);
+                    // see if we have this message cached, If not, create it.
+                    Message message = (Message)articles.get(key);
+                    if (message == null) {
+                        message = new NNTPMessage(this, (NNTPStore) store, key.intValue(), messageID);
+                        articles.put(key, message);
+                    }
+
+                    messages.add(message);
+
+                } catch (NumberFormatException e) {
+                    // should never happen, but just skip this entry if it does.
+                }
+            }
+        } else {
+            // grumble, we need to stat each article id to see if it
+            // exists....lots of round trips.
+            for (int i = firstArticle; i <= lastArticle; i++) {
+                try {
+                    messages.add(getMessage(i));
+                } catch (MessagingException e) {
+                    // just assume if there is an error, it's because the
+                    // message id doesn't exist.
+                }
+            }
+        }
+
+        return (Message[]) messages.toArray(new Message[0]);
+    }
+
+    /**
+     * @see javax.mail.Folder#fetch(javax.mail.Message[],
+     *      javax.mail.FetchProfile)
+     * 
+     * The JavaMail API recommends that this method be overrident to provide a
+     * meaningfull implementation.
+     */
+    public void fetch(Message[] msgs, FetchProfile fp) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+
+        for (int i = 0; i < msgs.length; i++) {
+            Message msg = msgs[i];
+            // we can only perform this operation for NNTPMessages.
+            if (msg == null || !(msg instanceof NNTPMessage)) {
+                // we can't fetch if it's the wrong message type
+                continue;
+            }
+
+            // fetching both the headers and body?
+            if (fp.contains(FetchProfile.Item.ENVELOPE) && fp.contains(FetchProfile.Item.CONTENT_INFO)) {
+
+                // retrive everything
+                ((NNTPMessage) msg).loadArticle();
+            }
+            // headers only?
+            else if (fp.contains(FetchProfile.Item.ENVELOPE)) {
+                ((NNTPMessage) msg).loadHeaders();
+            } else if (fp.contains(FetchProfile.Item.CONTENT_INFO)) {
+                ((NNTPMessage) msg).loadContent();
+            }
+        }
+    }
+
+    /**
+     * Return the subscription status of this folder.
+     * 
+     * @return true if the folder is marked as subscribed, false for
+     *         unsubscribed.
+     */
+    public boolean isSubscribed() {
+        return groupInfo.isSubscribed();
+    }
+
+    /**
+     * Set or clear the subscription status of a file.
+     * 
+     * @param flag
+     *            The new subscription state.
+     */
+    public void setSubscribed(boolean flag) {
+        groupInfo.setSubscribed(flag);
+    }
+
+    /**
+     * Return the "seen" state for an article in a folder.
+     * 
+     * @param article
+     *            The article number.
+     * 
+     * @return true if the article is marked as seen in the newsrc file, false
+     *         for unseen files.
+     */
+    public boolean isSeen(int article) {
+        return groupInfo.isArticleSeen(article);
+    }
+
+    /**
+     * Set the seen state for an article in a folder.
+     * 
+     * @param article
+     *            The article number.
+     * @param flag
+     *            The new seen state.
+     */
+    public void setSeen(int article, boolean flag) {
+        if (flag) {
+            groupInfo.markArticleSeen(article);
+        } else {
+            groupInfo.markArticleUnseen(article);
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java
new file mode 100644
index 0000000..1e346cc
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java
@@ -0,0 +1,377 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+import javax.mail.Flags;
+import javax.mail.IllegalWriteException;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
+import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
+import org.apache.geronimo.javamail.transport.nntp.StringListInputStream;
+
+/**
+ * NNTP implementation of javax.mail.internet.MimeMessage
+ * 
+ * Only the most basic information is given and Message objects created here is
+ * a light-weight reference to the actual Message As per the JavaMail spec items
+ * from the actual message will get filled up on demand
+ * 
+ * If some other items are obtained from the server as a result of one call,
+ * then the other details are also processed and filled in. For ex if RETR is
+ * called then header information will also be processed in addition to the
+ * content
+ * 
+ * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
+ */
+public class NNTPMessage extends MimeMessage {
+    // the server message identifer
+    String messageID = null;
+
+    // our attached session
+    protected Session session;
+
+    // the Store we're stored in (which manages the connection and other stuff).
+    protected NNTPStore store;
+
+    // our active connection.
+    protected NNTPConnection connection;
+
+    // used to force loading of headers
+    protected boolean headersLoaded = false;
+
+    // use to force content loading
+    protected boolean contentLoaded = false;
+
+    /**
+     * Contruct an NNTPMessage instance.
+     * 
+     * @param folder
+     *            The hosting folder for the message.
+     * @param store
+     *            The Store owning the article (and folder).
+     * @param msgnum
+     *            The article message number.
+     * @param messageID
+     *            The article messageID (as assigned by the server).
+     * 
+     * @exception MessagingException
+     */
+    NNTPMessage(NNTPFolder folder, NNTPStore store, int msgnum, String messageID) throws MessagingException {
+        super(folder, msgnum);
+        this.messageID = messageID;
+        this.store = store;
+        this.session = ((NNTPStore) store).getSession();
+        // get the active connection from the store...all commands are sent
+        // there
+        this.connection = ((NNTPStore) store).getConnection();
+
+        // get our flag set from the folder.
+        flags = folder.getPermanentFlags();
+        // now check our initial SEEN state and set the flags appropriately
+        if (folder.isSeen(msgnum)) {
+            flags.add(Flags.Flag.SEEN);
+        } else {
+            flags.remove(Flags.Flag.SEEN);
+        }
+    }
+
+    /**
+     * Retrieve the size of the message content. The content will be retrieved
+     * from the server, if necessary.
+     * 
+     * @return The size of the content.
+     * @exception MessagingException
+     */
+    public int getSize() throws MessagingException {
+        // make sure we've retrieved the message content and continue with the
+        // superclass version.
+        loadContent();
+        return super.getSize();
+    }
+
+    /**
+     * Get a line count for the NNTP message. This is potentially stored in the
+     * Lines article header. If not there, we return a default of -1.
+     * 
+     * @return The header line count estimate, or -1 if not retrieveable.
+     * @exception MessagingException
+     */
+    public int getLineCount() throws MessagingException {
+        String[] headers = getHeader("Lines");
+
+        // hopefully, there's only a single one of these. No sensible way of
+        // interpreting
+        // multiples.
+        if (headers.length == 1) {
+            try {
+                return Integer.parseInt(headers[0].trim());
+
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+        // dunno...and let them know I don't know.
+        return -1;
+    }
+
+    /**
+     * @see javax.mail.internet.MimeMessage#getContentStream()
+     */
+    protected InputStream getContentStream() throws MessagingException {
+        // get the article information.
+        loadArticle();
+        return super.getContentStream();
+    }
+
+    /***************************************************************************
+     * Following is a set of methods that deal with headers These methods are
+     * just overrides on the superclass methods to allow lazy loading of the
+     * header information.
+     **************************************************************************/
+
+    public String[] getHeader(String name) throws MessagingException {
+        loadHeaders();
+        return headers.getHeader(name);
+    }
+
+    public String getHeader(String name, String delimiter) throws MessagingException {
+        loadHeaders();
+        return headers.getHeader(name, delimiter);
+    }
+
+    public Enumeration getAllHeaders() throws MessagingException {
+        loadHeaders();
+        return headers.getAllHeaders();
+    }
+
+    public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getMatchingHeaders(names);
+    }
+
+    public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getNonMatchingHeaders(names);
+    }
+
+    public Enumeration getAllHeaderLines() throws MessagingException {
+        loadHeaders();
+        return headers.getAllHeaderLines();
+    }
+
+    public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getMatchingHeaderLines(names);
+    }
+
+    public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
+        loadHeaders();
+        return headers.getNonMatchingHeaderLines(names);
+    }
+
+    // the following are overrides for header modification methods. These
+    // messages are read only,
+    // so the headers cannot be modified.
+    public void addHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    public void setHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    public void removeHeader(String name) throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    public void addHeaderLine(String line) throws MessagingException {
+        throw new IllegalWriteException("IMAP messages are read-only");
+    }
+
+    /**
+     * We cannot modify these messages
+     */
+    public void saveChanges() throws MessagingException {
+        throw new IllegalWriteException("NNTP messages are read-only");
+    }
+
+    /**
+     * Retrieve the message headers from the NNTP server.
+     * 
+     * @exception MessagingException
+     */
+    public void loadHeaders() throws MessagingException {
+        // don't retrieve if already loaded.
+        if (headersLoaded) {
+            return;
+        }
+
+        NNTPReply reply = connection.sendCommand("HEAD " + messageID, NNTPReply.HEAD_FOLLOWS);
+
+        if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
+            try {
+                // wrap a stream around the reply data and read as headers.
+                updateHeaders(new StringListInputStream(reply.getData()));
+            } catch (IOException e) {
+                throw new MessagingException("Error retrieving article headers from server", e);
+            }
+        } else {
+            throw new MessagingException("Error retrieving article headers from server: " + reply);
+        }
+    }
+
+    /**
+     * Update the message headers from an input stream.
+     * 
+     * @param in
+     *            The InputStream source for the header information.
+     * 
+     * @exception MessagingException
+     */
+    public void updateHeaders(InputStream in) throws MessagingException {
+        // wrap a stream around the reply data and read as headers.
+        headers = new InternetHeaders(in);
+        headersLoaded = true;
+    }
+
+    /**
+     * Load just the message content from the NNTP server.
+     * 
+     * @exception MessagingException
+     */
+    public void loadContent() throws MessagingException {
+        if (contentLoaded) {
+            return;
+        }
+
+        NNTPReply reply = connection.sendCommand("BODY " + messageID, NNTPReply.BODY_FOLLOWS);
+
+        if (reply.getCode() == NNTPReply.BODY_FOLLOWS) {
+            try {
+                InputStream in = new StringListInputStream(reply.getData());
+                updateContent(in);
+            } catch (IOException e) {
+                throw new MessagingException("Error retrieving article body from server", e);
+            }
+        } else {
+            throw new MessagingException("Error retrieving article body from server: " + reply);
+        }
+    }
+
+    /**
+     * Load the entire article from the NNTP server. This updates both the
+     * headers and the content.
+     * 
+     * @exception MessagingException
+     */
+    public void loadArticle() throws MessagingException {
+        // if the headers are already loaded, retrieve the content portion.
+        if (headersLoaded) {
+            loadContent();
+            return;
+        }
+
+        // we need to retrieve everything.
+        NNTPReply reply = connection.sendCommand("ARTICLE " + messageID, NNTPReply.ARTICLE_FOLLOWS);
+
+        if (reply.getCode() == NNTPReply.ARTICLE_FOLLOWS) {
+            try {
+                InputStream in = new StringListInputStream(reply.getData());
+                // update both the headers and the content.
+                updateHeaders(in);
+                updateContent(in);
+            } catch (IOException e) {
+                throw new MessagingException("Error retrieving article from server", e);
+            }
+        } else {
+            throw new MessagingException("Error retrieving article from server: " + reply);
+        }
+    }
+
+    /**
+     * Update the article content from an input stream.
+     * 
+     * @param in
+     *            The content data source.
+     * 
+     * @exception MessagingException
+     */
+    public void updateContent(InputStream in) throws MessagingException {
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            byte[] buffer = new byte[4096];
+
+            // copy the content data from the stream into a byte buffer for the
+            // content.
+            while (true) {
+                int read = in.read(buffer);
+                if (read == -1) {
+                    break;
+                }
+                out.write(buffer, 0, read);
+            }
+
+            content = out.toByteArray();
+            contentLoaded = true;
+        } catch (IOException e) {
+            throw new MessagingException("Error retrieving message body from server", e);
+        }
+    }
+
+    /**
+     * Get the server assigned messageid for the article.
+     * 
+     * @return The server assigned message id.
+     */
+    public String getMessageId() {
+        return messageID;
+    }
+
+    /**
+     * Override of setFlags(). We need to ensure that if the SEEN flag is set or
+     * cleared, that the newsrc file correctly reflects the current state.
+     * 
+     * @param flag
+     *            The flag being set.
+     * @param newvalue
+     *            The new flag value.
+     * 
+     * @exception MessagingException
+     */
+    public void setFlags(Flags flag, boolean newvalue) throws MessagingException {
+        // if this is the SEEN flag, make sure we shadow this in the newsrc
+        // file.
+        if (flag.contains(Flags.Flag.SEEN)) {
+            ((NNTPFolder) folder).setSeen(msgnum, newvalue);
+        }
+        // have the superclass do the real flag setting.
+        super.setFlags(flag, newvalue);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java
new file mode 100644
index 0000000..cea8790
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java
@@ -0,0 +1,399 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
+import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
+import org.apache.geronimo.mail.util.SessionUtil;
+
+/**
+ * The base NNTP implementation of the javax.mail.Folder This is a base class
+ * for both the Root NNTP server and each NNTP group folder.
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 437941 $
+ */
+public class NNTPRootFolder extends NNTPFolder {
+    protected static final String NNTP_LISTALL = "mail.nntp.listall";
+
+    /**
+     * Construct the NNTPRootFolder.
+     * 
+     * @param store
+     *            The owning Store.
+     * @param name
+     *            The folder name (by default, this is the server host name).
+     * @param fullName
+     *            The fullName to use for this server (derived from welcome
+     *            string).
+     */
+    protected NNTPRootFolder(NNTPStore store, String name, String fullName) {
+        super(store);
+
+        this.name = name;
+        this.fullName = fullName;
+    }
+
+    /**
+     * List the subfolders. For group folders, this is a meaningless so we throw
+     * a MethodNotSupportedException.
+     * 
+     * @param pattern
+     *            The folder pattern string.
+     * 
+     * @return Never returns.
+     * @exception MessagingException
+     */
+    public synchronized Folder[] list(String pattern) throws MessagingException {
+        // the pattern specfied for javamail uses two wild card characters, "%"
+        // and "*". The "%" matches
+        // and character except hierarchy separators. Since we have a flag
+        // hierarchy, "%" and "*" are
+        // essentially the same. If we convert the "%" into "*", we can just
+        // treat this as a wildmat
+        // formatted pattern and pass this on to the server rather than having
+        // to read everything and
+        // process the strings on the client side.
+
+        pattern = pattern.replace('%', '*');
+
+        // if we're not supposed to list everything, then just filter the list
+        // of subscribed groups.
+        if (SessionUtil.getBooleanProperty(NNTP_LISTALL, false)) {
+            return filterActiveGroups(pattern);
+        } else {
+            return filterSubscribedGroups(pattern);
+        }
+    }
+
+    /**
+     * Retrieve the list of subscribed folders that match the given pattern
+     * string.
+     * 
+     * @param pattern
+     *            The pattern string used for the matching
+     * 
+     * @return An array of matching folders from the subscribed list.
+     */
+    public Folder[] listSubscribed(String pattern) throws MessagingException {
+        // the pattern specfied for javamail uses two wild card characters, "%"
+        // and "*". The "%" matches
+        // and character except hierarchy separators. Since we have a flag
+        // hierarchy, "%" and "*" are
+        // essentially the same. If we convert the "%" into "*", we can just
+        // treat this as a wildmat
+        // formatted pattern and pass this on to the server rather than having
+        // to read everything and
+        // process the strings on the client side.
+
+        pattern = pattern.replace('%', '*');
+
+        return filterSubscribedGroups(pattern);
+    }
+
+    /**
+     * Retrieve the list of matching groups from the NNTP server using the LIST
+     * ACTIVE command. The server does the wildcard matching for us.
+     * 
+     * @param pattern
+     *            The pattern string (in wildmat format) used to match.
+     * 
+     * @return An array of folders for the matching groups.
+     */
+    protected Folder[] filterActiveGroups(String pattern) throws MessagingException {
+        NNTPReply reply = connection.sendCommand("LIST ACTIVE " + pattern, NNTPReply.LIST_FOLLOWS);
+
+        // if the LIST ACTIVE command isn't supported,
+        if (reply.getCode() == NNTPReply.COMMAND_NOT_RECOGNIZED) {
+            // only way to list all is to retrieve all and filter.
+            return filterAllGroups(pattern);
+        } else if (reply.getCode() != NNTPReply.LIST_FOLLOWS) {
+            throw new MessagingException("Error retrieving group list from NNTP server: " + reply);
+        }
+
+        // get the response back from the server and process each returned group
+        // name.
+        List groups = reply.getData();
+
+        Folder[] folders = new Folder[groups.size()];
+        for (int i = 0; i < groups.size(); i++) {
+            folders[i] = getFolder(getGroupName((String) groups.get(i)));
+        }
+        return folders;
+    }
+
+    /**
+     * Retrieve a list of all groups from the server and filter on the names.
+     * Not recommended for the usenet servers, as there are over 30000 groups to
+     * process.
+     * 
+     * @param pattern
+     *            The pattern string used for the selection.
+     * 
+     * @return The Folders for the matching groups.
+     */
+    protected Folder[] filterAllGroups(String pattern) throws MessagingException {
+        NNTPReply reply = connection.sendCommand("LIST", NNTPReply.LIST_FOLLOWS);
+
+        if (reply.getCode() != NNTPReply.LIST_FOLLOWS) {
+            throw new MessagingException("Error retrieving group list from NNTP server: " + reply);
+        }
+
+        // get the response back from the server and process each returned group
+        // name.
+        List groups = reply.getData();
+
+        WildmatMatcher matcher = new WildmatMatcher(pattern);
+
+        List folders = new ArrayList();
+        for (int i = 0; i < groups.size(); i++) {
+            String name = getGroupName((String) groups.get(i));
+            // does this match our pattern? Add to the list
+            if (matcher.matches(name)) {
+                folders.add(getFolder(name));
+            }
+        }
+        return (Folder[]) folders.toArray(new Folder[0]);
+    }
+
+    /**
+     * Return the set of groups from the newsrc subscribed groups list that
+     * match a given filter.
+     * 
+     * @param pattern
+     *            The selection pattern.
+     * 
+     * @return The Folders for the matching groups.
+     */
+    protected Folder[] filterSubscribedGroups(String pattern) throws MessagingException {
+        Iterator groups = ((NNTPStore) store).getNewsrcGroups();
+
+        WildmatMatcher matcher = new WildmatMatcher(pattern);
+
+        List folders = new ArrayList();
+        while (groups.hasNext()) {
+            NNTPNewsrcGroup group = (NNTPNewsrcGroup) groups.next();
+            if (group.isSubscribed()) {
+                // does this match our pattern? Add to the list
+                if (matcher.matches(group.getName())) {
+                    folders.add(getFolder(group.getName()));
+                }
+            }
+        }
+        return (Folder[]) folders.toArray(new Folder[0]);
+    }
+
+    /**
+     * Utility method for extracting a name from a group list response.
+     * 
+     * @param response
+     *            The response string.
+     * 
+     * @return The group name.
+     */
+    protected String getGroupName(String response) {
+        int blank = response.indexOf(' ');
+        return response.substring(0, blank).trim();
+    }
+
+    /**
+     * Return whether this folder can hold just messages or also subfolders.
+     * Only the root folder can hold other folders, so it will need to override.
+     * 
+     * @return Always returns Folder.HOLDS_FOLDERS.
+     * @exception MessagingException
+     */
+    public int getType() throws MessagingException {
+        return HOLDS_FOLDERS;
+    }
+
+    /**
+     * Get a new folder from the root folder. This creates a new folder, which
+     * might not actually exist on the server. If the folder doesn't exist, an
+     * error will occur on folder open.
+     * 
+     * @param name
+     *            The name of the requested folder.
+     * 
+     * @return A new folder object for this folder.
+     * @exception MessagingException
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        // create a new group folder and return
+        return new NNTPGroupFolder(this, (NNTPStore) store, name, ((NNTPStore) store).getNewsrcGroup(name));
+    }
+
+    /**
+     * Utility class to do Wildmat pattern matching on folder names.
+     */
+    class WildmatMatcher {
+        // middle match sections...because these are separated by wildcards, if
+        // they appear in
+        // sequence in the string, it is a match.
+        List matchSections = new ArrayList();
+
+        // just a "*" match, so everything is true
+        boolean matchAny = false;
+
+        // no wildcards, so this must be an exact match.
+        String exactMatch = null;
+
+        // a leading section which must be at the beginning
+        String firstSection = null;
+
+        // a trailing section which must be at the end of the string.
+        String lastSection = null;
+
+        /**
+         * Create a wildmat pattern matcher.
+         * 
+         * @param pattern
+         *            The wildmat pattern to apply to string matches.
+         */
+        public WildmatMatcher(String pattern) {
+            int section = 0;
+
+            // handle the easy cases first
+
+            // single wild card?
+            if (pattern.equals("*")) {
+                matchAny = true;
+                return;
+            }
+
+            // find the first wild card
+            int wildcard = pattern.indexOf('*');
+
+            // no wild card at all?
+            if (wildcard == -1) {
+                exactMatch = pattern;
+                return;
+            }
+
+            // pattern not begin with a wildcard? We need to pull off the
+            // leading section
+            if (!pattern.startsWith("*")) {
+                firstSection = pattern.substring(0, wildcard);
+                section = wildcard + 1;
+                // this could be "yada*", so we could be done.
+                if (section >= pattern.length()) {
+                    return;
+                }
+            }
+
+            // now parse off the middle sections, making sure to handle the end
+            // condition correctly.
+            while (section < pattern.length()) {
+                // find the next wildcard position
+                wildcard = pattern.indexOf('*', section);
+                if (wildcard == -1) {
+                    // not found, we're at the end of the pattern. We need to
+                    // match on the end.
+                    lastSection = pattern.substring(section);
+                    return;
+                }
+                // we could have a null section, which we'll just ignore.
+                else if (wildcard == section) {
+                    // step over the wild card
+                    section++;
+                } else {
+                    // pluck off the next section
+                    matchSections.add(pattern.substring(section, wildcard));
+                    // step over the wild card character and check if we've
+                    // reached the end.
+                    section = wildcard + 1;
+                }
+            }
+        }
+
+        /**
+         * Test if a name string matches to parsed wildmat pattern.
+         * 
+         * @param name
+         *            The name to test.
+         * 
+         * @return true if the string matches the pattern, false otherwise.
+         */
+        public boolean matches(String name) {
+
+            // handle the easy cases first
+
+            // full wildcard? Always matches
+            if (matchAny) {
+                return true;
+            }
+
+            // required exact matches are easy.
+            if (exactMatch != null) {
+                return exactMatch.equals(name);
+            }
+
+            int span = 0;
+
+            // must match the beginning?
+            if (firstSection != null) {
+                // if it doesn't start with that, it can't be true.
+                if (!name.startsWith(firstSection)) {
+                    return false;
+                }
+
+                // we do all additional matching activity from here.
+                span = firstSection.length();
+            }
+
+            // scan for each of the sections along the string
+            for (int i = 1; i < matchSections.size(); i++) {
+                // if a section is not found, this is false
+
+                String nextMatch = (String) matchSections.get(i);
+                int nextLocation = name.indexOf(nextMatch, span);
+                if (nextLocation == -1) {
+                    return false;
+                }
+                // step over that one
+                span = nextMatch.length() + nextLocation;
+            }
+
+            // we've matched everything up to this point, now check to see if
+            // need an end match
+            if (lastSection != null) {
+                // we need to have at least the number of characters of the end
+                // string left, else this fails.
+                if (name.length() - span < lastSection.length()) {
+                    return false;
+                }
+
+                // ok, make sure we end with this string
+                return name.endsWith(lastSection);
+            }
+
+            // no falsies, this must be the truth.
+            return true;
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java
new file mode 100644
index 0000000..767b78c
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java
@@ -0,0 +1,44 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.nntp;
+
+import javax.mail.Session;
+import javax.mail.URLName;
+
+/**
+ * NNTP implementation of javax.mail.Store over an SSL connection.
+ *
+ * @version $Rev: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
+ */
+public class NNTPSSLStore extends NNTPStore {
+    /**
+     * Construct an NNTPSSLStore item.
+     *
+     * @param session The owning javamail Session.
+     * @param urlName The Store urlName, which can contain server target information.
+     */
+	public NNTPSSLStore(Session session, URLName urlName) {
+        // we're the imaps protocol, our default connection port is 563, and we must use
+        // an SSL connection for the initial hookup 
+		super(session, urlName, "nntps", DEFAULT_NNTP_SSL_PORT, true);
+	}
+}
+
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java
new file mode 100644
index 0000000..ec86f6e
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java
@@ -0,0 +1,260 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.util.Iterator;
+
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrc;
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcFile;
+import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
+import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
+import org.apache.geronimo.javamail.util.ProtocolProperties; 
+import org.apache.geronimo.mail.util.SessionUtil;
+
+/**
+ * NNTP implementation of javax.mail.Store POP protocol spec is implemented in
+ * org.apache.geronimo.javamail.store.pop3.NNTPConnection
+ * 
+ * @version $Rev: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
+ */
+public class NNTPStore extends Store {
+    protected static final String NNTP_NEWSRC = "newsrc";
+
+    protected static final String protocol = "nntp";
+
+    protected static final int DEFAULT_NNTP_PORT = 119;
+    protected static final int DEFAULT_NNTP_SSL_PORT = 563;
+
+    // our accessor for protocol properties and the holder of 
+    // protocol-specific information 
+    protected ProtocolProperties props; 
+    // our active connection object (shared code with the NNTPStore).
+    protected NNTPConnection connection;
+
+    // the root folder
+    protected NNTPRootFolder root;
+    // the newsrc file where we store subscriptions and seen message markers.
+    protected NNTPNewsrc newsrc;
+    
+    /**
+     * Construct an NNTPStore item. This will load the .newsrc file associated
+     * with the server.
+     * 
+     * @param session
+     *            The owning javamail Session.
+     * @param name
+     *            The Store urlName, which can contain server target
+     *            information.
+     */
+    public NNTPStore(Session session, URLName name) {
+        this(session, name, "nntp", DEFAULT_NNTP_PORT, false);
+    }
+
+    /**
+     * Common constructor used by the POP3Store and POP3SSLStore classes
+     * to do common initialization of defaults.
+     *
+     * @param session
+     *            The host session instance.
+     * @param name
+     *            The URLName of the target.
+     * @param protocol
+     *            The protocol type ("nntp" or "nntps"). This helps us in
+     *            retrieving protocol-specific session properties.
+     * @param defaultPort
+     *            The default port used by this protocol. For pop3, this will
+     *            be 110. The default for pop3 with ssl is 995.
+     * @param sslConnection
+     *            Indicates whether an SSL connection should be used to initial
+     *            contact the server. This is different from the STARTTLS
+     *            support, which switches the connection to SSL after the
+     *            initial startup.
+     */
+    protected NNTPStore(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+        super(session, name);
+        
+        // create the protocol property holder.  This gives an abstraction over the different 
+        // flavors of the protocol. 
+        props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
+
+        // the connection manages connection for the transport 
+        connection = new NNTPConnection(props); 
+    }
+
+    /**
+     * @see javax.mail.Store#getDefaultFolder()
+     * 
+     * This returns a root folder object for all of the news groups.
+     */
+    public Folder getDefaultFolder() throws MessagingException {
+        checkConnectionStatus();
+        if (root == null) {
+            return new NNTPRootFolder(this, connection.getHost(), connection.getWelcomeString());
+        }
+        return root;
+    }
+
+    /**
+     * @see javax.mail.Store#getFolder(java.lang.String)
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        return getDefaultFolder().getFolder(name);
+    }
+
+    /**
+     * 
+     * @see javax.mail.Store#getFolder(javax.mail.URLName)
+     */
+    public Folder getFolder(URLName url) throws MessagingException {
+        return getDefaultFolder().getFolder(url.getFile());
+    }
+
+    
+    /**
+     * Do the protocol connection for an NNTP transport. This handles server
+     * authentication, if possible. Returns false if unable to connect to the
+     * server.
+     * 
+     * @param host
+     *            The target host name.
+     * @param port
+     *            The server port number.
+     * @param user
+     *            The authentication user (if any).
+     * @param password
+     *            The server password. Might not be sent directly if more
+     *            sophisticated authentication is used.
+     * 
+     * @return true if we were able to connect to the server properly, false for
+     *         any failures.
+     * @exception MessagingException
+     */
+    protected boolean protocolConnect(String host, int port, String username, String password)
+            throws MessagingException {
+        // the connection pool handles all of the details here. But don't proceed 
+        // without a connection 
+        if (!connection.protocolConnect(host, port, username, password)) {
+            return false; 
+        }
+
+        // see if we have a newsrc file location specified
+        String newsrcFile = props.getProperty(NNTP_NEWSRC);
+
+        File source = null;
+
+        // not given as a property? Then look for a file in user.home
+        if (newsrcFile != null) {
+            source = new File(newsrcFile);
+        } else {
+            // ok, look for a file in the user.home directory. If possible,
+            // we'll try for a file
+            // with the hostname appended.
+            String home = SessionUtil.getProperty("user.home");
+
+            // try for a host-specific file first. If not found, use (and
+            // potentially create) a generic
+            // .newsrc file.
+            newsrcFile = ".newsrc-" + host;
+            source = new File(home, newsrcFile);
+            if (!source.exists()) {
+                source = new File(home, ".newsrc");
+            }
+        }
+
+        // now create a newsrc read and load the file.
+        newsrc = new NNTPNewsrcFile(source);
+        newsrc.load();
+
+        // we're going to return success here, but in truth, the server may end
+        // up asking for our bonafides at any time, and we'll be expected to authenticate then.
+        return true;
+    }
+    
+
+    /**
+     * @see javax.mail.Service#close()
+     */
+    public void close() throws MessagingException {
+        // This is done to ensure proper event notification.
+        super.close();
+        // persist the newsrc file, if possible
+        if (newsrc != null) {
+            newsrc.close();
+            newsrc = null; 
+        }
+        connection.close();
+        connection = null;
+    }
+
+    private void checkConnectionStatus() throws MessagingException {
+        if (!this.isConnected()) {
+            throw new MessagingException("Not connected ");
+        }
+    }
+
+    /**
+     * Retrieve the server connection created by this store.
+     * 
+     * @return The active connection object.
+     */
+    NNTPConnection getConnection() {
+        return connection;
+    }
+
+    /**
+     * Retrieve the Session object this Store is operating under.
+     * 
+     * @return The attached Session instance.
+     */
+    Session getSession() {
+        return session;
+    }
+
+    /**
+     * Retrieve all of the groups we nave persistent store information about.
+     * 
+     * @return The set of groups contained in the newsrc file.
+     */
+    Iterator getNewsrcGroups() {
+        return newsrc.getGroups();
+    }
+
+    /**
+     * Retrieve the newsrc group information for a named group. If the file does
+     * not currently include this group, an unsubscribed group will be added to
+     * the file.
+     * 
+     * @param name
+     *            The name of the target group.
+     * 
+     * @return The NNTPNewsrcGroup item corresponding to this name.
+     */
+    NNTPNewsrcGroup getNewsrcGroup(String name) {
+        return newsrc.getGroup(name);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java
new file mode 100644
index 0000000..def485c
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java
@@ -0,0 +1,182 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Base class implementation of a standard news reader news rc file. This is
+ * used to track newsgroup subscriptions and SEEN flags for articles. This is an
+ * abstract class designed for subclasses to bridge to the physical store type
+ * used for the newsgroup information.
+ */
+public abstract class NNTPNewsrc {
+
+    // the group information we've read from the news rc file.
+    Map groups = new HashMap();
+
+    // flag to let us know of we need to persist the newsrc file on close.
+    boolean dirty = false;
+
+    /**
+     * Base class constructor for NNTPNewsrc items. Subclasses provide their own
+     * domain-specific intialization.
+     */
+    protected NNTPNewsrc() {
+    }
+
+    /**
+     * Load the data from the newsrc file and parse into an instore group
+     * database.
+     */
+    public void load() {
+        BufferedReader in = null;
+
+        try {
+            in = getInputReader();
+
+            String line = in.readLine();
+
+            while (line != null) {
+                // parse the line...this returns null if it's something
+                // unrecognized.
+                NNTPNewsrcGroup group = NNTPNewsrcGroup.parse(this, line);
+                // if it parsed ok, add it to the group list, and potentially to
+                // the subscribed list.
+                if (group != null) {
+                    groups.put(group.getName(), group);
+                }
+
+                line = in.readLine();
+            }
+
+            in.close();
+        } catch (IOException e) {
+            // an IOException may mean that the file just doesn't exist, which
+            // is fine. We'll ignore and
+            // proceed with the information we have.
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    /**
+     * Save the newsrc file data back to the original source file.
+     * 
+     * @exception IOException
+     */
+    public void save() throws IOException {
+        Writer out = getOutputWriter();
+
+        Iterator i = groups.values().iterator();
+
+        while (i.hasNext()) {
+            NNTPNewsrcGroup group = (NNTPNewsrcGroup) i.next();
+            group.save(out);
+        }
+
+        out.close();
+    }
+
+    /**
+     * Abstract open method intended for sub class initialization. The subclass
+     * is responsible for creating the BufferedReaded used to read the .newsrc
+     * file.
+     * 
+     * @return A BufferedReader for reading the .newsrc file.
+     * @exception IOException
+     */
+    abstract public BufferedReader getInputReader() throws IOException;
+
+    /**
+     * Abstract open for output method intended for subclass implementation. The
+     * subclasses are reponsible for opening the output stream and creating an
+     * appropriate Writer for saving the .newsrc file.
+     * 
+     * @return A Writer target at the .newsrc file save location.
+     * @exception IOException
+     */
+    abstract public Writer getOutputWriter() throws IOException;
+
+    /**
+     * Retrieve the newsrc group information for a named group. If the file does
+     * not currently include this group, an unsubscribed group will be added to
+     * the file.
+     * 
+     * @param name
+     *            The name of the target group.
+     * 
+     * @return The NNTPNewsrcGroup item corresponding to this name.
+     */
+    public NNTPNewsrcGroup getGroup(String name) {
+        NNTPNewsrcGroup group = (NNTPNewsrcGroup) groups.get(name);
+        // if we don't know about this, create a new one and add to the list.
+        // This
+        // will be an unsubscribed one.
+        if (group == null) {
+            group = new NNTPNewsrcGroup(this, name, null, false);
+            groups.put(name, group);
+            // we've added a group, so we need to resave
+            dirty = true;
+        }
+        return group;
+    }
+
+    /**
+     * Mark this newsrc database as dirty.
+     */
+    public void setDirty() {
+        dirty = true;
+    }
+
+    /**
+     * Close the newsrc file, persisting it back to disk if the file has
+     * changed.
+     */
+    public void close() {
+        if (dirty) {
+            try {
+                save();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Retrieve the current set of loaded groups.
+     * 
+     * @return An iterator for traversing the group set.
+     */
+    public Iterator getGroups() {
+        return groups.values().iterator();
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java
new file mode 100644
index 0000000..8a8a97c
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public class NNTPNewsrcFile extends NNTPNewsrc {
+    // source for the file data
+    File source;
+
+    /**
+     * Construct a NNTPNewsrc object that is targetted at a file-based backing
+     * store.
+     * 
+     * @param source
+     *            The source File for the .newsrc data.
+     */
+    public NNTPNewsrcFile(File source) {
+        this.source = source;
+    }
+
+    /**
+     * Retrieve an input reader for loading the newsrc file.
+     * 
+     * @return A BufferedReader object for reading from the newsrc file.
+     * @exception IOException
+     */
+    public BufferedReader getInputReader() throws IOException {
+        return new BufferedReader(new InputStreamReader(new FileInputStream(source), "ISO8859-1"));
+    }
+
+    /**
+     * Obtain a writer for saving a newsrc file.
+     * 
+     * @return The output writer targetted to the newsrc file.
+     * @exception IOException
+     */
+    public Writer getOutputWriter() throws IOException {
+        // open this for overwriting
+        return new OutputStreamWriter(new FileOutputStream(source, false), "ISO8859-1");
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java
new file mode 100644
index 0000000..b628361
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java
@@ -0,0 +1,185 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class NNTPNewsrcGroup {
+    // the newsrc database we're part of
+    NNTPNewsrc newsrc;
+
+    // the name of the group
+    protected String name;
+
+    // the subscription flage
+    protected boolean subscribed;
+
+    // the range of already seen articles.
+    protected RangeList ranges;
+
+    /**
+     * Construct a NNTPNewsrcGroup item associated with a given .newsrc
+     * database.
+     * 
+     * @param newsrc
+     *            The owning .newsrc database.
+     * @param line
+     *            The .newsrc range entries in .newsrc format. These ranges are
+     *            parsed to create a set of seen flags.
+     * 
+     * @return A created NNTPNewsrcGroup item.
+     */
+    public static NNTPNewsrcGroup parse(NNTPNewsrc newsrc, String line) {
+        String groupName = null;
+        String ranges = null;
+
+        // subscribed lines have a ':' marker acting as a delimiter
+        int marker = line.indexOf(':');
+
+        if (marker != -1) {
+            groupName = line.substring(0, marker);
+            ranges = line.substring(marker + 1);
+            return new NNTPNewsrcGroup(newsrc, groupName, ranges, true);
+        }
+
+        // now check for an unsubscribed group
+        marker = line.indexOf('!');
+
+        if (marker != -1) {
+            groupName = line.substring(0, marker);
+            ranges = line.substring(marker + 1);
+            return new NNTPNewsrcGroup(newsrc, groupName, ranges, false);
+        }
+
+        // must be a comment line
+        return null;
+    }
+
+    /**
+     * Construct a .newsrc group item.
+     * 
+     * @param newsrc
+     *            The owning newsrc database.
+     * @param name
+     *            The group name.
+     * @param newsrcRanges
+     *            The initial set of seen ranges for the group (may be null).
+     * @param subscribed
+     *            The initial group subscription state.
+     */
+    public NNTPNewsrcGroup(NNTPNewsrc newsrc, String name, String newsrcRanges, boolean subscribed) {
+        this.newsrc = newsrc;
+        this.name = name;
+        this.subscribed = subscribed;
+        this.ranges = new RangeList(newsrcRanges);
+    }
+
+    /**
+     * Get the group name.
+     * 
+     * @return The String name of the group.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the newsrc subscribed status for an article.
+     * 
+     * @return The current subscription flag.
+     */
+    public boolean isSubscribed() {
+        return subscribed;
+    }
+
+    /**
+     * Set the subscription status for an article.
+     * 
+     * @param flag
+     *            The new subscription value.
+     */
+    public void setSubscribed(boolean flag) {
+        // we don't blindly set this to the new value since we only want to
+        // resave the newsrc file if
+        // something changes.
+        if (flag && !subscribed) {
+            subscribed = true;
+            newsrc.setDirty();
+        } else if (!flag && subscribed) {
+            subscribed = false;
+            newsrc.setDirty();
+        }
+    }
+
+    /**
+     * Test if an article has been seen yet.
+     * 
+     * @param article
+     *            The target article.
+     * 
+     * @return The seen mark for the article.
+     */
+    public boolean isArticleSeen(int article) {
+        return ranges.isMarked(article);
+    }
+
+    /**
+     * Mark an article as seen.
+     * 
+     * @param article
+     *            The target article number.
+     */
+    public void markArticleSeen(int article) {
+        ranges.setMarked(article);
+        if (ranges.isDirty()) {
+            newsrc.setDirty();
+        }
+    }
+
+    /**
+     * Mark an article as unseen.
+     * 
+     * @param article
+     *            The target article number.
+     */
+    public void markArticleUnseen(int article) {
+        ranges.setUnmarked(article);
+        if (ranges.isDirty()) {
+            newsrc.setDirty();
+        }
+    }
+
+    /**
+     * Save this group definition to a .newsrc file.
+     * 
+     * @param out
+     *            The output writer to send the information to.
+     * 
+     * @exception IOException
+     */
+    public void save(Writer out) throws IOException {
+        out.write(name);
+        out.write(subscribed ? ": " : "! ");
+        ranges.save(out);
+        // put a terminating line end
+        out.write("\r\n");
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java
new file mode 100644
index 0000000..90e4707
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java
@@ -0,0 +1,318 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Represent a single Range in a newsrc file. A Range can be either a single
+ * number (start == end) or a span of article numbers.
+ */
+public class Range {
+    // the low end of the range
+    int start;
+
+    // the high end of the range (start and end are inclusive);
+    int end;
+
+    /**
+     * Construct a Range item for a single digit range.
+     * 
+     * @param spot
+     *            The location of the singleton.
+     */
+    public Range(int spot) {
+        this(spot, spot);
+    }
+
+    /**
+     * Construct a Range item.
+     * 
+     * @param start
+     *            The starting point of the Range.
+     * @param end
+     *            The Range end point (which may be equal to the starting
+     *            point).
+     */
+    public Range(int start, int end) {
+        this.start = start;
+        this.end = end;
+    }
+
+    /**
+     * Parse a section of a .newsrc range string into a single Range item. The
+     * range is either a single number, or a pair of numbers separated by a
+     * hyphen.
+     * 
+     * @param range
+     *            The range string.
+     * 
+     * @return A constructed Range item, or null if there is a parsing error.
+     */
+    static public Range parse(String range) {
+        // a range from a newsrc file is either a single number or in the format
+        // 'nnnn-mmmm'. We need
+        // to figure out which type this is.
+        int marker = range.indexOf('-');
+
+        try {
+            if (marker != -1) {
+                String rangeStart = range.substring(0, marker).trim();
+                String rangeEnd = range.substring(marker + 1).trim();
+
+                int start = Integer.parseInt(rangeStart);
+                int end = Integer.parseInt(rangeEnd);
+
+                if (start >= 0 && end >= 0) {
+                    return new Range(start, end);
+                }
+            } else {
+                // use the entire token
+                int start = Integer.parseInt(range);
+                // and start and the end are the same
+                return new Range(start, start);
+
+            }
+        } catch (NumberFormatException e) {
+        }
+        // return null for any bad values
+        return null;
+    }
+
+    /**
+     * Get the starting point for the Range.
+     * 
+     * @return The beginning of the mark range.
+     */
+    public int getStart() {
+        return start;
+    }
+
+    /**
+     * Set the starting point for a Range.
+     * 
+     * @param start
+     *            The new start value.
+     */
+    public void setStart(int start) {
+        this.start = start;
+    }
+
+    /**
+     * Get the ending point for the Range.
+     * 
+     * @return The end of the mark range.
+     */
+    public int getEnd() {
+        return end;
+    }
+
+    /**
+     * Set the ending point for a Range.
+     * 
+     * @param end
+     *            The new end value.
+     */
+    public void setEnd(int end) {
+        this.end = end;
+    }
+
+    /**
+     * Test if a range contains a point value.
+     * 
+     * @param target
+     *            The article location to test.
+     * 
+     * @return True if the target is between the start and end values,
+     *         inclusive.
+     */
+    public boolean contains(int target) {
+        return target >= start && target <= end;
+    }
+
+    /**
+     * Test if one range is completely contained within another Range.
+     * 
+     * @param other
+     *            The other test range.
+     * 
+     * @return true if the other start and end points are contained within this
+     *         range.
+     */
+    public boolean contains(Range other) {
+        return contains(other.getStart()) && contains(other.getEnd());
+    }
+
+    /**
+     * Tests if two ranges overlap
+     * 
+     * @param other
+     *            The other test range.
+     * 
+     * @return true if the start or end points of either range are contained
+     *         within the range of the other.
+     */
+    public boolean overlaps(Range other) {
+        return other.contains(start) || other.contains(end) || contains(other.getStart()) || contains(other.getEnd());
+    }
+
+    /**
+     * Test if two ranges exactly abutt each other.
+     * 
+     * @param other
+     *            The other Range to test.
+     * 
+     * @return true if the end of one range abutts the start of the other range.
+     */
+    public boolean abutts(Range other) {
+        return other.getStart() == end + 1 || other.getEnd() == start - 1;
+    }
+
+    /**
+     * Tests if a single point abutts either the start or end of this Range.
+     * 
+     * @param article
+     *            The point to test.
+     * 
+     * @return true if test point is equal to start - 1 or end + 1.
+     */
+    public boolean abutts(int article) {
+        return article == start - 1 || article == end + 1;
+    }
+
+    /**
+     * Test if a point is below the test Range.
+     * 
+     * @param article
+     *            The point to test.
+     * 
+     * @return true if the entire range is less than the test point.
+     */
+    public boolean lessThan(int article) {
+        return end < article;
+    }
+
+    /**
+     * Test if another Range is less than this Range.
+     * 
+     * @param other
+     *            The other Range to test.
+     * 
+     * @return true if the other Range lies completely below this Range.
+     */
+    public boolean lessThan(Range other) {
+        return end < other.start;
+    }
+
+    /**
+     * Test if a point is above the test Range.
+     * 
+     * @param article
+     *            The point to test.
+     * 
+     * @return true if the entire range is greater than the test point.
+     */
+    public boolean greaterThan(int article) {
+        return start > article;
+    }
+
+    /**
+     * Test if another Range is greater than this Range.
+     * 
+     * @param other
+     *            The other Range to test.
+     * 
+     * @return true if the other Range lies completely below this Range.
+     */
+    public boolean greaterThan(Range other) {
+        return start > other.end;
+    }
+
+    /**
+     * Merge another Range into this one. Merging will increase the bounds of
+     * this Range to encompass the entire span of the two. If the Ranges do not
+     * overlap, the newly created range will include the gap between the two.
+     * 
+     * @param other
+     *            The Range to merge.
+     */
+    public void merge(Range other) {
+        if (other.start < start) {
+            start = other.start;
+        }
+
+        if (other.end > end) {
+            end = other.end;
+        }
+    }
+
+    /**
+     * Split a range at a given split point. Splitting will truncate at the
+     * split location - 1 and return a new range beginning at location + 1; This
+     * code assumes that the split location is at neither end poing.
+     * 
+     * @param location
+     *            The split location. Location must be in the range start <
+     *            location < end.
+     * 
+     * @return A new Range object for the split portion of the range.
+     */
+    public Range split(int location) {
+        int newEnd = end;
+
+        end = location - 1;
+
+        return new Range(location + 1, newEnd);
+    }
+
+    /**
+     * Save an individual range element to a newsrc file. The range is expressed
+     * either as a single number, or a hypenated pair of numbers.
+     * 
+     * @param out
+     *            The output writer used to save the data.
+     * 
+     * @exception IOException
+     */
+    public void save(Writer out) throws IOException {
+        // do we have a single data point range?
+        if (start == end) {
+            out.write(Integer.toString(start));
+        } else {
+            out.write(Integer.toString(start));
+            out.write("-");
+            out.write(Integer.toString(end));
+        }
+    }
+
+    /**
+     * Convert a Range into String form. Used mostly for debugging.
+     * 
+     * @return The String representation of the Range.
+     */
+    public String toString() {
+        if (start == end) {
+            return Integer.toString(start);
+        } else {
+            return Integer.toString(start) + "-" + Integer.toString(end);
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java
new file mode 100644
index 0000000..845f54a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java
@@ -0,0 +1,227 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.nntp.newsrc;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+/**
+ * Manage a list of ranges values from a newsrc file.
+ */
+public class RangeList {
+    boolean dirty = false;
+
+    ArrayList ranges = new ArrayList();
+
+    /**
+     * Create a RangeList instance from a newsrc range line. Values are saved as
+     * a comma separated set of range values. A range value is either a single
+     * number or a hypenated pair of numbers.
+     * 
+     * @param line
+     *            The newsrc range line.
+     */
+    public RangeList(String line) {
+
+        // we might be creating an first time list, so nothing to parse.
+        if (line != null) {
+            // ranges are comma delimited tokens
+            StringTokenizer tokenizer = new StringTokenizer(line, ",");
+
+            while (tokenizer.hasMoreTokens()) {
+                String rangeString = (String) tokenizer.nextToken();
+                rangeString = rangeString.trim();
+                if (rangeString.length() != 0) {
+                    Range range = Range.parse(rangeString);
+                    if (range != null) {
+                        insert(range);
+                    }
+                }
+            }
+        }
+        // make sure we start out in a clean state. Any changes from this point
+        // will flip on the dirty flat.
+        dirty = false;
+    }
+
+    /**
+     * Insert a range item into our list. If possible, the inserted range will
+     * be merged with existing ranges.
+     * 
+     * @param newRange
+     *            The new range item.
+     */
+    public void insert(Range newRange) {
+        // first find the insertion point
+        for (int i = 0; i < ranges.size(); i++) {
+            Range range = (Range) ranges.get(i);
+            // does an existing range fully contain the new range, we don't need
+            // to insert anything.
+            if (range.contains(newRange)) {
+                return;
+            }
+
+            // does the current one abutt or overlap with the inserted range?
+            if (range.abutts(newRange) || range.overlaps(newRange)) {
+                // rats, we have an overlap...and it is possible that we could
+                // overlap with
+                // the next range after this one too. Therefore, we merge these
+                // two ranges together,
+                // remove the place where we're at, and then recursively insert
+                // the larger range into
+                // the list.
+                dirty = true;
+                newRange.merge(range);
+                ranges.remove(i);
+                insert(newRange);
+                return;
+            }
+
+            // ok, we don't touch the current one at all. If it is completely
+            // above
+            // range we're adding, we can just poke this into the list here.
+            if (newRange.lessThan(range)) {
+                dirty = true;
+                ranges.add(i, newRange);
+                return;
+            }
+        }
+        dirty = true;
+        // this is easy (and fairly common)...we just tack this on to the end.
+        ranges.add(newRange);
+    }
+
+    /**
+     * Test if a given article point falls within one of the contained Ranges.
+     * 
+     * @param article
+     *            The test point.
+     * 
+     * @return true if this falls within one of our current mark Ranges, false
+     *         otherwise.
+     */
+    public boolean isMarked(int article) {
+        for (int i = 0; i < ranges.size(); i++) {
+            Range range = (Range) ranges.get(i);
+            if (range.contains(article)) {
+                return true;
+            }
+            // we've passed the point where a match is possible.
+            if (range.greaterThan(article)) {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Mark a target article as having been seen.
+     * 
+     * @param article
+     *            The target article number.
+     */
+    public void setMarked(int article) {
+        // go through the insertion logic.
+        insert(new Range(article, article));
+    }
+
+    /**
+     * Clear the seen mark for a target article.
+     * 
+     * @param article
+     *            The target article number.
+     */
+    public void setUnmarked(int article) {
+        for (int i = 0; i < ranges.size(); i++) {
+            Range range = (Range) ranges.get(i);
+            // does this fall within an existing range? We don't need to do
+            // anything here.
+            if (range.contains(article)) {
+                // ok, we've found where to insert, now to figure out how to
+                // insert
+                // article is at the beginning of the range. We can just
+                // increment the lower
+                // bound, or if this is a single element range, we can remove it
+                // entirely.
+                if (range.getStart() == article) {
+                    if (range.getEnd() == article) {
+                        // piece of cake!
+                        ranges.remove(i);
+                    } else {
+                        // still pretty easy.
+                        range.setStart(article + 1);
+                    }
+                } else if (range.getEnd() == article) {
+                    // pretty easy also
+                    range.setEnd(article - 1);
+                } else {
+                    // split this into two ranges and insert the trailing piece
+                    // after this.
+                    Range section = range.split(article);
+                    ranges.add(i + 1, section);
+                }
+                dirty = true;
+                return;
+            }
+            // did we find a point where any articles are greater?
+            if (range.greaterThan(article)) {
+                // nothing to do
+                return;
+            }
+        }
+        // didn't find it at all. That was easy!
+    }
+
+    /**
+     * Save this List of Ranges out to a .newsrc file. This creates a
+     * comma-separated list of range values from each of the Ranges.
+     * 
+     * @param out
+     *            The target output stream.
+     * 
+     * @exception IOException
+     */
+    public void save(Writer out) throws IOException {
+        // we have an empty list
+        if (ranges.size() == 0) {
+            return;
+        }
+
+        Range range = (Range) ranges.get(0);
+        range.save(out);
+
+        for (int i = 1; i < ranges.size(); i++) {
+            out.write(",");
+            range = (Range) ranges.get(i);
+            range.save(out);
+        }
+    }
+
+    /**
+     * Return the state of the dirty flag.
+     * 
+     * @return True if the range list information has changed, false otherwise.
+     */
+    public boolean isDirty() {
+        return dirty;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
new file mode 100644
index 0000000..33179f9
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
@@ -0,0 +1,40 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3;
+
+/**
+ * Defines a few constants that are used throught the implementation.
+ * 
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+
+public interface POP3Constants {
+    public final static String SPACE = " ";
+
+    public final static String CRLF = "\r\n";
+
+    public final static int DOT = '.';
+
+    public final static int OK = 0;
+
+    public final static int ERR = 1;
+    
+    public final static int CHALLENGE = 2;
+}
\ No newline at end of file
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java
new file mode 100644
index 0000000..3ef0275
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java
@@ -0,0 +1,515 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3;
+
+import java.util.List;     
+
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.FolderClosedException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+import javax.mail.event.ConnectionEvent;
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection; 
+import org.apache.geronimo.javamail.store.pop3.connection.POP3StatusResponse; 
+
+/**
+ * The POP3 implementation of the javax.mail.Folder Note that only INBOX is
+ * supported in POP3
+ * <p>
+ * <url>http://www.faqs.org/rfcs/rfc1939.html</url>
+ * </p>
+ * 
+ * @see javax.mail.Folder
+ * 
+ * @version $Rev: 1610855 $ $Date: 2014-07-15 17:27:30 -0400 (Tue, 15 Jul 2014) $
+ */
+public class POP3Folder extends Folder {
+
+    protected boolean isFolderOpen = false;
+
+    protected int mode;
+
+    protected int msgCount;
+
+    private POP3Message[] messageCache; 
+    // The fully qualified name of the folder.  For a POP3 folder, this is either "" for the root or 
+    // "INPUT" for the in-basket.  It is possible to create other folders, but they will report that 
+    // they don't exist. 
+    protected String fullName;  
+    // indicates whether this folder exists or not 
+    protected boolean exists = false; 
+    // indicates the type of folder this is. 
+    protected int folderType; 
+    
+    /**
+     * Create a new folder associate with a POP3 store instance.
+     * 
+     * @param store  The owning Store.
+     * @param name   The name of the folder.  Note that POP3 stores only
+     *               have 2 real folders, the root ("") and the in-basket
+     *               ("INBOX").  It is possible to create other instances
+     *               of Folder associated with the Store, but they will
+     *               be non-functional.
+     */
+     public POP3Folder(POP3Store store, String name) {
+        super(store);
+        this.fullName = name; 
+        // if this is the input folder, this exists 
+        if (name.equalsIgnoreCase("INBOX")) {
+            exists = true; 
+        }
+        // by default, we're holding messages. 
+        folderType = Folder.HOLDS_MESSAGES; 
+    }
+    
+    
+    /**
+     * Retrieve the folder name.  This is the simple folder
+     * name at the its hiearchy level.  This can be invoked when the folder is closed.
+     * 
+     * @return The folder's name.
+     */
+	public String getName() {
+        // the name and the full name are always the same
+        return fullName; 
+	}
+
+    /**
+     * Retrieve the folder's full name (including hierarchy information).
+     * This can be invoked when the folder is closed.
+     *
+     * @return The full name value.
+     */
+	public String getFullName() {
+        return fullName;
+	}
+
+    
+    /**
+     * Never return "this" as the parent folder. Somebody not familliar with
+     * POP3 may do something like while(getParent() != null) or something
+     * simmilar which will result in an infinte loop
+     */
+    public Folder getParent() throws MessagingException {
+        // the default folder returns null.  We return the default 
+        // folder 
+        return store.getDefaultFolder(); 
+    }
+
+    /**
+     * Indicate whether a folder exists.  Only the root 
+     * folder and "INBOX" will ever return true. 
+     * 
+     * @return true for real POP3 folders, false for any other 
+     *         instances that have been created.
+     * @exception MessagingException
+     */
+    public boolean exists() throws MessagingException {
+        // only one folder truely exists...this might be it.
+        return exists; 
+    }
+
+    public Folder[] list(String pattern) throws MessagingException {
+        throw new MethodNotSupportedException("Only INBOX is supported in POP3, no sub folders");
+    }
+
+    /**
+     * No sub folders, hence there is no notion of a seperator.  This is always a null character. 
+     */
+    public char getSeparator() throws MessagingException {
+        return '\0';
+    }
+
+    /**
+     * There's no hierarchy in POP3, so the only type 
+     * is HOLDS_MESSAGES (and only one of those exists).
+     * 
+     * @return Always returns HOLDS_MESSAGES. 
+     * @exception MessagingException
+     */
+    public int getType() throws MessagingException {
+        return folderType;      
+    }
+
+    /**
+     * Always returns false as any creation operation must 
+     * fail. 
+     * 
+     * @param type   The type of folder to create.  This is ignored.
+     * 
+     * @return Always returns false. 
+     * @exception MessagingException
+     */
+    public boolean create(int type) throws MessagingException {
+        return false; 
+    }
+
+    /**
+     * No way to detect new messages, so always return false. 
+     * 
+     * @return Always returns false. 
+     * @exception MessagingException
+     */
+    public boolean hasNewMessages() throws MessagingException {
+        return false; 
+    }
+
+    public Folder getFolder(String name) throws MessagingException {
+        throw new MethodNotSupportedException("Only INBOX is supported in POP3, no sub folders");
+    }
+
+    public boolean delete(boolean recurse) throws MessagingException {
+        throw new MethodNotSupportedException("Only INBOX is supported in POP3 and INBOX cannot be deleted");
+    }
+
+    public boolean renameTo(Folder f) throws MessagingException {
+        throw new MethodNotSupportedException("Only INBOX is supported in POP3 and INBOX cannot be renamed");
+    }
+
+    /**
+     * @see javax.mail.Folder#open(int)
+     */
+    public void open(int mode) throws MessagingException {
+        // Can only be performed on a closed folder
+        checkClosed();
+
+        // get a connection object 
+        POP3Connection connection = getConnection(); 
+        
+        try {
+            POP3StatusResponse res = connection.retrieveMailboxStatus();
+            this.mode = mode;
+            this.isFolderOpen = true;
+            this.msgCount = res.getNumMessages();
+            // JavaMail API has no method in Folder to expose the total
+            // size (no of bytes) of the mail drop;
+
+            // NB:  We use the actual message number to access the messages from 
+            // the cache, which is origin 1.  Vectors are origin 0, so we have to subtract each time 
+            // we access a messagge.  
+            messageCache = new POP3Message[msgCount]; 
+        } catch (Exception e) {
+            throw new MessagingException("Unable to execute STAT command", e);
+        }
+        finally {
+            // return the connection when finished 
+            releaseConnection(connection); 
+        }
+
+        notifyConnectionListeners(ConnectionEvent.OPENED);
+    }
+
+    /**
+     * Close a POP3 folder.
+     * 
+     * @param expunge The expunge flag (ignored for POP3).
+     * 
+     * @exception MessagingException
+     */
+    public void close(boolean expunge) throws MessagingException {
+        // Can only be performed on an open folder
+        checkOpen();
+
+        // get a connection object 
+        POP3Connection connection = getConnection(); 
+        try {
+            // we might need to reset the connection before we 
+            // process deleted messages and send the QUIT.  The 
+            // connection knows if we need to do this. 
+            connection.reset(); 
+            // clean up any messages marked for deletion 
+            expungeDeletedMessages(connection); 
+        } finally {
+            // return the connection when finished 
+            releaseConnection(connection); 
+            // cleanup the the state even if exceptions occur when deleting the 
+            // messages. 
+            cleanupFolder(false); 
+        }
+    }
+    
+    /**
+     * Mark any messages we've flagged as deleted from the 
+     * POP3 server before closing. 
+     * 
+     * @exception MessagingException
+     */
+    protected void expungeDeletedMessages(POP3Connection connection) throws MessagingException {
+        if (mode == READ_WRITE) {
+            for (int i = 0; i < messageCache.length; i++) {
+                POP3Message msg = messageCache[i]; 
+                if (msg != null) {
+                    // if the deleted flag is set, go delete this 
+                    // message. NB:  We adjust the index back to an 
+                    // origin 1 value 
+                    if (msg.isSet(Flags.Flag.DELETED)) {
+                        try {
+                            connection.deleteMessage(i + 1); 
+                        } catch (MessagingException e) {
+                            throw new MessagingException("Exception deleting message number " + (i + 1), e); 
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    
+    /**
+     * Do folder cleanup.  This is used both for normal
+     * close operations, and adnormal closes where the
+     * server has sent us a BYE message.
+     * 
+     * @param expunge Indicates whether open messages should be expunged.
+     * @param disconnected
+     *                The disconnected flag.  If true, the server has cut
+     *                us off, which means our connection can not be returned
+     *                to the connection pool.
+     * 
+     * @exception MessagingException
+     */
+    protected void cleanupFolder(boolean disconnected) throws MessagingException {
+        messageCache = null;
+        isFolderOpen = false;
+		notifyConnectionListeners(ConnectionEvent.CLOSED);
+    }
+    
+    
+    /**
+     * Obtain a connection object for a Message attached to this Folder.  This 
+     * will be the Folder's connection, which is only available if the Folder 
+     * is currently open.
+     * 
+     * @return The connection object for the Message instance to use. 
+     * @exception MessagingException
+     */
+    synchronized POP3Connection getMessageConnection() throws MessagingException {
+        // we always get one from the store.  If we're fully single threaded, then 
+        // we can get away with just a single one. 
+        return getConnection(); 
+    }
+    
+    
+    /**
+     * Release the connection object back to the Folder instance.  
+     * 
+     * @param connection The connection being released.
+     * 
+     * @exception MessagingException
+     */
+    void releaseMessageConnection(POP3Connection connection) throws MessagingException {
+        // give this back to the store 
+        releaseConnection(connection); 
+    }
+
+    public boolean isOpen() {
+        // if we're not open, we're not open 
+        if (!isFolderOpen) {
+            return false; 
+        }
+        
+        try {
+            // we might be open, but the Store has been closed.  In which case, we're not any more
+            // closing also changes the isFolderOpen flag. 
+            if (!((POP3Store)store).isConnected()) {
+                close(false); 
+            }
+        } catch (MessagingException e) {
+        }
+        return isFolderOpen;
+    }
+
+    public Flags getPermanentFlags() {
+        // unfortunately doesn't have a throws clause for this method
+        // throw new MethodNotSupportedException("POP3 doesn't support permanent
+        // flags");
+
+        // Better than returning null, save the extra condition from a user to
+        // check for null
+        // and avoids a NullPointerException for the careless.
+        return new Flags();
+    }
+
+    /**
+     * Get the folder message count.
+     * 
+     * @return The number of messages in the folder.
+     * @exception MessagingException
+     */
+    public int getMessageCount() throws MessagingException {
+        // NB: returns -1 if the folder isn't open. 
+        return msgCount;
+    }
+
+    /**
+     * Checks wether the message is in cache, if not will create a new message
+     * object and return it.
+     * 
+     * @see javax.mail.Folder#getMessage(int)
+     */
+    public Message getMessage(int msgNum) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        if (msgNum < 1 || msgNum > getMessageCount()) {
+            throw new MessagingException("Invalid Message number");
+        }
+
+        Message msg = messageCache[msgNum - 1];
+        if (msg == null) {
+            msg = new POP3Message(this, msgNum); 
+            messageCache[msgNum - 1] = (POP3Message)msg; 
+        }
+
+        return msg;
+    }
+
+    public void appendMessages(Message[] msgs) throws MessagingException {
+        throw new MethodNotSupportedException("Message appending is not supported in POP3");
+
+    }
+
+    public Message[] expunge() throws MessagingException {
+        throw new MethodNotSupportedException("Expunge is not supported in POP3");
+    }
+
+    public int getMode() throws IllegalStateException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        return mode;
+    }
+
+    /**
+     * @see javax.mail.Folder#fetch(javax.mail.Message[],
+     *      javax.mail.FetchProfile)
+     * 
+     * The JavaMail API recommends that this method be overrident to provide a
+     * meaningfull implementation.
+     */
+    public synchronized void fetch(Message[] msgs, FetchProfile fp) throws MessagingException {
+        // Can only be performed on an Open folder
+        checkOpen();
+        for (int i = 0; i < msgs.length; i++) {
+            Message msg = msgs[i];
+            
+            if (fp.contains(FetchProfile.Item.ENVELOPE)) {
+                // fetching the size and the subject will force all of the 
+                // envelope information to load 
+                msg.getHeader("Subject"); 
+                msg.getSize(); 
+            }
+            if (fp.contains(FetchProfile.Item.CONTENT_INFO)) {
+                // force the content to load...this also fetches the header information. 
+                // C'est la vie. 
+                ((POP3Message)msg).loadContent(); 
+                msg.getSize(); 
+            }
+            // force flag loading for this message 
+            if (fp.contains(FetchProfile.Item.FLAGS)) {
+                msg.getFlags(); 
+            }
+            
+            if (fp.getHeaderNames().length > 0) {
+                // loading any header loads all headers, so just grab the header set. 
+                msg.getHeader("Subject"); 
+            }
+        }
+    }
+    
+    /**
+     * Retrieve the UID for a given message.
+     * 
+     * @param msg    The message of interest.
+     * 
+     * @return The String UID value for this message.
+     * @exception MessagingException
+     */
+    public synchronized String getUID(Message msg) throws MessagingException {
+        checkOpen(); 
+        // the Message knows how to do this 
+        return ((POP3Message)msg).getUID(); 
+    }
+    
+
+    /**
+     * Below is a list of covinience methods that avoid repeated checking for a
+     * value and throwing an exception
+     */
+
+    /** Ensure the folder is open */
+    private void checkOpen() throws IllegalStateException {
+        if (!isFolderOpen) {
+            throw new IllegalStateException("Folder is not Open");
+        }
+    }
+
+    /** Ensure the folder is not open */
+    private void checkClosed() throws IllegalStateException {
+        if (isFolderOpen) {
+            throw new IllegalStateException("Folder is Open");
+        }
+    }
+
+    /**
+     * @see javax.mail.Folder#notifyMessageChangedListeners(int,
+     *      javax.mail.Message)
+     * 
+     * this method is protected and cannot be used outside of Folder, therefore
+     * had to explicitly expose it via a method in POP3Folder, so that
+     * POP3Message has access to it
+     * 
+     * Bad design on the part of the Java Mail API.
+     */
+    public void notifyMessageChangedListeners(int type, Message m) {
+        super.notifyMessageChangedListeners(type, m);
+    }
+
+    
+    /**
+     * Retrieve the connection attached to this folder.  Throws an
+     * exception if we don't have an active connection.
+     *
+     * @return The current connection object.
+     * @exception MessagingException
+     */
+    protected synchronized POP3Connection getConnection() throws MessagingException {
+        // request a connection from the central store. 
+        return ((POP3Store)store).getFolderConnection(this); 
+    }
+    
+    
+    /**
+     * Release our connection back to the Store.
+     * 
+     * @param connection The connection to release.
+     * 
+     * @exception MessagingException
+     */
+    protected void releaseConnection(POP3Connection connection) throws MessagingException {
+        // we need to release the connection to the Store once we're finished with it 
+        ((POP3Store)store).releaseFolderConnection(this, connection); 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java
new file mode 100644
index 0000000..1d5deb1
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java
@@ -0,0 +1,378 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.IllegalWriteException;
+import javax.mail.MessagingException;
+import javax.mail.event.MessageChangedEvent;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection;
+
+/**
+ * POP3 implementation of javax.mail.internet.MimeMessage
+ * 
+ * Only the most basic information is given and Message objects created here is
+ * a light-weight reference to the actual Message As per the JavaMail spec items
+ * from the actual message will get filled up on demand
+ * 
+ * If some other items are obtained from the server as a result of one call,
+ * then the other details are also processed and filled in. For ex if RETR is
+ * called then header information will also be processed in addition to the
+ * content
+ * 
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+public class POP3Message extends MimeMessage {
+    // the size of the message, in bytes
+    protected int msgSize = -1;
+    // the size of the headers.  We keep this around, as it's needed to 
+    // properly calculate the size of the message 
+    protected int headerSize = -1;
+    // the UID value retrieved from the server 
+    protected String uid; 
+    // the raw message data from loading the message
+    protected byte[] messageData; 
+
+    /**
+     * Create a new POP3 message associated with a folder.
+     * 
+     * @param folder The owning folder.
+     * @param msgnum The message sequence number in the folder.
+     */
+    protected POP3Message(Folder folder, int msgnum) {
+        super(folder, msgnum);
+        this.session = session;
+        // force the headers to empty so we'll load them the first time they're referenced. 
+        this.headers = null; 
+    }
+
+    /**
+     * Get an InputStream for reading the message content. 
+     * 
+     * @return An InputStream instance initialized to read the message 
+     *         content.
+     * @exception MessagingException
+     */
+    protected InputStream getContentStream() throws MessagingException {
+        // make sure the content is loaded first 
+        loadContent(); 
+        // allow the super class to handle creating it from the loaded content.
+        return super.getContentStream();
+    }
+
+
+    /**
+     * Write out the byte data to the provided output stream.
+     *
+     * @param out    The target stream.
+     *
+     * @exception IOException
+     * @exception MessagingException
+     */
+    public void writeTo(OutputStream out) throws IOException, MessagingException {
+        // make sure we have everything loaded 
+        loadContent(); 
+        // just write out the raw message data 
+        out.write(messageData); 
+    }
+    
+
+    /**
+     * Set a flag value for this Message.  The flags are 
+     * only set locally, not the server.  When the folder 
+     * is closed, any messages with the Deleted flag set 
+     * will be removed from the server. 
+     * 
+     * @param newFlags The new flag values.
+     * @param set      Indicates whether this is a set or an unset operation.
+     * 
+     * @exception MessagingException
+     */
+    public void setFlags(Flags newFlags, boolean set) throws MessagingException {
+        Flags oldFlags = (Flags) flags.clone();
+        super.setFlags(newFlags, set);
+
+        if (!flags.equals(oldFlags)) {
+            ((POP3Folder) folder).notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, this);
+        }
+    }
+
+    /**
+     * Unconditionally load the headers from an inputstream. 
+     * When retrieving content, we get back the entire message, 
+     * including the headers.  This allows us to skip over 
+     * them to reach the content, even if we already have 
+     * headers loaded. 
+     * 
+     * @param in     The InputStream with the header data.
+     * 
+     * @exception MessagingException
+     */
+    protected void loadHeaders(InputStream in) throws MessagingException {
+        try {
+            headerSize = in.available(); 
+            // just load and replace the haders 
+            headers = new InternetHeaders(in);
+            headerSize -= in.available(); 
+        } catch (IOException e) {
+            // reading from a ByteArrayInputStream...this should never happen. 
+        }
+    }
+    
+    /**
+     * Lazy loading of the message content. 
+     * 
+     * @exception MessagingException
+     */
+    protected void loadContent() throws MessagingException {
+        if (content == null) {
+            POP3Connection connection = getConnection(); 
+            try {
+                // retrieve (and save the raw message data 
+                messageData = connection.retrieveMessageData(msgnum);
+            } finally {
+                // done with the connection
+                releaseConnection(connection); 
+            }
+            // now create a input stream for splitting this into headers and 
+            // content 
+            ByteArrayInputStream in = new ByteArrayInputStream(messageData); 
+            
+            // the Sun implementation has an option that forces headers loaded using TOP 
+            // should be forgotten when retrieving the message content.  This is because 
+            // some POP3 servers return different results for TOP and RETR.  Since we need to 
+            // retrieve the headers anyway, and this set should be the most complete, we'll 
+            // just replace the headers unconditionally. 
+            loadHeaders(in);
+            // load headers stops loading at the header terminator.  Everything 
+            // after that is content. 
+            loadContent(in);
+        }
+    }
+
+    /**
+     * Load the message content from the server.
+     * 
+     * @param stream A ByteArrayInputStream containing the message content.
+     *               We explicitly use ByteArrayInputStream because
+     *               there are some optimizations that can take advantage
+     *               of the fact it is such a stream.
+     * 
+     * @exception MessagingException
+     */
+    protected void loadContent(ByteArrayInputStream stream) throws MessagingException {
+        // since this is a byte array input stream, available() returns reliable value. 
+        content = new byte[stream.available()];
+        try {
+            // just read everything in to the array 
+            stream.read(content); 
+        } catch (IOException e) {
+            // should never happen 
+            throw new MessagingException("Error loading content info", e);
+        }
+    }
+
+    /**
+     * Get the size of the message.
+     * 
+     * @return The calculated message size, in bytes. 
+     * @exception MessagingException
+     */
+    public int getSize() throws MessagingException {
+        if (msgSize < 0) {
+            // we need to get the headers loaded, since we need that information to calculate the total 
+            // content size without retrieving the content. 
+            loadHeaders();  
+            
+            POP3Connection connection = getConnection(); 
+            try {
+
+                // get the total message size, and adjust by size of the headers to get the content size. 
+                msgSize = connection.retrieveMessageSize(msgnum) - headerSize; 
+            } finally {
+                // done with the connection
+                releaseConnection(connection); 
+            }
+        }
+        return msgSize;
+    }
+
+    /**
+     * notice that we pass zero as the no of lines from the message,as it
+     * doesn't serv any purpose to get only a certain number of lines.
+     * 
+     * However this maybe important if a mail client only shows 3 or 4 lines of
+     * the message in the list and then when the user clicks they would load the
+     * message on demand.
+     * 
+     */
+    protected void loadHeaders() throws MessagingException {
+        if (headers == null) {
+            POP3Connection connection = getConnection(); 
+            try {
+                loadHeaders(connection.retrieveMessageHeaders(msgnum)); 
+            } finally {
+                // done with the connection
+                releaseConnection(connection); 
+            }
+        }
+    }
+    
+    /**
+     * Retrieve the message UID from the server.
+     * 
+     * @return The string UID value. 
+     * @exception MessagingException
+     */
+    protected String getUID() throws MessagingException {
+        if (uid == null) {
+            POP3Connection connection = getConnection(); 
+            try {
+                uid = connection.retrieveMessageUid(msgnum); 
+            } finally {
+                // done with the connection
+                releaseConnection(connection); 
+            }
+        }
+        return uid; 
+    }
+    
+    // The following are methods that deal with all header accesses.  Most of the 
+    // methods that retrieve information from the headers funnel through these, so we 
+    // can lazy-retrieve the header information. 
+
+    public String[] getHeader(String name) throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getHeader(name); 
+    }
+
+    public String getHeader(String name, String delimiter) throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getHeader(name, delimiter); 
+    }
+
+    public Enumeration getAllHeaders() throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getAllHeaders(); 
+    }
+
+    public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getMatchingHeaders(names); 
+    }
+
+    public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getNonMatchingHeaders(names); 
+    }
+
+    public Enumeration getAllHeaderLines() throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getAllHeaderLines();       
+    }
+
+    public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getMatchingHeaderLines(names); 
+    }
+
+    public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
+        // make sure the headers are loaded 
+        loadHeaders(); 
+        // allow the super class to handle everything from here 
+        return super.getNonMatchingHeaderLines(names); 
+    }
+
+    // the following are overrides for header modification methods. These
+    // messages are read only,
+    // so the headers cannot be modified.
+    public void addHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("POP3 messages are read-only");
+    }
+
+    public void setHeader(String name, String value) throws MessagingException {
+        throw new IllegalWriteException("POP3 messages are read-only");
+    }
+
+    public void removeHeader(String name) throws MessagingException {
+        throw new IllegalWriteException("POP3 messages are read-only");
+    }
+
+    public void addHeaderLine(String line) throws MessagingException {
+        throw new IllegalWriteException("POP3 messages are read-only");
+    }
+
+    /**
+     * We cannot modify these messages
+     */
+    public void saveChanges() throws MessagingException {
+        throw new IllegalWriteException("POP3 messages are read-only");
+    }
+
+    
+    /**
+     * get the current connection pool attached to the folder.  We need
+     * to do this dynamically, to A) ensure we're only accessing an
+     * currently open folder, and B) to make sure we're using the
+     * correct connection attached to the folder.
+     *
+     * @return A connection attached to the hosting folder.
+     */
+    protected POP3Connection getConnection() throws MessagingException {
+        // the folder owns everything.
+        return ((POP3Folder)folder).getMessageConnection();
+    }
+    
+    /**
+     * Release the connection back to the Folder after performing an operation 
+     * that requires a connection.
+     * 
+     * @param connection The previously acquired connection.
+     */
+    protected void releaseConnection(POP3Connection connection) throws MessagingException {
+        // the folder owns everything.
+        ((POP3Folder)folder).releaseMessageConnection(connection);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java
new file mode 100644
index 0000000..99cde3b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java
@@ -0,0 +1,142 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.pop3;
+
+import javax.mail.Folder; 
+import javax.mail.Message; 
+import javax.mail.MessagingException; 
+import javax.mail.MethodNotSupportedException;
+import javax.mail.Store; 
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection; 
+
+/**
+ * An POP3 folder instance for the root of POP3 folder tree.  This has 
+ * some of the folder operations disabled. 
+ */
+public class POP3RootFolder extends POP3Folder {
+    // the inbox folder is the only one that exists 
+    protected Folder inbox; 
+    
+    /**
+     * Create a default POP3RootFolder attached to a specific Store instance.
+     * 
+     * @param store  The Store instance this is the root for.
+     */
+    public POP3RootFolder(POP3Store store) {
+        // create a folder with a null string name and the default separator. 
+        super(store, ""); 
+        // this only holds folders 
+        folderType = HOLDS_FOLDERS; 
+        // this folder does exist
+        exists = true; 
+        // no messages in this folder 
+        msgCount = 0; 
+    }
+
+    
+    /**
+     * Get the parent.  This is the root folder, which 
+     * never has a parent. 
+     * 
+     * @return Always returns null. 
+     */
+    public Folder getParent() {
+        // we never have a parent folder 
+        return null; 
+    }
+
+    /**
+     * We have a separator because the root folder is "special". 
+     */
+    public char getSeparator() throws MessagingException {
+        return '/';
+    }
+    
+    /**
+     * Retrieve a list of folders that match a pattern.
+     * 
+     * @param pattern The match pattern.
+     * 
+     * @return An array of matching folders.
+     * @exception MessagingException
+     */
+    public Folder[] list(String pattern) throws MessagingException {
+        // I'm not sure this is correct, but the Sun implementation appears to 
+        // return a array containing the inbox regardless of what pattern was specified. 
+        return new Folder[] { getInbox() };
+    }
+    
+    /**
+     * Get a folder of a given name from the root folder.
+     * The Sun implementation seems somewhat inconsistent 
+     * here.  The docs for Store claim that only INBOX is 
+     * supported, but it will return a Folder instance for any 
+     * name.  On the other hand, the root folder raises 
+     * an exception for anything but the INBOX.
+     * 
+     * @param name   The folder name (which must be "INBOX".
+     * 
+     * @return The inbox folder instance. 
+     * @exception MessagingException
+     */
+    public Folder getFolder(String name) throws MessagingException {
+        if (!name.equalsIgnoreCase("INBOX")) {
+            throw new MessagingException("Only the INBOX folder is supported"); 
+        }
+        // return the inbox folder 
+        return getInbox(); 
+    }
+    
+    /**
+     * Override for the isOpen method.  The root folder can 
+     * never be opened. 
+     * 
+     * @return always returns false. 
+     */
+    public boolean isOpen() {
+        return false; 
+    }
+    
+    public void open(int mode) throws MessagingException {
+        throw new MessagingException("POP3 root folder cannot be opened"); 
+    }
+    
+    public void open(boolean expunge) throws MessagingException {
+        throw new MessagingException("POP3 root folder cannot be close"); 
+    }
+    
+    
+    /**
+     * Retrieve the INBOX folder from the root. 
+     * 
+     * @return The Folder instance for the inbox. 
+     * @exception MessagingException
+     */
+    protected Folder getInbox() throws MessagingException {
+        // we're the only place that creates folders, and 
+        // we only create the single instance. 
+        if (inbox == null) {
+            inbox = new POP3Folder((POP3Store)store, "INBOX"); 
+        }
+        return inbox; 
+    }
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java
new file mode 100644
index 0000000..c92b922
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java
@@ -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 org.apache.geronimo.javamail.store.pop3;
+
+import javax.mail.Session;
+import javax.mail.URLName;
+
+/**
+ * POP3 implementation of javax.mail.Store over an SSL connection.
+ *
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+public class POP3SSLStore extends POP3Store {
+    /**
+     * Construct an POP3SSLStore item.
+     *
+     * @param session The owning javamail Session.
+     * @param urlName The Store urlName, which can contain server target information.
+     */
+	public POP3SSLStore(Session session, URLName urlName) {
+        // we're the imaps protocol, our default connection port is 993, and we must use
+        // an SSL connection for the initial hookup 
+		super(session, urlName, "pop3s", DEFAULT_POP3_SSL_PORT, true);
+	}
+}
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
new file mode 100644
index 0000000..5be4af5
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
@@ -0,0 +1,359 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3;
+ 
+import java.io.PrintStream; 
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.mail.AuthenticationFailedException;
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+
+import org.apache.geronimo.javamail.store.pop3.connection.POP3Connection; 
+import org.apache.geronimo.javamail.store.pop3.connection.POP3ConnectionPool; 
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+
+/**
+ * POP3 implementation of javax.mail.Store POP protocol spec is implemented in
+ * org.apache.geronimo.javamail.store.pop3.POP3Connection
+ * 
+ * @version $Rev: 693530 $ $Date: 2008-09-09 13:57:23 -0400 (Tue, 09 Sep 2008) $
+ */
+
+public class POP3Store extends Store {
+    protected static final int DEFAULT_POP3_PORT = 110;
+    protected static final int DEFAULT_POP3_SSL_PORT = 995;
+    
+    
+    // our accessor for protocol properties and the holder of 
+    // protocol-specific information 
+    protected ProtocolProperties props; 
+    // our connection object    
+    protected POP3ConnectionPool connectionPool; 
+    // our session provided debug output stream.
+    protected PrintStream debugStream;
+    // the debug flag 
+    protected boolean debug; 
+    // the root folder 
+    protected POP3RootFolder root; 
+    // until we're connected, we're closed 
+    boolean closedForBusiness = true; 
+    protected LinkedList openFolders = new LinkedList(); 
+    
+    
+    public POP3Store(Session session, URLName name) {
+        this(session, name, "pop3", DEFAULT_POP3_PORT, false);
+    }
+
+    /**
+     * Common constructor used by the POP3Store and POP3SSLStore classes
+     * to do common initialization of defaults.
+     *
+     * @param session
+     *            The host session instance.
+     * @param name
+     *            The URLName of the target.
+     * @param protocol
+     *            The protocol type ("pop3"). This helps us in
+     *            retrieving protocol-specific session properties.
+     * @param defaultPort
+     *            The default port used by this protocol. For pop3, this will
+     *            be 110. The default for pop3 with ssl is 995.
+     * @param sslConnection
+     *            Indicates whether an SSL connection should be used to initial
+     *            contact the server. This is different from the STARTTLS
+     *            support, which switches the connection to SSL after the
+     *            initial startup.
+     */
+    protected POP3Store(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+        super(session, name);
+        
+        // create the protocol property holder.  This gives an abstraction over the different 
+        // flavors of the protocol. 
+        props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
+
+        // get our debug settings
+        debugStream = session.getDebugOut();
+        debug = session.getDebug(); 
+        // the connection pool manages connections for the stores, folder, and message usage. 
+        connectionPool = new POP3ConnectionPool(this, props); 
+    }
+
+
+    /**
+     * Return a Folder object that represents the root of the namespace for the current user.
+     *
+     * Note that in some store configurations (such as IMAP4) the root folder might
+     * not be the INBOX folder.
+     *
+     * @return the root Folder
+     * @throws MessagingException if there was a problem accessing the store
+     */
+	public Folder getDefaultFolder() throws MessagingException {
+		checkConnectionStatus();
+        // if no root yet, create a root folder instance. 
+        if (root == null) {
+            return new POP3RootFolder(this);
+        }
+        return root;
+	}
+
+    /**
+     * Return the Folder corresponding to the given name.
+     * The folder might not physically exist; the {@link Folder#exists()} method can be used
+     * to determine if it is real.
+     * 
+     * @param name   the name of the Folder to return
+     * 
+     * @return the corresponding folder
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+	public Folder getFolder(String name) throws MessagingException {
+        return getDefaultFolder().getFolder(name);
+	}
+
+    
+    /**
+     * Return the folder identified by the URLName; the URLName must refer to this Store.
+     * Implementations may use the {@link URLName#getFile()} method to determined the folder name.
+     * 
+     * @param url
+     * 
+     * @return the corresponding folder
+     * @throws MessagingException
+     *                if there was a problem accessing the store
+     */
+	public Folder getFolder(URLName url) throws MessagingException {
+        return getDefaultFolder().getFolder(url.getFile());
+	}
+
+    
+    /**
+     * @see javax.mail.Service#protocolConnect(java.lang.String, int,
+     *      java.lang.String, java.lang.String)
+     */
+    protected synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        
+        if (debug) {
+            debugOut("Connecting to server " + host + ":" + port + " for user " + username);
+        }
+
+        // the connection pool handles all of the details here. 
+        if (connectionPool.protocolConnect(host, port, username, password)) 
+        {
+            // the store is now open 
+            closedForBusiness = false; 
+            return true; 
+        }
+        return false; 
+    }
+    
+    
+    /**
+     * Get a connection for the store. 
+     * 
+     * @return The request connection object. 
+     * @exception MessagingException
+     */
+    protected POP3Connection getConnection() throws MessagingException {
+        return connectionPool.getConnection(); 
+    }
+    
+    /**
+     * Return a connection back to the connection pool after 
+     * it has been used for a request. 
+     * 
+     * @param connection The return connection.
+     * 
+     * @exception MessagingException
+     */
+    protected void releaseConnection(POP3Connection connection) throws MessagingException {
+        connectionPool.releaseConnection(connection); 
+    }
+    
+    /**
+     * Get a connection object for a folder to use. 
+     * 
+     * @param folder The requesting folder (always the inbox for POP3).
+     * 
+     * @return An active POP3Connection. 
+     * @exception MessagingException
+     */
+    synchronized POP3Connection getFolderConnection(POP3Folder folder) throws MessagingException {
+        POP3Connection connection = connectionPool.getConnection(); 
+        openFolders.add(folder);
+        return connection; 
+    }
+    
+    /**
+     * Release a connection object after a folder is 
+     * finished with a request. 
+     * 
+     * @param folder     The requesting folder.
+     * @param connection
+     * 
+     * @exception MessagingException
+     */
+    synchronized void releaseFolderConnection(POP3Folder folder, POP3Connection connection) throws MessagingException {
+        openFolders.remove(folder); 
+        // return this back to the pool 
+        connectionPool.releaseConnection(connection); 
+    }
+    
+    /**
+     * Close all open folders.  We have a small problem here with a race condition.  There's no safe, single
+     * synchronization point for us to block creation of new folders while we're closing.  So we make a copy of
+     * the folders list, close all of those folders, and keep repeating until we're done.
+     */
+    protected void closeOpenFolders() {
+        // we're no longer accepting additional opens.  Any folders that open after this point will get an
+        // exception trying to get a connection.
+        closedForBusiness = true;
+
+        while (true) {
+            List folders = null;
+
+            // grab our lock, copy the open folders reference, and null this out.  Once we see a null
+            // open folders ref, we're done closing.
+            synchronized(connectionPool) {
+                folders = openFolders;
+                openFolders = new LinkedList();
+            }
+
+            // null folder, we're done
+            if (folders.isEmpty()) {
+                return;
+            }
+            // now close each of the open folders.
+            for (int i = 0; i < folders.size(); i++) {
+                POP3Folder folder = (POP3Folder)folders.get(i);
+                try {
+                    folder.close(false);
+                } catch (MessagingException e) {
+                }
+            }
+        }
+    }
+    
+
+    /**
+     * @see javax.mail.Service#isConnected()
+     */
+    public boolean isConnected() {
+        // the connect() method of the super class checks here first.  If the connected flag 
+        // is off, then it's too early for use to try to get a connection and verify we still 
+        // have a live one.  
+        if (!super.isConnected()) {
+            return false; 
+        }
+        try {
+            POP3Connection connection = getConnection(); 
+            // a null connection likely means we had a failure establishing a 
+            // new connection to the POP3 server.  
+            if (connection == null) {
+                return false; 
+            }
+            try {
+                // make sure the server is really there 
+                connection.pingServer(); 
+                return true; 
+            }
+            finally {
+                // return the connection to the pool when finished 
+                if (connection != null) {
+                    releaseConnection(connection); 
+                }
+            }
+        } catch (MessagingException e) {
+        }
+        return false; 
+    }
+
+    /**
+     * Close the store, and any open folders associated with the 
+     * store. 
+     * 
+     * @exception MessagingException
+     */
+	public synchronized void close() throws MessagingException{
+        // if already closed, nothing to do. 
+        if (closedForBusiness) {
+            return; 
+        }
+        
+        // close the folders first, then shut down the Store. 
+        closeOpenFolders();
+        
+        connectionPool.close(); 
+        connectionPool = null; 
+
+		// make sure we do the superclass close operation first so 
+        // notification events get broadcast properly. 
+		super.close();
+	}
+
+    /**
+     * Check the status of our connection. 
+     * 
+     * @exception MessagingException
+     */
+    private void checkConnectionStatus() throws MessagingException {
+        if (!this.isConnected()) {
+            throw new MessagingException("Not connected ");
+        }
+    }
+
+    /**
+     * Internal debug output routine.
+     *
+     * @param value  The string value to output.
+     */
+    void debugOut(String message) {
+        debugStream.println("POP3Store DEBUG: " + message);
+    }
+
+    /**
+     * Internal debugging routine for reporting exceptions.
+     *
+     * @param message A message associated with the exception context.
+     * @param e       The received exception.
+     */
+    void debugOut(String message, Throwable e) {
+        debugOut("Received exception -> " + message);
+        debugOut("Exception message -> " + e.getMessage());
+        e.printStackTrace(debugStream);
+    }
+    
+    /**
+     * Finalizer to perform IMAPStore() cleanup when 
+     * no longer in use. 
+     * 
+     * @exception Throwable
+     */
+    protected void finalize() throws Throwable {
+        super.finalize(); 
+        close(); 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
new file mode 100644
index 0000000..138834e
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
@@ -0,0 +1,693 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.pop3.connection;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetHeaders;
+
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
+import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseStream;
+import org.apache.geronimo.javamail.store.pop3.POP3Constants;
+import org.apache.geronimo.javamail.util.CommandFailedException;
+import org.apache.geronimo.javamail.util.InvalidCommandException;
+import org.apache.geronimo.javamail.util.MIMEInputReader;
+import org.apache.geronimo.javamail.util.MailConnection;
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+import org.apache.geronimo.mail.util.Base64;
+import org.apache.geronimo.mail.util.Hex;
+
+/**
+ * Simple implementation of POP3 transport.
+ *
+ * @version $Rev: 1641706 $ $Date: 2014-11-25 16:39:49 -0500 (Tue, 25 Nov 2014) $
+ */
+public class POP3Connection extends MailConnection implements POP3Constants {
+
+    static final protected String MAIL_APOP_ENABLED = "apop.enable";
+    static final protected String MAIL_AUTH_ENABLED = "auth.enable";
+    static final protected String MAIL_RESET_QUIT = "rsetbeforequit";
+    static final protected String MAIL_DISABLE_TOP = "disabletop";
+    //static final protected String MAIL_FORGET_TOP = "forgettopheaders"; //TODO forgettopheaders
+
+    // the initial greeting string, which might be required for APOP authentication.
+    protected String greeting;
+    // is use of the AUTH command enabled
+    protected boolean authEnabled;
+    // is use of APOP command enabled
+    protected boolean apopEnabled;
+    // input reader wrapped around the socket input stream
+    protected BufferedReader reader;
+    // output writer wrapped around the socket output stream.
+    protected PrintWriter writer;
+    // this connection was closed unexpectedly
+    protected boolean closed;
+    // indicates whether this connection is currently logged in.  Once
+    // we send a QUIT, we're finished.
+    protected boolean loggedIn;
+    // indicates whether we need to avoid using the TOP command
+    // when retrieving headers
+    protected boolean topDisabled = false;
+    // is TLS enabled on our part?
+    protected boolean useTLS = false;
+    // is TLS required on our part?
+    protected boolean requireTLS = false;
+
+    /**
+     * Normal constructor for an POP3Connection() object.
+     *
+     * @param props  The protocol properties abstraction containing our
+     *               property modifiers.
+     */
+    public POP3Connection(ProtocolProperties props) {
+        super(props);
+
+        // get our login properties flags
+        authEnabled = props.getBooleanProperty(MAIL_AUTH_ENABLED, false);
+        apopEnabled = props.getBooleanProperty(MAIL_APOP_ENABLED, false);
+        topDisabled = props.getBooleanProperty(MAIL_DISABLE_TOP, false);
+        // and also check for TLS enablement.
+        useTLS = props.getBooleanProperty(MAIL_STARTTLS_ENABLE, false);
+        // and also check if TLS is required.
+        requireTLS = props.getBooleanProperty(MAIL_STARTTLS_REQUIRED, false);
+       
+    }
+
+
+    /**
+     * Connect to the server and do the initial handshaking.
+     *
+     * @exception MessagingException
+     */
+    public boolean protocolConnect(String host, int port, String authid, String realm, String username, String password) throws MessagingException {
+        this.serverHost = host;
+        this.serverPort = port;
+        this.realm = realm;
+        this.authid = authid;
+        this.username = username;
+        this.password = password;
+
+        try {
+            // create socket and connect to server.
+            getConnection();
+            // consume the welcome line
+            getWelcome();
+            
+            // if we're not already using an SSL connection, and we have permission to issue STARTTLS or its even required
+            // try to setup a SSL connection
+            if (!sslConnection && (useTLS || requireTLS)) {
+                
+                    // tell the server of our intention to start a TLS session
+                    POP3Response starttlsResponse = null;
+                    try {
+                        starttlsResponse = sendCommand("STLS");
+                    } catch (CommandFailedException e) {
+                       
+                    }
+                    
+                    //if the server does not support TLS check if its required.
+                    //If true then throw an error, if not establish a non SSL connection
+                    if(requireTLS && (starttlsResponse == null || starttlsResponse.isError())) {
+                        throw new MessagingException("Server doesn't support required transport level security");
+                    } else if(starttlsResponse != null && starttlsResponse.getStatus() == POP3Response.OK) {
+                     // The connection is then handled by the superclass level.
+                        getConnectedTLSSocket();
+                    } else {
+                        if (debug) {
+                            debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
+                        }
+                    }
+            }
+            
+            getConnection();
+            
+            // go login with the server
+            if (login())
+            {
+                loggedIn = true;
+                return true;
+            }
+            return false;
+        } catch (IOException e) {
+            if (debug) {
+                debugOut("I/O exception establishing connection", e);
+            }
+            throw new MessagingException("Connection error", e);
+        }
+    }
+
+
+    /**
+     * Create a transport connection object and connect it to the
+     * target server.
+     *
+     * @exception MessagingException
+     */
+    protected void getConnection() throws MessagingException
+    {
+        try {
+            // do all of the non-protocol specific set up.  This will get our socket established
+            // and ready use.
+            super.getConnection();
+        } catch (IOException e) {
+            throw new MessagingException("Unable to obtain a connection to the POP3 server", e);
+        }
+
+        // The POP3 protocol is inherently a string-based protocol, so we get
+        // string readers/writers for the connection streams.  Note that we explicitly
+        // set the encoding to ensure that an inappropriate native encoding is not picked up.
+        try {
+            reader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859-1"));
+            writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), "ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
+    }
+
+    protected void getWelcome() throws IOException {
+        // just read the line and consume it.  If debug is
+        // enabled, there I/O stream will be traced
+        greeting = reader.readLine();
+    }
+
+    public String toString() {
+        return "POP3Connection host: " + serverHost + " port: " + serverPort;
+    }
+
+
+    /**
+     * Close the connection.  On completion, we'll be disconnected from
+     * the server and unable to send more data.
+     *
+     * @exception MessagingException
+     */
+    public void close() throws MessagingException {
+        // if we're already closed, get outta here.
+        if (socket == null) {
+            return;
+        }
+        try {
+            // say goodbye
+            logout();
+        } finally {
+            // and close up the connection.  We do this in a finally block to make sure the connection
+            // is shut down even if quit gets an error.
+            closeServerConnection();
+            // get rid of our response processor too.
+            reader = null;
+            writer = null;
+        }
+    }
+
+
+    /**
+     * Tag this connection as having been closed by the
+     * server.  This will not be returned to the
+     * connection pool.
+     */
+    public void setClosed() {
+        closed = true;
+    }
+
+    /**
+     * Test if the connection has been forcibly closed.
+     *
+     * @return True if the server disconnected the connection.
+     */
+    public boolean isClosed() {
+        return closed;
+    }
+
+    protected POP3Response sendCommand(String cmd) throws MessagingException {
+        return sendCommand(cmd, false);
+    }
+
+    protected POP3Response sendMultiLineCommand(String cmd) throws MessagingException {
+        return sendCommand(cmd, true);
+    }
+
+    protected synchronized POP3Response sendCommand(String cmd, boolean multiLine) throws MessagingException {
+        if (socket.isConnected()) {
+            {
+                // NOTE:  We don't use println() because it uses the platform concept of a newline rather
+                // than using CRLF, which is required by the POP3 protocol.
+                writer.write(cmd);
+                writer.write("\r\n");
+                writer.flush();
+
+                POP3Response response = buildResponse(multiLine);
+                if (response.isError()) {
+                    throw new CommandFailedException("Error issuing POP3 command: " + cmd);
+                }
+                return response;
+            }
+        }
+        throw new MessagingException("Connection to Mail Server is lost, connection " + this.toString());
+    }
+
+    /**
+     * Build a POP3Response item from the response stream.
+     *
+     * @param isMultiLineResponse
+     *               If true, this command is expecting multiple lines back from the server.
+     *
+     * @return A POP3Response item with all of the command response data.
+     * @exception MessagingException
+     */
+    protected POP3Response buildResponse(boolean isMultiLineResponse) throws MessagingException {
+        int status = ERR;
+        byte[] data = null;
+
+        String line;
+        //MIMEInputReader source = new MIMEInputReader(reader); //TODO unused
+
+        try {
+            line = reader.readLine();
+        } catch (IOException e) {
+            throw new MessagingException("Error in receving response");
+        }
+
+        if (line == null || line.trim().equals("")) {
+            throw new MessagingException("Empty Response");
+        }
+
+        if (line.startsWith("+OK")) {
+            status = OK;
+            line = removeStatusField(line);
+            if (isMultiLineResponse) {
+                data = getMultiLineResponse();
+            }
+        } else if (line.startsWith("-ERR")) {
+            status = ERR;
+            line = removeStatusField(line);
+        }else if (line.startsWith("+")) {
+        	status = CHALLENGE;
+        	line = removeStatusField(line);
+        	if (isMultiLineResponse) {
+        		data = getMultiLineResponse();
+        	}
+        } else {
+            throw new MessagingException("Unexpected response: " + line);
+        }
+        return new POP3Response(status, line, data);
+    }
+
+    private static String removeStatusField(String line) {
+        return line.substring(line.indexOf(SPACE) + 1);
+    }
+
+    /**
+     * This could be a multiline response
+     */
+    private byte[] getMultiLineResponse() throws MessagingException {
+
+        MIMEInputReader source = new MIMEInputReader(reader);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        // it's more efficient to do this a buffer at a time.
+        // the MIMEInputReader takes care of the byte-stuffing and
+        // ".\r\n" input terminator for us.
+        try {
+            OutputStreamWriter outWriter = new OutputStreamWriter(out, "ISO8859-1");
+            char buffer[] = new char[500];
+            try {
+                int charsRead = -1;
+                while ((charsRead = source.read(buffer)) >= 0) {
+                    outWriter.write(buffer, 0, charsRead);
+                }
+                outWriter.flush();
+            } catch (IOException e) {
+                throw new MessagingException("Error processing a multi-line response", e);
+            }
+        } catch (UnsupportedEncodingException e) {
+        }
+        return out.toByteArray();
+    }
+
+
+    /**
+     * Retrieve the raw message content from the POP3
+     * server.  This is all of the message data, including
+     * the header.
+     *
+     * @param sequenceNumber
+     *               The message sequence number.
+     *
+     * @return A byte array containing all of the message data.
+     * @exception MessagingException
+     */
+    public byte[] retrieveMessageData(int sequenceNumber) throws MessagingException {
+        POP3Response msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
+        // we want the data directly in this case.
+        return msgResponse.getData();
+    }
+
+    /**
+     * Retrieve the message header information for a given
+     * message, returned as an input stream suitable
+     * for loading the message data.
+     *
+     * @param sequenceNumber
+     *               The server sequence number for the message.
+     *
+     * @return An inputstream that can be used to read the message
+     *         data.
+     * @exception MessagingException
+     */
+    public ByteArrayInputStream retrieveMessageHeaders(int sequenceNumber) throws MessagingException {
+        POP3Response msgResponse;
+
+        // some POP3 servers don't correctly implement TOP, so this can be disabled.  If
+        // we can't use TOP, then use RETR and retrieve everything.  We can just hand back
+        // the stream, as the header loading routine will stop at the first
+        // null line.
+        if (topDisabled) {
+            msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
+        }
+        else {
+            msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0");
+        }
+
+        // just load the returned message data as a set of headers
+        return msgResponse.getContentStream();
+    }
+
+    /**
+     * Retrieve the total message size from the mail
+     * server.  This is the size of the headers plus
+     * the size of the message content.
+     *
+     * @param sequenceNumber
+     *               The message sequence number.
+     *
+     * @return The full size of the message.
+     * @exception MessagingException
+     */
+    public int retrieveMessageSize(int sequenceNumber) throws MessagingException {
+        POP3Response msgResponse = sendCommand("LIST " + sequenceNumber);
+        // Convert this into the parsed response type we need.
+        POP3ListResponse list = new POP3ListResponse(msgResponse);
+        // this returns the total message size
+        return list.getSize();
+    }
+
+    /**
+     * Retrieve the mail drop status information.
+     *
+     * @return An object representing the returned mail drop status.
+     * @exception MessagingException
+     */
+    public POP3StatusResponse retrieveMailboxStatus() throws MessagingException {
+        // issue the STAT command and return this into a status response
+        return new POP3StatusResponse(sendCommand("STAT"));
+    }
+
+
+    /**
+     * Retrieve the UID for an individual message.
+     *
+     * @param sequenceNumber
+     *               The target message sequence number.
+     *
+     * @return The string UID maintained by the server.
+     * @exception MessagingException
+     */
+    public String retrieveMessageUid(int sequenceNumber) throws MessagingException {
+        POP3Response msgResponse = sendCommand("UIDL " + sequenceNumber);
+
+        String message = msgResponse.getFirstLine();
+        // the UID is everything after the blank separating the message number and the UID.
+        // there's not supposed to be anything else on the message, but trim it of whitespace
+        // just to be on the safe side.
+        return message.substring(message.indexOf(' ') + 1).trim();
+    }
+
+
+    /**
+     * Delete a single message from the mail server.
+     *
+     * @param sequenceNumber
+     *               The sequence number of the message to delete.
+     *
+     * @exception MessagingException
+     */
+    public void deleteMessage(int sequenceNumber) throws MessagingException {
+        // just issue the command...we ignore the command response
+        sendCommand("DELE " + sequenceNumber);
+    }
+
+    /**
+     * Logout from the mail server.  This sends a QUIT
+     * command, which will likely sever the mail connection.
+     *
+     * @exception MessagingException
+     */
+    public void logout() throws MessagingException {
+        // we may have already sent the QUIT command
+        if (!loggedIn) {
+            return;
+        }
+        // just issue the command...we ignore the command response
+        sendCommand("QUIT");
+        loggedIn = false;
+    }
+
+    /**
+     * Perform a reset on the mail server.
+     *
+     * @exception MessagingException
+     */
+    public void reset() throws MessagingException {
+        // some mail servers mark retrieved messages for deletion
+        // automatically.  This will reset the read flags before
+        // we go through normal cleanup.
+        if (props.getBooleanProperty(MAIL_RESET_QUIT, false)) {
+            // just send an RSET command first
+            sendCommand("RSET");
+        }
+    }
+
+    /**
+     * Ping the mail server to see if we still have an active connection.
+     *
+     * @exception MessagingException thrown if we do not have an active connection.
+     */
+    public void pingServer() throws MessagingException {
+        // just issue the command...we ignore the command response
+        sendCommand("NOOP");
+    }
+
+    /**
+     * Login to the mail server, using whichever method is
+     * configured.  This will try multiple methods, if allowed,
+     * in decreasing levels of security.
+     *
+     * @return true if the login was successful.
+     * @exception MessagingException
+     */
+    public synchronized boolean login() throws MessagingException {
+        // permitted to use the AUTH command?
+        if (authEnabled) {
+            try {
+                // go do the SASL thing
+                return processSaslAuthentication();
+            } catch (MessagingException e) {
+                // Any error here means fall back to the next mechanism
+            }
+        }
+
+        if (apopEnabled) {
+            try {
+                // go do the SASL thing
+                return processAPOPAuthentication();
+            } catch (MessagingException e) {
+                // Any error here means fall back to the next mechanism
+            }
+        }
+
+        try {
+            // do the tried and true login processing.
+            return processLogin();
+        } catch (MessagingException e) {
+        }
+        // everything failed...can't get in
+        return false;
+    }
+
+
+    /**
+     * Process a basic LOGIN operation, using the
+     * plain test USER/PASS command combo.
+     *
+     * @return true if we logged successfully.
+     * @exception MessagingException
+     */
+    public boolean processLogin() throws MessagingException {
+        // start by sending the USER command, followed by
+        // the PASS command
+        sendCommand("USER " + username);
+        sendCommand("PASS " + password);
+        return true;       // we're in
+    }
+
+    /**
+     * Process logging in using the APOP command.  Only
+     * works on servers that give a timestamp value
+     * in the welcome response.
+     *
+     * @return true if the login was accepted.
+     * @exception MessagingException
+     */
+    public boolean processAPOPAuthentication() throws MessagingException {
+        int timeStart = greeting.indexOf('<');
+        // if we didn't get an APOP challenge on the greeting, throw an exception
+        // the main login processor will swallow that and fall back to the next
+        // mechanism
+        if (timeStart == -1) {
+            throw new MessagingException("POP3 Server does not support APOP");
+        }
+        int timeEnd = greeting.indexOf('>');
+        String timeStamp = greeting.substring(timeStart, timeEnd + 1);
+
+        // we create the digest password using the timestamp value sent to use
+        // concatenated with the password.
+        String digestPassword = timeStamp + password;
+
+        byte[] digest;
+
+        try {
+            // create a digest value from the password.
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            digest = md.digest(digestPassword.getBytes("iso-8859-1"));
+        } catch (NoSuchAlgorithmException e) {
+            // this shouldn't happen, but if it does, we'll just try a plain
+            // login.
+            throw new MessagingException("Unable to create MD5 digest", e);
+        } catch (UnsupportedEncodingException e) {
+            // this shouldn't happen, but if it does, we'll just try a plain
+            // login.
+            throw new MessagingException("Unable to create MD5 digest", e);
+        }
+        // this will throw an exception if it gives an error failure
+        sendCommand("APOP " + username + " " + new String(Hex.encode(digest)));
+        // no exception, we must have passed
+        return true;
+    }
+
+
+    /**
+     * Process SASL-type authentication.
+     *
+     * @return Returns true if the server support a SASL authentication mechanism and
+     *         accepted reponse challenges.
+     * @exception MessagingException
+     */
+    protected boolean processSaslAuthentication() throws MessagingException {
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
+        if (authenticator == null) {
+            throw new MessagingException("Unable to obtain SASL authenticator");
+        }
+
+        // go process the login.
+        return processLogin(authenticator);
+    }
+
+    /**
+     * Attempt to retrieve a SASL authenticator for this
+     * protocol.
+     *
+     * @return A SASL authenticator, or null if a suitable one
+     *         was not located.
+     */
+    protected ClientAuthenticator getSaslAuthenticator() {
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
+    }
+
+
+    /**
+     * Process a login using the provided authenticator object.
+     *
+     * NB:  This method is synchronized because we have a multi-step process going on
+     * here.  No other commands should be sent to the server until we complete.
+     *
+     * @return Returns true if the server support a SASL authentication mechanism and
+     * accepted reponse challenges.
+     * @exception MessagingException
+     */
+    protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
+        if (debug) {
+            debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
+        }
+
+        POP3Response response = sendCommand("AUTH " + authenticator.getMechanismName());
+
+        // now process the challenge sequence.  We get a continuation response back for each stage of the
+        // authentication, and finally an OK when everything passes muster.
+        while (true) {
+            // this should be a continuation reply, if things are still good.
+            if (response.isChallenge()) {
+                // we're passed back a challenge value, Base64 encoded.
+                byte[] challenge = response.decodeChallengeResponse();
+
+                try {
+                    String responseString = new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII");
+
+                    // have the authenticator evaluate and send back the encoded response.
+                    response = sendCommand(responseString);
+                } catch (UnsupportedEncodingException ex) {
+                }
+            }
+            else {
+                // there are only two choices here, OK or a continuation.  OK means
+                // we've passed muster and are in.
+                return true;
+            }
+        }
+    }
+
+
+    /**
+     * Merge the configured SASL mechanisms with the capabilities that the
+     * server has indicated it supports, returning a merged list that can
+     * be used for selecting a mechanism.
+     *
+     * @return A List representing the intersection of the configured list and the
+     *         capabilities list.
+     */
+    protected List selectSaslMechanisms() {
+        // just return the set that have been explicity permitted
+        return getSaslMechanisms();
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java
new file mode 100644
index 0000000..8aa9c4b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java
@@ -0,0 +1,224 @@
+/**
+ * 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 org.apache.geronimo.javamail.store.pop3.connection;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.mail.MessagingException; 
+import javax.mail.Session;
+import javax.mail.Store;
+
+import javax.mail.StoreClosedException;
+
+import org.apache.geronimo.javamail.store.pop3.POP3Store; 
+import org.apache.geronimo.javamail.util.ProtocolProperties; 
+
+public class POP3ConnectionPool {
+
+    protected static final String MAIL_PORT = "port";
+    
+    protected static final String MAIL_SASL_REALM = "sasl.realm"; 
+    protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid"; 
+
+    protected static final String DEFAULT_MAIL_HOST = "localhost";
+
+    // Our hosting Store instance
+    protected POP3Store store;
+    // our Protocol abstraction 
+    protected ProtocolProperties props; 
+    // POP3 is not nearly as multi-threaded as IMAP.  We really just have a single folder, 
+    // plus the Store, but the Store doesn't really talk to the server very much.  We only
+    // hold one connection available, and on the off chance there is a situation where 
+    // we need to create a new one, we'll authenticate on demand.  The one case where 
+    // I know this might be an issue is a folder checking back with the Store to see it if
+    // it is still connected.  
+    protected POP3Connection availableConnection;      
+    
+    // our debug flag
+    protected boolean debug;
+
+    // the target host
+    protected String host;
+    // the target server port.
+    protected int port;
+    // the username we connect with
+    protected String username;
+    // the authentication password.
+    protected String password;
+    // the SASL realm name 
+    protected String realm; 
+    // the authorization id.  
+    protected String authid; 
+    // Turned on when the store is closed for business. 
+    protected boolean closed = false; 
+
+    /**
+     * Create a connection pool associated with a give POP3Store instance.  The
+     * connection pool manages handing out connections for both the Store and
+     * Folder and Message usage.
+     * 
+     * @param store  The Store we're creating the pool for.
+     * @param props  The protocol properties abstraction we use.
+     */
+    public POP3ConnectionPool(POP3Store store, ProtocolProperties props) {
+        this.store = store;
+        this.props = props; 
+    }
+
+
+    /**
+     * Manage the initial connection to the POP3 server.  This is the first 
+     * point where we obtain the information needed to make an actual server 
+     * connection.  Like the Store protocolConnect method, we return false 
+     * if there's any sort of authentication difficulties. 
+     * 
+     * @param host     The host of the mail server.
+     * @param port     The mail server connection port.
+     * @param user     The connection user name.
+     * @param password The connection password.
+     * 
+     * @return True if we were able to connect and authenticate correctly. 
+     * @exception MessagingException
+     */
+    public synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        // NOTE:  We don't check for the username/password being null at this point.  It's possible that 
+        // the server will send back a PREAUTH response, which means we don't need to go through login 
+        // processing.  We'll need to check the capabilities response after we make the connection to decide 
+        // if logging in is necesssary. 
+        
+        // save this for subsequent connections.  All pool connections will use this info.
+        // if the port is defaulted, then see if we have something configured in the session.
+        // if not configured, we just use the default default.
+        if (port == -1) {
+            // check for a property and fall back on the default if it's not set.
+            port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
+            // it's possible that -1 might have been explicitly set, so one last check. 
+            if (port == -1) {
+                port = props.getDefaultPort(); 
+            }
+        }
+    	
+    	// Before we do anything, let's make sure that we succesfully received a host
+    	if ( host == null ) {
+    		host = DEFAULT_MAIL_HOST;
+    	}
+        
+        this.host = host;
+        this.port = port;
+        this.username = username;
+        this.password = password;
+        
+        // make sure we have the realm information 
+        realm = props.getProperty(MAIL_SASL_REALM); 
+        // get an authzid value, if we have one.  The default is to use the username.
+        authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
+
+        // go create a connection and just add it to the pool.  If there is an authenticaton error, 
+        // return the connect failure, and we may end up trying again. 
+        availableConnection = createPoolConnection(); 
+        if (availableConnection == null) {
+            return false; 
+        }
+        // we're connected, authenticated, and ready to go. 
+        return true; 
+    }
+
+    /**
+     * Creates an authenticated pool connection and adds it to
+     * the connection pool.  If there is an existing connection
+     * already in the pool, this returns without creating a new
+     * connection.
+     *
+     * @exception MessagingException
+     */
+    protected POP3Connection createPoolConnection() throws MessagingException {
+        POP3Connection connection = new POP3Connection(props);
+        if (!connection.protocolConnect(host, port, authid, realm, username, password)) {
+            // we only add live connections to the pool.  Sever the connections and 
+            // allow it to go free. 
+            connection.closeServerConnection(); 
+            return null; 
+        }
+        // just return this connection 
+        return connection; 
+    }
+
+
+    /**
+     * Get a connection from the pool.  We try to retrieve a live
+     * connection, but we test the connection's liveness before
+     * returning one.  If we don't have a viable connection in
+     * the pool, we'll create a new one.  The returned connection
+     * will be in the authenticated state already.
+     *
+     * @return A POP3Connection object that is connected to the server.
+     */
+    public synchronized POP3Connection getConnection() throws MessagingException {
+        // if we have an available one (common when opening the INBOX), just return it 
+        POP3Connection connection = availableConnection; 
+        
+        if (connection != null) {
+            availableConnection = null; 
+            return connection; 
+        }
+        // we need an additional connection...rare, but it can happen if we've closed the INBOX folder. 
+        return createPoolConnection(); 
+    }
+    
+    
+    /**
+     * Return a connection to the connection pool.
+     * 
+     * @param connection The connection getting returned.
+     * 
+     * @exception MessagingException
+     */
+    public synchronized void releaseConnection(POP3Connection connection) throws MessagingException
+    {
+        // we're generally only called if the store needed to talk to the server and 
+        // then returned the connection to the pool.  So it's pretty likely that we'll just cache this
+        if (availableConnection == null) {
+            availableConnection = connection; 
+        }
+        else {
+            // got too many connections created...not sure how, but get rid of this one. 
+            connection.close(); 
+        }
+    }
+    
+    
+    /**
+     * Close the entire connection pool. 
+     * 
+     * @exception MessagingException
+     */
+    public synchronized void close() throws MessagingException {
+        // we'll on have the single connection in reserver 
+        if (availableConnection != null) {
+            availableConnection.close(); 
+            availableConnection = null; 
+        }
+        // turn out the lights, hang the closed sign on the wall. 
+        closed = true; 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java
new file mode 100644
index 0000000..5eeb7ba
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java
@@ -0,0 +1,99 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3.connection;
+
+import java.io.ByteArrayInputStream; 
+
+import java.util.ArrayList; 
+import java.util.List;     
+
+import javax.mail.MessagingException;
+
+/**
+ * This class adds functionality to the basic response by parsing the reply for
+ * LIST command and obtaining specific information about the msgnum and the
+ * size. It could be for one or more msgs depending on wether a msg number was
+ * passed or not into the LIST command
+ * 
+ * @see org.apache.geronimo.javamail.store.pop3.POP3Response
+ * @see org.apache.geronimo.javamail.store.pop3.response.DefaultPOP3Response
+ * 
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+
+public class POP3ListResponse extends POP3Response {
+
+    private int msgnum = 0;
+
+    private int size = 0;
+
+    private List multipleMsgs = null;
+
+    POP3ListResponse(POP3Response baseRes) throws MessagingException {
+        super(baseRes.getStatus(), baseRes.getFirstLine(), baseRes.getData());
+
+        // if ERR not worth proceeding any further
+        if (OK == getStatus()) {
+
+            // if data == null, then it mean it's a single line response
+            if (baseRes.getData() == null) {
+                String[] args = getFirstLine().split(SPACE);
+                try {
+                    msgnum = Integer.parseInt(args[0]);
+                } catch (NumberFormatException e) {
+                    throw new MessagingException("Invalid response for LIST command", e);
+                }
+                try {
+                    size = Integer.parseInt(args[1]);
+                } catch (NumberFormatException e) {
+                    throw new MessagingException("Invalid response for LIST command", e);
+                }
+            } else {
+                int totalMsgs = 0;
+                String[] args = getFirstLine().split(SPACE);
+                try {
+                    totalMsgs = Integer.parseInt(args[0]);
+                } catch (NumberFormatException e) {
+                    throw new MessagingException("Invalid response for LIST command", e);
+                }
+                multipleMsgs = new ArrayList(totalMsgs);
+                // Todo : multi-line response parsing
+            }
+
+        }
+    }
+
+    public int getMessageNumber() {
+        return msgnum;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Messages can be accessed by multipleMsgs.getElementAt(msgnum)
+     * 
+     */
+    public List getMultipleMessageDetails() {
+        return multipleMsgs;
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java
new file mode 100644
index 0000000..e4fc2aa
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java
@@ -0,0 +1,85 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3.connection;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.geronimo.javamail.store.pop3.POP3Constants;
+
+import org.apache.geronimo.mail.util.Base64;
+
+/**
+ * This class provides the basic implementation for the POP3Response.
+ * 
+ * @see org.apache.geronimo.javamail.store.pop3.POP3Response
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+
+public class POP3Response implements POP3Constants {
+
+    private int status = ERR;
+
+    private String firstLine;
+
+    private byte[] data;
+
+    POP3Response(int status, String firstLine, byte []data) {
+        this.status = status;
+        this.firstLine = firstLine;
+        this.data = data;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+    
+    public byte[] getData() {
+        return data; 
+    }
+
+    public ByteArrayInputStream getContentStream() {
+        return new ByteArrayInputStream(data);
+    }
+
+    public String getFirstLine() {
+        return firstLine;
+    }
+    
+    public boolean isError() {
+        return status == ERR; 
+    }
+    
+    public boolean isChallenge() {
+        return status == CHALLENGE; 
+    }
+    
+    /**
+     * Decode the message portion of a continuation challenge response.
+     * 
+     * @return The byte array containing the decoded data. 
+     */
+    public byte[] decodeChallengeResponse() 
+    {
+        // the challenge response is a base64 encoded string...
+        return Base64.decode(firstLine.trim()); 
+    }
+
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java
new file mode 100644
index 0000000..7472cfc
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.geronimo.javamail.store.pop3.connection;
+
+import javax.mail.MessagingException;
+
+/**
+ * This class adds functionality to the basic response by parsing the status
+ * line and obtaining specific information about num of msgs and the size
+ * 
+ * @see org.apache.geronimo.javamail.store.pop3.POP3Response
+ * @see org.apache.geronimo.javamail.store.pop3.response.DefaultPOP3Response
+ * 
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+
+public class POP3StatusResponse extends POP3Response {
+
+    private int numMessages = 0;
+
+    private int size = 0;
+
+    POP3StatusResponse(POP3Response baseRes) throws MessagingException {
+        super(baseRes.getStatus(), baseRes.getFirstLine(), baseRes.getData());
+
+        // if ERR not worth proceeding any further
+        if (OK == getStatus()) {
+            String[] args = getFirstLine().split(SPACE);
+            try {
+                numMessages = Integer.parseInt(args[0]);
+            } catch (NumberFormatException e) {
+                throw new MessagingException("Invalid response for STAT command", e);
+            }
+            try {
+                size = Integer.parseInt(args[1]);
+            } catch (NumberFormatException e) {
+                throw new MessagingException("Invalid response for STAT command", e);
+            }
+        }
+    }
+
+    public int getNumMessages() {
+        return numMessages;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
new file mode 100644
index 0000000..8ab1e2f
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
@@ -0,0 +1,728 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.nntp;
+
+import java.io.BufferedReader;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+
+import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
+import org.apache.geronimo.javamail.util.MailConnection;
+import org.apache.geronimo.javamail.util.MIMEOutputStream;
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+import org.apache.geronimo.mail.util.Base64;
+import org.apache.geronimo.mail.util.SessionUtil;
+
+/**
+ * Simple implementation of NNTP transport. Just does plain RFC977-ish delivery.
+ *
+ * @version $Rev: 953638 $ $Date: 2010-06-11 06:09:00 -0400 (Fri, 11 Jun 2010) $
+ */
+public class NNTPConnection extends MailConnection {
+
+    /**
+     * constants for EOL termination
+     */
+    protected static final char CR = '\r';
+
+    protected static final char LF = '\n';
+
+    /**
+     * property keys for protocol properties.
+     */
+    protected static final int DEFAULT_NNTP_PORT = 119;
+    // does the server support posting?
+    protected boolean postingAllowed = true;
+
+    // different authentication mechanisms
+    protected boolean authInfoUserAllowed = false;
+    protected boolean authInfoSaslAllowed = false;
+
+    // the last response line received from the server.
+    protected NNTPReply lastServerResponse = null;
+
+    // the welcome string from the server.
+    protected String welcomeString = null;
+
+    // input reader wrapped around the socket input stream
+    protected BufferedReader reader;
+    // output writer wrapped around the socket output stream.
+    protected PrintWriter writer;
+
+    /**
+     * Normal constructor for an NNTPConnection() object.
+     *
+     * @param props  The property bundle for this protocol instance.
+     */
+    public NNTPConnection(ProtocolProperties props) {
+        super(props);
+    }
+
+
+    /**
+     * Connect to the server and do the initial handshaking.
+     *
+     * @param host     The target host name.
+     * @param port     The target port
+     * @param username The connection username (can be null)
+     * @param password The authentication password (can be null).
+     *
+     * @return true if we were able to obtain a connection and
+     *         authenticate.
+     * @exception MessagingException
+     */
+    public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        super.protocolConnect(host, port, username, password);
+        // create socket and connect to server.
+        getConnection();
+
+        // receive welcoming message
+        getWelcome();
+
+        return true;
+    }
+
+
+    /**
+     * Create a transport connection object and connect it to the
+     * target server.
+     *
+     * @exception MessagingException
+     */
+    protected void getConnection() throws MessagingException
+    {
+        try {
+            // do all of the non-protocol specific set up.  This will get our socket established
+            // and ready use.
+            super.getConnection();
+        } catch (IOException e) {
+            throw new MessagingException("Unable to obtain a connection to the NNTP server", e);
+        }
+
+        // The NNTP protocol is inherently a string-based protocol, so we get
+        // string readers/writers for the connection streams.  Note that we explicitly
+        // set the encoding to ensure that an inappropriate native encoding is not picked up.
+        try {
+            reader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859-1"));
+            writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), "ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
+    }
+
+
+    /**
+     * Close the connection. On completion, we'll be disconnected from the
+     * server and unable to send more data.
+     *
+     * @exception MessagingException
+     */
+    public void close() throws MessagingException {
+        // if we're already closed, get outta here.
+        if (socket == null) {
+            return;
+        }
+        try {
+            // say goodbye
+            sendQuit();
+        } finally {
+            // and close up the connection. We do this in a finally block to
+            // make sure the connection
+            // is shut down even if quit gets an error.
+            closeServerConnection();
+            // get rid of our response processor too.
+            reader = null;
+            writer = null;
+        }
+    }
+
+    public String toString() {
+        return "NNTPConnection host: " + serverHost + " port: " + serverPort;
+    }
+
+
+    /**
+     * Get the servers welcome blob from the wire....
+     */
+    public void getWelcome() throws MessagingException {
+        NNTPReply line = getReply();
+
+        //
+        if (line.isError()) {
+            throw new MessagingException("Error connecting to news server: " + line.getMessage());
+        }
+
+        // remember we can post.
+        if (line.getCode() == NNTPReply.POSTING_ALLOWED) {
+            postingAllowed = true;
+        } else {
+            postingAllowed = false;
+        }
+
+        // the NNTP store will want to use the welcome string, so save it.
+        welcomeString = line.getMessage();
+
+        // find out what extensions this server supports.
+        getExtensions();
+    }
+
+
+    /**
+     * Sends the QUIT message and receieves the response
+     */
+    public void sendQuit() throws MessagingException {
+        sendLine("QUIT");
+    }
+
+
+    /**
+     * Tell the server to switch to a named group.
+     *
+     * @param name
+     *            The name of the target group.
+     *
+     * @return The server response to the GROUP command.
+     */
+    public NNTPReply selectGroup(String name) throws MessagingException {
+        // send the GROUP command
+        return sendCommand("GROUP " + name);
+    }
+
+
+    /**
+     * Ask the server what extensions it supports.
+     *
+     * @return True if the command was accepted ok, false for any errors.
+     * @exception MessagingException
+     */
+    protected void getExtensions() throws MessagingException {
+        NNTPReply reply = sendCommand("LIST EXTENSIONS", NNTPReply.EXTENSIONS_SUPPORTED);
+
+        // we get a 202 code back. The first line is just a greeting, and
+        // extensions are delivered as data
+        // lines terminated with a "." line.
+        if (reply.getCode() != NNTPReply.EXTENSIONS_SUPPORTED) {
+            return;
+        }
+
+        // get a fresh extension mapping table.
+        capabilities = new HashMap();
+        authentications = new ArrayList();
+
+        // get the extension data lines.
+        List extensions = reply.getData();
+
+        // process all of the continuation lines
+        for (int i = 0; i < extensions.size(); i++) {
+            // go process the extention
+            processExtension((String) extensions.get(i));
+        }
+    }
+
+
+    /**
+     * Process an extension string passed back as the LIST EXTENSIONS response.
+     *
+     * @param extension
+     *            The string value of the extension (which will be of the form
+     *            "NAME arguments").
+     */
+    protected void processExtension(String extension) {
+        String extensionName = extension.toUpperCase();
+        String argument = "";
+
+        int delimiter = extension.indexOf(' ');
+        // if we have a keyword with arguments, parse them out and add to the
+        // argument map.
+        if (delimiter != -1) {
+            extensionName = extension.substring(0, delimiter).toUpperCase();
+            argument = extension.substring(delimiter + 1);
+        }
+
+        // add this to the map so it can be tested later.
+        capabilities.put(extensionName, argument);
+
+        // we need to determine which authentication mechanisms are supported here
+        if (extensionName.equals("AUTHINFO")) {
+            StringTokenizer tokenizer = new StringTokenizer(argument);
+
+            while (tokenizer.hasMoreTokens()) {
+                // we only know how to do USER or SASL
+                String mechanism = tokenizer.nextToken().toUpperCase();
+                if (mechanism.equals("SASL")) {
+                    authInfoSaslAllowed = true;
+                }
+                else if (mechanism.equals("USER")) {
+                    authInfoUserAllowed = true;
+                }
+            }
+        }
+        // special case for some older servers.
+        else if (extensionName.equals("SASL")) {
+            // The security mechanisms are blank delimited tokens.
+            StringTokenizer tokenizer = new StringTokenizer(argument);
+
+            while (tokenizer.hasMoreTokens()) {
+                String mechanism = tokenizer.nextToken().toUpperCase();
+                authentications.add(mechanism);
+            }
+        }
+    }
+
+
+    /**
+     * Retrieve any argument information associated with a extension reported
+     * back by the server on the EHLO command.
+     *
+     * @param name
+     *            The name of the target server extension.
+     *
+     * @return Any argument passed on a server extension. Returns null if the
+     *         extension did not include an argument or the extension was not
+     *         supported.
+     */
+    public String extensionParameter(String name) {
+        if (capabilities != null) {
+            return (String) capabilities.get(name);
+        }
+        return null;
+    }
+
+    /**
+     * Tests whether the target server supports a named extension.
+     *
+     * @param name
+     *            The target extension name.
+     *
+     * @return true if the target server reported on the EHLO command that is
+     *         supports the targer server, false if the extension was not
+     *         supported.
+     */
+    public boolean supportsExtension(String name) {
+        // this only returns null if we don't have this extension
+        return extensionParameter(name) != null;
+    }
+
+
+    /**
+     * Sends the data in the message down the socket. This presumes the server
+     * is in the right place and ready for getting the DATA message and the data
+     * right place in the sequence
+     */
+    public synchronized void sendPost(Message msg) throws MessagingException {
+
+        // send the POST command
+        NNTPReply line = sendCommand("POST");
+
+        if (line.getCode() != NNTPReply.SEND_ARTICLE) {
+            throw new MessagingException("Server rejected POST command: " + line);
+        }
+
+        // we've received permission to send the data, so ask the message to
+        // write itself out.
+        try {
+            // the data content has two requirements we need to meet by
+            // filtering the
+            // output stream. Requirement 1 is to conicalize any line breaks.
+            // All line
+            // breaks will be transformed into properly formed CRLF sequences.
+            //
+            // Requirement 2 is to perform byte-stuff for any line that begins
+            // with a "."
+            // so that data is not confused with the end-of-data marker (a
+            // "\r\n.\r\n" sequence.
+            //
+            // The MIME output stream performs those two functions on behalf of
+            // the content
+            // writer.
+            MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
+
+            msg.writeTo(mimeOut);
+
+            // now to finish, we send a CRLF sequence, followed by a ".".
+            mimeOut.writeSMTPTerminator();
+            // and flush the data to send it along
+            mimeOut.flush();
+        } catch (IOException e) {
+            throw new MessagingException("I/O error posting message", e);
+        } catch (MessagingException e) {
+            throw new MessagingException("Exception posting message", e);
+        }
+
+        // use a longer time out here to give the server time to process the
+        // data.
+        line = new NNTPReply(receiveLine());
+
+        if (line.getCode() != NNTPReply.POSTED_OK) {
+            throw new MessagingException("Server rejected POST command: " + line);
+        }
+    }
+
+    /**
+     * Issue a command and retrieve the response. If the given success indicator
+     * is received, the command is returning a longer response, terminated by a
+     * "crlf.crlf" sequence. These lines are attached to the reply.
+     *
+     * @param command
+     *            The command to issue.
+     * @param success
+     *            The command reply that indicates additional data should be
+     *            retrieved.
+     *
+     * @return The command reply.
+     */
+    public synchronized NNTPReply sendCommand(String command, int success) throws MessagingException {
+        NNTPReply reply = sendCommand(command);
+        if (reply.getCode() == success) {
+            reply.retrieveData(reader);
+        }
+        return reply;
+    }
+
+    /**
+     * Send a command to the server, returning the first response line back as a
+     * reply.
+     *
+     * @param data
+     *            The data to send.
+     *
+     * @return A reply object with the reply line.
+     * @exception MessagingException
+     */
+    public NNTPReply sendCommand(String data) throws MessagingException {
+        sendLine(data);
+        NNTPReply reply = getReply();
+        // did the server just inform us we need to authenticate? The spec
+        // allows this
+        // response to be sent at any time, so we need to try to authenticate
+        // and then retry the command.
+        if (reply.getCode() == NNTPReply.AUTHINFO_REQUIRED || reply.getCode() == NNTPReply.AUTHINFO_SIMPLE_REQUIRED) {
+            debugOut("Authentication required received from server.");
+            // authenticate with the server, if necessary
+            processAuthentication(reply.getCode());
+            // if we've safely authenticated, we can reissue the command and
+            // process the response.
+            sendLine(data);
+            reply = getReply();
+        }
+        return reply;
+    }
+
+    /**
+     * Send a command to the server, returning the first response line back as a
+     * reply.
+     *
+     * @param data
+     *            The data to send.
+     *
+     * @return A reply object with the reply line.
+     * @exception MessagingException
+     */
+    public NNTPReply sendAuthCommand(String data) throws MessagingException {
+        sendLine(data);
+        return getReply();
+    }
+
+    /**
+     * Sends a message down the socket and terminates with the appropriate CRLF
+     */
+    public void sendLine(String data) throws MessagingException {
+        if (socket == null || !socket.isConnected()) {
+            throw new MessagingException("no connection");
+        }
+        try {
+            outputStream.write(data.getBytes("ISO8859-1"));
+            outputStream.write(CR);
+            outputStream.write(LF);
+            outputStream.flush();
+        } catch (IOException e) {
+            throw new MessagingException(e.toString());
+        }
+    }
+
+    /**
+     * Get a reply line for an NNTP command.
+     *
+     * @return An NNTP reply object from the stream.
+     */
+    public NNTPReply getReply() throws MessagingException {
+        lastServerResponse = new NNTPReply(receiveLine());
+        return lastServerResponse;
+    }
+
+    /**
+     * Retrieve the last response received from the NNTP server.
+     *
+     * @return The raw response string (including the error code) returned from
+     *         the NNTP server.
+     */
+    public String getLastServerResponse() {
+        if (lastServerResponse == null) {
+            return "";
+        }
+        return lastServerResponse.getReply();
+    }
+
+    /**
+     * Receives one line from the server. A line is a sequence of bytes
+     * terminated by a CRLF
+     *
+     * @return the line from the server as String
+     */
+    public String receiveLine() throws MessagingException {
+        if (socket == null || !socket.isConnected()) {
+            throw new MessagingException("no connection");
+        }
+
+        try {
+            String line = reader.readLine();
+            if (line == null) {
+                throw new MessagingException("Unexpected end of stream");
+            }
+            return line;
+        } catch (IOException e) {
+            throw new MessagingException("Error reading from server", e);
+        }
+    }
+
+
+    /**
+     * Authenticate with the server, if necessary (or possible).
+     */
+    protected void processAuthentication(int request) throws MessagingException {
+        // we need to authenticate, but we don't have userid/password
+        // information...fail this
+        // immediately.
+        if (username == null || password == null) {
+            throw new MessagingException("Server requires user authentication");
+        }
+
+        if (request == NNTPReply.AUTHINFO_SIMPLE_REQUIRED) {
+            processAuthinfoSimple();
+        } else {
+            if (!processSaslAuthentication()) {
+                processAuthinfoUser();
+            }
+        }
+    }
+
+    /**
+     * Process an AUTHINFO SIMPLE command. Not widely used, but if the server
+     * asks for it, we can respond.
+     *
+     * @exception MessagingException
+     */
+    protected void processAuthinfoSimple() throws MessagingException {
+        NNTPReply reply = sendAuthCommand("AUTHINFO SIMPLE");
+        if (reply.getCode() != NNTPReply.AUTHINFO_CONTINUE) {
+            throw new MessagingException("Error authenticating with server using AUTHINFO SIMPLE");
+        }
+        reply = sendAuthCommand(username + " " + password);
+        if (reply.getCode() != NNTPReply.AUTHINFO_ACCEPTED) {
+            throw new MessagingException("Error authenticating with server using AUTHINFO SIMPLE");
+        }
+    }
+
+
+    /**
+     * Process SASL-type authentication.
+     *
+     * @return Returns true if the server support a SASL authentication mechanism and
+     *         accepted reponse challenges.
+     * @exception MessagingException
+     */
+    protected boolean processSaslAuthentication() throws MessagingException {
+        // only do this if permitted
+        if (!authInfoSaslAllowed) {
+            return false;
+        }
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
+        if (authenticator == null) {
+            throw new MessagingException("Unable to obtain SASL authenticator");
+        }
+
+        // go process the login.
+        return processLogin(authenticator);
+    }
+
+    /**
+     * Attempt to retrieve a SASL authenticator for this
+     * protocol.
+     *
+     * @return A SASL authenticator, or null if a suitable one
+     *         was not located.
+     */
+    protected ClientAuthenticator getSaslAuthenticator() {
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
+    }
+
+
+    /**
+     * Process a login using the provided authenticator object.
+     *
+     * NB:  This method is synchronized because we have a multi-step process going on
+     * here.  No other commands should be sent to the server until we complete.
+     *
+     * @return Returns true if the server support a SASL authentication mechanism and
+     * accepted reponse challenges.
+     * @exception MessagingException
+     */
+    protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
+        debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
+
+        // if the authenticator has some initial data, we compose a command
+        // containing the initial data.
+        if (authenticator.hasInitialResponse()) {
+            StringBuffer command = new StringBuffer();
+            // the auth command initiates the handshaking.
+            command.append("AUTHINFO SASL ");
+            // and tell the server which mechanism we're using.
+            command.append(authenticator.getMechanismName());
+            command.append(" ");
+            // and append the response data
+            try {
+                command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
+            } catch (UnsupportedEncodingException e) {
+            }
+            // send the command now
+            sendLine(command.toString());
+        }
+        // we just send an auth command with the command type.
+        else {
+            StringBuffer command = new StringBuffer();
+            // the auth command initiates the handshaking.
+            command.append("AUTHINFO SASL");
+            // and tell the server which mechanism we're using.
+            command.append(authenticator.getMechanismName());
+            // send the command now
+            sendLine(command.toString());
+        }
+
+        // now process the challenge sequence. We get a 235 response back when
+        // the server accepts the
+        // authentication, and a 334 indicates we have an additional challenge.
+        while (true) {
+            // get the next line, and if it is an error response, return now.
+            NNTPReply line = getReply();
+
+            // if we get a completion return, we've passed muster, so give an
+            // authentication response.
+            if (line.getCode() == NNTPReply.AUTHINFO_ACCEPTED || line.getCode() == NNTPReply.AUTHINFO_ACCEPTED_FINAL) {
+                debugOut("Successful SMTP authentication");
+                return true;
+            }
+            // we have an additional challenge to process.
+            else if (line.getCode() == NNTPReply.AUTHINFO_CHALLENGE) {
+                // Does the authenticator think it is finished? We can't answer
+                // an additional challenge,
+                // so fail this.
+                if (authenticator.isComplete()) {
+                    debugOut("Extra authentication challenge " + line);
+                    return false;
+                }
+
+                // we're passed back a challenge value, Base64 encoded.
+                try {
+                    byte[] challenge = Base64.decode(line.getMessage().getBytes("ISO8859-1"));
+
+                    // have the authenticator evaluate and send back the encoded
+                    // response.
+                    sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII"));
+                } catch (UnsupportedEncodingException e) {
+                }
+            }
+            // completion or challenge are the only responses we know how to
+            // handle. Anything else must
+            // be a failure.
+            else {
+                debugOut("Authentication failure " + line);
+                return false;
+            }
+        }
+    }
+
+
+    /**
+     * Process an AUTHINFO USER command. Most common form of NNTP
+     * authentication.
+     *
+     * @exception MessagingException
+     */
+    protected void processAuthinfoUser() throws MessagingException {
+        // only do this if allowed by the server
+        if (!authInfoUserAllowed) {
+            return;
+        }
+        NNTPReply reply = sendAuthCommand("AUTHINFO USER " + username);
+        // accepted without a password (uncommon, but allowed), we're done
+        if (reply.getCode() == NNTPReply.AUTHINFO_ACCEPTED) {
+            return;
+        }
+        // the only other non-error response is continue.
+        if (reply.getCode() != NNTPReply.AUTHINFO_CONTINUE) {
+            throw new MessagingException("Error authenticating with server using AUTHINFO USER: " + reply);
+        }
+        // now send the password. We expect an accepted response.
+        reply = sendAuthCommand("AUTHINFO PASS " + password);
+        if (reply.getCode() != NNTPReply.AUTHINFO_ACCEPTED) {
+            throw new MessagingException("Error authenticating with server using AUTHINFO SIMPLE");
+        }
+    }
+
+
+    /**
+     * Indicate whether posting is allowed for a given server.
+     *
+     * @return True if the server allows posting, false if the server is
+     *         read-only.
+     */
+    public boolean isPostingAllowed() {
+        return postingAllowed;
+    }
+
+    /**
+     * Retrieve the welcome string sent back from the server.
+     *
+     * @return The server provided welcome string.
+     */
+    public String getWelcomeString() {
+        return welcomeString;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java
new file mode 100644
index 0000000..d631d72
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java
@@ -0,0 +1,242 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.nntp;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a reply from a NNTP server
+ * 
+ * @version $Rev: 673152 $ $Date: 2008-07-01 13:37:38 -0400 (Tue, 01 Jul 2008) $
+ */
+public class NNTPReply {
+    // general server responses
+    public static final int CAPABILITY_LIST = 101; 
+    
+    public static final int POSTING_ALLOWED = 200;
+
+    public static final int NO_POSTING_ALLOWED = 201;
+
+    public static final int EXTENSIONS_SUPPORTED = 202;
+
+    public static final int SERVICE_DISCONTINUED = 400;
+
+    public static final int COMMAND_NOT_RECOGNIZED = 500;
+
+    public static final int COMMAND_SYNTAX_ERROR = 501;
+
+    public static final int PERMISSION_DENIED = 502;
+
+    public static final int PROGRAM_FAULT = 503;
+
+    // article responses
+    public static final int ARTICLE_FOLLOWS = 220;
+
+    public static final int HEAD_FOLLOWS = 221;
+
+    public static final int BODY_FOLLOWS = 222;
+
+    public static final int REQUEST_TEXT_SEPARATELY = 223;
+
+    public static final int OVERVIEW_FOLLOWS = 224;
+
+    public static final int NEW_ARTICLES_FOLLOWS = 230;
+
+    public static final int NEW_GROUPS_FOLLOWS = 231;
+
+    public static final int ARTICLE_TRANSFERRED = 235;
+
+    public static final int NO_NEWSGROUP_SELECTED = 412;
+
+    public static final int NO_ARTICLE_SELECTED = 420;
+
+    public static final int NO_ARTICLE_NUMBER = 423;
+
+    public static final int NO_ARTICLE_FOUND = 430;
+
+    // group responses
+    public static final int GROUP_SELECTED = 211;
+
+    public static final int NO_SUCH_NEWSGROUP = 411;
+
+    // post responses
+    public static final int POSTED_OK = 240;
+
+    public static final int SEND_ARTICLE = 340;
+
+    public static final int POSTING_NOT_ALLOWED = 440;
+
+    public static final int POSTING_FAILED = 441;
+
+    // quit responses
+    public static final int CLOSING_CONNECTION = 205;
+
+    // authentication responses
+    public static final int AUTHINFO_ACCEPTED = 250;
+
+    public static final int AUTHINFO_ACCEPTED_FINAL = 251;
+
+    public static final int AUTHINFO_CONTINUE = 350;
+
+    public static final int AUTHINFO_CHALLENGE = 350;
+
+    public static final int AUTHINFO_SIMPLE_REJECTED = 402;
+
+    public static final int AUTHENTICATION_ACCEPTED = 281;
+
+    public static final int MORE_AUTHENTICATION_REQUIRED = 381;
+
+    public static final int AUTHINFO_REQUIRED = 480;
+
+    public static final int AUTHINFO_SIMPLE_REQUIRED = 450;
+
+    public static final int AUTHENTICATION_REJECTED = 482;
+
+    // list active reponses
+    public static final int LIST_FOLLOWS = 215;
+
+    // The original reply string
+    private final String reply;
+
+    // returned message code
+    private final int code;
+
+    // the returned message text
+    private final String message;
+
+    // data associated with a long response command.
+    private ArrayList data;
+
+    NNTPReply(String s) throws MessagingException {
+        // save the reply
+        reply = s;
+
+        // In a normal response, the first 3 must be the return code. However,
+        // the response back from a QUIT command is frequently a null string.
+        // Therefore, if the result is
+        // too short, just default the code to -1 and use the entire text for
+        // the message.
+        if (s == null || s.length() < 3) {
+            code = -1;
+            message = s;
+            return;
+        }
+
+        try {
+            code = Integer.parseInt(s.substring(0, 3));
+
+            // message should be separated by a space OR a continuation
+            // character if this is a
+            // multi-line response.
+            if (s.length() > 4) {
+                message = s.substring(4);
+            } else {
+                message = "";
+            }
+        } catch (NumberFormatException e) {
+            throw new MessagingException("error in parsing reply code", e);
+        }
+    }
+
+    /**
+     * Retrieve data associated with a multi-line reponse from a server stream.
+     * 
+     * @param in
+     *            The reader that's the source of the additional lines.
+     * 
+     * @exception IOException
+     */
+    public void retrieveData(BufferedReader in) throws MessagingException {
+        try {
+            data = new ArrayList();
+
+            String line = in.readLine();
+            // read until the end of file or until we see the end of data
+            // marker.
+            while (line != null && !line.equals(".")) {
+                // this line is not the terminator, but it may have been byte
+                // stuffed. If it starts with
+                // '.', throw away the leading one.
+                if (line.startsWith(".")) {
+                    line = line.substring(1);
+                }
+
+                // just add the line to the list
+                data.add(line);
+                line = in.readLine();
+            }
+        } catch (IOException e) {
+            throw new MessagingException("Error reading message reply", e);
+        }
+    }
+
+    /**
+     * Retrieve the long-command data from this response.
+     * 
+     * @return The data list. Returns null if there is no associated data.
+     */
+    public List getData() {
+        return data;
+    }
+
+    /**
+     * Return the code value associated with the reply.
+     * 
+     * @return The integer code associated with the reply.
+     */
+    public int getCode() {
+        return this.code;
+    }
+
+    /**
+     * Get the message text associated with the reply.
+     * 
+     * @return The string value of the message from the reply.
+     */
+    public String getMessage() {
+        return this.message;
+    }
+
+    /**
+     * Retrieve the raw reply string for the reponse.
+     * 
+     * @return The original reply string from the server.
+     */
+    public String getReply() {
+        return reply;
+    }
+
+    /**
+     * Indicates if reply is an error condition
+     */
+    boolean isError() {
+        // error codes are all above 400
+        return code >= 400;
+    }
+
+    public String toString() {
+        return "CODE = " + getCode() + " : MSG = " + getMessage();
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java
new file mode 100644
index 0000000..e27a064
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java
@@ -0,0 +1,34 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.nntp;
+
+import javax.mail.Session;
+import javax.mail.URLName;
+
+public class NNTPSSLTransport extends NNTPTransport {
+    /**
+     * @param session
+     * @param name
+     */
+    public NNTPSSLTransport(Session session, URLName name) {
+        super(session, name, "nntp-posts", DEFAULT_NNTP_SSL_PORT, true);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java
new file mode 100644
index 0000000..78d5408
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java
@@ -0,0 +1,260 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.nntp;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+
+import javax.mail.Address;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.URLName;
+import javax.mail.event.TransportEvent;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.NewsAddress;
+
+import org.apache.geronimo.javamail.util.ProtocolProperties; 
+
+/**
+ * Simple implementation of NNTP transport. Just does plain RFC977-ish delivery.
+ * <p/> There is no way to indicate failure for a given recipient (it's possible
+ * to have a recipient address rejected). The sun impl throws exceptions even if
+ * others successful), but maybe we do a different way... <p/>
+ * 
+ * @version $Rev: 673649 $ $Date: 2008-07-03 06:37:56 -0400 (Thu, 03 Jul 2008) $
+ */
+public class NNTPTransport extends Transport {
+    /**
+     * property keys for protocol properties.
+     */
+    protected static final String NNTP_FROM = "from";
+
+    protected static final int DEFAULT_NNTP_PORT = 119;
+    protected static final int DEFAULT_NNTP_SSL_PORT = 563;
+
+    // our accessor for protocol properties and the holder of 
+    // protocol-specific information 
+    protected ProtocolProperties props; 
+    // our active connection object (shared code with the NNTPStore).
+    protected NNTPConnection connection;
+
+    /**
+     * Normal constructor for an NNTPTransport() object. This constructor is
+     * used to build a transport instance for the "smtp" protocol.
+     * 
+     * @param session
+     *            The attached session.
+     * @param name
+     *            An optional URLName object containing target information.
+     */
+    public NNTPTransport(Session session, URLName name) {
+        this(session, name, "nntp-post", DEFAULT_NNTP_PORT, false);
+    }
+
+    /**
+     * Common constructor used by the POP3Store and POP3SSLStore classes
+     * to do common initialization of defaults.
+     *
+     * @param session
+     *            The host session instance.
+     * @param name
+     *            The URLName of the target.
+     * @param protocol
+     *            The protocol type ("pop3"). This helps us in
+     *            retrieving protocol-specific session properties.
+     * @param defaultPort
+     *            The default port used by this protocol. For pop3, this will
+     *            be 110. The default for pop3 with ssl is 995.
+     * @param sslConnection
+     *            Indicates whether an SSL connection should be used to initial
+     *            contact the server. This is different from the STARTTLS
+     *            support, which switches the connection to SSL after the
+     *            initial startup.
+     */
+    protected NNTPTransport(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+        super(session, name);
+        
+        // create the protocol property holder.  This gives an abstraction over the different 
+        // flavors of the protocol. 
+        props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
+        // the connection manages connection for the transport 
+        connection = new NNTPConnection(props); 
+    }
+
+    /**
+     * Do the protocol connection for an NNTP transport. This handles server
+     * authentication, if possible. Returns false if unable to connect to the
+     * server.
+     * 
+     * @param host
+     *            The target host name.
+     * @param port
+     *            The server port number.
+     * @param user
+     *            The authentication user (if any).
+     * @param password
+     *            The server password. Might not be sent directly if more
+     *            sophisticated authentication is used.
+     * 
+     * @return true if we were able to connect to the server properly, false for
+     *         any failures.
+     * @exception MessagingException
+     */
+    protected boolean protocolConnect(String host, int port, String username, String password)
+            throws MessagingException {
+        // the connection pool handles all of the details here. 
+        return connection.protocolConnect(host, port, username, password);
+    }
+    
+
+    /**
+     * Send a message to multiple addressees.
+     * 
+     * @param message
+     *            The message we're sending.
+     * @param addresses
+     *            An array of addresses to send to.
+     * 
+     * @exception MessagingException
+     */
+    public void sendMessage(Message message, Address[] addresses) throws MessagingException {
+        if (!isConnected()) {
+            throw new IllegalStateException("Not connected");
+        }
+
+        if (!connection.isPostingAllowed()) {
+            throw new MessagingException("Posting disabled for host server");
+        }
+        // don't bother me w/ null messages or no addreses
+        if (message == null) {
+            throw new MessagingException("Null message");
+        }
+
+        // NNTP only handles instances of MimeMessage, not the more general
+        // message case.
+        if (!(message instanceof MimeMessage)) {
+            throw new MessagingException("NNTP can only send MimeMessages");
+        }
+
+        // need to sort the from value out from a variety of sources.
+        InternetAddress from = null;
+
+        Address[] fromAddresses = message.getFrom();
+
+        // If the message has a From address set, we just use that. Otherwise,
+        // we set a From using
+        // the property version, if available.
+        if (fromAddresses == null || fromAddresses.length == 0) {
+            // the from value can be set explicitly as a property
+            String defaultFrom = props.getProperty(NNTP_FROM);
+            if (defaultFrom == null) {
+                message.setFrom(new InternetAddress(defaultFrom));
+            }
+        }
+
+        // we must have a message list.
+        if (addresses == null || addresses.length == 0) {
+            throw new MessagingException("Null or empty address array");
+        }
+
+        boolean haveGroup = false;
+
+        // enforce the requirement that all of the targets are NewsAddress
+        // instances.
+        for (int i = 0; i < addresses.length; i++) {
+            if (!(addresses[i] instanceof NewsAddress)) {
+                throw new MessagingException("Illegal NewsAddress " + addresses[i]);
+            }
+        }
+
+        // event notifcation requires we send lists of successes and failures
+        // broken down by category.
+        // The categories are:
+        //
+        // 1) addresses successfully processed.
+        // 2) addresses deemed valid, but had a processing failure that
+        // prevented sending.
+        // 3) addressed deemed invalid (basically all other processing
+        // failures).
+        ArrayList sentAddresses = new ArrayList();
+        ArrayList unsentAddresses = new ArrayList();
+        ArrayList invalidAddresses = new ArrayList();
+
+        boolean sendFailure = false;
+
+        // now try to post this message to the different news groups.
+        for (int i = 0; i < addresses.length; i++) {
+            try {
+                // select the target news group
+                NNTPReply reply = connection.selectGroup(((NewsAddress) addresses[i]).getNewsgroup());
+
+                if (reply.getCode() != NNTPReply.GROUP_SELECTED) {
+                    invalidAddresses.add(addresses[i]);
+                    sendFailure = true;
+                } else {
+                    // send data
+                    connection.sendPost(message);
+                    sentAddresses.add(addresses[i]);
+                }
+            } catch (MessagingException e) {
+                unsentAddresses.add(addresses[i]);
+                sendFailure = true;
+            }
+        }
+
+        // create our lists for notification and exception reporting from this
+        // point on.
+        Address[] sent = (Address[]) sentAddresses.toArray(new Address[0]);
+        Address[] unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+        Address[] invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
+
+        if (sendFailure) {
+            // did we deliver anything at all?
+            if (sent.length == 0) {
+                // notify of the error.
+                notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
+            } else {
+                // notify that we delivered at least part of this
+                notifyTransportListeners(TransportEvent.MESSAGE_PARTIALLY_DELIVERED, sent, unsent, invalid, message);
+            }
+
+            throw new MessagingException("Error posting NNTP message");
+        }
+
+        // notify our listeners of successful delivery.
+        notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED, sent, unsent, invalid, message);
+    }
+
+    /**
+     * Close the connection. On completion, we'll be disconnected from the
+     * server and unable to send more data.
+     * 
+     * @exception MessagingException
+     */
+    public void close() throws MessagingException {
+        // This is done to ensure proper event notification.
+        super.close();
+        // NB:  We reuse the connection if asked to reconnect 
+        connection.close();
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java
new file mode 100644
index 0000000..5de6e5a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.nntp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+/**
+ * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
+ */
+public class StringListInputStream extends InputStream {
+    // the list of lines we're reading from
+    protected List lines;
+
+    // the next line to process.
+    protected int nextLine = 0;
+
+    // current buffer of bytes to read from
+    byte[] buffer;
+
+    // current offset within the buffer;
+    int offset;
+
+    // indicator that we've left off at a split between the CR and LF of a line
+    // break.
+    boolean atLineBreak = false;
+
+    public StringListInputStream(List lines) throws IOException {
+        this.lines = lines;
+        nextLine = 0;
+        buffer = null;
+        offset = 0;
+        atLineBreak = false;
+
+        // if we have at least one line in the list, get the bytes now.
+        if (lines.size() > 0) {
+            nextBuffer();
+        }
+    }
+
+    /**
+     * Just override the single byte read version, which handles all of the
+     * lineend markers correctly.
+     * 
+     * @return The next byte from the stream or -1 if we've hit the EOF.
+     */
+    public int read() throws IOException {
+        // leave off at the split between a line?
+        if (atLineBreak) {
+            // flip this off and return the second line end character. Also step
+            // to the next line.
+            atLineBreak = false;
+            nextBuffer();
+            return '\n';
+        }
+        // gone past the end? Got an EOF
+        if (buffer == null) {
+            return -1;
+        }
+
+        // reach the end of the line?
+        if (offset >= buffer.length) {
+            // we're now working on a virtual linebreak
+            atLineBreak = true;
+            return '\r';
+        }
+        // just return the next byte
+        return buffer[offset++];
+
+    }
+
+    /**
+     * Step to the next buffer of string data.
+     * 
+     * @exception IOException
+     */
+    protected void nextBuffer() throws IOException {
+        // give an eof check.
+        if (nextLine >= lines.size()) {
+            buffer = null;
+        } else {
+            try {
+                String next = (String) lines.get(nextLine++);
+                buffer = next.getBytes("US-ASCII");
+
+            } catch (UnsupportedEncodingException e) {
+                throw new IOException("Invalid string encoding");
+            }
+        }
+
+        offset = 0;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java
new file mode 100644
index 0000000..86652b2
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java
@@ -0,0 +1,39 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+/**
+ * Exception for when a SMTP reply string has a problem
+ * 
+ * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
+ */
+class MalformedSMTPReplyException extends Exception {
+    MalformedSMTPReplyException() {
+        super();
+    }
+
+    MalformedSMTPReplyException(String msg) {
+        super(msg);
+    }
+
+    MalformedSMTPReplyException(String msg, Exception t) {
+        super(msg, t);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java
new file mode 100644
index 0000000..bfd2699
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+
+public class SMTPAddressFailedException extends MessagingException {
+    // the failing address
+    InternetAddress addr;
+
+    // the failing command
+    protected String cmd;
+
+    // the error code for the failure
+    protected int rc;
+
+    /**
+     * Constructor for an SMTPAddressFailingException.
+     * 
+     * @param addr
+     *            The failing address.
+     * @param cmd
+     *            The failing command string.
+     * @param rc
+     *            The error code for the command.
+     * @param err
+     *            An error message for the exception.
+     */
+    SMTPAddressFailedException(InternetAddress addr, java.lang.String cmd, int rc, java.lang.String err) {
+        super(err);
+        this.cmd = cmd;
+        this.rc = rc;
+        this.addr = addr;
+    }
+
+    /**
+     * Get the failing command string for the exception.
+     * 
+     * @return The string value of the failing command.
+     */
+    public String getCommand() {
+        return cmd;
+    }
+
+    /**
+     * The failing command return code.
+     * 
+     * @return The failure return code.
+     */
+    public int getReturnCode() {
+        return rc;
+    }
+
+    /**
+     * Retrieve the internet address associated with this exception.
+     * 
+     * @return The provided InternetAddress object.
+     */
+    public InternetAddress getAddress() {
+        return addr;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java
new file mode 100644
index 0000000..990d656
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+
+public class SMTPAddressSucceededException extends MessagingException {
+    // the succeeding address
+    InternetAddress addr;
+
+    // the failing command
+    protected String cmd;
+
+    // the error code for the failure
+    protected int rc;
+
+    /**
+     * Constructor for an SMTPAddressSucceededException.
+     * 
+     * @param addr
+     *            The succeeding address.
+     * @param cmd
+     *            The succeeding command string.
+     * @param rc
+     *            The error code for the command.
+     * @param err
+     *            An error message for the exception.
+     */
+    SMTPAddressSucceededException(InternetAddress addr, java.lang.String cmd, int rc, java.lang.String err) {
+        super(err);
+        this.cmd = cmd;
+        this.rc = rc;
+        this.addr = addr;
+    }
+
+    /**
+     * Get the failing command string for the exception.
+     * 
+     * @return The string value of the failing command.
+     */
+    public String getCommand() {
+        return cmd;
+    }
+
+    /**
+     * The failing command return code.
+     * 
+     * @return The failure return code.
+     */
+    public int getReturnCode() {
+        return rc;
+    }
+
+    /**
+     * Retrieve the internet address associated with this exception.
+     * 
+     * @return The provided InternetAddress object.
+     */
+    public InternetAddress getAddress() {
+        return addr;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
new file mode 100644
index 0000000..ea84556
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
@@ -0,0 +1,1370 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.mail.Address;
+import javax.mail.AuthenticationFailedException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimePart;
+import javax.mail.Session;
+
+import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
+import org.apache.geronimo.javamail.util.CountingOutputStream;
+import org.apache.geronimo.javamail.util.MailConnection;
+import org.apache.geronimo.javamail.util.MIMEOutputStream;
+import org.apache.geronimo.javamail.util.ProtocolProperties;
+import org.apache.geronimo.mail.util.Base64;
+import org.apache.geronimo.mail.util.XText;
+
+/**
+ * Simple implementation of SMTP transport. Just does plain RFC977-ish delivery.
+ *
+ * @version $Rev: 1741822 $ $Date: 2016-04-30 18:04:39 -0400 (Sat, 30 Apr 2016) $
+ */
+public class SMTPConnection extends MailConnection {
+    protected static final String MAIL_SMTP_QUITWAIT = "quitwait";
+    protected static final String MAIL_SMTP_EXTENSION = "mailextension";
+    protected static final String MAIL_SMTP_EHLO = "ehlo";
+    protected static final String MAIL_SMTP_ALLOW8BITMIME = "allow8bitmime";
+    protected static final String MAIL_SMTP_REPORT_SUCCESS = "reportsuccess";
+    protected static final String MAIL_SMTP_STARTTLS_ENABLE = "starttls.enable";
+    protected static final String MAIL_SMTP_STARTTLS_REQUIRED = "starttls.required";
+    protected static final String MAIL_SMTP_AUTH = "auth";
+    protected static final String MAIL_SMTP_FROM = "from";
+    protected static final String MAIL_SMTP_DSN_RET = "dsn.ret";
+    protected static final String MAIL_SMTP_SUBMITTER = "submitter";
+
+    /**
+     * property keys for protocol properties.
+     */
+    protected static final int DEFAULT_NNTP_PORT = 119;
+
+    // the last response line received from the server.
+    protected SMTPReply lastServerResponse = null;
+
+    // do we report success after completion of each mail send.
+    protected boolean reportSuccess;
+    // does the server support transport level security?
+    protected boolean serverTLS = false;
+    // is TLS enabled on our part?
+    protected boolean useTLS = false;
+    // is TLS required on our part?
+    protected boolean requireTLS = false;
+    // should we use 8BITMIME encoding if supported by the server?
+    protected boolean use8bit = false;
+
+    /**
+     * Normal constructor for an SMTPConnection() object.
+     *
+     * @param props  The property bundle for this protocol instance.
+     */
+    public SMTPConnection(ProtocolProperties props) {
+        super(props);
+
+        // check to see if we need to throw an exception after a send operation.
+        reportSuccess = props.getBooleanProperty(MAIL_SMTP_REPORT_SUCCESS, false);
+        // and also check for TLS enablement.
+        useTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_ENABLE, false);
+        // and also check if TLS is required.
+        requireTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_REQUIRED, false);
+        // and also check for 8bitmime support
+        use8bit = props.getBooleanProperty(MAIL_SMTP_ALLOW8BITMIME, false);
+    }
+
+
+    /**
+     * Connect to the server and do the initial handshaking.
+     *
+     * @param host     The target host name.
+     * @param port     The target port
+     * @param username The connection username (can be null)
+     * @param password The authentication password (can be null).
+     *
+     * @return true if we were able to obtain a connection and
+     *         authenticate.
+     * @exception MessagingException
+     */
+    public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+
+        // now check to see if we need to authenticate. If we need this, then
+        // we must have a username and
+        // password specified. Failing this may result in a user prompt to
+        // collect the information.
+        boolean mustAuthenticate = props.getBooleanProperty(MAIL_SMTP_AUTH, false);
+
+        // if we need to authenticate, and we don't have both a userid and
+        // password, then we fail this
+        // immediately. The Service.connect() method will try to obtain the user
+        // information and retry the
+        // connection one time.
+        if (mustAuthenticate && (username == null || password == null)) {
+            debugOut("Failing connection for missing authentication information");
+            return false;
+        }
+
+        super.protocolConnect(host, port, username, password);
+
+        try {
+            // create socket and connect to server.
+            getConnection();
+
+            // receive welcoming message
+            if (!getWelcome()) {
+                debugOut("Error getting welcome message");
+                throw new MessagingException("Error in getting welcome msg");
+            }
+
+            // say hello
+            if (!sendHandshake()) {
+                debugOut("Error getting processing handshake message");
+                throw new MessagingException("Error in saying EHLO to server");
+            }
+
+            // authenticate with the server, if necessary
+            if (!processAuthentication()) {
+                debugOut("User authentication failure");
+                throw new AuthenticationFailedException("Error authenticating with server");
+            }
+        } catch (IOException e) {
+            debugOut("I/O exception establishing connection", e);
+            throw new MessagingException("Connection error", e);
+        }
+        debugOut("Successful connection");
+        return true;
+    }
+
+
+    /**
+     * Close the connection. On completion, we'll be disconnected from the
+     * server and unable to send more data.
+     *
+     * @exception MessagingException
+     */
+    public void close() throws MessagingException {
+        // if we're already closed, get outta here.
+        if (socket == null) {
+            return;
+        }
+        try {
+            // say goodbye
+            sendQuit();
+        } finally {
+            // and close up the connection. We do this in a finally block to
+            // make sure the connection
+            // is shut down even if quit gets an error.
+            closeServerConnection();
+        }
+    }
+
+    public String toString() {
+        return "SMTPConnection host: " + serverHost + " port: " + serverPort;
+    }
+
+
+    /**
+     * Set the sender for this mail.
+     *
+     * @param message
+     *                   The message we're sending.
+     *
+     * @return True if the command was accepted, false otherwise.
+     * @exception MessagingException
+     */
+    protected boolean sendMailFrom(Message message) throws MessagingException {
+
+        // need to sort the from value out from a variety of sources.
+        String from = null;
+
+        // first potential source is from the message itself, if it's an
+        // instance of SMTPMessage.
+        if (message instanceof SMTPMessage) {
+            from = ((SMTPMessage) message).getEnvelopeFrom();
+        }
+
+        // if not available from the message, check the protocol property next
+        if (from == null || from.length() == 0) {
+            // the from value can be set explicitly as a property
+            from = props.getProperty(MAIL_SMTP_FROM);
+        }
+
+        // if not there, see if we have something in the message header.
+        if (from == null || from.length() == 0) {
+            Address[] fromAddresses = message.getFrom();
+
+            // if we have some addresses in the header, then take the first one
+            // as our From: address
+            if (fromAddresses != null && fromAddresses.length > 0) {
+                from = ((InternetAddress) fromAddresses[0]).getAddress();
+            }
+            // get what the InternetAddress class believes to be the local
+            // address.
+            else {
+                InternetAddress local = InternetAddress.getLocalAddress(session);
+                if (local != null) {
+                    from = local.getAddress();
+                }
+            }
+        }
+
+        if (from == null || from.length() == 0) {
+            throw new MessagingException("no FROM address");
+        }
+
+        StringBuffer command = new StringBuffer();
+
+        // start building up the command
+        command.append("MAIL FROM: ");
+        command.append(fixEmailAddress(from));
+
+        // If the server supports the 8BITMIME extension, we might need to change the
+        // transfer encoding for the content to allow for direct transmission of the
+        // 8-bit codes.
+        if (supportsExtension("8BITMIME")) {
+            // we only do this if the capability was enabled via a property option or
+            // by explicitly setting the property on the message object.
+            if (use8bit || (message instanceof SMTPMessage && ((SMTPMessage)message).getAllow8bitMIME())) {
+                // make sure we add the BODY= option to the FROM message.
+                command.append(" BODY=8BITMIME");
+
+                // go check the content and see if the can convert the transfer encoding to
+                // allow direct 8-bit transmission.
+                if (convertTransferEncoding((MimeMessage)message)) {
+                    // if we changed the encoding on any of the parts, then we
+                    // need to save the message again
+                    message.saveChanges();
+                }
+            }
+        }
+
+        // some servers ask for a size estimate on the initial send
+        if (supportsExtension("SIZE")) {
+            int estimate = getSizeEstimate(message);
+            if (estimate > 0) {
+                command.append(" SIZE=" + estimate);
+            }
+        }
+
+        // does this server support Delivery Status Notification? Then we may
+        // need to add some extra to the command.
+        if (supportsExtension("DSN")) {
+            String returnNotification = null;
+
+            // the return notification stuff might be set as value on the
+            // message object itself.
+            if (message instanceof SMTPMessage) {
+                // we need to convert the option into a string value.
+                switch (((SMTPMessage) message).getReturnOption()) {
+                case SMTPMessage.RETURN_FULL:
+                    returnNotification = "FULL";
+                    break;
+
+                case SMTPMessage.RETURN_HDRS:
+                    returnNotification = "HDRS";
+                    break;
+                }
+            }
+
+            // if not obtained from the message object, it can also be set as a
+            // property.
+            if (returnNotification == null) {
+                // the DSN value is set by yet another property.
+                returnNotification = props.getProperty(MAIL_SMTP_DSN_RET);
+            }
+
+            // if we have a target, add the notification stuff to our FROM
+            // command.
+            if (returnNotification != null) {
+                command.append(" RET=");
+                command.append(returnNotification);
+            }
+        }
+
+        // if this server supports AUTH and we have submitter information, then
+        // we also add the
+        // "AUTH=" keyword to the MAIL FROM command (see RFC 2554).
+
+        if (supportsExtension("AUTH")) {
+            String submitter = null;
+
+            // another option that can be specified on the message object.
+            if (message instanceof SMTPMessage) {
+                submitter = ((SMTPMessage) message).getSubmitter();
+            }
+            // if not part of the object, try for a propery version.
+            if (submitter == null) {
+                // we only send the extra keyword is a submitter is specified.
+                submitter = props.getProperty(MAIL_SMTP_SUBMITTER);
+            }
+            // we have one...add the keyword, plus the submitter info in xtext
+            // format (defined by RFC 1891).
+            if (submitter != null) {
+                command.append(" AUTH=");
+                try {
+                    // add this encoded
+                    command.append(new String(XText.encode(submitter.getBytes("US-ASCII")), "US-ASCII"));
+                } catch (UnsupportedEncodingException e) {
+                    throw new MessagingException("Invalid submitter value " + submitter);
+                }
+            }
+        }
+
+        String extension = null;
+
+        // now see if we need to add any additional extension info to this
+        // command. The extension is not
+        // checked for validity. That's the reponsibility of the caller.
+        if (message instanceof SMTPMessage) {
+            extension = ((SMTPMessage) message).getMailExtension();
+        }
+        // this can come either from the object or from a set property.
+        if (extension == null) {
+            extension = props.getProperty(MAIL_SMTP_EXTENSION);
+        }
+
+        // have something real to add?
+        if (extension != null && extension.length() != 0) {
+            // tack this on the end with a blank delimiter.
+            command.append(' ');
+            command.append(extension);
+        }
+
+        // and finally send the command
+        SMTPReply line = sendCommand(command.toString());
+
+        // 250 response indicates success.
+        return line.getCode() == SMTPReply.COMMAND_ACCEPTED;
+    }
+
+
+    /**
+     * Check to see if a MIME body part can have its
+     * encoding changed from quoted-printable or base64
+     * encoding to 8bit encoding.  In order for this
+     * to work, it must follow the rules laid out in
+     * RFC 2045.  To qualify for conversion, the text
+     * must be:
+     *
+     * 1)  No more than 998 bytes long
+     * 2)  All lines are terminated with CRLF sequences
+     * 3)  CR and LF characters only occur in properly
+     * formed line separators
+     * 4)  No null characters are allowed.
+     *
+     * The conversion will only be applied to text
+     * elements, and this will recurse through the
+     * different elements of MultiPart content.
+     *
+     * @param bodyPart The bodyPart to convert. Initially, this will be
+     *                 the message itself.
+     *
+     * @return true if any conversion was performed, false if
+     *         nothing was converted.
+     */
+    protected boolean convertTransferEncoding(MimePart bodyPart)
+    {
+        boolean converted = false;
+        try {
+            // if this is a multipart element, apply the conversion rules
+            // to each of the parts.
+            if (bodyPart.isMimeType("multipart/")) {
+                MimeMultipart parts = (MimeMultipart)bodyPart.getContent();
+                for (int i = 0; i < parts.getCount(); i++) {
+                    // convert each body part, and accumulate the conversion result
+                    converted = converted && convertTransferEncoding((MimePart)parts.getBodyPart(i));
+                }
+            }
+            else {
+                // we only do this if the encoding is quoted-printable or base64
+                String encoding =  bodyPart.getEncoding();
+                if (encoding != null) {
+                    encoding = encoding.toLowerCase();
+                    if (encoding.equals("quoted-printable") || encoding.equals("base64")) {
+                        // this requires encoding.  Read the actual content to see if
+                        // it conforms to the 8bit encoding rules.
+                        if (isValid8bit(bodyPart.getInputStream())) {
+                            // There's a huge hidden gotcha lurking under the covers here.
+                            // If the content just exists as an encoded byte array, then just
+                            // switching the transfer encoding will mess things up because the
+                            // already encoded data gets transmitted in encoded form, but with
+                            // and 8bit encoding style.  As a result, it doesn't get unencoded on
+                            // the receiving end.  This is a nasty problem to debug.
+                            //
+                            // The solution is to get the content as it's object type, set it back
+                            // on the the message in raw form.  Requesting the content will apply the
+                            // current transfer encoding value to the data.  Once we have set the
+                            // content value back, we can reset the transfer encoding.
+                            bodyPart.setContent(bodyPart.getContent(), bodyPart.getContentType());
+
+                            // it's valid, so change the transfer encoding to just
+                            // pass the data through.
+                            bodyPart.setHeader("Content-Transfer-Encoding", "8bit");
+                            converted = true;   // we've changed something
+                        }
+                    }
+                }
+            }
+        } catch (MessagingException e) {
+        } catch (IOException e) {
+        }
+        return converted;
+    }
+
+
+    /**
+     * Get the server's welcome blob from the wire....
+     */
+    protected boolean getWelcome() throws MessagingException {
+        SMTPReply line = getReply();
+        // just return the error status...we don't care about any of the
+        // response information
+        return !line.isError();
+    }
+
+
+    /**
+     * Get an estimate of the transmission size for this
+     * message.  This size is the complete message as it is
+     * encoded and transmitted on the DATA command, not counting
+     * the terminating ".CRLF".
+     *
+     * @param msg    The message we're sending.
+     *
+     * @return The count of bytes, if it can be calculated.
+     */
+    protected int getSizeEstimate(Message msg) {
+        // now the data... I could look at the type, but
+        try {
+            CountingOutputStream outputStream = new CountingOutputStream();
+
+            // the data content has two requirements we need to meet by
+            // filtering the
+            // output stream. Requirement 1 is to conicalize any line breaks.
+            // All line
+            // breaks will be transformed into properly formed CRLF sequences.
+            //
+            // Requirement 2 is to perform byte-stuff for any line that begins
+            // with a "."
+            // so that data is not confused with the end-of-data marker (a
+            // "\r\n.\r\n" sequence.
+            //
+            // The MIME output stream performs those two functions on behalf of
+            // the content
+            // writer.
+            MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
+
+            msg.writeTo(mimeOut);
+
+            // now to finish, we make sure there's a line break at the end.
+            mimeOut.forceTerminatingLineBreak();
+            // and flush the data to send it along
+            mimeOut.flush();
+
+            return outputStream.getCount();
+        } catch (IOException e) {
+            return 0;     // can't get an estimate
+        } catch (MessagingException e) {
+            return 0;     // can't get an estimate
+        }
+    }
+
+
+    /**
+     * Sends the data in the message down the socket. This presumes the server
+     * is in the right place and ready for getting the DATA message and the data
+     * right place in the sequence
+     */
+    protected void sendData(MimeMessage msg) throws MessagingException {
+
+        // send the DATA command
+        SMTPReply line = sendCommand("DATA");
+
+        if (line.isError()) {
+            throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
+        }
+
+        // now the data... I could look at the type, but
+        try {
+            // the data content has two requirements we need to meet by
+            // filtering the
+            // output stream. Requirement 1 is to conicalize any line breaks.
+            // All line
+            // breaks will be transformed into properly formed CRLF sequences.
+            //
+            // Requirement 2 is to perform byte-stuff for any line that begins
+            // with a "."
+            // so that data is not confused with the end-of-data marker (a
+            // "\r\n.\r\n" sequence.
+            //
+            // The MIME output stream performs those two functions on behalf of
+            // the content
+            // writer.
+            MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
+
+            msg.writeTo(mimeOut, new String[] {"Bcc", "Content-Length"});
+
+            // now to finish, we send a CRLF sequence, followed by a ".".
+            mimeOut.writeSMTPTerminator();
+            // and flush the data to send it along
+            mimeOut.flush();
+            this.outputStream.flush(); // most of the time MIMEOutputStream#flush does nothing so ensure we actually flush the data
+        } catch (IOException e) {
+            throw new MessagingException(e.toString());
+        } catch (MessagingException e) {
+            throw new MessagingException(e.toString());
+        }
+
+        // use a longer time out here to give the server time to process the
+        // data.
+        line = getReply(TIMEOUT * 2);
+
+        if (line.isError()) {
+            throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
+        }
+    }
+
+    /**
+     * Sends the QUIT message and receieves the response
+     */
+    protected void sendQuit() throws MessagingException {
+        // there's yet another property that controls whether we should wait for
+        // a reply for a QUIT command. If true, we're suppposed to wait for a response
+        // from the QUIT command.  Otherwise we just send the QUIT and bail.  The default
+        // is "false"
+        if (props.getBooleanProperty(MAIL_SMTP_QUITWAIT, true)) {
+            // handle as a real command...we're going to ignore the response.
+            sendCommand("QUIT");
+        } else {
+            // just send the command without waiting for a response.
+            sendLine("QUIT");
+        }
+    }
+
+    /**
+     * Sets a receiver address for the current message
+     *
+     * @param addr
+     *            The target address.
+     * @param dsn
+     *            An optional DSN option appended to the RCPT TO command.
+     *
+     * @return The status for this particular send operation.
+     * @exception MessagingException
+     */
+    public SendStatus sendRcptTo(InternetAddress addr, String dsn) throws MessagingException {
+        // compose the command using the fixed up email address. Normally, this
+        // involves adding
+        // "<" and ">" around the address.
+
+        StringBuffer command = new StringBuffer();
+
+        // compose the first part of the command
+        command.append("RCPT TO: ");
+        command.append(fixEmailAddress(addr.getAddress()));
+
+        // if we have DSN information, append it to the command.
+        if (dsn != null) {
+            command.append(" NOTIFY=");
+            command.append(dsn);
+        }
+
+        // get a string version of this command.
+        String commandString = command.toString();
+
+        SMTPReply line = sendCommand(commandString);
+
+        switch (line.getCode()) {
+        // these two are both successful transmissions
+        case SMTPReply.COMMAND_ACCEPTED:
+        case SMTPReply.ADDRESS_NOT_LOCAL:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.SUCCESS, addr, commandString, line);
+
+        // these are considered invalid address errors
+        case SMTPReply.PARAMETER_SYNTAX_ERROR:
+        case SMTPReply.INVALID_COMMAND_SEQUENCE:
+        case SMTPReply.MAILBOX_NOT_FOUND:
+        case SMTPReply.INVALID_MAILBOX:
+        case SMTPReply.USER_NOT_LOCAL:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.INVALID_ADDRESS, addr, commandString, line);
+
+        // the command was valid, but something went wrong in the server.
+        case SMTPReply.SERVICE_NOT_AVAILABLE:
+        case SMTPReply.MAILBOX_BUSY:
+        case SMTPReply.PROCESSING_ERROR:
+        case SMTPReply.INSUFFICIENT_STORAGE:
+        case SMTPReply.MAILBOX_FULL:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.SEND_FAILURE, addr, commandString, line);
+
+        // everything else is considered really bad...
+        default:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.GENERAL_ERROR, addr, commandString, line);
+        }
+    }
+
+    /**
+     * Send a command to the server, returning the first response line back as a
+     * reply.
+     *
+     * @param data
+     *            The data to send.
+     *
+     * @return A reply object with the reply line.
+     * @exception MessagingException
+     */
+    protected SMTPReply sendCommand(String data) throws MessagingException {
+        sendLine(data);
+        return getReply();
+    }
+
+    /**
+     * Sends a message down the socket and terminates with the appropriate CRLF
+     */
+    protected void sendLine(String data) throws MessagingException {
+        if (socket == null || !socket.isConnected()) {
+            throw new MessagingException("no connection");
+        }
+        try { // don't write it in multiple times, ie build the data + "\r\n" string in memory to not get surprises on servers read() side
+            outputStream.write((data + "\r\n").getBytes("ISO8859-1"));
+            outputStream.flush();
+        } catch (IOException e) {
+            throw new MessagingException(e.toString());
+        }
+    }
+
+    /**
+     * Receives one line from the server. A line is a sequence of bytes
+     * terminated by a CRLF
+     *
+     * @return the line from the server as String
+     */
+    protected String receiveLine() throws MessagingException {
+        return receiveLine(TIMEOUT);
+    }
+
+    protected SMTPReply getReply() throws MessagingException {
+        return getReply(TIMEOUT);
+    }
+
+    /**
+     * Get a reply line for an SMTP command.
+     *
+     * @return An SMTP reply object from the stream.
+     */
+    protected SMTPReply getReply(int timeout) throws MessagingException {
+        try {
+            lastServerResponse = new SMTPReply(receiveLine(timeout));
+            // if the first line we receive is a continuation, continue
+            // reading lines until we reach the non-continued one.
+            while (lastServerResponse.isContinued()) {
+                lastServerResponse.addLine(receiveLine(timeout));
+            }
+        } catch (MalformedSMTPReplyException e) {
+            throw new MessagingException(e.toString());
+        }
+        return lastServerResponse;
+    }
+
+    /**
+     * Retrieve the last response received from the SMTP server.
+     *
+     * @return The raw response string (including the error code) returned from
+     *         the SMTP server.
+     */
+    public SMTPReply getLastServerResponse() {
+        return lastServerResponse;
+    }
+
+
+    /**
+     * Receives one line from the server. A line is a sequence of bytes
+     * terminated by a CRLF
+     *
+     * @return the line from the server as String
+     */
+    protected String receiveLine(int delayMillis) throws MessagingException {
+        if (socket == null || !socket.isConnected()) {
+            throw new MessagingException("no connection");
+        }
+
+        int timeout = 0;
+
+        try {
+            // for now, read byte for byte, looking for a CRLF
+            timeout = socket.getSoTimeout();
+
+            socket.setSoTimeout(delayMillis);
+
+            StringBuffer buff = new StringBuffer();
+
+            int c;
+            boolean crFound = false, lfFound = false;
+
+            while ((c = inputStream.read()) != -1 && crFound == false && lfFound == false) {
+                // we're looking for a CRLF sequence, so mark each one as seen.
+                // Any other
+                // character gets appended to the end of the buffer.
+                if (c == CR) {
+                    crFound = true;
+                } else if (c == LF) {
+                    lfFound = true;
+                } else {
+                    buff.append((char) c);
+                }
+            }
+
+            String line = buff.toString();
+            return line;
+
+        } catch (SocketException e) {
+            throw new MessagingException(e.toString());
+        } catch (IOException e) {
+            throw new MessagingException(e.toString());
+        } finally {
+            try {
+                socket.setSoTimeout(timeout);
+            } catch (SocketException e) {
+                // ignore - was just trying to do the decent thing...
+            }
+        }
+    }
+
+    /**
+     * Convert an InternetAddress into a form sendable on an SMTP mail command.
+     * InternetAddress.getAddress() generally returns just the address portion
+     * of the full address, minus route address markers. We need to ensure we
+     * have an address with '<' and '>' delimiters.
+     *
+     * @param mail
+     *            The mail address returned from InternetAddress.getAddress().
+     *
+     * @return A string formatted for sending.
+     */
+    protected String fixEmailAddress(String mail) {
+        if (mail.charAt(0) == '<') {
+            return mail;
+        }
+        return "<" + mail + ">";
+    }
+
+    /**
+     * Start the handshake process with the server, including setting up and
+     * TLS-level work. At the completion of this task, we should be ready to
+     * authenticate with the server, if needed.
+     */
+    protected boolean sendHandshake() throws MessagingException {
+        // check to see what sort of initial handshake we need to make.
+        boolean useEhlo = props.getBooleanProperty(MAIL_SMTP_EHLO, true);
+        // if we're to use Ehlo, send it and then fall back to just a HELO
+        // message if it fails.
+        if (useEhlo) {
+            if (!sendEhlo()) {
+                sendHelo();
+            }
+        } else {
+            // send the initial hello response.
+            sendHelo();
+        }
+
+        if (useTLS || requireTLS) {
+            // if we've been told to use TLS
+            // if its not required and server does not support it we establish an unsecure connection
+            //see GERONIMO-5873 and GERONIMO-5430
+            if (requireTLS && !serverTLS) {
+                // if we've been told to use TLS, and this server doesn't support
+                // it, then this is a failure
+                throw new MessagingException("Server doesn't support required transport level security");
+            } else if (serverTLS){
+                // if the server supports TLS, then use it for the connection.
+                // on our connection.
+                getConnectedTLSSocket();
+
+                // some servers (gmail is one that I know of) only send a STARTTLS
+                // extension message on the
+                // first EHLO command. Now that we have the TLS handshaking
+                // established, we need to send a
+                // second EHLO message to retrieve the AUTH records from the server.
+                if (!sendEhlo()) {
+                    throw new MessagingException("Failure sending EHLO command to SMTP server");
+                }
+            } else {
+                if (debug) {
+                    debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
+                }
+            }
+        }
+
+        // this worked.
+        return true;
+    }
+
+
+    /**
+     * Switch the connection to using TLS level security, switching to an SSL
+     * socket.
+     */
+    protected void getConnectedTLSSocket() throws MessagingException {
+        debugOut("Attempting to negotiate STARTTLS with server " + serverHost);
+        // tell the server of our intention to start a TLS session
+        SMTPReply line = sendCommand("STARTTLS");
+
+        if (line.getCode() != SMTPReply.SERVICE_READY) {
+            debugOut("STARTTLS command rejected by SMTP server " + serverHost);
+            throw new MessagingException("Unable to make TLS server connection");
+        }
+
+        debugOut("STARTTLS command accepted");
+
+        // the base class handles the socket switch details
+        super.getConnectedTLSSocket();
+    }
+
+
+    /**
+     * Send the EHLO command to the SMTP server.
+     *
+     * @return True if the command was accepted ok, false for any errors.
+     * @exception SMTPTransportException
+     * @exception MalformedSMTPReplyException
+     * @exception MessagingException
+     */
+    protected boolean sendEhlo() throws MessagingException {
+        sendLine("EHLO " + getLocalHost());
+
+        SMTPReply reply = getReply();
+
+        // we get a 250 code back. The first line is just a greeting, and
+        // extensions are identifed on
+        // continuations. If this fails, then we'll try once more with HELO to
+        // establish bona fides.
+        if (reply.getCode() != SMTPReply.COMMAND_ACCEPTED) {
+            return false;
+        }
+
+        // create a fresh mapping and authentications table
+        capabilities = new HashMap();
+        authentications = new ArrayList();
+
+        List lines = reply.getLines();
+        // process all of the continuation lines
+        for (int i = 1; i < lines.size(); i++) {
+            // go process the extention
+            processExtension((String)lines.get(i));
+        }
+        return true;
+    }
+
+    /**
+     * Send the HELO command to the SMTP server.
+     *
+     * @exception MessagingException
+     */
+    protected void sendHelo() throws MessagingException {
+        // create a fresh mapping and authentications table
+        // these will be empty, but it will prevent NPEs
+        capabilities = new HashMap();
+        authentications = new ArrayList();
+
+        sendLine("HELO " + getLocalHost());
+
+        SMTPReply line = getReply();
+
+        // we get a 250 code back. The first line is just a greeting, and
+        // extensions are identifed on
+        // continuations. If this fails, then we'll try once more with HELO to
+        // establish bona fides.
+        if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
+            throw new MessagingException("Failure sending HELO command to SMTP server");
+        }
+    }
+
+    /**
+     * Return the current startTLS property.
+     *
+     * @return The current startTLS property.
+     */
+    public boolean getStartTLS() {
+        return useTLS;
+    }
+
+
+    /**
+     * Set a new value for the startTLS property.
+     *
+     * @param start
+     *            The new setting.
+     */
+    public void setStartTLS(boolean start) {
+        useTLS = start;
+    }
+
+    
+    /**
+     * Return the current requireTLS property.
+     * 
+     * @return The current requireTLS property.
+     */
+    public boolean getRequireTLS() {
+        return requireTLS;
+    }
+
+
+    /**
+     * Set a new value for the requireTLS property.
+     * 
+     * @param require
+     *                  The new setting.
+     */
+    public void setRequireTLS(boolean require) {
+        requireTLS = require;
+    }
+
+
+    /**
+     * Process an extension string passed back as the EHLP response.
+     *
+     * @param extension
+     *            The string value of the extension (which will be of the form
+     *            "NAME arguments").
+     */
+    protected void processExtension(String extension) {
+        debugOut("Processing extension " + extension);
+        String extensionName = extension.toUpperCase();
+        String argument = "";
+
+        int delimiter = extension.indexOf(' ');
+        // if we have a keyword with arguments, parse them out and add to the
+        // argument map.
+        if (delimiter != -1) {
+            extensionName = extension.substring(0, delimiter).toUpperCase();
+            argument = extension.substring(delimiter + 1);
+        }
+
+        // add this to the map so it can be tested later.
+        capabilities.put(extensionName, argument);
+
+        // process a few special ones that don't require extra parsing.
+        // AUTH and AUTH=LOGIN are handled the same
+        if (extensionName.equals("AUTH")) {
+            // if we don't have an argument on AUTH, this means LOGIN.
+            if (argument == null) {
+                authentications.add("LOGIN");
+            } else {
+                // The security mechanisms are blank delimited tokens.
+                StringTokenizer tokenizer = new StringTokenizer(argument);
+
+                while (tokenizer.hasMoreTokens()) {
+                    String mechanism = tokenizer.nextToken().toUpperCase();
+                    authentications.add(mechanism);
+                }
+            }
+        }
+        // special case for some older servers.
+        else if (extensionName.equals("AUTH=LOGIN")) {
+            authentications.add("LOGIN");
+        }
+        // does this support transport level security?
+        else if (extensionName.equals("STARTTLS")) {
+            // flag this for later
+            serverTLS = true;
+        }
+    }
+
+
+    /**
+     * Retrieve any argument information associated with a extension reported
+     * back by the server on the EHLO command.
+     *
+     * @param name
+     *            The name of the target server extension.
+     *
+     * @return Any argument passed on a server extension. Returns null if the
+     *         extension did not include an argument or the extension was not
+     *         supported.
+     */
+    public String extensionParameter(String name) {
+        if (capabilities != null) {
+            return (String)capabilities.get(name);
+        }
+        return null;
+    }
+
+
+    /**
+     * Tests whether the target server supports a named extension.
+     *
+     * @param name
+     *            The target extension name.
+     *
+     * @return true if the target server reported on the EHLO command that is
+     *         supports the targer server, false if the extension was not
+     *         supported.
+     */
+    public boolean supportsExtension(String name) {
+        // this only returns null if we don't have this extension
+        return extensionParameter(name) != null;
+    }
+
+
+    /**
+     * Authenticate with the server, if necessary (or possible).
+     *
+     * @return true if we are ok to proceed, false for an authentication
+     *         failures.
+     */
+    protected boolean processAuthentication() throws MessagingException {
+        // no authentication defined?
+        if (!props.getBooleanProperty(MAIL_SMTP_AUTH, false)) {
+            return true;
+        }
+
+        // we need to authenticate, but we don't have userid/password
+        // information...fail this
+        // immediately.
+        if (username == null || password == null) {
+            return false;
+        }
+
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
+        if (authenticator == null) {
+            throw new MessagingException("Unable to obtain SASL authenticator");
+        }
+
+
+        if (debug) {
+            debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
+        }
+
+        // if the authenticator has some initial data, we compose a command
+        // containing the initial data.
+        if (authenticator.hasInitialResponse()) {
+            StringBuffer command = new StringBuffer();
+            // the auth command initiates the handshaking.
+            command.append("AUTH ");
+            // and tell the server which mechanism we're using.
+            command.append(authenticator.getMechanismName());
+            command.append(" ");
+            // and append the response data
+            try {
+                command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
+            } catch (UnsupportedEncodingException e) {
+            }
+            // send the command now
+            sendLine(command.toString());
+        }
+        // we just send an auth command with the command type.
+        else {
+            StringBuffer command = new StringBuffer();
+            // the auth command initiates the handshaking.
+            command.append("AUTH ");
+            // and tell the server which mechanism we're using.
+            command.append(authenticator.getMechanismName());
+            // send the command now
+            sendLine(command.toString());
+        }
+
+        // now process the challenge sequence. We get a 235 response back when
+        // the server accepts the
+        // authentication, and a 334 indicates we have an additional challenge.
+        while (true) {
+            // get the next line, and if it is an error response, return now.
+            SMTPReply line;
+            try {
+                line = new SMTPReply(receiveLine());
+            } catch (MalformedSMTPReplyException e) {
+                throw new MessagingException(e.toString());
+            } catch (MessagingException e) {
+                throw e;
+            }
+
+            // if we get a completion return, we've passed muster, so give an
+            // authentication response.
+            if (line.getCode() == SMTPReply.AUTHENTICATION_COMPLETE) {
+                debugOut("Successful SMTP authentication");
+                return true;
+            }
+            // we have an additional challenge to process.
+            else if (line.getCode() == SMTPReply.AUTHENTICATION_CHALLENGE) {
+                // Does the authenticator think it is finished? We can't answer
+                // an additional challenge,
+                // so fail this.
+                if (authenticator.isComplete()) {
+                    return false;
+                }
+
+                try {
+                    // we're passed back a challenge value, Base64 encoded.
+                    byte[] challenge = Base64.decode(line.getMessage().getBytes("ISO8859-1"));
+
+                    // have the authenticator evaluate and send back the encoded
+                    // response.
+                    sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII"));
+                } catch (UnsupportedEncodingException e) {
+                }
+            }
+            // completion or challenge are the only responses we know how to
+            // handle. Anything else must
+            // be a failure.
+            else {
+                if (debug) {
+                    debugOut("Authentication failure " + line);
+                }
+                return false;
+            }
+        }
+    }
+
+
+    /**
+     * Attempt to retrieve a SASL authenticator for this
+     * protocol.
+     *
+     * @return A SASL authenticator, or null if a suitable one
+     *         was not located.
+     */
+    protected ClientAuthenticator getSaslAuthenticator() {
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
+    }
+
+
+    /**
+     * Read the bytes in a stream a test to see if this
+     * conforms to the RFC 2045 rules for 8bit encoding.
+     *
+     * 1)  No more than 998 bytes long
+     * 2)  All lines are terminated with CRLF sequences
+     * 3)  CR and LF characters only occur in properly
+     * formed line separators
+     * 4)  No null characters are allowed.
+     *
+     * @param inStream The source input stream.
+     *
+     * @return true if this can be transmitted successfully
+     *         using 8bit encoding, false if an alternate encoding
+     *         will be required.
+     */
+    protected boolean isValid8bit(InputStream inStream) {
+        try {
+            int ch;
+            int lineLength = 0;
+            while ((ch = inStream.read()) >= 0) {
+                // nulls are decidedly not allowed
+                if (ch == 0) {
+                    return false;
+                }
+                // start of a CRLF sequence (potentially)
+                else if (ch == '\r') {
+                    // check the next character.  There must be one,
+                    // and it must be a LF for this to be value
+                    ch = inStream.read();
+                    if (ch != '\n') {
+                        return false;
+                    }
+                    // reset the line length
+                    lineLength = 0;
+                }
+                else {
+                    // a normal character
+                    lineLength++;
+                    // make sure the line is not too long
+                    if (lineLength > 998) {
+                        return false;
+                    }
+                }
+
+            }
+        } catch (IOException e) {
+            return false;  // can't read this, don't try passing it
+        }
+        // this converted ok
+        return true;
+    }
+
+
+    /**
+     * Simple holder class for the address/send status duple, as we can have
+     * mixed success for a set of addresses and a message
+     */
+    static public class SendStatus {
+        public final static int SUCCESS = 0;
+
+        public final static int INVALID_ADDRESS = 1;
+
+        public final static int SEND_FAILURE = 2;
+
+        public final static int GENERAL_ERROR = 3;
+
+        // the status type of the send operation.
+        int status;
+
+        // the address associated with this status
+        InternetAddress address;
+
+        // the command string send to the server.
+        String cmd;
+
+        // the reply from the server.
+        SMTPReply reply;
+
+        /**
+         * Constructor for a SendStatus item.
+         *
+         * @param s
+         *            The status type.
+         * @param a
+         *            The address this is the status for.
+         * @param c
+         *            The command string associated with this status.
+         * @param r
+         *            The reply information from the server.
+         */
+        public SendStatus(int s, InternetAddress a, String c, SMTPReply r) {
+            this.cmd = c;
+            this.status = s;
+            this.address = a;
+            this.reply = r;
+        }
+
+        /**
+         * Get the status information for this item.
+         *
+         * @return The current status code.
+         */
+        public int getStatus() {
+            return this.status;
+        }
+
+        /**
+         * Retrieve the InternetAddress object associated with this send
+         * operation.
+         *
+         * @return The associated address object.
+         */
+        public InternetAddress getAddress() {
+            return this.address;
+        }
+
+        /**
+         * Retrieve the reply information associated with this send operati
+         *
+         * @return The SMTPReply object received for the operation.
+         */
+        public SMTPReply getReply() {
+            return reply;
+        }
+
+        /**
+         * Get the command string sent for this send operation.
+         *
+         * @return The command string for the MAIL TO command sent to the
+         *         server.
+         */
+        public String getCommand() {
+            return cmd;
+        }
+
+        /**
+         * Get an exception object associated with this send operation. There is
+         * a mechanism for reporting send success via a send operation, so this
+         * will be either a success or failure exception.
+         *
+         * @param reportSuccess
+         *            Indicates if we want success operations too.
+         *
+         * @return A newly constructed exception object.
+         */
+        public MessagingException getException(boolean reportSuccess) {
+            if (status != SUCCESS) {
+                return new SMTPAddressFailedException(address, cmd, reply.getCode(), reply.getMessage());
+            } else {
+                if (reportSuccess) {
+                    return new SMTPAddressSucceededException(address, cmd, reply.getCode(), reply.getMessage());
+                }
+            }
+            return null;
+        }
+    }
+
+
+    /**
+     * Reset the server connection after an error.
+     *
+     * @exception MessagingException
+     */
+    public void resetConnection() throws MessagingException {
+        // we want the caller to retrieve the last response responsbile for
+        // requiring the reset, so save and
+        // restore that info around the reset.
+        SMTPReply last = lastServerResponse;
+
+        // send a reset command.
+        SMTPReply line = sendCommand("RSET");
+
+        // if this did not reset ok, just close the connection
+        if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
+            close();
+        }
+        // restore this.
+        lastServerResponse = last;
+    }
+
+
+    /**
+     * Return the current reportSuccess property.
+     *
+     * @return The current reportSuccess property.
+     */
+    public boolean getReportSuccess() {
+        return reportSuccess;
+    }
+
+    /**
+     * Set a new value for the reportSuccess property.
+     *
+     * @param report
+     *            The new setting.
+     */
+    public void setReportSuccess(boolean report) {
+        reportSuccess = report;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java
new file mode 100644
index 0000000..91d8c95
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java
@@ -0,0 +1,237 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import java.io.InputStream;
+
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+
+public class SMTPMessage extends MimeMessage {
+
+    // never notify
+    public static final int NOTIFY_NEVER = -1;
+
+    // notify of successful deliveries.
+    public static final int NOTIFY_SUCCESS = 1;
+
+    // notify of delivery failures.
+    public static final int NOTIFY_FAILURE = 2;
+
+    // notify of delivery delays
+    public static final int NOTIFY_DELAY = 4;
+
+    // return full message with status notifications
+    public static final int RETURN_FULL = 1;
+
+    // return only message headers with status notifications
+    public static final int RETURN_HDRS = 2;
+
+    // support 8BitMime encodings
+    protected boolean allow8bitMIME = false;
+
+    // a from address specified in the message envelope. Overrides other from
+    // sources.
+    protected String envelopeFrom = null;
+
+    // an option string to append to the MAIL command on sending.
+    protected String mailExtension = null;
+
+    // SMTP mail notification options if DSN is supported.
+    protected int notifyOptions = 0;
+
+    // DSN return option notification values.
+    protected int returnOption = 0;
+
+    // allow sending if some addresses give errors.
+    protected boolean sendPartial = false;
+
+    // an RFC 2554 AUTH= value.
+    protected String submitter = null;
+
+    /**
+     * Default (and normal) constructor for an SMTPMessage.
+     * 
+     * @param session
+     *            The hosting Javamail Session.
+     */
+    public SMTPMessage(Session session) {
+        // this is a simple one.
+        super(session);
+    }
+
+    /**
+     * Construct an SMTPMessage instance by reading and parsing the data from
+     * the provided InputStream. The InputStream will be left positioned at the
+     * end of the message data on constructor completion.
+     * 
+     * @param session
+     *            The hosting Javamail Session.
+     */
+    public SMTPMessage(Session session, InputStream source) throws MessagingException {
+        // this is a simple one.
+        super(session, source);
+    }
+
+    /**
+     * Construct an SMTPMimeMessage from another source MimeMessage object. The
+     * new object and the old object are independent of each other.
+     * 
+     * @param source
+     *            The source MimeMessage object.
+     */
+    public SMTPMessage(MimeMessage source) throws MessagingException {
+        super(source);
+    }
+
+    /**
+     * Change the allow8BitMime attribute for the message.
+     * 
+     * @param a
+     *            The new setting.
+     */
+    public void setAllow8bitMIME(boolean a) {
+        allow8bitMIME = a;
+    }
+
+    /**
+     * Retrieve the current 8bitMIME attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public boolean getAllow8bitMIME() {
+        return allow8bitMIME;
+    }
+
+    /**
+     * Change the envelopeFrom attribute for the message.
+     * 
+     * @param from
+     *            The new setting.
+     */
+    public void setEnvelopeFrom(String from) {
+        envelopeFrom = from;
+    }
+
+    /**
+     * Retrieve the current evelopeFrom attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public String getEnvelopeFrom() {
+        return envelopeFrom;
+    }
+
+    /**
+     * Change the mailExtension attribute for the message.
+     * 
+     * @param e
+     *            The new setting.
+     */
+    public void setMailExtension(String e) {
+        mailExtension = e;
+    }
+
+    /**
+     * Retrieve the current mailExtension attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public String getMailExtension() {
+        return mailExtension;
+    }
+
+    /**
+     * Change the notifyOptions attribute for the message.
+     * 
+     * @param options
+     *            The new setting.
+     */
+    public void setNotifyOptions(int options) {
+        notifyOptions = options;
+    }
+
+    /**
+     * Retrieve the current notifyOptions attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public int getNotifyOptions() {
+        return notifyOptions;
+    }
+
+    /**
+     * Change the returnOptions attribute for the message.
+     * 
+     * @param option
+     *            The new setting.
+     */
+    public void setReturnOption(int option) {
+        returnOption = option;
+    }
+
+    /**
+     * Retrieve the current returnOption attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public int getReturnOption() {
+        return returnOption;
+    }
+
+    /**
+     * Change the sendPartial attribute for the message.
+     * 
+     * @param a
+     *            The new setting.
+     */
+    public void setSendPartial(boolean a) {
+        sendPartial = a;
+    }
+
+    /**
+     * Retrieve the current sendPartial attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public boolean getSendPartial() {
+        return sendPartial;
+    }
+
+    /**
+     * Change the submitter attribute for the message.
+     * 
+     * @param s
+     *            The new setting.
+     */
+    public void setSubmitter(String s) {
+        submitter = s;
+    }
+
+    /**
+     * Retrieve the current submitter attribute.
+     * 
+     * @return The current attribute value.
+     */
+    public String getSubmitter() {
+        return submitter;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java
new file mode 100644
index 0000000..092bd02
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java
@@ -0,0 +1,208 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+ 
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Util class to represent a reply from a SMTP server
+ * 
+ * @version $Rev: 673649 $ $Date: 2008-07-03 06:37:56 -0400 (Thu, 03 Jul 2008) $
+ */
+class SMTPReply {
+    // SMTP reply codes
+    public static final int SERVICE_READY = 220;
+
+    public static final int SERVICE_CLOSING = 221;
+
+    public static final int AUTHENTICATION_COMPLETE = 235;
+
+    public static final int COMMAND_ACCEPTED = 250;
+
+    public static final int ADDRESS_NOT_LOCAL = 251;
+
+    public static final int AUTHENTICATION_CHALLENGE = 334;
+
+    public static final int START_MAIL_INPUT = 354;
+
+    public static final int SERVICE_NOT_AVAILABLE = 421;
+
+    public static final int MAILBOX_BUSY = 450;
+
+    public static final int PROCESSING_ERROR = 451;
+
+    public static final int INSUFFICIENT_STORAGE = 452;
+
+    public static final int COMMAND_SYNTAX_ERROR = 500;
+
+    public static final int PARAMETER_SYNTAX_ERROR = 501;
+
+    public static final int COMMAND_NOT_IMPLEMENTED = 502;
+
+    public static final int INVALID_COMMAND_SEQUENCE = 503;
+
+    public static final int COMMAND_PARAMETER_NOT_IMPLEMENTED = 504;
+
+    public static final int MAILBOX_NOT_FOUND = 550;
+
+    public static final int USER_NOT_LOCAL = 551;
+
+    public static final int MAILBOX_FULL = 552;
+
+    public static final int INVALID_MAILBOX = 553;
+
+    public static final int TRANSACTION_FAILED = 553;
+    
+    // The original reply string
+    private final String reply;
+
+    // returned message code
+    private final int code;
+
+    // the returned message text
+    private final String message;
+    
+    // additional returned lines from a continued response 
+    private List lines; 
+
+    // indicates that this is a continuation response
+    private boolean continued;
+
+    SMTPReply(String s) throws MalformedSMTPReplyException {
+        // save the reply
+        reply = s;
+
+        // In a normal response, the first 3 must be the return code. However,
+        // the response back from a QUIT command is frequently a null string.
+        // Therefore, if the result is
+        // too short, just default the code to -1 and use the entire text for
+        // the message.
+        if (s == null || s.length() < 3) {
+            code = -1;
+            message = s;
+            return;
+        }
+
+        try {
+            continued = false;
+            code = Integer.parseInt(s.substring(0, 3));
+
+            // message should be separated by a space OR a continuation
+            // character if this is a
+            // multi-line response.
+            if (s.length() > 4) {
+                //
+                if (s.charAt(3) == '-') {
+                    continued = true;
+                }
+                message = s.substring(4);
+            } else {
+                message = "";
+            }
+        } catch (NumberFormatException e) {
+            throw new MalformedSMTPReplyException("error in parsing code", e);
+        }
+    }
+    
+    /**
+     * Add a line to a continued response.  This will 
+     * update the continued status if the end of the 
+     * response is reached. 
+     * 
+     * @param line   The line to add.
+     */
+    public void addLine(String line) {
+        if (lines == null) {
+            lines = new ArrayList(); 
+            lines.add(message); 
+        }
+        // mark if we're still continued 
+        continued = line.charAt(3) == '-';
+        // add the line to the list 
+        lines.add(line.substring(4)); 
+    }
+    
+    /**
+     * Get the list of all of the lines associated with 
+     * this reply. 
+     * 
+     * @return A List containing all lines associated with this
+     *         reply.
+     */
+    public List getLines() {
+        if (lines == null) {
+            lines = new ArrayList(); 
+            lines.add(message); 
+        }
+        return lines;
+    }
+    
+
+    /**
+     * Return the code value associated with the reply.
+     * 
+     * @return The integer code associated with the reply.
+     */
+    public int getCode() {
+        return this.code;
+    }
+
+    /**
+     * Get the message text associated with the reply.
+     * 
+     * @return The string value of the message from the reply.
+     */
+    public String getMessage() {
+        return this.message;
+    }
+
+    /**
+     * Retrieve the raw reply string for the reponse.
+     * 
+     * @return The original reply string from the server.
+     */
+    public String getReply() {
+        return reply;
+    }
+
+    /**
+     * Indicates if reply is an error condition
+     */
+    boolean isError() {
+        // error codes are all above 400
+        return code >= 400;
+    }
+
+    /**
+     * Indicates whether this response is flagged as part of a multiple line
+     * response.
+     * 
+     * @return true if the response has multiple lines, false if this is the
+     *         last line of the response.
+     */
+    public boolean isContinued() {
+        return continued;
+    }
+
+    public String toString() {
+        return "CODE = " + getCode() + " : MSG = " + getMessage();
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java
new file mode 100644
index 0000000..0794065
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import javax.mail.Session;
+import javax.mail.URLName;
+
+public class SMTPSTransport extends SMTPTransport {
+    /**
+     * @param session
+     * @param name
+     */
+    public SMTPSTransport(Session session, URLName name) {
+        super(session, name, "smtps", 465, true);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java
new file mode 100644
index 0000000..20ff08a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import javax.mail.Address;
+import javax.mail.SendFailedException;
+
+public class SMTPSendFailedException extends SendFailedException {
+    // the failing command
+    protected String cmd;
+
+    // the error code for the failure
+    protected int rc;
+
+    /**
+     * Constructor for an SMTPSendFaileException.
+     * 
+     * @param cmd
+     *            The failing command string.
+     * @param rc
+     *            The error code for the failing command.
+     * @param err
+     *            An error message for the exception.
+     * @param ex
+     *            Any associated nested exception.
+     * @param vs
+     *            An array of valid, sent addresses.
+     * @param vus
+     *            An array of addresses that were valid, but were unsent.
+     * @param inv
+     *            An array of addresses deemed invalid.
+     */
+    SMTPSendFailedException(java.lang.String cmd, int rc, java.lang.String err, java.lang.Exception ex, Address[] vs,
+            Address[] vus, Address[] inv) {
+        super(err, ex, vs, vus, inv);
+        this.cmd = cmd;
+        this.rc = rc;
+    }
+
+    /**
+     * Get the failing command string for the exception.
+     * 
+     * @return The string value of the failing command.
+     */
+    public String getCommand() {
+        return cmd;
+    }
+
+    /**
+     * The failing command return code.
+     * 
+     * @return The failure return code.
+     */
+    public int getReturnCode() {
+        return rc;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java
new file mode 100644
index 0000000..b89988f
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java
@@ -0,0 +1,656 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.Socket; 
+import java.util.ArrayList;
+
+import javax.mail.Address;
+import javax.mail.AuthenticationFailedException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.URLName;
+import javax.mail.event.TransportEvent;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;     
+import javax.mail.internet.MimePart;     
+
+import org.apache.geronimo.javamail.util.ProtocolProperties; 
+import org.apache.geronimo.javamail.transport.smtp.SMTPConnection.SendStatus; 
+
+/**
+ * Simple implementation of SMTP transport. Just does plain RFC821-ish delivery.
+ * <p/> Supported properties : <p/>
+ * <ul>
+ * <li> mail.host : to set the server to deliver to. Default = localhost</li>
+ * <li> mail.smtp.port : to set the port. Default = 25</li>
+ * <li> mail.smtp.locahost : name to use for HELO/EHLO - default getHostName()</li>
+ * </ul>
+ * <p/> There is no way to indicate failure for a given recipient (it's possible
+ * to have a recipient address rejected). The sun impl throws exceptions even if
+ * others successful), but maybe we do a different way... <p/> TODO : lots.
+ * ESMTP, user/pass, indicate failure, etc...
+ *
+ * @version $Rev: 995094 $ $Date: 2010-09-08 11:29:50 -0400 (Wed, 08 Sep 2010) $
+ */
+public class SMTPTransport extends Transport {
+    /**
+     * property keys for protocol properties. The actual property name will be
+     * appended with "mail." + protocol + ".", where the protocol is either
+     * "smtp" or "smtps".
+     */
+    protected static final String MAIL_SMTP_DSN_NOTIFY = "dsn.notify";
+    protected static final String MAIL_SMTP_SENDPARTIAL = "sendpartial";
+    protected static final String MAIL_SMTP_EXTENSION = "mailextension";
+    protected static final String DEFAULT_MAIL_HOST = "localhost";
+
+    protected static final int DEFAULT_MAIL_SMTP_PORT = 25;
+    protected static final int DEFAULT_MAIL_SMTPS_PORT = 465;
+
+
+    // do we use SSL for our initial connection?
+    protected boolean sslConnection = false;
+    
+    // our accessor for protocol properties and the holder of 
+    // protocol-specific information 
+    protected ProtocolProperties props; 
+    // our active connection object 
+    protected SMTPConnection connection;
+
+    // the last response line received from the server.
+    protected SMTPReply lastServerResponse = null;
+
+    /**
+     * Normal constructor for an SMTPTransport() object. This constructor is
+     * used to build a transport instance for the "smtp" protocol.
+     *
+     * @param session
+     *            The attached session.
+     * @param name
+     *            An optional URLName object containing target information.
+     */
+    public SMTPTransport(Session session, URLName name) {
+        this(session, name, "smtp", DEFAULT_MAIL_SMTP_PORT, false);
+    }
+    
+
+    /**
+     * Common constructor used by the SMTPTransport and SMTPSTransport classes
+     * to do common initialization of defaults.
+     *
+     * @param session
+     *            The host session instance.
+     * @param name
+     *            The URLName of the target.
+     * @param protocol
+     *            The protocol type (either "smtp" or "smtps". This helps us in
+     *            retrieving protocol-specific session properties.
+     * @param defaultPort
+     *            The default port used by this protocol. For "smtp", this will
+     *            be 25. The default for "smtps" is 465.
+     * @param sslConnection
+     *            Indicates whether an SSL connection should be used to initial
+     *            contact the server. This is different from the STARTTLS
+     *            support, which switches the connection to SSL after the
+     *            initial startup.
+     */
+    protected SMTPTransport(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+        super(session, name);
+        
+        // create the protocol property holder.  This gives an abstraction over the different 
+        // flavors of the protocol. 
+        props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
+        // the connection manages connection for the transport 
+        connection = new SMTPConnection(props); 
+    }
+
+    
+    /**
+     * Connect to a server using an already created socket. This connection is
+     * just like any other connection, except we will not create a new socket.
+     *
+     * @param socket
+     *            The socket connection to use.
+     */
+    public void connect(Socket socket) throws MessagingException {
+        connection.connect(socket); 
+        super.connect();
+    }
+    
+
+    /**
+     * Do the protocol connection for an SMTP transport. This handles server
+     * authentication, if possible. Returns false if unable to connect to the
+     * server.
+     *
+     * @param host
+     *            The target host name.
+     * @param port
+     *            The server port number.
+     * @param user
+     *            The authentication user (if any).
+     * @param password
+     *            The server password. Might not be sent directly if more
+     *            sophisticated authentication is used.
+     *
+     * @return true if we were able to connect to the server properly, false for
+     *         any failures.
+     * @exception MessagingException
+     */
+    protected boolean protocolConnect(String host, int port, String username, String password)
+            throws MessagingException {
+        // the connection pool handles all of the details here. 
+        return connection.protocolConnect(host, port, username, password);
+    }
+
+    /**
+     * Send a message to multiple addressees.
+     *
+     * @param message
+     *            The message we're sending.
+     * @param addresses
+     *            An array of addresses to send to.
+     *
+     * @exception MessagingException
+     */
+    public void sendMessage(Message message, Address[] addresses) throws MessagingException {
+        if (!isConnected()) {
+            throw new IllegalStateException("Not connected");
+        }
+        // don't bother me w/ null messages or no addreses
+        if (message == null) {
+            throw new MessagingException("Null message");
+        }
+
+        // SMTP only handles instances of MimeMessage, not the more general
+        // message case.
+        if (!(message instanceof MimeMessage)) {
+            throw new MessagingException("SMTP can only send MimeMessages");
+        }
+
+        // we must have a message list.
+        if (addresses == null || addresses.length == 0) {
+            throw new MessagingException("Null or empty address array");
+        }
+        
+        boolean reportSuccess = getReportSuccess(); 
+        
+        // now see how we're configured for this send operation.
+        boolean partialSends = false;
+
+        // this can be attached directly to the message.
+        if (message instanceof SMTPMessage) {
+            partialSends = ((SMTPMessage) message).getSendPartial();
+        }
+
+        // if still false on the message object, check for a property
+        // version also
+        if (!partialSends) {
+            partialSends = props.getBooleanProperty(MAIL_SMTP_SENDPARTIAL, false);
+        }
+
+        boolean haveGroup = false;
+
+        // enforce the requirement that all of the targets are InternetAddress
+        // instances.
+        for (int i = 0; i < addresses.length; i++) {
+            if (addresses[i] instanceof InternetAddress) {
+                // and while we're here, see if we have a groups in the address
+                // list. If we do, then
+                // we're going to need to expand these before sending.
+                if (((InternetAddress) addresses[i]).isGroup()) {
+                    haveGroup = true;
+                }
+            } else {
+                throw new MessagingException("Illegal InternetAddress " + addresses[i]);
+            }
+        }
+
+        // did we find a group? Time to expand this into our full target list.
+        if (haveGroup) {
+            addresses = expandGroups(addresses);
+        }
+
+        SendStatus[] stats = new SendStatus[addresses.length];
+
+        // create our lists for notification and exception reporting.
+        Address[] sent = null;
+        Address[] unsent = null;
+        Address[] invalid = null;
+
+        try {
+            // send sender first. If this failed, send a failure notice of the
+            // event, using the full list of
+            // addresses as the unsent, and nothing for the rest.
+            if (!connection.sendMailFrom(message)) {
+                unsent = addresses;
+                sent = new Address[0];
+                invalid = new Address[0];
+                // notify of the error.
+                notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
+
+                // include the reponse information here.
+                SMTPReply last = connection.getLastServerResponse(); 
+                // now send an "uber-exception" to indicate the failure.
+                throw new SMTPSendFailedException("MAIL FROM", last.getCode(), last.getMessage(), null, sent, unsent,
+                        invalid);
+            }
+
+            // get the additional notification status, if available 
+            String dsn = getDeliveryStatusNotification(message);
+
+            // we need to know about any failures once we've gone through the
+            // complete list, so keep a
+            // failure flag.
+            boolean sendFailure = false;
+
+            // event notifcation requires we send lists of successes and
+            // failures broken down by category.
+            // The categories are:
+            //
+            // 1) addresses successfully processed.
+            // 2) addresses deemed valid, but had a processing failure that
+            // prevented sending.
+            // 3) addressed deemed invalid (basically all other processing
+            // failures).
+            ArrayList sentAddresses = new ArrayList();
+            ArrayList unsentAddresses = new ArrayList();
+            ArrayList invalidAddresses = new ArrayList();
+
+            // Now we add a MAIL TO record for each recipient. At this point, we
+            // just collect
+            for (int i = 0; i < addresses.length; i++) {
+                InternetAddress target = (InternetAddress) addresses[i];
+
+                // write out the record now.
+                SendStatus status = connection.sendRcptTo(target, dsn);
+                stats[i] = status;
+
+                switch (status.getStatus()) {
+                    // successfully sent
+                    case SendStatus.SUCCESS:
+                        sentAddresses.add(target);
+                        break;
+
+                    // we have an invalid address of some sort, or a general sending
+                    // error (which we'll
+                    // interpret as due to an invalid address.
+                    case SendStatus.INVALID_ADDRESS:
+                    case SendStatus.GENERAL_ERROR:
+                        sendFailure = true;
+                        invalidAddresses.add(target);
+                        break;
+
+                    // good address, but this was a send failure.
+                    case SendStatus.SEND_FAILURE:
+                        sendFailure = true;
+                        unsentAddresses.add(target);
+                        break;
+                    }
+            }
+
+            // if we had a send failure, then we need to check if we allow
+            // partial sends. If not allowed,
+            // we abort the send operation now.
+            if (sendFailure) {
+                // if we're not allowing partial successes or we've failed on
+                // all of the addresses, it's
+                // time to abort.
+                if (!partialSends || sentAddresses.isEmpty()) {
+                    // we send along the valid and invalid address lists on the
+                    // notifications and
+                    // exceptions.
+                    // however, since we're aborting the entire send, the
+                    // successes need to become
+                    // members of the failure list.
+                    unsentAddresses.addAll(sentAddresses);
+
+                    // this one is empty.
+                    sent = new Address[0];
+                    unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+                    invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
+
+                    // go reset our connection so we can process additional
+                    // sends.
+                    connection.resetConnection();
+
+                    // get a list of chained exceptions for all of the failures.
+                    MessagingException failures = generateExceptionChain(stats, false);
+
+                    // now send an "uber-exception" to indicate the failure.
+                    throw new SMTPSendFailedException("MAIL TO", 0, "Invalid Address", failures, sent, unsent, invalid);
+                }
+            }
+
+            try {
+                // try to send the data
+                connection.sendData((MimeMessage)message);
+            } catch (MessagingException e) {
+                // If there's an error at this point, this is a complete
+                // delivery failure.
+                // we send along the valid and invalid address lists on the
+                // notifications and
+                // exceptions.
+                // however, since we're aborting the entire send, the successes
+                // need to become
+                // members of the failure list.
+                unsentAddresses.addAll(sentAddresses);
+
+                // this one is empty.
+                sent = new Address[0];
+                unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+                invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
+                // notify of the error.
+                notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
+                // send a send failure exception.
+                throw new SMTPSendFailedException("DATA", 0, "Send failure", e, sent, unsent, invalid);
+            }
+
+            // create our lists for notification and exception reporting from
+            // this point on.
+            sent = (Address[]) sentAddresses.toArray(new Address[0]);
+            unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+            invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
+
+            // if sendFailure is true, we had an error during the address phase,
+            // but we had permission to
+            // process this as a partial send operation. Now that the data has
+            // been sent ok, it's time to
+            // report the partial failure.
+            if (sendFailure) {
+                // notify our listeners of the partial delivery.
+                notifyTransportListeners(TransportEvent.MESSAGE_PARTIALLY_DELIVERED, sent, unsent, invalid, message);
+
+                // get a list of chained exceptions for all of the failures (and
+                // the successes, if reportSuccess has been
+                // turned on).
+                MessagingException failures = generateExceptionChain(stats, reportSuccess);
+
+                // now send an "uber-exception" to indicate the failure.
+                throw new SMTPSendFailedException("MAIL TO", 0, "Invalid Address", failures, sent, unsent, invalid);
+            }
+
+            // notify our listeners of successful delivery.
+            notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED, sent, unsent, invalid, message);
+
+            // we've not had any failures, but we've been asked to report
+            // success as an exception. Do
+            // this now.
+            if (reportSuccess) {
+                // generate the chain of success exceptions (we already know
+                // there are no failure ones to report).
+                MessagingException successes = generateExceptionChain(stats, reportSuccess);
+                if (successes != null) {
+                    throw successes;
+                }
+            }
+        } catch (SMTPSendFailedException e) {
+            // if this is a send failure, we've already handled
+            // notifications....just rethrow it.
+            throw e;
+        } catch (MessagingException e) {
+            // notify of the error.
+            notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
+            throw e;
+        }
+    }
+    
+    
+    /**
+     * Determine what delivery status notification should
+     * be added to the RCPT TO: command. 
+     * 
+     * @param message The message we're sending.
+     * 
+     * @return The string NOTIFY= value to add to the command. 
+     */
+    protected String getDeliveryStatusNotification(Message message) {
+        String dsn = null;
+
+        // there's an optional notification argument that can be added to
+        // MAIL TO. See if we've been
+        // provided with one.
+
+        // an SMTPMessage object is the first source
+        if (message instanceof SMTPMessage) {
+            // get the notification options
+            int options = ((SMTPMessage) message).getNotifyOptions();
+
+            switch (options) {
+            // a zero value indicates nothing is set.
+            case 0:
+                break;
+
+            case SMTPMessage.NOTIFY_NEVER:
+                dsn = "NEVER";
+                break;
+
+            case SMTPMessage.NOTIFY_SUCCESS:
+                dsn = "SUCCESS";
+                break;
+
+            case SMTPMessage.NOTIFY_FAILURE:
+                dsn = "FAILURE";
+                break;
+
+            case SMTPMessage.NOTIFY_DELAY:
+                dsn = "DELAY";
+                break;
+
+            // now for combinations...there are few enough combinations here
+            // that we can just handle this in the switch statement rather
+            // than have to
+            // concatentate everything together.
+            case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE):
+                dsn = "SUCCESS,FAILURE";
+                break;
+
+            case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_DELAY):
+                dsn = "SUCCESS,DELAY";
+                break;
+
+            case (SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
+                dsn = "FAILURE,DELAY";
+                break;
+
+            case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
+                dsn = "SUCCESS,FAILURE,DELAY";
+                break;
+            }
+        }
+
+        // if still null, grab a property value (yada, yada, yada...)
+        if (dsn == null) {
+            dsn = props.getProperty(MAIL_SMTP_DSN_NOTIFY);
+        }
+        return dsn; 
+    }
+    
+
+
+    /**
+     * Close the connection. On completion, we'll be disconnected from the
+     * server and unable to send more data.
+     * 
+     * @exception MessagingException
+     */
+    public void close() throws MessagingException {
+        // This is done to ensure proper event notification.
+        super.close();
+        // NB:  We reuse the connection if asked to reconnect 
+        connection.close();
+    }
+    
+    
+    /**
+     * Turn a series of send status items into a chain of exceptions indicating
+     * the state of each send operation.
+     *
+     * @param stats
+     *            The list of SendStatus items.
+     * @param reportSuccess
+     *            Indicates whether we should include the report success items.
+     *
+     * @return The head of a chained list of MessagingExceptions.
+     */
+    protected MessagingException generateExceptionChain(SendStatus[] stats, boolean reportSuccess) {
+        MessagingException current = null;
+
+        for (int i = 0; i < stats.length; i++) {
+            SendStatus status = stats[i];
+
+            if (status != null) {
+                MessagingException nextException = stats[i].getException(reportSuccess);
+                // if there's an exception associated with this status, chain it
+                // up with the rest.
+                if (nextException != null) {
+                    if (current == null) {
+                        current = nextException;
+                    } else {
+                        current.setNextException(nextException);
+                        current = nextException;
+                    }
+                }
+            }
+        }
+        return current;
+    }
+
+    /**
+     * Expand the address list by converting any group addresses into single
+     * address targets.
+     *
+     * @param addresses
+     *            The input array of addresses.
+     *
+     * @return The expanded array of addresses.
+     * @exception MessagingException
+     */
+    protected Address[] expandGroups(Address[] addresses) throws MessagingException {
+        ArrayList expandedAddresses = new ArrayList();
+
+        // run the list looking for group addresses, and add the full group list
+        // to our targets.
+        for (int i = 0; i < addresses.length; i++) {
+            InternetAddress address = (InternetAddress) addresses[i];
+            // not a group? Just copy over to the other list.
+            if (!address.isGroup()) {
+                expandedAddresses.add(address);
+            } else {
+                // get the group address and copy each member of the group into
+                // the expanded list.
+                InternetAddress[] groupAddresses = address.getGroup(true);
+                for (int j = 1; j < groupAddresses.length; j++) {
+                    expandedAddresses.add(groupAddresses[j]);
+                }
+            }
+        }
+
+        // convert back into an array.
+        return (Address[]) expandedAddresses.toArray(new Address[0]);
+    }
+    
+
+    /**
+     * Retrieve the local client host name.
+     *
+     * @return The string version of the local host name.
+     * @exception SMTPTransportException
+     */
+    public String getLocalHost() throws MessagingException {
+        return connection.getLocalHost(); 
+    }
+
+    
+    /**
+     * Explicitly set the local host information.
+     *
+     * @param localHost
+     *            The new localHost name.
+     */
+    public void setLocalHost(String localHost) {
+        connection.setLocalHost(localHost); 
+    }
+
+    
+    /**
+     * Return the current reportSuccess property.
+     *
+     * @return The current reportSuccess property.
+     */
+    public boolean getReportSuccess() {
+        return connection.getReportSuccess(); 
+    }
+
+    /**
+     * Set a new value for the reportSuccess property.
+     *
+     * @param report
+     *            The new setting.
+     */
+    public void setReportSuccess(boolean report) {
+        connection.setReportSuccess(report); 
+    }
+
+    /**
+     * Return the current startTLS property.
+     *
+     * @return The current startTLS property.
+     */
+    public boolean getStartTLS() {
+        return connection.getStartTLS(); 
+    }
+
+    /**
+     * Set a new value for the startTLS property.
+     *
+     * @param start
+     *            The new setting.
+     */
+    public void setStartTLS(boolean start) {
+        connection.setStartTLS(start); 
+    }
+
+    /**
+     * Retrieve the SASL realm used for DIGEST-MD5 authentication. This will
+     * either be explicitly set, or retrieved using the mail.smtp.sasl.realm
+     * session property.
+     *
+     * @return The current realm information (which can be null).
+     */
+    public String getSASLRealm() {
+        return connection.getSASLRealm(); 
+    }
+
+    /**
+     * Explicitly set the SASL realm used for DIGEST-MD5 authenticaiton.
+     *
+     * @param name
+     *            The new realm name.
+     */
+    public void setSASLRealm(String name) {
+        connection.setSASLRealm(name); 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java
new file mode 100644
index 0000000..d6851e3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.geronimo.javamail.transport.smtp;
+
+/**
+ * General purpose Exception
+ * 
+ * @version $Id: SMTPTransportException.java 437941 2006-08-29 03:56:02Z jdillon $
+ */
+class SMTPTransportException extends Exception {
+
+    SMTPTransportException() {
+        super();
+    }
+
+    SMTPTransportException(String s) {
+        super(s);
+    }
+
+    SMTPTransportException(String s, Exception t) {
+        super(s, t);
+    }
+
+    SMTPTransportException(Exception t) {
+        super("SMTP Transport error", t);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java
new file mode 100644
index 0000000..2c12b70
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java
@@ -0,0 +1,35 @@
+/**
+ * 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 org.apache.geronimo.javamail.util;
+
+import javax.mail.MessagingException; 
+
+public class CommandFailedException extends MessagingException {
+    public CommandFailedException() {
+        super();
+    }
+
+    public CommandFailedException(String message) {
+        super(message);
+    }
+
+    public CommandFailedException(String message, Exception cause) {
+        super(message, cause);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java
new file mode 100644
index 0000000..ece163d
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java
@@ -0,0 +1,35 @@
+/**
+ * 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 org.apache.geronimo.javamail.util;
+
+import javax.mail.MessagingException; 
+
+public class ConnectionException extends MessagingException {
+    public ConnectionException() {
+        super();
+    }
+
+    public ConnectionException(String message) {
+        super(message);
+    }
+
+    public ConnectionException(String message, Exception cause) {
+        super(message, cause);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java
new file mode 100644
index 0000000..3dc5e1c
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.geronimo.javamail.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An implementation of an OutputStream just counts
+ * the number of bytes written to the stream. 
+ * @version $Rev: 671217 $ $Date: 2008-06-24 11:39:52 -0400 (Tue, 24 Jun 2008) $
+ */
+public class CountingOutputStream extends OutputStream {
+    // the counting accumulator 
+    int count = 0; 
+
+    // in order for this to work, we only need override the single character
+    // form, as the others
+    // funnel through this one by default.
+    public void write(int ch) throws IOException {
+        // just increment the count 
+        count++; 
+    }
+    
+    
+    /**
+     * Get the current accumulator total for this stream. 
+     * 
+     * @return The current count. 
+     */
+    public int getCount() {
+        return count; 
+    }
+    
+    
+    /**
+     * Reset the counter to zero. 
+     */
+    public void reset() {
+        count = 0; 
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java
new file mode 100644
index 0000000..4273cbb
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java
@@ -0,0 +1,35 @@
+/**
+ * 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 org.apache.geronimo.javamail.util;
+
+import javax.mail.MessagingException; 
+
+public class InvalidCommandException extends MessagingException {
+    public InvalidCommandException() {
+        super();
+    }
+
+    public InvalidCommandException(String message) {
+        super(message);
+    }
+
+    public InvalidCommandException(String message, Exception cause) {
+        super(message, cause);
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java
new file mode 100644
index 0000000..70c3727
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java
@@ -0,0 +1,140 @@
+/*
+ * 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 org.apache.geronimo.javamail.util;
+
+import java.io.IOException;
+import java.io.Reader; 
+
+/**
+ * An implementation of an OutputStream that performs MIME linebreak
+ * canonicalization and "byte-stuff" so that data content does not get mistaken
+ * for a message data-end marker (CRLF.CRLF)l
+ * 
+ * @version $Rev: 597135 $ $Date: 2007-11-21 11:26:57 -0500 (Wed, 21 Nov 2007) $
+ */
+public class MIMEInputReader extends Reader {
+
+    // the wrappered output stream.
+    protected Reader source;
+
+    // a flag to indicate we've just processed a line break. This is used for
+    // byte stuffing purposes. This
+    // is initially true, because if the first character of the content is a
+    // period, we need to byte-stuff
+    // immediately.
+    protected boolean atLineBreak = true;
+    // we've hit the terminating marker on the data
+    protected boolean endOfData = false; 
+    
+
+    /**
+     * Create an input reader that reads from the source input reader  
+     * 
+     * @param out
+     *            The wrapped Reader        
+     */
+    public MIMEInputReader(Reader source) {
+        this.source = source; 
+    }
+    
+    /**
+     * Concrete implementation of the Reader read() 
+     * abstract method.  This appears to be the only 
+     * abstract method, so all of the other reads must 
+     * funnel through this method. 
+     * 
+     * @param buffer The buffer to fill.
+     * @param off    The offset to start adding characters.
+     * @param len    The number of requested characters.
+     * 
+     * @return The actual count of characters read.  Returns -1 
+     *         if we hit an EOF without reading any characters.
+     * @exception IOException
+     */
+    public int read(char buffer[], int off, int len) throws IOException {
+        // we've been asked for nothing, we'll return nothing. 
+        if (len == 0) {
+            return 0; 
+        }
+        
+        // have we hit the end of data?  Return a -1 indicator
+        if (endOfData) {
+            return -1; 
+        }
+        
+        // number of bytes read 
+        int bytesRead = 0; 
+        
+        int lastRead; 
+        
+        while (bytesRead < len && (lastRead = source.read()) >= 0) {
+            // We are checking for the end of a multiline response
+            // the format is .CRLF
+            
+            // we also have to check for byte-stuffing situation 
+            // where we remove a leading period.  
+            if (atLineBreak && lastRead == '.') {
+                // step to the next character 
+                lastRead = source.read();
+                // we have ".CR"...this is our end of stream 
+                // marker.  Consume the LF from the reader and return 
+                if (lastRead == '\r') {
+                    source.read(); 
+                    // no more reads from this point. 
+                    endOfData = true; 
+                    break; 
+                }
+                // the next character SHOULD be a ".".  We swallow the first 
+                // dot and just write the next character to the buffer 
+                atLineBreak = false; 
+            }
+            else if (lastRead == '\n') {
+                // hit an end-of-line marker?
+                // remember we just had a line break 
+                atLineBreak = true; 
+            }
+            else 
+            {
+                // something other than a line break character 
+                atLineBreak = false; 
+            }
+            // add the character to the buffer 
+            buffer[off++] = (char)lastRead; 
+            bytesRead++; 
+        }
+        
+        // we must have had an EOF condition of some sort 
+        if (bytesRead == 0) {
+            return -1; 
+        }
+        // return the actual length read in 
+        return bytesRead; 
+    }
+    
+     /**
+      * Close the stream.  This is a NOP for this stream.  
+      * 
+      * @exception IOException
+      */
+     public void close() throws IOException {
+         // does nothing 
+     }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java
new file mode 100644
index 0000000..ac7b2bc
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java
@@ -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 org.apache.geronimo.javamail.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An implementation of an OutputStream that performs MIME linebreak
+ * canonicalization and "byte-stuff" so that data content does not get mistaken
+ * for a message data-end marker (CRLF.CRLF)l
+ * 
+ * @version $Rev: 670717 $ $Date: 2008-06-23 15:41:19 -0400 (Mon, 23 Jun 2008) $
+ */
+public class MIMEOutputStream extends OutputStream {
+
+    // the wrappered output stream.
+    protected OutputStream out;
+
+    // last character we handled...used to recongnize line breaks.
+    protected int lastWrite = -1;
+
+    // a flag to indicate we've just processed a line break. This is used for
+    // byte stuffing purposes. This
+    // is initially true, because if the first character of the content is a
+    // period, we need to byte-stuff
+    // immediately.
+    protected boolean atLineBreak = true;
+
+    /**
+     * Create an output stream that writes to the target output stream.
+     * 
+     * @param out
+     *            The wrapped output stream.
+     */
+    public MIMEOutputStream(OutputStream out) {
+        this.out = out;
+    }
+
+    // in order for this to work, we only need override the single character
+    // form, as the others
+    // funnel through this one by default.
+    public void write(int ch) throws IOException {
+        // if this is a CR character, always write out a full sequence, and
+        // remember that we just did this.
+        if (ch == '\r') {
+            out.write((byte) '\r');
+            out.write((byte) '\n');
+            // we've just taken a break;
+            atLineBreak = true;
+        }
+        // if this is a new line, then we need to determine if this is a loner
+        // or part of a CRLF sequence.
+        else if (ch == '\n') {
+            // is this a lone ranger?
+            if (lastWrite != '\r') {
+                // write the full CRLF sequence.
+                out.write((byte) '\r');
+                out.write((byte) '\n');
+            }
+            // regardless of whether we wrote something or not, we're still at a
+            // line break.
+            atLineBreak = true;
+        }
+        // potential byte-stuffing situation?
+        else if (ch == '.') {
+            // ok, this is a potential stuff situation. Did we just have a line
+            // break? Double up the character.
+            if (atLineBreak) {
+                out.write('.');
+            }
+            out.write('.');
+            atLineBreak = false;
+        } else {
+            // just write this out and flip the linebreak flag.
+            out.write(ch);
+            atLineBreak = false;
+        }
+        // remember this last one for CRLF tracking purposes.
+        lastWrite = ch;
+    }
+    
+    
+    /**
+     * Force the stream to be terminated at a line break. 
+     * This is generally in preparation for the transport to 
+     * write out an end-of-data marker, which generally 
+     * needs to be preceded by a CRLF sequence. 
+     * 
+     * @exception IOException
+     */
+    public void forceTerminatingLineBreak() throws IOException {
+        if (!atLineBreak) {
+            out.write((byte) '\r');
+            out.write((byte) '\n');
+            // we've just taken a break;
+            atLineBreak = true;
+        }
+    }
+    
+    
+    /**
+     * Write out the SMTP terminator to the output stream. 
+     * This ensures that we don't write out an extra 
+     * CRLF if the data terminates with that value.  
+     * 
+     * @exception IOException
+     */
+    public void writeSMTPTerminator() throws IOException {
+        forceTerminatingLineBreak(); 
+        out.write('.'); 
+        out.write('\r'); 
+        out.write('\n'); 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java
new file mode 100644
index 0000000..af079ae
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java
@@ -0,0 +1,960 @@
+/**
+ * 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 org.apache.geronimo.javamail.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
+import org.apache.geronimo.javamail.authentication.CramMD5Authenticator;
+import org.apache.geronimo.javamail.authentication.DigestMD5Authenticator;
+import org.apache.geronimo.javamail.authentication.LoginAuthenticator;
+import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
+import org.apache.geronimo.javamail.authentication.SASLAuthenticator;
+
+/**
+ * Base class for all mail Store/Transport connection.  Centralizes management
+ * of a lot of common connection handling.  Actual protcol-specific 
+ * functions are handled at the subclass level. 
+ */
+public class MailConnection {
+    /**
+     * constants for EOL termination
+     */
+    protected static final char CR = '\r';
+    protected static final char LF = '\n';
+
+    /**
+     * property keys for protocol properties.
+     */
+    protected static final String MAIL_PORT = "port";
+    protected static final String MAIL_LOCALHOST = "localhost";
+    protected static final String MAIL_STARTTLS_ENABLE = "starttls.enable";
+    protected static final String MAIL_STARTTLS_REQUIRED = "starttls.required";
+    protected static final String MAIL_SSL_ENABLE = "ssl.enable";
+    protected static final String MAIL_TIMEOUT = "timeout";
+    protected static final String MAIL_SASL_ENABLE = "sasl.enable";
+    protected static final String MAIL_SASL_REALM = "sasl.realm";
+    protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid"; 
+    protected static final String MAIL_SASL_MECHANISMS = "sasl.mechanisms";
+    protected static final String MAIL_PLAIN_DISABLE = "auth.plain.disable";
+    protected static final String MAIL_LOGIN_DISABLE = "auth.login.disable";
+    
+    protected static final String MAIL_FACTORY = "socketFactory"; //GERONIMO-5429
+    protected static final String MAIL_FACTORY_CLASS = "socketFactory.class";
+    protected static final String MAIL_FACTORY_FALLBACK = "socketFactory.fallback";
+    protected static final String MAIL_FACTORY_PORT = "socketFactory.port";
+
+    protected static final String MAIL_SSL_FACTORY = "ssl.socketFactory"; //GERONIMO-5429
+    protected static final String MAIL_SSL_FACTORY_CLASS = "ssl.socketFactory.class";
+    protected static final String MAIL_SSL_FACTORY_PORT = "ssl.socketFactory.port";
+    protected static final String MAIL_SSL_PROTOCOLS = "ssl.protocols";
+    protected static final String MAIL_SSL_CIPHERSUITES = "ssl.ciphersuites";
+    protected static final String MAIL_SSL_TRUST = "ssl.trust";
+
+    protected static final String MAIL_LOCALADDRESS = "localaddress";
+    protected static final String MAIL_LOCALPORT = "localport";
+    protected static final String MAIL_ENCODE_TRACE = "encodetrace";
+
+    protected static final int MIN_MILLIS = 1000 * 60;
+    protected static final int TIMEOUT = MIN_MILLIS * 5;
+    protected static final String DEFAULT_MAIL_HOST = "localhost";
+
+    protected static final String CAPABILITY_STARTTLS = "STARTTLS";
+
+    protected static final String AUTHENTICATION_PLAIN = "PLAIN";
+    protected static final String AUTHENTICATION_LOGIN = "LOGIN";
+    protected static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
+    protected static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
+    
+    // The mail Session we're associated with
+    protected Session session; 
+    // The protocol we're implementing 
+    protected String protocol; 
+    // There are usually SSL and non-SSL versions of these protocols.  This 
+    // indicates which version we're using.
+    protected boolean sslConnection; 
+    // This is the default port we should be using for making a connection.  Each 
+    // protocol (and each ssl version of the protocol) normally has a different default that 
+    // should be used. 
+    protected int defaultPort; 
+    
+    // a wrapper around our session to provide easier lookup of protocol 
+    // specific property values 
+    protected ProtocolProperties props; 
+    
+    // The target server host 
+    protected String serverHost;
+    // The target server port 
+    protected int serverPort; 
+    
+    // the connection socket...can be a plain socket or SSLSocket, if TLS is being used.
+    protected Socket socket;
+    
+    // our local host name
+    protected InetAddress localAddress;
+    // our local port value 
+    protected int localPort; 
+    // our local host name
+    protected String localHost;
+    
+    // our timeout value 
+    protected int timeout; 
+    
+    // our login username 
+    protected String username; 
+    // our login password 
+    protected String password; 
+    // our SASL security realm 
+    protected String realm; 
+    // our authorization id 
+    protected String authid; 
+    
+    // input stream used to read data.  If Sasl is in use, this might be other than the
+    // direct access to the socket input stream.
+    protected InputStream inputStream;
+    // the other end of the connection pipeline.
+    protected OutputStream outputStream;
+
+    // our session provided debug output stream.
+    protected PrintStream debugStream;
+    // our debug flag (passed from the hosting transport)
+    protected boolean debug;
+
+    // list of authentication mechanisms supported by the server
+    protected List authentications;
+    // map of server extension arguments
+    protected Map capabilities;        
+    // property list of authentication mechanisms
+    protected List mechanisms; 
+    
+    protected MailConnection(ProtocolProperties props) 
+    {
+        // this is our properties retriever utility, which will look up 
+        // properties based on the appropriate "mail.protocol." prefix. 
+        // this also holds other information we might need for access, such as 
+        // the protocol name and the Session; 
+        this.props = props; 
+        this.protocol = props.getProtocol(); 
+        this.session = props.getSession(); 
+        this.sslConnection = props.getSSLConnection(); 
+        this.defaultPort = props.getDefaultPort(); 
+        
+        // initialize our debug settings from the session 
+        debug = session.getDebug(); 
+        debugStream = session.getDebugOut();
+        
+        String mailSSLEnable = props.getProperty(MAIL_SSL_ENABLE);
+        if(mailSSLEnable != null) {
+            this.sslConnection = Boolean.valueOf(mailSSLEnable);
+        }
+    }
+    
+    
+    /**
+     * Connect to the server and do the initial handshaking.
+     * 
+     * @param host     The target host name.
+     * @param port     The target port
+     * @param username The connection username (can be null)
+     * @param password The authentication password (can be null).
+     * 
+     * @return true if we were able to obtain a connection and 
+     *         authenticate.
+     * @exception MessagingException
+     */
+    public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        // NOTE:  We don't check for the username/password being null at this point.  It's possible that 
+        // the server will send back a PREAUTH response, which means we don't need to go through login 
+        // processing.  We'll need to check the capabilities response after we make the connection to decide 
+        // if logging in is necesssary. 
+        
+        // save this for subsequent connections.  All pool connections will use this info.
+        // if the port is defaulted, then see if we have something configured in the session.
+        // if not configured, we just use the default default.
+        if (port == -1) {
+            // check for a property and fall back on the default if it's not set.
+            port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
+            // it's possible that -1 might have been explicitly set, so one last check. 
+            if (port == -1) {
+                port = props.getDefaultPort(); 
+            }
+        }
+    	
+    	// Before we do anything, let's make sure that we successfully received a host
+    	if ( host == null ) {
+    		host = DEFAULT_MAIL_HOST;
+    	}
+        
+        this.serverHost = host;
+        this.serverPort = port;
+        this.username = username;
+        this.password = password;
+        
+        // make sure we have the realm information 
+        realm = props.getProperty(MAIL_SASL_REALM); 
+        // get an authzid value, if we have one.  The default is to use the username.
+        authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
+        return true; 
+    }
+    
+    
+    /**
+     * Establish a connection using an existing socket. 
+     * 
+     * @param s      The socket to use.
+     */
+    public void connect(Socket s) {
+        // just save the socket connection 
+        this.socket = s; 
+    }
+    
+    
+    /**
+     * Create a transport connection object and connect it to the
+     * target server.
+     *
+     * @exception MessagingException
+     */
+    protected void getConnection() throws IOException, MessagingException
+    {
+        // We might have been passed a socket to connect with...if not, we need to create one of the correct type.
+        if (socket == null) {
+            // get the connection properties that control how we set this up. 
+            getConnectionProperties(); 
+            // if this is the SSL version of the protocol, we start with an SSLSocket
+            if (sslConnection) {
+                getConnectedSSLSocket();
+            }
+            else
+            {
+                getConnectedSocket();
+            }
+        }
+        // if we already have a socket, get some information from it and override what we've been passed.
+        else {
+            localPort = socket.getPort();
+            localAddress = socket.getInetAddress();
+        }
+        
+        // now set up the input/output streams.
+        getConnectionStreams(); 
+    }
+
+    /**
+     * Get common connection properties before creating a connection socket. 
+     */
+    protected void getConnectionProperties() {
+
+        // there are several protocol properties that can be set to tune the created socket.  We need to
+        // retrieve those bits before creating the socket.
+        timeout = props.getIntProperty(MAIL_TIMEOUT, -1);
+        localAddress = null;
+        // see if we have a local address override.
+        String localAddrProp = props.getProperty(MAIL_LOCALADDRESS);
+        if (localAddrProp != null) {
+            try {
+                localAddress = InetAddress.getByName(localAddrProp);
+            } catch (UnknownHostException e) {
+                // not much we can do if this fails. 
+            }
+        }
+
+        // check for a local port...default is to allow socket to choose.
+        localPort = props.getIntProperty(MAIL_LOCALPORT, 0);
+    }
+    
+
+    /**
+     * Creates a connected socket
+     *
+     * @exception MessagingException
+     */
+    protected void getConnectedSocket() throws IOException {
+        debugOut("Attempting plain socket connection to server " + serverHost + ":" + serverPort);
+
+        // make sure this is null 
+        socket = null;
+        
+        createSocket(false);
+        
+        // if we have a timeout value, set that before returning 
+        if (timeout >= 0) {
+            socket.setSoTimeout(timeout);
+        }
+    }
+    
+    private boolean createSocketFromFactory(boolean ssl, boolean layer) throws IOException {
+        
+        String socketFactoryClass = props.getProperty(ssl?MAIL_SSL_FACTORY_CLASS:MAIL_FACTORY_CLASS);
+        
+        if(socketFactoryClass == null) {
+            return false;
+        }
+        
+        // we'll try this with potentially two different factories if we're allowed to fall back.
+        boolean fallback = props.getBooleanProperty(MAIL_FACTORY_FALLBACK, false);
+        int socketFactoryPort = props.getIntProperty(ssl?MAIL_SSL_FACTORY_PORT:MAIL_FACTORY_PORT, -1);
+        Integer portArg = new Integer(socketFactoryPort == -1 ? serverPort : socketFactoryPort);
+        
+        debugOut("Creating "+(ssl?"":"non-")+"SSL socket using factory " + socketFactoryClass+ " listening on port "+portArg);
+
+        while (true) {
+            try {
+                
+                // use the current context loader to resolve this.
+                ClassLoader loader = Thread.currentThread().getContextClassLoader();
+                Class factoryClass = loader.loadClass(socketFactoryClass);
+
+                // done indirectly, we need to invoke the method using reflection.
+                // This retrieves a factory instance.
+                //Method getDefault = factoryClass.getMethod("getDefault", new Class[0]); //TODO check instantiation of socket factory
+                Object defFactory = factoryClass.newInstance();// getDefault.invoke(new Object(), new Object[0]);
+                // now that we have the factory, there are two different createSocket() calls we use,
+                // depending on whether we have a localAddress override.
+
+                if (localAddress != null && !layer) {
+                    // retrieve the createSocket(String, int, InetAddress, int) method.
+                    Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
+                    Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+                    Object[] createSocketArgs = new Object[] { serverHost, portArg, localAddress, new Integer(localPort) };
+                    socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
+                    break; 
+                }
+                else {
+                    if(layer) {
+                     // retrieve the createSocket(String, int) method.
+                        Class[] createSocketSig = new Class[] { Socket.class, String.class, Integer.TYPE, Boolean.TYPE };
+                        Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+                        Object[] createSocketArgs = new Object[] { socket, serverHost, new Integer(serverPort), Boolean.TRUE };
+                        socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
+                        break; 
+                    } else {
+                     // retrieve the createSocket(String, int) method.
+                        Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
+                        Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+                        Object[] createSocketArgs = new Object[] { serverHost, portArg };
+                        socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
+                        break; 
+                    }
+                    
+                    
+                }
+            } catch (Throwable e) {
+                // if we're allowed to fallback, then use the default factory and try this again.  We only
+                // allow this to happen once.
+                if (fallback) {
+                    debugOut("First attempt at creating "+(ssl?"":"non-")+"SSL socket failed, falling back to default factory");
+                    socketFactoryClass = ssl?"javax.net.ssl.SSLSocketFactory":"javax.net.SocketFactory";
+                    fallback = false;
+                    continue;
+                }
+                // we have an exception.  We're going to throw an IOException, which may require unwrapping
+                // or rewrapping the exception.
+                else {
+                    // we have an exception from the reflection, so unwrap the base exception
+                    if (e instanceof InvocationTargetException) {
+                        e = ((InvocationTargetException)e).getTargetException();
+                    }
+
+                    debugOut("Failure creating "+(ssl?"":"non-")+"SSL socket", e);
+                    // throw this as an IOException, with the original exception attached.
+                    IOException ioe = new IOException("Error connecting to " + serverHost + ", " + serverPort);
+                    ioe.initCause(e);
+                    throw ioe;
+                }
+            }
+        }
+        
+        return true;
+    }
+    
+    private void createSocketFromFactory(SocketFactory sf, boolean layer) throws IOException {
+        
+        if(sf instanceof SSLSocketFactory && layer) {
+            socket = ((SSLSocketFactory) sf).createSocket(socket, serverHost, serverPort, true);
+            return;
+        }
+        
+        if (localAddress != null) {
+            socket = sf.createSocket(serverHost, serverPort, localAddress, localPort);
+        } else
+        {
+            socket = sf.createSocket(serverHost, serverPort);
+        }
+    }
+    
+    private boolean createSocketFromConfiguredFactoryInstance(boolean ssl, boolean layer) throws IOException {
+        
+        
+        
+        if (ssl) {
+            Object sfProp = props.getPropertyAsObject(MAIL_SSL_FACTORY);
+            if (sfProp != null && sfProp instanceof SSLSocketFactory) {
+                createSocketFromFactory((SSLSocketFactory) sfProp, layer);
+                debugOut("Creating "+(ssl?"":"non-")+"SSL "+(layer?"layered":"non-layered")+" socket using a instance of factory " + sfProp.getClass()+ " listening");
+                return true;
+            }
+        } else {
+            Object sfProp = props.getPropertyAsObject(MAIL_FACTORY);
+            if (sfProp != null && sfProp instanceof SocketFactory) {
+                createSocketFromFactory((SocketFactory) sfProp, layer);
+                debugOut("Creating "+(ssl?"":"non-")+"SSL "+(layer?"layered":"non-layered")+" socket using a instance of factory " + sfProp.getClass()+ " listening");
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    private void createSSLSocketFromSSLContext(boolean layer) throws IOException{
+        
+        debugOut("Creating "+(layer?"layered ":"non-layered ")+"SSL socket using SSL Context");
+
+        
+        try {
+            SSLContext sslcontext = SSLContext.getInstance("TLS");
+            
+            String sslTrust = props.getProperty(MAIL_SSL_TRUST);
+            
+            TrustManager trustManager = null;
+            
+            if(sslTrust != null) {
+                if(sslTrust.equals("*")) {
+                    trustManager = new SSLTrustManager(null, true); //trust all
+                } else
+                {
+                   String[] trustedHosts = sslTrust.split("\\s+");
+                   trustManager = new SSLTrustManager(trustedHosts, false); //trust some
+                   
+                   if(serverHost == null || serverHost.isEmpty() || !Arrays.asList(trustedHosts).contains(serverHost)) {
+                       throw new IOException("Server is not trusted: " + serverHost);
+                   }
+                   
+                }
+            } else {
+                trustManager = new SSLTrustManager(null, false); //default
+                
+            }
+             
+            sslcontext.init(null, new TrustManager[]{trustManager}, null);
+            
+            createSocketFromFactory(sslcontext.getSocketFactory(), layer);
+        } catch (KeyManagementException e) {
+            //cannot happen
+            throw new IOException(e);
+        } catch (NoSuchAlgorithmException e) {
+            //cannot happen
+            throw new IOException(e);
+        }
+    }
+    
+    private void createSocket(boolean ssl) throws IOException {
+        
+        if(createSocketFromConfiguredFactoryInstance(ssl, false)) {
+            return;
+        }
+
+        if(createSocketFromFactory(ssl, false)) {
+            return;
+        }
+        
+        if(!ssl) {
+            createSocketFromFactory(SocketFactory.getDefault(), false);
+            return;
+        }
+        
+          
+        createSSLSocketFromSSLContext(false);
+    }
+
+
+    /**
+     * Creates a connected SSL socket for an initial SSL connection.
+     *
+     * @exception MessagingException
+     */
+    protected void getConnectedSSLSocket() throws IOException {
+        debugOut("Attempting SSL socket connection to server " + serverHost + ":" + serverPort);
+        // the socket factory can be specified via a protocol property, a session property, and if all else
+        // fails (which it usually does), we fall back to the standard factory class.
+
+        // make sure this is null 
+        socket = null;
+        
+        createSocket(true);
+
+        // and set the timeout value 
+        if (timeout >= 0) {
+            socket.setSoTimeout(timeout);
+        }
+        
+        // if there is a list of protocols specified, we need to break this down into 
+        // the individual names 
+        String protocols = props.getProperty(MAIL_SSL_PROTOCOLS); 
+        if (protocols != null) {
+            ArrayList list = new ArrayList(); 
+            StringTokenizer t = new StringTokenizer(protocols); 
+            
+            while (t.hasMoreTokens()) {
+                list.add(t.nextToken()); 
+            }
+            
+            ((SSLSocket)socket).setEnabledProtocols((String[])list.toArray(new String[list.size()])); 
+        }
+        
+        // and do the same for any cipher suites 
+        String suites = props.getProperty(MAIL_SSL_CIPHERSUITES); 
+        if (suites != null) {
+            ArrayList list = new ArrayList(); 
+            StringTokenizer t = new StringTokenizer(suites); 
+            
+            while (t.hasMoreTokens()) {
+                list.add(t.nextToken()); 
+            }
+            
+            ((SSLSocket)socket).setEnabledCipherSuites((String[])list.toArray(new String[list.size()])); 
+        }
+    }
+
+
+    /**
+     * Switch the connection to using TLS level security,
+     * switching to an SSL socket.
+     */
+    protected void getConnectedTLSSocket() throws MessagingException {
+     	// it worked, now switch the socket into TLS mode
+     	try {
+
+            // we use the same target and port as the current connection.
+            serverHost = socket.getInetAddress().getHostName();
+            serverPort = socket.getPort();
+
+            // the socket factory can be specified via a session property.  By default, we use
+            // the native SSL factory.
+            if(createSocketFromConfiguredFactoryInstance(true, true)) {
+                debugOut("TLS socket factory configured as instance"); 
+            } else if(createSocketFromFactory(true, true)) {
+                debugOut("TLS socket factory configured as class"); 
+            } else {
+                debugOut("TLS socket factory from SSLContext"); 
+                createSSLSocketFromSSLContext(true);
+            }
+
+            // if this is an instance of SSLSocket (very common), try setting the protocol to be
+            // "TLSv1".  If this is some other class because of a factory override, we'll just have to
+            // accept that things will work.
+            if (socket instanceof SSLSocket) {
+                String[] suites = ((SSLSocket)socket).getSupportedCipherSuites();
+                ((SSLSocket)socket).setEnabledCipherSuites(suites);
+                ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1"} );
+                ((SSLSocket)socket).setUseClientMode(true);
+                debugOut("Initiating STARTTLS handshake");
+                ((SSLSocket)socket).startHandshake();
+            } else {
+                throw new IOException("Socket is not an instance of SSLSocket, maybe wrong configured ssl factory?");
+            }
+
+            getConnectionStreams(); 
+            debugOut("TLS connection established"); 
+     	}
+        catch (Exception e) {
+            debugOut("Failure attempting to convert connection to TLS", e);
+     	    throw new MessagingException("Unable to convert connection to SSL", e);
+     	}
+    }
+    
+    
+    /**
+     * Set up the input and output streams for server communications once the 
+     * socket connection has been made. 
+     * 
+     * @exception MessagingException
+     */
+    protected void getConnectionStreams() throws MessagingException, IOException {
+        // and finally, as a last step, replace our input streams with the secure ones.
+        // now set up the input/output streams.
+        inputStream = new TraceInputStream(socket.getInputStream(), debugStream, debug, props.getBooleanProperty(
+                MAIL_ENCODE_TRACE, false));
+        outputStream = new TraceOutputStream(socket.getOutputStream(), debugStream, debug, props.getBooleanProperty(
+                MAIL_ENCODE_TRACE, false));
+    }
+    
+
+    /**
+     * Close the server connection at termination.
+     */
+    public void closeServerConnection()
+    {
+        try {
+            socket.close();
+        } catch (IOException ignored) {
+        }
+
+        socket = null;
+        inputStream = null;
+        outputStream = null;
+    }
+    
+    
+    /**
+     * Verify that we have a good connection before 
+     * attempting to send a command. 
+     * 
+     * @exception MessagingException
+     */
+    protected void checkConnected() throws MessagingException {
+        if (socket == null || !socket.isConnected()) {
+            throw new MessagingException("no connection");
+        }
+    }
+
+
+    /**
+     * Retrieve the SASL realm used for DIGEST-MD5 authentication.
+     * This will either be explicitly set, or retrieved using the
+     * mail.imap.sasl.realm session property.
+     *
+     * @return The current realm information (which can be null).
+     */
+    public String getSASLRealm() {
+        // if the realm is null, retrieve it using the realm session property.
+        if (realm == null) {
+            realm = props.getProperty(MAIL_SASL_REALM);
+        }
+        return realm;
+    }
+
+
+    /**
+     * Explicitly set the SASL realm used for DIGEST-MD5 authenticaiton.
+     *
+     * @param name   The new realm name.
+     */
+    public void setSASLRealm(String name) {
+        realm = name;
+    }
+
+
+    /**
+     * Get a list of the SASL mechanisms we're configured to accept.
+     *
+     * @return A list of mechanisms we're allowed to use.
+     */
+    protected List getSaslMechanisms() {
+        if (mechanisms == null) {
+            mechanisms = new ArrayList();
+            String mechList = props.getProperty(MAIL_SASL_MECHANISMS);
+            if (mechList != null) {
+                // the mechanisms are a blank or comma-separated list
+                StringTokenizer tokenizer = new StringTokenizer(mechList, " ,");
+
+                while (tokenizer.hasMoreTokens()) {
+                    String mech = tokenizer.nextToken().toUpperCase();
+                    mechanisms.add(mech);
+                }
+            }
+        }
+        return mechanisms;
+    }
+    
+    
+    /**
+     * Get the list of authentication mechanisms the server
+     * is supposed to support. 
+     * 
+     * @return A list of the server supported authentication 
+     *         mechanisms.
+     */
+    protected List getServerMechanisms() {
+        return authentications; 
+    }
+    
+    
+    /**
+     * Merge the configured SASL mechanisms with the capabilities that the 
+     * server has indicated it supports, returning a merged list that can 
+     * be used for selecting a mechanism. 
+     * 
+     * @return A List representing the intersection of the configured list and the 
+     *         capabilities list.
+     */
+    protected List selectSaslMechanisms() {
+        List configured = getSaslMechanisms(); 
+        List supported = getServerMechanisms(); 
+        
+        // if not restricted, then we'll select from anything supported. 
+        if (configured.isEmpty()) {
+            return supported; 
+        }
+        
+        List merged = new ArrayList(); 
+        
+        // we might need a subset of the supported ones 
+        for (int i = 0; i < configured.size(); i++) {
+            // if this is in both lists, add to the merged one. 
+            String mech = (String)configured.get(i); 
+            if (supported.contains(mech)) {
+                merged.add(mech); 
+            }
+        }
+        return merged; 
+    }
+
+
+    /**
+     * Process SASL-type authentication.
+     *
+     * @return An authenticator to process the login challenge/response handling.    
+     * @exception MessagingException
+     */
+    protected ClientAuthenticator getLoginAuthenticator() throws MessagingException {
+        
+        // get the list of mechanisms we're allowed to use. 
+        List mechs = selectSaslMechanisms(); 
+
+        try {
+            String[] mechArray = (String[])mechs.toArray(new String[0]); 
+            // create a SASLAuthenticator, if we can.  A failure likely indicates we're not 
+            // running on a Java 5 VM, and the Sasl API isn't available. 
+            return new SASLAuthenticator(mechArray, session.getProperties(), protocol, serverHost, getSASLRealm(), authid, username, password); 
+        } catch (Throwable e) {
+        }
+        
+
+        // now go through the progression of mechanisms we support, from the most secure to the
+        // least secure.
+
+        if (mechs.contains(AUTHENTICATION_DIGESTMD5)) {
+            return new DigestMD5Authenticator(serverHost, username, password, getSASLRealm());
+        }
+        else if (mechs.contains(AUTHENTICATION_CRAMMD5)) {
+            return new CramMD5Authenticator(username, password);
+        }
+        else if (mechs.contains(AUTHENTICATION_LOGIN)) {
+            return new LoginAuthenticator(username, password);
+        }
+        else if (mechs.contains(AUTHENTICATION_PLAIN)) {
+            return new PlainAuthenticator(authid, username, password);
+        }
+        else {
+            // can't find a mechanism we support in common
+            return null;  
+        }
+    }
+    
+    
+    /**
+     * Internal debug output routine.
+     *
+     * @param value  The string value to output.
+     */
+    protected void debugOut(String message) {
+        if (debug) {
+            debugStream.println(protocol + " DEBUG: " + message);
+        }
+    }
+
+    /**
+     * Internal debugging routine for reporting exceptions.
+     *
+     * @param message A message associated with the exception context.
+     * @param e       The received exception.
+     */
+    protected void debugOut(String message, Throwable e) {
+        if (debug) {
+            debugOut("Received exception -> " + message);
+            debugOut("Exception message -> " + e.getMessage());
+            e.printStackTrace(debugStream);
+        }
+    }
+    
+    
+    /**
+     * Test if this connection has a given capability. 
+     * 
+     * @param capability The capability name.
+     * 
+     * @return true if this capability is in the list, false for a mismatch. 
+     */
+    public boolean hasCapability(String capability) {
+        return capabilities.containsKey(capability); 
+    }
+    
+    /**
+     * Get the capabilities map. 
+     * 
+     * @return The capabilities map for the connection. 
+     */
+    public Map getCapabilities() {
+        return capabilities; 
+    }
+    
+    
+    /**
+     * Test if the server supports a given mechanism. 
+     * 
+     * @param mech   The mechanism name.
+     * 
+     * @return true if the server has asserted support for the named 
+     *         mechanism.
+     */
+    public boolean supportsMechanism(String mech) {
+        return authentications.contains(mech); 
+    }
+    
+    
+    /**
+     * Retrieve the connection host. 
+     * 
+     * @return The host name. 
+     */
+    public String getHost() {
+        return serverHost; 
+    }
+    
+
+    /**
+     * Retrieve the local client host name.
+     *
+     * @return The string version of the local host name.
+     * @exception SMTPTransportException
+     */
+    public String getLocalHost() throws MessagingException {
+        if (localHost == null) {
+
+            if (localHost == null) {
+                localHost = props.getProperty(MAIL_LOCALHOST);
+            }
+
+            if (localHost == null) {
+                localHost = props.getSessionProperty(MAIL_LOCALHOST);
+            }
+
+            if (localHost == null) {
+        	try {
+            	    localHost = InetAddress.getLocalHost().getHostName();
+                } catch (UnknownHostException e) {
+	            // fine, we're misconfigured - ignore
+    	        }
+	    }
+
+            if (localHost == null) {
+                throw new MessagingException("Can't get local hostname. "
+                        + " Please correctly configure JDK/DNS or set mail.smtp.localhost");
+            }
+        }
+
+        return localHost;
+    }
+
+    
+    /**
+     * Explicitly set the local host information.
+     *
+     * @param localHost
+     *            The new localHost name.
+     */
+    public void setLocalHost(String localHost) {
+        this.localHost = localHost;
+    }
+    
+    private class SSLTrustManager implements X509TrustManager {
+        
+        private final X509TrustManager defaultTrustManager;
+        
+        private final boolean trustAll;
+        private final String[] trustedHosts;
+
+        SSLTrustManager(String[] trustedHosts, boolean trustAll) throws IOException{
+            super();
+            this.trustAll = trustAll;
+            this.trustedHosts = trustedHosts;
+            
+            try {
+                TrustManagerFactory defaultTrustManagerFactory = TrustManagerFactory.getInstance("X509");
+                defaultTrustManagerFactory.init((KeyStore)null);
+                defaultTrustManager = (X509TrustManager) defaultTrustManagerFactory.getTrustManagers()[0];
+            } catch (NoSuchAlgorithmException e) {
+                //cannot happen
+                throw new IOException(e);
+            } catch (KeyStoreException e) {
+                //cannot happen
+                throw new IOException(e);
+            }
+            
+        }
+
+        /* (non-Javadoc)
+         * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
+         */
+        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+            defaultTrustManager.checkClientTrusted(chain, authType);
+            
+        }
+
+        /* (non-Javadoc)
+         * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
+         */
+        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+            if (!trustAll || trustedHosts != null) {
+                defaultTrustManager.checkServerTrusted(chain, authType);
+            }
+            
+        }
+
+        /* (non-Javadoc)
+         * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+         */
+        public X509Certificate[] getAcceptedIssuers() {
+            return defaultTrustManager.getAcceptedIssuers();
+        }
+        
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java
new file mode 100644
index 0000000..7ef1a6d
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java
@@ -0,0 +1,291 @@
+/**
+ * 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 org.apache.geronimo.javamail.util;
+ 
+import java.util.Properties;
+
+import javax.mail.Session;
+
+/**
+ * Interface for providing access to protocol specific properties to 
+ * utility classes. 
+ */
+public class ProtocolProperties {
+    // the protocol we're working with. 
+    protected String protocol; 
+    // a preconstructed prefix string to reduce concatenation operations.  
+    protected String protocolPrefix; 
+    // the Session that's the source of all of the properties 
+    protected Session session; 
+    // the sslConnection property.  This indicates this protocol is to use SSL for 
+    // all communications with the server. 
+    protected boolean sslConnection;
+    // the default port property.  The default port differs with the protocol 
+    // and the sslConnection property. 
+    protected int defaultPort; 
+    
+    
+    public ProtocolProperties(Session session, String protocol, boolean sslConnection, int defaultPort) {
+        this.session = session; 
+        this.protocol = protocol; 
+        this.sslConnection = sslConnection; 
+        this.defaultPort = defaultPort; 
+        // this helps avoid a lot of concatenates when retrieving properties. 
+        protocolPrefix = "mail." + protocol + ".";
+    }
+    
+    
+    /**
+     * Retrieve the Session associated with this property bundle instance.
+     * 
+     * @return A Session object that's the source of the accessed properties. 
+     */
+    public Session getSession() {
+        return session; 
+    }
+    
+    
+    /**
+     * Retrieve the name of the protocol used to access properties.
+     * 
+     * @return The protocol String name. 
+     */
+    public String getProtocol() {
+        return protocol; 
+    }
+    
+    
+    /**
+     * Retrieve the SSL Connection flag for this protocol; 
+     * 
+     * @return true if an SSL connection is required, false otherwise. 
+     */
+    public boolean getSSLConnection() {
+        return sslConnection; 
+    }
+    
+    
+    /**
+     * Return the default port to use with this connection.
+     * 
+     * @return The default port value. 
+     */
+    public int getDefaultPort() {
+        return defaultPort; 
+    }
+    
+    
+    /**
+     * Get a property associated with this mail protocol.
+     *
+     * @param name   The name of the property.
+     *
+     * @return The property value (returns null if the property has not been set).
+     */
+    public String getProperty(String name) {
+        // the name we're given is the least qualified part of the name.  
+        // We construct the full property name
+        // using the protocol
+        String fullName = protocolPrefix + name;
+        return session.getProperty(fullName);
+    }
+    
+    /**
+     * Get a property (as object) associated with this mail protocol.
+     *
+     * @param name   The name of the property.
+     *
+     * @return The property value (returns null if the property has not been set).
+     */
+    public Object getPropertyAsObject(String name) {
+        // the name we're given is the least qualified part of the name.  
+        // We construct the full property name
+        // using the protocol
+        String fullName = protocolPrefix + name;
+        return session.getProperties().get(fullName);
+    }
+
+    /**
+     * Get a property associated with this mail session.  Returns
+     * the provided default if it doesn't exist.
+     *
+     * @param name   The name of the property.
+     * @param defaultValue
+     *               The default value to return if the property doesn't exist.
+     *
+     * @return The property value (returns defaultValue if the property has not been set).
+     */
+    public String getProperty(String name, String defaultValue) {
+        // the name we're given is the least qualified part of the name.  
+        // We construct the full property name
+        // using the protocol
+        String fullName = protocolPrefix + name;
+        String value = session.getProperty(fullName);
+        if (value == null) {
+            value = defaultValue; 
+        }
+        return value; 
+    }
+
+
+    /**
+     * Get a property associated with this mail session as an integer value.  Returns
+     * the default value if the property doesn't exist or it doesn't have a valid int value.
+     *
+     * @param name   The name of the property.
+     * @param defaultValue
+     *               The default value to return if the property doesn't exist.
+     *
+     * @return The property value converted to an int.
+     */
+    public int getIntProperty(String name, int defaultValue)
+    {
+        // retrieve the property 
+        String value = getProperty(name); 
+        // return the default value if not set. 
+        if (value == null) {
+            return defaultValue; 
+        }
+        return Integer.parseInt(value); 
+    }
+    
+
+    /**
+     * Get a property associated with this mail session as an boolean value.  Returns
+     * the default value if the property doesn't exist or it doesn't have a valid int value.
+     *
+     * @param name   The name of the property.
+     * @param defaultValue
+     *               The default value to return if the property doesn't exist.
+     *
+     * @return The property value converted to a boolean
+     */
+    public boolean getBooleanProperty(String name, boolean defaultValue)
+    {
+        // retrieve the property 
+        String value = getProperty(name); 
+        // return the default value if not set. 
+        if (value == null) {
+            return defaultValue; 
+        }
+        // just do a single test for true. 
+        if ("true".equals(value)) {
+            return true; 
+        }
+        // return false for anything other than true
+        return false; 
+    }
+    
+    
+    /**
+     * Get a property associated with this mail session.  Session 
+     * properties all begin with "mail."
+     *
+     * @param name   The name of the property.
+     *
+     * @return The property value (returns null if the property has not been set).
+     */
+    public String getSessionProperty(String name) {
+        // the name we're given is the least qualified part of the name.  
+        // We construct the full property name
+        // using the protocol
+        String fullName = "mail." + name;
+        return session.getProperty(fullName);
+    }
+
+    /**
+     * Get a property associated with this mail session.  Returns
+     * the provided default if it doesn't exist.
+     *
+     * @param name   The name of the property.
+     * @param defaultValue
+     *               The default value to return if the property doesn't exist.
+     *
+     * @return The property value (returns defaultValue if the property has not been set).
+     */
+    public String getSessionProperty(String name, String defaultValue) {
+        // the name we're given is the least qualified part of the name.  
+        // We construct the full property name
+        // using the protocol
+        String fullName = "mail." + name;
+        String value = session.getProperty(fullName);
+        if (value == null) {
+            value = defaultValue; 
+        }
+        return value; 
+    }
+
+
+    /**
+     * Get a property associated with this mail session as an integer value.  Returns
+     * the default value if the property doesn't exist or it doesn't have a valid int value.
+     *
+     * @param name   The name of the property.
+     * @param defaultValue
+     *               The default value to return if the property doesn't exist.
+     *
+     * @return The property value converted to an int.
+     */
+    public int getIntSessionProperty(String name, int defaultValue)
+    {
+        // retrieve the property 
+        String value = getSessionProperty(name); 
+        // return the default value if not set. 
+        if (value == null) {
+            return defaultValue; 
+        }
+        return Integer.parseInt(value); 
+    }
+    
+
+    /**
+     * Get a property associated with this mail session as an boolean value.  Returns
+     * the default value if the property doesn't exist or it doesn't have a valid int value.
+     *
+     * @param name   The name of the property.
+     * @param defaultValue
+     *               The default value to return if the property doesn't exist.
+     *
+     * @return The property value converted to a boolean
+     */
+    public boolean getBooleanSessionProperty(String name, boolean defaultValue)
+    {
+        // retrieve the property 
+        String value = getSessionProperty(name); 
+        // return the default value if not set. 
+        if (value == null) {
+            return defaultValue; 
+        }
+        // just do a single test for true. 
+        if ("true".equals(value)) {
+            return true; 
+        }
+        // return false for anything other than true
+        return false; 
+    }
+    
+    /**
+     * Get the complete set of properties associated with this Session.
+     * 
+     * @return The Session properties bundle. 
+     */
+    public Properties getProperties() {
+        return session.getProperties(); 
+    }
+    
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java
new file mode 100644
index 0000000..e533313
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java
@@ -0,0 +1,34 @@
+/**
+ * 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 org.apache.geronimo.javamail.util;
+
+import javax.mail.MessagingException; 
+
+public class ResponseFormatException extends MessagingException {
+    public ResponseFormatException() {
+        super();
+    }
+
+    public ResponseFormatException(String message) {
+        super(message);
+    }
+
+    public ResponseFormatException(String message, Exception cause) {
+        super(message, cause);
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java
new file mode 100644
index 0000000..05763b6
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java
@@ -0,0 +1,110 @@
+/*
+ * 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 org.apache.geronimo.javamail.util;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.geronimo.mail.james.mime4j.codec.QuotedPrintableOutputStream;
+
+/**
+ * @version $Rev: 1704974 $ $Date: 2015-09-23 22:13:31 -0400 (Wed, 23 Sep 2015) $
+ */
+public class TraceInputStream extends FilterInputStream {
+    // the current debug setting
+    protected boolean debug = false;
+
+    // the target trace output stream.
+    protected OutputStream traceStream;
+
+    /**
+     * Construct a debug trace stream.
+     * 
+     * @param in
+     *            The source input stream.
+     * @param traceStream
+     *            The side trace stream to which trace data gets written.
+     * @param encode
+     *            Indicates whether we wish the Trace data to be Q-P encoded.
+     */
+    public TraceInputStream(InputStream in, OutputStream traceStream, boolean debug, boolean encode) {
+        super(in);
+        this.debug = debug;
+        if (encode) {
+            this.traceStream = new QuotedPrintableOutputStream(traceStream, false);
+        } else {
+            this.traceStream = traceStream;
+        }
+    }
+
+    /**
+     * Set the current setting of the debug trace stream debug flag.
+     * 
+     * @param d
+     *            The new debug flag settings.
+     */
+    public void setDebug(boolean d) {
+        debug = d;
+    }
+
+    /**
+     * Reads up to len bytes of data from this input stream, placing them directly 
+     * into the provided byte array. 
+     * 
+     * @param b   the provided data buffer. 
+     * @param off the starting offset within the buffer for placing the data. 
+     * @param len the maximum number of bytes to read. 
+     * @return    that number of bytes that have been read and copied into the 
+     *            buffer or -1 if an end of stream occurs. 
+     * @exception IOException for any I/O errors. 
+     */
+    public int read(byte b[], int off, int len) throws IOException {
+        int count = in.read(b, off, len);
+        if (debug && count > 0) {
+            traceStream.write(b, off, count);
+        }
+        return count;
+    }
+
+    /**
+     * Read the next byte of data from the input stream, returning it as an 
+     * int value.  Returns -1 if the end of stream is detected. 
+     * 
+     * @return The next byte of data or -1 to indicate end-of-stream.      
+     * @exception IOException for any I/O errors
+     */
+    public int read() throws IOException {
+        int b = in.read();
+        if (debug) {
+            traceStream.write(b);
+        }
+        return b;
+    }
+
+    public int read(byte[] b) throws IOException {
+        final int read = in.read(b);
+        if (debug && read > 0) {
+            traceStream.write(b, 0, read);
+        }
+        return read;
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java
new file mode 100644
index 0000000..2f545fa
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java
@@ -0,0 +1,97 @@
+/*
+ * 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 org.apache.geronimo.javamail.util;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.geronimo.mail.james.mime4j.codec.QuotedPrintableOutputStream;
+
+/**
+ * @version $Rev: 1704974 $ $Date: 2015-09-23 22:13:31 -0400 (Wed, 23 Sep 2015) $
+ */
+public class TraceOutputStream extends FilterOutputStream {
+    // the current debug setting
+    protected boolean debug = false;
+
+    // the target trace output stream.
+    protected OutputStream traceStream;
+
+    /**
+     * Construct a debug trace stream.
+     *
+     * @param out
+     *            The target out put stream.
+     * @param traceStream
+     *            The side trace stream to which trace data gets written.
+     * @param encode
+     *            Indicates whether we wish the Trace data to be Q-P encoded.
+     */
+    public TraceOutputStream(OutputStream out, OutputStream traceStream, boolean debug, boolean encode) {
+        super(out);
+        this.debug = debug;
+        if (encode) {
+            this.traceStream = new QuotedPrintableOutputStream(traceStream, false);
+        } else {
+            this.traceStream = traceStream;
+        }
+    }
+
+    /**
+     * Set the current setting of the debug trace stream debug flag.
+     *
+     * @param d
+     *            The new debug flag settings.
+     */
+    public void setDebug(boolean d) {
+        debug = d;
+    }
+
+
+    /**
+     * Write a single byte to the output stream.
+     * 
+     * @param b      The byte to be written.
+     * 
+     * @exception IOException
+     *                   thrown for any I/O errors.
+     */
+    public void write(int b) throws IOException {
+        if (debug) {
+            traceStream.write(b);
+        }
+        super.write(b);
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {
+        if (this.debug) {
+            this.traceStream.write(b, off, len);
+        }
+        out.write(b, off, len);
+    }
+
+    public void write(byte[] b) throws IOException {
+        if (this.debug) {
+            this.traceStream.write(b);
+        }
+        out.write(b);
+    } 
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map
new file mode 100644
index 0000000..3bba278
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map
@@ -0,0 +1,34 @@
+##
+## 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: 437934 $ $Date: 2006-08-28 20:27:42 -0700 (Mon, 28 Aug 2006) $
+##
+
+#
+# This file configures the default behaviour of JavaMail. DO NOT EDIT.
+# Create a new file /META-INF/javamail.address.map and put
+# the same format lines in there.
+#
+# Note that you can't override these defaults, merely add to them.
+#
+# $Rev: 351866 $ $Date: 2005-12-02 20:12:14 -0500 (Fri, 02 Dec 2005) $
+#
+rfc822=smtp
+news=nntp
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers
new file mode 100644
index 0000000..e4db1a3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers
@@ -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.
+##
+
+##
+## $Rev: 437934 $ $Date: 2006-08-28 20:27:42 -0700 (Mon, 28 Aug 2006) $
+##
+
+#
+# This file configures the default behaviour of JavaMail. DO NOT EDIT.
+# Create a new file /META-INF/javamail.providers and put
+# the same format lines in there.
+#
+# Note that you can't override these defaults, merely add to them.
+#
+# $Rev: 398634 $ $Date: 2006-05-01 12:56:06 -0400 (Mon, 01 May 2006) $
+#
+protocol=smtp; type=transport; class=org.apache.geronimo.javamail.transport.smtp.SMTPTransport; vendor=Apache Software Foundation; version=1.0
+protocol=smtps; type=transport; class=org.apache.geronimo.javamail.transport.smtp.SMTPSTransport; vendor=Apache Software Foundation; version=1.0
+protocol=nntp-post; type=transport; class=org.apache.geronimo.javamail.transport.nntp.NNTPTransport; vendor=Apache Software Foundation; version=1.0
+protocol=nntp-posts; type=transport; class=org.apache.geronimo.javamail.transport.nntp.NNTPSSLTransport; vendor=Apache Software Foundation; version=1.0
+protocol=nntp; type=store; class=org.apache.geronimo.javamail.store.nntp.NNTPStore; vendor=Apache Software Foundation; version=1.0
+protocol=nntps; type=store; class=org.apache.geronimo.javamail.store.nntp.NNTPSSLStore; vendor=Apache Software Foundation; version=1.0
+protocol=pop3; type=store; class=org.apache.geronimo.javamail.store.pop3.POP3Store; vendor=Apache Software Foundation; version=1.0
+protocol=pop3s; type=store; class=org.apache.geronimo.javamail.store.pop3.POP3SSLStore; vendor=Apache Software Foundation; version=1.0
+protocol=imap; type=store; class=org.apache.geronimo.javamail.store.imap.IMAPStore; vendor=Apache Software Foundation; version=1.0
+protocol=imaps; type=store; class=org.apache.geronimo.javamail.store.imap.IMAPSSLStore; vendor=Apache Software Foundation; version=1.0
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap
new file mode 100644
index 0000000..2783191
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap
@@ -0,0 +1,31 @@
+##
+## 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$ $Date$
+##
+
+text/plain;;    x-java-content-handler=org.apache.geronimo.javamail.handlers.TextPlainHandler
+text/html;;     x-java-content-handler=org.apache.geronimo.javamail.handlers.TextHtmlHandler
+text/xml;;      x-java-content-handler=org.apache.geronimo.javamail.handlers.TextXmlHandler
+
+## These are not implemented in the reference implementation because the required support                  
+## is not available on server JVMs. 
+## image/gif;;     x-java-content-handler=org.apache.geronimo.javamail.handlers.ImageGifHandler
+## image/jpeg;;    x-java-content-handler=org.apache.geronimo.javamail.handlers.ImageJpegHandler
+## image/jpg;;    x-java-content-handler=org.apache.geronimo.javamail.handlers.ImageJpegHandler
+
+multipart/*;;   x-java-content-handler=org.apache.geronimo.javamail.handlers.MultipartHandler
+message/rfc822;; x-java-content-handler=org.apache.geronimo.javamail.handlers.RFC822MessageHandler
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler
new file mode 100644
index 0000000..c6e297b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.ImageGifHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler
new file mode 100644
index 0000000..c8148bb
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.ImageJpegHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler
new file mode 100644
index 0000000..39d2e16
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.MultipartHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler
new file mode 100644
index 0000000..a091915
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.RFC822MessageHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler
new file mode 100644
index 0000000..0da58ec
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.TextHtmlHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler
new file mode 100644
index 0000000..c3518a0
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.TextPlainHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler
new file mode 100644
index 0000000..04b32e3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.handlers.TextXmlHandler   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore
new file mode 100644
index 0000000..18127c3
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.store.imap.IMAPSSLStore   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore
new file mode 100644
index 0000000..6c35475
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.store.imap.IMAPStore   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore
new file mode 100644
index 0000000..c8df215
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.store.nntp.NNTPSSLStore   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore
new file mode 100644
index 0000000..83d3d3a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.store.nntp.NNTPStore   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore
new file mode 100644
index 0000000..ace45de
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.store.pop3.POP3SSLStore   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store
new file mode 100644
index 0000000..28dd416
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.store.pop3.POP3Store   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport
new file mode 100644
index 0000000..5af212f
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.transport.nntp.NNTPSSLTransport   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport
new file mode 100644
index 0000000..7db7ae2
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.transport.nntp.NNTPTransport   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport
new file mode 100644
index 0000000..cc5bbb5
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.transport.smtp.SMTPSTransport   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport
new file mode 100644
index 0000000..a16aa75
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport
@@ -0,0 +1 @@
+org.apache.geronimo.javamail.transport.smtp.SMTPTransport   # This is directly mapped back to the same class name
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml
new file mode 100644
index 0000000..251ed2b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $ -->
+
+<project name="${project.name}">
+    
+    <body>
+        
+        ${parentProject}
+        
+        ${modules}
+        
+        ${reports}
+        
+    </body>
+
+</project>
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java
new file mode 100644
index 0000000..36c7cbb
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java
@@ -0,0 +1,63 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import javax.activation.DataContentHandler;
+import javax.activation.DataSource;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
+ */
+public abstract class AbstractHandler extends TestCase {
+    protected DataContentHandler dch;
+    protected String mimeType;
+
+    public void testGetContent() throws Exception {
+        final byte[] bytes = "Hello World".getBytes();
+        DataSource ds = new DataSource() {
+            public InputStream getInputStream() {
+                return new ByteArrayInputStream(bytes);
+            }
+
+            public OutputStream getOutputStream() {
+                throw new UnsupportedOperationException();
+            }
+
+            public String getContentType() {
+                return mimeType; 
+            }
+
+            public String getName() {
+                throw new UnsupportedOperationException();
+            }
+        };
+        Object o = dch.getContent(ds);
+        assertEquals("Hello World", o);
+    }
+
+    public void testWriteTo() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        dch.writeTo("Hello World", mimeType, baos);
+        assertEquals("Hello World", baos.toString());
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java
new file mode 100644
index 0000000..79da869
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java
@@ -0,0 +1,40 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.datatransfer.DataFlavor;
+
+/**
+ * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
+ */
+public class TextHtmlTest extends AbstractHandler {
+    public void testDataFlavor() {
+        DataFlavor[] flavours = dch.getTransferDataFlavors();
+        assertEquals(1, flavours.length);
+        DataFlavor flavor = flavours[0];
+        assertEquals(String.class, flavor.getRepresentationClass());
+        assertEquals("text/html", flavor.getMimeType());
+        assertEquals("HTML Text", flavor.getHumanPresentableName());
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        dch = new TextHtmlHandler();
+        mimeType = "text/html"; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java
new file mode 100644
index 0000000..95dead8
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java
@@ -0,0 +1,40 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.datatransfer.DataFlavor;
+
+/**
+ * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
+ */
+public class TextPlainTest extends AbstractHandler {
+    public void testDataFlavor() {
+        DataFlavor[] flavours = dch.getTransferDataFlavors();
+        assertEquals(1, flavours.length);
+        DataFlavor flavor = flavours[0];
+        assertEquals(String.class, flavor.getRepresentationClass());
+        assertEquals("text/plain", flavor.getMimeType());
+        assertEquals("Plain Text", flavor.getHumanPresentableName());
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        dch = new TextPlainHandler();
+        mimeType = "text/plain"; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java
new file mode 100644
index 0000000..9122ec8
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java
@@ -0,0 +1,40 @@
+/**
+ *  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 org.apache.geronimo.javamail.handlers;
+
+import java.awt.datatransfer.DataFlavor;
+
+/**
+ * @version $Rev: 669902 $ $Date: 2008-06-20 10:04:41 -0400 (Fri, 20 Jun 2008) $
+ */
+public class TextXmlTest extends AbstractHandler {
+    public void testDataFlavor() {
+        DataFlavor[] flavours = dch.getTransferDataFlavors();
+        assertEquals(1, flavours.length);
+        DataFlavor flavor = flavours[0];
+        assertEquals(String.class, flavor.getRepresentationClass());
+        assertEquals("text/xml", flavor.getMimeType());
+        assertEquals("XML Text", flavor.getHumanPresentableName());
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        dch = new TextXmlHandler();
+        mimeType = "text/xml"; 
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java
new file mode 100755
index 0000000..e999475
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java
@@ -0,0 +1,139 @@
+/**
+ *  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 org.apache.geronimo.javamail.issues;
+
+import java.io.File;
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+import javax.mail.BodyPart;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import junit.framework.Assert;
+
+import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
+
+public class GERONIMO6480Test extends AbstractProtocolTest {
+
+    public void testGERONIMO6480_0() throws Exception {
+        BodyPart attachmentPart = new MimeBodyPart();
+        attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
+        attachmentPart.setFileName("test.pdf");
+        String contentType = getSendedAttachmentContentType(attachmentPart);
+        Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
+        // "text/plain; name=test.pdf" with Geronimo because setFileName force it to 'text/plain' when adding the 'name=' part instead of keeping it null
+    }
+
+    public void testGERONIMO6480_1() throws Exception {
+        BodyPart attachmentPart = new MimeBodyPart();
+        attachmentPart.addHeader("Content-Type", "aplication/pdf");
+        // setDataHandler reset "Content-Type" so equivalent to previous test
+        attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
+        attachmentPart.setFileName("test.pdf");
+        String contentType = getSendedAttachmentContentType(attachmentPart);
+        Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
+        // "text/plain; name=test.pdf" with Geronimo because setFileName force it to 'text/plain' when adding the 'name=' part instead of keeping it null
+    }
+
+    public void testGERONIMO6480_2() throws Exception {
+        BodyPart attachmentPart = new MimeBodyPart();
+        attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
+        attachmentPart.addHeader("Content-Type", "aplication/pdf");
+        attachmentPart.setFileName("test.pdf");
+        String contentType = getSendedAttachmentContentType(attachmentPart);
+        Assert.assertEquals("aplication/pdf; name=test.pdf".toLowerCase(), contentType.toLowerCase());
+    }
+
+    public void testGERONIMO6480_3() throws Exception {
+        System.setProperty("mail.mime.setcontenttypefilename", Boolean.FALSE.toString());
+        try {
+            BodyPart attachmentPart = new MimeBodyPart();
+            attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
+            attachmentPart.setFileName("test.pdf");
+            String contentType = getSendedAttachmentContentType(attachmentPart);
+            Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
+        } finally {
+            System.setProperty("mail.mime.setcontenttypefilename", Boolean.TRUE.toString());
+        }
+    }
+
+    public void testGERONIMO6480_4() throws Exception {
+        BodyPart attachmentPart = new MimeBodyPart();
+        attachmentPart.setFileName("test.pdf");
+        attachmentPart.setDataHandler(new DataHandler(new FileDataSource(getAbsoluteFilePathFromClassPath("pdf-test.pdf"))));
+        String contentType = getSendedAttachmentContentType(attachmentPart);
+        Assert.assertEquals("application/octet-stream; name=test.pdf".toLowerCase(), contentType.toLowerCase());
+    }
+
+    private File getAbsoluteFilePathFromClassPath(String filename) throws Exception {
+        return new File(GERONIMO6480Test.class.getClassLoader().getResource(filename).toURI());
+    }
+
+    private String getSendedAttachmentContentType(BodyPart attachmentPart) throws Exception {
+
+        start();
+        Properties props = new Properties();
+        props.setProperty("mail.transport.protocol", "smtp");
+        props.setProperty("mail.store.protocol", "imap");
+        props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
+        props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
+        //props.setProperty("mail.debug", "true");
+        Session session = Session.getInstance(props);
+
+        BodyPart messageBodyPart = new MimeBodyPart();
+        messageBodyPart.setText("See attachment.");
+
+        MimeMultipart multipart = new MimeMultipart();
+        multipart.addBodyPart(messageBodyPart);
+        multipart.addBodyPart(attachmentPart);
+
+        Message message = new MimeMessage(session);
+        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("test@mockserver.com"));
+        message.setSubject("Test attachment content-type");
+        message.setContent(multipart);
+
+        Transport.send(message);
+
+        return getAttachmentContentType(session);
+    }
+
+    private String getAttachmentContentType(Session session) throws Exception {
+        Store store = session.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+
+        Folder folder = store.getDefaultFolder();
+        folder = folder.getFolder("inbox");
+        folder.open(Folder.READ_ONLY);
+
+        server.ensureMsgCount(1);
+
+        Message message = folder.getMessage(1);
+        MimeMultipart multipart = (MimeMultipart) message.getContent();
+        BodyPart attachmentPart = multipart.getBodyPart(1);
+        return attachmentPart.getContentType();
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java
new file mode 100644
index 0000000..e10bf5a
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java
@@ -0,0 +1,149 @@
+/**
+ *  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 org.apache.geronimo.javamail.issues;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import junit.framework.Assert;
+
+import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
+import org.apache.geronimo.javamail.testserver.MailServer;
+
+public class IssuesTest extends AbstractProtocolTest {
+
+    public void testGERONIMO6519() throws Exception {
+
+        PrintStream original = System.out;
+
+        try {
+
+            start();
+            // Setup JavaMail session
+            Properties props = new Properties();
+            props.setProperty("mail.debug", "true");
+            props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
+            props.setProperty("mail.smtp.localhost", "some.full.qualified.name.com");
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            System.setOut(new PrintStream(baos, true));
+
+            Session session = Session.getInstance(props);
+            MimeMessage message = new MimeMessage(session);
+            message.setFrom(new InternetAddress("test@localhost"));
+            message.setRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress("test@localhost"));
+            message.setText("test");
+
+            Transport.send(message);
+            Assert.assertTrue(baos.toString().contains("EHLO some.full.qualified.name.com"));
+
+        } finally {
+            System.setOut(original);
+        }
+
+    }
+    
+    public void testGERONIMO4594() throws Exception {
+        Assert.assertTrue(doGERONIMO4594(true, true));
+    }
+    
+    public void testGERONIMO4594Fail0() throws Exception {
+        Assert.assertFalse(doGERONIMO4594(false, true));
+    }
+    
+    public void testGERONIMO4594Fail1() throws Exception {
+        Assert.assertFalse(doGERONIMO4594(false, false));
+    }
+    
+    public void testGERONIMO4594Fail2() throws Exception {
+        Assert.assertFalse(doGERONIMO4594(true, false));
+    }
+        
+    private boolean doGERONIMO4594(boolean decode, boolean encode) throws Exception {
+
+        final String specialFileName = "encoded_filename_\u00C4\u00DC\u00D6\u0226(test).pdf";
+        
+        System.setProperty("mail.mime.decodefilename", String.valueOf(decode));
+        System.setProperty("mail.mime.encodefilename", String.valueOf(encode));
+        try {
+
+            start();
+
+            // Setup JavaMail session
+            Properties props = new Properties();
+            props.setProperty("mail.transport.protocol", "smtp");
+            props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
+            props.setProperty("mail.store.protocol", "imap");
+            props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
+            //props.setProperty("mail.debug","true");
+            Session session = Session.getInstance(props);
+
+            MimeMessage msg = new MimeMessage(session);
+            msg.setSubject("a file for you");
+            msg.setRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress("serveruser@localhost"));
+            msg.setFrom(new InternetAddress("serveruser@localhost"));
+
+            MimeBodyPart messageBodyPart = new MimeBodyPart();
+            Multipart multipart = new MimeMultipart();
+            messageBodyPart.setText("This is message body");
+            File file = MailServer.getAbsoluteFilePathFromClassPath("pdf-test.pdf");
+            Assert.assertTrue(file.exists());
+            DataSource source = new FileDataSource(file.getAbsoluteFile());
+            messageBodyPart.setDataHandler(new DataHandler(source));
+            messageBodyPart.setFileName(specialFileName);
+            multipart.addBodyPart(messageBodyPart);
+            msg.setContent(multipart);
+            sendMessage(msg);
+            server.ensureMsgCount(1);
+
+            Session jmsession = Session.getInstance(props);
+            Store store = jmsession.getStore();
+            store.connect("127.0.0.1", "serveruser", "serverpass");
+            Folder f = store.getFolder("INBOX");
+            f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+            Assert.assertEquals(1, f.getMessageCount());
+            Message[] messages = new Message[2];
+            messages[0] = f.getMessage(1);
+            boolean match = specialFileName.equals(((Multipart) messages[0].getContent()).getBodyPart(0).getFileName());
+            f.close(false);
+            store.close();
+            return match;
+
+        } finally {
+            System.setProperty("mail.mime.decodefilename", "false");
+            System.setProperty("mail.mime.encodefilename", "false");
+        }
+
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java
new file mode 100644
index 0000000..ff09eb8
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java
@@ -0,0 +1,208 @@
+/**
+ *  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 org.apache.geronimo.javamail.store.imap;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Properties;
+
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.geronimo.mail.util.Base64;
+import org.apache.james.protocols.lib.PortUtil;
+
+public class AuthenticationTest extends TestCase {
+
+    public void testImplUsage() throws Exception {
+
+        //check that we load our mail impl
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "imap");
+        Session jmsession = Session.getInstance(props);
+        Assert.assertEquals(org.apache.geronimo.javamail.store.imap.IMAPStore.class, jmsession.getStore().getClass());
+        
+    }
+    
+    public void testAuthenticatePlain() throws Exception {
+
+        final int listenerPort = PortUtil.getNonPrivilegedPort();
+        //greenmail does not have AUTHENTICATE "PLAIN" support
+        FakeImapAuthPlainServer fs = new FakeImapAuthPlainServer(null, "user", "pass");
+        fs.startServer(listenerPort);
+        // Setup JavaMail session
+        Properties props = new Properties();
+        props.setProperty("mail.imap.port", String.valueOf(listenerPort));
+        props.setProperty("mail.debug", String.valueOf(true));
+        props.setProperty("mail.debug.auth", String.valueOf(true));
+
+        Session session = Session.getInstance(props);
+        Store store = session.getStore("imap");
+        store.connect("localhost", "user", "pass");
+        assertTrue(store.isConnected());
+        fs.join();
+        assertNull(fs.exception);
+    }
+
+    public void testAuthenticatePlainFail() throws Exception {
+
+        final int listenerPort = PortUtil.getNonPrivilegedPort();
+        //greenmail does not have AUTHENTICATE "PLAIN" support
+        FakeImapAuthPlainServer fs = new FakeImapAuthPlainServer(null, "user", "pass");
+        fs.startServer(listenerPort);
+        // Setup JavaMail session
+        Properties props = new Properties();
+        props.setProperty("mail.imap.port", String.valueOf(listenerPort));
+        props.setProperty("mail.debug", String.valueOf(true));
+        props.setProperty("mail.debug.auth", String.valueOf(true));
+        Session session = Session.getInstance(props);
+        Store store = session.getStore("imap");
+
+        try {
+
+            store.connect("localhost", "userXXX", "passXXX");
+            fail();
+        } catch (MessagingException e) {
+            //expected
+        }
+    }
+
+    public void testAuthenticatePlainAuthzid() throws Exception {
+
+        final int listenerPort = PortUtil.getNonPrivilegedPort();
+        //greenmail does not have AUTHENTICATE "PLAIN" support
+        FakeImapAuthPlainServer fs = new FakeImapAuthPlainServer("authzid", "user", "pass");
+        fs.startServer(listenerPort);
+        // Setup JavaMail session
+        Properties props = new Properties();
+        props.setProperty("mail.imap.port", String.valueOf(listenerPort));
+        props.setProperty("mail.debug", String.valueOf(true));
+        props.setProperty("mail.debug.auth", String.valueOf(true));
+        props.setProperty("mail.imap.sasl.authorizationid", "authzid");
+
+        Session session = Session.getInstance(props);
+        Store store = session.getStore("imap");
+        store.connect("localhost", "user", "pass");
+        assertTrue(store.isConnected());
+        fs.join();
+        assertNull(fs.exception);
+    }
+
+
+    private class FakeImapAuthPlainServer extends Thread{
+
+        private ServerSocket serverSocket;
+        private Socket socket;
+        private String authzid;
+        private String username;
+        private String password;
+        Exception exception;
+
+        private FakeImapAuthPlainServer(String authzid, String username, String password) {
+            this.password = password;
+            this.username = username;
+            this.authzid = authzid==null?"":authzid;
+        }
+
+        void startServer(int port) throws IOException {
+
+            serverSocket = new ServerSocket(port);
+            this.setDaemon(false);
+            this.start();
+
+        }
+
+
+        public void run() {
+            try {
+                socket = serverSocket.accept();
+                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+                PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
+                pw.write("* OK ready\r\n");
+                pw.flush();
+                String tag = br.readLine().split(" ")[0];
+                pw.write("* OK IMAP4rev1 Server ready\r\n");
+                pw.write("* CAPABILITY IMAP4rev1 AUTH=PLAIN\r\n");
+                pw.write(tag+" OK CAPABILITY completed.\r\n");
+                pw.flush();
+                tag = br.readLine().split(" ")[0];
+                pw.write("+ \r\n");
+                pw.flush();
+                String authline = new String(Base64.decode(br.readLine()));
+                System.out.println("authline : "+authline );
+
+                if(!"".equals(authzid) && !(authzid+"\0"+username+"\0"+password).equals(authline)) {
+                    pw.write(tag+" BAD username password invalid.\r\n");
+                    pw.flush();
+                    return;
+                }
+
+                if("".equals(authzid) && !(username+"\0"+username+"\0"+password).equals(authline) && !("\0"+username+"\0"+password).equals(authline)) {
+                    pw.write(tag+" BAD username password invalid.\r\n");
+                    pw.flush();
+                    return;
+                }
+
+                pw.write(tag + " OK Authenticated.\r\n");
+                pw.flush();
+
+                String fin = br.readLine();
+                tag = fin.split(" ")[0];
+
+                if(fin.contains("CAPA")) {
+                    pw.write("* CAPABILITY IMAP4rev1 AUTH=PLAIN\r\n");
+                    pw.write(tag+" OK CAPABILITY completed.\r\n");
+                    pw.flush();
+                    tag = br.readLine().split(" ")[0];
+                    pw.write(tag+" OK NOOP.\r\n");
+                }
+                else {
+                    pw.write(tag+" OK NOOP.\r\n");
+                }
+
+                pw.flush();
+
+            } catch (Exception e) {
+                exception = e;
+            }finally {
+
+                try {
+                    socket.close();
+                } catch (Exception e) {
+                    //ignore
+                }
+
+                try {
+                    serverSocket.close();
+                } catch (Exception e) {
+                    //ignore
+                }
+
+            }
+        }
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java
new file mode 100644
index 0000000..3dd7866
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java
@@ -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 org.apache.geronimo.javamail.store.imap;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Properties;
+
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
+
+
+public class IMAPStoreTest extends AbstractProtocolTest {
+    
+    public void testSimple() throws Exception {
+       
+        start();
+        sendTestMsgs();
+        
+        Properties props = new Properties();
+        props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        Session session = Session.getInstance(props);
+        
+        // Load the message from IMAP
+        Store store = session.getStore("imap");
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder folder = store.getFolder("INBOX");
+        folder.open(Folder.READ_ONLY);
+        Message[] messages = new Message[2];
+        messages[0] = folder.getMessage(1);
+        messages[1] = folder.getMessage(2);
+        checkMessages(messages);
+        folder.close(false);
+        store.close();
+    }
+    
+    
+    private void checkMessages(Message[] messages) throws Exception {
+        MimeMessage msg1 = (MimeMessage)messages[0];
+        Object content = msg1.getContent();
+        assertTrue(content instanceof MimeMultipart);
+        MimeMultipart multipart = (MimeMultipart)content;
+        assertEquals("First part", multipart.getBodyPart(0).getContent());
+        assertEquals("Second part", multipart.getBodyPart(1).getContent());        
+        checkMessage(msg1);
+        
+        MimeMessage msg2 = (MimeMessage)messages[1];
+        assertEquals("Foo Bar", msg2.getContent().toString().trim());
+        checkMessage(msg2);
+    }
+    
+    private void checkMessage(MimeMessage input) throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        input.writeTo(out);
+        
+        Properties props = new Properties();
+        Session s = Session.getInstance(props);
+        
+        byte [] inputData = out.toByteArray();
+        System.out.println(new String(inputData, 0, inputData.length));
+        
+        MimeMessage output = new MimeMessage(s, new ByteArrayInputStream(inputData));
+        
+        assertEquals(input.getContentType().toLowerCase(), output.getContentType().toLowerCase());        
+    }
+    
+ 
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
new file mode 100644
index 0000000..9ef05e7
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
@@ -0,0 +1,42 @@
+/**
+ *  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 org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+
+import javax.mail.internet.MimeMessage;
+
+import junit.framework.TestCase;
+import org.apache.geronimo.javamail.store.imap.IMAPStoreTest;
+
+public class IMAPBodyStructureTest extends TestCase {
+
+    public void testMultipart() throws Exception {
+        InputStream in = IMAPStoreTest.class.getResourceAsStream("/imap/multipart.bodystructure");
+        BufferedReader r = new BufferedReader(new InputStreamReader(in));
+        try {
+            IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(r.readLine().getBytes("ISO8859-1"));
+            IMAPBodyStructure s = new IMAPBodyStructure(tokenizer);
+            assertNull(s.disposition.getDisposition());
+            assertNull(s.md5Hash);
+        } finally {
+            in.close();
+        }
+    }
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java
new file mode 100644
index 0000000..a91133d
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java
@@ -0,0 +1,449 @@
+/**
+ *  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 org.apache.geronimo.javamail.store.pop3;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.mail.Address;
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Flags.Flag;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Transport;
+import javax.mail.UIDFolder;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import junit.framework.Assert;
+
+import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
+import org.apache.geronimo.javamail.testserver.MailServer.DummySocketFactory;
+
+public class POP3StoreTest extends AbstractProtocolTest {
+
+    
+    
+    
+    public void testSendRetrieve() throws Exception {
+        
+        start();
+        
+        // Setup JavaMail session
+        Properties props = new Properties();
+        props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
+        props.setProperty("mail.debug","true");
+        Session session = Session.getInstance(props);
+        // Send messages for the current test to James
+        sendMessage(session, "/messages/multipart.msg");
+        sendMessage(session, "/messages/simple.msg");
+        server.ensureMsgCount(2);
+        
+        props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        Message[] messages = new Message[2];
+        messages[0] = f.getMessage(1);
+        messages[1] = f.getMessage(2);
+        checkMessages(messages);
+        f.close(false);
+        store.close();
+    }
+    
+
+    
+    
+    private void checkMessages(Message[] messages) throws Exception {
+        MimeMessage msg1 = (MimeMessage)messages[0];
+        Object content = msg1.getContent();
+        assertTrue(content instanceof MimeMultipart);
+        MimeMultipart multipart = (MimeMultipart)content;
+        assertEquals("First part", multipart.getBodyPart(0).getContent());
+        assertEquals("Second part", multipart.getBodyPart(1).getContent());        
+        checkMessage(msg1);
+        
+        MimeMessage msg2 = (MimeMessage)messages[1];
+        assertEquals("Foo Bar", msg2.getContent().toString().trim());
+        checkMessage(msg2);
+    }
+    
+    private void checkMessage(MimeMessage input) throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        input.writeTo(out);
+        
+        Properties props = new Properties();
+        Session s = Session.getInstance(props);
+        
+        byte [] inputData = out.toByteArray();
+        System.out.println(new String(inputData, 0, inputData.length));
+        
+        MimeMessage output = new MimeMessage(s, new ByteArrayInputStream(inputData));
+        
+        assertEquals(input.getContentType().toLowerCase(), output.getContentType().toLowerCase());        
+    }
+    
+
+    public void testStartTLS() throws Exception {
+
+        pop3Conf.enableSSL(true, false);
+
+        start();
+
+        sendTestMsgs();
+        
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3.starttls.required", "true");
+        props.setProperty("mail.pop3.ssl.trust", "*");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        f.close(false);
+        store.close();
+
+    }
+
+    public void testAPOP() throws Exception {
+
+        pop3Conf.enableSSL(true, false);
+
+        start();
+        sendTestMsgs();
+        
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3.apop.enable", "true");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        f.close(false);
+        store.close();
+
+    }
+
+    public void testFetch() throws Exception {
+
+        
+        pop3Conf.enableSSL(true, false);
+
+        start();
+        sendTestMsgs();
+        
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        FetchProfile fp = new FetchProfile();
+        fp.add(UIDFolder.FetchProfileItem.UID);
+        fp.add(FetchProfile.Item.CONTENT_INFO);
+        
+        Message[] msgs = f.getMessages();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        Assert.assertEquals(2, msgs.length);
+        
+        f.fetch(msgs, fp);
+        Assert.assertEquals(2, f.getMessageCount());
+        
+        for (int i = 0; i < msgs.length; i++) {
+            Message message = msgs[i];
+            message.writeTo(bout);
+            String msg = bout.toString();
+            Assert.assertNotNull(msg);
+            int num = message.getMessageNumber();
+            Assert.assertTrue(num > 0);
+            String uid = ((POP3Folder) f).getUID(message);
+            Assert.assertNotNull(uid);
+            Assert.assertTrue(!uid.isEmpty());
+        }
+        
+        f.close(false);
+        store.close();
+
+    }
+    
+    
+    
+    public void testDelete() throws Exception {
+
+        
+        pop3Conf.enableSSL(true, false);
+
+        start();
+        sendTestMsgs();
+        
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_WRITE); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        Message[] msgs =  f.getMessages();
+        f.setFlags(msgs, new Flags(Flag.DELETED), true);
+        Assert.assertEquals(2, f.getMessageCount());
+        f.getMessage(1).getSubject(); //should fail
+        //Assert.assertEquals(2, f.expunge());
+        f.close(false);
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(0, f.getMessageCount());
+        store.close();
+
+    }
+    
+    
+    
+    public void testStartTLSFail() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, false);
+
+        start();
+        sendTestMsgs();
+        
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3.starttls.required", "true");
+        props.setProperty("mail.pop3.ssl.trust", "*");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        try {
+            store.connect("127.0.0.1", "serveruser", "serverpass");
+            fail();
+        } catch (MessagingException e) {
+            //Expected
+        }
+    }
+
+    public void testSSLEnable() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, true);
+
+        start();
+        sendTestMsgs();
+
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3.ssl.enable", "true");
+        props.setProperty("mail.pop3.ssl.trust", "*");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        f.close(false);
+        store.close();
+
+    }
+
+    public void testSSLPop3s() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, true);
+
+        start();
+        sendTestMsgs();
+
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3s");
+        props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3s.ssl.trust", "*");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        f.close(false);
+        store.close();
+
+    }
+    
+    public void testSSLPop3sFactoryClass() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, true);
+
+        start();
+        sendTestMsgs();
+
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3s");
+        props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3s.ssl.trust", "*");
+        props.setProperty("mail.pop3s.ssl.socketFactory.class", DummySocketFactory.class.getName());
+       
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        try {
+            store.connect("127.0.0.1", "serveruser", "serverpass");
+            fail();
+        } catch (MessagingException e) {
+            Assert.assertEquals("dummy socket factory", e.getCause().getCause().getMessage());
+            
+            //Expected
+        }
+
+        
+        
+    }
+
+    public void testSSLPop3sFactoryInstance() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, true);
+
+        start();
+        sendTestMsgs();
+
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3s");
+        props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3s.ssl.trust", "*");
+        props.put("mail.pop3s.ssl.socketFactory", new DummySocketFactory());
+       
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        try {
+            store.connect("127.0.0.1", "serveruser", "serverpass");
+            fail();
+        } catch (MessagingException e) {
+            Assert.assertEquals("dummy socket factory", e.getCause().getMessage());
+            
+            //Expected
+        }
+
+    }
+    
+    public void testSSLPop3sNotEnabled() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, false);
+
+        start();
+        sendTestMsgs();
+
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3s");
+        props.setProperty("mail.pop3s.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        props.setProperty("mail.pop3s.ssl.trust", "*");
+        props.setProperty("mail.pop3s.ssl.enable", "false");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        Assert.assertEquals(2, f.getMessageCount());
+        f.close(false);
+        store.close();
+
+    }
+    
+    public void testPop3GetMsgs() throws Exception {
+
+        
+        pop3Conf.enableSSL(false, false);
+
+        start();
+        sendTestMsgs();
+
+        Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        props.setProperty("mail.pop3.port", String.valueOf(pop3Conf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+
+        Session jmsession = Session.getInstance(props);
+        Store store = jmsession.getStore();
+        store.connect("127.0.0.1", "serveruser", "serverpass");
+        Folder f = store.getFolder("INBOX");
+        f.open(Folder.READ_ONLY); //TODO STAT only when folder open???
+        
+        
+        Message[] msgs =  f.getMessages();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        Assert.assertEquals(2, msgs.length);
+        
+        for (int i = 0; i < msgs.length; i++) {
+            Message message = msgs[i];
+            message.writeTo(bout);
+            String msg = bout.toString();
+            Assert.assertNotNull(msg);
+            int num = message.getMessageNumber();
+            Assert.assertTrue(num > 0);
+            String uid = ((POP3Folder) f).getUID(message);
+            Assert.assertNotNull(uid);
+            Assert.assertTrue(!uid.isEmpty());
+        }
+        
+        f.close(false);
+        store.close();
+
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java
new file mode 100644
index 0000000..8648869
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java
@@ -0,0 +1,115 @@
+/**
+ *  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 org.apache.geronimo.javamail.testserver;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.mail.Address;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.geronimo.javamail.store.pop3.POP3StoreTest;
+
+public abstract class AbstractProtocolTest extends TestCase {
+
+    protected MailServer server = new MailServer();
+    protected MailServer.Pop3TestConfiguration pop3Conf;
+    protected MailServer.SmtpTestConfiguration smtpConf;
+    protected MailServer.ImapTestConfiguration imapConf;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        pop3Conf = new MailServer.Pop3TestConfiguration();
+        smtpConf = new MailServer.SmtpTestConfiguration();
+        imapConf = new MailServer.ImapTestConfiguration();
+
+    }
+
+    protected void start() throws Exception {
+
+        server.start(smtpConf, pop3Conf, imapConf);
+
+    }
+
+    public void testImplUsageImap() throws Exception {
+
+        //check that we load our mail impl
+        final Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "imap");
+        final Session jmsession = Session.getInstance(props);
+        Assert.assertEquals(org.apache.geronimo.javamail.store.imap.IMAPStore.class, jmsession.getStore().getClass());
+
+    }
+
+    public void testImplUsagePop3() throws Exception {
+
+        //check that we load our mail impl
+        final Properties props = new Properties();
+        props.setProperty("mail.store.protocol", "pop3");
+        final Session jmsession = Session.getInstance(props);
+        Assert.assertEquals(org.apache.geronimo.javamail.store.pop3.POP3Store.class, jmsession.getStore().getClass());
+
+    }
+
+    public void testImplUsageSmtp() throws Exception {
+
+        //check that we load our mail impl
+        final Properties props = new Properties();
+        props.setProperty("mail.transport.protocol", "smtp");
+        final Session jmsession = Session.getInstance(props);
+        Assert.assertEquals(org.apache.geronimo.javamail.transport.smtp.SMTPTransport.class, jmsession.getTransport().getClass());
+
+    }
+
+    protected void sendTestMsgs() throws Exception {
+        final Properties props = new Properties();
+        props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+        final Session session = Session.getInstance(props);
+        sendMessage(session, "/messages/multipart.msg");
+        sendMessage(session, "/messages/simple.msg");
+        server.ensureMsgCount(2);
+    }
+
+    protected void sendMessage(final Session session, final String msgFile) throws Exception {
+        MimeMessage message;
+        final InputStream in = POP3StoreTest.class.getResourceAsStream(msgFile);
+        try {
+            message = new MimeMessage(session, in);
+        } finally {
+            in.close();
+        }
+        Transport.send(message, new Address[] { new InternetAddress("serveruser@localhost") });
+    }
+    
+    protected void sendMessage(final MimeMessage message) throws Exception {
+        Transport.send(message, new Address[] { new InternetAddress("serveruser@localhost") });
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        server.stop();
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java
new file mode 100644
index 0000000..4c0bead
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java
@@ -0,0 +1,119 @@
+/**
+ *  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 org.apache.geronimo.javamail.testserver;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.annotation.Resource;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.exception.BadCredentialsException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.pop3server.mailbox.MailboxAdapter;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.lib.POP3BeforeSMTPHelper;
+import org.apache.james.protocols.lib.Slf4jLoggerAdapter;
+import org.apache.james.protocols.pop3.POP3Response;
+import org.apache.james.protocols.pop3.POP3Session;
+import org.apache.james.protocols.pop3.core.AbstractApopCmdHandler;
+import org.apache.james.protocols.pop3.mailbox.Mailbox;
+
+public class ApopCmdHandler extends AbstractApopCmdHandler  {
+
+    private MailboxManager manager;
+
+
+    @Resource(name = "mailboxmanager")
+    public void setMailboxManager(MailboxManager manager) {
+        this.manager = manager;
+    }
+
+    @Override
+    public Response onCommand(POP3Session session, Request request) {
+        Response response =  super.onCommand(session, request);
+        if (POP3Response.OK_RESPONSE.equals(response.getRetCode())) {
+            POP3BeforeSMTPHelper.addIPAddress(session.getRemoteAddress().getAddress().getHostAddress());
+        }
+        return response;
+    }
+
+    @Override
+    protected Mailbox auth(POP3Session session, String apopTimestamp, String user, String digest) throws Exception {
+        MailboxSession mSession = null;
+        
+        String plaintextpassword = "serverpass";
+        
+        try {
+            final String toHash = apopTimestamp.trim()+plaintextpassword;
+            
+            if(!getMD5(toHash).equals(digest))
+            {
+                System.out.println("Digests does not match");
+                return null;
+            }
+            
+            
+            session.setUser(user);
+            
+            mSession = manager.createSystemSession(session.getUser(), new Slf4jLoggerAdapter(session.getLogger()));
+            manager.startProcessingRequest(mSession);
+            MailboxPath inbox = MailboxPath.inbox(mSession);
+            
+            // check if the mailbox exists, if not create it
+            if (!manager.mailboxExists(inbox, mSession)) {
+                manager.createMailbox(inbox, mSession);
+            }
+            MessageManager mailbox = manager.getMailbox(MailboxPath.inbox(mSession), mSession);
+            return new MailboxAdapter(manager, mailbox, mSession);
+        } catch (BadCredentialsException e) {
+            return null;
+        } catch (MailboxException e) {
+            throw new IOException("Unable to access mailbox for user " + session.getUser(), e);
+        } finally {
+            if (mSession != null) {
+                manager.endProcessingRequest(mSession);
+            }
+        }
+
+    }
+    
+    private static String getMD5(final String input) {
+        try {
+            final MessageDigest md = MessageDigest.getInstance("MD5");
+            final byte[] messageDigest = md.digest(input.getBytes());
+            final BigInteger number = new BigInteger(1, messageDigest);
+            String hashtext = number.toString(16);
+            // Now we need to zero pad it if you actually want the full 32 chars.
+            while (hashtext.length() < 32) {
+                hashtext = "0" + hashtext;
+            }
+            return hashtext;
+        }
+        catch (final NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java
new file mode 100644
index 0000000..b73d6f4
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java
@@ -0,0 +1,590 @@
+/**
+ *  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 org.apache.geronimo.javamail.testserver;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+import javax.mail.Flags;
+import javax.mail.internet.MimeMessage;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.commons.configuration.DefaultConfigurationBuilder;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.api.DomainListException;
+import org.apache.james.domainlist.api.mock.SimpleDomainList;
+import org.apache.james.filesystem.api.mock.MockFileSystem;
+import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
+import org.apache.james.imap.encode.main.DefaultLocalizer;
+import org.apache.james.imap.main.DefaultImapDecoderFactory;
+import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
+import org.apache.james.imapserver.netty.IMAPServer;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.acl.GroupMembershipResolver;
+import org.apache.james.mailbox.acl.MailboxACLResolver;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.Authenticator;
+import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailrepository.mock.MockMailRepositoryStore;
+import org.apache.james.pop3server.netty.POP3Server;
+import org.apache.james.protocols.lib.PortUtil;
+import org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader;
+import org.apache.james.queue.api.MailQueue;
+import org.apache.james.queue.api.MailQueue.MailQueueItem;
+import org.apache.james.queue.api.MailQueueFactory;
+import org.apache.james.queue.file.FileMailQueueFactory;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.smtpserver.netty.SMTPServer;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.user.lib.mock.MockUsersRepository;
+import org.apache.mailet.HostAddress;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+//James based POP3 or IMAP or SMTP server (for unittesting only)
+public class MailServer {
+
+    private POP3Server pop3Server;
+    private IMAPServer imapServer;
+    private SMTPServer smtpServer;
+    private AlterableDNSServer dnsServer;
+    private final MockUsersRepository usersRepository = new MockUsersRepository();
+    private final MockFileSystem fileSystem = new MockFileSystem();
+    private MockProtocolHandlerLoader protocolHandlerChain;
+    private StoreMailboxManager<Long> mailboxManager;
+
+    private MockMailRepositoryStore store;
+    private DNSService dnsService;
+    private MailQueueFactory queueFactory;
+    private MailQueue queue;
+    private final Semaphore sem = new Semaphore(0);
+    private final Logger log = LoggerFactory.getLogger("Mock");
+
+    public void ensureMsgCount(final int count) throws InterruptedException {
+        sem.acquire(count);
+    }
+
+    private class Fetcher extends Thread {
+
+        private final MailQueue queue;
+        private final MessageManager mailbox;
+        private final MailboxSession session;
+
+        Fetcher(final MailQueue queue, final MessageManager mailbox, final MailboxSession session) {
+            super();
+            this.queue = queue;
+            this.mailbox = mailbox;
+            this.session = session;
+        }
+
+        @Override
+        public void run() {
+            while (true) {
+                try {
+                    System.out.println("Await new mail ...");
+                    final MailQueueItem item = queue.deQueue();
+                    System.out.println("got it");
+                    final MimeMessage msg = item.getMail().getMessage();
+                    final ByteArrayOutputStream bout = new ByteArrayOutputStream();
+                    msg.writeTo(bout);
+                    mailbox.appendMessage(new ByteArrayInputStream(bout.toByteArray()), new Date(), session, true, new Flags());
+                    item.done(true);
+                    sem.release();
+                    System.out.println("mail copied over");
+                } catch (final Exception e) {
+                    e.printStackTrace();
+                    return;
+                }
+            }
+        }
+
+    }
+
+    public MailServer() {
+        super();
+        try {
+            usersRepository.addUser("serveruser", "serverpass");
+        } catch (final UsersRepositoryException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    public void start(final SmtpTestConfiguration smtpConfig, final Pop3TestConfiguration pop3Config, final ImapTestConfiguration imapConfig)
+            throws Exception {
+        setUpServiceManager();
+
+        imapServer = new IMAPServer();
+
+        imapServer.setImapEncoder(DefaultImapEncoderFactory.createDefaultEncoder(new DefaultLocalizer(), false));
+        imapServer.setImapDecoder(DefaultImapDecoderFactory.createDecoder());
+
+        pop3Server = new POP3Server();
+        pop3Server.setProtocolHandlerLoader(protocolHandlerChain);
+
+        smtpServer = new SMTPServer() {
+            @Override
+            protected java.lang.Class<? extends org.apache.james.protocols.lib.handler.HandlersPackage> getJMXHandlersPackage() {
+                return RefinedJMXHandlersLoader.class;
+            };
+
+        };
+        smtpServer.setProtocolHandlerLoader(protocolHandlerChain);
+        smtpServer.setDNSService(dnsServer);
+
+        imapServer.setFileSystem(fileSystem);
+        pop3Server.setFileSystem(fileSystem);
+        smtpServer.setFileSystem(fileSystem);
+
+        imapServer.setLog(log);
+        pop3Server.setLog(log);
+        smtpServer.setLog(log);
+
+        final MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, "serveruser", "INBOX");
+        final MailboxSession session = mailboxManager.login("serveruser", "serverpass", LoggerFactory.getLogger("Test"));
+
+        if (!mailboxManager.mailboxExists(mailboxPath, session)) {
+            mailboxManager.createMailbox(mailboxPath, session);
+        }
+
+        imapServer.setImapProcessor(DefaultImapProcessorFactory.createXListSupportingProcessor(mailboxManager, null, null));//new StoreSubscriptionManager(new InMemoryMailboxSessionMapperFactory()), null));
+
+        //setupTestMails(session, mailboxManager.getMailbox(mailboxPath, session));
+
+        new Fetcher(queue, mailboxManager.getMailbox(mailboxPath, session), session).start();
+
+        smtpConfig.init();
+        pop3Config.init();
+        imapConfig.init();
+
+        smtpServer.configure(smtpConfig);
+        pop3Server.configure(pop3Config);
+        imapServer.configure(imapConfig);
+
+        smtpServer.init();
+        pop3Server.init();
+        imapServer.init();
+
+    }
+
+    public void stop() throws Exception {
+
+        if (protocolHandlerChain != null) {
+            protocolHandlerChain.dispose();
+        }
+
+        if (imapServer != null) {
+            imapServer.destroy();
+        }
+
+        if (pop3Server != null) {
+            pop3Server.destroy();
+        }
+
+        if (smtpServer != null) {
+            smtpServer.destroy();
+        }
+
+    }
+
+    /* protected void setupTestMailsx(MailboxSession session, MessageManager mailbox) throws MailboxException {
+         mailbox.appendMessage(new ByteArrayInputStream(content), new Date(), session, true, new Flags());
+         byte[] content2 = ("EMPTY").getBytes();
+         mailbox.appendMessage(new ByteArrayInputStream(content2), new Date(), session, true, new Flags());
+     }*/
+
+    protected void setUpServiceManager() throws Exception {
+        protocolHandlerChain = new MockProtocolHandlerLoader();
+        protocolHandlerChain.put("usersrepository", usersRepository);
+
+        final InMemoryMailboxSessionMapperFactory factory = new InMemoryMailboxSessionMapperFactory();
+        final MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
+        final GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
+        mailboxManager = new StoreMailboxManager<Long>(factory, new Authenticator() {
+
+            public boolean isAuthentic(final String userid, final CharSequence passwd) {
+                try {
+                    return usersRepository.test(userid, passwd.toString());
+                } catch (final UsersRepositoryException e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }, aclResolver, groupMembershipResolver);
+        mailboxManager.init();
+
+        protocolHandlerChain.put("mailboxmanager", mailboxManager);
+
+        protocolHandlerChain.put("fileSystem", fileSystem);
+
+        //smtp
+        dnsServer = new AlterableDNSServer();
+        store = new MockMailRepositoryStore();
+        protocolHandlerChain.put("mailStore", store);
+        protocolHandlerChain.put("dnsservice", dnsServer);
+        protocolHandlerChain.put("org.apache.james.smtpserver.protocol.DNSService", dnsService);
+
+        protocolHandlerChain.put("recipientrewritetable", new RecipientRewriteTable() {
+
+            public void addRegexMapping(final String user, final String domain, final String regex) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void removeRegexMapping(final String user, final String domain, final String regex)
+                    throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void addAddressMapping(final String user, final String domain, final String address)
+                    throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void removeAddressMapping(final String user, final String domain, final String address)
+                    throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void addErrorMapping(final String user, final String domain, final String error) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void removeErrorMapping(final String user, final String domain, final String error)
+                    throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public Collection<String> getUserDomainMappings(final String user, final String domain) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void addMapping(final String user, final String domain, final String mapping) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void removeMapping(final String user, final String domain, final String mapping) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public Map<String, Collection<String>> getAllMappings() throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void addAliasDomainMapping(final String aliasDomain, final String realDomain) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public void removeAliasDomainMapping(final String aliasDomain, final String realDomain) throws RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+
+            public Collection<String> getMappings(final String user, final String domain) throws ErrorMappingException,
+            RecipientRewriteTableException {
+                throw new UnsupportedOperationException("Not implemented");
+            }
+        });
+
+        protocolHandlerChain.put("org.apache.james.smtpserver.protocol.DNSService", dnsService);
+
+        final FileMailQueueFactory ff = new FileMailQueueFactory();// MockMailQueueFactory();
+        ff.setLog(log);
+        ff.setFileSystem(fileSystem);
+        queueFactory = ff;
+
+        queue = queueFactory.getQueue(MailQueueFactory.SPOOL);
+        protocolHandlerChain.put("mailqueuefactory", queueFactory);
+        protocolHandlerChain.put("domainlist", new SimpleDomainList() {
+
+            @Override
+            public String getDefaultDomain() {
+                return "localhost";
+            }
+
+            @Override
+            public String[] getDomains() throws DomainListException {
+                return new String[] { "localhost" };
+            }
+
+            @Override
+            public boolean containsDomain(final String serverName) {
+                return "localhost".equals(serverName);
+            }
+        });
+
+    }
+
+    /**
+     * @return the queue
+     */
+    public MailQueue getQueue() {
+        return queue;
+    }
+
+    public static File getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) throws FileNotFoundException {
+
+        File configFile = null;
+        final URL configURL = MailServer.class.getClassLoader().getResource(fileNameFromClasspath);
+        if (configURL != null) {
+            try {
+                configFile = new File(configURL.toURI());
+            } catch (URISyntaxException e) {
+                configFile = new File(configURL.getPath());
+            }
+
+            //Java 7 only
+            /*if(!configFile.exists()) {
+                try {
+                    configFile = Paths.get(configURL.toURI()).toFile();
+                } catch (URISyntaxException e) {
+                    throw new FileNotFoundException("Failed to load " + fileNameFromClasspath+ " due to "+e);
+                }
+            }*/
+
+            if (configFile.exists()) {
+                return configFile;
+            } else {
+                throw new FileNotFoundException("Cannot read from "+configFile.getAbsolutePath()+" (original resource was "+fileNameFromClasspath+", URL: "+configURL+"), because the file does not exist");
+            }
+            
+        } else {
+            throw new FileNotFoundException("Failed to load " + fileNameFromClasspath+", because resource cannot be found within the classpath");
+        }
+
+    }
+
+    public static abstract class AbstractTestConfiguration extends DefaultConfigurationBuilder {
+
+        private final int listenerPort = PortUtil.getNonPrivilegedPort();
+
+        /**
+         * @return the listenerPort
+         */
+        public int getListenerPort() {
+            return listenerPort;
+        }
+
+        public AbstractTestConfiguration enableSSL(final boolean enableStartTLS, final boolean enableSSL) throws FileNotFoundException {
+            addProperty("tls.[@startTLS]", enableStartTLS);
+            addProperty("tls.[@socketTLS]", enableSSL);
+            addProperty("tls.keystore", "file://" + getAbsoluteFilePathFromClassPath("dummykeystore.jks").getAbsolutePath());
+            addProperty("tls.secret", "123456");
+            addProperty("tls.provider", "org.bouncycastle.jce.provider.BouncyCastleProvider");
+            return this;
+        }
+
+        public void init() {
+            addProperty("[@enabled]", true);
+            addProperty("bind", "127.0.0.1:" + this.listenerPort);
+            addProperty("connectiontimeout", "360000");
+            //addProperty("jmxName", getServertype().name()+"on"+this.listenerPort);
+            addProperty("helloName", "jamesserver");
+            addProperty("helloName.[@autodetect]", false);
+        }
+
+    }
+
+    public static class Pop3TestConfiguration extends AbstractTestConfiguration {
+
+        @Override
+        public void init() {
+            super.init();
+
+            addProperty("helloName", "pop3 on port " + getListenerPort());
+
+            addProperty("handlerchain.[@coreHandlersPackage]", RefinedCoreCmdHandlerLoader.class.getName());
+
+        }
+
+    }
+
+    public static class ImapTestConfiguration extends AbstractTestConfiguration {
+
+        @Override
+        public void init() {
+            super.init();
+
+            addProperty("helloName", "imap on port " + getListenerPort());
+
+        }
+
+    }
+
+    public static class SmtpTestConfiguration extends AbstractTestConfiguration {
+
+        @Override
+        public void init() {
+            super.init();
+            addProperty("handlerchain.handler[@class]", RefinedSmtpCoreCmdHandlerLoader.class.getName());
+
+        }
+
+        public SmtpTestConfiguration setRequireAuth(final boolean requireAuth) {
+
+            addProperty("authRequired", requireAuth);
+            return this;
+        }
+
+        public SmtpTestConfiguration setHeloEhloEnforcement(final boolean heloEhloEnforcement) {
+
+            addProperty("heloEhloEnforcement", heloEhloEnforcement);
+            return this;
+        }
+
+    }
+
+    public static class DummySocketFactory extends SSLSocketFactory {
+
+        @Override
+        public Socket createSocket(final String host, final int port) throws IOException, UnknownHostException {
+            throw new IOException("dummy socket factory");
+        }
+
+        @Override
+        public Socket createSocket(final InetAddress host, final int port) throws IOException {
+            throw new IOException("dummy socket factory");
+        }
+
+        @Override
+        public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) throws IOException,
+                UnknownHostException {
+            throw new IOException("dummy socket factory");
+        }
+
+        @Override
+        public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddress, final int localPort)
+                throws IOException {
+            throw new IOException("dummy socket factory");
+        }
+
+        @Override
+        public Socket createSocket(final Socket arg0, final String arg1, final int arg2, final boolean arg3) throws IOException {
+            throw new IOException("dummy socket factory");
+        }
+
+        @Override
+        public String[] getDefaultCipherSuites() {
+            return new String[0];
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            return new String[0];
+        }
+
+    }
+
+    private final class AlterableDNSServer implements DNSService {
+
+        private InetAddress localhostByName = null;
+
+        public Collection<String> findMXRecords(final String hostname) {
+            final List<String> res = new ArrayList<String>();
+            if (hostname == null) {
+                return res;
+            }
+            if ("james.apache.org".equals(hostname)) {
+                res.add("nagoya.apache.org");
+            }
+            return res;
+        }
+
+        public Iterator<HostAddress> getSMTPHostAddresses(final String domainName) {
+            throw new UnsupportedOperationException("Unimplemented mock service");
+        }
+
+        public InetAddress[] getAllByName(final String host) throws UnknownHostException {
+            return new InetAddress[] { getByName(host) };
+        }
+
+        public InetAddress getByName(final String host) throws UnknownHostException {
+            if (getLocalhostByName() != null) {
+                if ("127.0.0.1".equals(host)) {
+                    return getLocalhostByName();
+                }
+            }
+
+            if ("0.0.0.0".equals(host)) {
+                return InetAddress.getByName("0.0.0.0");
+            }
+
+            if ("james.apache.org".equals(host)) {
+                return InetAddress.getByName("james.apache.org");
+            }
+
+            if ("abgsfe3rsf.de".equals(host)) {
+                throw new UnknownHostException();
+            }
+
+            if ("128.0.0.1".equals(host) || "192.168.0.1".equals(host) || "127.0.0.1".equals(host) || "127.0.0.0".equals(host)
+                    || "255.0.0.0".equals(host) || "255.255.255.255".equals(host)) {
+                return InetAddress.getByName(host);
+            }
+
+            throw new UnsupportedOperationException("getByName not implemented in mock for host: " + host);
+        }
+
+        public Collection<String> findTXTRecords(final String hostname) {
+            final List<String> res = new ArrayList<String>();
+            if (hostname == null) {
+                return res;
+            }
+
+            if ("2.0.0.127.bl.spamcop.net.".equals(hostname)) {
+                res.add("Blocked - see http://www.spamcop.net/bl.shtml?127.0.0.2");
+            }
+            return res;
+        }
+
+        public InetAddress getLocalhostByName() {
+            return localhostByName;
+        }
+
+        public void setLocalhostByName(final InetAddress localhostByName) {
+            this.localhostByName = localhostByName;
+        }
+
+        public String getHostName(final InetAddress addr) {
+            return addr.getHostName();
+        }
+
+        public InetAddress getLocalHost() throws UnknownHostException {
+            return InetAddress.getLocalHost();
+        }
+    }
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java
new file mode 100644
index 0000000..d2c0e9b
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java
@@ -0,0 +1,31 @@
+/**
+ *  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 org.apache.geronimo.javamail.testserver;
+
+
+
+public class RefinedCoreCmdHandlerLoader extends org.apache.james.pop3server.core.CoreCmdHandlerLoader {
+
+    public RefinedCoreCmdHandlerLoader() {
+        super();
+        getHandlers().add(ApopCmdHandler.class.getName());
+        
+    }
+    
+    
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java
new file mode 100644
index 0000000..32fd915
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java
@@ -0,0 +1,48 @@
+/**
+ *  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 org.apache.geronimo.javamail.testserver;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.james.protocols.lib.handler.HandlersPackage;
+import org.apache.james.smtpserver.jmx.CommandHandlerResultJMXMonitor;
+import org.apache.james.smtpserver.jmx.ConnectHandlerResultJMXMonitor;
+import org.apache.james.smtpserver.jmx.HookResultJMXMonitor;
+//import org.apache.james.smtpserver.jmx.LineHandlerResultJMXMonitor;
+
+public class RefinedJMXHandlersLoader implements HandlersPackage {
+
+    private final List<String> handlers = new ArrayList<String>();
+
+    public RefinedJMXHandlersLoader() {
+        handlers.add(ConnectHandlerResultJMXMonitor.class.getName());
+        handlers.add(CommandHandlerResultJMXMonitor.class.getName());
+        //handlers.add(LineHandlerResultJMXMonitor.class.getName());
+        handlers.add(HookResultJMXMonitor.class.getName());
+    }
+
+    /**
+     * @see org.apache.james.protocols.api.handler.HandlersPackage#getHandlers()
+     */
+    public List<String> getHandlers() {
+        return handlers;
+    }
+
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java
new file mode 100644
index 0000000..ba7f59d
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java
@@ -0,0 +1,146 @@
+/**
+ *  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 org.apache.geronimo.javamail.testserver;
+
+ /****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.protocols.api.handler.CommandDispatcher;
+import org.apache.james.protocols.api.handler.CommandHandlerResultLogger;
+import org.apache.james.protocols.lib.handler.HandlersPackage;
+import org.apache.james.protocols.smtp.core.ExpnCmdHandler;
+import org.apache.james.protocols.smtp.core.HeloCmdHandler;
+import org.apache.james.protocols.smtp.core.HelpCmdHandler;
+import org.apache.james.protocols.smtp.core.NoopCmdHandler;
+import org.apache.james.protocols.smtp.core.PostmasterAbuseRcptHook;
+import org.apache.james.protocols.smtp.core.QuitCmdHandler;
+import org.apache.james.protocols.smtp.core.ReceivedDataLineFilter;
+import org.apache.james.protocols.smtp.core.RsetCmdHandler;
+import org.apache.james.protocols.smtp.core.VrfyCmdHandler;
+import org.apache.james.protocols.smtp.core.esmtp.AuthCmdHandler;
+import org.apache.james.protocols.smtp.core.esmtp.EhloCmdHandler;
+import org.apache.james.protocols.smtp.core.esmtp.MailSizeEsmtpExtension;
+import org.apache.james.protocols.smtp.core.esmtp.StartTlsCmdHandler;
+import org.apache.james.protocols.smtp.core.log.HookResultLogger;
+import org.apache.james.smtpserver.AddDefaultAttributesMessageHook;
+import org.apache.james.smtpserver.AuthRequiredToRelayRcptHook;
+import org.apache.james.smtpserver.DataLineJamesMessageHookHandler;
+import org.apache.james.smtpserver.JamesDataCmdHandler;
+import org.apache.james.smtpserver.JamesMailCmdHandler;
+import org.apache.james.smtpserver.JamesRcptCmdHandler;
+import org.apache.james.smtpserver.JamesWelcomeMessageHandler;
+import org.apache.james.smtpserver.SendMailHandler;
+import org.apache.james.smtpserver.SenderAuthIdentifyVerificationRcptHook;
+import org.apache.james.smtpserver.UsersRepositoryAuthHook;
+
+/**
+ * This class represent the base command handlers which are shipped with james.
+ */
+public class RefinedSmtpCoreCmdHandlerLoader implements HandlersPackage {
+
+    private final String COMMANDDISPATCHER = CommandDispatcher.class.getName();
+    private final String AUTHCMDHANDLER = AuthCmdHandler.class.getName();
+    private final String DATACMDHANDLER = JamesDataCmdHandler.class.getName();
+    private final String EHLOCMDHANDLER = EhloCmdHandler.class.getName();
+    private final String EXPNCMDHANDLER = ExpnCmdHandler.class.getName();
+    private final String HELOCMDHANDLER = HeloCmdHandler.class.getName();
+    private final String HELPCMDHANDLER = HelpCmdHandler.class.getName();
+    private final String MAILCMDHANDLER = JamesMailCmdHandler.class.getName();
+    private final String NOOPCMDHANDLER = NoopCmdHandler.class.getName();
+    private final String QUITCMDHANDLER = QuitCmdHandler.class.getName();
+    private final String RCPTCMDHANDLER = JamesRcptCmdHandler.class.getName();
+    private final String RSETCMDHANDLER = RsetCmdHandler.class.getName();
+    private final String VRFYCMDHANDLER = VrfyCmdHandler.class.getName();
+    private final String MAILSIZEHOOK = MailSizeEsmtpExtension.class.getName();
+    private final String WELCOMEMESSAGEHANDLER = JamesWelcomeMessageHandler.class.getName();
+    private final String USERSREPOSITORYAUTHHANDLER = UsersRepositoryAuthHook.class.getName();
+    private final String POSTMASTERABUSEHOOK = PostmasterAbuseRcptHook.class.getName();
+    private final String AUTHREQUIREDTORELAY = AuthRequiredToRelayRcptHook.class.getName();
+    private final String SENDERAUTHIDENTITYVERIFICATION = SenderAuthIdentifyVerificationRcptHook.class.getName();
+    private final String RECEIVEDDATALINEFILTER = ReceivedDataLineFilter.class.getName();
+    private final String DATALINEMESSAGEHOOKHANDLER = DataLineJamesMessageHookHandler.class.getName();
+    private final String STARTTLSHANDLER = StartTlsCmdHandler.class.getName();
+
+    // MessageHooks
+    private final String ADDDEFAULTATTRIBUTESHANDLER = AddDefaultAttributesMessageHook.class.getName();
+    private final String SENDMAILHANDLER = SendMailHandler.class.getName();
+
+    // logging stuff
+    private final String COMMANDHANDLERRESULTLOGGER = CommandHandlerResultLogger.class.getName();
+    private final String HOOKRESULTLOGGER = HookResultLogger.class.getName();
+
+    private final List<String> commands = new LinkedList<String>();
+
+    public RefinedSmtpCoreCmdHandlerLoader() {
+        // Insert the base commands in the Map
+        commands.add(WELCOMEMESSAGEHANDLER);
+        commands.add(COMMANDDISPATCHER);
+        commands.add(AUTHCMDHANDLER);
+        commands.add(DATACMDHANDLER);
+        commands.add(EHLOCMDHANDLER);
+        commands.add(EXPNCMDHANDLER);
+        commands.add(HELOCMDHANDLER);
+        commands.add(HELPCMDHANDLER);
+        commands.add(MAILCMDHANDLER);
+        commands.add(NOOPCMDHANDLER);
+        commands.add(QUITCMDHANDLER);
+        commands.add(RCPTCMDHANDLER);
+        commands.add(RSETCMDHANDLER);
+        commands.add(VRFYCMDHANDLER);
+        commands.add(MAILSIZEHOOK);
+        commands.add(USERSREPOSITORYAUTHHANDLER);
+        commands.add(AUTHREQUIREDTORELAY);
+        commands.add(SENDERAUTHIDENTITYVERIFICATION);
+        commands.add(POSTMASTERABUSEHOOK);
+        commands.add(RECEIVEDDATALINEFILTER);
+        commands.add(DATALINEMESSAGEHOOKHANDLER);
+        commands.add(STARTTLSHANDLER);
+        // Add the default messageHooks
+        commands.add(ADDDEFAULTATTRIBUTESHANDLER);
+        commands.add(SENDMAILHANDLER);
+
+        // Add logging stuff
+        commands.add(COMMANDHANDLERRESULTLOGGER);
+        commands.add(HOOKRESULTLOGGER);
+    }
+
+    /**
+     * @see org.apache.james.protocols.api.handler.HandlersPackage#getHandlers()
+     */
+    public List<String> getHandlers() {
+        return commands;
+    }
+}
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java
new file mode 100644
index 0000000..d0f9ead
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java
@@ -0,0 +1,57 @@
+/**
+ *  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 org.apache.geronimo.javamail.transport.smtp;
+
+import java.util.Properties;
+
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.geronimo.javamail.testserver.AbstractProtocolTest;
+
+public class SMTPTransportTest extends AbstractProtocolTest {
+
+    public void testSSLEnable() throws Exception {
+
+        
+        smtpConf.enableSSL(false, false);
+
+        start();
+
+        Properties props = new Properties();
+        props.setProperty("mail.transport.protocol", "smtp");
+        props.setProperty("mail.smtp.port", String.valueOf(smtpConf.getListenerPort()));
+        props.setProperty("mail.debug", "true");
+
+        Session jmsession = Session.getInstance(props);
+        Transport t = jmsession.getTransport();
+        t.connect();
+        
+        MimeMessage msg = new MimeMessage(jmsession);
+        msg.setFrom(new InternetAddress("test@apache.org"));
+        msg.setSubject("Hi!");
+        msg.setText("All your base are belong to us");
+        
+        
+        t.sendMessage(msg, new InternetAddress[]{new InternetAddress("testto@apache.org")});
+
+    }
+
+
+}
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks
new file mode 100644
index 0000000..cb140cd
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks
Binary files differ
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure
new file mode 100644
index 0000000..e406923
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure
@@ -0,0 +1 @@
+(("TEXT" "PLAIN" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 1281 28 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 1510 33 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "0016e6d976ed8989d30464e986d1") NIL NIL)
\ No newline at end of file
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg
new file mode 100644
index 0000000..8fbc2af
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg
@@ -0,0 +1,19 @@
+Date: Sat, 11 Oct 2008 00:48:01 +0200 (CEST)
+From: from@localhost
+To: serveruser@localhost
+Message-ID: urn:uuid:219365EB848AD9CACB1223678880948
+Subject: Test
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----=_Part_0_6727097.1223678881682"
+
+------=_Part_0_6727097.1223678881682
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+First part
+------=_Part_0_6727097.1223678881682
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Second part
+------=_Part_0_6727097.1223678881682--
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg
new file mode 100644
index 0000000..9e429ed
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg
@@ -0,0 +1,11 @@
+Date: Sat, 11 Oct 2008 00:48:01 +0200 (CEST)
+From: from@localhost
+To: serveruser@localhost
+Subject: Test Foo
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+Foo Bar
+
+
diff --git a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf
new file mode 100644
index 0000000..8671636
--- /dev/null
+++ b/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf
Binary files differ
diff --git a/geronimo-javamail_1.5/pom.xml b/geronimo-javamail_1.5/pom.xml
new file mode 100644
index 0000000..6d18175
--- /dev/null
+++ b/geronimo-javamail_1.5/pom.xml
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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: 1704994 $ $Date: 2014-07-20 09:36:35 +0200 (So, 20. Jul 2014) 
+    $ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.genesis</groupId>
+        <artifactId>genesis-java5-flava</artifactId>
+        <version>2.2</version>
+    </parent>
+
+    <groupId>org.apache.geronimo.javamail</groupId>
+    <artifactId>geronimo-javamail_1.5</artifactId>
+    <name>Geronimo JavaMail 1.5</name>
+    <packaging>pom</packaging>
+
+    <version>0.0.1-SNAPSHOT</version>
+
+    <description>
+        Geronimmo JavaMail Bundle.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/geronimo/javamail/trunk/geronimo-javamail_1.5</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/geronimo/javamail/trunk/geronimo-javamail_1.5</developerConnection>
+        <url>http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.5</url>
+    </scm>
+
+    <properties>
+        <siteId>javamail/${project.artifactId}</siteId>
+        <projectName>Apache Geronimo Javamail Bundle</projectName>
+    </properties>
+
+    <url>http://geronimo.apache.org/maven/${siteId}/${project.version}</url>
+
+    <distributionManagement>
+        <site>
+            <id>apache-website</id>
+            <url>${site.deploy.url}/maven/${siteId}/${project.version}</url>
+        </site>
+    </distributionManagement>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-activation_1.1_spec</artifactId>
+                <version>1.1</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-javamail_1.5_spec</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>3.8.2</version>
+            </dependency>
+
+            <!-- INTERNAL -->
+
+            <dependency>
+                <groupId>org.apache.geronimo.javamail</groupId>
+                <artifactId>geronimo-javamail_1.5_provider</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-osgi-locator</artifactId>
+                <version>1.0</version>
+                <scope>provided</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-shade-plugin</artifactId>
+                    <version>2.3</version>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.18</version>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-site-plugin</artifactId>
+                    <version>3.3</version>
+                    <configuration>
+                        <stagingDirectory>${staging.directory}</stagingDirectory>
+                    </configuration>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.maven.doxia</groupId>
+                            <artifactId>doxia-module-markdown</artifactId>
+                            <version>1.3</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+
+        <plugins>
+
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <includes>
+                        <include>src/**/*</include>
+                        <include>pom.xml</include>
+                    </includes>
+                    <excludes>
+                        <exclude>**/*/MANIFEST.MF</exclude>
+                        <exclude>.git</exclude>
+                        <exclude>.gitignore</exclude>
+                        <exclude>.idea</exclude>
+                        <exclude>*.iws</exclude>
+                        <exclude>*.iml</exclude>
+                        <exclude>*.ipr</exclude>
+                        <exclude>**/src/test/resources/**/*.bodystructure</exclude>
+                        <exclude>**/src/test/resources/**/*.msg</exclude>
+                        <exclude>**/resources/OSGI-INF/providers/**/*</exclude>
+                    </excludes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>validate</phase>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <!-- Allow any Java >= 1.5 -->
+                                <requireJavaVersion>
+                                    <version>[1.5,)</version>
+                                </requireJavaVersion>
+
+                                <!-- Allow any Maven >= 2.0.7 -->
+                                <requireMavenVersion>
+                                    <version>[2.0.7,)</version>
+                                </requireMavenVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <modules>
+        <module>geronimo-javamail_1.5_provider</module>
+        <module>geronimo-javamail_1.5_mail</module>
+    </modules>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>3.0.0</version>
+                <configuration>
+                    <xmlOutput>true</xmlOutput>
+                    <!-- Optional directory to put findbugs xdoc xml report -->
+                    <xmlOutputDirectory>target/site</xmlOutputDirectory>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-pmd-plugin</artifactId>
+                <version>3.2</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>2.7</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.9.1</version>
+                <configuration>
+                    <notimestamp>true</notimestamp>
+                    <show>private</show>
+                </configuration>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>javadoc</report>
+                        </reports>
+                    </reportSet>
+                    <reportSet>
+                        <inherited>false</inherited>
+                        <reports>
+                            <report>aggregate</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-report-plugin</artifactId>
+                <version>2.18</version>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <formats>
+                        <format>html</format>
+                    </formats>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>versions-maven-plugin</artifactId>
+                <version>2.1</version>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>dependency-updates-report</report>
+                            <report>plugin-updates-report</report>
+                            <report>property-updates-report</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+
+</project>
diff --git a/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt b/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt
new file mode 100644
index 0000000..b842f21
--- /dev/null
+++ b/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt
@@ -0,0 +1,52 @@
+ ----
+ Privacy Policy
+ -----
+ Olivier Lamy
+ -----
+ 2013-11-13
+ -----
+
+~~ 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.
+
+Privacy Policy
+
+  Information about your use of this website is collected using server access logs and a tracking cookie. The 
+  collected information consists of the following:
+
+  [[1]] The IP address from which you access the website;
+  
+  [[2]] The type of browser and operating system you use to access our site;
+  
+  [[3]] The date and time you access our site;
+  
+  [[4]] The pages you visit; and
+  
+  [[5]] The addresses of pages from where you followed a link to our site.
+
+  []
+
+  Part of this information is gathered using a tracking cookie set by the 
+  {{{http://www.google.com/analytics/}Google Analytics}} service and handled by Google as described in their 
+  {{{http://www.google.com/privacy.html}privacy policy}}. See your browser documentation for instructions on how to 
+  disable the cookie if you prefer not to share this data with Google.
+
+  We use the gathered information to help us make our site more useful to visitors and to better understand how and 
+  when our site is used. We do not track or collect personally identifiable information or associate gathered data 
+  with any personally identifying information from other sources.
+
+  By using this website, you consent to the collection of this data in the manner and for the purpose described above.
diff --git a/geronimo-javamail_1.5/src/site/markdown/index.md b/geronimo-javamail_1.5/src/site/markdown/index.md
new file mode 100644
index 0000000..01cb1b9
--- /dev/null
+++ b/geronimo-javamail_1.5/src/site/markdown/index.md
@@ -0,0 +1,35 @@
+<!---
+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.
+-->
+# Geronimo JavaMail 1.5
+
+Geronimo JavaMail 1.5
+
+## Get started
+
+Just get it from maven
+
+### Core
+
+<pre class="prettyprint linenums"><![CDATA[
+<dependency>
+	<groupId>org.apache.geronimo.javamail</groupId>
+	<artifactId>geronimo-javamail_1.5_provider</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+</dependency>
+]]></pre>
\ No newline at end of file
diff --git a/geronimo-javamail_1.5/src/site/site.xml b/geronimo-javamail_1.5/src/site/site.xml
new file mode 100644
index 0000000..272648e
--- /dev/null
+++ b/geronimo-javamail_1.5/src/site/site.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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.
+-->
+<project name="Apache Johnzon"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/DECORATION/1.0.1"
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.1
+                             http://maven.apache.org/xsd/decoration-1.0.1.xsd">
+  <bannerLeft>
+    <name>Geronimo JavaMail</name>
+    <alt>Geronimo JavaMail</alt>
+    <href>/index.html</href>
+  </bannerLeft>
+  <bannerRight>
+    <src>http://geronimo.apache.org/images/topleft_logo_437x64.gif</src>
+    <href>http://geronimo.apache.org/</href>
+  </bannerRight>
+
+  <custom>
+    <fluidoSkin>
+      <topBarEnabled>true</topBarEnabled>
+      <sideBarEnabled>true</sideBarEnabled>
+      <sourceLineNumbersEnabled>true</sourceLineNumbersEnabled>
+    </fluidoSkin>
+  </custom>
+
+  <skin>
+    <groupId>org.apache.maven.skins</groupId>
+    <artifactId>maven-fluido-skin</artifactId>
+    <version>1.3.0</version>
+  </skin>
+
+  <body>
+
+    <head>
+
+      <script type="text/javascript">
+
+        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+        ga('create', 'UA-3211522-15', 'apache.org');
+        ga('send', 'pageview');
+
+      </script>
+
+    </head>
+
+    <menu name="User Guide">
+      <item name="Home" href="/index.html"/>
+    </menu>
+
+    <menu ref="reports" inherit="bottom"/>
+
+    <menu name="ASF">
+      <item name="How Apache Works" href="http://www.apache.org/foundation/how-it-works.html"/>
+      <item name="Foundation" href="http://www.apache.org/foundation/"/>
+      <item name="Sponsoring Apache" href="http://www.apache.org/foundation/sponsorship.html"/>
+      <item name="Thanks" href="http://www.apache.org/foundation/thanks.html"/>
+    </menu>
+
+    <footer>
+      <div class="row span16"><div>Apache Geronimo, Apache, the Apache feather logo, and the Apache Johnzon project logos are trademarks of The Apache Software Foundation.
+        All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div>
+        <a href="${project.url}/privacy-policy.html">Privacy Policy</a>
+      </div>
+    </footer>
+
+  </body>
+</project>
