} // ResetMessages

        public string DeleteMimeFiles()
        {
            string DeleteMimeFilesRet = default;
            // Delete all the MIME files marked for deletion in array blnDeleteFlags.
            // Only called after QUIT received in the Transaction state...

            int intIndex;

            if (intNumberOfMimeFiles == 0)
            {
                DeleteMimeFilesRet = "+OK" + Globals.CRLF;
                return(DeleteMimeFilesRet);
            }

            if (intNumberOfMimeFiles > 0)
            {
                var messageStore = new MessageStore(DatabaseFactory.Get());
                var emails       = messageStore.GetAccountEmails(strAccountName);
                var loopTo       = intNumberOfMimeFiles;
                for (intIndex = 1; intIndex <= loopTo; intIndex++)
                {
                    if (blnDeleteFlags[intIndex - 1] == true)
                    {
                        messageStore.DeleteAccountEmail(strAccountName, emails[intIndex - 1].Key);
                    }
                }
            }

            DeleteMimeFilesRet = "+OK" + Globals.CRLF;
            return(DeleteMimeFilesRet);
        } // DeleteMimeFiles
        } // ListResponse

        private string UidlResponse(string strMessageId)
        {
            string UidlResponseRet = default;

            // Returns a unique code for each file in the MIME array (aryMime).
            // This uses the unique aryMime name (without extension). If
            // strMessageId = "" returns all messages otherwise the message
            // requested parameter...

            GetPendingMimeList();
            int    intCount = 0;
            int    intLastSlashPosition;
            int    intIndex;
            string strId;

            if (string.IsNullOrEmpty(strMessageId)) // Request for all messages and send a multi line response...
            {
                UidlResponseRet = "+OK " + Globals.CRLF;
                if (intNumberOfMimeFiles != 0)
                {
                    var messageStore = new MessageStore(DatabaseFactory.Get());
                    var emails       = messageStore.GetAccountEmails(strAccountName);
                    foreach (var email in emails)
                    {
                        intCount        = intCount + 1;
                        UidlResponseRet = UidlResponseRet + intCount.ToString() + " " + email.Key + Globals.CRLF;
                    }

                    UidlResponseRet = UidlResponseRet + "." + Globals.CRLF; // add terminator
                }
                else
                {
                    UidlResponseRet = "+OK" + Globals.CRLF + "." + Globals.CRLF;
                }
            }
            else // Request for specific message just send a single line response...
            {
                intIndex = Convert.ToInt32(strMessageId);

                if (intIndex > 0 & intIndex <= intNumberOfMimeFiles)
                {
                    var messageStore = new MessageStore(DatabaseFactory.Get());
                    var email        = messageStore.GetAccountEmails(strAccountName)[intIndex];
                    UidlResponseRet = "+OK " + intIndex.ToString() + " " + email.Key + Globals.CRLF;
                }
                else
                {
                    UidlResponseRet = "-ERR" + Globals.CRLF;
                }
            }

            return(UidlResponseRet);
        } // UidlResponse
        } // StatResponse

        private string ListResponse(string strMessageId)
        {
            // Returns the size of each file in the MIME array (aryMime)...
            GetPendingMimeList();
            string strResponse;
            int    intCount = 0;

            if (string.IsNullOrEmpty(strMessageId))  // List everything as a multi line response...
            {
                strResponse = "+OK " + intNumberOfMimeFiles.ToString() + " " + intTotalBytes.ToString() + Globals.CRLF;
                if (intNumberOfMimeFiles > 0)
                {
                    var messageStore  = new MessageStore(DatabaseFactory.Get());
                    var pendingEmails = messageStore.GetAccountEmails(strAccountName);
                    foreach (var email in pendingEmails)
                    {
                        intCount    = intCount + 1;
                        strResponse = strResponse + intCount.ToString() + " " + email.Value.Length.ToString() + Globals.CRLF;
                    }
                }

                strResponse = strResponse + "." + Globals.CRLF;  // Add the terminator
            }
            else  // Just list the requested message as a one line response...
            {
                int intIndex;
                intIndex = Convert.ToInt32(strMessageId);
                if (intNumberOfMimeFiles > 0)
                {
                    var messageStore = new MessageStore(DatabaseFactory.Get());
                    if (intIndex > 0 & intIndex <= intNumberOfMimeFiles)
                    {
                        var email = messageStore.GetAccountEmails(strAccountName)[intIndex - 1].Value;
                        strResponse = "+OK " + intIndex.ToString() + " " + email.Length.ToString() + Globals.CRLF;
                    }
                    else
                    {
                        strResponse = "-ERR no such message" + Globals.CRLF;
                    }
                }
                else
                {
                    strResponse = "-ERR no such message" + Globals.CRLF;
                }
            }

            return(strResponse);
        } // ListResponse
        } // Protocol

        private void GetPendingMimeList()
        {
            var messageStore = new MessageStore(DatabaseFactory.Get());
            int intCount     = 0;
            int intByteCount = 0;

            blnDeleteFlags = null;
            var pendingEmails = messageStore.GetAccountEmails(strAccountName);

            foreach (var email in pendingEmails)
            {
                Array.Resize(ref blnDeleteFlags, intCount + 1);
                blnDeleteFlags[intCount] = false;
                intCount     += 1;
                intByteCount += Convert.ToInt32(email.Value.Length);
            }

            intNumberOfMimeFiles = intCount;
            intTotalBytes        = intByteCount;
        } // GetPendingMimeList
        } // RetrieveMessage

        public string TopResponse(string strMessageId)
        {
            string TopResponseRet = default;
            // Returns the Header and top n lines of a specific message identified in strMessageId...

            string       strMessage;
            StreamReader strMime;
            int          intIndex;

            try
            {
                if (!string.IsNullOrEmpty(strMessageId))
                {
                    var Param = strMessageId.Split(' ');
                    intIndex = Convert.ToInt32(Param[0]);
                    int intLineCounter = 0;
                    if (Param.Length > 1)
                    {
                        intLineCounter = Convert.ToInt32(Param[1]);
                    }
                    if (intNumberOfMimeFiles == 0)
                    {
                        TopResponseRet = "-ERR no messages" + Globals.CRLF;
                        return(TopResponseRet);
                    }

                    if (intIndex > 0 & intIndex <= blnDeleteFlags.Length)
                    {
                        if (blnDeleteFlags[intIndex - 1] == false) // only retrieve messages NOT marked for deletion
                        {
                            var messageStore = new MessageStore(DatabaseFactory.Get());
                            var emails       = messageStore.GetAccountEmails(strAccountName);

                            strMessage = UTF8Encoding.UTF8.GetString(emails[intIndex - 1].Value);
                            // Add byte stuffing for <CrLf . >
                            strMessage = strMessage.Replace(Globals.CRLF + ".", Globals.CRLF + "..");
                            int    intEndOfHeader = 4 + strMessage.IndexOf(Globals.CRLF + Globals.CRLF);
                            string sHeader        = strMessage.Substring(0, intEndOfHeader);
                            strMessage = strMessage.Substring(intEndOfHeader);
                            string sBody = "";
                            int    intLineEnd;
                            for (int intLine = 1, loopTo = intLineCounter; intLine <= loopTo; intLine++) // Will not execute if no second parameter or if it is 0
                            {
                                intLineEnd = 2 + strMessage.IndexOf(Globals.CRLF);
                                if (intLineEnd != 1)
                                {
                                    sBody      = sBody + strMessage.Substring(0, intLineEnd);
                                    strMessage = strMessage.Substring(intLineEnd);
                                }
                                else
                                {
                                    sBody = sBody + strMessage;
                                    break;
                                }
                            }

                            return("+OK " + Globals.CRLF + sHeader + sBody + Globals.CRLF + "." + Globals.CRLF);
                        }
                    }
                }

                return("-ERR no such message" + Globals.CRLF);
            }
            catch (Exception e)
            {
                Log.Error("[8273] " + e.Message);
                return("-ERR internal error" + Globals.CRLF);
            }
        } // TopResponse
        } // DeleteMimeFiles

        public string RetrieveMessage(string strMessageNumber)
        {
            string RetrieveMessageRet = default;
            // Retrieve a specific message identified in strMessageId...

            string       strMessage;
            StreamReader srdMime;
            int          intIndex;

            if (!string.IsNullOrEmpty(strMessageNumber))
            {
                intIndex = Convert.ToInt32(strMessageNumber);
                if (intNumberOfMimeFiles == 0)
                {
                    RetrieveMessageRet = "-ERR no messages" + Globals.CRLF;
                    return(RetrieveMessageRet);
                }

                if (intNumberOfMimeFiles > 0)
                {
                    var messageStore = new MessageStore(DatabaseFactory.Get());
                    var emails       = messageStore.GetAccountEmails(strAccountName);
                    if (intIndex > 0 & intIndex <= blnDeleteFlags.Length)
                    {
                        if (blnDeleteFlags[intIndex - 1] == false) // Only retrieve messages NOT marked for deletion
                        {
                            strMessage = UTF8Encoding.UTF8.GetString(emails[intIndex - 1].Value);

                            // Decode header for display and logging.
                            var strSubject     = default(string);
                            var strFrom        = default(string);
                            var strHeaderLines = strMessage.Split(Convert.ToChar(Globals.CR));
                            foreach (string strLine in strHeaderLines)
                            {
                                var tmpStrLine = strLine.Replace(Globals.LF, "").Trim();
                                if (tmpStrLine.StartsWith("From:"))
                                {
                                    strFrom = tmpStrLine;
                                }
                                else if (tmpStrLine.StartsWith("Subject:"))
                                {
                                    strSubject = tmpStrLine;
                                    break;
                                }
                            }

                            // Add byte stuffing for <CrLf . >
                            strMessage = strMessage.Replace(Globals.CRLF + ".", Globals.CRLF + "..");
                            string strMessageId = emails[intIndex - 1].Key;
                            Globals.queSMTPDisplay.Enqueue("G" + strMessageId + " delivered to " + strAccountName);
                            Globals.queSMTPDisplay.Enqueue("G   " + strFrom);
                            Globals.queSMTPDisplay.Enqueue("G   " + strSubject);
                            RetrieveMessageRet = "+OK " + Globals.CRLF + strMessage + Globals.CRLF + "." + Globals.CRLF;
                            return(RetrieveMessageRet);
                        }
                    }
                }
            }

            RetrieveMessageRet = "-ERR no such message" + Globals.CRLF;
            return(RetrieveMessageRet);
        } // RetrieveMessage