GERONIMO-5326 Geronimo javamail does not work on non-ASCII platforms



git-svn-id: https://svn.apache.org/repos/asf/geronimo/javamail/trunk@946314 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
index 17da4db..c62deac 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/CramMD5Authenticator.java
@@ -19,6 +19,7 @@
 
 package org.apache.geronimo.javamail.authentication;
 
+import java.nio.charset.Charset;
 import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -40,7 +41,7 @@
 
     /**
      * Main constructor.
-     * 
+     *
      * @param username
      *            The login user name.
      * @param password
@@ -54,7 +55,7 @@
     /**
      * Respond to the hasInitialResponse query. This mechanism does not have an
      * initial response.
-     * 
+     *
      * @return Always returns false.
      */
     public boolean hasInitialResponse() {
@@ -63,7 +64,7 @@
 
     /**
      * Indicate whether the challenge/response process is complete.
-     * 
+     *
      * @return True if the last challenge has been processed, false otherwise.
      */
     public boolean isComplete() {
@@ -72,7 +73,7 @@
 
     /**
      * Retrieve the authenticator mechanism name.
-     * 
+     *
      * @return Always returns the string "CRAM-MD5"
      */
     public String getMechanismName() {
@@ -82,10 +83,10 @@
     /**
      * 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
      */
@@ -102,9 +103,9 @@
 
             // create a unified string using the user name and the hex encoded
             // digest
-            String responseString = username + " " + new String(Hex.encode(digest));
+            String responseString = username + " " + new String(Hex.encode(digest), "ISO8859-1");
             complete = true;
-            return responseString.getBytes();
+            return responseString.getBytes("ISO8859-1");
         } catch (UnsupportedEncodingException e) {
             // got an error, fail this
             throw new MessagingException("Invalid character encodings");
@@ -115,12 +116,12 @@
     /**
      * 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
      */
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
index c762f70..5784ec3 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/DigestMD5Authenticator.java
@@ -74,7 +74,7 @@
 
     /**
      * Main constructor.
-     * 
+     *
      * @param host
      *            The server host name.
      * @param username
@@ -94,7 +94,7 @@
     /**
      * Respond to the hasInitialResponse query. This mechanism does not have an
      * initial response.
-     * 
+     *
      * @return Always returns false.
      */
     public boolean hasInitialResponse() {
@@ -103,7 +103,7 @@
 
     /**
      * Indicate whether the challenge/response process is complete.
-     * 
+     *
      * @return True if the last challenge has been processed, false otherwise.
      */
     public boolean isComplete() {
@@ -112,7 +112,7 @@
 
     /**
      * Retrieve the authenticator mechanism name.
-     * 
+     *
      * @return Always returns the string "DIGEST-MD5"
      */
     public String getMechanismName() {
@@ -122,10 +122,10 @@
     /**
      * 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
      */
@@ -161,10 +161,10 @@
     /**
      * 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
      */
@@ -180,11 +180,11 @@
             // 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()));
+            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()));
+            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.
@@ -202,10 +202,10 @@
     /**
      * 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
      */
@@ -242,13 +242,13 @@
         byte[] cnonceBytes = new byte[32];
 
         randomGenerator.nextBytes(cnonceBytes);
-        // and get this as a base64 encoded string.
-        String cnonce = new String(Base64.encode(cnonceBytes));
-
-        // Now the digest computation part. This gets a bit tricky, and must be
-        // done in strict order.
 
         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
@@ -265,20 +265,20 @@
             // (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())) + ":" + nonce + ":00000001:" + cnonce + ":auth:";
+            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()));
+            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()));
+            String challengeResponse = new String(Hex.encode(digest.digest()), "US-ASCII");
 
             // now finally build the keyword/value part of the challenge
             // response. These can be
@@ -323,17 +323,21 @@
     /**
      * 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 = new DigestParser(new String(challenge));
+        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.
@@ -376,7 +380,7 @@
 
         /**
          * Normal constructor.
-         * 
+         *
          * @param challenge
          *            The challenge string to be parsed.
          */
@@ -388,7 +392,7 @@
 
         /**
          * 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.
          */
@@ -398,7 +402,7 @@
 
         /**
          * Return the character at the current parsing position.
-         * 
+         *
          * @return The string character for the current parse position.
          */
         private char currentChar() {
@@ -424,7 +428,7 @@
         /**
          * 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() {
@@ -467,7 +471,7 @@
 
         /**
          * 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.
          */
@@ -533,7 +537,7 @@
 
         /**
          * Parse out a name token of a name/value pair.
-         * 
+         *
          * @return The string value of the name.
          */
         private String parseName() {
@@ -546,7 +550,7 @@
 
         /**
          * Parse out a a value of a name/value pair.
-         * 
+         *
          * @return The string value associated with the name.
          */
         private String parseValue() {
@@ -564,7 +568,7 @@
 
         /**
          * Parse a name/value pair in an DIGEST-MD5 string.
-         * 
+         *
          * @return A NameValuePair object containing the two parts of the value.
          * @exception MessagingException
          */
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
index 3726cd9..23f38b4 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/IMAPMessage.java
@@ -31,7 +31,7 @@
 
 import javax.activation.DataHandler;
 
-import javax.mail.Address; 
+import javax.mail.Address;
 import javax.mail.FetchProfile;
 import javax.mail.Flags;
 import javax.mail.Folder;
@@ -47,13 +47,13 @@
 
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.InternetHeaders;
-import javax.mail.internet.MailDateFormat;     
+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.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;
@@ -77,9 +77,9 @@
  * @version $Rev$ $Date$
  */
 public class IMAPMessage extends MimeMessage {
-    
-    private static final byte[] CRLF = "\r\n".getBytes();
-    
+
+    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;
 
@@ -87,27 +87,27 @@
     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 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 
+    // 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; 
+    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
@@ -117,15 +117,15 @@
      *                 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.  
+        // 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();
@@ -147,7 +147,7 @@
             sequenceNumber = -1;
         }
     }
-    
+
 
     /**
      * Return a copy the flags associated with this message.
@@ -156,9 +156,9 @@
      * @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(); 
+        // load the flags, if needed
+        loadFlags();
+        return super.getFlags();
     }
 
 
@@ -171,9 +171,9 @@
      * @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); 
+        // load the flags, if needed
+        loadFlags();
+        return super.isSet(flag);
     }
 
     /**
@@ -187,31 +187,31 @@
     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. 
+
+        // 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); 
+                // 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); 
+                releaseConnection(connection);
             }
         }
     }
 
 
     /**
-     * Return an InputStream instance for accessing the 
+     * Return an InputStream instance for accessing the
      * message content.
-     * 
+     *
      * @return An InputStream instance for accessing the content
      *         (body) of the message.
      * @exception MessagingException
@@ -240,7 +240,7 @@
      * @exception IOException
      * @exception MessagingException
      */
-    public void writeTo(OutputStream out) throws IOException, MessagingException {                      
+    public void writeTo(OutputStream out) throws IOException, MessagingException {
         // no content loaded yet?
         if (content == null) {
             // make sure we're still valid
@@ -248,26 +248,26 @@
             // 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());
+            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.                         
+	 * 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
@@ -281,14 +281,14 @@
     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; 
+        // 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 (Address[])addresses.clone();
     }
-    
+
 
     /**
      * Return the "Sender" header as an address.
@@ -299,13 +299,13 @@
     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; 
+        // 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]; 
+        return addresses[0];
     }
 
     /**
@@ -325,26 +325,26 @@
     public Address[] getRecipients(Message.RecipientType type) throws MessagingException {
         // make sure we've retrieved the envelope information.
         loadEnvelope();
-        Address[] addresses = null; 
-        
+        Address[] addresses = null;
+
         if (type == Message.RecipientType.TO) {
-            addresses = envelope.to; 
+            addresses = envelope.to;
         }
         else if (type == Message.RecipientType.CC) {
-            addresses = envelope.cc; 
+            addresses = envelope.cc;
         }
         else if (type == Message.RecipientType.BCC) {
-            addresses = envelope.bcc; 
+            addresses = envelope.bcc;
         }
         else {
-            // this could be a newsgroup type, which will tickle the message headers. 
+            // 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. 
+        // make sure we return a copy of the array so this can't be changed.
         if (addresses == null) {
             return null;
         }
-        return (Address[])addresses.clone(); 
+        return (Address[])addresses.clone();
     }
 
     /**
@@ -358,12 +358,12 @@
     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; 
+        // 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(); 
+        return (Address[])addresses.clone();
     }
 
     /**
@@ -378,16 +378,16 @@
     public String getSubject() throws MessagingException {
         // make sure we've retrieved the envelope information.
         loadEnvelope();
-        
+
         if (envelope.subject == null) {
-            return null; 
+            return null;
         }
-        // the subject could be encoded.  If there is a decoding error, 
-        // return the raw subject string. 
+        // the subject could be encoded.  If there is a decoding error,
+        // return the raw subject string.
         try {
-            return MimeUtility.decodeText(envelope.subject); 
+            return MimeUtility.decodeText(envelope.subject);
         } catch (UnsupportedEncodingException e) {
-            return envelope.subject; 
+            return envelope.subject;
         }
     }
 
@@ -401,8 +401,8 @@
     public Date getSentDate() throws MessagingException {
         // make sure we've retrieved the envelope information.
         loadEnvelope();
-        // just return that directly 
-        return envelope.date; 
+        // just return that directly
+        return envelope.date;
     }
 
 
@@ -414,7 +414,7 @@
      */
     public Date getReceivedDate() throws MessagingException {
         loadEnvelope();
-        return receivedDate; 
+        return receivedDate;
     }
 
 
@@ -426,12 +426,12 @@
      * @exception MessagingException
      */
 	public int getSize() throws MessagingException {
-        // make sure we've retrieved the envelope information.  We load the 
-        // size when we retrieve that. 
+        // make sure we've retrieved the envelope information.  We load the
+        // size when we retrieve that.
         loadEnvelope();
-        return size;                          
+        return size;
 	}
-    
+
 
     /**
      * Get a line count for the IMAP message.  This is potentially
@@ -443,7 +443,7 @@
      */
     public int getLineCount() throws MessagingException {
         loadBodyStructure();
-        return bodyStructure.lines; 
+        return bodyStructure.lines;
     }
 
     /**
@@ -467,7 +467,7 @@
      */
     public String getContentType() throws MessagingException {
         loadBodyStructure();
-        return bodyStructure.mimeType.toString(); 
+        return bodyStructure.mimeType.toString();
     }
 
 
@@ -482,7 +482,7 @@
      */
     public boolean isMimeType(String type) throws MessagingException {
         loadBodyStructure();
-        return bodyStructure.mimeType.match(type); 
+        return bodyStructure.mimeType.match(type);
     }
 
     /**
@@ -496,9 +496,9 @@
     public String getDisposition() throws MessagingException {
         loadBodyStructure();
         if (bodyStructure.disposition != null) {
-            return bodyStructure.disposition.getDisposition(); 
+            return bodyStructure.disposition.getDisposition();
         }
-        return null; 
+        return null;
     }
 
     /**
@@ -510,7 +510,7 @@
      */
     public String getEncoding() throws MessagingException {
         loadBodyStructure();
-        return bodyStructure.transferEncoding; 
+        return bodyStructure.transferEncoding;
     }
 
     /**
@@ -522,95 +522,95 @@
      */
     public String getContentID() throws MessagingException {
         loadBodyStructure();
-        return bodyStructure.contentID;         
+        return bodyStructure.contentID;
     }
 
     public String getContentMD5() throws MessagingException {
         loadBodyStructure();
-        return bodyStructure.md5Hash;         
+        return bodyStructure.md5Hash;
     }
-    
-    
+
+
     public String getDescription() throws MessagingException {
         loadBodyStructure();
-        
+
         if (bodyStructure.contentDescription == null) {
-            return null; 
+            return null;
         }
-        // the subject could be encoded.  If there is a decoding error, 
-        // return the raw subject string. 
+        // the subject could be encoded.  If there is a decoding error,
+        // return the raw subject string.
         try {
-            return MimeUtility.decodeText(bodyStructure.contentDescription); 
+            return MimeUtility.decodeText(bodyStructure.contentDescription);
         } catch (UnsupportedEncodingException e) {
             return bodyStructure.contentDescription;
         }
     }
 
     /**
-     * Return the content languages associated with this 
+     * Return the content languages associated with this
      * message.
-     * 
-     * @return 
+     *
+     * @return
      * @exception MessagingException
      */
     public String[] getContentLanguage() throws MessagingException {
         loadBodyStructure();
-        
+
         if (!bodyStructure.languages.isEmpty()) {
-            return (String[])bodyStructure.languages.toArray(new String[bodyStructure.languages.size()]); 
+            return (String[])bodyStructure.languages.toArray(new String[bodyStructure.languages.size()]);
         }
-        return null; 
+        return null;
     }
 
     public String getMessageID() throws MessagingException {
         loadEnvelope();
-        return envelope.messageID; 
+        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");
     }
@@ -622,7 +622,7 @@
     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");
     }
@@ -630,7 +630,7 @@
     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
@@ -753,7 +753,7 @@
      * @exception MessagingException
      */
     public synchronized DataHandler getDataHandler() throws MessagingException {
-        // check the validity and make sure we have the body structure information. 
+        // check the validity and make sure we have the body structure information.
         checkValidity();
         loadBodyStructure();
         if (dh == null) {
@@ -763,8 +763,8 @@
                 return dh;
             }
             else if (bodyStructure.isAttachedMessage()) {
-                dh = new DataHandler(new IMAPAttachedMessage(this, section, bodyStructure.nestedEnvelope, bodyStructure.nestedBody), 
-                     bodyStructure.mimeType.toString()); 
+                dh = new DataHandler(new IMAPAttachedMessage(this, section, bodyStructure.nestedEnvelope, bodyStructure.nestedBody),
+                     bodyStructure.mimeType.toString());
                 return dh;
             }
         }
@@ -789,32 +789,32 @@
         headers = new InternetHeaders(in);
         allHeadersRetrieved = true;
     }
-    
+
     /**
-     * Load the flag set for this message from the server. 
-     * 
+     * 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 the flags are already loaded, nothing to do
         if (flags != null) {
-            return; 
+            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. 
+        // 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); 
+                // fetch the flags for this item.
+                flags = connection.fetchFlags(sequenceNumber);
             } finally {
-                releaseConnection(connection); 
+                releaseConnection(connection);
             }
         }
     }
@@ -833,21 +833,21 @@
 
         // 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. 
+        // 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 
+                // get the headers and set
                 headers = connection.fetchHeaders(sequenceNumber, section);
-                // we have the entire header set, not just a subset. 
-                allHeadersRetrieved = true;                                               
+                // we have the entire header set, not just a subset.
+                allHeadersRetrieved = true;
             } finally {
-                releaseConnection(connection); 
+                releaseConnection(connection);
             }
         }
     }
@@ -858,7 +858,7 @@
      * information.
      *
      * @exception MessagingException
-     */                                
+     */
     protected synchronized void loadEnvelope() throws MessagingException {
         // don't retrieve if already loaded.
         if (envelope != null) {
@@ -867,28 +867,28 @@
 
         // 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. 
+        // 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. 
+                // 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. 
+                    // and process.
                     IMAPFetchResponse fetch = (IMAPFetchResponse)fetches.get(i);
-                    // update the internal info 
-                    updateMessageInformation(fetch); 
+                    // update the internal info
+                    updateMessageInformation(fetch);
                 }
             } finally {
-                releaseConnection(connection); 
+                releaseConnection(connection);
             }
         }
     }
@@ -901,8 +901,8 @@
      * @exception MessagingException
      */
     protected synchronized void updateEnvelope(IMAPEnvelope envelope) throws MessagingException {
-        // set the envelope item 
-        this.envelope = envelope; 
+        // set the envelope item
+        this.envelope = envelope;
 
         // copy header type information from the envelope into the headers.
         updateHeader("From", envelope.from);
@@ -933,24 +933,24 @@
 
         // 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. 
+        // 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 
+                // go update all of the information
             } finally {
-                releaseConnection(connection); 
+                releaseConnection(connection);
             }
-            
-            // update this before we release the folder lock so we can avoid 
-            // deadlock. 
-            updateBodyStructure(bodyStructure); 
+
+            // update this before we release the folder lock so we can avoid
+            // deadlock.
+            updateBodyStructure(bodyStructure);
         }
     }
 
@@ -961,9 +961,9 @@
      * @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 
+        // 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) {
@@ -972,9 +972,9 @@
 
         // 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. 
+            // 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));
             }
@@ -1010,24 +1010,24 @@
         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. 
+
+        // 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); 
+                // load the content from the server.
+                content = connection.fetchContent(getSequenceNumber(), section);
             } finally {
-                releaseConnection(connection); 
+                releaseConnection(connection);
             }
         }
     }
 
-    
+
     /**
      * Retrieve the sequence number assigned to this message.
      *
@@ -1037,16 +1037,16 @@
     int getSequenceNumber() {
         return sequenceNumber;
     }
-    
+
     /**
-     * Set the sequence number for the message.  This 
-     * is updated whenever messages get expunged from 
-     * the folder. 
-     * 
+     * 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; 
+        sequenceNumber = s;
     }
 
 
@@ -1068,7 +1068,7 @@
         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
@@ -1081,11 +1081,11 @@
         // the folder owns everything.
         return ((IMAPFolder)folder).getMessageConnection();
     }
-    
+
     /**
-     * Release the connection back to the Folder after performing an operation 
+     * 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 {
@@ -1102,7 +1102,7 @@
      * @exception MessagingException
      */
     protected void checkValidity() throws MessagingException {
-        checkValidity(false); 
+        checkValidity(false);
     }
 
 
@@ -1114,24 +1114,24 @@
      * @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. 
+        // 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(); 
+                IMAPConnection connection = getConnection();
 
                 try {
                     connection.updateMailboxStatus();
                 } finally {
-                    // this will force any expunged messages to be processed before we release 
-                    // the lock. 
-                    releaseConnection(connection); 
+                    // this will force any expunged messages to be processed before we release
+                    // the lock.
+                    releaseConnection(connection);
                 }
             }
         }
@@ -1141,160 +1141,160 @@
             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 
+     * 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 
+     * 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.  
-     * 
+     *
+     * 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 
+     *
+     * @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. 
+        // 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; 
+            return true;
         }
         if (profile.contains(FetchProfile.Item.ENVELOPE) && envelope == null) {
-            return true; 
+            return true;
         }
         if (profile.contains(FetchProfile.Item.FLAGS) && flags == null) {
-            return true; 
+            return true;
         }
         if (profile.contains(FetchProfile.Item.CONTENT_INFO) && bodyStructure == null) {
-            return true; 
+            return true;
         }
-        // The following profile items are our implementation of items that the 
-        // Sun IMAPFolder implementation supports.  
+        // The following profile items are our implementation of items that the
+        // Sun IMAPFolder implementation supports.
         if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS) && !allHeadersRetrieved) {
-            return true; 
+            return true;
         }
         if (profile.contains(IMAPFolder.FetchProfileItem.SIZE) && bodyStructure.bodySize < 0) {
-            return true; 
+            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. 
+        // 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; 
+                return true;
             }
         }
-        // this message, at least, does not need anything fetched. 
-        return false; 
+        // this message, at least, does not need anything fetched.
+        return false;
     }
-    
+
     /**
-     * Update a message instance with information retrieved via an IMAP FETCH 
+     * 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(); 
-        
+        // 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); 
-            
+            IMAPFetchDataItem item = (IMAPFetchDataItem)items.get(i);
+
             switch (item.getType()) {
-                // if the envelope has been requested, we'll end up with all of these items. 
+                // 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. 
+                    // 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;      
+                    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 
+                    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 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; 
+                        // 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); 
+                        // 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 
+     * 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  
+        // 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(); 
-        
+        // 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. 
+            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); 
+                // 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]); 
+                    newHeaders.addHeader(name, a[i]);
                 }
             }
         }
         // and replace the current header set
-        headers = newHeaders; 
+        headers = newHeaders;
     }
 }
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
index 705dedf..d49b513 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPCommand.java
@@ -28,7 +28,7 @@
 import java.util.List;
 import java.util.Vector;
 
-import javax.mail.FetchProfile; 
+import javax.mail.FetchProfile;
 import javax.mail.Flags;
 import javax.mail.Message;
 import javax.mail.MessagingException;
@@ -58,10 +58,10 @@
 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.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.store.imap.Rights;
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
 
 import org.apache.geronimo.javamail.util.CommandFailedException;
 
@@ -89,127 +89,127 @@
         '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 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. 
+     * 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(' '); 
+            // 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); 
+        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; 
+        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. 
+     * 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() 
+    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. 
+            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(); 
+                segments = new ArrayList();
             }
-            // ok, we need to issue this command as a conversation. 
+            // 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. 
-     * 
+     * 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. 
+            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. 
+        // 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(); 
+                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); 
+                    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. 
+            // 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');
         }
@@ -224,7 +224,7 @@
      */
     public void append(String value) {
         try {
-            // add the bytes direcly 
+            // add the bytes direcly
             out.writeBytes(value);
             // assume we're needing whitespace after this (pretty much unknown).
             needWhiteSpace = true;
@@ -242,20 +242,26 @@
      * @param value  The value to append.
      */
     public void appendString(String value) {
-        // work off the byte values
-        appendString(value.getBytes());
+        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) {
-        // work off the byte values
-        appendQuotedString(value.getBytes());
+        try {
+            // work off the byte values
+            appendQuotedString(value.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
     }
 
 
@@ -270,11 +276,14 @@
     public void appendEncodedString(String value) {
         // encode first.
         value = encode(value);
-        // work off the byte values
-        appendString(value.getBytes());
+        try {
+            // work off the byte values
+            appendString(value.getBytes("ISO8859-1"));
+        } catch (UnsupportedEncodingException e) {
+        }
     }
 
-    
+
     /**
      * Encode a string using the modified UTF-7 encoding.
      *
@@ -354,7 +363,7 @@
         // convert the encoded string.
         return result.toString();
     }
-    
+
 
     /**
      * Encode a single buffer of characters.  This buffer will have
@@ -428,15 +437,18 @@
      */
     public void appendString(String value, String charset) throws MessagingException {
         if (charset == null) {
-            // work off the byte values
-            appendString(value.getBytes());
+            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));
-            } catch (UnsupportedEncodingException e) {
                 throw new MessagingException("Invalid text encoding");
+            } catch (UnsupportedEncodingException e) {
             }
         }
     }
@@ -467,20 +479,20 @@
 
 
     /**
-     * Append an integer value to the command, converting 
+     * 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 
+     * Append a long value to the command, converting
      * the integer into string form.
-     * 
+     *
      * @param value  The value to append.
      */
     public void appendLong(long value) {
@@ -489,22 +501,25 @@
 
 
     /**
-     * Append an atom value to the command.  Atoms are directly 
-     * appended without using literal encodings. 
-     * 
+     * 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) {
-        appendAtom(value.getBytes());
+        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. 
-     * 
+     * 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) {
@@ -519,11 +534,11 @@
 
 
     /**
-     * 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. 
-     * 
+     * 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) {
@@ -535,10 +550,10 @@
     }
 
     /**
-     * Add a literal header to the buffer.  The literal 
-     * header is the literal length enclosed in a 
+     * 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) {
@@ -547,19 +562,19 @@
             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(); 
+            // 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 
+     * 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) {
@@ -572,10 +587,10 @@
     }
 
     /**
-     * Write out a string of literal data, taking into 
-     * account the need to escape both '"' and '\' 
+     * 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) {
@@ -599,10 +614,10 @@
     }
 
     /**
-     * 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. 
+     * 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 {
@@ -614,7 +629,7 @@
     }
 
     /**
-     * Write out the end of the list. 
+     * Write out the end of the list.
      */
     public void endList() {
         try {
@@ -626,9 +641,9 @@
 
 
     /**
-     * Add a whitespace character to the command if the 
-     * previous token was a type that required a 
-     * white space character to mark the boundary. 
+     * 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 {
@@ -646,15 +661,15 @@
     /**
      * 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 
+            // we sometimes get called from the top level
             if (section == null) {
-                appendBodySection(partName); 
+                appendBodySection(partName);
                 return;
             }
 
@@ -674,7 +689,7 @@
     /**
      * 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) {
@@ -758,8 +773,8 @@
         // 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
@@ -966,15 +981,15 @@
 
         // we're going to generate this with parenthetical search keys, even if it is just a simple term.
         appendAtom("OR");
-        startList(); 
+        startList();
         // generated OR argument 1
         appendSearchTerm(terms[0], charset);
-        endList(); 
-        startList(); 
+        endList();
+        startList();
         // generated OR argument 2
         appendSearchTerm(terms[0], charset);
         // and the closing parens
-        endList(); 
+        endList();
     }
 
 
@@ -987,11 +1002,11 @@
     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(); 
+        startList();
         // generated the NOT expression
         appendSearchTerm(term.getTerm(), charset);
         // and the closing parens
-        endList(); 
+        endList();
     }
 
 
@@ -1348,114 +1363,114 @@
 
         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(); 
+        // the fetch profile items are a parenthtical list passed on a
+        // FETCH command.
+        startList();
         if (profile.contains(UIDFolder.FetchProfileItem.UID)) {
-            appendAtom("UID"); 
+            appendAtom("UID");
         }
         if (profile.contains(FetchProfile.Item.ENVELOPE)) {
-            // fetching the envelope involves several items 
-            appendAtom("ENVELOPE"); 
-            appendAtom("INTERNALDATE"); 
-            appendAtom("RFC822.SIZE"); 
+            // fetching the envelope involves several items
+            appendAtom("ENVELOPE");
+            appendAtom("INTERNALDATE");
+            appendAtom("RFC822.SIZE");
         }
         if (profile.contains(FetchProfile.Item.FLAGS)) {
-            appendAtom("FLAGS"); 
+            appendAtom("FLAGS");
         }
         if (profile.contains(FetchProfile.Item.CONTENT_INFO)) {
-            appendAtom("BODYSTRUCTURE"); 
+            appendAtom("BODYSTRUCTURE");
         }
         if (profile.contains(IMAPFolder.FetchProfileItem.SIZE)) {
-            appendAtom("RFC822.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. 
+        // 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]"); 
+            appendAtom("BODY.PEEK[HEADER]");
         }
         else {
-            String[] headers = profile.getHeaderNames(); 
+            String[] headers = profile.getHeaderNames();
             // have an actual list to retrieve?  need to craft this as a sublist
-            // of identified fields. 
+            // of identified fields.
             if (headers.length > 0) {
-                appendAtom("BODY.PEEK[HEADER.FIELDS]"); 
-                startList(); 
+                appendAtom("BODY.PEEK[HEADER.FIELDS]");
+                startList();
                 for (int i = 0; i < headers.length; i++) {
-                    appendAtom(headers[i]); 
+                    appendAtom(headers[i]);
                 }
-                endList(); 
+                endList();
             }
         }
-        // end the list.  
-        endList(); 
+        // end the list.
+        endList();
     }
-    
-    
+
+
     /**
-     * Append an ACL value to a command.  The ACL is the writes string name, 
+     * 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); 
+        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. 
-     * 
+     * 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(); 
-        
+        appendString(acl.getName());
+        String rights = acl.getRights().toString();
+
         if (modifier != null) {
-            rights = modifier + rights; 
+            rights = modifier + rights;
         }
-        appendString(rights); 
+        appendString(rights);
     }
-    
-    
+
+
     /**
-     * Append a quota specification to an IMAP command. 
-     * 
+     * Append a quota specification to an IMAP command.
+     *
      * @param quota  The quota value to append.
      */
     public void appendQuota(Quota quota) {
-        appendString(quota.quotaRoot); 
-        startList(); 
+        appendString(quota.quotaRoot);
+        startList();
         for (int i = 0; i < quota.resources.length; i++) {
-            appendQuotaResource(quota.resources[i]); 
+            appendQuotaResource(quota.resources[i]);
         }
-        endList(); 
+        endList();
     }
-    
+
     /**
-     * Append a Quota.Resource element to an IMAP command.  This converts as 
-     * the resoure name, the usage value and limit value). 
-     * 
+     * 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. 
+        appendAtom(resource.name);
+        // NB:  For command purposes, only the limit is used.
         appendLong(resource.limit);
     }
 }
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
index d84ec69..b8f9186 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
@@ -37,7 +37,7 @@
 
 import javax.mail.Address;
 import javax.mail.AuthenticationFailedException;
-import javax.mail.FetchProfile; 
+import javax.mail.FetchProfile;
 import javax.mail.Flags;
 import javax.mail.Folder;
 import javax.mail.Message;
@@ -52,17 +52,17 @@
 
 import javax.mail.search.SearchTerm;
 
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory; 
+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.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.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.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;
@@ -79,13 +79,13 @@
  * @version $Rev$ $Date$
  */
 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; 
-    
+    // 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;
 
@@ -95,85 +95,85 @@
     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. 
+    // 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; 
+        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; 
-        
+        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.  
+            // we need to ask the server what its capabilities are.  This can be done
+            // before we login.
             getCapability();
-            // do a preauthoriziation check. 
+            // do a preauthoriziation check.
             if (extractResponse("PREAUTH") != null) {
-                preAuthorized = true; 
+                preAuthorized = true;
             }
-            
+
             // make sure we process these now
-            processPendingResponses(); 
+            processPendingResponses();
 
             // if we're not already using an SSL connection, and we have permission to issue STARTTLS, AND
             // the server supports this, then switch to TLS mode before continuing.
             if (!sslConnection && props.getBooleanProperty(MAIL_STARTTLS_ENABLE, false) && hasCapability(CAPABILITY_STARTTLS)) {
                 // if the server supports TLS, then use it for the connection.
                 // on our connection.
-                
+
                 // tell the server of our intention to start a TLS session
                 sendSimpleCommand("STARTTLS");
-                
-                // The connection is then handled by the superclass level. 
+
+                // 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. 
+                // 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. 
+                // and we need to repeat this check.
                 if (extractResponse("PREAUTH") != null) {
-                    preAuthorized = true; 
+                    preAuthorized = true;
                 }
             }
-            
-            // damn, no login required.  
+
+            // damn, no login required.
             if (preAuthorized) {
-                return true; 
+                return true;
             }
-            
-            // go login with the server 
-            return login(); 
+
+            // go login with the server
+            return login();
         } catch (IOException e) {
             if (debug) {
                 debugOut("I/O exception establishing connection", e);
@@ -181,8 +181,8 @@
             throw new MessagingException("Connection error", e);
         }
         finally {
-            // make sure the queue is cleared 
-            processPendingResponses(); 
+            // make sure the queue is cleared
+            processPendingResponses();
         }
     }
 
@@ -220,13 +220,13 @@
         }
         try {
             // say goodbye
-            logout();   
+            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; 
+            // get rid of our response processor too.
+            reader = null;
         }
     }
 
@@ -239,9 +239,9 @@
      */
     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(); 
+        // 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);
 
@@ -263,9 +263,9 @@
      * @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); 
+        // create a command object and issue the command with that.
+        IMAPCommand command = new IMAPCommand(data);
+        sendSimpleCommand(command);
     }
 
 
@@ -283,94 +283,99 @@
      */
     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. 
+        // 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); 
+        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 
+     *
+     * @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(); 
+        // check first
+        checkConnected();
         try {
-            // have the command write the command data.  This also prepends a tag. 
+            // 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(); 
+            // 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 {
-        return sendLine(data.getBytes()); 
+        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); 
+        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. 
+     *
+     * @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(); 
-        
+        // check first
+        checkConnected();
+
         try {
             outputStream.write(data, offset, length);
             outputStream.write(CR);
@@ -378,13 +383,13 @@
             outputStream.flush();
             // update the activity timestamp
             updateLastAccess();
-            return receiveResponse(); 
+            return receiveResponse();
         } catch (IOException e) {
             throw new MessagingException(e.toString(), e);
         }
     }
 
-    
+
     /**
      * Get a reply line for an IMAP command.
      *
@@ -394,80 +399,80 @@
         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). 
+            // 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. 
+                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"); 
+                    throw new InvalidCommandException("Unexpected command IMAP command error");
                 }
                 else if (tagged.isNO()) {
-                    throw new CommandFailedException("Unexpected error executing IMAP command"); 
+                    throw new CommandFailedException("Unexpected error executing IMAP command");
                 }
-                return tagged;                       
+                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); 
+                // 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(); 
+        IMAPCapabilityResponse response = (IMAPCapabilityResponse)extractResponse("CAPABILITY");
+        capabilities = response.getCapabilities();
+        authentications = response.getAuthentications();
     }
 
     /**
-     * Logs out from the server.                                     
+     * Logs out from the server.
      */
     public void logout() throws MessagingException {
-        // We can just send the command and generally ignore the 
-        // status response. 
+        // 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. 
+        // 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 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; 
+            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
@@ -488,17 +493,17 @@
             // 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. 
+
+        // 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(); 
+            return processLogin();
         }
-        
-        throw new MessagingException("No supported LOGIN methods enabled"); 
+
+        throw new MessagingException("No supported LOGIN methods enabled");
     }
 
-    
+
     /**
      * Process SASL-type authentication.
      *
@@ -507,24 +512,24 @@
      * @exception MessagingException
      */
     protected boolean processSaslAuthentication() throws MessagingException {
-        // if unable to get an appropriate authenticator, just fail it. 
-        ClientAuthenticator authenticator = getSaslAuthenticator(); 
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
         if (authenticator == null) {
-            return false; 
+            return false;
         }
-        
+
         // go process the login.
         return processLogin(authenticator);
     }
-    
+
     protected ClientAuthenticator getSaslAuthenticator() {
-        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm); 
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
     }
 
     /**
      * Process SASL-type PLAIN authentication.
      *
-     * @return Returns true if the login is accepted. 
+     * @return Returns true if the login is accepted.
      * @exception MessagingException
      */
     protected boolean processPlainAuthentication() throws MessagingException {
@@ -536,44 +541,44 @@
     /**
      * Process SASL-type LOGIN authentication.
      *
-     * @return Returns true if the login is accepted. 
+     * @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. 
+     * 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 
+        command.appendAtom(username);
+        command.appendAtom(password);
+
+        // go issue the command
         try {
-            sendCommand(command); 
+            sendCommand(command);
         } catch (CommandFailedException e) {
             // we'll get a NO response for a rejected login
-            return false; 
+            return false;
         }
         // seemed to work ok....
-        return true;   
+        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. 
+     *
+     * 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.
@@ -588,7 +593,7 @@
         // and tell the server which mechanism we're using.
         command.appendAtom(authenticator.getMechanismName());
         // send the command now
-        
+
         try {
             IMAPTaggedResponse response = sendCommand(command);
 
@@ -604,19 +609,19 @@
                     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; 
+                    // 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; 
+            // 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.
@@ -627,7 +632,7 @@
         return serverHost;
     }
 
-    
+
     /**
      * Attach a handler for untagged responses to this connection.
      *
@@ -664,7 +669,7 @@
      */
     public void processPendingResponses() throws MessagingException {
         List pendingResponses = null;
-        List handlerList = null; 
+        List handlerList = null;
 
         synchronized(this) {
             if (queuedResponses.isEmpty()) {
@@ -672,172 +677,172 @@
             }
             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(); 
+            // 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); 
+            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; 
+                // 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. 
-     * 
+     * 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. 
+     *
+     * @return A List of all matching queued responses.
      */
     public IMAPUntaggedResponse extractResponse(String type) {
-        Iterator i = queuedResponses.iterator(); 
+        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. 
+            IMAPUntaggedResponse response = (IMAPUntaggedResponse)i.next();
+            // if this is of the target type, move it to the response set.
             if (response.isKeyword(type)) {
-                i.remove(); 
+                i.remove();
                 return response;
             }
         }
-        return null;  
+        return null;
     }
-    
+
     /**
-     * Extract all responses from the pending queue that 
-     * match a give keyword type.  All matching responses 
-     * are removed from the pending queue. 
-     * 
+     * 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. 
+     *
+     * @return A List of all matching queued responses.
      */
     public List extractResponses(String type) {
-        List responses = new ArrayList(); 
-        
-        Iterator i = queuedResponses.iterator(); 
+        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. 
+            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); 
+                i.remove();
+                responses.add(response);
             }
         }
-        return responses; 
+        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. 
-     * 
+     * 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. 
+     *
+     * @return A List of all matching queued responses.
      */
     public List extractFetchResponses(int sequenceNumber) {
-        List responses = new ArrayList(); 
-        
-        Iterator i = queuedResponses.iterator(); 
+        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. 
+            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; 
+                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); 
+                    // pluck these from the list and add to the response set.
+                    i.remove();
+                    responses.add(response);
                 }
             }
         }
-        return responses; 
+        return responses;
     }
-    
+
     /**
-     * Extract a fetch response data item from the queued elements. 
-     * 
+     * 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) 
+    protected IMAPFetchDataItem extractFetchDataItem(long sequenceNumber, int type)
     {
-        Iterator i = queuedResponses.iterator(); 
+        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. 
+            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; 
+                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); 
+                    IMAPFetchDataItem item = fetch.getDataItem(type);
                     if (item != null) {
-                        // remove this from the pending queue and return the 
+                        // remove this from the pending queue and return the
                         // located item
-                        i.remove(); 
-                        return item; 
+                        i.remove();
+                        return item;
                     }
                 }
             }
         }
-        // not located, sorry 
-        return null;       
+        // not located, sorry
+        return null;
     }
-    
+
     /**
-     * Extract a all fetch responses that contain a given data item.  
-     * 
+     * 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.                         
+     *
+     * @return A List of all matching Fetch responses.
      */
-    protected List extractFetchDataItems(int type) 
+    protected List extractFetchDataItems(int type)
     {
-        Iterator i = queuedResponses.iterator(); 
-        List items = new ArrayList(); 
-        
+        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. 
+            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; 
+                IMAPFetchResponse fetch = (IMAPFetchResponse)response;
                 // does this response have the item we're looking for?
-                IMAPFetchDataItem item = fetch.getDataItem(type); 
+                IMAPFetchDataItem item = fetch.getDataItem(type);
                 if (item != null) {
-                    // remove this from the pending queue and return the 
+                    // 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); 
+                    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;      
+        // return whatever we have.
+        return items;
     }
 
     /**
@@ -852,26 +857,26 @@
 
     /**
      * 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; 
+        long lastUsed = System.currentTimeMillis() - lastAccess;
         if (lastUsed < timeout) {
-            return true; 
+            return true;
         }
-        
+
         try {
-            sendSimpleCommand("NOOP"); 
+            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.  
+            // the NOOP command will throw a MessagingException if we get anything
+            // other than an OK response back from the server.
         }
         return false;
     }
@@ -887,17 +892,17 @@
     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();   
-        
+        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); 
+        // 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.
      *
@@ -909,13 +914,13 @@
     public synchronized IMAPBodyStructure fetchBodyStructure(int sequenceNumber) throws MessagingException {
         IMAPCommand command = new IMAPCommand("FETCH");
         command.appendInteger(sequenceNumber);
-        command.startList(); 
-        command.appendAtom("BODYSTRUCTURE"); 
-        command.endList();   
-        
+        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 
+        // locate the response from this
         IMAPBodyStructure bodyStructure = (IMAPBodyStructure)extractFetchDataItem(sequenceNumber, IMAPFetchDataItem.BODYSTRUCTURE);
 
         if (bodyStructure == null) {
@@ -937,11 +942,11 @@
     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();   
-        
+        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);
@@ -965,11 +970,11 @@
     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();   
-        
+        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);
@@ -993,11 +998,11 @@
     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();   
-        
+        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);
@@ -1013,12 +1018,12 @@
     /**
      * 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
@@ -1026,13 +1031,13 @@
     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();   
-        
+        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);
@@ -1043,32 +1048,32 @@
         // and return the body structure directly.
         return body;
     }
-    
-    
+
+
     /**
-     * Fetch the message content.  This sorts out which method should be used 
+     * 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 
+        // 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 
+     * 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
      */
@@ -1101,8 +1106,8 @@
 
         sendCommand(command);
 
-        // pull out the ones we're interested in 
-        return extractResponses("LIST"); 
+        // pull out the ones we're interested in
+        return extractResponses("LIST");
     }
 
 
@@ -1123,8 +1128,8 @@
         command.appendEncodedString(pattern);
 
         sendCommand(command);
-        // pull out the ones we're interested in 
-        return extractResponses("LSUB"); 
+        // pull out the ones we're interested in
+        return extractResponses("LSUB");
     }
 
 
@@ -1234,13 +1239,13 @@
 
         // 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")); 
+        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;
     }
@@ -1275,25 +1280,25 @@
         // 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.  
+        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; 
+            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")); 
+
+        // 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; 
+        return status;
     }
 
 
@@ -1301,17 +1306,17 @@
      * 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. 
+     * 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 
+        // send the message, and make sure we got an OK response
         sendCommand("EXPUNGE");
-        // extract all of the expunged responses and return. 
-        return extractResponses("EXPUNGED"); 
+        // extract all of the expunged responses and return.
+        return extractResponses("EXPUNGED");
     }
 
     public int[] searchMailbox(SearchTerm term) throws MessagingException {
@@ -1369,16 +1374,16 @@
         // 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); 
+        // 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; 
+        // get the list of search responses
+        IMAPSearchResponse hits = (IMAPSearchResponse)extractResponse("SEARCH");
+        // and return the message hits
+        return hits.messageNumbers;
     }
 
 
@@ -1422,29 +1427,29 @@
 
     /**
      * 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.  
+    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; 
+        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
      */
@@ -1461,28 +1466,28 @@
 
         // 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. 
+
+        // 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); 
+        command.appendInteger(sequenceNumber);
         // the command varies depending on whether this is a set or clear operation
         if (set) {
             command.appendAtom("+FLAGS");
@@ -1493,21 +1498,21 @@
 
         // append the flag set
         command.appendFlags(flags);
-        
-        // we want just the flag item here.  
-        sendCommand(command); 
+
+        // 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; 
+        return flagResponse.flags;
     }
 
 
     /**
-     * Copy a range of messages to a target mailbox. 
-     * 
+     * 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 {
@@ -1520,455 +1525,455 @@
         // 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)"); 
+        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.  
+        // 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. 
+        // 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 responses = extractResponses("FETCH");
 
-        // we're looking for a fetch response with a UID data item with the UID information 
-        // inside of it. 
+        // 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. 
+            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; 
+                return item;
             }
-            // not one meant for us, add it back to the pending queue. 
+            // not one meant for us, add it back to the pending queue.
             queuePendingResponse(response);
         }
-        // didn't find this one 
-        return null; 
+        // didn't find this one
+        return null;
     }
-    
-    
+
+
     /**
-     * Fetch the message numbers for a consequetive range 
+     * 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.  
+     *
+     * @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. 
+        // 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. 
+        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)"); 
+        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.  
+        // 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. 
+        // 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 responses = extractResponses("FETCH");
 
-        List uids = new ArrayList((int)(end - start + 1)); 
+        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. 
+        // 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. 
+            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); 
+                uids.add(item);
             }
             else {
-                // not one meant for us, add it back to the pending queue. 
+                // not one meant for us, add it back to the pending queue.
                 queuePendingResponse(response);
             }
         }
-        // return the list of uids we located. 
-        return uids; 
+        // 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)"); 
+        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. 
+        // 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); 
+        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 
+     *
+     * @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 no namespace capability, then return an empty
+        // response, which will trigger the default behavior.
         if (!hasCapability("NAMESPACE")) {
-            return new IMAPNamespaceResponse(); 
+            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"); 
+        // 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. 
-     * 
+     * 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. 
+     *
+     * @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"); 
+        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 
+     * 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); 
+
+        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"); 
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
         }
         IMAPCommand command = new IMAPCommand("SETACL");
         command.appendEncodedString(mailbox);
-        
-        command.appendACL(acl, "+"); 
-        
-        sendSimpleCommand(command); 
+
+        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"); 
+            throw new MethodNotSupportedException("ACL not available from this IMAP server");
         }
         IMAPCommand command = new IMAPCommand("SETACL");
         command.appendEncodedString(mailbox);
-        
-        command.appendACL(acl, "-"); 
-        
-        sendSimpleCommand(command); 
+
+        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 
+     *
+     * @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"); 
+            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; 
+
+        // 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. 
-     * 
+     * Get the current user's ACL rights to a given mailbox.
+     *
      * @param mailbox The target mailbox.
-     * 
-     * @return The Rights associated with this 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"); 
+            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; 
+
+        // 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 
+     * 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. 
+     *
+     * @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"); 
+            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; 
+        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. 
-     * 
+     * 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"); 
+            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); 
+        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"); 
+            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()]; 
+
+        // 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; 
+            IMAPQuotaResponse q = (IMAPQuotaResponse)responses.get(i);
+            quotas[i] = q.quota;
         }
-        
-        return quotas; 
+
+        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"); 
+            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()]; 
+
+        // 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; 
+            IMAPQuotaResponse q = (IMAPQuotaResponse)responses.get(i);
+            quotas[i] = q.quota;
         }
-        
-        return quotas; 
+
+        return quotas;
     }
-    
+
     /**
-     * Set a Quota item for the currently accessed 
-     * userid/folder resource. 
-     * 
+     * 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"); 
+            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"); 
+        // 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. 
-     * 
+     * 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. 
+     *
+     * @return true if this capability is in the list, false for a mismatch.
      */
     public boolean hasCapability(String capability) {
         if (capabilities == null) {
-            return false; 
+            return false;
         }
-        return capabilities.containsKey(capability); 
+        return capabilities.containsKey(capability);
     }
-    
+
     /**
-     * Tag this connection as having been closed by the 
-     * server.  This will not be returned to the 
-     * connection pool. 
+     * 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; 
+        return closed;
     }
 }
 
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
index 0c2e458..cd28d54 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
@@ -18,6 +18,7 @@
 package org.apache.geronimo.javamail.store.imap.connection;
 
 import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
 
 /**
  * Simple extension to the ByteArrayOutputStream to allow inspection
@@ -120,11 +121,14 @@
                 return -1;
             }
 
-            String lenString = new String(buf, literalStart + 1, size() - (literalStart + 2));
             try {
-                return Integer.parseInt(lenString);
-            } catch (NumberFormatException e) {
-                e.printStackTrace(); 
+                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
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
index 9c8e365..26c787f 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
@@ -20,62 +20,63 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.mail.MessagingException; 
-import javax.mail.event.FolderEvent; 
+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;   
-    
+    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; 
+    // 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 we can't read any more, that's an EOF condition.
         if (!fillBufferIfNeeded()) {
-            return -1; 
+            return -1;
         }
-        // just grab the next character 
-        return buffer[position++]; 
+        // 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.  
+            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); 
+                readLength = in.read(buffer, 0, buffer.length);
             }
-            // we may have hit the EOF.  Indicate the read failure   
+            // we may have hit the EOF.  Indicate the read failure
             if (readLength == -1) {
-                return false; 
+                return false;
             }
-            // set our new buffer positions. 
-            position = 0; 
-            length = readLength; 
+            // set our new buffer positions.
+            position = 0;
+            length = readLength;
         }
-        return true; 
+        return true;
     }
 
 
@@ -86,180 +87,180 @@
      * @return A parsed IMAPResponse item using the response data.
      * @exception MessagingException
      */
-    public IMAPResponse readResponse() throws MessagingException  
-      {  
-        // reset our accumulator 
-        out.reset(); 
+    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. 
+
+        int type = token.getType();
+
+        // a continuation response.  This will terminate a response set.
         if (type == Token.CONTINUATION) {
-            return new IMAPContinuationResponse(data); 
+            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. 
+        // 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 
+            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. 
+                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 IMAPFetchResponse(size, data, tokenizer);
                 }
-                return new IMAPSizeResponse(keyword, size, data); 
+                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. 
+
+            // 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) {
-                throw new MessagingException("Unknown server response: " + new String(data)); 
+                throw new MessagingException("Unknown server response: " + new String(data, Charset.forName("ISO8859-1")));
             }
-            
-            String keyword = token.getValue(); 
-            // many response are in the form "* OK [keyword value] message". 
+
+            String keyword = token.getValue();
+            // many response are in the form "* OK [keyword value] message".
             if (keyword.equals("OK")) {
-                return parseUntaggedOkResponse(data, tokenizer); 
+                return parseUntaggedOkResponse(data, tokenizer);
             }
-            // preauth status response 
+            // preauth status response
             else if (keyword.equals("PREAUTH")) {
-                return new IMAPServerStatusResponse("PREAUTH", tokenizer.getRemainder(), data); 
+                return new IMAPServerStatusResponse("PREAUTH", tokenizer.getRemainder(), data);
             }
-            // preauth status response 
+            // preauth status response
             else if (keyword.equals("BYE")) {
-                return new IMAPServerStatusResponse("BYE", tokenizer.getRemainder(), data); 
+                return new IMAPServerStatusResponse("BYE", tokenizer.getRemainder(), data);
             }
             else if (keyword.equals("BAD")) {
-                // these are generally ignored. 
-                return new IMAPServerStatusResponse("BAD", tokenizer.getRemainder(), data); 
+                // 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); 
+                // these are generally ignored.
+                return new IMAPServerStatusResponse("NO", tokenizer.getRemainder(), data);
             }
-            // a complex CAPABILITY response 
+            // a complex CAPABILITY response
             else if (keyword.equals("CAPABILITY")) {
-                return new IMAPCapabilityResponse(tokenizer, data); 
+                return new IMAPCapabilityResponse(tokenizer, data);
             }
-            // a complex LIST response 
+            // a complex LIST response
             else if (keyword.equals("LIST")) {
-                return new IMAPListResponse("LIST", data, tokenizer); 
+                return new IMAPListResponse("LIST", data, tokenizer);
             }
-            // a complex FLAGS response 
+            // a complex FLAGS response
             else if (keyword.equals("FLAGS")) {
-                // parse this into a flags set. 
-                return new IMAPFlagsResponse(data, tokenizer); 
+                // 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); 
+                return new IMAPListResponse("LSUB", data, tokenizer);
             }
-            // a STATUS response, which will contain a list of elements 
+            // a STATUS response, which will contain a list of elements
             else if (keyword.equals("STATUS")) {
-                return new IMAPStatusResponse(data, tokenizer); 
+                return new IMAPStatusResponse(data, tokenizer);
             }
-            // SEARCH requests return an variable length list of message matches. 
+            // SEARCH requests return an variable length list of message matches.
             else if (keyword.equals("SEARCH")) {
-                return new IMAPSearchResponse(data, tokenizer); 
+                return new IMAPSearchResponse(data, tokenizer);
             }
-            // ACL requests return an variable length list of ACL values . 
+            // ACL requests return an variable length list of ACL values .
             else if (keyword.equals("ACL")) {
-                return new IMAPACLResponse(data, tokenizer); 
+                return new IMAPACLResponse(data, tokenizer);
             }
-            // LISTRIGHTS requests return a variable length list of RIGHTS values . 
+            // LISTRIGHTS requests return a variable length list of RIGHTS values .
             else if (keyword.equals("LISTRIGHTS")) {
-                return new IMAPListRightsResponse(data, tokenizer); 
+                return new IMAPListRightsResponse(data, tokenizer);
             }
-            // MYRIGHTS requests return a list of user rights for a mailbox name. 
+            // MYRIGHTS requests return a list of user rights for a mailbox name.
             else if (keyword.equals("MYRIGHTS")) {
-                return new IMAPMyRightsResponse(data, tokenizer); 
+                return new IMAPMyRightsResponse(data, tokenizer);
             }
-            // QUOTAROOT requests return a list of mailbox quota root names  
+            // QUOTAROOT requests return a list of mailbox quota root names
             else if (keyword.equals("QUOTAROOT")) {
-                return new IMAPQuotaRootResponse(data, tokenizer); 
+                return new IMAPQuotaRootResponse(data, tokenizer);
             }
-            // QUOTA requests return a list of quota values for a root name  
+            // QUOTA requests return a list of quota values for a root name
             else if (keyword.equals("QUOTA")) {
-                return new IMAPQuotaResponse(data, tokenizer); 
+                return new IMAPQuotaResponse(data, tokenizer);
             }
             else if (keyword.equals("NAMESPACE")) {
-                return new IMAPNamespaceResponse(data, tokenizer); 
+                return new IMAPNamespaceResponse(data, tokenizer);
             }
         }
-        // begins with a word, this should be the tagged response from the last command. 
+        // 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(); 
-            // primary information in one of these is the status field, which hopefully 
+            String tag = token.getValue();
+            token = tokenizer.next();
+            String status = token.getValue();
+            // primary information in one of these is the status field, which hopefully
             // is 'OK'
-            return new IMAPTaggedResponse(tag, status, tokenizer.getRemainder(), data); 
+            return new IMAPTaggedResponse(tag, status, tokenizer.getRemainder(), data);
         }
-        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); 
+        throw new MessagingException("Unknown server response: " + new String(data, Charset.forName("ISO8859-1")));
     }
 
-    
+    /**
+     * 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.
@@ -322,7 +323,7 @@
         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;
@@ -341,11 +342,11 @@
                 // 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; 
+                    int read = -1;
                     try {
                         read = in.read(bytes, offset, length);
                     } catch (IOException e) {
-                        throw new MessagingException("Unexpected read error on server connection", e); 
+                        throw new MessagingException("Unexpected read error on server connection", e);
                     }
                     // premature EOF we can't ignore.
                     if (read == -1) {
@@ -362,7 +363,7 @@
             // additional literals).  Just recurse on the line reading logic.
             readBuffer();
         } catch (IOException e) {
-            e.printStackTrace(); 
+            e.printStackTrace();
             // this is a byte array output stream...should never happen
         }
     }
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
index 8bafb2b..7641344 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
@@ -19,6 +19,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -186,7 +187,7 @@
             return "";
         }
 
-        return new String(response, pos, response.length - pos);
+        return new String(response, pos, response.length - pos, Charset.forName("ISO8859-1"));
     }
 
 
@@ -236,7 +237,7 @@
         }
 
         // Numeric tokens we store as a different type.
-        String value = new String(response, start, pos - start);
+        String value = new String(response, start, pos - start, Charset.forName("ISO8859-1"));
         try {
             int intValue = Integer.parseInt(value);
             return new Token(Token.NUMERIC, value);
@@ -376,7 +377,7 @@
      */
     private Token readQuotedString() throws MessagingException {
 
-        String value = new String(readQuotedStringData());
+        String value = new String(readQuotedStringData(), Charset.forName("ISO8859-1"));
         return new Token(Token.QUOTEDSTRING, value);
     }
 
@@ -428,7 +429,7 @@
      * @exception ResponseFormatException
      */
     protected Token readLiteral() throws MessagingException {
-        String value = new String(readLiteralData());
+        String value = new String(readLiteralData(), Charset.forName("ISO8859-1"));
         return new Token(Token.LITERAL, value);
     }
 
@@ -480,7 +481,7 @@
      * @return A String extracted from the buffer.
      */
     protected String substring(int start, int end ) {
-        return new String(response, start, end - start);
+        return new String(response, start, end - start, Charset.forName("ISO8859-1"));
     }
 
 
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
index 0b12a09..0721840 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
@@ -22,6 +22,7 @@
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
@@ -35,48 +36,48 @@
 import javax.mail.MessagingException;
 import javax.mail.internet.InternetHeaders;
 
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory; 
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
 import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-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.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.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.  
+ * Simple implementation of POP3 transport.
  *
  * @version $Rev$ $Date$
  */
 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_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"; 
-    
-    // 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; 
+    static final protected String MAIL_FORGET_TOP = "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 conneciton 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 
+    // indicates whether this conneciton 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; 
+    protected boolean topDisabled = false;
 
     /**
      * Normal constructor for an POP3Connection() object.
@@ -95,40 +96,40 @@
      */
     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); 
+
+        // 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);
     }
 
-                          
+
     /**
      * 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; 
-        
+        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(); 
+            // consume the welcome line
+            getWelcome();
 
-            // go login with the server 
-            if (login())  
+            // go login with the server
+            if (login())
             {
-                loggedIn = true; 
+                loggedIn = true;
                 return true;
             }
-            return false; 
+            return false;
         } catch (IOException e) {
             if (debug) {
                 debugOut("I/O exception establishing connection", e);
@@ -147,23 +148,25 @@
     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(); 
+            // 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); 
+            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 
-        reader = new BufferedReader(new InputStreamReader(inputStream));
-        writer = new PrintWriter(new BufferedOutputStream(outputStream));
+
+        // 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.
+        Charset iso88591 = Charset.forName("ISO8859-1");
+        reader = new BufferedReader(new InputStreamReader(inputStream, iso88591));
+        writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), iso88591));
     }
-    
+
     protected void getWelcome() throws IOException {
-        // just read the line and consume it.  If debug is 
+        // just read the line and consume it.  If debug is
         // enabled, there I/O stream will be traced
-        greeting = reader.readLine(); 
+        greeting = reader.readLine();
     }
 
     public String toString() {
@@ -184,70 +187,70 @@
         }
         try {
             // say goodbye
-            logout();   
+            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; 
+            // 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. 
+     * 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; 
+        return closed;
     }
-    
+
     protected POP3Response sendCommand(String cmd) throws MessagingException {
-        return sendCommand(cmd, false); 
+        return sendCommand(cmd, false);
     }
-    
+
     protected POP3Response sendMultiLineCommand(String cmd) throws MessagingException {
-        return sendCommand(cmd, true); 
+        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.  
+                // 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.write("\r\n");
                 writer.flush();
-                
-                POP3Response response = buildResponse(multiLine); 
+
+                POP3Response response = buildResponse(multiLine);
                 if (response.isError()) {
-                    throw new CommandFailedException("Error issuing POP3 command: " + cmd); 
+                    throw new CommandFailedException("Error issuing POP3 command: " + cmd);
                 }
-                return response; 
+                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. 
+     *
+     * @return A POP3Response item with all of the command response data.
      * @exception MessagingException
      */
     protected POP3Response buildResponse(boolean isMultiLineResponse) throws MessagingException {
@@ -255,18 +258,18 @@
         byte[] data = null;
 
         String line;
-        MIMEInputReader source = new MIMEInputReader(reader); 
-        
+        MIMEInputReader source = new MIMEInputReader(reader);
+
         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);
@@ -297,314 +300,314 @@
      */
     private byte[] getMultiLineResponse() throws MessagingException {
 
-        MIMEInputReader source = new MIMEInputReader(reader); 
-        
+        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. 
-        OutputStreamWriter outWriter = new OutputStreamWriter(out); 
-        char buffer[] = new char[500]; 
+
+        // 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.
+        OutputStreamWriter outWriter = new OutputStreamWriter(out);
+        char buffer[] = new char[500];
         try {
             int charsRead = -1;
             while ((charsRead = source.read(buffer)) >= 0) {
                 outWriter.write(buffer, 0, charsRead);
             }
-            outWriter.flush(); 
+            outWriter.flush();
         } catch (IOException e) {
             throw new MessagingException("Error processing a multi-line response", e);
         }
-        
+
         return out.toByteArray();
     }
-    
-    
+
+
     /**
-     * Retrieve the raw message content from the POP3 
-     * server.  This is all of the message data, including 
-     * the header. 
-     * 
+     * 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. 
+     *
+     * @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();          
+        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 
+     * 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 
+     *
+     * @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. 
+        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); 
+            msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
         }
         else {
-            msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0"); 
+            msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0");
         }
-        
-        // just load the returned message data as a set of headers 
+
+        // 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. 
-     * 
+     * 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(); 
+        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. 
+     *
+     * @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")); 
+        // 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. 
+     *
+     * @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(); 
+        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); 
+        // just issue the command...we ignore the command response
+        sendCommand("DELE " + sequenceNumber);
     }
-    
+
     /**
-     * Logout from the mail server.  This sends a QUIT 
+     * 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; 
+            return;
         }
-        // just issue the command...we ignore the command response 
-        sendCommand("QUIT"); 
-        loggedIn = false; 
+        // just issue the command...we ignore the command response
+        sendCommand("QUIT");
+        loggedIn = false;
     }
-    
+
     /**
-     * Perform a reset on the mail server.                   
-     * 
+     * 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. 
+        // 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"); 
+            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. 
+     * 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"); 
+        // 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. 
+     * 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(); 
+                // go do the SASL thing
+                return processSaslAuthentication();
             } catch (MessagingException e) {
-                // Any error here means fall back to the next mechanism 
+                // Any error here means fall back to the next mechanism
             }
         }
-        
+
         if (apopEnabled) {
             try {
-                // go do the SASL thing 
-                return processAPOPAuthentication(); 
+                // go do the SASL thing
+                return processAPOPAuthentication();
             } catch (MessagingException e) {
-                // Any error here means fall back to the next mechanism 
+                // Any error here means fall back to the next mechanism
             }
         }
-        
+
         try {
-            // do the tried and true login processing. 
-            return processLogin(); 
+            // do the tried and true login processing.
+            return processLogin();
         } catch (MessagingException e) {
         }
-        // everything failed...can't get in 
-        return false; 
+        // 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. 
+     * 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  
+        // start by sending the USER command, followed by
         // the PASS command
-        sendCommand("USER " + username); 
-        sendCommand("PASS " + password); 
-        return true;       // we're in 
+        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. 
+     * 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 
+        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"); 
+            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; 
-        
+        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")); 
+            // 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); 
+            // 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 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 + " " + Hex.encode(digest)); 
-        // no exception, we must have passed 
-        return true; 
+        sendCommand("APOP " + username + " " + 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 unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
         if (authenticator == null) {
-            throw new MessagingException("Unable to obtain SASL authenticator"); 
+            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 
+     * 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); 
+        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. 
+     *
+     * 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.
@@ -615,41 +618,44 @@
             debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
         }
 
-        POP3Response response = sendCommand("AUTH " + 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.     
+        // 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();
-                
-                String responseString = new String(Base64.encode(authenticator.evaluateChallenge(challenge)));
 
-                // have the authenticator evaluate and send back the encoded response.
-                response = sendCommand(responseString);
+                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; 
+                // 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 
+     * 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(); 
+        // just return the set that have been explicity permitted
+        return getSaslMechanisms();
     }
 }
 
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
index de490dc..5b2db9c 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
@@ -20,18 +20,20 @@
 package org.apache.geronimo.javamail.transport.nntp;
 
 import java.io.BufferedReader;
-import java.io.BufferedOutputStream; 
+import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 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.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.StringTokenizer;
@@ -40,17 +42,17 @@
 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.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.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$ $Date$
  */
 public class NNTPConnection extends MailConnection {
@@ -68,53 +70,53 @@
     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; 
-    
+
+    // 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; 
+
+    // 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 
+     *
+     * @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); 
+        super.protocolConnect(host, port, username, password);
         // create socket and connect to server.
         getConnection();
 
         // receive welcoming message
         getWelcome();
-        
-        return true; 
+
+        return true;
     }
 
 
@@ -127,24 +129,26 @@
     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(); 
+            // 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); 
+            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 
-        reader = new BufferedReader(new InputStreamReader(inputStream));
+
+        // 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.
+        Charset iso88591 = Charset.forName("ISO8859-1");
+        reader = new BufferedReader(new InputStreamReader(inputStream, iso88591));
         writer = new PrintWriter(new BufferedOutputStream(outputStream));
     }
-    
+
 
     /**
      * 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 {
@@ -160,16 +164,16 @@
             // 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; 
+            // 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....
@@ -196,32 +200,32 @@
         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
      */
@@ -237,7 +241,7 @@
 
         // get a fresh extension mapping table.
         capabilities = new HashMap();
-        authentications = new ArrayList(); 
+        authentications = new ArrayList();
 
         // get the extension data lines.
         List extensions = reply.getData();
@@ -249,10 +253,10 @@
         }
     }
 
-    
+
     /**
      * 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").
@@ -272,18 +276,18 @@
         // 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 
+        // we need to determine which authentication mechanisms are supported here
         if (extensionName.equals("AUTHINFO")) {
-            StringTokenizer tokenizer = new StringTokenizer(argument); 
-            
+            StringTokenizer tokenizer = new StringTokenizer(argument);
+
             while (tokenizer.hasMoreTokens()) {
-                // we only know how to do USER or SASL 
+                // we only know how to do USER or SASL
                 String mechanism = tokenizer.nextToken().toUpperCase();
                 if (mechanism.equals("SASL")) {
-                    authInfoSaslAllowed = true; 
+                    authInfoSaslAllowed = true;
                 }
                 else if (mechanism.equals("USER")) {
-                    authInfoUserAllowed = true; 
+                    authInfoUserAllowed = true;
                 }
             }
         }
@@ -298,15 +302,15 @@
             }
         }
     }
-    
+
 
     /**
      * 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.
@@ -320,10 +324,10 @@
 
     /**
      * 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.
@@ -333,7 +337,7 @@
         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
@@ -370,9 +374,9 @@
             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();   
+            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) {
@@ -392,13 +396,13 @@
      * 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 {
@@ -412,10 +416,10 @@
     /**
      * 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
      */
@@ -441,10 +445,10 @@
     /**
      * 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
      */
@@ -461,7 +465,7 @@
             throw new MessagingException("no connection");
         }
         try {
-            outputStream.write(data.getBytes());
+            outputStream.write(data.getBytes("ISO8859-1"));
             outputStream.write(CR);
             outputStream.write(LF);
             outputStream.flush();
@@ -472,7 +476,7 @@
 
     /**
      * Get a reply line for an NNTP command.
-     * 
+     *
      * @return An NNTP reply object from the stream.
      */
     public NNTPReply getReply() throws MessagingException {
@@ -482,7 +486,7 @@
 
     /**
      * Retrieve the last response received from the NNTP server.
-     * 
+     *
      * @return The raw response string (including the error code) returned from
      *         the NNTP server.
      */
@@ -496,7 +500,7 @@
     /**
      * 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 {
@@ -515,7 +519,7 @@
         }
     }
 
-    
+
     /**
      * Authenticate with the server, if necessary (or possible).
      */
@@ -539,7 +543,7 @@
     /**
      * 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 {
@@ -553,46 +557,46 @@
         }
     }
 
-    
+
     /**
      * 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 
+        // only do this if permitted
         if (!authInfoSaslAllowed) {
-            return false; 
+            return false;
         }
-        // if unable to get an appropriate authenticator, just fail it. 
-        ClientAuthenticator authenticator = getSaslAuthenticator(); 
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
         if (authenticator == null) {
-            throw new MessagingException("Unable to obtain SASL authenticator"); 
+            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 
+     * 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); 
+        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. 
+     *
+     * 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.
@@ -611,7 +615,10 @@
             command.append(authenticator.getMechanismName());
             command.append(" ");
             // and append the response data
-            command.append(new String(Base64.encode(authenticator.evaluateChallenge(null))));
+            try {
+                command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
+            } catch (UnsupportedEncodingException e) {
+            }
             // send the command now
             sendLine(command.toString());
         }
@@ -650,11 +657,14 @@
                 }
 
                 // we're passed back a challenge value, Base64 encoded.
-                byte[] challenge = Base64.decode(line.getMessage().getBytes());
+                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))));
+                    // 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
@@ -666,17 +676,17 @@
         }
     }
 
-    
+
     /**
      * 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 
+        // only do this if allowed by the server
         if (!authInfoUserAllowed) {
-            return; 
+            return;
         }
         NNTPReply reply = sendAuthCommand("AUTHINFO USER " + username);
         // accepted without a password (uncommon, but allowed), we're done
@@ -694,10 +704,10 @@
         }
     }
 
-    
+
     /**
      * Indicate whether posting is allowed for a given server.
-     * 
+     *
      * @return True if the server allows posting, false if the server is
      *         read-only.
      */
@@ -707,7 +717,7 @@
 
     /**
      * Retrieve the welcome string sent back from the server.
-     * 
+     *
      * @return The server provided welcome string.
      */
     public String getWelcomeString() {
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
index 32f7572..5abe7e9 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPConnection.java
@@ -19,21 +19,16 @@
 
 package org.apache.geronimo.javamail.transport.smtp;
 
-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.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.net.SocketException; 
-import java.util.ArrayList; 
+import java.net.SocketException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.StringTokenizer;
@@ -43,23 +38,23 @@
 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.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.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.MailConnection;
 import org.apache.geronimo.javamail.util.MIMEOutputStream;
-import org.apache.geronimo.javamail.util.ProtocolProperties; 
+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$ $Date$
  */
 public class SMTPConnection extends MailConnection {
@@ -78,15 +73,10 @@
      * 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;
-    
-    // input reader wrapped around the socket input stream 
-    protected BufferedReader reader; 
-    // output writer wrapped around the socket output stream. 
-    protected PrintWriter writer; 
-    
+
     // do we report success after completion of each mail send.
     protected boolean reportSuccess;
     // does the server support transport level security?
@@ -94,34 +84,34 @@
     // is TLS enabled on our part?
     protected boolean useTLS = false;
     // should we use 8BITMIME encoding if supported by the server?
-    protected boolean use8bit = false; 
+    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 for 8bitmime support  
+        // 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 
+     *
+     * @return true if we were able to obtain a connection and
      *         authenticate.
      * @exception MessagingException
      */
@@ -142,22 +132,22 @@
             debugOut("Failing connection for missing authentication information");
             return false;
         }
-        
-        super.protocolConnect(host, port, username, password); 
-        
+
+        super.protocolConnect(host, port, username, password);
+
         try {
             // create socket and connect to server.
             getConnection();
 
             // receive welcoming message
             if (!getWelcome()) {
-                debugOut("Error getting welcome message"); 
+                debugOut("Error getting welcome message");
                 throw new MessagingException("Error in getting welcome msg");
             }
 
             // say hello
             if (!sendHandshake()) {
-                debugOut("Error getting processing handshake message"); 
+                debugOut("Error getting processing handshake message");
                 throw new MessagingException("Error in saying EHLO to server");
             }
 
@@ -170,15 +160,15 @@
             debugOut("I/O exception establishing connection", e);
             throw new MessagingException("Connection error", e);
         }
-        debugOut("Successful connection"); 
+        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 {
@@ -201,14 +191,14 @@
         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. 
+     *
+     * @return True if the command was accepted, false otherwise.
      * @exception MessagingException
      */
     protected boolean sendMailFrom(Message message) throws MessagingException {
@@ -242,7 +232,7 @@
             else {
                 InternetAddress local = InternetAddress.getLocalAddress(session);
                 if (local != null) {
-                    from = local.getAddress(); 
+                    from = local.getAddress();
                 }
             }
         }
@@ -256,32 +246,32 @@
         // 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 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. 
+            // 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. 
+                // 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(); 
+                    // 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 
+
+        // some servers ask for a size estimate on the initial send
         if (supportsExtension("SIZE")) {
-            int estimate = getSizeEstimate(message); 
+            int estimate = getSizeEstimate(message);
             if (estimate > 0) {
-                command.append(" SIZE=" + estimate); 
+                command.append(" SIZE=" + estimate);
             }
         }
 
@@ -342,7 +332,7 @@
                 command.append(" AUTH=");
                 try {
                     // add this encoded
-                    command.append(new String(XText.encode(submitter.getBytes("US-ASCII"))));
+                    command.append(new String(XText.encode(submitter.getBytes("US-ASCII")), "US-ASCII"));
                 } catch (UnsupportedEncodingException e) {
                     throw new MessagingException("Invalid submitter value " + submitter);
                 }
@@ -375,70 +365,70 @@
         // 250 response indicates success.
         return line.getCode() == SMTPReply.COMMAND_ACCEPTED;
     }
-    
-    
+
+
     /**
-     * Check to see if a MIME body part can have its 
+     * 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 
+     * 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. 
-     * 
+     * 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 
+     *
+     * @return true if any conversion was performed, false if
      *         nothing was converted.
      */
     protected boolean convertTransferEncoding(MimePart bodyPart)
     {
-        boolean converted = false; 
+        boolean converted = false;
         try {
-            // if this is a multipart element, apply the conversion rules 
-            // to each of the parts. 
+            // if this is a multipart element, apply the conversion rules
+            // to each of the parts.
             if (bodyPart.isMimeType("multipart/")) {
-                MimeMultipart parts = (MimeMultipart)bodyPart.getContent(); 
+                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)); 
+                    // 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(); 
+                String encoding =  bodyPart.getEncoding();
                 if (encoding != null) {
-                    encoding = encoding.toLowerCase(); 
+                    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. 
+                        // 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.  
+                            // 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"); 
+                            // 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
                         }
                     }
@@ -447,36 +437,36 @@
         } catch (MessagingException e) {
         } catch (IOException e) {
         }
-        return converted; 
+        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 
+        // 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". 
-     * 
+     * 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. 
+     *
+     * @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(); 
-            
+            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.
@@ -495,19 +485,19 @@
 
             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();   
+            // 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 
+            return 0;     // can't get an estimate
         } catch (MessagingException e) {
-            return 0;     // can't get an estimate 
+            return 0;     // can't get an estimate
         }
     }
-    
+
 
     /**
      * Sends the data in the message down the socket. This presumes the server
@@ -544,9 +534,9 @@
             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();   
+            mimeOut.writeSMTPTerminator();
+            // and flush the data to send it along
+            mimeOut.flush();
         } catch (IOException e) {
             throw new MessagingException(e.toString());
         } catch (MessagingException e) {
@@ -573,14 +563,14 @@
      */
     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 
+        // 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. 
+            // just send the command without waiting for a response.
             sendLine("QUIT");
         }
     }
@@ -673,7 +663,7 @@
             throw new MessagingException("no connection");
         }
         try {
-            outputStream.write(data.getBytes());
+            outputStream.write(data.getBytes("ISO8859-1"));
             outputStream.write(CR);
             outputStream.write(LF);
             outputStream.flush();
@@ -700,10 +690,10 @@
     protected SMTPReply getReply() throws MessagingException {
         try {
             lastServerResponse = new SMTPReply(receiveLine());
-            // if the first line we receive is a continuation, continue 
-            // reading lines until we reach the non-continued one. 
+            // 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()); 
+                lastServerResponse.addLine(receiveLine());
             }
         } catch (MalformedSMTPReplyException e) {
             throw new MessagingException(e.toString());
@@ -720,9 +710,9 @@
      *         the SMTP server.
      */
     public SMTPReply getLastServerResponse() {
-        return lastServerResponse; 
+        return lastServerResponse;
     }
-    
+
 
     /**
      * Receives one line from the server. A line is a sequence of bytes
@@ -852,14 +842,14 @@
             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(); 
+
+        debugOut("STARTTLS command accepted");
+
+        // the base class handles the socket switch details
+        super.getConnectedTLSSocket();
     }
 
-    
+
     /**
      * Send the EHLO command to the SMTP server.
      *
@@ -881,11 +871,11 @@
             return false;
         }
 
-        // create a fresh mapping and authentications table 
+        // create a fresh mapping and authentications table
         capabilities = new HashMap();
-        authentications = new ArrayList(); 
+        authentications = new ArrayList();
 
-        List lines = reply.getLines(); 
+        List lines = reply.getLines();
         // process all of the continuation lines
         for (int i = 1; i < lines.size(); i++) {
             // go process the extention
@@ -900,11 +890,11 @@
      * @exception MessagingException
      */
     protected void sendHelo() throws MessagingException {
-        // create a fresh mapping and authentications table 
-        // these will be empty, but it will prevent NPEs 
+        // create a fresh mapping and authentications table
+        // these will be empty, but it will prevent NPEs
         capabilities = new HashMap();
-        authentications = new ArrayList(); 
-        
+        authentications = new ArrayList();
+
         sendLine("HELO " + getLocalHost());
 
         SMTPReply line = getReply();
@@ -927,7 +917,7 @@
         return useTLS;
     }
 
-    
+
     /**
      * Set a new value for the startTLS property.
      *
@@ -938,7 +928,7 @@
         useTLS = start;
     }
 
-    
+
     /**
      * Process an extension string passed back as the EHLP response.
      *
@@ -947,7 +937,7 @@
      *            "NAME arguments").
      */
     protected void processExtension(String extension) {
-        debugOut("Processing extension " + extension); 
+        debugOut("Processing extension " + extension);
         String extensionName = extension.toUpperCase();
         String argument = "";
 
@@ -958,7 +948,7 @@
             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);
 
@@ -989,7 +979,7 @@
         }
     }
 
-    
+
     /**
      * Retrieve any argument information associated with a extension reported
      * back by the server on the EHLO command.
@@ -1007,7 +997,7 @@
         }
         return null;
     }
-    
+
 
     /**
      * Tests whether the target server supports a named extension.
@@ -1023,7 +1013,7 @@
         // this only returns null if we don't have this extension
         return extensionParameter(name) != null;
     }
-    
+
 
     /**
      * Authenticate with the server, if necessary (or possible).
@@ -1043,14 +1033,14 @@
         if (username == null || password == null) {
             return false;
         }
-        
-        // if unable to get an appropriate authenticator, just fail it. 
-        ClientAuthenticator authenticator = getSaslAuthenticator(); 
+
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
         if (authenticator == null) {
-            throw new MessagingException("Unable to obtain SASL authenticator"); 
+            throw new MessagingException("Unable to obtain SASL authenticator");
         }
-        
-        
+
+
         if (debug) {
             debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
         }
@@ -1065,7 +1055,10 @@
             command.append(authenticator.getMechanismName());
             command.append(" ");
             // and append the response data
-            command.append(new String(Base64.encode(authenticator.evaluateChallenge(null))));
+            try {
+                command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
+            } catch (UnsupportedEncodingException e) {
+            }
             // send the command now
             sendLine(command.toString());
         }
@@ -1109,12 +1102,15 @@
                     return false;
                 }
 
-                // we're passed back a challenge value, Base64 encoded.
-                byte[] challenge = Base64.decode(line.getMessage().getBytes());
+                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))));
+                    // 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
@@ -1127,74 +1123,74 @@
             }
         }
     }
-    
-    
+
+
     /**
-     * Attempt to retrieve a SASL authenticator for this 
-     * protocol. 
-     * 
-     * @return A SASL authenticator, or null if a suitable one 
+     * 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); 
+        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 
+     * 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. 
-     * 
+     * 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 
+     *
+     * @return true if this can be transmitted successfully
      *         using 8bit encoding, false if an alternate encoding
      *         will be required.
      */
-    protected boolean isValid8bit(InputStream inStream) { 
+    protected boolean isValid8bit(InputStream inStream) {
         try {
-            int ch;  
-            int lineLength = 0; 
+            int ch;
+            int lineLength = 0;
             while ((ch = inStream.read()) >= 0) {
-                // nulls are decidedly not allowed 
+                // nulls are decidedly not allowed
                 if (ch == 0) {
-                    return false; 
+                    return false;
                 }
-                // start of a CRLF sequence (potentially) 
+                // 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(); 
+                    // 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; 
+                        return false;
                     }
-                    // reset the line length 
-                    lineLength = 0; 
+                    // reset the line length
+                    lineLength = 0;
                 }
                 else {
-                    // a normal character 
-                    lineLength++; 
-                    // make sure the line is not too long 
+                    // a normal character
+                    lineLength++;
+                    // make sure the line is not too long
                     if (lineLength > 998) {
-                        return false; 
+                        return false;
                     }
                 }
-                
+
             }
         } catch (IOException e) {
-            return false;  // can't read this, don't try passing it 
+            return false;  // can't read this, don't try passing it
         }
-        // this converted ok 
-        return true; 
+        // 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
@@ -1299,7 +1295,7 @@
         }
     }
 
-    
+
     /**
      * Reset the server connection after an error.
      *
@@ -1322,14 +1318,14 @@
         lastServerResponse = last;
     }
 
-    
+
     /**
      * Return the current reportSuccess property.
      *
      * @return The current reportSuccess property.
      */
     public boolean getReportSuccess() {
-        return reportSuccess; 
+        return reportSuccess;
     }
 
     /**
@@ -1339,7 +1335,7 @@
      *            The new setting.
      */
     public void setReportSuccess(boolean report) {
-        reportSuccess = report; 
+        reportSuccess = report;
     }
 }
 
diff --git a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
index e172d91..9ef05e7 100644
--- a/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
+++ b/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/test/java/org/apache/geronimo/javamail/store/imap/connection/IMAPBodyStructureTest.java
@@ -31,7 +31,7 @@
         InputStream in = IMAPStoreTest.class.getResourceAsStream("/imap/multipart.bodystructure");
         BufferedReader r = new BufferedReader(new InputStreamReader(in));
         try {
-            IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(r.readLine().getBytes());
+            IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(r.readLine().getBytes("ISO8859-1"));
             IMAPBodyStructure s = new IMAPBodyStructure(tokenizer);
             assertNull(s.disposition.getDisposition());
             assertNull(s.md5Hash);