/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.geronimo.javamail.store.imap;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import javax.activation.DataHandler;

import javax.mail.Address;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Header;
import javax.mail.IllegalWriteException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.MessageRemovedException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.UIDFolder;
import javax.mail.event.MessageChangedEvent;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MailDateFormat;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import org.apache.geronimo.javamail.store.imap.connection.IMAPBody;
import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchDataItem;
import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchResponse;
import org.apache.geronimo.javamail.store.imap.connection.IMAPInternalDate;
import org.apache.geronimo.javamail.store.imap.connection.IMAPInternetHeader;
import org.apache.geronimo.javamail.store.imap.connection.IMAPMessageSize;
import org.apache.geronimo.javamail.store.imap.connection.IMAPUid;
import org.apache.geronimo.javamail.util.MailConnection;

/**
 * IMAP implementation of javax.mail.internet.MimeMessage
 *
 * Only the most basic information is given and
 * Message objects created here is a light-weight reference to the actual Message
 * As per the JavaMail spec items from the actual message will get filled up on demand
 *
 * If some other items are obtained from the server as a result of one call, then the other
 * details are also processed and filled in. For ex if RETR is called then header information
 * will also be processed in addition to the content
 *
 * @version $Rev: 946314 $ $Date: 2010-05-19 14:01:55 -0400 (Wed, 19 May 2010) $
 */
public class IMAPMessage extends MimeMessage {

    private static final byte[] CRLF = new byte[]{'\r', '\n'};

    // the Store we're stored in (which manages the connection and other stuff).
    protected IMAPStore store;

    // the IMAP server sequence number (potentially updated during the life of this message object).
    protected int sequenceNumber;
    // the IMAP uid value;
    protected long uid = -1;
    // the section identifier.  This is only really used for nested messages.  The toplevel version
    // will be null, and each nested message will set the appropriate part identifier
    protected String section;
    // the loaded message envelope (delayed until needed)
    protected IMAPEnvelope envelope;
    // the body structure information (also lazy loaded).
    protected IMAPBodyStructure bodyStructure;
    // the IMAP INTERNALDATE value.
    protected Date receivedDate;
    // the size item, which is maintained separately from the body structure
    // as it can be retrieved without getting the body structure
    protected int size;
    // turned on once we've requested the entire header set.
    protected boolean allHeadersRetrieved = false;
    // singleton date formatter for this class.
    static protected MailDateFormat dateFormat = new MailDateFormat();


    /**
     * Contruct an IMAPMessage instance.
     *
     * @param folder   The hosting folder for the message.
     * @param store    The Store owning the article (and folder).
     * @param msgnum   The article message number.  This is assigned by the Folder, and is unique
     *                 for each message in the folder.  The message numbers are only valid
     *                 as long as the Folder is open.
     * @param sequenceNumber The IMAP server manages messages by sequence number, which is subject to
     *                 change whenever messages are expunged.  This is the server retrieval number
     *                 of the message, which needs to be synchronized with status updates
     *                 sent from the server.
     *
     * @exception MessagingException
     */
	IMAPMessage(IMAPFolder folder, IMAPStore store, int msgnum, int sequenceNumber) {
		super(folder, msgnum);
        this.sequenceNumber = sequenceNumber;
		this.store = store;
        // The default constructor creates an empty Flags item.  We need to clear this out so we
        // know if the flags need to be fetched from the server when requested.
        flags = null;
        // make sure this is a totally fresh set of headers.  We'll fill things in as we retrieve them.
        headers = new InternetHeaders();
	}


    /**
     * Override for the Message class setExpunged() method to allow
     * us to do additional cleanup for expunged messages.
     *
     * @param value  The new expunge setting.
     */
    public void setExpunged(boolean value) {
        // super class handles most of the details
        super.setExpunged(value);
        // if we're now expunged, this removes us from the server message sequencing scheme, so
        // we need to invalidate the sequence number.
        if (isExpunged()) {
            sequenceNumber = -1;
        }
    }


    /**
     * Return a copy the flags associated with this message.
     *
     * @return a copy of the flags for this message
     * @throws MessagingException if there was a problem accessing the Store
     */
    public synchronized Flags getFlags() throws MessagingException {
        // load the flags, if needed
        loadFlags();
        return super.getFlags();
    }


    /**
     * Check whether the supplied flag is set.
     * The default implementation checks the flags returned by {@link #getFlags()}.
     *
     * @param flag the flags to check for
     * @return true if the flags is set
     * @throws MessagingException if there was a problem accessing the Store
     */
    public synchronized boolean isSet(Flags.Flag flag) throws MessagingException {
        // load the flags, if needed
        loadFlags();
        return super.isSet(flag);
    }

    /**
     * Set or clear a flag value.
     *
     * @param flags  The set of flags to effect.
     * @param set    The value to set the flag to (true or false).
     *
     * @exception MessagingException
     */
    public synchronized void setFlags(Flags flag, boolean set) throws MessagingException {
        // make sure this is in a valid state.
        checkValidity();

        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        synchronized (folder) {
            IMAPConnection connection = getConnection();

            try {
                // set the flags for this item and update the
                // internal state with the new values returned from the
                // server.
                flags = connection.setFlags(sequenceNumber, flag, set);
            } finally {
                releaseConnection(connection);
            }
        }
    }


    /**
     * Return an InputStream instance for accessing the
     * message content.
     *
     * @return An InputStream instance for accessing the content
     *         (body) of the message.
     * @exception MessagingException
     * @see javax.mail.internet.MimeMessage#getContentStream()
     */
	protected InputStream getContentStream() throws MessagingException {

        // no content loaded yet?
        if (content == null) {
            // make sure we're still valid
            checkValidity();
            // make sure the content is fully loaded
            loadContent();
        }

        // allow the super class to handle creating it from the loaded content.
        return super.getContentStream();
	}


    /**
     * Write out the byte data to the provided output stream.
     *
     * @param out    The target stream.
     *
     * @exception IOException
     * @exception MessagingException
     */
    public void writeTo(OutputStream out) throws IOException, MessagingException {
        // no content loaded yet?
        if (content == null) {
            // make sure we're still valid
            checkValidity();
            // make sure the content is fully loaded
            loadContent();
        }

        loadHeaders();

        Enumeration e = headers.getAllHeaderLines();
        while(e.hasMoreElements()) {
            String line = (String)e.nextElement();
            out.write(line.getBytes("ISO8859-1"));
            out.write(CRLF);
        }
        out.write(CRLF);
        out.write(CRLF);
        out.write(content);
    }

	/******************************************************************
	 * Following is a set of methods that deal with information in the
	 * envelope.  These methods ensure the enveloper is loaded and
     * retrieve the information.
	 ********************************************************************/


    /**
     * Get the message "From" addresses.  This looks first at the
     * "From" headers, and no "From" header is found, the "Sender"
     * header is checked.  Returns null if not found.
     *
     * @return An array of addresses identifying the message from target.  Returns
     *         null if this is not resolveable from the headers.
     * @exception MessagingException
     */
    public Address[] getFrom() throws MessagingException {
        // make sure we've retrieved the envelope information.
        loadEnvelope();
        // make sure we return a copy of the array so this can't be changed.
        Address[] addresses = envelope.from;
        if (addresses == null) {
            return null;
        }
        return (Address[])addresses.clone();
    }


    /**
     * Return the "Sender" header as an address.
     *
     * @return the "Sender" header as an address, or null if not present
     * @throws MessagingException if there was a problem parsing the header
     */
    public Address getSender() throws MessagingException {
        // make sure we've retrieved the envelope information.
        loadEnvelope();
        // make sure we return a copy of the array so this can't be changed.
        Address[] addresses = envelope.sender;
        if (addresses == null) {
            return null;
        }
        // There's only a single sender, despite IMAP potentially returning a list
        return addresses[0];
    }

    /**
     * Gets the recipients by type.  Returns null if there are no
     * headers of the specified type.  Acceptable RecipientTypes are:
     *
     *   javax.mail.Message.RecipientType.TO
     *   javax.mail.Message.RecipientType.CC
     *   javax.mail.Message.RecipientType.BCC
     *   javax.mail.internet.MimeMessage.RecipientType.NEWSGROUPS
     *
     * @param type   The message RecipientType identifier.
     *
     * @return The array of addresses for the specified recipient types.
     * @exception MessagingException
     */
    public Address[] getRecipients(Message.RecipientType type) throws MessagingException {
        // make sure we've retrieved the envelope information.
        loadEnvelope();
        Address[] addresses = null;

        if (type == Message.RecipientType.TO) {
            addresses = envelope.to;
        }
        else if (type == Message.RecipientType.CC) {
            addresses = envelope.cc;
        }
        else if (type == Message.RecipientType.BCC) {
            addresses = envelope.bcc;
        }
        else {
            // this could be a newsgroup type, which will tickle the message headers.
            return super.getRecipients(type);
        }
        // make sure we return a copy of the array so this can't be changed.
        if (addresses == null) {
            return null;
        }
        return (Address[])addresses.clone();
    }

    /**
     * Get the ReplyTo address information.  The headers are parsed
     * using the "mail.mime.address.strict" setting.  If the "Reply-To" header does
     * not have any addresses, then the value of the "From" field is used.
     *
     * @return An array of addresses obtained from parsing the header.
     * @exception MessagingException
     */
    public Address[] getReplyTo() throws MessagingException {
        // make sure we've retrieved the envelope information.
        loadEnvelope();
        // make sure we return a copy of the array so this can't be changed.
        Address[] addresses = envelope.replyTo;
        if (addresses == null) {
            return null;
        }
        return (Address[])addresses.clone();
    }

    /**
     * Returns the value of the "Subject" header.  If the subject
     * is encoded as an RFC 2047 value, the value is decoded before
     * return.  If decoding fails, the raw string value is
     * returned.
     *
     * @return The String value of the subject field.
     * @exception MessagingException
     */
    public String getSubject() throws MessagingException {
        // make sure we've retrieved the envelope information.
        loadEnvelope();

        if (envelope.subject == null) {
            return null;
        }
        // the subject could be encoded.  If there is a decoding error,
        // return the raw subject string.
        try {
            return MimeUtility.decodeText(envelope.subject);
        } catch (UnsupportedEncodingException e) {
            return envelope.subject;
        }
    }

    /**
     * Get the value of the "Date" header field.  Returns null if
     * if the field is absent or the date is not in a parseable format.
     *
     * @return A Date object parsed according to RFC 822.
     * @exception MessagingException
     */
    public Date getSentDate() throws MessagingException {
        // make sure we've retrieved the envelope information.
        loadEnvelope();
        // just return that directly
        return envelope.date;
    }


    /**
     * Get the message received date.
     *
     * @return Always returns the formatted INTERNALDATE, if available.
     * @exception MessagingException
     */
    public Date getReceivedDate() throws MessagingException {
        loadEnvelope();
        return receivedDate;
    }


    /**
     * Retrieve the size of the message content.  The content will
     * be retrieved from the server, if necessary.
     *
     * @return The size of the content.
     * @exception MessagingException
     */
	public int getSize() throws MessagingException {
        // make sure we've retrieved the envelope information.  We load the
        // size when we retrieve that.
        loadEnvelope();
        return size;
	}


    /**
     * Get a line count for the IMAP message.  This is potentially
     * stored in the Lines article header.  If not there, we return
     * a default of -1.
     *
     * @return The header line count estimate, or -1 if not retrieveable.
     * @exception MessagingException
     */
    public int getLineCount() throws MessagingException {
        loadBodyStructure();
        return bodyStructure.lines;
    }

    /**
     * Return the IMAP in reply to information (retrieved with the
     * ENVELOPE).
     *
     * @return The in reply to String value, if available.
     * @exception MessagingException
     */
    public String getInReplyTo() throws MessagingException {
        loadEnvelope();
        return envelope.inReplyTo;
    }

    /**
     * Returns the current content type (defined in the "Content-Type"
     * header.  If not available, "text/plain" is the default.
     *
     * @return The String name of the message content type.
     * @exception MessagingException
     */
    public String getContentType() throws MessagingException {
        loadBodyStructure();
        return bodyStructure.mimeType.toString();
    }


    /**
     * Tests to see if this message has a mime-type match with the
     * given type name.
     *
     * @param type   The tested type name.
     *
     * @return If this is a type match on the primary and secondare portion of the types.
     * @exception MessagingException
     */
    public boolean isMimeType(String type) throws MessagingException {
        loadBodyStructure();
        return bodyStructure.mimeType.match(type);
    }

    /**
     * Retrieve the message "Content-Disposition" header field.
     * This value represents how the part should be represented to
     * the user.
     *
     * @return The string value of the Content-Disposition field.
     * @exception MessagingException
     */
    public String getDisposition() throws MessagingException {
        loadBodyStructure();
        if (bodyStructure.disposition != null) {
            return bodyStructure.disposition.getDisposition();
        }
        return null;
    }

    /**
     * Decode the Content-Transfer-Encoding header to determine
     * the transfer encoding type.
     *
     * @return The string name of the required encoding.
     * @exception MessagingException
     */
    public String getEncoding() throws MessagingException {
        loadBodyStructure();
        return bodyStructure.transferEncoding;
    }

    /**
     * Retrieve the value of the "Content-ID" header.  Returns null
     * if the header does not exist.
     *
     * @return The current header value or null.
     * @exception MessagingException
     */
    public String getContentID() throws MessagingException {
        loadBodyStructure();
        return bodyStructure.contentID;
    }

    public String getContentMD5() throws MessagingException {
        loadBodyStructure();
        return bodyStructure.md5Hash;
    }


    public String getDescription() throws MessagingException {
        loadBodyStructure();

        if (bodyStructure.contentDescription == null) {
            return null;
        }
        // the subject could be encoded.  If there is a decoding error,
        // return the raw subject string.
        try {
            return MimeUtility.decodeText(bodyStructure.contentDescription);
        } catch (UnsupportedEncodingException e) {
            return bodyStructure.contentDescription;
        }
    }

    /**
     * Return the content languages associated with this
     * message.
     *
     * @return
     * @exception MessagingException
     */
    public String[] getContentLanguage() throws MessagingException {
        loadBodyStructure();

        if (!bodyStructure.languages.isEmpty()) {
            return (String[])bodyStructure.languages.toArray(new String[bodyStructure.languages.size()]);
        }
        return null;
    }

    public String getMessageID() throws MessagingException {
        loadEnvelope();
        return envelope.messageID;
    }

    public void setFrom(Address address) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void addFrom(Address[] address) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setSender(Address address) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setRecipients(Message.RecipientType type, Address[] addresses) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setRecipients(Message.RecipientType type, String address) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void addRecipients(Message.RecipientType type, Address[] address) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setReplyTo(Address[] address) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setSubject(String subject) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setSubject(String subject, String charset) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setSentDate(Date sent) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setDisposition(String disposition) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setContentID(String cid) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setContentMD5(String md5) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setDescription(String description) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setDescription(String description, String charset) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setContentLanguage(String[] languages) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }


	/******************************************************************
	 * Following is a set of methods that deal with headers
	 * These methods are just overrides on the superclass methods to
     * allow lazy loading of the header information.
	 ********************************************************************/

	public String[] getHeader(String name) throws MessagingException {
        loadHeaders();
		return headers.getHeader(name);
	}

	public String getHeader(String name, String delimiter) throws MessagingException {
        loadHeaders();
		return headers.getHeader(name, delimiter);
	}

	public Enumeration getAllHeaders() throws MessagingException {
        loadHeaders();
		return headers.getAllHeaders();
	}

	public Enumeration getMatchingHeaders(String[] names)  throws MessagingException {
        loadHeaders();
		return headers.getMatchingHeaders(names);
	}

	public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
        loadHeaders();
		return headers.getNonMatchingHeaders(names);
	}

	public Enumeration getAllHeaderLines() throws MessagingException {
        loadHeaders();
		return headers.getAllHeaderLines();
	}

	public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
        loadHeaders();
		return headers.getMatchingHeaderLines(names);
	}

	public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
        loadHeaders();
		return headers.getNonMatchingHeaderLines(names);
	}

    // the following are overrides for header modification methods.  These messages are read only,
    // so the headers cannot be modified.
    public void addHeader(String name, String value) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void setHeader(String name, String value) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }


    public void removeHeader(String name) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    public void addHeaderLine(String line) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

	/**
	 * We cannot modify these messages
	 */
	public void saveChanges() throws MessagingException {
		throw new IllegalWriteException("IMAP messages are read-only");
	}


    /**
     * Utility method for synchronizing IMAP envelope information and
     * the message headers.
     *
     * @param header    The target header name.
     * @param addresses The update addresses.
     */
    protected void updateHeader(String header, InternetAddress[] addresses) throws MessagingException {
        if (addresses != null) {
            headers.addHeader(header, InternetAddress.toString(addresses));
        }
    }

    /**
     * Utility method for synchronizing IMAP envelope information and
     * the message headers.
     *
     * @param header    The target header name.
     * @param address   The update address.
     */
    protected void updateHeader(String header, Address address) throws MessagingException {
        if (address != null) {
            headers.setHeader(header, address.toString());
        }
    }

    /**
     * Utility method for synchronizing IMAP envelope information and
     * the message headers.
     *
     * @param header    The target header name.
     * @param value     The update value.
     */
    protected void updateHeader(String header, String value) throws MessagingException {
        if (value != null) {
            headers.setHeader(header, value);
        }
    }


    /**
     * Create the DataHandler object for this message.
     *
     * @return The DataHandler object that processes the content set for this
     *         message.
     * @exception MessagingException
     */
    public synchronized DataHandler getDataHandler() throws MessagingException {
        // check the validity and make sure we have the body structure information.
        checkValidity();
        loadBodyStructure();
        if (dh == null) {
            // are we working with a multipart message here?
            if (bodyStructure.isMultipart()) {
                dh = new DataHandler(new IMAPMultipartDataSource(this, this, section, bodyStructure));
                return dh;
            }
            else if (bodyStructure.isAttachedMessage()) {
                dh = new DataHandler(new IMAPAttachedMessage(this, section, bodyStructure.nestedEnvelope, bodyStructure.nestedBody),
                     bodyStructure.mimeType.toString());
                return dh;
            }
        }

        // single part messages get handled the normal way.
        return super.getDataHandler();
    }

    public void setDataHandler(DataHandler content) throws MessagingException {
        throw new IllegalWriteException("IMAP body parts are read-only");
    }

    /**
     * Update the message headers from an input stream.
     *
     * @param in     The InputStream source for the header information.
     *
     * @exception MessagingException
     */
    public void updateHeaders(InputStream in) throws MessagingException {
        // wrap a stream around the reply data and read as headers.
        headers = new InternetHeaders(in);
        allHeadersRetrieved = true;
    }

    /**
     * Load the flag set for this message from the server.
     *
     * @exception MessagingeException
     */
    public void loadFlags() throws MessagingException {
        // make sure this is in a valid state.
        checkValidity();
        // if the flags are already loaded, nothing to do
        if (flags != null) {
            return;
        }
        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        synchronized (folder) {
            IMAPConnection connection = getConnection();

            try {
                // fetch the flags for this item.
                flags = connection.fetchFlags(sequenceNumber);
            } finally {
                releaseConnection(connection);
            }
        }
    }


    /**
     * Retrieve the message raw message headers from the IMAP server, synchronizing with the existing header set.
     *
     * @exception MessagingException
     */
    protected synchronized void loadHeaders() throws MessagingException {
        // don't retrieve if already loaded.
        if (allHeadersRetrieved) {
            return;
        }

        // make sure this is in a valid state.
        checkValidity();
        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        synchronized (folder) {
            IMAPConnection connection = getConnection();

            try {
                // get the headers and set
                headers = connection.fetchHeaders(sequenceNumber, section);
                // we have the entire header set, not just a subset.
                allHeadersRetrieved = true;
            } finally {
                releaseConnection(connection);
            }
        }
    }


    /**
     * Retrieve the message envelope from the IMAP server, synchronizing the headers with the
     * information.
     *
     * @exception MessagingException
     */
    protected synchronized void loadEnvelope() throws MessagingException {
        // don't retrieve if already loaded.
        if (envelope != null) {
            return;
        }

        // make sure this is in a valid state.
        checkValidity();
        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        synchronized (folder) {
            IMAPConnection connection = getConnection();
            try {
                // fetch the envelope information for this
                List fetches = connection.fetchEnvelope(sequenceNumber);
                // now process all of the fetch responses before releasing the folder lock.
                // it's possible that an unsolicited update on another thread might try to
                // make an update, causing a potential deadlock.
                for (int i = 0; i < fetches.size(); i++) {
                    // get the returned data items from each of the fetch responses
                    // and process.
                    IMAPFetchResponse fetch = (IMAPFetchResponse)fetches.get(i);
                    // update the internal info
                    updateMessageInformation(fetch);
                }
            } finally {
                releaseConnection(connection);
            }
        }
    }


    /**
     * Retrieve the message envelope from the IMAP server, synchronizing the headers with the
     * information.
     *
     * @exception MessagingException
     */
    protected synchronized void updateEnvelope(IMAPEnvelope envelope) throws MessagingException {
        // set the envelope item
        this.envelope = envelope;

        // copy header type information from the envelope into the headers.
        updateHeader("From", envelope.from);
        if (envelope.sender != null) {
            // we can only have a single sender, even though the envelope theoretically supports more.
            updateHeader("Sender", envelope.sender[0]);
        }
        updateHeader("To", envelope.to);
        updateHeader("Cc", envelope.cc);
        updateHeader("Bcc", envelope.bcc);
        updateHeader("Reply-To", envelope.replyTo);
        // NB:  This is already in encoded form, if needed.
        updateHeader("Subject", envelope.subject);
        updateHeader("Message-ID", envelope.messageID);
    }


    /**
     * Retrieve the BODYSTRUCTURE information from the IMAP server.
     *
     * @exception MessagingException
     */
    protected synchronized void loadBodyStructure() throws MessagingException {
        // don't retrieve if already loaded.
        if (bodyStructure != null) {
            return;
        }

        // make sure this is in a valid state.
        checkValidity();
        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        synchronized (folder) {
            IMAPConnection connection = getConnection();
            try {
                // fetch the envelope information for this
                bodyStructure = connection.fetchBodyStructure(sequenceNumber);
                // go update all of the information
            } finally {
                releaseConnection(connection);
            }

            // update this before we release the folder lock so we can avoid
            // deadlock.
            updateBodyStructure(bodyStructure);
        }
    }


    /**
     * Update the BODYSTRUCTURE information from the IMAP server.
     *
     * @exception MessagingException
     */
    protected synchronized void updateBodyStructure(IMAPBodyStructure structure) throws MessagingException {
        // save the reference.
        bodyStructure = structure;
        // now update various headers with the information from the body structure

        // now update header information with the body structure data.
        if (bodyStructure.lines != -1) {
            updateHeader("Lines", Integer.toString(bodyStructure.lines));
        }

        // languages are a little more complicated
        if (bodyStructure.languages != null) {
            // this is a duplicate of what happens in the super class, but
            // the superclass methods call setHeader(), which we override and
            // throw an exception for.  We need to set the headers ourselves.
            if (bodyStructure.languages.size() == 1) {
                updateHeader("Content-Language", (String)bodyStructure.languages.get(0));
            }
            else {
                StringBuffer buf = new StringBuffer(bodyStructure.languages.size() * 20);
                buf.append(bodyStructure.languages.get(0));
                for (int i = 1; i < bodyStructure.languages.size(); i++) {
                    buf.append(',').append(bodyStructure.languages.get(i));
                }
                updateHeader("Content-Language", buf.toString());
            }
        }

        updateHeader("Content-Type", bodyStructure.mimeType.toString());
        if (bodyStructure.disposition != null) {
            updateHeader("Content-Disposition", bodyStructure.disposition.toString());
        }

        updateHeader("Content-Transfer-Encoding", bodyStructure.transferEncoding);
        updateHeader("Content-ID", bodyStructure.contentID);
        // NB:  This is already in encoded form, if needed.
        updateHeader("Content-Description", bodyStructure.contentDescription);
    }


    /**
     * Load the message content into the Message object.
     *
     * @exception MessagingException
     */
    protected void loadContent() throws MessagingException {
        // if we've loaded this already, just return
        if (content != null) {
            return;
        }

        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        synchronized (folder) {
            IMAPConnection connection = getConnection();
            try {
                // load the content from the server.
                content = connection.fetchContent(getSequenceNumber(), section);
            } finally {
                releaseConnection(connection);
            }
        }
    }


    /**
     * Retrieve the sequence number assigned to this message.
     *
     * @return The messages assigned sequence number.  This maps back to the server's assigned number for
     * this message.
     */
    int getSequenceNumber() {
        return sequenceNumber;
    }

    /**
     * Set the sequence number for the message.  This
     * is updated whenever messages get expunged from
     * the folder.
     *
     * @param s      The new sequence number.
     */
    void setSequenceNumber(int s) {
        sequenceNumber = s;
    }


    /**
     * Retrieve the message UID value.
     *
     * @return The assigned UID value, if we have the information.
     */
    long getUID() {
        return uid;
    }

    /**
     * Set the message UID value.
     *
     * @param uid    The new UID value.
     */
    void setUID(long uid) {
        this.uid = uid;
    }


    /**
     * get the current connection pool attached to the folder.  We need
     * to do this dynamically, to A) ensure we're only accessing an
     * currently open folder, and B) to make sure we're using the
     * correct connection attached to the folder.
     *
     * @return A connection attached to the hosting folder.
     */
    protected IMAPConnection getConnection() throws MessagingException {
        // the folder owns everything.
        return ((IMAPFolder)folder).getMessageConnection();
    }

    /**
     * Release the connection back to the Folder after performing an operation
     * that requires a connection.
     *
     * @param connection The previously acquired connection.
     */
    protected void releaseConnection(IMAPConnection connection) throws MessagingException {
        // the folder owns everything.
        ((IMAPFolder)folder).releaseMessageConnection(connection);
    }


    /**
     * Check the validity of the current message.  This ensures that
     * A) the folder is currently open, B) that the message has not
     * been expunged (after getting the latest status from the server).
     *
     * @exception MessagingException
     */
    protected void checkValidity() throws MessagingException {
        checkValidity(false);
    }


    /**
     * Check the validity of the current message.  This ensures that
     * A) the folder is currently open, B) that the message has not
     * been expunged (after getting the latest status from the server).
     *
     * @exception MessagingException
     */
    protected void checkValidity(boolean update) throws MessagingException {
        // we need to ensure that we're the only ones with access to the folder's
        // message cache any time we need to talk to the server.  This needs to be
        // held until after we release the connection so that any pending EXPUNGE
        // untagged responses are processed before the next time the folder connection is
        // used.
        if (update) {
            synchronized (folder) {
                // have the connection update the folder status.  This might result in this message
                // changing its state to expunged.  It might also result in an exception if the
                // folder has been closed.
                IMAPConnection connection = getConnection();

                try {
                    connection.updateMailboxStatus();
                } finally {
                    // this will force any expunged messages to be processed before we release
                    // the lock.
                    releaseConnection(connection);
                }
            }
        }

        // now see if we've been expunged, this is a bad op on the message.
        if (isExpunged()) {
            throw new MessageRemovedException("Illegal opertion on a deleted message");
        }
    }


    /**
     * Evaluate whether this message requires any of the information
     * in a FetchProfile to be fetched from the server.  If the messages
     * already contains the information in the profile, it returns false.
     * This allows IMAPFolder to optimize fetch() requests to just the
     * messages that are missing any of the requested information.
     *
     * NOTE:  If any of the items in the profile are missing, then this
     * message will be updated with ALL of the items.
     *
     * @param profile The FetchProfile indicating the information that should be prefetched.
     *
     * @return true if any of the profile information requires fetching.  false if this
     *         message already contains the given information.
     */
    protected boolean evaluateFetch(FetchProfile profile) {
        // the fetch profile can contain a number of different item types.  Validate
        // whether we need any of these and return true on the first mismatch.

        // the UID is a common fetch request, put it first.
        if (profile.contains(UIDFolder.FetchProfileItem.UID) && uid == -1) {
            return true;
        }
        if (profile.contains(FetchProfile.Item.ENVELOPE) && envelope == null) {
            return true;
        }
        if (profile.contains(FetchProfile.Item.FLAGS) && flags == null) {
            return true;
        }
        if (profile.contains(FetchProfile.Item.CONTENT_INFO) && bodyStructure == null) {
            return true;
        }
        // The following profile items are our implementation of items that the
        // Sun IMAPFolder implementation supports.
        if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS) && !allHeadersRetrieved) {
            return true;
        }
        if (profile.contains(IMAPFolder.FetchProfileItem.SIZE) && bodyStructure.bodySize < 0) {
            return true;
        }
        // last bit after checking each of the information types is to see if
        // particular headers have been requested and whether those are on the
        // set we do have loaded.
        String [] requestedHeaders = profile.getHeaderNames();

        // ok, any missing header in the list is enough to force us to request the
        // information.
        for (int i = 0; i < requestedHeaders.length; i++) {
            if (headers.getHeader(requestedHeaders[i]) == null) {
                return true;
            }
        }
        // this message, at least, does not need anything fetched.
        return false;
    }

    /**
     * Update a message instance with information retrieved via an IMAP FETCH
     * command.  The command response for this message may contain multiple pieces
     * that we need to process.
     *
     * @param response The response line, which may contain multiple data items.
     *
     * @exception MessagingException
     */
    void updateMessageInformation(IMAPFetchResponse response) throws MessagingException {
        // get the list of data items associated with this response.  We can have
        // a large number of items returned in a single update.
        List items = response.getDataItems();

        for (int i = 0; i < items.size(); i++) {
            IMAPFetchDataItem item = (IMAPFetchDataItem)items.get(i);

            switch (item.getType()) {
                // if the envelope has been requested, we'll end up with all of these items.
                case IMAPFetchDataItem.ENVELOPE:
                    // update the envelope and map the envelope items into the headers.
                    updateEnvelope((IMAPEnvelope)item);
                    break;
                case IMAPFetchDataItem.INTERNALDATE:
                    receivedDate = ((IMAPInternalDate)item).getDate();;
                    break;
                case IMAPFetchDataItem.SIZE:
                    size = ((IMAPMessageSize)item).size;
                    break;
                case IMAPFetchDataItem.UID:
                    uid = ((IMAPUid)item).uid;
                    // make sure the folder knows about the UID update.
                    ((IMAPFolder)folder).addToUidCache(new Long(uid), this);
                    break;
                case IMAPFetchDataItem.BODYSTRUCTURE:
                    updateBodyStructure((IMAPBodyStructure)item);
                    break;
                    // a partial or full header update
                case IMAPFetchDataItem.HEADER:
                {
                    // if we've fetched the complete set, then replace what we have
                    IMAPInternetHeader h = (IMAPInternetHeader)item;
                    if (h.isComplete()) {
                        // we've got a complete header set now.
                        this.headers = h.headers;
                        allHeadersRetrieved = true;
                    }
                    else {
                        // need to merge the requested headers in with
                        // our existing set.  We need to be careful, since we
                        // don't want to add duplicates.
                        mergeHeaders(h.headers);
                    }
                }
                default:
            }
        }
    }


    /**
     * Merge a subset of the requested headers with our existing partial set.
     * The new set will contain all headers requested from the server, plus
     * any of our existing headers that were not included in the retrieved set.
     *
     * @param newHeaders The retrieved set of headers.
     */
    protected synchronized void mergeHeaders(InternetHeaders newHeaders) {
        // This is sort of tricky to manage.  The input headers object is a fresh set
        // retrieved from the server, but it's a subset of the headers.  Our existing set
        // might not be complete, but it may contain duplicates of information in the
        // retrieved set, plus headers that are not in the retrieved set.  To keep from
        // adding duplicates, we'll only add headers that are not in the retrieved set to
        // that set.

        // start by running through the list of headers
        Enumeration e = headers.getAllHeaders();

        while (e.hasMoreElements()) {
            Header header = (Header)e.nextElement();
            // if there are no headers with this name in the new set, then
            // we can add this.  Note that to add the header, we need to
            // retrieve all instances by this name and add them as a unit.
            // When we hit one of the duplicates again with the enumeration,
            // we'll skip it then because the merge target will have everything.
            if (newHeaders.getHeader(header.getName()) == null) {
                // get all occurrences of this name and stuff them into the
                // new list
                String name = header.getName();
                String[] a = headers.getHeader(name);
                for (int i = 0; i < a.length; i++) {
                    newHeaders.addHeader(name, a[i]);
                }
            }
        }
        // and replace the current header set
        headers = newHeaders;
    }
}
