You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by rm...@apache.org on 2014/08/26 20:17:09 UTC

svn commit: r1620683 [2/17] - in /geronimo/specs/trunk: ./ geronimo-javamail_1.5_spec/ geronimo-javamail_1.5_spec/src/ geronimo-javamail_1.5_spec/src/main/ geronimo-javamail_1.5_spec/src/main/java/ geronimo-javamail_1.5_spec/src/main/java/javax/ geroni...

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Folder.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Folder.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Folder.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Folder.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,749 @@
+/*
+ * 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 javax.mail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.Flags.Flag;
+import javax.mail.event.ConnectionEvent;
+import javax.mail.event.ConnectionListener;
+import javax.mail.event.FolderEvent;
+import javax.mail.event.FolderListener;
+import javax.mail.event.MailEvent;
+import javax.mail.event.MessageChangedEvent;
+import javax.mail.event.MessageChangedListener;
+import javax.mail.event.MessageCountEvent;
+import javax.mail.event.MessageCountListener;
+import javax.mail.search.SearchTerm;
+
+/**
+ * An abstract representation of a folder in a mail system; subclasses would
+ * implement Folders for each supported protocol.
+ * <p/>
+ * Depending on protocol and implementation, folders may contain other folders, messages,
+ * or both as indicated by the {@link Folder#HOLDS_FOLDERS} and {@link Folder#HOLDS_MESSAGES} flags.
+ * If the immplementation supports hierarchical folders, the format of folder names is
+ * implementation dependent; however, components of the name are separated by the
+ * delimiter character returned by {@link Folder#getSeparator()}.
+ * <p/>
+ * The case-insensitive folder name "INBOX" is reserved to refer to the primary folder
+ * for the current user on the current server; not all stores will provide an INBOX
+ * and it may not be available at all times.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class Folder {
+    /**
+     * Flag that indicates that a folder can contain messages.
+     */
+    public static final int HOLDS_MESSAGES = 1;
+    /**
+     * Flag that indicates that a folder can contain other folders.
+     */
+    public static final int HOLDS_FOLDERS = 2;
+
+    /**
+     * Flag indicating that this folder cannot be modified.
+     */
+    public static final int READ_ONLY = 1;
+    /**
+     * Flag indictaing that this folder can be modified.
+     * Question: what does it mean if both are set?
+     */
+    public static final int READ_WRITE = 2;
+
+    /**
+     * The store that this folder is part of.
+     */
+    protected Store store;
+    /**
+     * The current mode of this folder.
+     * When open, this can be {@link #READ_ONLY} or {@link #READ_WRITE};
+     * otherwise is set to -1.
+     */
+    protected int mode = -1;
+
+    private final ArrayList connectionListeners = new ArrayList(2);
+    private final ArrayList folderListeners = new ArrayList(2);
+    private final ArrayList messageChangedListeners = new ArrayList(2);
+    private final ArrayList messageCountListeners = new ArrayList(2);
+    // the EventQueue spins off a new thread, so we only create this 
+    // if we have actual listeners to dispatch an event to. 
+    private EventQueue queue = null;
+
+    /**
+     * Constructor that initializes the Store.
+     *
+     * @param store the store that this folder is part of
+     */
+    protected Folder(final Store store) {
+        this.store = store;
+    }
+
+    /**
+     * Return the name of this folder.
+     * This can be invoked when the folder is closed.
+     *
+     * @return this folder's name
+     */
+    public abstract String getName();
+
+    /**
+     * Return the full absolute name of this folder.
+     * This can be invoked when the folder is closed.
+     *
+     * @return the full name of this folder
+     */
+    public abstract String getFullName();
+
+    /**
+     * Return the URLName for this folder, which includes the location of the store.
+     *
+     * @return the URLName for this folder
+     * @throws MessagingException
+     */
+    public URLName getURLName() throws MessagingException {
+        final URLName baseURL = store.getURLName(); 
+        return new URLName(baseURL.getProtocol(), baseURL.getHost(), baseURL.getPort(), 
+            getFullName(), baseURL.getUsername(), null); 
+    }
+
+    /**
+     * Return the store that this folder is part of.
+     *
+     * @return the store this folder is part of
+     */
+    public Store getStore() {
+        return store;
+    }
+
+    /**
+     * Return the parent for this folder; if the folder is at the root of a heirarchy
+     * this returns null.
+     * This can be invoked when the folder is closed.
+     *
+     * @return this folder's parent
+     * @throws MessagingException
+     */
+    public abstract Folder getParent() throws MessagingException;
+
+    /**
+     * Check to see if this folder physically exists in the store.
+     * This can be invoked when the folder is closed.
+     *
+     * @return true if the folder really exists
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract boolean exists() throws MessagingException;
+
+    /**
+     * Return a list of folders from this Folder's namespace that match the supplied pattern.
+     * Patterns may contain the following wildcards:
+     * <ul><li>'%' which matches any characater except hierarchy delimiters</li>
+     * <li>'*' which matches any character including hierarchy delimiters</li>
+     * </ul>
+     * This can be invoked when the folder is closed.
+     *
+     * @param pattern the pattern to search for
+     * @return a, possibly empty, array containing Folders that matched the pattern
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract Folder[] list(String pattern) throws MessagingException;
+
+    /**
+     * Return a list of folders to which the user is subscribed and which match the supplied pattern.
+     * If the store does not support the concept of subscription then this should match against
+     * all folders; the default implementation of this method achieves this by defaulting to the
+     * {@link #list(String)} method.
+     *
+     * @param pattern the pattern to search for
+     * @return a, possibly empty, array containing subscribed Folders that matched the pattern
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder[] listSubscribed(final String pattern) throws MessagingException {
+        return list(pattern);
+    }
+
+    /**
+     * Convenience method that invokes {@link #list(String)} with the pattern "%".
+     *
+     * @return a, possibly empty, array of subfolders
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder[] list() throws MessagingException {
+        return list("%");
+    }
+
+    /**
+     * Convenience method that invokes {@link #listSubscribed(String)} with the pattern "%".
+     *
+     * @return a, possibly empty, array of subscribed subfolders
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Folder[] listSubscribed() throws MessagingException {
+        return listSubscribed("%");
+    }
+
+    /**
+     * Return the character used by this folder's Store to separate path components.
+     *
+     * @return the name separater character
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract char getSeparator() throws MessagingException;
+
+    /**
+     * Return the type of this folder, indicating whether it can contain subfolders,
+     * messages, or both. The value returned is a bitmask with the appropriate bits set.
+     *
+     * @return the type of this folder
+     * @throws MessagingException if there was a problem accessing the store
+     * @see #HOLDS_FOLDERS
+     * @see #HOLDS_MESSAGES
+     */
+    public abstract int getType() throws MessagingException;
+
+    /**
+     * Create a new folder capable of containing subfoldera and/or messages as
+     * determined by the type parameter. Any hierarchy defined by the folder
+     * name will be recursively created.
+     * If the folder was sucessfully created, a {@link FolderEvent#CREATED CREATED FolderEvent}
+     * is sent to all FolderListeners registered with this Folder or with the Store.
+     *
+     * @param type the type, indicating if this folder should contain subfolders, messages or both
+     * @return true if the folder was sucessfully created
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract boolean create(int type) throws MessagingException;
+
+    /**
+     * Determine if the user is subscribed to this Folder. The default implementation in
+     * this class always returns true.
+     *
+     * @return true is the user is subscribed to this Folder
+     */
+    public boolean isSubscribed() {
+        return true;
+    }
+
+    /**
+     * Set the user's subscription to this folder.
+     * Not all Stores support subscription; the default implementation in this class
+     * always throws a MethodNotSupportedException
+     *
+     * @param subscribed whether to subscribe to this Folder
+     * @throws MessagingException          if there was a problem accessing the store
+     * @throws MethodNotSupportedException if the Store does not support subscription
+     */
+    public void setSubscribed(final boolean subscribed) throws MessagingException {
+        throw new MethodNotSupportedException();
+    }
+
+    /**
+     * Check to see if this Folder conatins messages with the {@link Flag.RECENT} flag set.
+     * This can be used when the folder is closed to perform a light-weight check for new mail;
+     * to perform an incremental check for new mail the folder must be opened.
+     *
+     * @return true if the Store has recent messages
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract boolean hasNewMessages() throws MessagingException;
+
+    /**
+     * Get the Folder determined by the supplied name; if the name is relative
+     * then it is interpreted relative to this folder. This does not check that
+     * the named folder actually exists.
+     *
+     * @param name the name of the folder to return
+     * @return the named folder
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract Folder getFolder(String name) throws MessagingException;
+
+    /**
+     * Delete this folder and possibly any subfolders. This operation can only be
+     * performed on a closed folder.
+     * If recurse is true, then all subfolders are deleted first, then any messages in
+     * this folder are removed and it is finally deleted; {@link FolderEvent#DELETED}
+     * events are sent as appropriate.
+     * If recurse is false, then the behaviour depends on the folder type and store
+     * implementation as followd:
+     * <ul>
+     * <li>If the folder can only conrain messages, then all messages are removed and
+     * then the folder is deleted; a {@link FolderEvent#DELETED} event is sent.</li>
+     * <li>If the folder can onlu contain subfolders, then if it is empty it will be
+     * deleted and a {@link FolderEvent#DELETED} event is sent; if the folder is not
+     * empty then the delete fails and this method returns false.</li>
+     * <li>If the folder can contain both subfolders and messages, then if the folder
+     * does not contain any subfolders, any messages are deleted, the folder itself
+     * is deleted and a {@link FolderEvent#DELETED} event is sent; if the folder does
+     * contain subfolders then the implementation may choose from the following three
+     * behaviors:
+     * <ol>
+     * <li>it may return false indicting the operation failed</li>
+     * <li>it may remove all messages within the folder, send a {@link FolderEvent#DELETED}
+     * event, and then return true to indicate the delete was performed. Note this does
+     * not delete the folder itself and the {@link #exists()} operation for this folder
+     * will return true</li>
+     * <li>it may remove all messages within the folder as per the previous option; in
+     * addition it may change the type of the Folder to only HOLDS_FOLDERS indictaing
+     * that messages may no longer be added</li>
+     * </li>
+     * </ul>
+     * FolderEvents are sent to all listeners registered with this folder or
+     * with the Store.
+     *
+     * @param recurse whether subfolders should be recursively deleted as well
+     * @return true if the delete operation succeeds
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract boolean delete(boolean recurse) throws MessagingException;
+
+    /**
+     * Rename this folder; the folder must be closed.
+     * If the rename is successfull, a {@link FolderEvent#RENAMED} event is sent to
+     * all listeners registered with this folder or with the store.
+     *
+     * @param newName the new name for this folder
+     * @return true if the rename succeeded
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract boolean renameTo(Folder newName) throws MessagingException;
+
+    /**
+     * Open this folder; the folder must be able to contain messages and
+     * must currently be closed. If the folder is opened successfully then
+     * a {@link ConnectionEvent#OPENED} event is sent to listeners registered
+     * with this Folder.
+     * <p/>
+     * Whether the Store allows multiple connections or if it allows multiple
+     * writers is implementation defined.
+     *
+     * @param mode READ_ONLY or READ_WRITE
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract void open(int mode) throws MessagingException;
+
+    /**
+     * Close this folder; it must already be open.
+     * A {@link ConnectionEvent#CLOSED} event is sent to all listeners registered
+     * with this folder.
+     *
+     * @param expunge whether to expunge all deleted messages
+     * @throws MessagingException if there was a problem accessing the store; the folder is still closed
+     */
+    public abstract void close(boolean expunge) throws MessagingException;
+
+    /**
+     * Indicates that the folder has been opened.
+     *
+     * @return true if the folder is open
+     */
+    public abstract boolean isOpen();
+
+    /**
+     * Return the mode of this folder ass passed to {@link #open(int)}, or -1 if
+     * the folder is closed.
+     *
+     * @return the mode this folder was opened with
+     */
+    public int getMode() {
+        return mode;
+    }
+
+    /**
+     * Get the flags supported by this folder.
+     *
+     * @return the flags supported by this folder, or null if unknown
+     * @see Flags
+     */
+    public abstract Flags getPermanentFlags();
+
+    /**
+     * Return the number of messages this folder contains.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     *
+     * @return the number of messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract int getMessageCount() throws MessagingException;
+
+    /**
+     * Return the numbew of messages in this folder that have the {@link Flag.RECENT} flag set.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     * The default implmentation of this method iterates over all messages
+     * in the folder; subclasses should override if possible to provide a more
+     * efficient implementation.
+     *
+     * @return the number of new messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public int getNewMessageCount() throws MessagingException {
+        return getCount(Flags.Flag.RECENT, true);
+    }
+
+    /**
+     * Return the numbew of messages in this folder that do not have the {@link Flag.SEEN} flag set.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     * The default implmentation of this method iterates over all messages
+     * in the folder; subclasses should override if possible to provide a more
+     * efficient implementation.
+     *
+     * @return the number of new messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public int getUnreadMessageCount() throws MessagingException {
+        return getCount(Flags.Flag.SEEN, false);
+    }
+
+    /**
+     * Return the numbew of messages in this folder that have the {@link Flag.DELETED} flag set.
+     * If this operation is invoked on a closed folder, the implementation
+     * may choose to return -1 to avoid the expense of opening the folder.
+     * The default implmentation of this method iterates over all messages
+     * in the folder; subclasses should override if possible to provide a more
+     * efficient implementation.
+     *
+     * @return the number of new messages, or -1 if unknown
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public int getDeletedMessageCount() throws MessagingException {
+        return getCount(Flags.Flag.DELETED, true);
+    }
+
+    private int getCount(final Flag flag, final boolean value) throws MessagingException {
+        if (!isOpen()) {
+            return -1;
+        }
+        final Message[] messages = getMessages();
+        int total = 0;
+        for (int i = 0; i < messages.length; i++) {
+            if (messages[i].getFlags().contains(flag) == value) {
+                total++;
+            }
+        }
+        return total;
+    }
+
+    /**
+     * Retrieve the message with the specified index in this Folder;
+     * messages indices start at 1 not zero.
+     * Clients should note that the index for a specific message may change
+     * if the folder is expunged; {@link Message} objects should be used as
+     * references instead.
+     *
+     * @param index the index of the message to fetch
+     * @return the message
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract Message getMessage(int index) throws MessagingException;
+
+    /**
+     * Retrieve messages with index between start and end inclusive
+     *
+     * @param start index of first message
+     * @param end   index of last message
+     * @return an array of messages from start to end inclusive
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Message[] getMessages(int start, final int end) throws MessagingException {
+        final Message[] result = new Message[end - start + 1];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = getMessage(start++);
+        }
+        return result;
+    }
+
+    /**
+     * Retrieve messages with the specified indices.
+     *
+     * @param ids the indices of the messages to fetch
+     * @return the specified messages
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Message[] getMessages(final int ids[]) throws MessagingException {
+        final Message[] result = new Message[ids.length];
+        for (int i = 0; i < ids.length; i++) {
+            result[i] = getMessage(ids[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Retrieve all messages.
+     *
+     * @return all messages in this folder
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Message[] getMessages() throws MessagingException {
+        return getMessages(1, getMessageCount());
+    }
+
+    /**
+     * Append the supplied messages to this folder. A {@link MessageCountEvent} is sent
+     * to all listeners registered with this folder when all messages have been appended.
+     * If the array contains a previously expunged message, it must be re-appended to the Store
+     * and implementations must not abort this operation.
+     *
+     * @param messages the messages to append
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract void appendMessages(Message[] messages) throws MessagingException;
+
+    /**
+     * Hint to the store to prefetch information on the supplied messaged.
+     * Subclasses should override this method to provide an efficient implementation;
+     * the default implementation in this class simply returns.
+     *
+     * @param messages messages for which information should be fetched
+     * @param profile  the information to fetch
+     * @throws MessagingException if there was a problem accessing the store
+     * @see FetchProfile
+     */
+    public void fetch(final Message[] messages, final FetchProfile profile) throws MessagingException {
+        return;
+    }
+
+    /**
+     * Set flags on the messages to the supplied value; all messages must belong to this folder.
+     * This method may be overridden by subclasses that can optimize the setting
+     * of flags on multiple messages at once; the default implementation simply calls
+     * {@link Message#setFlags(Flags, boolean)} for each supplied messages.
+     *
+     * @param messages whose flags should be set
+     * @param flags    the set of flags to modify
+     * @param value    the value the flags should be set to
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public void setFlags(final Message[] messages, final Flags flags, final boolean value) throws MessagingException {
+        for (int i = 0; i < messages.length; i++) {
+            final Message message = messages[i];
+            message.setFlags(flags, value);
+        }
+    }
+
+    /**
+     * Set flags on a range of messages to the supplied value.
+     * This method may be overridden by subclasses that can optimize the setting
+     * of flags on multiple messages at once; the default implementation simply
+     * gets each message and then calls {@link Message#setFlags(Flags, boolean)}.
+     *
+     * @param start first message end set
+     * @param end   last message end set
+     * @param flags the set of flags end modify
+     * @param value the value the flags should be set end
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public void setFlags(final int start, final int end, final Flags flags, final boolean value) throws MessagingException {
+        for (int i = start; i <= end; i++) {
+            final Message message = getMessage(i);
+            message.setFlags(flags, value);
+        }
+    }
+
+    /**
+     * Set flags on a set of messages to the supplied value.
+     * This method may be overridden by subclasses that can optimize the setting
+     * of flags on multiple messages at once; the default implementation simply
+     * gets each message and then calls {@link Message#setFlags(Flags, boolean)}.
+     *
+     * @param ids   the indexes of the messages to set
+     * @param flags the set of flags end modify
+     * @param value the value the flags should be set end
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public void setFlags(final int ids[], final Flags flags, final boolean value) throws MessagingException {
+        for (int i = 0; i < ids.length; i++) {
+            final Message message = getMessage(ids[i]);
+            message.setFlags(flags, value);
+        }
+    }
+
+    /**
+     * Copy the specified messages to another folder.
+     * The default implementation simply appends the supplied messages to the
+     * target folder using {@link #appendMessages(Message[])}.
+     * @param messages the messages to copy
+     * @param folder the folder to copy to
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public void copyMessages(final Message[] messages, final Folder folder) throws MessagingException {
+        folder.appendMessages(messages);
+    }
+
+    /**
+     * Permanently delete all supplied messages that have the DELETED flag set from the Store.
+     * The original message indices of all messages actually deleted are returned and a
+     * {@link MessageCountEvent} event is sent to all listeners with this folder. The expunge
+     * may cause the indices of all messaged that remain in the folder to change.
+     *
+     * @return the original indices of messages that were actually deleted
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public abstract Message[] expunge() throws MessagingException;
+
+    /**
+     * Search this folder for messages matching the supplied search criteria.
+     * The default implementation simply invoke <code>search(term, getMessages())
+     * applying the search over all messages in the folder; subclasses may provide
+     * a more efficient mechanism.
+     *
+     * @param term the search criteria
+     * @return an array containing messages that match the criteria
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Message[] search(final SearchTerm term) throws MessagingException {
+        return search(term, getMessages());
+    }
+
+    /**
+     * Search the supplied messages for those that match the supplied criteria;
+     * messages must belong to this folder.
+     * The default implementation iterates through the messages, returning those
+     * whose {@link Message#match(javax.mail.search.SearchTerm)} method returns true;
+     * subclasses may provide a more efficient implementation.
+     *
+     * @param term the search criteria
+     * @param messages the messages to search
+     * @return an array containing messages that match the criteria
+     * @throws MessagingException if there was a problem accessing the store
+     */
+    public Message[] search(final SearchTerm term, final Message[] messages) throws MessagingException {
+        final List result = new ArrayList(messages.length);
+        for (int i = 0; i < messages.length; i++) {
+            final Message message = messages[i];
+            if (message.match(term)) {
+                result.add(message);
+            }
+        }
+        return (Message[]) result.toArray(new Message[result.size()]);
+    }
+
+    public void addConnectionListener(final ConnectionListener listener) {
+        connectionListeners.add(listener);
+    }
+
+    public void removeConnectionListener(final ConnectionListener listener) {
+        connectionListeners.remove(listener);
+    }
+
+    protected void notifyConnectionListeners(final int type) {
+        queueEvent(new ConnectionEvent(this, type), connectionListeners);
+    }
+
+    public void addFolderListener(final FolderListener listener) {
+        folderListeners.add(listener);
+    }
+
+    public void removeFolderListener(final FolderListener listener) {
+        folderListeners.remove(listener);
+    }
+
+    protected void notifyFolderListeners(final int type) {
+        queueEvent(new FolderEvent(this, this, type), folderListeners);
+    }
+
+    protected void notifyFolderRenamedListeners(final Folder newFolder) {
+        queueEvent(new FolderEvent(this, this, newFolder, FolderEvent.RENAMED), folderListeners);
+    }
+
+    public void addMessageCountListener(final MessageCountListener listener) {
+        messageCountListeners.add(listener);
+    }
+
+    public void removeMessageCountListener(final MessageCountListener listener) {
+        messageCountListeners.remove(listener);
+    }
+
+    protected void notifyMessageAddedListeners(final Message[] messages) {
+        queueEvent(new MessageCountEvent(this, MessageCountEvent.ADDED, false, messages), messageChangedListeners);
+    }
+
+    protected void notifyMessageRemovedListeners(final boolean removed, final Message[] messages) {
+        queueEvent(new MessageCountEvent(this, MessageCountEvent.REMOVED, removed, messages), messageChangedListeners);
+    }
+
+    public void addMessageChangedListener(final MessageChangedListener listener) {
+        messageChangedListeners.add(listener);
+    }
+
+    public void removeMessageChangedListener(final MessageChangedListener listener) {
+        messageChangedListeners.remove(listener);
+    }
+
+    protected void notifyMessageChangedListeners(final int type, final Message message) {
+        queueEvent(new MessageChangedEvent(this, type, message), messageChangedListeners);
+    }
+
+    /**
+     * Unregisters all listeners.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        // shut our queue down, if needed. 
+        if (queue != null) {
+            queue.stop();
+            queue = null; 
+        }
+        connectionListeners.clear();
+        folderListeners.clear();
+        messageChangedListeners.clear();
+        messageCountListeners.clear();
+        store = null;
+        super.finalize();
+    }
+
+    /**
+     * Returns the full name of this folder; if null, returns the value from the superclass.
+     * @return a string form of this folder
+     */
+    @Override
+    public String toString() {
+        final String name = getFullName();
+        return name == null ? super.toString() : name;
+    }
+    
+    
+    /**
+     * Add an event on the event queue, creating the queue if this is the 
+     * first event with actual listeners. 
+     * 
+     * @param event     The event to dispatch.
+     * @param listeners The listener list.
+     */
+    private synchronized void queueEvent(final MailEvent event, final ArrayList listeners) {
+        // if there are no listeners to dispatch this to, don't put it on the queue. 
+        // This allows us to delay creating the queue (and its new thread) until 
+        // we 
+        if (listeners.isEmpty()) {
+            return; 
+        }
+        // first real event?  Time to get the queue kicked off. 
+        if (queue == null) {
+            queue = new EventQueue(); 
+        }
+        // tee it up and let it rip. 
+        queue.queueEvent(event, (List)listeners.clone()); 
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderClosedException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderClosedException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderClosedException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderClosedException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,60 @@
+/*
+ * 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 javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FolderClosedException extends MessagingException {
+	
+	private static final long serialVersionUID = 1687879213433302315L;
+
+	
+    private transient Folder _folder;
+
+    public FolderClosedException(final Folder folder) {
+        this(folder, "Folder Closed: " + folder.getName());
+    }
+
+    public FolderClosedException(final Folder folder, final String message) {
+        super(message);
+        _folder = folder;
+    }
+    
+    /**
+     * Constructs a FolderClosedException with the specified
+     * detail message and embedded exception.  The exception is chained
+     * to this exception.
+     *
+     * @param folder     The Folder
+     * @param message    The detailed error message
+     * @param e      The embedded exception
+     * @since        JavaMail 1.5
+     */
+    public FolderClosedException(final Folder folder, final String message, final Exception e) {
+        super(message, e);
+        _folder = folder;
+    }
+    
+
+    public Folder getFolder() {
+        return _folder;
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderNotFoundException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderNotFoundException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderNotFoundException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/FolderNotFoundException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FolderNotFoundException extends MessagingException {
+	
+	private static final long serialVersionUID = 472612108891249403L;
+	
+    private transient Folder _folder;
+
+    public FolderNotFoundException() {
+        super();
+    }
+
+    public FolderNotFoundException(final Folder folder) {
+        this(folder, "Folder not found: " + folder.getName());
+    }
+
+    public FolderNotFoundException(final Folder folder, final String message) {
+        super(message);
+        _folder = folder;
+    }
+
+    public FolderNotFoundException(final String message, final Folder folder) {
+        this(folder, message);
+    }
+    
+    /**
+     * Constructs a FolderNotFoundException with the specified
+     * detail message and embedded exception.  The exception is chained
+     * to this exception.
+     *
+     * @param folder The Folder
+     * @param s      The detailed error message
+     * @param e      The embedded exception
+     * @since        JavaMail 1.5
+     */
+    public FolderNotFoundException(final Folder folder, final String s, final Exception e) {
+        super(s, e);
+        _folder = folder;
+    }
+
+    public Folder getFolder() {
+        return _folder;
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Header.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Header.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Header.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Header.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,65 @@
+/*
+ * 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 javax.mail;
+
+/**
+ * Class representing a header field.
+ *
+ * @version $Rev$ $Date$
+ */
+public class Header {
+    /**
+     * The name of the header.
+     */
+    protected String name;
+    /**
+     * The header value (can be null).
+     */
+    protected String value;
+
+    /**
+     * Constructor initializing all immutable fields.
+     *
+     * @param name  the name of this header
+     * @param value the value of this header
+     */
+    public Header(final String name, final String value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    /**
+     * Return the name of this header.
+     *
+     * @return the name of this header
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Return the value of this header.
+     *
+     * @return the value of this header
+     */
+    public String getValue() {
+        return value;
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/IllegalWriteException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/IllegalWriteException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/IllegalWriteException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/IllegalWriteException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IllegalWriteException extends MessagingException {
+	
+	private static final long serialVersionUID = 3974370223328268013L;
+	
+    public IllegalWriteException() {
+        super();
+    }
+
+    public IllegalWriteException(final String message) {
+        super(message);
+    }
+    
+    /**
+     * Constructs an IllegalWriteException with the specified
+     * detail message and embedded exception.  The exception is chained
+     * to this exception.
+     *
+     * @param s      The detailed error message
+     * @param e      The embedded exception
+     * @since        JavaMail 1.5
+     */
+    public IllegalWriteException(final String s, final Exception e) {
+        super(s, e);
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinition.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinition.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinition.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinition.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,74 @@
+package javax.mail;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used by Java EE applications to define a MailSession
+ * to be registered with JNDI.  The MailSession may be configured
+ * by setting the annotation elements for commonly used Session
+ * properties.  Additional standard and vendor-specific properties may be
+ * specified using the properties element.
+ * 
+
+
+ * The session will be registered under the name specified in the
+ * name element.  It may be defined to be in any valid
+ * Java EE namespace, and will determine the accessibility of
+ * the session from other components.
+ *
+ * @since JavaMail 1.5
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MailSessionDefinition {
+
+    /**
+     * Description of this mail session.
+     */
+    String description() default "";
+
+    /**
+     * JNDI name by which the mail session will be registered.
+     */
+    String name();
+
+    /**
+     * Store protocol name.
+     */
+    String storeProtocol() default "";
+
+    /**
+     * Transport protocol name.
+     */
+    String transportProtocol() default "";
+
+    /**
+     * Host name for the mail server.
+     */
+    String host() default "";
+
+    /**
+     * User name to use for authentication.
+     */
+    String user() default "";
+
+    /**
+     * Password to use for authentication.
+     */
+    String password() default "";
+
+    /**
+     * From address for the user.
+     */
+    String from() default "";
+
+    /**
+     * Properties to include in the Session.
+     * Properties are specified using the format:
+     * propertyName=propertyValue with one property per array element.
+     */
+    String[] properties() default {};
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinitions.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinitions.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinitions.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MailSessionDefinitions.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,18 @@
+package javax.mail;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Declares one or more MailSessionDefinition annotations.
+ *
+ * @see MailSessionDefinition
+ * @since JavaMail 1.5
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MailSessionDefinitions {
+    MailSessionDefinition[] value();
+}
\ No newline at end of file

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Message.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Message.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Message.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Message.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,446 @@
+/*
+ * 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 javax.mail;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.mail.search.SearchTerm;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class Message implements Part {
+    /**
+     * Enumeration of types of recipients allowed by the Message class.
+     */
+    public static class RecipientType implements Serializable {
+        /**
+         * A "To" or primary recipient.
+         */
+        public static final RecipientType TO = new RecipientType("To");
+        /**
+         * A "Cc" or carbon-copy recipient.
+         */
+        public static final RecipientType CC = new RecipientType("Cc");
+        /**
+         * A "Bcc" or blind carbon-copy recipient.
+         */
+        public static final RecipientType BCC = new RecipientType("Bcc");
+        protected String type;
+
+        protected RecipientType(final String type) {
+            this.type = type;
+        }
+
+        protected Object readResolve() throws ObjectStreamException {
+            if (type.equals("To")) {
+                return TO;
+            } else if (type.equals("Cc")) {
+                return CC;
+            } else if (type.equals("Bcc")) {
+                return BCC;
+            } else {
+                throw new InvalidObjectException("Invalid RecipientType: " + type);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return type;
+        }
+    }
+
+    /**
+     * The index of a message within its folder, or zero if the message was not retrieved from a folder.
+     */
+    protected int msgnum;
+    /**
+     * True if this message has been expunged from the Store.
+     */
+    protected boolean expunged;
+    /**
+     * The {@link Folder} that contains this message, or null if it was not obtained from a folder.
+     */
+    protected Folder folder;
+    /**
+     * The {@link Session} associated with this message.
+     */
+    protected Session session;
+
+    /**
+     * Default constructor.
+     */
+    protected Message() {
+    }
+
+    /**
+     * Constructor initializing folder and message msgnum; intended to be used by implementations of Folder.
+     *
+     * @param folder the folder that contains the message
+     * @param msgnum the message index within the folder
+     */
+    protected Message(final Folder folder, final int msgnum) {
+        this.folder = folder;
+        this.msgnum = msgnum;
+        // make sure we copy the session information from the folder.
+        this.session = folder.getStore().getSession();
+    }
+
+    /**
+     * Constructor initializing the session; intended to by used by client created instances.
+     *
+     * @param session the session associated with this message
+     */
+    protected Message(final Session session) {
+        this.session = session;
+    }
+
+    /**
+     * Return the "From" header indicating the identity of the person the message is from;
+     * in some circumstances this may be different than the actual sender.
+     *
+     * @return a list of addresses this message is from; may be empty if the header is present but empty, or null
+     *         if the header is not present
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract Address[] getFrom() throws MessagingException;
+
+    /**
+     * Set the "From" header for this message to the value of the "mail.user" property,
+     * or if that property is not set, to the value of the system property "user.name"
+     *
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void setFrom() throws MessagingException;
+
+    /**
+     * Set the "From" header to the supplied address.
+     *
+     * @param address the address of the person the message is from
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void setFrom(Address address) throws MessagingException;
+
+    /**
+     * Add multiple addresses to the "From" header.
+     *
+     * @param addresses the addresses to add
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void addFrom(Address[] addresses) throws MessagingException;
+
+    /**
+     * Get all recipients of the given type.
+     *
+     * @param type the type of recipient to get
+     * @return a list of addresses; may be empty if the header is present but empty,
+     *         or null if the header is not present
+     * @throws MessagingException if there was a problem accessing the Store
+     * @see RecipientType
+     */
+    public abstract Address[] getRecipients(RecipientType type) throws MessagingException;
+
+    /**
+     * Get all recipients of this message.
+     * The default implementation extracts the To, Cc, and Bcc recipients using {@link #getRecipients(javax.mail.Message.RecipientType)}
+     * and then concatentates the results into a single array; it returns null if no headers are defined.
+     *
+     * @return an array containing all recipients
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public Address[] getAllRecipients() throws MessagingException {
+        final Address[] to = getRecipients(RecipientType.TO);
+        final Address[] cc = getRecipients(RecipientType.CC);
+        final Address[] bcc = getRecipients(RecipientType.BCC);
+        if (to == null && cc == null && bcc == null) {
+            return null;
+        }
+        final int length = (to != null ? to.length : 0) + (cc != null ? cc.length : 0) + (bcc != null ? bcc.length : 0);
+        final Address[] result = new Address[length];
+        int j = 0;
+        if (to != null) {
+            for (int i = 0; i < to.length; i++) {
+                result[j++] = to[i];
+            }
+        }
+        if (cc != null) {
+            for (int i = 0; i < cc.length; i++) {
+                result[j++] = cc[i];
+            }
+        }
+        if (bcc != null) {
+            for (int i = 0; i < bcc.length; i++) {
+                result[j++] = bcc[i];
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Set the list of recipients for the specified type.
+     *
+     * @param type      the type of recipient
+     * @param addresses the new addresses
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void setRecipients(RecipientType type, Address[] addresses) throws MessagingException;
+
+    /**
+     * Set the list of recipients for the specified type to a single address.
+     *
+     * @param type    the type of recipient
+     * @param address the new address
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public void setRecipient(final RecipientType type, final Address address) throws MessagingException {
+        setRecipients(type, new Address[]{address});
+    }
+
+    /**
+     * Add recipents of a specified type.
+     *
+     * @param type      the type of recipient
+     * @param addresses the addresses to add
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void addRecipients(RecipientType type, Address[] addresses) throws MessagingException;
+
+    /**
+     * Add a recipent of a specified type.
+     *
+     * @param type    the type of recipient
+     * @param address the address to add
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public void addRecipient(final RecipientType type, final Address address) throws MessagingException {
+        addRecipients(type, new Address[]{address});
+    }
+
+    /**
+     * Get the addresses to which replies should be directed.
+     * <p/>
+     * As the most common behavior is to return to sender, the default implementation
+     * simply calls {@link #getFrom()}.
+     *
+     * @return a list of addresses to which replies should be directed
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public Address[] getReplyTo() throws MessagingException {
+        return getFrom();
+    }
+
+    /**
+     * Set the addresses to which replies should be directed.
+     * <p/>
+     * The default implementation throws a MethodNotSupportedException.
+     *
+     * @param addresses to which replies should be directed
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public void setReplyTo(final Address[] addresses) throws MessagingException {
+        throw new MethodNotSupportedException("setReplyTo not supported");
+    }
+
+    /**
+     * Get the subject for this message.
+     *
+     * @return the subject
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract String getSubject() throws MessagingException;
+
+    /**
+     * Set the subject of this message
+     *
+     * @param subject the subject
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void setSubject(String subject) throws MessagingException;
+
+    /**
+     * Return the date that this message was sent.
+     *
+     * @return the date this message was sent
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract Date getSentDate() throws MessagingException;
+
+    /**
+     * Set the date this message was sent.
+     *
+     * @param sent the date when this message was sent
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void setSentDate(Date sent) throws MessagingException;
+    
+    /**
+     * Return the Session used when this message was created.
+     *
+     * @return      the message's Session
+     * @since       JavaMail 1.5
+     */
+    public Session getSession() {
+        return this.session;
+    }
+
+    /**
+     * Return the date this message was received.
+     *
+     * @return the date this message was received
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract Date getReceivedDate() throws MessagingException;
+
+    /**
+     * 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 abstract Flags getFlags() throws MessagingException;
+
+    /**
+     * 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 boolean isSet(final Flags.Flag flag) throws MessagingException {
+        return getFlags().contains(flag);
+    }
+
+    /**
+     * Set the flags specified to the supplied value; flags not included in the
+     * supplied {@link Flags} parameter are not affected.
+     *
+     * @param flags the flags to modify
+     * @param set   the new value of those flags
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void setFlags(Flags flags, boolean set) throws MessagingException;
+
+    /**
+     * Set a flag to the supplied value.
+     * The default implmentation uses {@link #setFlags(Flags, boolean)}.
+     *
+     * @param flag the flag to set
+     * @param set  the value for that flag
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public void setFlag(final Flags.Flag flag, final boolean set) throws MessagingException {
+        setFlags(new Flags(flag), set);
+    }
+
+    /**
+     * Return the message number for this Message.
+     * This number refers to the relative position of this message in a Folder; the message
+     * number for any given message can change during a session if the Folder is expunged.
+     * Message numbers for messages in a folder start at one; the value zero indicates that
+     * this message does not belong to a folder.
+     *
+     * @return the message number
+     */
+    public int getMessageNumber() {
+        return msgnum;
+    }
+
+    /**
+     * Set the message number for this Message.
+     * This must be invoked by implementation classes when the message number changes.
+     *
+     * @param number the new message number
+     */
+    protected void setMessageNumber(final int number) {
+        msgnum = number;
+    }
+
+    /**
+     * Return the folder containing this message. If this is a new or nested message
+     * then this method returns null.
+     *
+     * @return the folder containing this message
+     */
+    public Folder getFolder() {
+        return folder;
+    }
+
+    /**
+     * Checks to see if this message has been expunged. If true, all methods other than
+     * {@link #getMessageNumber()} are invalid.
+     *
+     * @return true if this method has been expunged
+     */
+    public boolean isExpunged() {
+        return expunged;
+    }
+
+    /**
+     * Set the expunged flag for this message.
+     *
+     * @param expunged true if this message has been expunged
+     */
+    protected void setExpunged(final boolean expunged) {
+        this.expunged = expunged;
+    }
+
+    /**
+     * Create a new message suitable as a reply to this message with all headers set
+     * up appropriately. The message body will be empty.
+     * <p/>
+     * if replyToAll is set then the new message will be addressed to all recipients
+     * of this message; otherwise the reply will be addressed only to the sender as
+     * returned by {@link #getReplyTo()}.
+     * <p/>
+     * The subject field will be initialized with the subject field from the orginal
+     * message; the text "Re:" will be prepended unless it is already present.
+     *
+     * @param replyToAll if true, indciates the message should be addressed to all recipients not just the sender
+     * @return a new message suitable as a reply to this message
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract Message reply(boolean replyToAll) throws MessagingException;
+
+    /**
+     * To ensure changes are saved to the Store, this message should be invoked
+     * before its containing Folder is closed. Implementations may save modifications
+     * immediately but are free to defer such updates to they may be sent to the server
+     * in one batch; if saveChanges is not called then such changes may not be made
+     * permanent.
+     *
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public abstract void saveChanges() throws MessagingException;
+
+    /**
+     * Apply the specified search criteria to this message
+     *
+     * @param term the search criteria
+     * @return true if this message matches the search criteria.
+     * @throws MessagingException if there was a problem accessing the Store
+     */
+    public boolean match(final SearchTerm term) throws MessagingException {
+        return term.match(this);
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageAware.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageAware.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageAware.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageAware.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,27 @@
+/*
+ * 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 javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface MessageAware {
+    public abstract MessageContext getMessageContext();
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageContext.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageContext.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageContext.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageContext.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,93 @@
+/*
+ * 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 javax.mail;
+
+/**
+ * The context in which a piece of message content is contained.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MessageContext {
+    private final Part part;
+
+    /**
+     * Create a MessageContext object describing the context of the supplied Part.
+     *
+     * @param part the containing part
+     */
+    public MessageContext(final Part part) {
+        this.part = part;
+    }
+
+    /**
+     * Return the {@link Part} that contains the content.
+     *
+     * @return the part
+     */
+    public Part getPart() {
+        return part;
+    }
+
+    /**
+     * Return the message that contains the content; if the Part is a {@link Multipart}
+     * then recurse up the chain until a {@link Message} is found.
+     *
+     * @return
+     */
+    public Message getMessage() {
+        return getMessageFrom(part);
+    }
+
+    /**
+     * Return the session associated with the Message containing this Part.
+     *
+     * @return the session associated with this context's root message
+     */
+    public Session getSession() {
+        final Message message = getMessage();
+        if (message == null) {
+            return null;
+        } else {
+            return message.session;
+        }
+    }
+
+    /**
+     * recurse up the chain of MultiPart/BodyPart parts until we hit a message
+     * 
+     * @param p      The starting part.
+     * 
+     * @return The encountered Message or null if no Message parts
+     *         are found.
+     */
+    private Message getMessageFrom(Part p) {
+        while (p != null) {
+            if (p instanceof Message) {
+                return (Message) p;
+            }
+            final Multipart mp = ((BodyPart) p).getParent();
+            if (mp == null) {
+                return null;
+            }
+            p = mp.getParent();
+        }
+        return null;
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageRemovedException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageRemovedException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageRemovedException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessageRemovedException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MessageRemovedException extends MessagingException {
+	
+	private static final long serialVersionUID = 1951292550679528690L;
+	
+    public MessageRemovedException() {
+        super();
+    }
+
+    public MessageRemovedException(final String message) {
+        super(message);
+    }
+    
+    /**
+     * Constructs a MessageRemovedException with the specified
+     * detail message and embedded exception.  The exception is chained
+     * to this exception.
+     *
+     * @param s      The detailed error message
+     * @param e      The embedded exception
+     * @since        JavaMail 1.5
+     */
+    public MessageRemovedException(final String s, final Exception e) {
+        super(s, e);
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessagingException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessagingException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessagingException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MessagingException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,83 @@
+/*
+ * 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 javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MessagingException extends Exception {
+
+    private static final long serialVersionUID = -7569192289819959253L;
+
+    // Required because serialization expects it to be here
+    private Exception next;
+
+    public MessagingException() {
+        super();
+    }
+
+    public MessagingException(final String message) {
+        super(message);
+    }
+
+    public MessagingException(final String message, final Exception cause) {
+        super(message, cause);
+        next = cause;
+    }
+
+    public synchronized Exception getNextException() {
+        return next;
+    }
+
+    public synchronized boolean setNextException(final Exception cause) {
+        if (next == null) {
+            next = cause;
+            return true;
+        } else if (next instanceof MessagingException) {
+            return ((MessagingException) next).setNextException(cause);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public String getMessage() {
+        final Exception next = getNextException();
+        if (next == null) {
+            return super.getMessage();
+        } else {
+            return super.getMessage()
+                    + " ("
+                    + next.getClass().getName()
+                    + ": "
+                    + next.getMessage()
+                    + ")";
+        }
+    }
+    
+    /**
+     * MessagingException uses the nextException to provide a legacy chained throwable.
+     * override the getCause method to return the nextException.
+     */
+    @Override
+    public synchronized  Throwable getCause() {
+        return next;
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MethodNotSupportedException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MethodNotSupportedException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MethodNotSupportedException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MethodNotSupportedException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodNotSupportedException extends MessagingException {
+	
+	private static final long serialVersionUID = -3757386618726131322L;
+	
+    public MethodNotSupportedException() {
+        super();
+    }
+
+    public MethodNotSupportedException(final String message) {
+        super(message);
+    }
+    
+    /**
+     * Constructs a MethodNotSupportedException with the specified
+     * detail message and embedded exception.  The exception is chained
+     * to this exception.
+     *
+     * @param s      The detailed error message
+     * @param e      The embedded exception
+     * @since        JavaMail 1.5
+     */
+    public MethodNotSupportedException(final String s, final Exception e) {
+        super(s, e);
+    }
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Multipart.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Multipart.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Multipart.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/Multipart.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,166 @@
+/*
+ * 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 javax.mail;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+/**
+ * A container for multiple {@link BodyPart BodyParts}.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class Multipart {
+    /**
+     * Vector of sub-parts.
+     */
+    protected Vector parts = new Vector();
+
+    /**
+     * The content type of this multipart object; defaults to "multipart/mixed"
+     */
+    protected String contentType = "multipart/mixed";
+
+    /**
+     * The Part that contains this multipart.
+     */
+    protected Part parent;
+
+    protected Multipart() {
+    }
+
+    /**
+     * Initialize this multipart object from the supplied data source.
+     * This adds any {@link BodyPart BodyParts} into this object and initializes the content type.
+     *
+     * @param mds the data source
+     * @throws MessagingException
+     */
+    protected void setMultipartDataSource(final MultipartDataSource mds) throws MessagingException {
+        parts.clear();
+        contentType = mds.getContentType();
+        final int size = mds.getCount();
+        for (int i = 0; i < size; i++) {
+            parts.add(mds.getBodyPart(i));
+        }
+    }
+
+    /**
+     * Return the content type.
+     *
+     * @return the content type
+     */
+    public String getContentType() {
+        return contentType;
+    }
+
+    /**
+     * Return the number of enclosed parts
+     *
+     * @return the number of parts
+     * @throws MessagingException
+     */
+    public int getCount() throws MessagingException {
+        return parts.size();
+    }
+
+    /**
+     * Get the specified part; numbering starts at zero.
+     *
+     * @param index the part to get
+     * @return the part
+     * @throws MessagingException
+     */
+    public BodyPart getBodyPart(final int index) throws MessagingException {
+        return (BodyPart) parts.get(index);
+    }
+
+    /**
+     * Remove the supplied part from the list.
+     *
+     * @param part the part to remove
+     * @return true if the part was removed
+     * @throws MessagingException
+     */
+    public boolean removeBodyPart(final BodyPart part) throws MessagingException {
+        return parts.remove(part);
+    }
+
+    /**
+     * Remove the specified part; all others move down one
+     *
+     * @param index the part to remove
+     * @throws MessagingException
+     */
+    public void removeBodyPart(final int index) throws MessagingException {
+        parts.remove(index);
+    }
+
+    /**
+     * Add a part to the end of the list.
+     *
+     * @param part the part to add
+     * @throws MessagingException
+     */
+    public void addBodyPart(final BodyPart part) throws MessagingException {
+        parts.add(part);
+    }
+
+    /**
+     * Insert a part into the list at a designated point; all subsequent parts move down
+     *
+     * @param part the part to add
+     * @param pos  the index of the new part
+     * @throws MessagingException
+     */
+    public void addBodyPart(final BodyPart part, final int pos) throws MessagingException {
+        parts.add(pos, part);
+    }
+
+    /**
+     * Encode and write this multipart to the supplied OutputStream; the encoding
+     * used is determined by the implementation.
+     *
+     * @param out the stream to write to
+     * @throws IOException
+     * @throws MessagingException
+     */
+    public abstract void writeTo(OutputStream out) throws IOException, MessagingException;
+
+    /**
+     * Return the Part containing this Multipart object or null if unknown.
+     *
+     * @return this Multipart's parent
+     */
+    public Part getParent() {
+        return parent;
+    }
+
+    /**
+     * Set the parent of this Multipart object
+     *
+     * @param part this object's parent
+     */
+    public void setParent(final Part part) {
+        parent = part;
+    }
+
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MultipartDataSource.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MultipartDataSource.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MultipartDataSource.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/MultipartDataSource.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,31 @@
+/*
+ * 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 javax.mail;
+
+import javax.activation.DataSource;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface MultipartDataSource extends DataSource {
+    public abstract BodyPart getBodyPart(int index) throws MessagingException;
+
+    public abstract int getCount();
+}

Added: geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/NoSuchProviderException.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/NoSuchProviderException.java?rev=1620683&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/NoSuchProviderException.java (added)
+++ geronimo/specs/trunk/geronimo-javamail_1.5_spec/src/main/java/javax/mail/NoSuchProviderException.java Tue Aug 26 18:17:06 2014
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package javax.mail;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NoSuchProviderException extends MessagingException {
+	
+	private static final long serialVersionUID = 8058319293154708827L;
+	
+    public NoSuchProviderException() {
+        super();
+    }
+
+    public NoSuchProviderException(final String message) {
+        super(message);
+    }
+    
+    /**
+     * Constructs a NoSuchProviderException with the specified
+     * detail message and embedded exception.  The exception is chained
+     * to this exception.
+     *
+     * @param message    The detailed error message
+     * @param e      The embedded exception
+     * @since        JavaMail 1.5
+     */
+    public NoSuchProviderException(final String message, final Exception e) {
+        super(message, e);
+    }
+}