/// <inheritdoc/>
        protected internal override void SetDecryptableItem(
            JToken decryptableContent,
            Encryptor encryptor,
            CosmosSerializer cosmosSerializer)
        {
            if (this.decryptableItem != null)
            {
                throw new InvalidOperationException();
            }

            this.decryptableItem = new DecryptableItemCore(
                decryptableContent,
                encryptor,
                cosmosSerializer);
        }
        public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder <T>(
            string processorName,
            ChangesHandler <T> onChangesDelegate)
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(null);

            using (diagnosticsContext.CreateScope("GetChangeFeedProcessorBuilder"))
            {
                return(this.container.GetChangeFeedProcessorBuilder(
                           processorName,
                           async(IReadOnlyCollection <JObject> documents, CancellationToken cancellationToken) =>
                {
                    List <T> decryptItems = new List <T>(documents.Count);
                    if (typeof(T) == typeof(DecryptableItem))
                    {
                        foreach (JToken value in documents)
                        {
                            DecryptableItemCore item = new DecryptableItemCore(
                                value,
                                this.Encryptor,
                                this.CosmosSerializer);

                            decryptItems.Add((T)(object)item);
                        }
                    }
                    else
                    {
                        foreach (JObject document in documents)
                        {
                            (JObject decryptedDocument, DecryptionContext _) = await EncryptionProcessor.DecryptAsync(
                                document,
                                this.Encryptor,
                                diagnosticsContext,
                                cancellationToken);

                            decryptItems.Add(decryptedDocument.ToObject <T>());
                        }
                    }

                    // Call the original passed in delegate
                    await onChangesDelegate(decryptItems, cancellationToken);
                }));
            }
        }
        public override async Task <ItemResponse <T> > ReadItemAsync <T>(
            string id,
            PartitionKey partitionKey,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            using (diagnosticsContext.CreateScope("ReadItem"))
            {
                ResponseMessage responseMessage;

                if (typeof(T) == typeof(DecryptableItem))
                {
                    responseMessage = await this.ReadItemHelperAsync(
                        id,
                        partitionKey,
                        requestOptions,
                        decryptResponse : false,
                        diagnosticsContext,
                        cancellationToken);

                    DecryptableItemCore decryptableItem = new DecryptableItemCore(
                        EncryptionProcessor.BaseSerializer.FromStream <JObject>(responseMessage.Content),
                        this.Encryptor,
                        this.CosmosSerializer);

                    return(new EncryptionItemResponse <T>(
                               responseMessage,
                               (T)(object)decryptableItem));
                }

                responseMessage = await this.ReadItemHelperAsync(
                    id,
                    partitionKey,
                    requestOptions,
                    decryptResponse : true,
                    diagnosticsContext,
                    cancellationToken);

                return(this.ResponseFactory.CreateItemResponse <T>(responseMessage));
            }
        }