private void CloseMailClient(MailClient client, MailBox mailbox, ILogger log)
        {
            if (client == null)
            {
                return;
            }

            try
            {
                client.Authenticated -= ClientOnAuthenticated;
                client.GetMessage    -= ClientOnGetMessage;

                client.Cancel();
                client.Dispose();
            }
            catch (Exception ex)
            {
                log.Error(
                    "CloseMailClient(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}",
                    mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, ex.Message);
            }
        }
        private MailClient CreateMailClient(MailBox mailbox, ILogger log, CancellationToken cancelToken)
        {
            MailClient client = null;

            var connectError = false;

            Stopwatch watch = null;

            if (_tasksConfig.CollectStatistics)
            {
                watch = new Stopwatch();
                watch.Start();
            }

            var manager = new MailBoxManager(log)
            {
                AuthErrorWarningTimeout = _tasksConfig.AuthErrorWarningTimeout,
                AuthErrorDisableTimeout = _tasksConfig.AuthErrorDisableMailboxTimeout
            };

            try
            {
                client = new MailClient(mailbox, cancelToken, _tasksConfig.TcpTimeout,
                                        _tasksConfig.SslCertificateErrorsPermit, _tasksConfig.ProtocolLogPath, log, true);

                log.Debug("MailClient.LoginImapPop(Tenant = {0}, MailboxId = {1} Address = '{2}')",
                          mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail);

                client.Authenticated += ClientOnAuthenticated;

                client.LoginImapPop();
            }
            catch (TimeoutException exTimeout)
            {
                log.Warn(
                    "[TIMEOUT] CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}",
                    mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exTimeout.ToStringDescriptive());

                connectError = true;
            }
            catch (OperationCanceledException)
            {
                log.Info(
                    "[CANCEL] CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')",
                    mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail);
                connectError = true;
            }
            catch (AuthenticationException authEx)
            {
                log.Error(
                    "CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n",
                    mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, authEx.ToStringDescriptive());

                if (!mailbox.AuthErrorDate.HasValue)
                {
                    manager.SetMailboxAuthError(mailbox, true);
                }

                connectError = true;
            }
            catch (Exception ex)
            {
                log.Error(
                    "CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n",
                    mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail,
                    ex is ImapProtocolException || ex is Pop3ProtocolException ? ex.Message : ex.ToString());

                connectError = true;
            }
            finally
            {
                if (connectError)
                {
                    try
                    {
                        if (client != null)
                        {
                            client.Authenticated -= ClientOnAuthenticated;
                            client.Cancel();
                            client.Dispose();
                            client = null;
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error(
                            "CreateTasks->client.Dispose(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}",
                            mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, ex.Message);

                        client = null;
                    }
                }

                if (_tasksConfig.CollectStatistics && watch != null)
                {
                    watch.Stop();

                    LogStat(CONNECT_MAILBOX, mailbox, watch.Elapsed, connectError);
                }
            }

            return(client);
        }