/// <summary>
        /// Enqueue an email and store it into the database.
        /// </summary>
        /// <param name="mail">The mail to be enqueued.</param>
        /// <returns>A <see cref="Task" /> representing the asynchronous operation, with the guid associated to the email.</returns>
        public async Task <Guid> EnqueueAsync(Email mail)
        {
            var queuedEmail = new QueuedEmail();

            queuedEmail.Id    = Guid.NewGuid();
            queuedEmail.Email = JsonConvert.SerializeObject(mail, Formatting.Indented);

            using (var context = new QueuedEmailContext(this.ConnectionString))
            {
                await context.QueuedEmails.AddAsync(queuedEmail);

                await context.SaveChangesAsync();

                return(queuedEmail.Id);
            }
        }
        /// <summary>
        /// Send all mails in queue.
        /// </summary>
        /// <param name="client">Specify a custom smtp client to be used.</param>
        /// <param name="waitTime">Wait time between emails, in milliseconds.</param>
        public void SendQueuedMails(SmtpClient client = null, int waitTime = 0)
        {
            if (client == null)
            {
                client = new SmtpClient();
            }

            lock (LockSendMails)
            {
                using (var context = new QueuedEmailContext(this.ConnectionString))
                {
                    var queuedEmails = context.QueuedEmails.Where(x => x.Sent == null).ToList();
                    foreach (var queuedEmail in queuedEmails)
                    {
                        var email = JsonConvert.DeserializeObject <Email>(queuedEmail.Email);

                        var message = new MailMessage();
                        message.From       = new MailAddress(email.Sender);
                        message.Subject    = email.Subject;
                        message.Body       = email.Body;
                        message.IsBodyHtml = true;

                        if (email.ReplyTo != null)
                        {
                            message.ReplyToList.Add(new MailAddress(email.ReplyTo));
                        }

                        if (email.Recipients != null)
                        {
                            foreach (var recipient in email.Recipients)
                            {
                                message.To.Add(new MailAddress(recipient));
                            }
                        }

                        if (email.RecipientsCopy != null)
                        {
                            foreach (var recipientCopy in email.RecipientsCopy)
                            {
                                message.CC.Add(new MailAddress(recipientCopy));
                            }
                        }

                        if (email.RecipientsBlindCopy != null)
                        {
                            foreach (var recipientBlindCopy in email.RecipientsBlindCopy)
                            {
                                message.Bcc.Add(new MailAddress(recipientBlindCopy));
                            }
                        }

                        if (email.AdminCopy)
                        {
                            message.To.Add(new MailAddress(this.AdminEmail));
                        }

                        if (this.RedirectEmail)
                        {
                            var originalAddress = string.Join(", ", message.To.Select(x => x.Address));
                            message.Subject += " (" + originalAddress + ")";

                            message.To.Clear();
                            message.To.Add(new MailAddress(this.RedirectionAddress));
                        }

                        if (email.Attachments != null)
                        {
                            var attachments = JsonConvert.DeserializeObject <EmailAttachment[]>(email.Attachments);
                            foreach (var attachment in attachments)
                            {
                                var a = new Attachment(new MemoryStream(attachment.FileData), attachment.FileName);
                                message.Attachments.Add(a);
                            }
                        }

                        foreach (var customHeaderKey in this.CustomHeaders.AllKeys)
                        {
                            message.Headers.Add(customHeaderKey, this.CustomHeaders[customHeaderKey]);
                        }

                        try
                        {
                            client.Send(message);
                            queuedEmail.Sent          = DateTime.Now;
                            queuedEmail.ResultMessage = null;

                            if (waitTime != 0)
                            {
                                Thread.Sleep(waitTime);
                            }
                        }
                        catch (SmtpException e)
                        {
                            queuedEmail.ResultMessage = e.ToString();
                        }

                        context.SaveChanges();
                    }
                }
            }
        }