/// <summary>
        /// Sends all documents.
        /// </summary>
        /// <returns></returns>
        public async Task SendDocumentsInQueue()
        {
            var notificationItems = new List <NotificationData>();

            // Get all the 'Pending' documents
            var pendingDocuments = await _dataStore.FilterDocuments(new[] { DocumentStatus.Pending });

            // Set documents statuses to 'Sending'
            foreach (var document in pendingDocuments)
            {
                document.Status = DocumentStatus.Sending;
                await _dataStore.UpdateDocument(document);
            }

            Log.Information("Found '{documentsToSend}' document(s) to send", pendingDocuments.Count);

            // Process each document
            foreach (var document in pendingDocuments)
            {
                EventType?newEventType = null;

                string         newEventMessage   = null;
                DocumentStatus?newDocumentStatus = null;

                bool skipDocument = false;

                // Check if current document supercedes a document that hasn't been sent yet then set status back to 'Pending' and do not process document
                if (!string.IsNullOrEmpty(document.DocumentIdToReplace))
                {
                    var replaceDocument = await _dataStore.GetDocument(document.DocumentIdToReplace);

                    if (replaceDocument != null && replaceDocument.Status != DocumentStatus.Sent)
                    {
                        newEventType    = EventType.Deferred;
                        newEventMessage = $"Document to supercede ({replaceDocument.DocumentId}) hasn't been sent";

                        newDocumentStatus = DocumentStatus.Pending;

                        skipDocument = true;
                    }
                }

                if (!skipDocument)
                {
                    var uploadRequest = new DocumentUploadRequest
                    {
                        DocumentData   = document.DocumentData,
                        FormatCode     = document.FormatCode,
                        FormatCodeName = document.FormatCodeName
                    };

                    // Upload document
                    bool wasSendSuccessful;
                    try
                    {
                        DocumentUploadResult documentUploadResult = await _mhrDocumentUploadClient.UploadDocument(uploadRequest);

                        Log.Information("Document with ID '{documentId}' upload status is '{uploadStatus}'", document.DocumentId, documentUploadResult.Status);

                        wasSendSuccessful = documentUploadResult.Status == DocumentUploadResultStatus.Success;
                        if (!wasSendSuccessful)
                        {
                            // Determine the message
                            newEventMessage = documentUploadResult.AdditionalInfo;
                            if (!string.IsNullOrEmpty(documentUploadResult.ErrorCode))
                            {
                                newEventMessage = $"Code: {documentUploadResult.ErrorCode} - {newEventMessage}";
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(e, "Error uploading document");

                        wasSendSuccessful = false;
                        newEventMessage   = e.Message;
                    }

                    // Determine the result
                    if (wasSendSuccessful)
                    {
                        newEventType = EventType.Success;

                        newDocumentStatus = DocumentStatus.Sent;
                    }
                    else
                    {
                        newEventType = EventType.Failed;

                        // Check if the retry limit has been reached
                        if (document.Events.Count(e => e.Type == EventType.Failed) + 1 >= _retryLimit)
                        {
                            Log.Information("Retry limit reached for document with ID '{documentId}'", document.DocumentId);

                            newDocumentStatus = DocumentStatus.RetryLimitReached;
                        }
                        else
                        {
                            // Change back to pending
                            newDocumentStatus = DocumentStatus.Pending;
                        }
                    }
                }

                // Add an event
                await _dataStore.AddEvent(document, newEventType.Value, newEventMessage);

                // Set the status
                document.Status = newDocumentStatus.Value;

                // Update the document
                await _dataStore.UpdateDocument(document);

                // Add a notification
                notificationItems.Add(new NotificationData
                {
                    DocumentEvent = newEventType.Value,
                    DocumentId    = document.DocumentId
                });
            }

            // Send any notifications
            if (notificationItems.Any())
            {
                await _notificationService.SendNotification(notificationItems);
            }
        }