/// <summary>
        /// Gets an iterator for reencrypting the data.
        /// The source container should have no data changes during reEncryption operation or should have changefeed full fidelity enabled.
        /// </summary>
        /// <param name="container"> Source container object. </param>
        /// <param name="destinationContainerName"> Destination Container configured with new policy or key. </param>
        /// <param name="checkIfWritesHaveStoppedCb"> Callback to check if writes have stopped. The called function should return true if writes have stopped. If FullFidelity change feed is not enabled, return true by default. </param>
        /// <param name="changeFeedRequestOptions"> (Optional) Request options. </param>
        /// <param name="sourceFeedRange"> (Optional) The range to start from. </param>
        /// <param name="continuationToken"> (Optional) continuationToken: The continuation to resume from. </param>
        /// <param name="cancellationToken"> (Optional) System.Threading.CancellationToken representing request cancellation. </param>
        /// <returns> Returns a ReEncryption Iterator. </returns>
        public static async Task <ReEncryptionIterator> GetReEncryptionIteratorAsync(
            this Container container,
            string destinationContainerName,
            CosmosClient encryptionCosmosClient,
            Func <bool> checkIfWritesHaveStoppedCb,
            ChangeFeedRequestOptions changeFeedRequestOptions = null,
            FeedRange sourceFeedRange           = null,
            string continuationToken            = null,
            CancellationToken cancellationToken = default)
        {
            if (checkIfWritesHaveStoppedCb == null)
            {
                throw new ArgumentNullException(nameof(checkIfWritesHaveStoppedCb));
            }

            if (string.IsNullOrEmpty(destinationContainerName))
            {
                throw new ArgumentNullException(nameof(destinationContainerName));
            }

            if (!encryptionCosmosClient.ClientOptions.AllowBulkExecution)
            {
                throw new NotSupportedException("GetReEncryptionIteratorAsync requires client to be enabled with Bulk Execution. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
            }

            Container           destContainer       = encryptionCosmosClient.GetContainer(container.Database.Id, destinationContainerName);
            ContainerProperties containerProperties = await container.ReadContainerAsync(cancellationToken : cancellationToken);

            if (containerProperties.ChangeFeedPolicy.FullFidelityRetention == TimeSpan.Zero && Constants.IsFFChangeFeedSupported)
            {
                throw new NotSupportedException("GetReEncryptionIteratorAsync requires container to be enabled with FullFidelity ChangeFeedPolicy. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
            }

            ReEncryptionIterator reEncryptionIterator = new ReEncryptionIterator(
                container,
                destContainer,
                containerProperties.PartitionKeyPath,
                sourceFeedRange,
                changeFeedRequestOptions,
                continuationToken,
                checkIfWritesHaveStoppedCb,
                isFFChangeFeedSupported: Constants.IsFFChangeFeedSupported);

            return(reEncryptionIterator);
        }
        private static async Task <ReEncryptionResponseMessage> ReEncryptNextAsync(
            Container sourceContainer,
            FeedRange feedRange                 = null,
            string continuationToken            = null,
            CancellationToken cancellationToken = default)
        {
            // make sure the containers are configured with the throughput depending on how many requests you want to send to the Azure Cosmos DB service.
            ChangeFeedRequestOptions changeFeedRequestOptions = new ChangeFeedRequestOptions
            {
                PageSizeHint = PageHintSize,
            };

            ReEncryptionIterator iterator = await sourceContainer.GetReEncryptionIteratorAsync(
                DestinationContainer,
                client,
                Program.CheckAndSetWritesAsStopped,
                changeFeedRequestOptions,
                sourceFeedRange : feedRange,
                continuationToken : continuationToken);

            ReEncryptionResponseMessage responseMessage = null;

            while (iterator.HasMoreResults)
            {
                responseMessage = await iterator.EncryptNextAsync(cancellationToken);

                File.WriteAllText(ContinuationTokenFile + sourceContainer.Id + feedRange.ToString(), responseMessage.ContinuationToken);

                if (responseMessage.StatusCode == HttpStatusCode.NotModified)
                {
                    break;
                }
            }

            if (iterator.HasMoreResults == false)
            {
                return(new ReEncryptionResponseMessage(
                           responseMessage: responseMessage,
                           reEncryptionContinuationToken: null,
                           reEncryptionBulkOperationResponse: responseMessage.ReEncryptionBulkOperationResponse));
            }

            return(responseMessage);
        }