private void SMTPThread()
        {
            _abortSMTPThread = false;

            // Open SMTP/POP3 ports...
            try
            {
                // Clear and re establish the objSMTPPort
                if (Globals.objSMTPPort != null)
                {
                    Globals.objSMTPPort.Close();
                    Globals.objSMTPPort = null;
                }

                Globals.objSMTPPort           = new SMTPPort();
                Globals.objSMTPPort.LocalPort = Globals.intSMTPPortNumber;
                Globals.objSMTPPort.Listen(true);

                // Clear and reestablish the objPOP3Port
                if (Globals.objPOP3Port != null)
                {
                    Globals.objPOP3Port.Close();
                    Globals.objPOP3Port = null;
                }

                Globals.objPOP3Port           = new POP3Port();
                Globals.objPOP3Port.LocalPort = Globals.intPOP3PortNumber;
                Globals.objPOP3Port.Listen(true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    ex.Message + Globals.CRLF +
                    "There may be a SMTP/POP3 confilct due to another program/service listening on the POP3/SMTP Ports." +
                    " Terminate that service or change POP3/SMTP ports in Paclink and your mail client." +
                    " Check the Paclink Errors.log for details of the error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                _log.Error("[SMTPThread] SMTP/POP3 Port Setup: " + ex.Message);
            }

            var messageStoreDatabase = new MessageStore(DatabaseFactory.Get());

            do
            {
                Thread.Sleep(4000);
                if (Globals.blnProgramClosing)
                {
                    break;
                }
                if (_intDay != DateTime.UtcNow.Day)
                {
                    _intDay = DateTime.UtcNow.Day;
                    messageStoreDatabase.PurgeMessageIdsSeen();
                }
                //
                // Initiates processing of any messages received from Winlink.
                //
                try
                {
                    var messageStore = new MessageStore(DatabaseFactory.Get());
                    foreach (var message in messageStore.GetFromWinlinkMessages())
                    {
                        string strMime           = UTF8Encoding.UTF8.GetString(message.Value);
                        var    objWinlinkMessage = new SMTPMessage(strMime, false);
                        if (objWinlinkMessage.IsAccepted)
                        {
                            if (objWinlinkMessage.SaveMessageToAccounts() == false)
                            {
                                _log.Error("[PrimaryThreads.SMTPThread] Failure to save " + objWinlinkMessage.Mime + " to user account");
                            }
                        }
                        else
                        {
                            _log.Error("[PrimaryThreads.SMTPThread] Failure to decode " + objWinlinkMessage.Mime + " from Winlink");
                        }

                        messageStore.DeleteFromWinlinkMessage(message.Key);
                    }
                }
                catch (Exception ex)
                {
                    _log.Error("[Main.PollSMTPSide A] " + ex.Message);
                }
                //
                // Updates the message pending counts.
                //
                try
                {
                    var messageStore       = new MessageStore(DatabaseFactory.Get());
                    var strFromMessageList = messageStore.GetToWinlinkMessages();
                    Globals.intPendingForWinlink = strFromMessageList.Count;
                    Globals.intPendingForClients = messageStore.GetNumberOfAccountEmails();
                    //
                    // Displays the message pending counts.
                    //
                    Globals.queSMTPStatus.Enqueue("To Clients: " + Globals.intPendingForClients.ToString() + "  To Winlink: " + Globals.intPendingForWinlink.ToString());
                }
                catch (Exception ex)
                {
                    _log.Error("[Main.PollSMTPSide B] " + ex.Message);
                }
            }while (!_abortSMTPThread);
        } // SMTPThread
        } // ParseInboundSID

        private void GetPendingOutboundMessages()
        {
            // Fill the outbound message collection...

            aryOutboundMessages = new ArrayList();
            var aryOutboundMessageIDs        = new ArrayList();
            var aryTemporaryOutboundMessages = new ArrayList();

            // Find all files pending for delivery...
            var messageStore = new MessageStore(DatabaseFactory.Get());
            var messages     = messageStore.GetToWinlinkMessages();

            if (messages.Count > 1)
            {
                Globals.queChannelDisplay.Enqueue("G*** Sorting " + messages.Count + " outbound messages for precedence...");
            }
            for (int intIndex = 0; intIndex <= 4; intIndex++) // step through each of the Precedence classes Highest to lowest order
            {
                aryTemporaryOutboundMessages.Clear();
                foreach (var kvp in messages)
                {
                    var objMessage = new Message(kvp.Key);
                    if (objMessage.Subject.ToUpper().IndexOf("//MARS " + "ZOPRM".Substring(intIndex, 1) + "/") != -1)
                    {
                        if (!string.IsNullOrEmpty(objMessage.MessageId) & !string.IsNullOrEmpty(objMessage.Mime) & objMessage.CompressedSize() > 0)
                        {
                            aryTemporaryOutboundMessages.Add(objMessage);
                        }
                        else
                        {
                            Globals.queChannelDisplay.Enqueue("R*** " + kvp.Key + " failed");
                            Globals.queChannelDisplay.Enqueue("R*** Check 'Failed Mime' table");
                            messageStore.SaveFailedMimeMessage(kvp.Key, kvp.Value);
                        }
                    }

                    if (objMessage.Subject.ToUpper().IndexOf("//WL2K " + "ZOPR ".Substring(intIndex, 1).Trim() + "/") != -1 | intIndex == 4 & objMessage.Subject.ToUpper().IndexOf("//WL2K") != -1)
                    {
                        if (!string.IsNullOrEmpty(objMessage.MessageId) & !string.IsNullOrEmpty(objMessage.Mime) & objMessage.CompressedSize() > 0)
                        {
                            aryTemporaryOutboundMessages.Add(objMessage);
                        }
                        else
                        {
                            Globals.queChannelDisplay.Enqueue("R*** " + kvp.Key + " failed");
                            Globals.queChannelDisplay.Enqueue("R*** Check 'Failed Mime' table");
                            messageStore.SaveFailedMimeMessage(kvp.Key, kvp.Value);
                        }
                    }
                }

                if (aryTemporaryOutboundMessages.Count > 0)
                {
                    aryTemporaryOutboundMessages.Sort(); // Sort messages of like precedence in size order
                    foreach (Message objMessage in aryTemporaryOutboundMessages)
                    {
                        if (aryOutboundMessageIDs.Contains(objMessage.MessageId) == false)
                        {
                            aryOutboundMessageIDs.Add(objMessage.MessageId);
                            aryOutboundMessages.Add(objMessage);
                        }
                    }
                }
            }
        } // GetPendingOutboundMessages