You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ri...@apache.org on 2010/05/19 20:01:55 UTC

svn commit: r946314 [3/5] - in /geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src: main/java/org/apache/geronimo/javamail/authentication/ main/java/org/apache/geronimo/javamail/store/imap/ main/java/org/apache/geronimo/ja...

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java?rev=946314&r1=946313&r2=946314&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnection.java Wed May 19 18:01:55 2010
@@ -37,7 +37,7 @@ import java.util.StringTokenizer;
 
 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.internet.InternetHeade
 
 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 @@ import org.apache.geronimo.mail.util.Bas
  * @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 @@ public class IMAPConnection extends Mail
     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 @@ public class IMAPConnection extends Mail
             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 @@ public class IMAPConnection extends Mail
         }
         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 @@ public class IMAPConnection extends Mail
      */
     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 @@ public class IMAPConnection extends Mail
      * @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 class IMAPConnection extends Mail
      */
     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 @@ public class IMAPConnection extends Mail
             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 @@ public class IMAPConnection extends Mail
         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 @@ public class IMAPConnection extends Mail
             // 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 @@ public class IMAPConnection extends Mail
      * @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 @@ public class IMAPConnection extends Mail
     /**
      * 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 @@ public class IMAPConnection extends Mail
         // 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 @@ public class IMAPConnection extends Mail
                     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 @@ public class IMAPConnection extends Mail
         return serverHost;
     }
 
-    
+
     /**
      * Attach a handler for untagged responses to this connection.
      *
@@ -664,7 +669,7 @@ public class IMAPConnection extends Mail
      */
     public void processPendingResponses() throws MessagingException {
         List pendingResponses = null;
-        List handlerList = null; 
+        List handlerList = null;
 
         synchronized(this) {
             if (queuedResponses.isEmpty()) {
@@ -672,172 +677,172 @@ public class IMAPConnection extends Mail
             }
             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 @@ public class IMAPConnection extends Mail
 
     /**
      * 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 class IMAPConnection extends Mail
     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 class IMAPConnection extends Mail
     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 class IMAPConnection extends Mail
     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 class IMAPConnection extends Mail
     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 class IMAPConnection extends Mail
     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 @@ public class IMAPConnection extends Mail
     /**
      * 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 class IMAPConnection extends Mail
     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 @@ public class IMAPConnection extends Mail
         // 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 @@ public class IMAPConnection extends Mail
 
         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 @@ public class IMAPConnection extends Mail
         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 @@ public class IMAPConnection extends Mail
 
         // 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 @@ public class IMAPConnection extends Mail
         // 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 @@ public class IMAPConnection extends Mail
      * 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 @@ public class IMAPConnection extends Mail
         // 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 @@ public class IMAPConnection extends Mail
 
     /**
      * 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 @@ public class IMAPConnection extends Mail
 
         // 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 @@ public class IMAPConnection extends Mail
 
         // 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 @@ public class IMAPConnection extends Mail
         // 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; 
-    }
-    
-    
-    /**
-     * Delete an ACL item for a given user name from 
-     * a target mailbox. 
-     * 
+        command.appendString(name);
+
+        // now send the GETACL command, which will return a single ACL untagged response.
+        sendCommand(command);
+        // there should be just a single ACL response back from this command.
+        IMAPListRightsResponse response = (IMAPListRightsResponse)extractResponse("LISTRIGHTS");
+        return response.rights;
+    }
+
+
+    /**
+     * Delete an ACL item for a given user name from
+     * a target mailbox.
+     *
      * @param mailbox The mailbox we're altering.
      * @param name    The user name.
-     * 
+     *
      * @exception MessagingException
      */
     public synchronized void deleteACL(String mailbox, String name) throws MessagingException {
         if (!hasCapability("ACL")) {
-            throw new MethodNotSupportedException("ACL not available from this IMAP server"); 
+            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;
     }
 }
 

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java?rev=946314&r1=946313&r2=946314&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseBuffer.java Wed May 19 18:01:55 2010
@@ -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 @@ public class IMAPResponseBuffer extends 
                 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