You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jl...@apache.org on 2006/04/01 00:24:56 UTC

svn commit: r390524 [6/7] - in /geronimo/trunk/modules/javamail-transport/src/java/org/apache/geronimo/javamail: authentication/ store/nntp/ store/nntp/newsrc/ store/pop3/ store/pop3/message/ store/pop3/response/ transport/nntp/ transport/smtp/ util/

Modified: geronimo/trunk/modules/javamail-transport/src/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/javamail-transport/src/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java?rev=390524&r1=390523&r2=390524&view=diff
==============================================================================
--- geronimo/trunk/modules/javamail-transport/src/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java (original)
+++ geronimo/trunk/modules/javamail-transport/src/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java Fri Mar 31 14:24:52 2006
@@ -49,32 +49,25 @@
 import org.apache.geronimo.javamail.authentication.DigestMD5Authenticator;
 import org.apache.geronimo.javamail.authentication.LoginAuthenticator;
 import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
-import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
-import org.apache.geronimo.mail.util.Base64;
-import org.apache.geronimo.mail.util.XText;
-
 import org.apache.geronimo.javamail.util.MIMEOutputStream;
 import org.apache.geronimo.javamail.util.TraceInputStream;
 import org.apache.geronimo.javamail.util.TraceOutputStream;
+import org.apache.geronimo.mail.util.Base64;
+import org.apache.geronimo.mail.util.XText;
 
 /**
- * Simple implementation of SMTP transport.  Just does plain RFC821-ish
- * delivery.
- * <p/>
- * Supported properties :
- * <p/>
+ * Simple implementation of SMTP transport. Just does plain RFC821-ish delivery.
+ * <p/> Supported properties : <p/>
  * <ul>
- * <li> mail.host : to set the server to deliver to.  Default = localhost</li>
- * <li> mail.smtp.port : to set the port.  Default = 25</li>
+ * <li> mail.host : to set the server to deliver to. Default = localhost</li>
+ * <li> mail.smtp.port : to set the port. Default = 25</li>
  * <li> mail.smtp.locahost : name to use for HELO/EHLO - default getHostName()</li>
  * </ul>
- * <p/>
- * There is no way to indicate failure for a given recipient (it's possible to have a
- * recipient address rejected).  The sun impl throws exceptions even if others successful),
- * but maybe we do a different way...
- * <p/>
- * TODO : lots.  ESMTP, user/pass, indicate failure, etc...
- *
+ * <p/> There is no way to indicate failure for a given recipient (it's possible
+ * to have a recipient address rejected). The sun impl throws exceptions even if
+ * others successful), but maybe we do a different way... <p/> TODO : lots.
+ * ESMTP, user/pass, indicate failure, etc...
+ * 
  * @version $Rev$ $Date$
  */
 public class SMTPTransport extends Transport {
@@ -83,97 +76,148 @@
      * constants for EOL termination
      */
     protected static final char CR = '\r';
+
     protected static final char LF = '\n';
 
     /**
      * property keys for top level session properties.
      */
     protected static final String MAIL_LOCALHOST = "mail.localhost";
-    protected static final String MAIL_SSLFACTORY_CLASS = "mail.SSLSocketFactory.class";
 
+    protected static final String MAIL_SSLFACTORY_CLASS = "mail.SSLSocketFactory.class";
 
     /**
-     * property keys for protocol properties.  The actual property name will
-     * be appended with "mail." + protocol + ".", where the protocol is either
+     * property keys for protocol properties. The actual property name will be
+     * appended with "mail." + protocol + ".", where the protocol is either
      * "smtp" or "smtps".
      */
     protected static final String MAIL_SMTP_AUTH = "auth";
+
     protected static final String MAIL_SMTP_PORT = "port";
+
     protected static final String MAIL_SMTP_LOCALHOST = "localhost";
+
     protected static final String MAIL_SMTP_TIMEOUT = "timeout";
+
     protected static final String MAIL_SMTP_SASL_REALM = "sasl.realm";
+
     protected static final String MAIL_SMTP_TLS = "starttls.enable";
+
     protected static final String MAIL_SMTP_FACTORY_CLASS = "socketFactory.class";
+
     protected static final String MAIL_SMTP_FACTORY_FALLBACK = "socketFactory.fallback";
+
     protected static final String MAIL_SMTP_FACTORY_PORT = "socketFactory.port";
+
     protected static final String MAIL_SMTP_REPORT_SUCCESS = "reportsuccess";
+
     protected static final String MAIL_SMTP_STARTTLS_ENABLE = "starttls.enable";
+
     protected static final String MAIL_SMTP_DSN_NOTIFY = "dsn.notify";
+
     protected static final String MAIL_SMTP_SENDPARTIAL = "sendpartial";
+
     protected static final String MAIL_SMTP_LOCALADDRESS = "localaddress";
+
     protected static final String MAIL_SMTP_LOCALPORT = "localport";
+
     protected static final String MAIL_SMTP_QUITWAIT = "quitwait";
+
     protected static final String MAIL_SMTP_FROM = "from";
+
     protected static final String MAIL_SMTP_DSN_RET = "dsn.ret";
+
     protected static final String MAIL_SMTP_SUBMITTER = "submitter";
+
     protected static final String MAIL_SMTP_EXTENSION = "mailextension";
+
     protected static final String MAIL_SMTP_EHLO = "ehlo";
-    protected static final String MAIL_SMTP_ENCODE_TRACE = "encodetrace";
 
+    protected static final String MAIL_SMTP_ENCODE_TRACE = "encodetrace";
 
     protected static final int MIN_MILLIS = 1000 * 60;
+
     protected static final int TIMEOUT = MIN_MILLIS * 5;
+
     protected static final String DEFAULT_MAIL_HOST = "localhost";
+
     protected static final int DEFAULT_MAIL_SMTP_PORT = 25;
+
     protected static final int DEFAULT_MAIL_SMTPS_PORT = 465;
 
     // SMTP reply codes
     protected static final int SERVICE_READY = 220;
+
     protected static final int SERVICE_CLOSING = 221;
+
     protected static final int AUTHENTICATION_COMPLETE = 235;
+
     protected static final int COMMAND_ACCEPTED = 250;
+
     protected static final int ADDRESS_NOT_LOCAL = 251;
 
     protected static final int AUTHENTICATION_CHALLENGE = 334;
+
     protected static final int START_MAIL_INPUT = 354;
 
     protected static final int SERVICE_NOT_AVAILABLE = 421;
+
     protected static final int MAILBOX_BUSY = 450;
+
     protected static final int PROCESSING_ERROR = 451;
+
     protected static final int INSUFFICIENT_STORAGE = 452;
 
     protected static final int COMMAND_SYNTAX_ERROR = 500;
+
     protected static final int PARAMETER_SYNTAX_ERROR = 501;
+
     protected static final int COMMAND_NOT_IMPLEMENTED = 502;
+
     protected static final int INVALID_COMMAND_SEQUENCE = 503;
+
     protected static final int COMMAND_PARAMETER_NOT_IMPLEMENTED = 504;
+
     protected static final int MAILBOX_NOT_FOUND = 550;
+
     protected static final int USER_NOT_LOCAL = 551;
+
     protected static final int MAILBOX_FULL = 552;
+
     protected static final int INVALID_MAILBOX = 553;
+
     protected static final int TRANSACTION_FAILED = 553;
 
     protected static final String AUTHENTICATION_PLAIN = "PLAIN";
+
     protected static final String AUTHENTICATION_LOGIN = "LOGIN";
+
     protected static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
+
     protected static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
 
-    // the protocol we're working with.  This will be either "smtp" or "smtps".
+    // the protocol we're working with. This will be either "smtp" or "smtps".
     protected String protocol;
+
     // the target host
     protected String host;
-    // the default port to use for this protocol (differs between "smtp" and "smtps").
+
+    // the default port to use for this protocol (differs between "smtp" and
+    // "smtps").
     protected int defaultPort;
+
     // the target server port.
     protected int port;
 
-    // the connection socket...can be a plain socket or SSLSocket, if TLS is being used.
+    // the connection socket...can be a plain socket or SSLSocket, if TLS is
+    // being used.
     protected Socket socket;
 
     // our local host name
     protected String localHost;
 
-    // input stream used to read data.  If Sasl is in use, this might be other than the
+    // input stream used to read data. If Sasl is in use, this might be other
+    // than the
     // direct access to the socket input stream.
     protected InputStream inputStream;
 
@@ -182,24 +226,30 @@
 
     // list of authentication mechanisms supported by the server
     protected HashMap serverAuthenticationMechanisms;
+
     // map of server extension arguments
     protected HashMap serverExtensionArgs;
 
     // do we report success after completion of each mail send.
     protected boolean reportSuccess;
+
     // does the server support transport level security?
     protected boolean serverTLS = false;
+
     // is TLS enabled on our part?
     protected boolean useTLS = false;
+
     // do we use SSL for our initial connection?
     protected boolean sslConnection = false;
 
-
     // the username we connect with
     protected String username;
+
     // the authentication password.
     protected String password;
-    // the target SASL realm (normally null unless explicitly set or we have an authentication mechanism that
+
+    // the target SASL realm (normally null unless explicitly set or we have an
+    // authentication mechanism that
     // requires it.
     protected String realm;
 
@@ -209,38 +259,40 @@
     // our session provided debug output stream.
     protected PrintStream debugStream;
 
-
     /**
-     * Normal constructor for an SMTPTransport() object.  This
-     * constructor is used to build a transport instance for the
-     * "smtp" protocol.
-     *
-     * @param session The attached session.
-     * @param name    An optional URLName object containing target information.
+     * Normal constructor for an SMTPTransport() object. This constructor is
+     * used to build a transport instance for the "smtp" protocol.
+     * 
+     * @param session
+     *            The attached session.
+     * @param name
+     *            An optional URLName object containing target information.
      */
     public SMTPTransport(Session session, URLName name) {
         this(session, name, "smtp", DEFAULT_MAIL_SMTP_PORT, false);
     }
 
     /**
-     * Common constructor used by the SMTPTransport and SMTPSTransport
-     * classes to do common initialization of defaults.
-     *
-     * @param session  The host session instance.
-     * @param name     The URLName of the target.
-     * @param protocol The protocol type (either "smtp" or "smtps".  This helps us
-     *                 in retrieving protocol-specific session properties.
+     * Common constructor used by the SMTPTransport and SMTPSTransport classes
+     * to do common initialization of defaults.
+     * 
+     * @param session
+     *            The host session instance.
+     * @param name
+     *            The URLName of the target.
+     * @param protocol
+     *            The protocol type (either "smtp" or "smtps". This helps us in
+     *            retrieving protocol-specific session properties.
      * @param defaultPort
-     *                 The default port used by this protocol.  For "smtp", this
-     *                 will be 25.  The default for "smtps" is 465.
+     *            The default port used by this protocol. For "smtp", this will
+     *            be 25. The default for "smtps" is 465.
      * @param sslConnection
-     *                 Indicates whether an SSL connection should be used to initial
-     *                 contact the server.  This is different from the STARTTLS
-     *                 support, which switches the connection to SSL after the
-     *                 initial startup.
+     *            Indicates whether an SSL connection should be used to initial
+     *            contact the server. This is different from the STARTTLS
+     *            support, which switches the connection to SSL after the
+     *            initial startup.
      */
-    protected SMTPTransport(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection)
-    {
+    protected SMTPTransport(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
         super(session, name);
         this.protocol = protocol;
 
@@ -258,13 +310,12 @@
         System.out.println("Debug value in transport = " + debug);
     }
 
-
     /**
-     * Connect to a server using an already created socket.  This
-     * connection is just like any other connection, except we will
-     * not create a new socket.
-     *
-     * @param socket The socket connection to use.
+     * Connect to a server using an already created socket. This connection is
+     * just like any other connection, except we will not create a new socket.
+     * 
+     * @param socket
+     *            The socket connection to use.
      */
     public void connect(Socket socket) throws MessagingException {
         this.socket = socket;
@@ -272,39 +323,47 @@
     }
 
     /**
-     * Do the protocol connection for an SMTP transport.  This
-     * handles server authentication, if possible.  Returns false if
-     * unable to connect to the server.
-     *
-     * @param host     The target host name.
-     * @param port     The server port number.
-     * @param user     The authentication user (if any).
-     * @param password The server password.  Might not be sent directly if more
-     *                 sophisticated authentication is used.
-     *
-     * @return true if we were able to connect to the server properly, false
-     *         for any failures.
+     * Do the protocol connection for an SMTP transport. This handles server
+     * authentication, if possible. Returns false if unable to connect to the
+     * server.
+     * 
+     * @param host
+     *            The target host name.
+     * @param port
+     *            The server port number.
+     * @param user
+     *            The authentication user (if any).
+     * @param password
+     *            The server password. Might not be sent directly if more
+     *            sophisticated authentication is used.
+     * 
+     * @return true if we were able to connect to the server properly, false for
+     *         any failures.
      * @exception MessagingException
      */
-    protected boolean protocolConnect(String host, int port, String username, String password) throws MessagingException
-    {
+    protected boolean protocolConnect(String host, int port, String username, String password)
+            throws MessagingException {
         if (debug) {
             debugOut("Connecting to server " + host + ":" + port + " for user " + username);
         }
 
-        // first check to see if we need to authenticate.  If we need this, then we must have a username and
-        // password specified.  Failing this may result in a user prompt to collect the information.
+        // first check to see if we need to authenticate. If we need this, then
+        // we must have a username and
+        // password specified. Failing this may result in a user prompt to
+        // collect the information.
         boolean mustAuthenticate = isProtocolPropertyTrue(MAIL_SMTP_AUTH);
 
-        // if we need to authenticate, and we don't have both a userid and password, then we fail this
-        // immediately.  The Service.connect() method will try to obtain the user information and retry the
+        // if we need to authenticate, and we don't have both a userid and
+        // password, then we fail this
+        // immediately. The Service.connect() method will try to obtain the user
+        // information and retry the
         // connection one time.
         if (mustAuthenticate && (username == null || password == null)) {
             return false;
         }
 
-
-        // if the port is defaulted, then see if we have something configured in the session.
+        // if the port is defaulted, then see if we have something configured in
+        // the session.
         // if not configured, we just use the default default.
         if (port == -1) {
             // take the default first.
@@ -315,7 +374,6 @@
             }
         }
 
-
         try {
 
             // create socket and connect to server.
@@ -349,10 +407,12 @@
 
     /**
      * Send a message to multiple addressees.
-     *
-     * @param message   The message we're sending.
-     * @param addresses An array of addresses to send to.
-     *
+     * 
+     * @param message
+     *            The message we're sending.
+     * @param addresses
+     *            An array of addresses to send to.
+     * 
      * @exception MessagingException
      */
     public void sendMessage(Message message, Address[] addresses) throws MessagingException {
@@ -364,7 +424,8 @@
             throw new MessagingException("Null message");
         }
 
-        // SMTP only handles instances of MimeMessage, not the more general message case.
+        // SMTP only handles instances of MimeMessage, not the more general
+        // message case.
         if (!(message instanceof MimeMessage)) {
             throw new MessagingException("SMTP can only send MimeMessages");
         }
@@ -376,26 +437,26 @@
 
         boolean haveGroup = false;
 
-        // enforce the requirement that all of the targets are InternetAddress instances.
+        // enforce the requirement that all of the targets are InternetAddress
+        // instances.
         for (int i = 0; i < addresses.length; i++) {
             if (addresses[i] instanceof InternetAddress) {
-                // and while we're here, see if we have a groups in the address list. If we do, then
+                // and while we're here, see if we have a groups in the address
+                // list. If we do, then
                 // we're going to need to expand these before sending.
-                if (((InternetAddress)addresses[i]).isGroup()) {
+                if (((InternetAddress) addresses[i]).isGroup()) {
                     haveGroup = true;
                 }
-            }
-            else {
+            } else {
                 throw new MessagingException("Illegal InternetAddress " + addresses[i]);
             }
         }
 
-        // did we find a group?  Time to expand this into our full target list.
+        // did we find a group? Time to expand this into our full target list.
         if (haveGroup) {
             addresses = expandGroups(addresses);
         }
 
-
         SendStatus[] stats = new SendStatus[addresses.length];
 
         // create our lists for notification and exception reporting.
@@ -404,10 +465,10 @@
         Address[] invalid = null;
 
         try {
-            // send sender first.  If this failed, send a failure notice of the event, using the full list of
+            // send sender first. If this failed, send a failure notice of the
+            // event, using the full list of
             // addresses as the unsent, and nothing for the rest.
-            if (!sendMailFrom(message))
-            {
+            if (!sendMailFrom(message)) {
                 unsent = addresses;
                 sent = new Address[0];
                 invalid = new Address[0];
@@ -417,58 +478,61 @@
                 // include the reponse information here.
                 SMTPReply last = lastServerResponse;
                 // now send an "uber-exception" to indicate the failure.
-                throw new SMTPSendFailedException("MAIL FROM", last.getCode(), last.getMessage(), null, sent, unsent, invalid);
+                throw new SMTPSendFailedException("MAIL FROM", last.getCode(), last.getMessage(), null, sent, unsent,
+                        invalid);
             }
 
             String dsn = null;
 
-            // there's an optional notification argument that can be added to MAIL TO.  See if we've been
+            // there's an optional notification argument that can be added to
+            // MAIL TO. See if we've been
             // provided with one.
 
             // an SMTPMessage object is the first source
             if (message instanceof SMTPMessage) {
                 // get the notification options
-                int options = ((SMTPMessage)message).getNotifyOptions();
+                int options = ((SMTPMessage) message).getNotifyOptions();
 
                 switch (options) {
-                    // a zero value indicates nothing is set.
-                    case 0:
-                        break;
-
-                    case SMTPMessage.NOTIFY_NEVER:
-                        dsn = "NEVER";
-                        break;
-
-                    case SMTPMessage.NOTIFY_SUCCESS:
-                        dsn = "SUCCESS";
-                        break;
-
-                    case SMTPMessage.NOTIFY_FAILURE:
-                        dsn = "FAILURE";
-                        break;
-
-                    case SMTPMessage.NOTIFY_DELAY:
-                        dsn = "DELAY";
-                        break;
-
-                    // now for combinations...there are few enough combinations here
-                    // that we can just handle this in the switch statement rather than have to
-                    // concatentate everything together.
-                    case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE):
-                        dsn = "SUCCESS,FAILURE";
-                        break;
-
-                    case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_DELAY):
-                        dsn = "SUCCESS,DELAY";
-                        break;
-
-                    case (SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
-                        dsn = "FAILURE,DELAY";
-                        break;
-
-                    case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
-                        dsn = "SUCCESS,FAILURE,DELAY";
-                        break;
+                // a zero value indicates nothing is set.
+                case 0:
+                    break;
+
+                case SMTPMessage.NOTIFY_NEVER:
+                    dsn = "NEVER";
+                    break;
+
+                case SMTPMessage.NOTIFY_SUCCESS:
+                    dsn = "SUCCESS";
+                    break;
+
+                case SMTPMessage.NOTIFY_FAILURE:
+                    dsn = "FAILURE";
+                    break;
+
+                case SMTPMessage.NOTIFY_DELAY:
+                    dsn = "DELAY";
+                    break;
+
+                // now for combinations...there are few enough combinations here
+                // that we can just handle this in the switch statement rather
+                // than have to
+                // concatentate everything together.
+                case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE):
+                    dsn = "SUCCESS,FAILURE";
+                    break;
+
+                case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_DELAY):
+                    dsn = "SUCCESS,DELAY";
+                    break;
+
+                case (SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
+                    dsn = "FAILURE,DELAY";
+                    break;
+
+                case (SMTPMessage.NOTIFY_SUCCESS + SMTPMessage.NOTIFY_FAILURE + SMTPMessage.NOTIFY_DELAY):
+                    dsn = "SUCCESS,FAILURE,DELAY";
+                    break;
                 }
             }
 
@@ -477,51 +541,58 @@
                 dsn = getProtocolProperty(MAIL_SMTP_DSN_NOTIFY);
             }
 
-            // we need to know about any failures once we've gone through the complete list, so keep a
+            // we need to know about any failures once we've gone through the
+            // complete list, so keep a
             // failure flag.
             boolean sendFailure = false;
 
-            // event notifcation requires we send lists of successes and failures broken down by category.
+            // event notifcation requires we send lists of successes and
+            // failures broken down by category.
             // The categories are:
             //
             // 1) addresses successfully processed.
-            // 2) addresses deemed valid, but had a processing failure that prevented sending.
-            // 3) addressed deemed invalid (basically all other processing failures).
+            // 2) addresses deemed valid, but had a processing failure that
+            // prevented sending.
+            // 3) addressed deemed invalid (basically all other processing
+            // failures).
             ArrayList sentAddresses = new ArrayList();
             ArrayList unsentAddresses = new ArrayList();
             ArrayList invalidAddresses = new ArrayList();
 
-            // Now we add a MAIL TO record for each recipient.  At this point, we just collect
+            // Now we add a MAIL TO record for each recipient. At this point, we
+            // just collect
             for (int i = 0; i < addresses.length; i++) {
-                InternetAddress target = (InternetAddress)addresses[i];
+                InternetAddress target = (InternetAddress) addresses[i];
 
                 // write out the record now.
                 SendStatus status = sendRcptTo(target, dsn);
                 stats[i] = status;
 
                 switch (status.getStatus()) {
-                    // successfully sent
-                    case SendStatus.SUCCESS:
-                        sentAddresses.add(target);
-                        break;
-
-                    // we have an invalid address of some sort, or a general sending error (which we'll
-                    // interpret as due to an invalid address.
-                    case SendStatus.INVALID_ADDRESS:
-                    case SendStatus.GENERAL_ERROR:
-                        sendFailure = true;
-                        invalidAddresses.add(target);
-                        break;
-
-                    // good address, but this was a send failure.
-                    case SendStatus.SEND_FAILURE:
-                        sendFailure = true;
-                        unsentAddresses.add(target);
-                        break;
+                // successfully sent
+                case SendStatus.SUCCESS:
+                    sentAddresses.add(target);
+                    break;
+
+                // we have an invalid address of some sort, or a general sending
+                // error (which we'll
+                // interpret as due to an invalid address.
+                case SendStatus.INVALID_ADDRESS:
+                case SendStatus.GENERAL_ERROR:
+                    sendFailure = true;
+                    invalidAddresses.add(target);
+                    break;
+
+                // good address, but this was a send failure.
+                case SendStatus.SEND_FAILURE:
+                    sendFailure = true;
+                    unsentAddresses.add(target);
+                    break;
                 }
             }
 
-            // if we had a send failure, then we need to check if we allow partial sends.  If not allowed,
+            // if we had a send failure, then we need to check if we allow
+            // partial sends. If not allowed,
             // we abort the send operation now.
             if (sendFailure) {
                 // now see how we're configured for this send operation.
@@ -529,30 +600,34 @@
 
                 // this can be attached directly to the message.
                 if (message instanceof SMTPMessage) {
-                    partialSends = ((SMTPMessage)message).getSendPartial();
+                    partialSends = ((SMTPMessage) message).getSendPartial();
                 }
 
-                // if still false on the message object, check for a property version also
+                // if still false on the message object, check for a property
+                // version also
                 if (!partialSends) {
                     partialSends = isProtocolPropertyTrue(MAIL_SMTP_SENDPARTIAL);
                 }
 
-
-                // if we're not allowing partial successes or we've failed on all of the addresses, it's
+                // if we're not allowing partial successes or we've failed on
+                // all of the addresses, it's
                 // time to abort.
                 if (!partialSends || sentAddresses.isEmpty()) {
-                    // we send along the valid and invalid address lists on the notifications and
+                    // we send along the valid and invalid address lists on the
+                    // notifications and
                     // exceptions.
-                    // however, since we're aborting the entire send, the successes need to become
+                    // however, since we're aborting the entire send, the
+                    // successes need to become
                     // members of the failure list.
                     unsentAddresses.addAll(sentAddresses);
 
                     // this one is empty.
                     sent = new Address[0];
-                    unsent = (Address[])unsentAddresses.toArray(new Address[0]);
-                    invalid = (Address[])invalidAddresses.toArray(new Address[0]);
+                    unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+                    invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
 
-                    // go reset our connection so we can process additional sends.
+                    // go reset our connection so we can process additional
+                    // sends.
                     resetConnection();
 
                     // get a list of chained exceptions for all of the failures.
@@ -563,43 +638,47 @@
                 }
             }
 
-
             try {
                 // try to send the data
                 sendData(message);
             } catch (MessagingException e) {
-                // If there's an error at this point, this is a complete delivery failure.
-                // we send along the valid and invalid address lists on the notifications and
+                // If there's an error at this point, this is a complete
+                // delivery failure.
+                // we send along the valid and invalid address lists on the
+                // notifications and
                 // exceptions.
-                // however, since we're aborting the entire send, the successes need to become
+                // however, since we're aborting the entire send, the successes
+                // need to become
                 // members of the failure list.
                 unsentAddresses.addAll(sentAddresses);
 
                 // this one is empty.
                 sent = new Address[0];
-                unsent = (Address[])unsentAddresses.toArray(new Address[0]);
-                invalid = (Address[])invalidAddresses.toArray(new Address[0]);
+                unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+                invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
                 // notify of the error.
                 notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, sent, unsent, invalid, message);
                 // send a send failure exception.
                 throw new SMTPSendFailedException("DATA", 0, "Send failure", e, sent, unsent, invalid);
             }
 
-
-            // create our lists for notification and exception reporting from this point on.
-            sent = (Address[])sentAddresses.toArray(new Address[0]);
-            unsent = (Address[])unsentAddresses.toArray(new Address[0]);
-            invalid = (Address[])invalidAddresses.toArray(new Address[0]);
-
-
-            // if sendFailure is true, we had an error during the address phase, but we had permission to
-            // process this as a partial send operation.  Now that the data has been sent ok, it's time to
+            // create our lists for notification and exception reporting from
+            // this point on.
+            sent = (Address[]) sentAddresses.toArray(new Address[0]);
+            unsent = (Address[]) unsentAddresses.toArray(new Address[0]);
+            invalid = (Address[]) invalidAddresses.toArray(new Address[0]);
+
+            // if sendFailure is true, we had an error during the address phase,
+            // but we had permission to
+            // process this as a partial send operation. Now that the data has
+            // been sent ok, it's time to
             // report the partial failure.
             if (sendFailure) {
                 // notify our listeners of the partial delivery.
                 notifyTransportListeners(TransportEvent.MESSAGE_PARTIALLY_DELIVERED, sent, unsent, invalid, message);
 
-                // get a list of chained exceptions for all of the failures (and the successes, if reportSuccess has been
+                // get a list of chained exceptions for all of the failures (and
+                // the successes, if reportSuccess has been
                 // turned on).
                 MessagingException failures = generateExceptionChain(stats, getReportSuccess());
 
@@ -610,17 +689,20 @@
             // notify our listeners of successful delivery.
             notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED, sent, unsent, invalid, message);
 
-            // we've not had any failures, but we've been asked to report success as an exception.  Do
+            // we've not had any failures, but we've been asked to report
+            // success as an exception. Do
             // this now.
             if (reportSuccess) {
-                // generate the chain of success exceptions (we already know there are no failure ones to report).
+                // generate the chain of success exceptions (we already know
+                // there are no failure ones to report).
                 MessagingException successes = generateExceptionChain(stats, reportSuccess);
                 if (successes != null) {
                     throw successes;
                 }
             }
         } catch (SMTPSendFailedException e) {
-            // if this is a send failure, we've already handled notifications....just rethrow it.
+            // if this is a send failure, we've already handled
+            // notifications....just rethrow it.
             throw e;
         } catch (MessagingException e) {
             // notify of the error.
@@ -629,11 +711,10 @@
         }
     }
 
-
     /**
-     * Close the connection.  On completion, we'll be disconnected from
-     * the server and unable to send more data.
-     *
+     * Close the connection. On completion, we'll be disconnected from the
+     * server and unable to send more data.
+     * 
      * @exception MessagingException
      */
     public void close() throws MessagingException {
@@ -645,21 +726,22 @@
             // say goodbye
             sendQuit();
         } finally {
-            // and close up the connection.  We do this in a finally block to make sure the connection
+            // and close up the connection. We do this in a finally block to
+            // make sure the connection
             // is shut down even if quit gets an error.
             closeServerConnection();
         }
     }
 
-
     /**
-     * Turn a series of send status items into a chain of exceptions
-     * indicating the state of each send operation.
-     *
-     * @param stats  The list of SendStatus items.
+     * Turn a series of send status items into a chain of exceptions indicating
+     * the state of each send operation.
+     * 
+     * @param stats
+     *            The list of SendStatus items.
      * @param reportSuccess
-     *               Indicates whether we should include the report success items.
-     *
+     *            Indicates whether we should include the report success items.
+     * 
      * @return The head of a chained list of MessagingExceptions.
      */
     protected MessagingException generateExceptionChain(SendStatus[] stats, boolean reportSuccess) {
@@ -670,12 +752,12 @@
 
             if (status != null) {
                 MessagingException nextException = stats[i].getException(reportSuccess);
-                // if there's an exception associated with this status, chain it up with the rest.
+                // if there's an exception associated with this status, chain it
+                // up with the rest.
                 if (nextException != null) {
                     if (current == null) {
                         current = nextException;
-                    }
-                    else {
+                    } else {
                         current.setNextException(nextException);
                         current = nextException;
                     }
@@ -685,14 +767,14 @@
         return current;
     }
 
-
     /**
      * Reset the server connection after an error.
-     *
+     * 
      * @exception MessagingException
      */
     protected void resetConnection() throws MessagingException {
-        // we want the caller to retrieve the last response responsbile for requiring the reset, so save and
+        // we want the caller to retrieve the last response responsbile for
+        // requiring the reset, so save and
         // restore that info around the reset.
         SMTPReply last = lastServerResponse;
 
@@ -707,28 +789,29 @@
         lastServerResponse = last;
     }
 
-
     /**
-     * Expand the address list by converting any group addresses
-     * into single address targets.
-     *
-     * @param addresses The input array of addresses.
-     *
+     * Expand the address list by converting any group addresses into single
+     * address targets.
+     * 
+     * @param addresses
+     *            The input array of addresses.
+     * 
      * @return The expanded array of addresses.
      * @exception MessagingException
      */
     protected Address[] expandGroups(Address[] addresses) throws MessagingException {
         ArrayList expandedAddresses = new ArrayList();
 
-        // run the list looking for group addresses, and add the full group list to our targets.
+        // run the list looking for group addresses, and add the full group list
+        // to our targets.
         for (int i = 0; i < addresses.length; i++) {
-            InternetAddress address = (InternetAddress)addresses[i];
-            // not a group?  Just copy over to the other list.
+            InternetAddress address = (InternetAddress) addresses[i];
+            // not a group? Just copy over to the other list.
             if (!address.isGroup()) {
                 expandedAddresses.add(address);
-            }
-            else {
-                // get the group address and copy each member of the group into the expanded list.
+            } else {
+                // get the group address and copy each member of the group into
+                // the expanded list.
                 InternetAddress[] groupAddresses = address.getGroup(true);
                 for (int j = 1; j < groupAddresses.length; j++) {
                     expandedAddresses.add(groupAddresses[j]);
@@ -737,21 +820,20 @@
         }
 
         // convert back into an array.
-        return (Address [])expandedAddresses.toArray(new Address[0]);
+        return (Address[]) expandedAddresses.toArray(new Address[0]);
     }
 
-
     /**
-     * Create a transport connection object and connect it to the
-     * target server.
-     *
-     * @param host   The target server host.
-     * @param port   The connection port.
-     *
+     * Create a transport connection object and connect it to the target server.
+     * 
+     * @param host
+     *            The target server host.
+     * @param port
+     *            The connection port.
+     * 
      * @exception MessagingException
      */
-    protected void getConnection(String host, int port, String username, String password) throws IOException
-    {
+    protected void getConnection(String host, int port, String username, String password) throws IOException {
         this.host = host;
         this.port = port;
         this.username = username;
@@ -759,36 +841,42 @@
         // and see if STARTTLS is enabled.
         useTLS = isProtocolPropertyTrue(MAIL_SMTP_TLS);
         serverAuthenticationMechanisms = new HashMap();
-        // We might have been passed a socket to connect with...if not, we need to create one of the correct type.
+        // We might have been passed a socket to connect with...if not, we need
+        // to create one of the correct type.
         if (socket == null) {
             // if this is the "smtps" protocol, we start with an SSLSocket
             if (sslConnection) {
                 getConnectedSSLSocket();
-            }
-            else
-            {
+            } else {
                 getConnectedSocket();
             }
         }
-        // if we already have a socket, get some information from it and override what we've been passed.
+        // if we already have a socket, get some information from it and
+        // override what we've been passed.
         else {
             port = socket.getPort();
             host = socket.getInetAddress().getHostName();
         }
         // now set up the input/output streams.
-        inputStream = new TraceInputStream(socket.getInputStream(), debugStream, debug, isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE)); ;
-        outputStream = new TraceOutputStream(socket.getOutputStream(), debugStream, debug, isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE));
+        inputStream = new TraceInputStream(socket.getInputStream(), debugStream, debug,
+                isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE));
+        ;
+        outputStream = new TraceOutputStream(socket.getOutputStream(), debugStream, debug,
+                isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE));
     }
 
     /**
      * Get a property associated with this mail protocol.
-     *
-     * @param name   The name of the property.
-     *
-     * @return The property value (returns null if the property has not been set).
+     * 
+     * @param name
+     *            The name of the property.
+     * 
+     * @return The property value (returns null if the property has not been
+     *         set).
      */
     protected String getProtocolProperty(String name) {
-        // the name we're given is the least qualified part of the name.  We construct the full property name
+        // the name we're given is the least qualified part of the name. We
+        // construct the full property name
         // using the protocol (either "smtp" or "smtps").
         String fullName = "mail." + protocol + "." + name;
         return getSessionProperty(fullName);
@@ -796,24 +884,28 @@
 
     /**
      * Get a property associated with this mail session.
-     *
-     * @param name   The name of the property.
-     *
-     * @return The property value (returns null if the property has not been set).
+     * 
+     * @param name
+     *            The name of the property.
+     * 
+     * @return The property value (returns null if the property has not been
+     *         set).
      */
     protected String getSessionProperty(String name) {
         return session.getProperty(name);
     }
 
     /**
-     * Get a property associated with this mail session.  Returns
-     * the provided default if it doesn't exist.
-     *
-     * @param name   The name of the property.
+     * Get a property associated with this mail session. Returns the provided
+     * default if it doesn't exist.
+     * 
+     * @param name
+     *            The name of the property.
      * @param defaultValue
-     *               The default value to return if the property doesn't exist.
-     *
-     * @return The property value (returns defaultValue if the property has not been set).
+     *            The default value to return if the property doesn't exist.
+     * 
+     * @return The property value (returns defaultValue if the property has not
+     *         been set).
      */
     protected String getSessionProperty(String name, String defaultValue) {
         String result = session.getProperty(name);
@@ -824,30 +916,35 @@
     }
 
     /**
-     * Get a property associated with this mail session.  Returns
-     * the provided default if it doesn't exist.
-     *
-     * @param name   The name of the property.
+     * Get a property associated with this mail session. Returns the provided
+     * default if it doesn't exist.
+     * 
+     * @param name
+     *            The name of the property.
      * @param defaultValue
-     *               The default value to return if the property doesn't exist.
-     *
-     * @return The property value (returns defaultValue if the property has not been set).
+     *            The default value to return if the property doesn't exist.
+     * 
+     * @return The property value (returns defaultValue if the property has not
+     *         been set).
      */
     protected String getProtocolProperty(String name, String defaultValue) {
-        // the name we're given is the least qualified part of the name.  We construct the full property name
+        // the name we're given is the least qualified part of the name. We
+        // construct the full property name
         // using the protocol (either "smtp" or "smtps").
         String fullName = "mail." + protocol + "." + name;
         return getSessionProperty(fullName, defaultValue);
     }
 
     /**
-     * Get a property associated with this mail session as an integer value.  Returns
-     * the default value if the property doesn't exist or it doesn't have a valid int value.
-     *
-     * @param name   The name of the property.
+     * Get a property associated with this mail session as an integer value.
+     * Returns the default value if the property doesn't exist or it doesn't
+     * have a valid int value.
+     * 
+     * @param name
+     *            The name of the property.
      * @param defaultValue
-     *               The default value to return if the property doesn't exist.
-     *
+     *            The default value to return if the property doesn't exist.
+     * 
      * @return The property value converted to an int.
      */
     protected int getIntSessionProperty(String name, int defaultValue) {
@@ -864,43 +961,46 @@
     }
 
     /**
-     * Get a property associated with this mail session as an integer value.  Returns
-     * the default value if the property doesn't exist or it doesn't have a valid int value.
-     *
-     * @param name   The name of the property.
+     * Get a property associated with this mail session as an integer value.
+     * Returns the default value if the property doesn't exist or it doesn't
+     * have a valid int value.
+     * 
+     * @param name
+     *            The name of the property.
      * @param defaultValue
-     *               The default value to return if the property doesn't exist.
-     *
+     *            The default value to return if the property doesn't exist.
+     * 
      * @return The property value converted to an int.
      */
     protected int getIntProtocolProperty(String name, int defaultValue) {
-        // the name we're given is the least qualified part of the name.  We construct the full property name
+        // the name we're given is the least qualified part of the name. We
+        // construct the full property name
         // using the protocol (either "smtp" or "smtps").
         String fullName = "mail." + protocol + "." + name;
         return getIntSessionProperty(fullName, defaultValue);
     }
 
-
     /**
-     * Process a session property as a boolean value, returning
-     * either true or false.
-     *
-     * @return True if the property value is "true".  Returns false for any
-     *         other value (including null).
+     * Process a session property as a boolean value, returning either true or
+     * false.
+     * 
+     * @return True if the property value is "true". Returns false for any other
+     *         value (including null).
      */
     protected boolean isProtocolPropertyTrue(String name) {
-        // the name we're given is the least qualified part of the name.  We construct the full property name
+        // the name we're given is the least qualified part of the name. We
+        // construct the full property name
         // using the protocol (either "smtp" or "smtps").
         String fullName = "mail." + protocol + "." + name;
         return isSessionPropertyTrue(fullName);
     }
 
     /**
-     * Process a session property as a boolean value, returning
-     * either true or false.
-     *
-     * @return True if the property value is "true".  Returns false for any
-     *         other value (including null).
+     * Process a session property as a boolean value, returning either true or
+     * false.
+     * 
+     * @return True if the property value is "true". Returns false for any other
+     *         value (including null).
      */
     protected boolean isSessionPropertyTrue(String name) {
         String property = session.getProperty(name);
@@ -911,11 +1011,11 @@
     }
 
     /**
-     * Process a session property as a boolean value, returning
-     * either true or false.
-     *
-     * @return True if the property value is "false".  Returns false for
-     *         other value (including null).
+     * Process a session property as a boolean value, returning either true or
+     * false.
+     * 
+     * @return True if the property value is "false". Returns false for other
+     *         value (including null).
      */
     protected boolean isSessionPropertyFalse(String name) {
         String property = session.getProperty(name);
@@ -926,25 +1026,24 @@
     }
 
     /**
-     * Process a session property as a boolean value, returning
-     * either true or false.
-     *
-     * @return True if the property value is "false".  Returns false for
-     *         other value (including null).
+     * Process a session property as a boolean value, returning either true or
+     * false.
+     * 
+     * @return True if the property value is "false". Returns false for other
+     *         value (including null).
      */
     protected boolean isProtocolPropertyFalse(String name) {
-        // the name we're given is the least qualified part of the name.  We construct the full property name
+        // the name we're given is the least qualified part of the name. We
+        // construct the full property name
         // using the protocol (either "smtp" or "smtps").
         String fullName = "mail." + protocol + "." + name;
         return isSessionPropertyTrue(fullName);
     }
 
-
     /**
      * Close the server connection at termination.
      */
-    protected void closeServerConnection()
-    {
+    protected void closeServerConnection() {
         try {
             socket.close();
         } catch (IOException ignored) {
@@ -955,10 +1054,9 @@
         outputStream = null;
     }
 
-
     /**
      * Creates a connected socket
-     *
+     * 
      * @exception MessagingException
      */
     protected void getConnectedSocket() throws IOException {
@@ -966,12 +1064,13 @@
             debugOut("Attempting plain socket connection to server " + host + ":" + port);
         }
 
-
-        // the socket factory can be specified via a session property.  By default, we just directly
+        // the socket factory can be specified via a session property. By
+        // default, we just directly
         // instantiate a socket without using a factor.
         String socketFactory = getProtocolProperty(MAIL_SMTP_FACTORY_CLASS);
 
-        // there are several protocol properties that can be set to tune the created socket.  We need to
+        // there are several protocol properties that can be set to tune the
+        // created socket. We need to
         // retrieve those bits before creating the socket.
         int timeout = getIntProtocolProperty(MAIL_SMTP_TIMEOUT, -1);
         InetAddress localAddress = null;
@@ -986,7 +1085,8 @@
 
         socket = null;
 
-        // if there is no socket factory defined (normal), we just create a socket directly.
+        // if there is no socket factory defined (normal), we just create a
+        // socket directly.
         if (socketFactory == null) {
             socket = new Socket(host, port, localAddress, localPort);
         }
@@ -1002,32 +1102,35 @@
                 ClassLoader loader = Thread.currentThread().getContextClassLoader();
                 Class factoryClass = loader.loadClass(socketFactory);
 
-                // done indirectly, we need to invoke the method using reflection.
+                // done indirectly, we need to invoke the method using
+                // reflection.
                 // This retrieves a factory instance.
                 Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
                 Object defFactory = getDefault.invoke(new Object(), new Object[0]);
 
-                // now that we have the factory, there are two different createSocket() calls we use,
+                // now that we have the factory, there are two different
+                // createSocket() calls we use,
                 // depending on whether we have a localAddress override.
 
                 if (localAddress != null) {
-                    // retrieve the createSocket(String, int, InetAddress, int) method.
+                    // retrieve the createSocket(String, int, InetAddress, int)
+                    // method.
                     Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
                     Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
 
                     Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
-                    socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
-                }
-                else {
+                    socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+                } else {
                     // retrieve the createSocket(String, int) method.
                     Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
                     Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
 
                     Object[] createSocketArgs = new Object[] { host, portArg };
-                    socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
+                    socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
                 }
             } catch (Throwable e) {
-                // if a socket factor is specified, then we may need to fall back to a default.  This behavior
+                // if a socket factor is specified, then we may need to fall
+                // back to a default. This behavior
                 // is controlled by (surprise) more session properties.
                 if (isProtocolPropertyTrue(MAIL_SMTP_FACTORY_FALLBACK)) {
                     if (debug) {
@@ -1035,19 +1138,22 @@
                     }
                     socket = new Socket(host, port, localAddress, localPort);
                 }
-                // we have an exception.  We're going to throw an IOException, which may require unwrapping
+                // we have an exception. We're going to throw an IOException,
+                // which may require unwrapping
                 // or rewrapping the exception.
                 else {
-                    // we have an exception from the reflection, so unwrap the base exception
+                    // we have an exception from the reflection, so unwrap the
+                    // base exception
                     if (e instanceof InvocationTargetException) {
-                        e = ((InvocationTargetException)e).getTargetException();
+                        e = ((InvocationTargetException) e).getTargetException();
                     }
 
                     if (debug) {
                         debugOut("Plain socket creation failure", e);
                     }
 
-                    // throw this as an IOException, with the original exception attached.
+                    // throw this as an IOException, with the original exception
+                    // attached.
                     IOException ioe = new IOException("Error connecting to " + host + ", " + port);
                     ioe.initCause(e);
                     throw ioe;
@@ -1060,21 +1166,24 @@
         }
     }
 
-
     /**
      * Creates a connected SSL socket for an initial SSL connection.
-     *
+     * 
      * @exception MessagingException
      */
     protected void getConnectedSSLSocket() throws IOException {
         if (debug) {
             debugOut("Attempting SSL socket connection to server " + host + ":" + port);
         }
-        // the socket factory can be specified via a protocol property, a session property, and if all else
-        // fails (which it usually does), we fall back to the standard factory class.
-        String socketFactory = getProtocolProperty(MAIL_SMTP_FACTORY_CLASS, getSessionProperty(MAIL_SSLFACTORY_CLASS, "javax.net.ssl.SSLSocketFactory"));
+        // the socket factory can be specified via a protocol property, a
+        // session property, and if all else
+        // fails (which it usually does), we fall back to the standard factory
+        // class.
+        String socketFactory = getProtocolProperty(MAIL_SMTP_FACTORY_CLASS, getSessionProperty(MAIL_SSLFACTORY_CLASS,
+                "javax.net.ssl.SSLSocketFactory"));
 
-        // there are several protocol properties that can be set to tune the created socket.  We need to
+        // there are several protocol properties that can be set to tune the
+        // created socket. We need to
         // retrieve those bits before creating the socket.
         int timeout = getIntProtocolProperty(MAIL_SMTP_TIMEOUT, -1);
         InetAddress localAddress = null;
@@ -1089,13 +1198,15 @@
 
         socket = null;
 
-        // if there is no socket factory defined (normal), we just create a socket directly.
+        // if there is no socket factory defined (normal), we just create a
+        // socket directly.
         if (socketFactory == null) {
             socket = new Socket(host, port, localAddress, localPort);
         }
 
         else {
-            // we'll try this with potentially two different factories if we're allowed to fall back.
+            // we'll try this with potentially two different factories if we're
+            // allowed to fall back.
             boolean fallback = isProtocolPropertyTrue(MAIL_SMTP_FACTORY_FALLBACK);
 
             while (true) {
@@ -1113,32 +1224,36 @@
                     ClassLoader loader = Thread.currentThread().getContextClassLoader();
                     Class factoryClass = loader.loadClass(socketFactory);
 
-                    // done indirectly, we need to invoke the method using reflection.
+                    // done indirectly, we need to invoke the method using
+                    // reflection.
                     // This retrieves a factory instance.
                     Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
                     Object defFactory = getDefault.invoke(new Object(), new Object[0]);
 
-                    // now that we have the factory, there are two different createSocket() calls we use,
+                    // now that we have the factory, there are two different
+                    // createSocket() calls we use,
                     // depending on whether we have a localAddress override.
 
                     if (localAddress != null) {
-                        // retrieve the createSocket(String, int, InetAddress, int) method.
-                        Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
+                        // retrieve the createSocket(String, int, InetAddress,
+                        // int) method.
+                        Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class,
+                                Integer.TYPE };
                         Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
 
                         Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
-                        socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
-                    }
-                    else {
+                        socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+                    } else {
                         // retrieve the createSocket(String, int) method.
                         Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
                         Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
 
                         Object[] createSocketArgs = new Object[] { host, portArg };
-                        socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
+                        socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
                     }
                 } catch (Throwable e) {
-                    // if we're allowed to fallback, then use the default factory and try this again.  We only
+                    // if we're allowed to fallback, then use the default
+                    // factory and try this again. We only
                     // allow this to happen once.
                     if (fallback) {
                         if (debug) {
@@ -1148,19 +1263,22 @@
                         fallback = false;
                         continue;
                     }
-                    // we have an exception.  We're going to throw an IOException, which may require unwrapping
+                    // we have an exception. We're going to throw an
+                    // IOException, which may require unwrapping
                     // or rewrapping the exception.
                     else {
-                        // we have an exception from the reflection, so unwrap the base exception
+                        // we have an exception from the reflection, so unwrap
+                        // the base exception
                         if (e instanceof InvocationTargetException) {
-                            e = ((InvocationTargetException)e).getTargetException();
+                            e = ((InvocationTargetException) e).getTargetException();
                         }
 
                         if (debug) {
                             debugOut("Failure creating SSL socket", e);
                         }
 
-                        // throw this as an IOException, with the original exception attached.
+                        // throw this as an IOException, with the original
+                        // exception attached.
                         IOException ioe = new IOException("Error connecting to " + host + ", " + port);
                         ioe.initCause(e);
                         throw ioe;
@@ -1174,10 +1292,9 @@
         }
     }
 
-
     /**
-     * Switch the connection to using TLS level security,
-     * switching to an SSL socket.
+     * Switch the connection to using TLS level security, switching to an SSL
+     * socket.
      */
     protected void getConnectedTLSSocket() throws MessagingException {
         if (debug) {
@@ -1192,14 +1309,15 @@
             }
             throw new MessagingException("Unable to make TLS server connection");
         }
-     	// it worked, now switch the socket into TLS mode
-     	try {
+        // it worked, now switch the socket into TLS mode
+        try {
 
             // we use the same target and port as the current connection.
             String host = socket.getInetAddress().getHostName();
             int port = socket.getPort();
 
-            // the socket factory can be specified via a session property.  By default, we use
+            // the socket factory can be specified via a session property. By
+            // default, we use
             // the native SSL factory.
             String socketFactory = getProtocolProperty(MAIL_SMTP_FACTORY_CLASS, "javax.net.ssl.SSLSocketFactory");
 
@@ -1219,32 +1337,36 @@
             Object[] createSocketArgs = new Object[] { socket, host, new Integer(port), Boolean.TRUE };
 
             // and finally create the socket
-            Socket sslSocket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
+            Socket sslSocket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
 
-            // if this is an instance of SSLSocket (very common), try setting the protocol to be
-            // "TLSv1".  If this is some other class because of a factory override, we'll just have to
+            // if this is an instance of SSLSocket (very common), try setting
+            // the protocol to be
+            // "TLSv1". If this is some other class because of a factory
+            // override, we'll just have to
             // accept that things will work.
             if (sslSocket instanceof SSLSocket) {
-                ((SSLSocket)sslSocket).setEnabledProtocols(new String[] {"TLSv1"} );
-                ((SSLSocket)sslSocket).setUseClientMode(true);
-                ((SSLSocket)sslSocket).startHandshake();
+                ((SSLSocket) sslSocket).setEnabledProtocols(new String[] { "TLSv1" });
+                ((SSLSocket) sslSocket).setUseClientMode(true);
+                ((SSLSocket) sslSocket).startHandshake();
             }
 
-
-            // and finally, as a last step, replace our input streams with the secure ones.
+            // and finally, as a last step, replace our input streams with the
+            // secure ones.
             // now set up the input/output streams.
-            inputStream = new TraceInputStream(sslSocket.getInputStream(), debugStream, debug, isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE)); ;
-            outputStream = new TraceOutputStream(sslSocket.getOutputStream(), debugStream, debug, isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE));
+            inputStream = new TraceInputStream(sslSocket.getInputStream(), debugStream, debug,
+                    isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE));
+            ;
+            outputStream = new TraceOutputStream(sslSocket.getOutputStream(), debugStream, debug,
+                    isProtocolPropertyTrue(MAIL_SMTP_ENCODE_TRACE));
             // this is our active socket now
             socket = sslSocket;
 
-     	}
-        catch (Exception e) {
+        } catch (Exception e) {
             if (debug) {
                 debugOut("Failure attempting to convert connection to TLS", e);
             }
-     	    throw new MessagingException("Unable to convert connection to SSL", e);
-     	}
+            throw new MessagingException("Unable to convert connection to SSL", e);
+        }
     }
 
     /**
@@ -1256,9 +1378,9 @@
     }
 
     /**
-     * Sends the data in the message down the socket.  This presumes the
-     * server is in the right place and ready for getting the DATA message
-     * and the data right place in the sequence
+     * Sends the data in the message down the socket. This presumes the server
+     * is in the right place and ready for getting the DATA message and the data
+     * right place in the sequence
      */
     protected void sendData(Message msg) throws MessagingException {
 
@@ -1269,16 +1391,21 @@
             throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
         }
 
-        // now the data...  I could look at the type, but
+        // now the data... I could look at the type, but
         try {
-            // the data content has two requirements we need to meet by filtering the
-            // output stream.  Requirement 1 is to conicalize any line breaks.  All line
+            // the data content has two requirements we need to meet by
+            // filtering the
+            // output stream. Requirement 1 is to conicalize any line breaks.
+            // All line
             // breaks will be transformed into properly formed CRLF sequences.
             //
-            // Requirement 2 is to perform byte-stuff for any line that begins with a "."
-            // so that data is not confused with the end-of-data marker (a "\r\n.\r\n" sequence.
+            // Requirement 2 is to perform byte-stuff for any line that begins
+            // with a "."
+            // so that data is not confused with the end-of-data marker (a
+            // "\r\n.\r\n" sequence.
             //
-            // The MIME output stream performs those two functions on behalf of the content
+            // The MIME output stream performs those two functions on behalf of
+            // the content
             // writer.
             OutputStream mimeOut = new MIMEOutputStream(outputStream);
 
@@ -1294,14 +1421,15 @@
         sendLine("");
         sendLine(".");
 
-        // use a longer time out here to give the server time to process the data.
+        // use a longer time out here to give the server time to process the
+        // data.
         try {
-			line = new SMTPReply(receiveLine(TIMEOUT * 2));
-		} catch (MalformedSMTPReplyException e) {
+            line = new SMTPReply(receiveLine(TIMEOUT * 2));
+        } catch (MalformedSMTPReplyException e) {
             throw new MessagingException(e.toString());
-		} catch (MessagingException e) {
+        } catch (MessagingException e) {
             throw new MessagingException(e.toString());
-		}
+        }
 
         if (line.isError()) {
             throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
@@ -1312,12 +1440,13 @@
      * Sends the QUIT message and receieves the response
      */
     protected void sendQuit() throws MessagingException {
-        // there's yet another property that controls whether we should wait for a
-        // reply for a QUIT command.  If on, just send the command and get outta here.
+        // there's yet another property that controls whether we should wait for
+        // a
+        // reply for a QUIT command. If on, just send the command and get outta
+        // here.
         if (isProtocolPropertyTrue(MAIL_SMTP_QUITWAIT)) {
             sendLine("QUIT");
-        }
-        else {
+        } else {
             // handle as a real command...we're going to ignore the response.
             sendCommand("QUIT");
         }
@@ -1325,15 +1454,18 @@
 
     /**
      * Sets a receiver address for the current message
-     *
-     * @param addr   The target address.
-     * @param dsn    An optional notification address appended to the MAIL command.
-     *
+     * 
+     * @param addr
+     *            The target address.
+     * @param dsn
+     *            An optional notification address appended to the MAIL command.
+     * 
      * @return The status for this particular send operation.
      * @exception MessagingException
      */
     protected SendStatus sendRcptTo(InternetAddress addr, String dsn) throws MessagingException {
-        // compose the command using the fixed up email address.  Normally, this involves adding
+        // compose the command using the fixed up email address. Normally, this
+        // involves adding
         // "<" and ">" around the address.
 
         StringBuffer command = new StringBuffer();
@@ -1354,42 +1486,43 @@
         SMTPReply line = sendCommand(commandString);
 
         switch (line.getCode()) {
-            // these two are both successful transmissions
-            case COMMAND_ACCEPTED:
-            case ADDRESS_NOT_LOCAL:
-                // we get out of here with the status information.
-                return new SendStatus(SendStatus.SUCCESS, addr, commandString, line);
-
-            // these are considered invalid address errors
-            case PARAMETER_SYNTAX_ERROR:
-            case INVALID_COMMAND_SEQUENCE:
-            case MAILBOX_NOT_FOUND:
-            case INVALID_MAILBOX:
-            case USER_NOT_LOCAL:
-                // we get out of here with the status information.
-                return new SendStatus(SendStatus.INVALID_ADDRESS, addr, commandString, line);
-
-            // the command was valid, but something went wrong in the server.
-            case SERVICE_NOT_AVAILABLE:
-            case MAILBOX_BUSY:
-            case PROCESSING_ERROR:
-            case INSUFFICIENT_STORAGE:
-            case MAILBOX_FULL:
-                // we get out of here with the status information.
-                return new SendStatus(SendStatus.SEND_FAILURE, addr, commandString, line);
-
-            // everything else is considered really bad...
-            default:
-                // we get out of here with the status information.
-                return new SendStatus(SendStatus.GENERAL_ERROR, addr, commandString, line);
+        // these two are both successful transmissions
+        case COMMAND_ACCEPTED:
+        case ADDRESS_NOT_LOCAL:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.SUCCESS, addr, commandString, line);
+
+        // these are considered invalid address errors
+        case PARAMETER_SYNTAX_ERROR:
+        case INVALID_COMMAND_SEQUENCE:
+        case MAILBOX_NOT_FOUND:
+        case INVALID_MAILBOX:
+        case USER_NOT_LOCAL:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.INVALID_ADDRESS, addr, commandString, line);
+
+        // the command was valid, but something went wrong in the server.
+        case SERVICE_NOT_AVAILABLE:
+        case MAILBOX_BUSY:
+        case PROCESSING_ERROR:
+        case INSUFFICIENT_STORAGE:
+        case MAILBOX_FULL:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.SEND_FAILURE, addr, commandString, line);
+
+        // everything else is considered really bad...
+        default:
+            // we get out of here with the status information.
+            return new SendStatus(SendStatus.GENERAL_ERROR, addr, commandString, line);
         }
     }
 
     /**
      * Set the sender for this mail.
-     *
-     * @param message The message we're sending.
-     *
+     * 
+     * @param message
+     *            The message we're sending.
+     * 
      * @exception MessagingException
      */
     protected boolean sendMailFrom(Message message) throws MessagingException {
@@ -1397,9 +1530,10 @@
         // need to sort the from value out from a variety of sources.
         String from = null;
 
-        // first potential source is from the message itself, if it's an instance of SMTPMessage.
+        // first potential source is from the message itself, if it's an
+        // instance of SMTPMessage.
         if (message instanceof SMTPMessage) {
-            from = ((SMTPMessage)message).getEnvelopeFrom();
+            from = ((SMTPMessage) message).getEnvelopeFrom();
         }
 
         // if not available from the message, check the protocol property next
@@ -1408,22 +1542,22 @@
             from = getProtocolProperty(MAIL_SMTP_FROM);
         }
 
-
         // if not there, see if we have something in the message header.
         if (from == null || from.length() == 0) {
             Address[] fromAddresses = message.getFrom();
 
-            // if we have some addresses in the header, then take the first one as our From: address
+            // if we have some addresses in the header, then take the first one
+            // as our From: address
             if (fromAddresses != null && fromAddresses.length > 0) {
-                from = ((InternetAddress)fromAddresses[0]).getAddress();
+                from = ((InternetAddress) fromAddresses[0]).getAddress();
             }
-            // get what the InternetAddress class believes to be the local address.
+            // get what the InternetAddress class believes to be the local
+            // address.
             else {
                 from = InternetAddress.getLocalAddress(session).getAddress();
             }
         }
 
-
         if (from == null || from.length() == 0) {
             throw new MessagingException("no FROM address");
         }
@@ -1434,38 +1568,43 @@
         command.append("MAIL FROM: ");
         command.append(fixEmailAddress(from));
 
-        // does this server support Delivery Status Notification?  Then we may need to add some extra to the command.
+        // does this server support Delivery Status Notification? Then we may
+        // need to add some extra to the command.
         if (supportsExtension("DSN")) {
             String returnNotification = null;
 
-            // the return notification stuff might be set as value on the message object itself.
+            // the return notification stuff might be set as value on the
+            // message object itself.
             if (message instanceof SMTPMessage) {
                 // we need to convert the option into a string value.
-                switch (((SMTPMessage)message).getReturnOption()) {
-                    case SMTPMessage.RETURN_FULL:
-                        returnNotification = "FULL";
-                        break;
+                switch (((SMTPMessage) message).getReturnOption()) {
+                case SMTPMessage.RETURN_FULL:
+                    returnNotification = "FULL";
+                    break;
 
-                    case SMTPMessage.RETURN_HDRS:
-                        returnNotification = "HDRS";
-                        break;
+                case SMTPMessage.RETURN_HDRS:
+                    returnNotification = "HDRS";
+                    break;
                 }
             }
 
-            // if not obtained from the message object, it can also be set as a property.
+            // if not obtained from the message object, it can also be set as a
+            // property.
             if (returnNotification == null) {
                 // the DSN value is set by yet another property.
                 returnNotification = getProtocolProperty(MAIL_SMTP_DSN_RET);
             }
 
-            // if we have a target, add the notification stuff to our FROM command.
+            // if we have a target, add the notification stuff to our FROM
+            // command.
             if (returnNotification != null) {
                 command.append(" RET=");
                 command.append(returnNotification);
             }
         }
 
-        // if this server supports AUTH and we have submitter information, then we also add the
+        // if this server supports AUTH and we have submitter information, then
+        // we also add the
         // "AUTH=" keyword to the MAIL FROM command (see RFC 2554).
 
         if (supportsExtension("AUTH")) {
@@ -1473,14 +1612,15 @@
 
             // another option that can be specified on the message object.
             if (message instanceof SMTPMessage) {
-                submitter = ((SMTPMessage)message).getSubmitter();
+                submitter = ((SMTPMessage) message).getSubmitter();
             }
             // if not part of the object, try for a propery version.
             if (submitter == null) {
                 // we only send the extra keyword is a submitter is specified.
                 submitter = getProtocolProperty(MAIL_SMTP_SUBMITTER);
             }
-            // we have one...add the keyword, plus the submitter info in xtext format (defined by RFC 1891).
+            // we have one...add the keyword, plus the submitter info in xtext
+            // format (defined by RFC 1891).
             if (submitter != null) {
                 command.append(" AUTH=");
                 try {
@@ -1494,10 +1634,11 @@
 
         String extension = null;
 
-        // now see if we need to add any additional extension info to this command.  The extension is not
-        // checked for validity.  That's the reponsibility of the caller.
+        // now see if we need to add any additional extension info to this
+        // command. The extension is not
+        // checked for validity. That's the reponsibility of the caller.
         if (message instanceof SMTPMessage) {
-            extension = ((SMTPMessage)message).getMailExtension();
+            extension = ((SMTPMessage) message).getMailExtension();
         }
         // this can come either from the object or from a set property.
         if (extension == null) {
@@ -1511,7 +1652,6 @@
             command.append(extension);
         }
 
-
         // and finally send the command
         SMTPReply line = sendCommand(command.toString());
 
@@ -1520,11 +1660,12 @@
     }
 
     /**
-     * Send a command to the server, returning the first response line
-     * back as a reply.
-     *
-     * @param data   The data to send.
-     *
+     * Send a command to the server, returning the first response line back as a
+     * reply.
+     * 
+     * @param data
+     *            The data to send.
+     * 
      * @return A reply object with the reply line.
      * @exception MessagingException
      */
@@ -1533,10 +1674,8 @@
         return getReply();
     }
 
-
     /**
-     * Sends a  message down the socket and terminates with the
-     * appropriate CRLF
+     * Sends a message down the socket and terminates with the appropriate CRLF
      */
     protected void sendLine(String data) throws MessagingException {
         if (socket == null || !socket.isConnected()) {
@@ -1553,9 +1692,9 @@
     }
 
     /**
-     * Receives one line from the server.  A line is a sequence of bytes
+     * Receives one line from the server. A line is a sequence of bytes
      * terminated by a CRLF
-     *
+     * 
      * @return the line from the server as String
      */
     protected String receiveLine() throws MessagingException {
@@ -1564,25 +1703,25 @@
 
     /**
      * Get a reply line for an SMTP command.
-     *
+     * 
      * @return An SMTP reply object from the stream.
      */
     protected SMTPReply getReply() throws MessagingException {
         try {
-			lastServerResponse = new SMTPReply(receiveLine());
-		} catch (MalformedSMTPReplyException e) {
-			throw new MessagingException(e.toString());
-		} catch (MessagingException e) {
-			throw e;
-		}
+            lastServerResponse = new SMTPReply(receiveLine());
+        } catch (MalformedSMTPReplyException e) {
+            throw new MessagingException(e.toString());
+        } catch (MessagingException e) {
+            throw e;
+        }
         return lastServerResponse;
     }
 
     /**
      * Retrieve the last response received from the SMTP server.
-     *
-     * @return The raw response string (including the error code) returned
-     *         from the SMTP server.
+     * 
+     * @return The raw response string (including the error code) returned from
+     *         the SMTP server.
      */
     public String getLastServerResponse() {
         if (lastServerResponse == null) {
@@ -1591,12 +1730,10 @@
         return lastServerResponse.getReply();
     }
 
-
-
     /**
-     * Receives one line from the server.  A line is a sequence of bytes
+     * Receives one line from the server. A line is a sequence of bytes
      * terminated by a CRLF
-     *
+     * 
      * @return the line from the server as String
      */
     protected String receiveLine(int delayMillis) throws MessagingException {
@@ -1617,17 +1754,15 @@
             int c;
             boolean crFound = false, lfFound = false;
 
-
             while ((c = inputStream.read()) != -1 && crFound == false && lfFound == false) {
-                // we're looking for a CRLF sequence, so mark each one as seen.  Any other
+                // we're looking for a CRLF sequence, so mark each one as seen.
+                // Any other
                 // character gets appended to the end of the buffer.
                 if (c == CR) {
                     crFound = true;
-                }
-                else if (c == LF) {
+                } else if (c == LF) {
                     lfFound = true;
-                }
-                else {
+                } else {
                     buff.append((char) c);
                 }
             }
@@ -1649,14 +1784,14 @@
     }
 
     /**
-     * Convert an InternetAddress into a form sendable on an SMTP
-     * mail command.  InternetAddress.getAddress() generally returns
-     * just the address portion of the full address, minus route address
-     * markers.  We need to ensure we have an address with '<' and '>'
-     * delimiters.
-     *
-     * @param mail   The mail address returned from InternetAddress.getAddress().
-     *
+     * Convert an InternetAddress into a form sendable on an SMTP mail command.
+     * InternetAddress.getAddress() generally returns just the address portion
+     * of the full address, minus route address markers. We need to ensure we
+     * have an address with '<' and '>' delimiters.
+     * 
+     * @param mail
+     *            The mail address returned from InternetAddress.getAddress().
+     * 
      * @return A string formatted for sending.
      */
     protected String fixEmailAddress(String mail) {
@@ -1667,27 +1802,28 @@
     }
 
     /**
-     * Start the handshake process with the server, including setting up and TLS-level work.  At the
-     * completion of this task, we should be ready to authenticate with the server, if needed.
+     * Start the handshake process with the server, including setting up and
+     * TLS-level work. At the completion of this task, we should be ready to
+     * authenticate with the server, if needed.
      */
     protected boolean sendHandshake() throws MessagingException {
         // check to see what sort of initial handshake we need to make.
         boolean useEhlo = !isProtocolPropertyFalse(MAIL_SMTP_EHLO);
 
-        // if we're to use Ehlo, send it and then fall back to just a HELO message if it fails.
+        // if we're to use Ehlo, send it and then fall back to just a HELO
+        // message if it fails.
         if (useEhlo) {
             if (!sendEhlo()) {
                 sendHelo();
             }
-        }
-        else {
+        } else {
             // send the initial hello response.
             sendHelo();
         }
 
-
         if (useTLS) {
-            // if we've been told to use TLS, and this server doesn't support it, then this is a failure
+            // if we've been told to use TLS, and this server doesn't support
+            // it, then this is a failure
             if (!serverTLS) {
                 throw new MessagingException("Server doesn't support required transport level security");
             }
@@ -1695,8 +1831,10 @@
             // on our connection.
             getConnectedTLSSocket();
 
-            // some servers (gmail is one that I know of) only send a STARTTLS extension message on the
-            // first EHLO command.  Now that we have the TLS handshaking established, we need to send a
+            // some servers (gmail is one that I know of) only send a STARTTLS
+            // extension message on the
+            // first EHLO command. Now that we have the TLS handshaking
+            // established, we need to send a
             // second EHLO message to retrieve the AUTH records from the server.
             serverAuthenticationMechanisms.clear();
             if (!sendEhlo()) {
@@ -1708,10 +1846,9 @@
         return true;
     }
 
-
     /**
      * Send the EHLO command to the SMTP server.
-     *
+     * 
      * @return True if the command was accepted ok, false for any errors.
      * @exception SMTPTransportException
      * @exception MalformedSMTPReplyException
@@ -1722,8 +1859,10 @@
 
         SMTPReply line = getReply();
 
-        // we get a 250 code back.  The first line is just a greeting, and extensions are identifed on
-        // continuations.   If this fails, then we'll try once more with HELO to establish bona fides.
+        // we get a 250 code back. The first line is just a greeting, and
+        // extensions are identifed on
+        // continuations. If this fails, then we'll try once more with HELO to
+        // establish bona fides.
         if (line.getCode() != COMMAND_ACCEPTED) {
             return false;
         }
@@ -1745,10 +1884,9 @@
         return true;
     }
 
-
     /**
      * Send the HELO command to the SMTP server.
-     *
+     * 
      * @exception MessagingException
      */
     protected void sendHelo() throws MessagingException {
@@ -1756,17 +1894,18 @@
 
         SMTPReply line = getReply();
 
-        // we get a 250 code back.  The first line is just a greeting, and extensions are identifed on
-        // continuations.   If this fails, then we'll try once more with HELO to establish bona fides.
+        // we get a 250 code back. The first line is just a greeting, and
+        // extensions are identifed on
+        // continuations. If this fails, then we'll try once more with HELO to
+        // establish bona fides.
         if (line.getCode() != COMMAND_ACCEPTED) {
             throw new MessagingException("Failure sending HELO command to SMTP server");
         }
     }
 
-
     /**
      * Retrieve the local client host name.
-     *
+     * 
      * @return The string version of the local host name.
      * @exception SMTPTransportException
      */
@@ -1788,60 +1927,57 @@
             }
 
             if (localHost == null) {

[... 474 lines stripped ...]