/// <summary>
        /// Inserts a Document object into the storage.
        /// </summary>
        /// <param name="collectionName">Name of the collection.</param>
        /// <param name="document">The Document object to insert.</param>
        /// <returns>
        /// The GUID of the inserted Document
        /// </returns>
        /// <exception cref="System.ArgumentException"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <remarks>
        /// If the Document object does not have an id, it will be auto-generated.
        /// </remarks>
        public async Task<Guid> InsertAsync(string collectionName, Document document)
        {
            if (String.IsNullOrWhiteSpace(collectionName))
                throw new ArgumentException($"{nameof(collectionName)} cannot be null or empty");
            if (document == null)
                throw new ArgumentNullException(nameof(document));

            if (document._id == null || document._id.Value == Guid.Empty)
                document._id = Guid.NewGuid();

            document._createdTimestamp = document._modifiedTimestamp = DateTime.UtcNow;
            document.ConvertDatesToUtc();

            EnsureCollectionIsInitialized(collectionName);

            var kv = document.ToKeyValuePair();
            await _storageEngine.InsertAsync(collectionName, kv).ConfigureAwait(false);
            return document._id.Value;
        }
        /// <summary>
        /// Updates the Document object.
        /// </summary>
        /// <param name="collectionName">Name of the collection.</param>
        /// <param name="document">The Document object to update.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentException"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.Exception">The document does not have an _id field</exception>
        public async Task<int> UpdateAsync(string collectionName, Document document)
        {
            if (String.IsNullOrWhiteSpace(collectionName))
                throw new ArgumentException($"{nameof(collectionName)} cannot be null or empty");
            if (document == null)
                throw new ArgumentNullException(nameof(document));

            if (document._id == null || document._id == Guid.Empty)
                throw new Exception("The document does not have an _id field");

            EnsureCollectionIsInitialized(collectionName);

            var key = document._id.Value.ToByteArray();
            var existingKv = await _storageEngine.GetAsync(collectionName, key).ConfigureAwait(false);
            if (existingKv == null)                
                return 0;

            // Make sure the _createdTimestamp is not overwritten
            // Copy the value from the existing Document.
            var existingDocument = existingKv.ToDocument();
            document._createdTimestamp = existingDocument._createdTimestamp;

            // Always set the _modifiedTimestamp to the current UTC date/time.
            document._modifiedTimestamp = DateTime.UtcNow;

            // Make sure all date/times are in ISO UTC format.
            document.ConvertDatesToUtc();

            var updatedKv = document.ToKeyValuePair();
            var updatedCount = await _storageEngine.UpdateAsync(collectionName, updatedKv).ConfigureAwait(false);
            return updatedCount;
            
        }