internal override void OnLogin(string login, string password)
        {
            string command;
            string result = String.Empty;
            string tag    = GetTag();
            string key;

            switch (AuthMethod)
            {
            case AuthMethods.CRAMMD5:
                command = tag + "AUTHENTICATE CRAM-MD5";
                result  = SendCommandGetResponse(command);
                // retrieve server key
                key = result.Replace("+ ", "");
                key = System.Text.Encoding.Default.GetString(Convert.FromBase64String(key));
                // calcul hash
                using (var kMd5 = new HMACMD5(System.Text.Encoding.ASCII.GetBytes(password)))
                {
                    var hash1 = kMd5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(key));
                    key    = BitConverter.ToString(hash1).ToLower().Replace("-", "");
                    result = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(login + " " + key));
                    result = SendCommandGetResponse(result);
                }
                break;

            case AuthMethods.Login:
                command = tag + "LOGIN " + login.QuoteString() + " " + password.QuoteString();
                result  = SendCommandGetResponse(command);
                break;

            case AuthMethods.SaslOAuth:
                string sasl   = "user="******"\x01" + "auth=Bearer " + password + "\x01" + "\x01";
                string base64 = Convert.ToBase64String(Encoding.GetBytes(sasl));
                command = tag + "AUTHENTICATE XOAUTH2 " + base64;
                result  = SendCommandGetResponse(command);
                break;

            default:
                throw new NotSupportedException();
            }

            if (result.StartsWith("* CAPABILITY "))
            {
                _Capability = result.Substring(13).Trim().Split(' ');
                result      = GetResponse();
            }

            if (!result.StartsWith(tag + "OK"))
            {
                if (result.StartsWith("+ ") && result.EndsWith("=="))
                {
                    string jsonErr = Utilities.DecodeBase64(result.Substring(2), System.Text.Encoding.UTF7);
                    throw new Exception(jsonErr);
                }
                else
                {
                    throw new Exception(result);
                }
            }

            //if (Supports("COMPRESS=DEFLATE")) {
            //  SendCommandCheckOK(GetTag() + "compress deflate");
            //  _Stream0 = _Stream;
            // // _Reader = new System.IO.StreamReader(new System.IO.Compression.DeflateStream(_Stream0, System.IO.Compression.CompressionMode.Decompress, true), System.Text.Encoding.Default);
            // // _Stream = new System.IO.Compression.DeflateStream(_Stream0, System.IO.Compression.CompressionMode.Compress, true);
            //}

            if (Supports("X-GM-EXT-1"))
            {
                _FetchHeaders = "X-GM-MSGID X-GM-THRID X-GM-LABELS ";
            }
        }
        public virtual void GetMessages(string start, string end, bool uid, bool uidsonly, bool headersonly, bool setseen, Func <System.IO.Stream, int, NameValueCollection, MailMessage> action)
        {
            CheckMailboxSelected();
            IdlePause();

            string tag     = GetTag();
            string command = tag + (uid ? "UID " : null)
                             + "FETCH " + start + ":" + end + " ("
                             + _FetchHeaders + "UID FLAGS"
                             + (uidsonly ? null : (setseen ? " BODY[" : " BODY.PEEK[") + (headersonly ? "HEADER]" : "]"))
                             + ")";

            string response;

            SendCommand(command);
            while (true)
            {
                response = GetResponse();
                if (string.IsNullOrEmpty(response) || response.Contains(tag + "OK"))
                {
                    break;
                }

                if (response[0] != '*' || !response.Contains("FETCH ("))
                {
                    continue;
                }

                var    imapHeaders = Utilities.ParseImapHeader(response.Substring(response.IndexOf('(') + 1));
                String body        = (imapHeaders["BODY[HEADER]"] ?? imapHeaders["BODY[]"]);
                if (body == null && !uidsonly)
                {
                    System.Diagnostics.Debugger.Break();
                    RaiseWarning(null, "Expected BODY[] in stream, but received \"" + response + "\"");
                    break;
                }

                var size = (uidsonly ? 0 : body.Trim('{', '}').ToInt());
                var msg  = action?.Invoke(_Stream, size, imapHeaders);

                // with only uids we have no body and the closing bracket is on the same line
                if (!uidsonly)
                {
                    response = GetResponse();
                    if (response == null)
                    {
                        System.Diagnostics.Debugger.Break();
                        RaiseWarning(null, "Expected \")\" in stream, but received nothing");
                        break;
                    }
                }

                var n = response.Trim().LastOrDefault();
                if (n != ')')
                {
                    System.Diagnostics.Debugger.Break();
                    RaiseWarning(null, "Expected \")\" in stream, but received \"" + response + "\"");
                }
            }

            IdleResume();
        }