public async Task <DocumentFeedResponse <CosmosElement> > ExecuteNextFeedResponseAsync(CancellationToken token)
        {
            if (this.IsDone)
            {
                throw new InvalidOperationException(RMResources.DocumentQueryExecutionContextIsDone);
            }

            Error error = null;

            try
            {
                return(await this.innerExecutionContext.ExecuteNextFeedResponseAsync(token));
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode != HttpStatusCode.BadRequest || ex.GetSubStatus() != SubStatusCodes.CrossPartitionQueryNotServable)
                {
                    throw;
                }

                error = ex.Error;
            }

            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo =
                JsonConvert.DeserializeObject <PartitionedQueryExecutionInfo>(error.AdditionalErrorInfo);

            DefaultDocumentQueryExecutionContext queryExecutionContext =
                (DefaultDocumentQueryExecutionContext)this.innerExecutionContext;

            List <PartitionKeyRange> partitionKeyRanges =
                await
                queryExecutionContext.GetTargetPartitionKeyRangesAsync(collection.ResourceId,
                                                                       partitionedQueryExecutionInfo.QueryRanges);

            DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams(this.client, this.resourceTypeEnum, this.resourceType, this.expression, this.feedOptions, this.resourceLink, false, correlatedActivityId);
            this.innerExecutionContext = await DocumentQueryExecutionContextFactory.CreateSpecializedDocumentQueryExecutionContextAsync(
                constructorParams,
                partitionedQueryExecutionInfo,
                partitionKeyRanges,
                this.collection.ResourceId,
                this.isContinuationExpected,
                token);

            return(await this.innerExecutionContext.ExecuteNextFeedResponseAsync(token));
        }
        /// <summary>
        /// Gets the list of partition key ranges.
        /// 1. Check partition key range id
        /// 2. Check Partition key
        /// 3. Check the effective partition key
        /// 4. Get the range from the PartitionedQueryExecutionInfo
        /// </summary>
        internal static async Task <List <PartitionKeyRange> > GetTargetPartitionKeyRangesAsync(
            DefaultDocumentQueryExecutionContext queryExecutionContext,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            ContainerProperties collection,
            FeedOptions feedOptions)
        {
            List <PartitionKeyRange> targetRanges = null;

            if (!string.IsNullOrEmpty(feedOptions.PartitionKeyRangeId))
            {
                targetRanges = new List <PartitionKeyRange>()
                {
                    await queryExecutionContext.GetTargetPartitionKeyRangeByIdAsync(
                        collection.ResourceId,
                        feedOptions.PartitionKeyRangeId)
                };
            }
            else if (feedOptions.PartitionKey != null)
            {
                targetRanges = await queryExecutionContext.GetTargetPartitionKeyRangesByEpkStringAsync(
                    collection.ResourceId,
                    feedOptions.PartitionKey.InternalKey.GetEffectivePartitionKeyString(collection.PartitionKey));
            }
            else if (TryGetEpkProperty(feedOptions, out string effectivePartitionKeyString))
            {
                targetRanges = await queryExecutionContext.GetTargetPartitionKeyRangesByEpkStringAsync(
                    collection.ResourceId,
                    effectivePartitionKeyString);
            }
            else
            {
                targetRanges = await queryExecutionContext.GetTargetPartitionKeyRangesAsync(
                    collection.ResourceId,
                    partitionedQueryExecutionInfo.QueryRanges);
            }

            return(targetRanges);
        }