/// <summary>
        /// Routine that attempts to resend emails that previously failed.
        /// </summary>
        /// <returns>List of emails that were successfully resent.</returns>
        /// <remarks>Uses internally maintained queue of emails that failed to send.</remarks>
        public PFListEx <stEmailArchiveEntry> ResendEmails()
        {
            PFListEx <stEmailArchiveEntry> successfulResends = new PFListEx <stEmailArchiveEntry>();
            PFListEx <stEmailArchiveEntry> failedResends     = new PFListEx <stEmailArchiveEntry>();

            _emailResendQueue = PFListEx <stEmailArchiveEntry> .LoadFromXmlFile(_emailResendQueueFile);

            _emailLastResendList.Clear();

            foreach (stEmailArchiveEntry emailEntry in _emailResendQueue)
            {
                stEmailSendResult res = this.SendEmail(emailEntry.emailMessage, false);

                if (res.emailSendResult == enEmailSendResult.Success)
                {
                    stEmailArchiveEntry successEntry = new stEmailArchiveEntry(res, emailEntry.emailMessage);
                    successEntry.numRetries       = emailEntry.numRetries + 1;
                    successEntry.firstSendAttempt = emailEntry.firstSendAttempt;
                    successEntry.lastSendAttempt  = DateTime.Now;
                    successfulResends.Add(successEntry);
                }
                else
                {
                    stEmailArchiveEntry failedEntry = new stEmailArchiveEntry(res, emailEntry.emailMessage);
                    failedEntry.firstSendAttempt = emailEntry.firstSendAttempt;
                    failedEntry.lastSendAttempt  = DateTime.Now;
                    failedEntry.numRetries       = emailEntry.numRetries + 1;
                    failedResends.Add(failedEntry);
                }
            }

            _emailResendQueue.Clear();
            if (failedResends.Count > 0)
            {
                foreach (stEmailArchiveEntry entry in failedResends)
                {
                    if (entry.numRetries < _maxNumResendAttempts)
                    {
                        stEmailArchiveEntry newEntry = new stEmailArchiveEntry(entry.sendResult, entry.emailMessage);
                        newEntry.firstSendAttempt = entry.firstSendAttempt;
                        newEntry.lastSendAttempt  = entry.lastSendAttempt;
                        newEntry.numRetries       = entry.numRetries;
                        _emailResendQueue.Add(newEntry);
                    }
                    else
                    {
                        stEmailArchiveEntry lastEntry = new stEmailArchiveEntry(entry.sendResult, entry.emailMessage);
                        lastEntry.firstSendAttempt = entry.firstSendAttempt;
                        lastEntry.lastSendAttempt  = entry.lastSendAttempt;
                        lastEntry.numRetries       = entry.numRetries;
                        _emailLastResendList.Add(lastEntry);
                    }
                }
            }

            _emailResendQueue.SaveToXmlFile(_emailResendQueueFile);

            return(successfulResends);
        }
        /// <summary>
        /// Sends the specified email.
        /// </summary>
        /// <param name="emailMsg">Email message object.</param>
        /// <param name="resendOnError">If true, email manager will attempt to resend a message that fails due to an SMTP error.</param>
        /// <returns>True if email sent successfully; otherwise false if an error occurred and email was not sent.</returns>
        /// <remarks>Email manager will retry up to MaxNumResendAttempts times.</remarks>
        public stEmailSendResult SendEmail(PFEmailMessage emailMsg, bool resendOnError)
        {
            stEmailSendResult result = new stEmailSendResult(enEmailSendResult.Unknown, enEmailFailedReason.Unknown);
            bool queueForResend      = false;

            try
            {
                emailMsg.Send();
                result.emailSendResult   = enEmailSendResult.Success;
                result.emailFailedReason = enEmailFailedReason.NoError;
                result.failureMessages   = string.Empty;
            }
            catch (System.Exception ex)
            {
                _msg.Length = 0;
                _msg.Append("Attempt to send email to ");
                _msg.Append(emailMsg.ToAddress);
                _msg.Append(" failed. Error Message: ");
                _msg.Append(PFTextProcessor.FormatErrorMessage(ex));
                result.emailSendResult = enEmailSendResult.Failed;
                result.failureMessages = _msg.ToString();
                if (ex is SmtpException)
                {
                    result.emailFailedReason = enEmailFailedReason.SmtpException;
                    queueForResend           = true;
                }
                else if (ex is SmtpFailedRecipientException)
                {
                    result.emailFailedReason = enEmailFailedReason.SmtpRecipientsException;
                    queueForResend           = true;
                }
                else if (ex is InvalidOperationException)
                {
                    result.emailFailedReason = enEmailFailedReason.InvalidOperationsException;
                }
                else if (ex is ArgumentNullException)
                {
                    result.emailFailedReason = enEmailFailedReason.ArgumentNullException;
                }
                else
                {
                    result.emailFailedReason = enEmailFailedReason.GeneralError;
                }
            }
            finally
            {
                if (queueForResend && resendOnError)
                {
                    stEmailArchiveEntry newEntry = new stEmailArchiveEntry(result, emailMsg);
                    newEntry.firstSendAttempt = DateTime.Now;
                    newEntry.lastSendAttempt  = DateTime.Now;
                    _emailResendQueue.Add(newEntry);
                    _emailResendQueue.SaveToXmlFile(_emailResendQueueFile);
                }
            }

            return(result);
        }