/// <inheritdoc />
        public async Task <VersionedDocumentUpsertResult <TDocument> > UpsertDocumentAsync <TDocument>(
            TDocument document,
            DocumentTypeMapping <TDocument> mapping,
            OperationOptions operationOptions)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            operationOptions = operationOptions ?? new OperationOptions();

            var documentId = mapping.IdMapper(document);

            // Get the newest document version if one exists.
            var existingDocument = await GetDocumentIncludingDeleted(documentId, mapping);

            if (existingDocument != null && operationOptions.CheckVersion.HasValue && operationOptions.CheckVersion != existingDocument.Version)
            {
                throw new NebulaStoreConcurrencyException("Existing document version does not match the specified check version.");
            }

            var version = CalculateNextVersion(existingDocument);

            var dbRecord = new VersionedDbDocument();

            dbRecord.Id           = CreateRecordId(documentId, version, mapping);
            dbRecord.DocumentId   = documentId;
            dbRecord.Service      = DbAccess.ConfigManager.ServiceName;
            dbRecord.PartitionKey = mapping.PartitionKeyMapper(document);
            dbRecord.Version      = version;
            dbRecord.Actor        = GetActorId();

            SetDocumentContent(dbRecord, document, mapping);

            await CreateDocumentAsync(dbRecord, existingDocument);

            return(new VersionedDocumentUpsertResult <TDocument>(documentId, version, document));
        }
        /// <inheritdoc />
        public async Task DeleteDocumentAsync <TDocument>(string id, DocumentTypeMapping <TDocument> mapping, OperationOptions operationOptions)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            operationOptions = operationOptions ?? new OperationOptions();

            var query     = QueryClient.CreateQueryById(id, mapping);
            var documents = await ExecuteQueryAsync(query);

            var existingDocument = FindLatestDocumentIncludingDeleted(documents);

            if (existingDocument == null)
            {
                // Document not found. Treated similarly to already deleted.
                return;
            }

            if (operationOptions.CheckVersion.HasValue && operationOptions.CheckVersion != existingDocument.Version)
            {
                throw new NebulaStoreConcurrencyException("Existing document version does not match the specified check version");
            }

            // Only perform removal if it is not already deleted.
            if (existingDocument.Deleted)
            {
                // Document already deleted.
                return;
            }

            // Document not deleted. Create deletion record.

            var version = CalculateNextVersion(existingDocument);

            var dbRecord = new VersionedDbDocument();

            dbRecord.Id           = CreateRecordId(id, version, mapping);
            dbRecord.DocumentId   = existingDocument.DocumentId;
            dbRecord.Service      = DbAccess.ConfigManager.ServiceName;
            dbRecord.PartitionKey = existingDocument.PartitionKey;
            dbRecord.Version      = version;
            dbRecord.Deleted      = true;
            dbRecord.Actor        = GetActorId();
            dbRecord.Timestamp    = DateTime.UtcNow;

            SetDocumentContentFromExisting(dbRecord, existingDocument, mapping);

            await CreateDocumentAsync(dbRecord, existingDocument);
        }