public override async Task <QueryResponseCore> DrainAsync(int maxElements, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();
            QueryResponseCore results = await base.DrainAsync(maxElements, token);

            if (!results.IsSuccess)
            {
                return(results);
            }

            List <CosmosElement> takedDocuments = results.CosmosElements.Take(this.takeCount).ToList();

            this.takeCount -= takedDocuments.Count;
            string updatedContinuationToken = null;

            if (results.DisallowContinuationTokenMessage == null)
            {
                if (!this.IsDone)
                {
                    string sourceContinuation = results.ContinuationToken;
                    TakeContinuationToken takeContinuationToken;
                    switch (this.takeEnum)
                    {
                    case TakeEnum.Limit:
                        takeContinuationToken = new LimitContinuationToken(
                            this.takeCount,
                            sourceContinuation);
                        break;

                    case TakeEnum.Top:
                        takeContinuationToken = new TopContinuationToken(
                            this.takeCount,
                            sourceContinuation);
                        break;

                    default:
                        throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}");
                    }

                    updatedContinuationToken = takeContinuationToken.ToString();
                }
            }

            return(QueryResponseCore.CreateSuccess(
                       result: takedDocuments,
                       continuationToken: updatedContinuationToken,
                       disallowContinuationTokenMessage: results.DisallowContinuationTokenMessage,
                       activityId: results.ActivityId,
                       requestCharge: results.RequestCharge,
                       queryMetricsText: results.QueryMetricsText,
                       queryMetrics: results.QueryMetrics,
                       requestStatistics: results.RequestStatistics,
                       responseLengthBytes: results.ResponseLengthBytes));
        }
        public override async Task <FeedResponse <CosmosElement> > DrainAsync(int maxElements, CancellationToken token)
        {
            FeedResponse <CosmosElement> results = await base.DrainAsync(maxElements, token);

            List <CosmosElement> takedDocuments = results.Take(this.takeCount).ToList();

            results = new FeedResponse <CosmosElement>(
                takedDocuments,
                takedDocuments.Count,
                results.Headers,
                results.UseETagAsContinuation,
                results.QueryMetrics,
                results.RequestStatistics,
                results.DisallowContinuationTokenMessage,
                results.ResponseLengthBytes);

            this.takeCount -= takedDocuments.Count;

            if (results.DisallowContinuationTokenMessage == null)
            {
                if (!this.IsDone)
                {
                    string sourceContinuation = results.ResponseContinuation;
                    TakeContinuationToken takeContinuationToken;
                    switch (this.takeEnum)
                    {
                    case TakeEnum.Limit:
                        takeContinuationToken = new LimitContinuationToken(
                            this.takeCount,
                            sourceContinuation);
                        break;

                    case TakeEnum.Top:
                        takeContinuationToken = new TopContinuationToken(
                            this.takeCount,
                            sourceContinuation);
                        break;

                    default:
                        throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {takeEnum}");
                    }

                    results.ResponseContinuation = takeContinuationToken.ToString();
                }
                else
                {
                    results.ResponseContinuation = null;
                }
            }

            return(results);
        }
        public override async Task <QueryResponse> DrainAsync(int maxElements, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();
            QueryResponse results = await base.DrainAsync(maxElements, token);

            if (!results.IsSuccessStatusCode)
            {
                return(results);
            }

            List <CosmosElement> takedDocuments = results.CosmosElements.Take(this.takeCount).ToList();

            this.takeCount -= takedDocuments.Count;
            string updatedContinuationToken = null;

            if (results.QueryHeaders.DisallowContinuationTokenMessage == null)
            {
                if (!this.IsDone)
                {
                    string sourceContinuation = results.Headers.ContinuationToken;
                    TakeContinuationToken takeContinuationToken;
                    switch (this.takeEnum)
                    {
                    case TakeEnum.Limit:
                        takeContinuationToken = new LimitContinuationToken(
                            this.takeCount,
                            sourceContinuation);
                        break;

                    case TakeEnum.Top:
                        takeContinuationToken = new TopContinuationToken(
                            this.takeCount,
                            sourceContinuation);
                        break;

                    default:
                        throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}");
                    }

                    updatedContinuationToken = takeContinuationToken.ToString();
                }
            }

            return(QueryResponse.CreateSuccess(
                       takedDocuments,
                       takedDocuments.Count,
                       results.ResponseLengthBytes,
                       results.QueryHeaders.CloneKnownProperties(updatedContinuationToken, results.QueryHeaders.DisallowContinuationTokenMessage),
                       results.queryMetrics));
        }
        public override bool TryGetContinuationToken(out string state)
        {
            if (!this.IsDone)
            {
                if (this.Source.TryGetContinuationToken(out string sourceState))
                {
                    TakeContinuationToken takeContinuationToken;
                    switch (this.takeEnum)
                    {
                    case TakeEnum.Limit:
                        takeContinuationToken = new LimitContinuationToken(
                            this.takeCount,
                            sourceState);
                        break;

                    case TakeEnum.Top:
                        takeContinuationToken = new TopContinuationToken(
                            this.takeCount,
                            sourceState);
                        break;

                    default:
                        throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}");
                    }

                    state = takeContinuationToken.ToString();
                    return(true);
                }
                else
                {
                    state = default(string);
                    return(false);
                }
            }
            else
            {
                state = default(string);
                return(true);
            }
        }