geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickmcgu...@apache.org
Subject svn commit: r594520 [9/10] - in /geronimo/javamail/trunk/geronimo-javamail_1.4: ./ geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/authentication/ geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/handl...
Date Tue, 13 Nov 2007 12:57:53 GMT
Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.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/IMAPResponseTokenizer.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,1441 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList; 
+import java.util.Date; 
+import java.util.List; 
+
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MailDateFormat;
+import javax.mail.internet.ParameterList;
+
+import org.apache.geronimo.javamail.util.ResponseFormatException; 
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IMAPResponseTokenizer {
+    /*
+     * set up the decoding table.
+     */
+    protected static final byte[] decodingTable = new byte[256];
+
+    protected static void initializeDecodingTable()
+    {
+        for (int i = 0; i < IMAPCommand.encodingTable.length; i++)
+        {
+            decodingTable[IMAPCommand.encodingTable[i]] = (byte)i;
+        }
+    }
+
+
+    static {
+        initializeDecodingTable();
+    }
+    
+    // a singleton formatter for header dates.
+    protected static MailDateFormat dateParser = new MailDateFormat();
+    
+    
+    public static class Token {
+        // Constant values from J2SE 1.4 API Docs (Constant values)
+        public static final int ATOM = -1;
+        public static final int QUOTEDSTRING = -2;
+        public static final int LITERAL = -3;
+        public static final int NUMERIC = -4;
+        public static final int EOF = -5;
+        public static final int NIL = -6;
+        // special single character markers     
+        public static final int CONTINUATION = '-';
+        public static final int UNTAGGED = '*';
+            
+        /**
+         * The type indicator.  This will be either a specific type, represented by 
+         * a negative number, or the actual character value. 
+         */
+        private int type;
+        /**
+         * The String value associated with this token.  All tokens have a String value, 
+         * except for the EOF and NIL tokens. 
+         */
+        private String value;
+
+        public Token(int type, String value) {
+            this.type = type;
+            this.value = value;
+        }
+
+        public int getType() {
+            return type;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public boolean isType(int type) {
+            return this.type == type;
+        }
+
+        /**
+         * Return the token as an integer value.  If this can't convert, an exception is 
+         * thrown. 
+         * 
+         * @return The integer value of the token. 
+         * @exception ResponseFormatException
+         */
+        public int getInteger() throws MessagingException {
+            if (value != null) {
+                try {
+                    return Integer.parseInt(value);
+                } catch (NumberFormatException e) {
+                }
+            }
+
+            throw new ResponseFormatException("Number value expected in response; fount: " + value);
+        }
+
+        /**
+         * Return the token as a long value.  If it can't convert, an exception is 
+         * thrown. 
+         * 
+         * @return The token as a long value. 
+         * @exception ResponseFormatException
+         */
+        public long getLong() throws MessagingException {
+            if (value != null) {
+                try {
+                    return Long.parseLong(value);
+                } catch (NumberFormatException e) {
+                }
+            }
+            throw new ResponseFormatException("Number value expected in response; fount: " + value);
+        }
+        
+        /**
+         * Handy debugging toString() method for token. 
+         * 
+         * @return The string value of the token. 
+         */
+        public String toString() {
+            if (type == NIL) {
+                return "NIL"; 
+            }
+            else if (type == EOF) {
+                return "EOF";
+            }
+            
+            if (value == null) {
+                return ""; 
+            }
+            return value; 
+        }
+    }
+
+    public static final Token EOF = new Token(Token.EOF, null);
+    public static final Token NIL = new Token(Token.NIL, null);
+
+    private static final String WHITE = " \t\n\r";
+    // The list of delimiter characters we process when    
+    // handling parsing of ATOMs.  
+    private static final String atomDelimiters = "(){}%*\"\\" + WHITE;
+    // this set of tokens is a slighly expanded set used for 
+    // specific response parsing.  When dealing with Body 
+    // section names, there are sub pieces to the name delimited 
+    // by "[", "]", ".", "<", ">" and SPACE, so reading these using 
+    // a superset of the ATOM processing makes for easier parsing. 
+    private static final String tokenDelimiters = "<>[].(){}%*\"\\" + WHITE;
+
+    // the response data read from the connection
+    private byte[] response;
+    // current parsing position
+    private int pos;
+
+    public IMAPResponseTokenizer(byte [] response) {
+        this.response = response;
+    }
+
+    /**
+     * Get the remainder of the response as a string.
+     *
+     * @return A string representing the remainder of the response.
+     */
+    public String getRemainder() {
+        // make sure we're still in range
+        if (pos >= response.length) {
+            return "";
+        }
+
+        return new String(response, pos, response.length - pos);
+    }
+    
+    
+    public Token next() throws MessagingException {
+        return next(false);
+    }
+
+    public Token next(boolean nilAllowed) throws MessagingException {
+        return readToken(nilAllowed, false);
+    }
+
+    public Token next(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
+        return readToken(nilAllowed, expandedDelimiters);
+    }
+
+    public Token peek() throws MessagingException {
+        return peek(false, false);
+    }
+
+    public Token peek(boolean nilAllowed) throws MessagingException {
+        return peek(nilAllowed, false);
+    }
+
+    public Token peek(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
+        int start = pos;
+        try {
+            return readToken(nilAllowed, expandedDelimiters);
+        } finally {
+            pos = start;
+        }
+    }
+
+    /**
+     * Read an ATOM token from the parsed response.
+     *
+     * @return A token containing the value of the atom token.
+     */
+    private Token readAtomicToken(String delimiters) {
+        // skip to next delimiter
+        int start = pos;
+        while (++pos < response.length) {
+            // break on the first non-atom character.
+            byte ch = response[pos];
+            if (delimiters.indexOf(response[pos]) != -1 || ch < 32 || ch >= 127) {
+                break;
+            }
+        }
+        
+        // Numeric tokens we store as a different type.  
+        String value = new String(response, start, pos - start); 
+        try {
+            int intValue = Integer.parseInt(value); 
+            return new Token(Token.NUMERIC, value);
+        } catch (NumberFormatException e) {
+        }
+        return new Token(Token.ATOM, value);
+    }
+
+    /**
+     * Read the next token from the response.
+     *
+     * @return The next token from the response.  White space is skipped, and comment
+     *         tokens are also skipped if indicated.
+     * @exception ResponseFormatException
+     */
+    private Token readToken(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
+        String delimiters = expandedDelimiters ? tokenDelimiters : atomDelimiters; 
+        
+        if (pos >= response.length) {
+            return EOF;
+        } else {
+            byte ch = response[pos];
+            if (ch == '\"') {
+                return readQuotedString();
+            // beginning of a length-specified literal?
+            } else if (ch == '{') {
+                return readLiteral();
+            // white space, eat this and find a real token.
+            } else if (WHITE.indexOf(ch) != -1) {
+                eatWhiteSpace();
+                return readToken(nilAllowed, expandedDelimiters);
+            // either a CTL or special.  These characters have a self-defining token type.
+            } else if (ch < 32 || ch >= 127 || delimiters.indexOf(ch) != -1) {
+                pos++;
+                return new Token((int)ch, String.valueOf((char)ch));
+            } else {
+                // start of an atom, parse it off.
+                Token token = readAtomicToken(delimiters);
+                // now, if we've been asked to look at NIL tokens, check to see if it is one,
+                // and return that instead of the ATOM.
+                if (nilAllowed) {
+                    if (token.getValue().equalsIgnoreCase("NIL")) {
+                        return NIL;
+                    }
+                }
+                return token;
+            }
+        }
+    }
+
+    /**
+     * Read the next token from the response, returning it as a byte array value.
+     *
+     * @return The next token from the response.  White space is skipped, and comment
+     *         tokens are also skipped if indicated.
+     * @exception ResponseFormatException
+     */
+    private byte[] readData(boolean nilAllowed) throws MessagingException {
+        if (pos >= response.length) {
+            return null;
+        } else {
+            byte ch = response[pos];
+            if (ch == '\"') {
+                return readQuotedStringData();
+            // beginning of a length-specified literal?
+            } else if (ch == '{') {
+                return readLiteralData();
+            // white space, eat this and find a real token.
+            } else if (WHITE.indexOf(ch) != -1) {
+                eatWhiteSpace();
+                return readData(nilAllowed);
+            // either a CTL or special.  These characters have a self-defining token type.
+            } else if (ch < 32 || ch >= 127 || atomDelimiters.indexOf(ch) != -1) {
+                throw new ResponseFormatException("Invalid string value: " + ch);
+            } else {
+                // only process this if we're allowing NIL as an option.
+                if (nilAllowed) {
+                    // start of an atom, parse it off.
+                    Token token = next(true);
+                    if (token.isType(Token.NIL)) {
+                        return null;
+                    }
+                    // invalid token type.
+                    throw new ResponseFormatException("Invalid string value: " + token.getValue());
+                }
+                // invalid token type.
+                throw new ResponseFormatException("Invalid string value: " + ch);
+            }
+        }
+    }
+
+    /**
+     * Extract a substring from the response string and apply any
+     * escaping/folding rules to the string.
+     *
+     * @param start  The starting offset in the response.
+     * @param end    The response end offset + 1.
+     *
+     * @return The processed string value.
+     * @exception ResponseFormatException
+     */
+    private byte[] getEscapedValue(int start, int end) throws MessagingException {
+        ByteArrayOutputStream value = new ByteArrayOutputStream();
+
+        for (int i = start; i < end; i++) {
+            byte ch = response[i];
+            // is this an escape character?
+            if (ch == '\\') {
+                i++;
+                if (i == end) {
+                    throw new ResponseFormatException("Invalid escape character");
+                }
+                value.write(response[i]);
+            }
+            // line breaks are ignored, except for naked '\n' characters, which are consider
+            // parts of linear whitespace.
+            else if (ch == '\r') {
+                // see if this is a CRLF sequence, and skip the second if it is.
+                if (i < end - 1 && response[i + 1] == '\n') {
+                    i++;
+                }
+            }
+            else {
+                // just append the ch value.
+                value.write(ch);
+            }
+        }
+        return value.toByteArray();
+    }
+
+    /**
+     * Parse out a quoted string from the response, applying escaping
+     * rules to the value.
+     *
+     * @return The QUOTEDSTRING token with the value.
+     * @exception ResponseFormatException
+     */
+    private Token readQuotedString() throws MessagingException {
+
+        String value = new String(readQuotedStringData());
+        return new Token(Token.QUOTEDSTRING, value);
+    }
+
+    /**
+     * Parse out a quoted string from the response, applying escaping
+     * rules to the value.
+     *
+     * @return The byte array with the resulting string bytes.
+     * @exception ResponseFormatException
+     */
+    private byte[] readQuotedStringData() throws MessagingException {
+        int start = pos + 1;
+        boolean requiresEscaping = false;
+
+        // skip to end of comment/string
+        while (++pos < response.length) {
+            byte ch = response[pos];
+            if (ch == '"') {
+                byte[] value;
+                if (requiresEscaping) {
+                    value = getEscapedValue(start, pos);
+                }
+                else {
+                    value = subarray(start, pos);
+                }
+                // step over the delimiter for all cases.
+                pos++;
+                return value;
+            }
+            else if (ch == '\\') {
+                pos++;
+                requiresEscaping = true;
+            }
+            // we need to process line breaks also
+            else if (ch == '\r') {
+                requiresEscaping = true;
+            }
+        }
+
+        throw new ResponseFormatException("Missing '\"'");
+    }
+
+
+    /**
+     * Parse out a literal string from the response, using the length
+     * encoded before the listeral.
+     *
+     * @return The LITERAL token with the value.
+     * @exception ResponseFormatException
+     */
+    protected Token readLiteral() throws MessagingException {
+        String value = new String(readLiteralData());
+        return new Token(Token.LITERAL, value);
+    }
+
+
+    /**
+     * Parse out a literal string from the response, using the length
+     * encoded before the listeral.
+     *
+     * @return The byte[] array with the value.
+     * @exception ResponseFormatException
+     */
+    protected byte[] readLiteralData() throws MessagingException {
+        int lengthStart = pos + 1;
+
+        // see if we have a close marker.
+        int lengthEnd = indexOf("}\r\n", lengthStart);
+        if (lengthEnd == -1) {
+            throw new ResponseFormatException("Missing terminator on literal length");
+        }
+
+        int count = 0;
+        try {
+            count = Integer.parseInt(substring(lengthStart, lengthEnd));
+        } catch (NumberFormatException e) {
+            throw new ResponseFormatException("Invalid literal length " + substring(lengthStart, lengthEnd));
+        }
+        
+        // step over the length
+        pos = lengthEnd + 3;
+
+        // too long?
+        if (pos + count > response.length) {
+            throw new ResponseFormatException("Invalid literal length: " + count);
+        }
+
+        byte[] value = subarray(pos, pos + count);
+        pos += count;
+        
+        return value;
+    }
+
+
+    /**
+     * Extract a substring from the response buffer.
+     *
+     * @param start  The starting offset.
+     * @param end    The end offset (+ 1).
+     *
+     * @return A String extracted from the buffer.
+     */
+    protected String substring(int start, int end ) {
+        return new String(response, start, end - start);
+    }
+
+
+    /**
+     * Extract a subarray from the response buffer.
+     *
+     * @param start  The starting offset.
+     * @param end    The end offset (+ 1).
+     *
+     * @return A byte array string extracted rom the buffer.
+     */
+    protected byte[] subarray(int start, int end ) {
+        byte[] result = new byte[end - start];
+        System.arraycopy(response, start, result, 0, end - start);
+        return result;
+    }
+
+
+    /**
+     * Test if the bytes in the response buffer match a given
+     * string value.
+     *
+     * @param position The compare position.
+     * @param needle   The needle string we're testing for.
+     *
+     * @return True if the bytes match the needle value, false for any
+     *         mismatch.
+     */
+    public boolean match(int position, String needle) {
+        int length = needle.length();
+
+        if (response.length - position < length) {
+            return false;
+        }
+
+        for (int i = 0; i < length; i++) {
+            if (response[position + i ] != needle.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * Search for a given string starting from the current position
+     * cursor.
+     *
+     * @param needle The search string.
+     *
+     * @return The index of a match (in absolute byte position in the
+     *         response buffer).
+     */
+    public int indexOf(String needle) {
+        return indexOf(needle, pos);
+    }
+
+    /**
+     * Search for a string in the response buffer starting from the
+     * indicated position.
+     *
+     * @param needle   The search string.
+     * @param position The starting buffer position.
+     *
+     * @return The index of the match position.  Returns -1 for no match.
+     */
+    public int indexOf(String needle, int position) {
+        // get the last possible match position
+        int last = response.length - needle.length();
+        // no match possible
+        if (last < position) {
+            return -1;
+        }
+
+        for (int i = position; i <= last; i++) {
+            if (match(i, needle)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+
+
+    /**
+     * Skip white space in the token string.
+     */
+    private void eatWhiteSpace() {
+        // skip to end of whitespace
+        while (++pos < response.length
+                && WHITE.indexOf(response[pos]) != -1)
+            ;
+    }
+    
+    
+    /**
+     * Ensure that the next token in the parsed response is a
+     * '(' character.
+     *
+     * @exception ResponseFormatException
+     */
+    public void checkLeftParen() throws MessagingException {
+        Token token = next();
+        if (token.getType() != '(') {
+            throw new ResponseFormatException("Missing '(' in response");
+        }
+    }
+
+
+    /**
+     * Ensure that the next token in the parsed response is a
+     * ')' character.
+     *
+     * @exception ResponseFormatException
+     */
+    public void checkRightParen() throws MessagingException {
+        Token token = next();
+        if (token.getType() != ')') {
+            throw new ResponseFormatException("Missing ')' in response");
+        }
+    }
+
+
+    /**
+     * Read a string-valued token from the response.  A string
+     * valued token can be either a quoted string, a literal value,
+     * or an atom.  Any other token type is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readString() throws MessagingException {
+        Token token = next();
+        int type = token.getType();
+
+        if (type != Token.ATOM && type != Token.QUOTEDSTRING && type != Token.LITERAL && type != Token.NUMERIC) {
+            throw new ResponseFormatException("String token expected in response: " + token.getValue());
+        }
+        return token.getValue();
+    }
+    
+
+    /**
+     * Read an encoded string-valued token from the response.  A string
+     * valued token can be either a quoted string, a literal value,
+     * or an atom.  Any other token type is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readEncodedString() throws MessagingException {
+        String value = readString(); 
+        return decode(value); 
+    }
+
+
+    /**
+     * Decode a Base 64 encoded string value.
+     * 
+     * @param original The original encoded string.
+     * 
+     * @return The decoded string. 
+     * @exception MessagingException
+     */
+    public String decode(String original) throws MessagingException {
+        StringBuffer result = new StringBuffer();
+
+        for (int i = 0; i < original.length(); i++) {
+            char ch = original.charAt(i);
+
+            if (ch == '&') {
+                i = decode(original, i, result);
+            }
+            else {
+                result.append(ch);
+            }
+        }
+
+        return result.toString();
+    }
+
+
+    /**
+     * Decode a section of an encoded string value. 
+     * 
+     * @param original The original source string.
+     * @param index    The current working index.
+     * @param result   The StringBuffer used for the decoded result.
+     * 
+     * @return The new index for the decoding operation. 
+     * @exception MessagingException
+     */
+    public static int decode(String original, int index, StringBuffer result) throws MessagingException {
+        // look for the section terminator
+        int terminator = original.indexOf('-', index);
+
+        // unmatched?
+        if (terminator == -1) {
+            throw new MessagingException("Invalid UTF-7 encoded string");
+        }
+
+        // is this just an escaped "&"?
+        if (terminator == index + 1) {
+            // append and skip over this.
+            result.append('&');
+            return index + 2;
+        }
+
+        // step over the starting char
+        index++;
+
+        int chars = terminator - index;
+        int quads = chars / 4;
+        int residual = chars % 4;
+
+        // buffer for decoded characters
+        byte[] buffer = new byte[4];
+        int bufferCount = 0;
+
+        // process each of the full triplet pairs
+        for (int i = 0; i < quads; i++) {
+            byte b1 = decodingTable[original.charAt(index++) & 0xff];
+            byte b2 = decodingTable[original.charAt(index++) & 0xff];
+            byte b3 = decodingTable[original.charAt(index++) & 0xff];
+            byte b4 = decodingTable[original.charAt(index++) & 0xff];
+
+            buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
+            buffer[bufferCount++] = (byte)((b2 << 4) | (b3 >> 2));
+            buffer[bufferCount++] = (byte)((b3 << 6) | b4);
+
+            // we've written 3 bytes to the buffer, but we might have a residual from a previous
+            // iteration to deal with.
+            if (bufferCount == 4) {
+                // two complete chars here
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                b1 = buffer[2];
+                b2 = buffer[3];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                bufferCount = 0;
+            }
+            else {
+                // we need to save the 3rd byte for the next go around
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                buffer[0] = buffer[2];
+                bufferCount = 1;
+            }
+        }
+
+        // properly encoded, we should have an even number of bytes left.
+
+        switch (residual) {
+            // no residual...so we better not have an extra in the buffer
+            case 0:
+                // this is invalid...we have an odd number of bytes so far,
+                if (bufferCount == 1) {
+                    throw new MessagingException("Invalid UTF-7 encoded string");
+                }
+            // one byte left.  This shouldn't be valid.  We need at least 2 bytes to
+            // encode one unprintable char.
+            case 1:
+                throw new MessagingException("Invalid UTF-7 encoded string");
+
+            // ok, we have two bytes left, which can only encode a single byte.  We must have
+            // a dangling unhandled char.
+            case 2:
+            {
+                if (bufferCount != 1) {
+                    throw new MessagingException("Invalid UTF-7 encoded string");
+                }
+                byte b1 = decodingTable[original.charAt(index++) & 0xff];
+                byte b2 = decodingTable[original.charAt(index++) & 0xff];
+                buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
+
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                break;
+            }
+
+            // we have 2 encoded chars.  In this situation, we can't have a leftover.
+            case 3:
+            {
+                // this is invalid...we have an odd number of bytes so far,
+                if (bufferCount == 1) {
+                    throw new MessagingException("Invalid UTF-7 encoded string");
+                }
+                byte b1 = decodingTable[original.charAt(index++) & 0xff];
+                byte b2 = decodingTable[original.charAt(index++) & 0xff];
+                byte b3 = decodingTable[original.charAt(index++) & 0xff];
+
+                buffer[bufferCount++] = (byte)((b1 << 2) | (b2 >> 4));
+                buffer[bufferCount++] = (byte)((b2 << 4) | (b3 >> 2));
+
+                b1 = buffer[0];
+                b2 = buffer[1];
+                result.append((char)((b1 << 8) + (b2 & 0xff)));
+                break;
+            }
+        }
+
+        // return the new scan location
+        return terminator + 1;
+    }
+
+    /**
+     * Read a string-valued token from the response, verifying this is an ATOM token.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readAtom() throws MessagingException {
+        return readAtom(false); 
+    }
+    
+
+    /**
+     * Read a string-valued token from the response, verifying this is an ATOM token.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readAtom(boolean expandedDelimiters) throws MessagingException {
+        Token token = next(false, expandedDelimiters);
+        int type = token.getType();
+
+        if (type != Token.ATOM) {
+            Thread.currentThread().dumpStack(); 
+            throw new ResponseFormatException("ATOM token expected in response: " + token.getValue());
+        }
+        return token.getValue();
+    }
+
+
+    /**
+     * Read a number-valued token from the response.  This must be an ATOM
+     * token.
+     *
+     * @return The integer value of the source token.
+     * @exception ResponseFormatException
+     */
+    public int readInteger() throws MessagingException {
+        Token token = next();
+        return token.getInteger(); 
+    }
+
+
+    /**
+     * Read a number-valued token from the response.  This must be an ATOM
+     * token.
+     *
+     * @return The long value of the source token.
+     * @exception ResponseFormatException
+     */
+    public int readLong() throws MessagingException {
+        Token token = next();
+        return token.getInteger(); 
+    }
+
+
+    /**
+     * Read a string-valued token from the response.  A string
+     * valued token can be either a quoted string, a literal value,
+     * or an atom.  Any other token type is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    public String readStringOrNil() throws MessagingException {
+        // we need to recognize the NIL token.
+        Token token = next(true);
+        int type = token.getType();
+
+        if (type != Token.ATOM && type != Token.QUOTEDSTRING && type != Token.LITERAL && type != Token.NIL) {
+            throw new ResponseFormatException("String token or NIL expected in response: " + token.getValue());
+        }
+        // this returns null if the token is the NIL token.
+        return token.getValue();
+    }
+
+
+    /**
+     * Read a quoted string-valued token from the response.
+     * Any other token type other than NIL is an error.
+     *
+     * @return The string value of the source token.
+     * @exception ResponseFormatException
+     */
+    protected String readQuotedStringOrNil() throws MessagingException {
+        // we need to recognize the NIL token.
+        Token token = next(true);
+        int type = token.getType();
+
+        if (type != Token.QUOTEDSTRING && type != Token.NIL) {
+            throw new ResponseFormatException("String token or NIL expected in response");
+        }
+        // this returns null if the token is the NIL token.
+        return token.getValue();
+    }
+
+
+    /**
+     * Read a date from a response string.  This is expected to be in
+     * Internet Date format, but there's a lot of variation implemented
+     * out there.  If we're unable to format this correctly, we'll
+     * just return null.
+     *
+     * @return A Date object created from the source date.
+     */
+    public Date readDate() throws MessagingException {
+        String value = readString();
+
+        try {
+            return dateParser.parse(value);
+        } catch (Exception e) {
+            // we're just skipping over this, so return null
+            return null;
+        }
+    }
+
+
+    /**
+     * Read a date from a response string.  This is expected to be in
+     * Internet Date format, but there's a lot of variation implemented
+     * out there.  If we're unable to format this correctly, we'll
+     * just return null.
+     *
+     * @return A Date object created from the source date.
+     */
+    public Date readDateOrNil() throws MessagingException {
+        String value = readStringOrNil();
+        // this might be optional
+        if (value == null) {
+            return null; 
+        }
+
+        try {
+            return dateParser.parse(value);
+        } catch (Exception e) {
+            // we're just skipping over this, so return null
+            return null;
+        }
+    }
+
+    /**
+     * Read an internet address from a Fetch response.  The
+     * addresses are returned as a set of string tokens in the
+     * order "personal list mailbox host".  Any of these tokens
+     * can be NIL.
+     *
+     * The address may also be the start of a group list, which
+     * is indicated by the host being NIL.  If we have found the
+     * start of a group, then we need to parse multiple elements
+     * until we find the group end marker (indicated by both the
+     * mailbox and the host being NIL), and create a group
+     * InternetAddress instance from this.
+     *
+     * @return An InternetAddress instance parsed from the
+     *         element.
+     * @exception ResponseFormatException
+     */
+    public InternetAddress readAddress() throws MessagingException {
+        // we recurse, expecting a null response back for sublists.  
+        if (peek().getType() != '(') {
+            return null; 
+        }
+        
+        // must start with a paren
+        checkLeftParen(); 
+
+        // personal information
+        String personal = readStringOrNil();
+        // the domain routine information.
+        String routing = readStringOrNil();
+        // the target mailbox
+        String mailbox = readStringOrNil();
+        // and finally the host
+        String host = readStringOrNil();
+        // and validate the closing paren
+        checkRightParen();
+
+        // if this is a real address, we need to compose
+        if (host != null) {
+            StringBuffer address = new StringBuffer();
+            if (routing != null) {
+                address.append(routing);
+                address.append(':');
+            }
+            address.append(mailbox);
+            address.append('@');
+            address.append(host);
+
+            try {
+                return new InternetAddress(address.toString(), personal);
+            } catch (UnsupportedEncodingException e) {
+                throw new ResponseFormatException("Invalid Internet address format");
+            }
+        }
+        else {
+            // we're going to recurse on this.  If the mailbox is null (the group name), this is the group item
+            // terminator.
+            if (mailbox == null) {
+                return null;
+            }
+
+            StringBuffer groupAddress = new StringBuffer();
+
+            groupAddress.append(mailbox);
+            groupAddress.append(':');
+            int count = 0;
+
+            while (true) {
+                // now recurse until we hit the end of the list
+                InternetAddress member = readAddress();
+                if (member == null) {
+                    groupAddress.append(';');
+
+                    try {
+                        return new InternetAddress(groupAddress.toString(), personal);
+                    } catch (UnsupportedEncodingException e) {
+                        throw new ResponseFormatException("Invalid Internet address format");
+                    }
+                }
+                else {
+                    if (count != 0) {
+                        groupAddress.append(',');
+                    }
+                    groupAddress.append(member.toString());
+                    count++;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Parse out a list of addresses.  This list of addresses is
+     * surrounded by parentheses, and each address is also
+     * parenthized (SP?).
+     *
+     * @return An array of the parsed addresses.
+     * @exception ResponseFormatException
+     */
+    public InternetAddress[] readAddressList() throws MessagingException {
+        // must start with a paren, but can be NIL also.
+        Token token = next(true);
+        int type = token.getType();
+
+        // either of these results in a null address.  The caller determines based on
+        // context whether this was optional or not.
+        if (type == Token.NIL) {
+            return null;
+        }
+        // non-nil address and no paren.  This is a syntax error.
+        else if (type != '(') {
+            throw new ResponseFormatException("Missing '(' in response");
+        }
+
+        List addresses = new ArrayList();
+
+        // we have a list, now parse it.
+        while (notListEnd()) {
+            // go read the next address.  If we had an address, add to the list.
+            // an address ITEM cannot be NIL inside the parens. 
+            InternetAddress address = readAddress();
+            addresses.add(address);
+        }
+        // we need to skip over the peeked token.
+        checkRightParen(); 
+        return (InternetAddress[])addresses.toArray(new InternetAddress[addresses.size()]);
+    }
+
+
+    /**
+     * Check to see if we're at the end of a parenthized list
+     * without advancing the parsing pointer.  If we are at the
+     * end, then this will step over the closing paren.
+     *
+     * @return True if the next token is a closing list paren, false otherwise.
+     * @exception ResponseFormatException
+     */
+    public boolean checkListEnd() throws MessagingException {
+        Token token = peek(true);
+        if (token.getType() == ')') {
+            // step over this token.
+            next();
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Reads a string item which can be encoded either as a single
+     * string-valued token or a parenthized list of string tokens.
+     *
+     * @return A List containing all of the strings.
+     * @exception ResponseFormatException
+     */
+    public List readStringList() throws MessagingException {
+        Token token = peek();
+
+        List list = new ArrayList();
+
+        if (token.getType() == '(') {
+            next();
+
+            while (notListEnd()) {
+                String value = readString();
+                // this can be NIL, technically
+                if (value != null) {
+                    list.add(value);
+                }
+            }
+            // step over the closing paren 
+            next(); 
+        }
+        else {
+            // just a single string value.
+            String value = readString();
+            // this can be NIL, technically
+            if (value != null) {
+                list.add(value);
+            }
+        }
+        return list;
+    }
+
+
+    /**
+     * Reads all remaining tokens and returns them as a list of strings. 
+     * NIL values are not supported. 
+     *
+     * @return A List containing all of the strings.
+     * @exception ResponseFormatException
+     */
+    public List readStrings() throws MessagingException {
+        List list = new ArrayList();
+        
+        while (hasMore()) {
+            String value = readString();
+            list.add(value);
+        }
+        return list; 
+    }
+
+
+    /**
+     * Skip over an extension item.  This may be either a string
+     * token or a parenthized item (with potential nesting).
+     *
+     * At the point where this is called, we're looking for a closing
+     * ')', but we know it is not that.  An EOF is an error, however,
+     */
+    public void skipExtensionItem() throws MessagingException {
+        Token token = next();
+        int type = token.getType();
+
+        // list form?  Scan to find the correct list closure.
+        if (type == '(') {
+            skipNestedValue();
+        }
+        // found an EOF?  Big problem
+        else if (type == Token.EOF) {
+            throw new ResponseFormatException("Missing ')'");
+        }
+    }
+
+    /**
+     * Skip over a parenthized value that we're not interested in.
+     * These lists may contain nested sublists, so we need to
+     * handle the nesting properly.
+     */
+    public void skipNestedValue() throws MessagingException {
+        Token token = next();
+
+        while (true) {
+            int type = token.getType();
+            // list terminator?
+            if (type == ')') {
+                return;
+            }
+            // unexpected end of the tokens.
+            else if (type == Token.EOF) {
+                throw new ResponseFormatException("Missing ')'");
+            }
+            // encountered a nested list?
+            else if (type == '(') {
+                // recurse and finish this list.
+                skipNestedValue();
+            }
+            // we're just skipping the token.
+            token = next();
+        }
+    }
+
+    /**
+     * Get the next token and verify that it's of the expected type
+     * for the context.
+     *
+     * @param type   The type of token we're expecting.
+     */
+    public void checkToken(int type) throws MessagingException {
+        Token token = next();
+        if (token.getType() != type) {
+            throw new ResponseFormatException("Unexpected token: " + token.getValue());
+        }
+    }
+
+
+    /**
+     * Read the next token as binary data.  The next token can be a literal, a quoted string, or
+     * the token NIL (which returns a null result).  Any other token throws a ResponseFormatException.
+     *
+     * @return A byte array representing the rest of the response data.
+     */
+    public byte[] readByteArray() throws MessagingException {
+        return readData(true);
+    }
+    
+    
+    /**
+     * Determine what type of token encoding needs to be 
+     * used for a string value.
+     * 
+     * @param value  The string to test.
+     * 
+     * @return Either Token.ATOM, Token.QUOTEDSTRING, or 
+     *         Token.LITERAL, depending on the characters contained
+     *         in the value.
+     */
+    static public int getEncoding(byte[] value) {
+        
+        // a null string always needs to be represented as a quoted literal. 
+        if (value.length == 0) {
+            return Token.QUOTEDSTRING; 
+        }
+        
+        for (int i = 0; i < value.length; i++) {
+            int ch = value[i]; 
+            // make sure the sign extension is eliminated 
+            ch = ch & 0xff;
+            // check first for any characters that would 
+            // disqualify a quoted string 
+            // NULL
+            if (ch == 0x00) {
+                return Token.LITERAL; 
+            }
+            // non-7bit ASCII
+            if (ch > 0x7F) {
+                return Token.LITERAL; 
+            }
+            // carriage return
+            if (ch == '\r') {
+                return Token.LITERAL; 
+            }
+            // linefeed 
+            if (ch == '\n') {
+                return Token.LITERAL; 
+            }
+            // now check for ATOM disqualifiers 
+            if (atomDelimiters.indexOf(ch) != -1) {
+                return Token.QUOTEDSTRING; 
+            }
+            // CTL character.  We've already eliminated the high characters 
+            if (ch < 0x20) {
+                return Token.QUOTEDSTRING; 
+            }
+        }
+        // this can be an ATOM token 
+        return Token.ATOM;
+    }
+    
+    
+    /**
+     * Read a ContentType or ContentDisposition parameter 
+     * list from an IMAP command response.
+     * 
+     * @return A ParameterList instance containing the parameters. 
+     * @exception MessagingException
+     */
+    public ParameterList readParameterList() throws MessagingException {
+        ParameterList params = new ParameterList(); 
+        
+        // read the tokens, taking NIL into account. 
+        Token token = next(true, false); 
+        
+        // just return an empty list if this is NIL 
+        if (token.isType(token.NIL)) {
+            return params; 
+        }
+        
+        // these are pairs of strings for each parameter value 
+        while (notListEnd()) {
+            String name = readString(); 
+            String value = readString(); 
+            params.set(name, value); 
+        }
+        // we need to consume the list terminator 
+        checkRightParen(); 
+        return params; 
+    }
+    
+    
+    /**
+     * Test if we have more data in the response buffer.
+     * 
+     * @return true if there are more tokens to process.  false if 
+     *         we've reached the end of the stream.
+     */
+    public boolean hasMore() throws MessagingException {
+        // we need to eat any white space that might be in the stream.  
+        eatWhiteSpace();
+        return pos < response.length; 
+    }
+    
+    
+    /**
+     * Tests if we've reached the end of a parenthetical
+     * list in our parsing stream.
+     * 
+     * @return true if the next token will be a ')'.  false if the 
+     *         next token is anything else.
+     * @exception MessagingException
+     */
+    public boolean notListEnd() throws MessagingException {
+        return peek().getType() != ')';
+    }
+    
+    /**
+     * Read a list of Flag values from an IMAP response, 
+     * returning a Flags instance containing the appropriate 
+     * pieces. 
+     * 
+     * @return A Flags instance with the flag values. 
+     * @exception MessagingException
+     */
+    public Flags readFlagList() throws MessagingException {
+        Flags flags = new Flags();
+        
+        // this should be a list here 
+        checkLeftParen(); 
+        
+        // run through the flag list 
+        while (notListEnd()) {
+            // the flags are a bit of a pain.  The flag names include "\" in the name, which 
+            // is not a character allowed in an atom.  This requires a bit of customized parsing 
+            // to handle this. 
+            Token token = next(); 
+            // flags can be specified as just atom tokens, so allow this as a user flag. 
+            if (token.isType(token.ATOM)) {
+                // append the atom as a raw name 
+                flags.add(token.getValue()); 
+            }
+            // all of the system flags start with a '\' followed by 
+            // an atom.  They also can be extension flags.  IMAP has a special 
+            // case of "\*" that we need to check for. 
+            else if (token.isType('\\')) {
+                token = next(); 
+                // the next token is the real bit we need to process. 
+                if (token.isType('*')) {
+                    // this indicates USER flags are allowed. 
+                    flags.add(Flags.Flag.USER); 
+                }
+                // if this is an atom name, handle as a system flag 
+                else if (token.isType(Token.ATOM)) {
+                    String name = token.getValue(); 
+                    if (name.equalsIgnoreCase("Seen")) {
+                        flags.add(Flags.Flag.SEEN);
+                    }
+                    else if (name.equalsIgnoreCase("RECENT")) {
+                        flags.add(Flags.Flag.RECENT);
+                    }
+                    else if (name.equalsIgnoreCase("DELETED")) {
+                        flags.add(Flags.Flag.DELETED);
+                    }
+                    else if (name.equalsIgnoreCase("ANSWERED")) {
+                        flags.add(Flags.Flag.ANSWERED);
+                    }
+                    else if (name.equalsIgnoreCase("DRAFT")) {
+                        flags.add(Flags.Flag.DRAFT);
+                    }
+                    else if (name.equalsIgnoreCase("FLAGGED")) {
+                        flags.add(Flags.Flag.FLAGGED);
+                    }
+                    else {
+                        // this is a server defined flag....just add the name with the 
+                        // flag thingy prepended. 
+                        flags.add("\\" + name); 
+                    }
+                }
+                else {
+                    throw new MessagingException("Invalid Flag: " + token.getValue()); 
+                }
+            }
+            else {
+                throw new MessagingException("Invalid Flag: " + token.getValue()); 
+            }
+        }
+        
+        // step over this for good practice. 
+        checkRightParen(); 
+        
+        return flags; 
+    }
+    
+    
+    /**
+     * Read a list of Flag values from an IMAP response, 
+     * returning a Flags instance containing the appropriate 
+     * pieces. 
+     * 
+     * @return A Flags instance with the flag values. 
+     * @exception MessagingException
+     */
+    public List readSystemNameList() throws MessagingException {
+        List flags = new ArrayList(); 
+        
+        // this should be a list here 
+        checkLeftParen(); 
+        
+        // run through the flag list 
+        while (notListEnd()) {
+            // the flags are a bit of a pain.  The flag names include "\" in the name, which 
+            // is not a character allowed in an atom.  This requires a bit of customized parsing 
+            // to handle this. 
+            Token token = next(); 
+            // all of the system flags start with a '\' followed by 
+            // an atom.  They also can be extension flags.  IMAP has a special 
+            // case of "\*" that we need to check for. 
+            if (token.isType('\\')) {
+                token = next(); 
+                // if this is an atom name, handle as a system flag 
+                if (token.isType(Token.ATOM)) {
+                    // add the token value to the list WITH the 
+                    // flag indicator included.  The attributes method returns 
+                    // these flag indicators, so we need to include it. 
+                    flags.add("\\" + token.getValue()); 
+                }
+                else {
+                    throw new MessagingException("Invalid Flag: " + token.getValue()); 
+                }
+            }
+            else {
+                throw new MessagingException("Invalid Flag: " + token.getValue()); 
+            }
+        }
+        
+        // step over this for good practice. 
+        checkRightParen(); 
+        
+        return flags; 
+    }
+}
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.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/IMAPSearchDateFormat.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Formats ths date in the form used by the javamail IMAP SEARCH command, 
+ * <p/>
+ * The format used is <code>d MMM yyyy</code> and  locale is always US-ASCII.
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPSearchDateFormat extends SimpleDateFormat {
+    public IMAPSearchDateFormat() {
+        super("dd-MMM-yyyy", Locale.US);
+    }
+    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) {
+        StringBuffer result = super.format(date, buffer, position);
+        // The RFC 2060 requires that the day in the date be formatted with either 2 digits
+        // or one digit.  Our format specifies 2 digits, which pads with leading
+        // zeros.  We need to check for this and whack it if it's there
+        if (result.charAt(0) == '0') {
+            result.deleteCharAt(0); 
+        }
+        return result;
+    }
+
+    /**
+     * The calendar cannot be set
+     * @param calendar
+     * @throws UnsupportedOperationException
+     */
+    public void setCalendar(Calendar calendar) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The format cannot be set
+     * @param format
+     * @throws UnsupportedOperationException
+     */
+    public void setNumberFormat(NumberFormat format) {
+        throw new UnsupportedOperationException();
+    }
+}
+
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchDateFormat.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.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/IMAPSearchResponse.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token; 
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPSearchResponse extends IMAPUntaggedResponse {
+    public int[] messageNumbers; 
+    
+    public IMAPSearchResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("SEARCH",  data); 
+        
+        Token token = source.next(); 
+        List tokens = new ArrayList();
+        
+        // just accumulate the list of tokens first 
+        while (token.getType() != Token.EOF) {
+            tokens.add(token); 
+            token = source.next(); 
+        }
+        
+        messageNumbers = new int[tokens.size()]; 
+        
+        // now parse these into numbers 
+        for (int i = 0; i < messageNumbers.length; i++) {
+            token = (Token)tokens.get(i); 
+            messageNumbers[i] = token.getInteger(); 
+        }
+    }
+}

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSearchResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.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/IMAPServerStatusResponse.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPServerStatusResponse extends IMAPUntaggedResponse {
+    // any message following the response 
+    protected String message; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPServerStatusResponse(String keyword, String message, byte [] response) {
+        super(keyword, response); 
+        this.message = message; 
+    }
+    
+    /**
+     * Get any trailing message associated with this 
+     * status response. 
+     * 
+     * @return 
+     */
+    public String getMessage() {
+        return message; 
+    }
+}
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPServerStatusResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.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/IMAPSizeResponse.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent a server size response.
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPSizeResponse extends IMAPUntaggedResponse {
+    // the associated size 
+    protected int size; 
+
+    /**
+     * Create a size response item.
+     * 
+     * @param keyword  The KEYWORD item associated with the size.
+     * @param size     The size value.
+     * @param response The raw response data.
+     */
+    public IMAPSizeResponse(String keyword, int size, byte [] response) {
+        super(keyword, response); 
+        this.size = size; 
+    }
+    
+    public int getSize() {
+        return size; 
+    }
+}
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPSizeResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.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/IMAPStatusResponse.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Utility class to aggregate status responses for a mailbox.
+ */
+public class IMAPStatusResponse extends IMAPUntaggedResponse {
+    // the mail box name 
+    public String mailbox; 
+    // number of messages in the box
+    public int messages = -1;
+    // number of recent messages 
+    public int recentMessages = -1; 
+    // the number of unseen messages
+    public int unseenMessages = -1;
+    // the next UID for this mailbox
+    public long uidNext = -1L;
+    // the UID validity item
+    public long uidValidity = -1L;
+
+    public IMAPStatusResponse(byte[] data, IMAPResponseTokenizer source) throws MessagingException {
+        super("STATUS",  data); 
+        
+        // the mail box name is supposed to be encoded, so decode it now.
+        mailbox = source.readEncodedString();
+
+        // parse the list of flag values
+        List flags = source.readStringList();
+
+        for (int i = 0; i < flags.size(); i += 2) {
+            String field = ((String)flags.get(i)).toUpperCase();
+            String stringValue = ((String)flags.get(i + 1)); 
+            long value; 
+            try {
+                value = Long.parseLong(stringValue); 
+            } catch (NumberFormatException e) {
+                throw new MessagingException("Invalid IMAP Status response", e); 
+            }
+                
+
+            if (field.equals("MESSAGES")) {
+                messages = (int)value; 
+            }
+            else if (field.equals("RECENT")) {
+                recentMessages = (int)value;
+            }
+            else if (field.equals("UIDNEXT")) {
+                uidNext = value;
+            }
+            else if (field.equals("UIDVALIDITY")) {
+                uidValidity = value; 
+            }
+            else if (field.equals("UNSEEN")) {
+                unseenMessages = (int)value; 
+            }
+        }
+    }
+}
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPStatusResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.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/IMAPTaggedResponse.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,155 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.apache.geronimo.mail.util.Base64;
+
+/**
+ * Util class to represent a response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPTaggedResponse extends IMAPResponse {
+
+    // the reply state
+    protected String status;
+    // the tag associated with a reply.
+    protected String tag;
+    // the message associated with the completion response 
+    protected String message;
+
+    /**
+     * Create a command completion response for a 
+     * submitted command.  The tag prefix identifies 
+     * the command this response is for. 
+     * 
+     * @param tag      The command tag value.
+     * @param status   The Status response (OK, BAD, or NO).
+     * @param message  The remainder of the response, as a string.
+     * @param response The response data used to create the reply object.
+     */
+    public IMAPTaggedResponse(String tag, String status, String message, byte [] response) {
+        super(response); 
+        this.tag = tag; 
+        this.status = status;
+        this.message = message; 
+    }
+
+
+    /**
+     * Create a continuation response for a 
+     * submitted command.  
+     * 
+     * @param response The response data used to create the reply object.
+     */
+    public IMAPTaggedResponse(byte [] response) {
+        super(response); 
+        this.tag = "";  
+        this.status = "CONTINUATION";
+        this.message = message; 
+    }
+
+    /**
+     * Test if the response code was "OK".
+     *
+     * @return True if the response status was OK, false for any other status.
+     */
+    public boolean isOK() {
+        return status.equals("OK");
+    }
+
+    /**
+     * Test for an error return from a command.
+     *
+     * @return True if the response status was BAD.
+     */
+    public boolean isBAD() {
+        return status.equals("BAD"); 
+    }
+
+    /**
+     * Test for an error return from a command.
+     *
+     * @return True if the response status was NO.
+     */
+    public boolean isNO() {
+        return status.equals("NO"); 
+    }
+    
+    /**
+     * Get the message included on the tagged response. 
+     * 
+     * @return The String message data. 
+     */
+    public String getMessage() {
+        return message; 
+    }
+    
+    /**
+     * Decode the message portion of a continuation challenge response.
+     * 
+     * @return The byte array containing the decoded data. 
+     */
+    public byte[] decodeChallengeResponse() 
+    {
+        // we're passed back a challenge value, Base64 encoded.  Decode that portion of the 
+        // response data. 
+        return Base64.decode(response, 2, response.length - 2);
+    }
+    
+    
+    /**
+     * Test if this is a continuation response. 
+     * 
+     * @return True if this a continuation.  false for a normal tagged response. 
+     */
+    public boolean isContinuation() {
+        return status.equals("CONTINUATION"); 
+    }
+    
+    
+    /**
+     * Test if the untagged response includes a given 
+     * status indicator.  Mostly used for checking 
+     * READ-ONLY or READ-WRITE status after selecting a 
+     * mail box.
+     * 
+     * @param name   The status name to check.
+     * 
+     * @return true if this is found in the "[" "]" delimited
+     *         section of the response message.
+     */
+    public boolean hasStatus(String name) {
+        // see if we have the status bits at all 
+        int statusStart = message.indexOf('['); 
+        if (statusStart == -1) {
+            return false; 
+        }
+        
+        int statusEnd = message.indexOf(']'); 
+        String statusString = message.substring(statusStart, statusEnd).toUpperCase(); 
+        // just search for the status token. 
+        return statusString.indexOf(name) != -1; 
+    }
+}
+
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPTaggedResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.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/IMAPUid.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+import javax.mail.MessagingException;
+
+public class IMAPUid extends IMAPFetchDataItem {
+    // the returned uid
+    public long uid;
+    // the returned sequence number for the message 
+    public int messageNumber; 
+
+    public IMAPUid(int messageNumber, IMAPResponseTokenizer source) throws MessagingException {
+        super(UID);
+        // just read the number pairs 
+        this.messageNumber = messageNumber;
+        uid = source.readLong();
+    }
+}
+
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUid.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.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/IMAPUntaggedResponse.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+/**
+ * Util class to represent an untagged response from a IMAP server
+ *
+ * @version $Rev$ $Date$
+ */
+public class IMAPUntaggedResponse extends IMAPResponse {
+    // the response key word 
+    protected String keyword; 
+
+    /**
+     * Create a reply object from a server response line (normally, untagged).  This includes
+     * doing the parsing of the response line.
+     *
+     * @param response The response line used to create the reply object.
+     */
+    public IMAPUntaggedResponse(String keyword, byte [] response) {
+        super(response); 
+        this.keyword = keyword; 
+    }
+
+    /**
+     * Return the KEYWORD that identifies the type 
+     * of this untagged response.
+     * 
+     * @return The identifying keyword.
+     */
+    public String getKeyword() {
+        return keyword; 
+    }
+    
+    
+    /**
+     * Test if an untagged response is of a given 
+     * keyword type.
+     * 
+     * @param keyword The test keyword.
+     * 
+     * @return True if this is a type match, false for mismatches.
+     */
+    public boolean isKeyword(String keyword) {
+        return this.keyword.equals(keyword); 
+    }
+}
+

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.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/IMAPUntaggedResponseHandler.java?rev=594520&view=auto
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java (added)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java Tue Nov 13 04:57:39 2007
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.javamail.store.imap.connection;
+
+public interface IMAPUntaggedResponseHandler {
+    /**
+     * Handle an unsolicited untagged response receive back from a command.  This 
+     * will be any responses left over after the command has cherry picked the 
+     * bits that are relevent to the command just issued.  It is important 
+     * that the unsolicited response be reacted to in order to keep the message 
+     * caches in sync. 
+     * 
+     * @param response The response to handle.
+     * 
+     * @return true if the handle took care of the response and it should not be sent 
+     *         to additional handlers.  false if broadcasting of the response should continue.
+     */
+    public boolean handleResponse(IMAPUntaggedResponse response);
+}

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPUntaggedResponseHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.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/transport/nntp/NNTPTransport.java?rev=594520&r1=594519&r2=594520&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPTransport.java Tue Nov 13 04:57:39 2007
@@ -195,7 +195,6 @@
         // instances.
         for (int i = 0; i < addresses.length; i++) {
             if (!(addresses[i] instanceof NewsAddress)) {
-                System.out.println("Illegal address is of class " + addresses[i].getClass());
                 throw new MessagingException("Illegal NewsAddress " + addresses[i]);
             }
         }

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.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/transport/smtp/SMTPTransport.java?rev=594520&r1=594519&r2=594520&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java Tue Nov 13 04:57:39 2007
@@ -1697,7 +1697,6 @@
             throw new MessagingException("no connection");
         }
         try {
-            System.out.println(">>>>>Sending data " + data + "<<<<<<");
             outputStream.write(data.getBytes());
             outputStream.write(CR);
             outputStream.write(LF);



Mime
View raw message