/// <summary>
        /// Authenticates the ImapConnection using the username and password specified.
        /// </summary>
        /// <param name="username">A string value representing the username to authenticate.</param>
        /// <param name="password">A string value representing the password to use for authentication.</param>
        /// <exception cref="ImapAuthenticationException" />
        /// <exception cref="ImapAuthenticationNotSupportedException" />
        public void Login(string username, string password)
        {
            string command;
            string result;

            if (!(Connection.ConnectionState == ConnectionState.Connected))
            {
                throw new ImapConnectionException("Connection must be connected before authentication");
            }
            Connection.ConnectionState = ConnectionState.Authenticating;

            //Moved from ImapConnect.Open because not all login methods will be advertised at the
            //opening of the connection (Plain authentication usually won't be available until after
            //a STARTTLS command has been sent for example. --Scott

            //Not all servers advertise their capabilities on the OK response
            //So ask for them seperatley.
            string read;
            string serverResponse;

            _connection.Write("CAPABILITY\r\n");
            read = _connection.Read();

            //Check the Capabilities for available types
            _connection.LoginType = ParseLoginType(read);
            _connection.Read(); //Grab the extra OK line at the end
            switch (Connection.LoginType)
            {
            case LoginType.PLAIN:
                command = "LOGIN " + username + " " + password + "\r\n";
                Connection.Write(command);
                break;

            case LoginType.LOGIN:
                Connection.Write("AUTHENTICATE LOGIN\r\n");
                serverResponse = Connection.Read();
                Connection.UntaggedWrite(string.Format("{0}\r\n", base64Encode(username)));
                serverResponse = Connection.Read();
                Connection.UntaggedWrite(string.Format("{0}\r\n", base64Encode(password)));
                break;

            case LoginType.CRAM_MD5:
                //Let the server know to use CRAM-MD5 and read it's response (Base64 encoded)
                Connection.Write("AUTHENTICATE CRAM-MD5\r\n");
                serverResponse = Connection.Read();

                string hmac = HmacMd5(username, password, serverResponse);
                Connection.UntaggedWrite(hmac + "\r\n");

                break;

            default:
                throw new ImapAuthenticationNotSupportedException("Authentication type unsupported:" + Connection.LoginType.ToString());
            }
            result = Connection.Read();
            if (result.StartsWith("* OK") || result.Substring(7, 2) == "OK")
            {
                Connection.ConnectionState = ConnectionState.Open;
            }
            else
            {
                Connection.ConnectionState = ConnectionState.Broken;
                throw new ImapAuthenticationException("Authentication failed: " + result);
            }
        }