You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jl...@apache.org on 2020/10/07 15:58:41 UTC

svn commit: r1882306 [8/17] - in /geronimo/javamail/trunk/geronimo-javamail_1.6: ./ geronimo-javamail_1.6_mail/ geronimo-javamail_1.6_mail/src/ geronimo-javamail_1.6_mail/src/site/ geronimo-javamail_1.6_provider/ geronimo-javamail_1.6_provider/src/ ger...

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPConnectionPool.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,589 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.mail.MessagingException; 
+import javax.mail.Session;
+import javax.mail.Store;
+
+import javax.mail.StoreClosedException;
+
+import org.apache.geronimo.javamail.store.imap.IMAPStore; 
+import org.apache.geronimo.javamail.util.ProtocolProperties; 
+
+public class IMAPConnectionPool {
+
+    protected static final String MAIL_PORT = "port";
+    protected static final String MAIL_POOL_SIZE = "connectionpoolsize";
+    protected static final String MAIL_POOL_TIMEOUT = "connectionpooltimeout";
+    protected static final String MAIL_SEPARATE_STORE_CONNECTION = "separatestoreconnection";
+    
+    protected static final String MAIL_SASL_REALM = "sasl.realm"; 
+    protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid"; 
+
+    // 45 seconds, by default.
+    protected static final int DEFAULT_POOL_TIMEOUT = 45000;
+    protected static final String DEFAULT_MAIL_HOST = "localhost";
+    
+    protected static final int MAX_CONNECTION_RETRIES = 3; 
+    protected static final int MAX_POOL_WAIT = 500; 
+
+
+    // Our hosting Store instance
+    protected IMAPStore store;
+    // our Protocol abstraction 
+    protected ProtocolProperties props; 
+    // our list of created connections
+    protected List poolConnections = new ArrayList();
+    // our list of available connections 
+    protected List availableConnections = new ArrayList();
+    
+    // the dedicated Store connection (if we're configured that way)
+    protected IMAPConnection storeConnection = null;
+    
+    // our dedicated Store connection attribute
+    protected boolean dedicatedStoreConnection;
+    // the size of our connection pool (by default, we only keep a single connection in the pool)
+    protected int poolSize = 1;
+    // the connection timeout property
+    protected long poolTimeout;
+    // our debug flag
+    protected boolean debug;
+
+    // the target host
+    protected String host;
+    // the target server port.
+    protected int port;
+    // the username we connect with
+    protected String username;
+    // the authentication password.
+    protected String password;
+    // the SASL realm name 
+    protected String realm; 
+    // the authorization id.  With IMAP, it's possible to 
+    // log on with another's authorization. 
+    protected String authid; 
+    // Turned on when the store is closed for business. 
+    protected boolean closed = false; 
+    // the connection capabilities map
+    protected Map capabilities; 
+
+    /**
+     * Create a connection pool associated with a give IMAPStore instance.  The
+     * connection pool manages handing out connections for both the Store and
+     * Folder and Message usage.
+     * 
+     * Depending on the session properties, the Store may be given a dedicated
+     * connection, or will share connections with the Folders.  Connections may
+     * be requested from either the Store or Folders.  Messages must request
+     * their connections from their hosting Folder, and only one connection is
+     * allowed per folder.
+     * 
+     * @param store  The Store we're creating the pool for.
+     * @param props  The property bundle that defines protocol properties
+     *               that alter the connection behavior.
+     */
+    public IMAPConnectionPool(IMAPStore store, ProtocolProperties props) {
+        this.store = store;
+        this.props = props; 
+
+        // get the pool size.  By default, we just use a single connection that's 
+        // shared among Store and all of the Folders.  Since most apps that use 
+        // javamail tend to be single-threaded, this generally poses no great hardship. 
+        poolSize = props.getIntProperty(MAIL_POOL_SIZE, 1);
+        // get the timeout property.  Default is 45 seconds.
+        poolTimeout = props.getIntProperty(MAIL_POOL_TIMEOUT, DEFAULT_POOL_TIMEOUT);
+        // we can create a dedicated connection over and above the pool set that's 
+        // reserved for the Store instance to use. 
+        dedicatedStoreConnection = props.getBooleanProperty(MAIL_SEPARATE_STORE_CONNECTION, false);
+        // if we have a dedicated pool connection, we allocated that from the pool.  Add this to 
+        // the total pool size so we don't find ourselves stuck if the pool size is 1. 
+        if (dedicatedStoreConnection) {
+            poolSize++; 
+        }
+    }
+
+
+    /**
+     * Manage the initial connection to the IMAP server.  This is the first 
+     * point where we obtain the information needed to make an actual server 
+     * connection.  Like the Store protocolConnect method, we return false 
+     * if there's any sort of authentication difficulties. 
+     * 
+     * @param host     The host of the IMAP server.
+     * @param port     The IMAP server connection port.
+     * @param user     The connection user name.
+     * @param password The connection password.
+     * 
+     * @return True if we were able to connect and authenticate correctly. 
+     * @exception MessagingException
+     */
+    public synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
+        // NOTE:  We don't check for the username/password being null at this point.  It's possible that 
+        // the server will send back a PREAUTH response, which means we don't need to go through login 
+        // processing.  We'll need to check the capabilities response after we make the connection to decide 
+        // if logging in is necesssary. 
+        
+        // save this for subsequent connections.  All pool connections will use this info.
+        // if the port is defaulted, then see if we have something configured in the session.
+        // if not configured, we just use the default default.
+        if (port == -1) {
+            // check for a property and fall back on the default if it's not set.
+            port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
+            // it's possible that -1 might have been explicitly set, so one last check. 
+            if (port == -1) {
+                port = props.getDefaultPort(); 
+            }
+        }
+    	
+    	// Before we do anything, let's make sure that we succesfully received a host
+    	if ( host == null ) {
+    		host = DEFAULT_MAIL_HOST;
+    	}
+        
+        this.host = host;
+        this.port = port;
+        this.username = username;
+        this.password = password;
+        
+        // make sure we have the realm information 
+        realm = props.getProperty(MAIL_SASL_REALM); 
+        // get an authzid value, if we have one.  The default is to use the username.
+        authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
+
+        // go create a connection and just add it to the pool.  If there is an authenticaton error, 
+        // return the connect failure, and we may end up trying again. 
+        IMAPConnection connection = createPoolConnection(); 
+        if (connection == null) {
+            return false; 
+        }
+        // save the capabilities map from the first connection. 
+        capabilities = connection.getCapabilities(); 
+        // if we're using a dedicated store connection, remove this from the pool and
+        // reserve it for the store.
+        if (dedicatedStoreConnection)  
+        {  
+            storeConnection = connection;
+            // make sure this is hooked up to the store. 
+            connection.addResponseHandler(store); 
+        }
+        else {
+            // just put this back in the pool.  It's ready for anybody to use now. 
+            synchronized(this) {
+                availableConnections.add(connection); 
+            }
+        }
+        // we're connection, authenticated, and ready to go. 
+        return true; 
+    }
+
+    /**
+     * Creates an authenticated pool connection and adds it to
+     * the connection pool.  If there is an existing connection
+     * already in the pool, this returns without creating a new
+     * connection.
+     *
+     * @exception MessagingException
+     */
+    protected IMAPConnection createPoolConnection() throws MessagingException {
+        IMAPConnection connection = new IMAPConnection(props, this);
+        if (!connection.protocolConnect(host, port, authid, realm, username, password)) {
+            // we only add live connections to the pool.  Sever the connections and 
+            // allow it to go free. 
+            connection.closeServerConnection(); 
+            return null; 
+        }
+        
+        // add this to the master list.  We do NOT add this to the 
+        // available queue because we're handing this out. 
+        synchronized(this) {
+            // uh oh, we closed up shop while we were doing this...clean it up a 
+            // get out of here 
+            if (closed) {
+                connection.close(); 
+                throw new StoreClosedException(store, "No Store connections available"); 
+            }
+            
+            poolConnections.add(connection);
+        }
+        // return that connection 
+        return connection; 
+    }
+
+
+    /**
+     * Get a connection from the pool.  We try to retrieve a live
+     * connection, but we test the connection's liveness before
+     * returning one.  If we don't have a viable connection in
+     * the pool, we'll create a new one.  The returned connection
+     * will be in the authenticated state already.
+     *
+     * @return An IMAPConnection object that is connected to the server.
+     */
+    protected IMAPConnection getConnection() throws MessagingException {
+        int retryCount = 0; 
+        
+        // To keep us from falling into a futile failure loop, we'll only allow 
+        // a set number of connection failures. 
+        while (retryCount < MAX_CONNECTION_RETRIES) {
+            // first try for an already created one.  If this returns 
+            // null, then we'll probably have to make a new one. 
+            IMAPConnection connection = getPoolConnection(); 
+            // cool, we got one, the hard part is done.  
+            if (connection != null) {
+                return connection; 
+            }
+            // ok, create a new one.  This *should* work, but the server might 
+            // have gone down, or other problem may occur. If we have a problem, 
+            // retry the entire process...but only for a bit.  No sense 
+            // being stubborn about it. 
+            connection = createPoolConnection(); 
+            if (connection != null) {
+                return connection; 
+            }
+            // step the retry count 
+            retryCount++; 
+        }
+        
+        throw new MessagingException("Unable to get connection to IMAP server"); 
+    }
+    
+    /**
+     * Obtain a connection from the existing connection pool.  If none are 
+     * available, and we've reached the connection pool limit, we'll wait for 
+     * some other thread to return one.  It generally doesn't take too long, as 
+     * they're usually only held for the time required to execute a single 
+     * command.   If we're not at the pool limit, return null, which will signal 
+     * the caller to go ahead and create a new connection outside of the 
+     * lock. 
+     * 
+     * @return Either an active connection instance, or null if the caller should go 
+     *         ahead and try to create a new connection.
+     * @exception MessagingException
+     */
+    protected synchronized IMAPConnection getPoolConnection() throws MessagingException {
+        // if the pool is closed, we can't process this 
+        if (closed) {
+            throw new StoreClosedException(store, "No Store connections available"); 
+        }
+        
+        // we'll retry this a few times if the connection pool is full, but 
+        // after that, we'll just create a new connection. 
+        for (int i = 0; i < MAX_CONNECTION_RETRIES; i++) {
+            Iterator it = availableConnections.iterator(); 
+            while (it.hasNext()) {
+                IMAPConnection connection = (IMAPConnection)it.next(); 
+                // live or dead, we're going to remove this from the 
+                // available list. 
+                it.remove(); 
+                if (connection.isAlive(poolTimeout)) {
+                    // return the connection to the requestor 
+                    return connection; 
+                }
+                else {
+                    // remove this from the pool...it's toast. 
+                    poolConnections.remove(connection); 
+                    // make sure this cleans up after itself. 
+                    connection.closeServerConnection(); 
+                }
+            }
+
+            // we've not found something usable in the pool.  Now see if 
+            // we're allowed to add another connection, or must just wait for 
+            // someone else to return one. 
+
+            if (poolConnections.size() >= poolSize) {
+                // check to see if we've been told to shutdown before waiting
+                if (closed) {
+                    throw new StoreClosedException(store, "No Store connections available"); 
+                }
+                // we need to wait for somebody to return a connection 
+                // once woken up, we'll spin around and try to snag one from 
+                // the pool again.
+                try {
+                    wait(MAX_POOL_WAIT);
+                } catch (InterruptedException e) {
+                }
+                
+                // check to see if we've been told to shutdown while we waited
+                if (closed) {
+                    throw new StoreClosedException(store, "No Store connections available"); 
+                }
+            }
+            else {
+                // exit out and create a new connection.  Since 
+                // we're going to be outside the synchronized block, it's possible 
+                // we'll go over our pool limit.  We'll take care of that when connections start 
+                // getting returned. 
+                return null; 
+            }
+        }
+        // we've hit the maximum number of retries...just create a new connection. 
+        return null; 
+    }
+    
+    /**
+     * Return a connection to the connection pool.
+     * 
+     * @param connection The connection getting returned.
+     * 
+     * @exception MessagingException
+     */
+    protected void returnPoolConnection(IMAPConnection connection) throws MessagingException
+    {
+        synchronized(this) {
+            // If we're still within the bounds of our connection pool, 
+            // just add this to the active list and send out a notification 
+            // in case somebody else is waiting for the connection. 
+            if (availableConnections.size() < poolSize) {
+                availableConnections.add(connection); 
+                notify(); 
+                return; 
+            }
+            // remove this from the connection pool...we have too many. 
+            poolConnections.remove(connection); 
+        }
+        // the additional cleanup occurs outside the synchronized block 
+        connection.close(); 
+    }
+    
+    /**
+     * Release a closed connection.
+     * 
+     * @param connection The connection getting released.
+     * 
+     * @exception MessagingException
+     */
+    protected void releasePoolConnection(IMAPConnection connection) throws MessagingException
+    {
+        synchronized(this) {
+            // remove this from the connection pool...it's no longer usable. 
+            poolConnections.remove(connection); 
+        }
+        // the additional cleanup occurs outside the synchronized block 
+        connection.close(); 
+    }
+
+
+    /**
+     * Get a connection for the Store.  This will be either a
+     * dedicated connection object, or one from the pool, depending
+     * on the mail.imap.separatestoreconnection property.
+     *
+     * @return An authenticated connection object.
+     */
+    public synchronized IMAPConnection getStoreConnection() throws MessagingException {  
+        if (closed) {
+            throw new StoreClosedException(store, "No Store connections available"); 
+        }
+        // if we have a dedicated connection created, return it.
+        if (storeConnection != null) {
+            return storeConnection;
+        }
+        else {
+            IMAPConnection connection = getConnection();
+            // add the store as a response handler while it has it. 
+            connection.addResponseHandler(store); 
+            return connection; 
+        }
+    }
+
+
+    /**
+     * Return the Store connection to the connection pool.  If we have a dedicated
+     * store connection, this is simple.  Otherwise, the connection goes back 
+     * into the general connection pool.
+     * 
+     * @param connection The connection getting returned.
+     */
+    public synchronized void releaseStoreConnection(IMAPConnection connection) throws MessagingException {
+        // have a server disconnect situation?
+        if (connection.isClosed()) {
+            // we no longer have a dedicated store connection.  
+            // we need to return to the pool from now on. 
+            storeConnection = null; 
+            // throw this away. 
+            releasePoolConnection(connection); 
+        }
+        else {
+            // if we have a dedicated connection, nothing to do really.  Otherwise, 
+            // return this connection to the pool. 
+            if (storeConnection == null) {
+                // unhook the store from the connection. 
+                connection.removeResponseHandler(store); 
+                returnPoolConnection(connection); 
+            }
+        }
+    }
+
+
+    /**
+     * Get a connection for Folder.  
+     *
+     * @return An authenticated connection object.
+     */
+    public IMAPConnection getFolderConnection() throws MessagingException {  
+        // just get a connection from the pool 
+        return getConnection(); 
+    }
+
+
+    /**
+     * Return a Folder connection to the connection pool.  
+     * 
+     * @param connection The connection getting returned.
+     */
+    public void releaseFolderConnection(IMAPConnection connection) throws MessagingException {
+        // potentially, the server may have decided to shut us down.  
+        // In that case, the connection is no longer usable, so we need 
+        // to remove it from the list of available ones. 
+        if (!connection.isClosed()) {
+            // back into the pool with yee, matey....arrggghhh
+            returnPoolConnection(connection); 
+        }
+        else {
+            // can't return this one to the pool.  It's been stomped on 
+            releasePoolConnection(connection); 
+        }
+    }
+    
+    
+    /**
+     * Close the entire connection pool. 
+     * 
+     * @exception MessagingException
+     */
+    public synchronized void close() throws MessagingException {
+        // first close each of the connections.  This also closes the 
+        // store connection. 
+        for (int i = 0; i < poolConnections.size(); i++) {
+            IMAPConnection connection = (IMAPConnection)poolConnections.get(i);
+            connection.close(); 
+        }
+        // clear the pool 
+        poolConnections.clear(); 
+        availableConnections.clear(); 
+        storeConnection = null; 
+        // turn out the lights, hang the closed sign on the wall. 
+        closed = true; 
+    }
+
+
+    /**
+     * Flush any connections from the pool that have not been used
+     * for at least the connection pool timeout interval.
+     */
+    protected synchronized void closeStaleConnections() {
+        Iterator i = poolConnections.iterator();
+
+        while (i.hasNext()) {
+            IMAPConnection connection = (IMAPConnection)i.next();
+            // if this connection is a stale one, remove it from the pool
+            // and close it out.
+            if (connection.isStale(poolTimeout)) {
+                i.remove();
+                try {
+                    connection.close();
+                } catch (MessagingException e) {
+                    // ignored.  we're just closing connections that are probably timed out anyway, so errors
+                    // on those shouldn't have an effect on the real operation we're dealing with.
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Return a connection back to the connection pool.  If we're not
+     * over our limit, the connection is kept around.  Otherwise, it's
+     * given a nice burial.
+     *
+     * @param connection The returned connection.
+     */
+    protected synchronized void releaseConnection(IMAPConnection connection) {
+        // before adding this to the pool, close any stale connections we may
+        // have.  The connection we're adding is quite likely to be a fresh one,
+        // so we should cache that one if we can.
+        closeStaleConnections();
+        // still over the limit?
+        if (poolConnections.size() + 1 > poolSize) {
+            try {
+                // close this out and forget we ever saw it.
+                connection.close();
+            } catch (MessagingException e) {
+                // ignore....this is a non-critical problem if this fails now.
+            }
+        }
+        else {
+            // listen to alerts on this connection, and put it back in the pool.
+            poolConnections.add(connection);
+        }
+    }
+
+    /**
+     * Cleanup time.  Sever and cleanup all of the pool connection
+     * objects, including the special Store connection, if we have one.
+     */
+    protected synchronized void freeAllConnections() {
+        for (int i = 0; i < poolConnections.size(); i++) {
+            IMAPConnection connection = (IMAPConnection)poolConnections.get(i);
+            try {
+                // close this out and forget we ever saw it.
+                connection.close();
+            } catch (MessagingException e) {
+                // ignore....this is a non-critical problem if this fails now.
+            }
+        }
+        // everybody, out of the pool!
+        poolConnections.clear();
+
+        // don't forget the special store connection, if we have one.
+        if (storeConnection != null) {
+            try {
+                // close this out and forget we ever saw it.
+                storeConnection.close();
+            } catch (MessagingException e) {
+                // ignore....this is a non-critical problem if this fails now.
+            }
+            storeConnection = null;
+        }
+    }
+    
+    
+    /**
+     * Test if this connection has a given capability. 
+     * 
+     * @param capability The capability name.
+     * 
+     * @return true if this capability is in the list, false for a mismatch. 
+     */
+    public boolean hasCapability(String capability) {
+        if (capabilities == null) {
+            return false; 
+        }
+        return capabilities.containsKey(capability); 
+    }
+}
+
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPContinuationResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a continuation response from an IMAP server. 
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPContinuationResponse extends IMAPTaggedResponse {
+    /**
+     * Create a continuation object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    protected IMAPContinuationResponse(byte [] response) {
+        super(response); 
+    }
+}
+
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPDateFormat.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Formats ths date as specified by
+ * draft-ietf-drums-msg-fmt-08 dated January 26, 2000
+ * which supercedes RFC822.
+ * <p/>
+ * <p/>
+ * The format used is <code>EEE, d MMM yyyy HH:mm:ss Z</code> and
+ * locale is always US-ASCII.
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPDateFormat extends SimpleDateFormat {
+    public IMAPDateFormat() {
+        super("dd-MMM-yyyy HH:mm:ss Z", Locale.US);
+    }
+    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) {
+        StringBuffer result = super.format(date, buffer, position);
+        // The RFC 2060 requires that the day in the date be formatted with either 2 digits
+        // or one digit.  Our format specifies 2 digits, which pads with leading
+        // zeros.  We need to check for this and whack it if it's there
+        if (result.charAt(0) == '0') {
+            result.deleteCharAt(0); 
+        }
+        return result;
+    }
+
+    /**
+     * The calendar cannot be set
+     * @param calendar
+     * @throws UnsupportedOperationException
+     */
+    public void setCalendar(Calendar calendar) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The format cannot be set
+     * @param format
+     * @throws UnsupportedOperationException
+     */
+    public void setNumberFormat(NumberFormat format) {
+        throw new UnsupportedOperationException();
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPEnvelope.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.Date;
+
+import javax.mail.MessagingException;
+
+import javax.mail.internet.InternetAddress;
+
+
+public class IMAPEnvelope extends IMAPFetchDataItem {
+    // the following are various fields from the FETCH ENVELOPE structure.  These
+    // should be self-explanitory.
+    public Date date;
+    public String subject;
+    public InternetAddress[] from;
+    public InternetAddress[] sender;
+    public InternetAddress[] replyTo;
+    public InternetAddress[] to;
+    public InternetAddress[] cc;
+    public InternetAddress[] bcc;
+
+    public String inReplyTo;
+    public String messageID;
+
+
+    /**
+     * Parse an IMAP FETCH ENVELOPE response into the component pieces.
+     * 
+     * @param source The tokenizer for the response we're processing.
+     */
+    public IMAPEnvelope(IMAPResponseTokenizer source) throws MessagingException {
+        super(ENVELOPE);
+
+        // these should all be a parenthetical list 
+        source.checkLeftParen(); 
+        // the following fields are all positional
+        // The envelope date is defined in the spec as being an "nstring" value, which 
+        // means it is either a string value or NIL.  
+        date = source.readDateOrNil(); 
+        subject = source.readStringOrNil();
+        from = source.readAddressList();
+        sender = source.readAddressList();
+        replyTo = source.readAddressList();
+        to = source.readAddressList();
+        cc = source.readAddressList();
+        bcc = source.readAddressList();
+        inReplyTo = source.readStringOrNil();
+        messageID = source.readStringOrNil();
+
+        // make sure we have a correct close on the field.
+        source.checkRightParen();
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchBodyPart.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+public class IMAPFetchBodyPart extends IMAPFetchDataItem {
+    // the parse body section information. 
+    protected IMAPBodySection section; 
+
+    /**
+     * Construct a base BODY section subpiece.
+     * 
+     * @param type    The fundamental type of the body section.  This will be either BODY, TEXT,
+     *                or HEADER, depending on the subclass.
+     * @param section The section information.  This will contain the section numbering information,
+     *                the section name, and and substring information if this was a partial fetch
+     *                request.
+     */
+    public IMAPFetchBodyPart(int type, IMAPBodySection section) {
+        super(type); 
+        this.section = section; 
+    }
+    
+    /**
+     * Get the part number information associated with this request.
+     * 
+     * @return The string form of the part number. 
+     */
+    public String getPartNumber() {
+        return section.partNumber;
+    }
+    
+    /**
+     * Get the section type information.  This is the qualifier that appears
+     * within the "[]" of the body sections.
+     * 
+     * @return The numeric identifier for the type from the IMAPBodySection.
+     */
+    public int getSectionType() {
+        return section.section; 
+    }
+    
+    /**
+     * Get the substring start location.  
+     * 
+     * @return The start location for the substring.  Returns -1 if this is not a partial 
+     *         fetch.
+     */
+    public int getSubstringStart() {
+        return section.start; 
+    }
+    
+    /**
+     * Returns the length of the substring section.  
+     * 
+     * @return The length of the substring section.  Returns -1 if this was not a partial 
+     *         fetch.
+     */
+    public int getSubstringLength() {
+        return section.length; 
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchDataItem.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.internet.MailDateFormat;
+
+public class IMAPFetchDataItem {
+    public static final int FETCH = 0;
+    public static final int ENVELOPE = 1;
+    public static final int BODY = 2;
+    public static final int BODYSTRUCTURE = 3;
+    public static final int INTERNALDATE = 4;
+    public static final int SIZE = 5;
+    public static final int UID = 6;
+    public static final int TEXT = 7;
+    public static final int HEADER = 8;
+    public static final int FLAGS = 9;
+
+    // the type of the FETCH response item.
+    protected int type;
+
+    public IMAPFetchDataItem(int type) {
+        this.type = type;
+    }
+
+    /**
+     * Get the type of the FetchResponse.
+     *
+     * @return The type indicator.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Test if this fetch response is of the correct type.
+     *
+     * @param t      The type to test against.
+     *
+     * @return True if the Fetch response contains the requested type information.
+     */
+    public boolean isType(int t) {
+        return type == t;
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFetchResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a composite FETCH response from an IMAP server.  The
+ * response may have information about multiple message dataItems.
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPFetchResponse extends IMAPUntaggedResponse {
+    // parsed sections within the FETCH response structure 
+    protected List dataItems = new ArrayList();
+    // the message number to which this applies 
+    public int sequenceNumber; 
+
+    public IMAPFetchResponse(int sequenceNumber, byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("FETCH", data);
+        
+        this.sequenceNumber = sequenceNumber; 
+
+        // fetch responses are a list, even if there is just a single member.
+        source.checkLeftParen();
+
+        // loop until we find the list end.
+        while (source.notListEnd()) {
+            // the response names are coded as ATOMS.  The BODY one's use a special 
+            // syntax, so we need to use the expanded delimiter set to pull this out. 
+            String itemName = source.readAtom(true).toUpperCase();
+
+            if (itemName.equals("ENVELOPE")) {
+                dataItems.add(new IMAPEnvelope(source));
+            }
+            else if (itemName.equals("BODYSTRUCTURE")) {
+                dataItems.add(new IMAPBodyStructure(source));
+            }
+            else if (itemName.equals("FLAGS")) {
+                dataItems.add(new IMAPFlags(source));
+            }
+            else if (itemName.equals("INTERNALDATE")) {
+                dataItems.add(new IMAPInternalDate(source));
+            }
+            else if (itemName.equals("UID")) {
+                dataItems.add(new IMAPUid(sequenceNumber, source));
+            }
+            else if (itemName.equals("RFC822")) {
+                // all of the RFC822 items are of form 
+                // "RFC822.name".  We used the expanded parse above because 
+                // the BODY names include some complicated bits.  If we got one 
+                // of the RFC822 sections, then parse the rest of the name using 
+                // the old rules, which will pull in the rest of the name from the period. 
+                itemName = source.readAtom(false).toUpperCase();
+                if (itemName.equals(".SIZE")) {
+                    dataItems.add(new IMAPMessageSize(source));
+                }
+                else if (itemName.equals(".HEADER")) {
+                    dataItems.add(new IMAPInternetHeader(source.readByteArray()));
+                }
+                else if (itemName.equals(".TEXT")) {
+                    dataItems.add(new IMAPMessageText(source.readByteArray()));
+                }
+            }
+            // this is just the body alone. Specific body segments 
+            // have a more complex naming structure.  Believe it or  
+            // not, 
+            else if (itemName.equals("BODY")) {
+                // time to go parse out the section information from the 
+                // name.  
+                IMAPBodySection section = new IMAPBodySection(source); 
+                
+                switch (section.section) {
+                    case IMAPBodySection.BODY:
+                        // a "full body cast".  Just grab the binary data 
+                        dataItems.add(new IMAPBody(section, source.readByteArray())); 
+                        break; 
+                        
+                    case IMAPBodySection.HEADERS:
+                    case IMAPBodySection.HEADERSUBSET:
+                    case IMAPBodySection.MIME:
+                        // these 3 are all variations of a header request
+                        dataItems.add(new IMAPInternetHeader(section, source.readByteArray())); 
+                        break; 
+                        
+                    case IMAPBodySection.TEXT:
+                        // just the text portion of the body 
+                        // a "full body cast".  Just grab the binary data 
+                        dataItems.add(new IMAPMessageText(section, source.readByteArray())); 
+                        break; 
+                }
+            }
+        }
+        // swallow the terminating right paren
+        source.checkRightParen(); 
+    }
+    
+    /**
+     * Retrieve the sequence number for the FETCH item. 
+     * 
+     * @return The message sequence number this FETCH applies to. 
+     */
+    public int getSequenceNumber() {
+        return sequenceNumber; 
+    }
+
+    /**
+     * Get the section count.
+     *
+     * @return The number of sections in the response.
+     */
+    public int getCount() {
+        return dataItems.size();
+    }
+
+    /**
+     * Get the complete set of response dataItems.
+     *
+     * @return The List of IMAPFetchResponse values.
+     */
+    public List getDataItems() {
+        return dataItems;
+    }
+
+
+    /**
+     * Fetch a particular response type from the response dataItems.
+     *
+     * @param type   The target FETCH type.
+     *
+     * @return The first IMAPFetchDataItem item that matches the response type.
+     */
+    public IMAPFetchDataItem getDataItem(int type) {
+        for (int i = 0; i < dataItems.size(); i ++) {
+            IMAPFetchDataItem item = (IMAPFetchDataItem)dataItems.get(i);
+            if (item.isType(type)) {
+                return item;
+            }
+        }
+        return null;
+    }
+    
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlags.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+import javax.mail.Flags;
+
+
+/**
+ * A fetched FLAGS value returned on a FETCH response.
+ */
+public class IMAPFlags extends IMAPFetchDataItem {
+
+    public Flags flags;
+
+    public IMAPFlags(IMAPResponseTokenizer source) throws MessagingException {
+        super(FLAGS);
+
+        // parse the list of flag values and merge each one into the flag set
+        flags = source.readFlagList(); 
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPFlagsResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+import javax.mail.Flags;
+
+import java.util.List;
+
+/**
+ * A parsed FLAGS untagged response.
+ */
+public class IMAPFlagsResponse extends IMAPUntaggedResponse {
+
+    protected Flags flags = new Flags();
+
+    public IMAPFlagsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("FLAGS", data);
+        
+        // read the flags from the response tokenizer. 
+        flags = source.readFlagList(); 
+    }
+
+    /**
+     * Get the parsed flags value.
+     *
+     * @return The accumulated flags setting.
+     */
+    public Flags getFlags() {
+        return flags;
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternalDate.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.Date;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.util.ResponseFormatException; 
+
+public class IMAPInternalDate extends IMAPFetchDataItem {
+    // the parsed date.
+    protected Date date;
+
+    public IMAPInternalDate(IMAPResponseTokenizer source) throws MessagingException {
+        super(INTERNALDATE);
+        // read the date from the stream 
+        date = source.readDate(); 
+    }
+
+    /**
+     * Retrieved the parsed internal date object.
+     *
+     * @return The parsed Date object.
+     */
+    public Date getDate() {
+        return date;
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPInternetHeader.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayInputStream;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetHeaders; 
+
+public class IMAPInternetHeader extends IMAPFetchBodyPart {
+    // the parsed headers
+    public InternetHeaders headers; 
+    
+    /**
+     * Construct a top-level HEADER data item. 
+     * 
+     * @param data   The data for the InternetHeaders.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPInternetHeader(byte[] data) throws MessagingException {
+        this(new IMAPBodySection(IMAPBodySection.HEADERS), data);
+    }
+    
+
+    /**
+     * Construct a HEADER request data item.
+     * 
+     * @param section  The Section identifier information.
+     * @param data     The raw data for the internet headers.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPInternetHeader(IMAPBodySection section, byte[] data) throws MessagingException {
+        super(HEADER, section);
+        
+        // and convert these into real headers 
+        ByteArrayInputStream in = new ByteArrayInputStream(data); 
+        headers = new InternetHeaders(in); 
+    }
+    
+    /**
+     * Test if this is a complete header fetch, or just a partial list fetch.
+     * 
+     * @return 
+     */
+    public boolean isComplete() {
+        return section.section == IMAPBodySection.HEADERS;
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a list response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class IMAPListResponse extends IMAPUntaggedResponse {
+    // parsed flag responses
+    public boolean noinferiors = false;
+    public boolean noselect = false;
+    public boolean marked = false;
+    public boolean unmarked = false;
+
+    // the name separator character
+    public char separator;
+    // the mail box name
+    public String mailboxName;
+    // this is for support of the get attributes command
+    public String[] attributes;
+
+    /**
+     * Construct a LIST response item.  This can be either 
+     * a response from a LIST command or an LSUB command, 
+     * and will be tagged accordingly.
+     * 
+     * @param type   The type of resonse (LIST or LSUB).
+     * @param data   The raw response data.
+     * @param source The tokenizer source.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPListResponse(String type, byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super(type, data); 
+
+        // parse the list of flag values
+        List flags = source.readSystemNameList(); 
+        
+        // copy this into the attributes array. 
+        attributes = new String[flags.size()]; 
+        attributes = (String[])flags.toArray(attributes); 
+
+        for (int i = 0; i < flags.size(); i++) {
+            String flag = ((String)flags.get(i));
+
+            if (flag.equalsIgnoreCase("\\Marked")) {
+                marked = true;
+            }
+            else if (flag.equalsIgnoreCase("\\Unmarked")) {
+                unmarked = true;
+            }
+            else if (flag.equalsIgnoreCase("\\Noselect")) {
+                noselect = true;
+            }
+            else if (flag.equalsIgnoreCase("\\Noinferiors")) {
+                noinferiors = true;
+            }
+        }
+
+        // set a default sep value 
+        separator = '\0';    
+        // get the separator and name tokens
+        String separatorString = source.readQuotedStringOrNil();
+        if (separatorString != null && separatorString.length() == 1) {
+            separator = separatorString.charAt(0); 
+        }
+        mailboxName = source.readEncodedString();
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPListRightsResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException; 
+
+import org.apache.geronimo.javamail.store.imap.Rights; 
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPListRightsResponse extends IMAPUntaggedResponse {
+    public String mailbox; 
+    public String name; 
+    public Rights[] rights; 
+    
+    public IMAPListRightsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("LISTRIGHTS",  data); 
+        
+        mailbox = source.readEncodedString();
+        name = source.readString(); 
+        List acls = new ArrayList(); 
+        
+        while (source.hasMore()) {
+            acls.add(new Rights(source.readString())); 
+        }
+        
+        rights = new Rights[acls.size()]; 
+        acls.toArray(rights); 
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+/**
+ * Util class to represent a status response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class IMAPMailboxResponse {
+    // count/message number parameter from the response.
+    public int count;
+    // the name of the status code
+    public String name;
+
+    public IMAPMailboxResponse(int count, String name) {
+        this.count = count;
+        this.name = name;
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMailboxStatus.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,188 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
+
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPMailboxStatus {
+    // the set of available flag values for this mailbox
+    public Flags availableFlags = null;
+    // the permanent flags for this mailbox.
+    public Flags permanentFlags = null;
+    // the open mode flags
+    public int mode = Folder.READ_WRITE;
+
+    // number of messages in the box
+    public int messages = -1;
+    // the number of newly added messages
+    public int recentMessages = -1;
+    // the number of unseen messages
+    public int unseenMessages = -1;
+
+    // the next UID for this mailbox
+    public long uidNext = -1L;
+    // the UID validity item
+    public long uidValidity = -1L;
+
+    public IMAPMailboxStatus() {
+    }
+
+
+    /**
+     * Merge information from a server status message.  These
+     * messages are in the form "* NAME args".  We only handle
+     * STATUS and FLAGS messages here.
+     *
+     * @param source The parsed status message.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPStatusResponse source) throws MessagingException {
+        // update any of the values that have changed since the last. 
+        if (source.messages != -1) {
+            messages = source.messages; 
+        }
+        if (source.uidNext != -1L) {
+            uidNext = source.uidNext; 
+        }
+        if (source.uidValidity != -1L) {
+            uidValidity = source.uidValidity; 
+        }
+        if (source.recentMessages != -1) {
+            recentMessages = source.recentMessages; 
+        }
+        if (source.unseenMessages != -1) {
+            unseenMessages = source.unseenMessages; 
+        }
+    }
+    
+    /**
+     * Merge in the FLAGS response from an EXAMINE or 
+     * SELECT mailbox command.
+     * 
+     * @param response The returned FLAGS item.
+     * 
+     * @exception MessagingException
+     */
+    public void mergeFlags(IMAPFlagsResponse response) throws MessagingException {
+        if (response != null) {
+            availableFlags = response.getFlags(); 
+        }
+    }
+    
+    
+    public void mergeSizeResponses(List responses) throws MessagingException  
+      {  
+        for (int i = 0; i < responses.size(); i++) {
+            mergeStatus((IMAPSizeResponse)responses.get(i)); 
+        }
+    }
+    
+    
+    public void mergeOkResponses(List responses) throws MessagingException {
+        for (int i = 0; i < responses.size(); i++) {
+            mergeStatus((IMAPOkResponse)responses.get(i)); 
+        }
+    }
+
+    
+    /**
+     * Gather mailbox status information from mailbox status
+     * messages.  These messages come in as untagged messages in the
+     * form "* nnn NAME".
+     *
+     * @param source The parse message information.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPSizeResponse source) throws MessagingException {
+        if (source != null) {
+            String name = source.getKeyword(); 
+
+            // untagged exists response
+            if (source.isKeyword("EXISTS")) {
+                messages = source.getSize();
+            }
+            // untagged resent response
+            else if (source.isKeyword("RECENT")) {
+                recentMessages = source.getSize();
+            }
+        }
+    }
+
+    
+
+    
+    /**
+     * Gather mailbox status information from mailbox status
+     * messages.  These messages come in as untagged messages in the
+     * form "* OK [NAME args]".
+     *
+     * @param source The parse message information.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPOkResponse source) throws MessagingException {
+        if (source != null) {
+            String name = source.getKeyword(); 
+
+            // untagged UIDVALIDITY response 
+            if (source.isKeyword("UIDVALIDITY")) {
+                List arguments = source.getStatus(); 
+                uidValidity = ((Token)arguments.get(0)).getLong(); 
+            }
+            // untagged UIDNEXT response 
+            if (source.isKeyword("UIDNEXT")) {
+                List arguments = source.getStatus(); 
+                uidNext = ((Token)arguments.get(0)).getLong(); 
+            }
+            // untagged unseen response
+            else if (source.isKeyword("UNSEEN")) {
+                List arguments = source.getStatus(); 
+                uidValidity = ((Token)arguments.get(0)).getInteger(); 
+            }
+        }
+    }
+
+    
+    /**
+     * Gather mailbox status information from mailbox status
+     * messages.  These messages come in as untagged messages in the
+     * form "* OK [NAME args]".
+     *
+     * @param source The parse message information.
+     *
+     * @exception MessagingException
+     */
+    public void mergeStatus(IMAPPermanentFlagsResponse source) throws MessagingException {
+        if (source != null) {
+            // this is already parsed.          
+            permanentFlags = source.flags; 
+        }
+    }
+}

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageSize.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPMessageSize extends IMAPFetchDataItem {
+    // the size information 
+    public int size;         
+
+    public IMAPMessageSize(IMAPResponseTokenizer source) throws MessagingException {
+        super(SIZE);
+
+        // the size is just a single integer 
+        size = source.readInteger();  
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMessageText.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPMessageText extends IMAPFetchBodyPart {
+    // the header data
+    protected byte[] data;
+
+    /**
+     * Construct a top-level TEXT data item. 
+     * 
+     * @param data   The data for the message text.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPMessageText(byte[] data) throws MessagingException {
+        this(new IMAPBodySection(IMAPBodySection.TEXT), data);
+    }
+    
+    
+    public IMAPMessageText(IMAPBodySection section, byte[] data) throws MessagingException {
+        super(TEXT, section);
+        this.data = data; 
+    }
+    
+    /**
+     * Retrieved the header data.
+     *
+     * @return The header data.
+     */
+    public byte[] getContent() {
+        return data;
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPMyRightsResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.Rights;
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPMyRightsResponse extends IMAPUntaggedResponse {
+    public String mailbox; 
+    public Rights rights; 
+    
+    public IMAPMyRightsResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("MYRIGHTS", data); 
+        
+        mailbox = source.readEncodedString();
+        rights = new Rights(source.readString());
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespace.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a NAMESPACE response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class IMAPNamespace {
+    // the namespace prefix 
+    public String prefix; 
+    // the namespace hierarchy delimiter
+    public char separator = '\0'; 
+    
+    public IMAPNamespace(IMAPResponseTokenizer source) throws MessagingException {
+        source.checkLeftParen(); 
+        // read the two that make up the response and ...
+        prefix = source.readString(); 
+        String delim = source.readString(); 
+        // if the delimiter is not a null string, grab the first character. 
+        if (delim.length() != 0) {
+            separator = delim.charAt(0); 
+        }
+        source.checkRightParen(); 
+    }
+}
+

Added: geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java?rev=1882306&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.6/geronimo-javamail_1.6_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPNamespaceResponse.java Wed Oct  7 15:58:39 2020
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+import org.apache.geronimo.javamail.util.ResponseFormatException; 
+
+/**
+ * Util class to represent a NAMESPACE response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class IMAPNamespaceResponse extends IMAPUntaggedResponse {
+    // the personal namespaces defined 
+    public List personalNamespaces; 
+    // the other use name spaces this user has access to. 
+    public List otherUserNamespaces; 
+    // the list of shared namespaces 
+    public List sharedNamespaces; 
+    
+    // construct a default IMAPNamespace response for return when the server doesn't support this. 
+    public IMAPNamespaceResponse() 
+    {
+        super("NAMESPACE", null); 
+        // fill in default lists to simplify processing 
+        personalNamespaces = Collections.EMPTY_LIST; 
+        otherUserNamespaces = Collections.EMPTY_LIST; 
+        sharedNamespaces = Collections.EMPTY_LIST; 
+    }
+
+    /**
+     * Construct a LIST response item.  This can be either 
+     * a response from a LIST command or an LSUB command, 
+     * and will be tagged accordingly.
+     * 
+     * @param type   The type of resonse (LIST or LSUB).
+     * @param data   The raw response data.
+     * @param source The tokenizer source.
+     * 
+     * @exception MessagingException
+     */
+    public IMAPNamespaceResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("NAMESPACE", data); 
+        // the namespace response is a set of 3 items, which will be either NIL or a "list of lists".  
+        // if the item exists, then there will be a set of list parens, with 1 or more subitems inside. 
+        // Each of the subitems will consist of a namespace prefix and the hierarchy delimiter for that 
+        // particular namespace. 
+        personalNamespaces = parseNamespace(source); 
+        otherUserNamespaces = parseNamespace(source); 
+        sharedNamespaces = parseNamespace(source); 
+    }
+    
+    private List parseNamespace(IMAPResponseTokenizer source) throws MessagingException {
+        Token token = source.next(true); 
+        // is this token the NIL token?
+        if (token.getType() == Token.NIL) {
+            // no items at this position. 
+            return null; 
+        }
+        if (token.getType() != '(') {
+            throw new ResponseFormatException("Missing '(' in response");
+        }
+        
+        // ok, we're processing a namespace list.  Create a list and populate it with IMAPNamespace 
+        // items. 
+        
+        List namespaces = new ArrayList(); 
+        
+        while (source.notListEnd()) {
+            namespaces.add(new IMAPNamespace(source)); 
+        }
+        // this should always pass, since it terminated the loop 
+        source.checkRightParen(); 
+        return namespaces; 
+    }
+}