/// <summary>
        /// Sends the specified communication.
        /// </summary>
        /// <param name="communication">The communication.</param>
        public static void Send(Rock.Model.Communication communication)
        {
            if (communication == null || communication.Status != CommunicationStatus.Approved)
            {
                return;
            }

            if (communication.ListGroupId.HasValue && !communication.SendDateTime.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    communication.RefreshCommunicationRecipientList(rockContext);
                }
            }

            foreach (var medium in communication.GetMediums())
            {
                medium.Send(communication);
            }

            using (var rockContext = new RockContext())
            {
                var dbCommunication = new CommunicationService(rockContext).Get(communication.Id);

                // Set the SendDateTime of the Communication
                dbCommunication.SendDateTime = RockDateTime.Now;
                rockContext.SaveChanges();
            }
        }
        /// <summary>
        /// Sends the specified communication.
        /// </summary>
        /// <param name="communication">The communication.</param>
        public static void Send(Rock.Model.Communication communication)
        {
            if (communication == null || communication.Status != CommunicationStatus.Approved)
            {
                return;
            }

            // only alter the Recipient list if it the communication hasn't sent a message to any recipients yet
            if (communication.SendDateTime.HasValue == false)
            {
                using (var rockContext = new RockContext())
                {
                    if (communication.ListGroupId.HasValue)
                    {
                        communication.RefreshCommunicationRecipientList(rockContext);
                    }

                    if (communication.ExcludeDuplicateRecipientAddress)
                    {
                        communication.RemoveRecipientsWithDuplicateAddress(rockContext);
                    }

                    communication.RemoveNonPrimaryPersonAliasRecipients(rockContext);
                }
            }

            foreach (var medium in communication.GetMediums())
            {
                medium.Send(communication);
            }

            using (var rockContext = new RockContext())
            {
                var dbCommunication = new CommunicationService(rockContext).Get(communication.Id);

                // Set the SendDateTime of the Communication
                dbCommunication.SendDateTime = RockDateTime.Now;
                rockContext.SaveChanges();
            }
        }
        /// <summary>
        /// Sends the specified communication.
        /// </summary>
        /// <param name="communication">The communication.</param>
        public async static Task SendAsync(Rock.Model.Communication communication)
        {
            if (communication == null || communication.Status != CommunicationStatus.Approved)
            {
                return;
            }

            // only alter the Recipient list if it the communication hasn't sent a message to any recipients yet
            if (communication.SendDateTime.HasValue == false)
            {
                using (var rockContext = new RockContext())
                {
                    if (communication.ListGroupId.HasValue)
                    {
                        communication.RefreshCommunicationRecipientList(rockContext);
                    }

                    if (communication.ExcludeDuplicateRecipientAddress)
                    {
                        communication.RemoveRecipientsWithDuplicateAddress(rockContext);
                    }

                    communication.RemoveNonPrimaryPersonAliasRecipients(rockContext);
                }
            }

            var sendTasks = new List <Task>();

            foreach (var medium in communication.GetMediums())
            {
                var asyncMedium = medium as IAsyncMediumComponent;

                if (asyncMedium == null)
                {
                    sendTasks.Add(Task.Run(() => medium.Send(communication)));
                }
                else
                {
                    sendTasks.Add(asyncMedium.SendAsync(communication));
                }
            }

            var aggregateExceptions = new List <Exception>();

            while (sendTasks.Count > 0)
            {
                var completedTask = await Task.WhenAny(sendTasks).ConfigureAwait(false);

                if (completedTask.Exception != null)
                {
                    aggregateExceptions.AddRange(completedTask.Exception.InnerExceptions);
                }

                sendTasks.Remove(completedTask);
            }

            if (aggregateExceptions.Count > 0)
            {
                throw new AggregateException(aggregateExceptions);
            }

            using (var rockContext = new RockContext())
            {
                var dbCommunication = new CommunicationService(rockContext).Get(communication.Id);

                // Set the SendDateTime of the Communication
                dbCommunication.SendDateTime = RockDateTime.Now;
                rockContext.SaveChanges();
            }
        }