diff --git a/geronimo-javamail_1.5/.travis.yml b/geronimo-javamail_1.5/.travis.yml
deleted file mode 100644
index ca8fc8c..0000000
--- a/geronimo-javamail_1.5/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: java
-
-jdk:
-  - openjdk6
-  - openjdk7
-  - oraclejdk7
-  - oraclejdk8
-  
diff --git a/geronimo-javamail_1.5/LICENSE b/geronimo-javamail_1.5/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/geronimo-javamail_1.5/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 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
deleted file mode 100644
index e288221..0000000
--- a/geronimo-javamail_1.5/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-
-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
deleted file mode 100644
index cad0219..0000000
--- a/geronimo-javamail_1.5/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-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
deleted file mode 100644
index 2aed314..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/pom.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?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
deleted file mode 100644
index 251ed2b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_mail/src/site/site.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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
deleted file mode 100644
index c9cccf5..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/pom.xml
+++ /dev/null
@@ -1,345 +0,0 @@
-<?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
deleted file mode 100644
index c4341c7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/AuthenticatorFactory.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 0404d36..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/ClientAuthenticator.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 91a6425..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0272b24..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 9c52f62..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/LoginAuthenticator.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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
deleted file mode 100644
index dd1e704..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/PlainAuthenticator.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 9b22442..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/authentication/SASLAuthenticator.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d0d202a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractImageHandler.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 52afca7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/AbstractTextHandler.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 6cc4d76..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageGifHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *  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
deleted file mode 100644
index c3623c8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/ImageJpegHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 015953d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/MultipartHandler.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 1df03d3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/RFC822MessageHandler.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 59a802e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextHtmlHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *  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
deleted file mode 100644
index c2c3b97..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextPlainHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 2fdb9d3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/handlers/TextXmlHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- *  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
deleted file mode 100644
index ba9a179..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/ACL.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 03fc82e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPAttachedMessage.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 62b7fd7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPFolder.java
+++ /dev/null
@@ -1,2393 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 44cfb45..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
+++ /dev/null
@@ -1,1300 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 9370451..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMimeBodyPart.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 30c2515..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMultipartDataSource.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 3349830..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPNamespaceFolder.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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
deleted file mode 100644
index dce9420..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPRootFolder.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 110f3c3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPSSLStore.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 215557b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPStore.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- * 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
deleted file mode 100644
index c08ef0f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/Rights.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 46ed792..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPACLResponse.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 9efe633..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBody.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * 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
deleted file mode 100644
index cb2dc35..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodySection.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 80cf50e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructure.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/**
- * 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
deleted file mode 100644
index c0012ea..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCapabilityResponse.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * 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
deleted file mode 100644
index d49b513..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
+++ /dev/null
@@ -1,1477 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 9922c68..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
+++ /dev/null
@@ -1,1992 +0,0 @@
-/**
- * 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
deleted file mode 100644
index f89619c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 32ea079..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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
deleted file mode 100644
index c2e947e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 37b8a3f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * 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
deleted file mode 100644
index ec17870..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 6d15af3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * 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
deleted file mode 100644
index c556665..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 21f025a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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
deleted file mode 100644
index ce55057..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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
deleted file mode 100644
index ce0e088..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 09fde92..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 9a7befd..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 27fb4d7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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
deleted file mode 100644
index d5a9827..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * 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
deleted file mode 100644
index bf1b712..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 5d3cf81..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 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
deleted file mode 100644
index f72bdb0..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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
deleted file mode 100644
index fdb3209..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 603837a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 866b6e6..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 9554ea8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPOkResponse.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * 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
deleted file mode 100644
index a85f491..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPPermanentFlagsResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 8ea5698..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaResponse.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 44d564f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPQuotaRootResponse.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 7180402..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponse.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * 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
deleted file mode 100644
index cd28d54..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 420934a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 9a5f5c9..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
+++ /dev/null
@@ -1,1469 +0,0 @@
-/**
- * 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
deleted file mode 100644
index abeaf9c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 1afeb84..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 60a3141..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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
deleted file mode 100644
index e2d3a41..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 053a2db..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * 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
deleted file mode 100644
index a31eb89..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 45137ee..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 8674f3a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 1a6812a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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
deleted file mode 100644
index a38d0a1..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPFolder.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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
deleted file mode 100644
index bb24800..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPGroupFolder.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1e346cc..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPMessage.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * 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
deleted file mode 100644
index cea8790..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPRootFolder.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 767b78c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPSSLStore.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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
deleted file mode 100644
index ec86f6e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/NNTPStore.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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
deleted file mode 100644
index def485c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrc.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8a8a97c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcFile.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b628361..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/NNTPNewsrcGroup.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 90e4707..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/Range.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 845f54a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/nntp/newsrc/RangeList.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 33179f9..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3ef0275..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Folder.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1d5deb1..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Message.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 99cde3b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3RootFolder.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * 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
deleted file mode 100644
index c92b922..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3SSLStore.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 5be4af5..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 138834e..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
+++ /dev/null
@@ -1,693 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 8aa9c4b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ConnectionPool.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 5eeb7ba..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3ListResponse.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e4fc2aa..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Response.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7472cfc..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3StatusResponse.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8ab1e2f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d631d72..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPReply.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e27a064..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPSSLTransport.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 78d5408..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 5de6e5a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/StringListInputStream.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 86652b2..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/MalformedSMTPReplyException.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644
index bfd2699..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressFailedException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 990d656..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPAddressSucceededException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ea84556..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 91d8c95..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPMessage.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 092bd02..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPReply.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0794065..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSTransport.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 20ff08a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPSendFailedException.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b89988f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d6851e3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2c12b70..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CommandFailedException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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
deleted file mode 100644
index ece163d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ConnectionException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 3dc5e1c..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/CountingOutputStream.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 4273cbb..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/InvalidCommandException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 70c3727..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEInputReader.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ac7b2bc..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MIMEOutputStream.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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
deleted file mode 100644
index af079ae..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/MailConnection.java
+++ /dev/null
@@ -1,960 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 7ef1a6d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ProtocolProperties.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * 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
deleted file mode 100644
index e533313..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/ResponseFormatException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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
deleted file mode 100644
index 05763b6..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceInputStream.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2f545fa..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/java/org/apache/geronimo/javamail/util/TraceOutputStream.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3bba278..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.address.map
+++ /dev/null
@@ -1,34 +0,0 @@
-##
-## 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
deleted file mode 100644
index e4db1a3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/javamail.default.providers
+++ /dev/null
@@ -1,43 +0,0 @@
-##
-## 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
deleted file mode 100644
index 2783191..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/META-INF/mailcap
+++ /dev/null
@@ -1,31 +0,0 @@
-##
-## 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
deleted file mode 100644
index c6e297b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageGifHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c8148bb..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.ImageJpegHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 39d2e16..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.MultipartHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a091915..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.RFC822MessageHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0da58ec..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextHtmlHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c3518a0..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextPlainHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 04b32e3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.handlers.TextXmlHandler
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 18127c3..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPSSSLStore
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6c35475..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.imap.IMAPStore
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c8df215..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPSSLStore
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 83d3d3a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.nntp.NNTPStore
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index ace45de..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3SSLStore
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 28dd416..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.store.pop3.POP3Store
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 5af212f..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPSSLTransport
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 7db7ae2..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.nntp.NNTPTransport
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index cc5bbb5..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPSSLTransport
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a16aa75..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/main/resources/OSGI-INF/providers/org.apache.javamail.transport.smtp.SMTPTransport
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 251ed2b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/site/site.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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
deleted file mode 100644
index 36c7cbb..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/AbstractHandler.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 79da869..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextHtmlTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 95dead8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextPlainTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 9122ec8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/handlers/TextXmlTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- *  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
deleted file mode 100755
index e999475..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/GERONIMO6480Test.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- *  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
deleted file mode 100644
index e10bf5a..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/issues/IssuesTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- *  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
deleted file mode 100644
index ff09eb8..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/AuthenticationTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 3dd7866..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/IMAPStoreTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 9ef05e7..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- *  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
deleted file mode 100644
index a91133d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/store/pop3/POP3StoreTest.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 8648869..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/AbstractProtocolTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 4c0bead..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/ApopCmdHandler.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- *  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
deleted file mode 100644
index b73d6f4..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/MailServer.java
+++ /dev/null
@@ -1,590 +0,0 @@
-/**
- *  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
deleted file mode 100644
index d2c0e9b..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedCoreCmdHandlerLoader.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- *  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
deleted file mode 100644
index 32fd915..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedJMXHandlersLoader.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- *  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
deleted file mode 100644
index ba7f59d..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/testserver/RefinedSmtpCoreCmdHandlerLoader.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- *  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
deleted file mode 100644
index d0f9ead..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransportTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- *  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
deleted file mode 100644
index cb140cd..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/dummykeystore.jks
+++ /dev/null
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
deleted file mode 100644
index e406923..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/imap/multipart.bodystructure
+++ /dev/null
@@ -1 +0,0 @@
-(("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
deleted file mode 100644
index 8fbc2af..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/multipart.msg
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644
index 9e429ed..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/messages/simple.msg
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 8671636..0000000
--- a/geronimo-javamail_1.5/geronimo-javamail_1.5_provider/src/test/resources/pdf-test.pdf
+++ /dev/null
Binary files differ
diff --git a/geronimo-javamail_1.5/pom.xml b/geronimo-javamail_1.5/pom.xml
deleted file mode 100644
index 6d18175..0000000
--- a/geronimo-javamail_1.5/pom.xml
+++ /dev/null
@@ -1,273 +0,0 @@
-<?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
deleted file mode 100644
index b842f21..0000000
--- a/geronimo-javamail_1.5/src/site/apt/privacy-policy.apt
+++ /dev/null
@@ -1,52 +0,0 @@
- ----
- 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
deleted file mode 100644
index 01cb1b9..0000000
--- a/geronimo-javamail_1.5/src/site/markdown/index.md
+++ /dev/null
@@ -1,35 +0,0 @@
-<!---
-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
deleted file mode 100644
index 272648e..0000000
--- a/geronimo-javamail_1.5/src/site/site.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?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>
