private async Task <IEnumerable <CompositeContinuationToken> > BuildCompositeTokensAsync(string initialContinuationToken)
        {
            if (string.IsNullOrEmpty(initialContinuationToken))
            {
                // Initialize composite token with all the ranges
                IReadOnlyList <Documents.PartitionKeyRange> allRanges = await this.pkRangeCacheDelegate(
                    this.containerRid,
                    new Documents.Routing.Range <string>(
                        Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey,
                        Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey,
                        isMinInclusive: true,
                        isMaxInclusive: false),
                    false);

                Debug.Assert(allRanges.Count != 0);
                // Initial state for a scenario where user does not provide any initial continuation token.
                // StartTime and StartFromBeginning can handle the logic if the user wants to start reading from any particular point in time
                // After the first iteration, token will be updated with a recent value
                return(allRanges.Select(e => StandByFeedContinuationToken.CreateCompositeContinuationTokenForRange(e.MinInclusive, e.MaxExclusive, null)));
            }

            try
            {
                return(StandByFeedContinuationToken.DeserializeTokens(initialContinuationToken));
            }
            catch (JsonReaderException ex)
            {
                throw new ArgumentOutOfRangeException($"Provided token has an invalid format: {initialContinuationToken}", ex);
            }
        }
        private void HandleSplit(IReadOnlyList <Documents.PartitionKeyRange> keyRanges)
        {
            if (keyRanges == null)
            {
                throw new ArgumentNullException(nameof(keyRanges));
            }

            // Update current
            Documents.PartitionKeyRange firstRange = keyRanges[0];
            this.currentToken.Range = new Documents.Routing.Range <string>(firstRange.MinInclusive, firstRange.MaxExclusive, true, false);
            // Add children
            foreach (Documents.PartitionKeyRange keyRange in keyRanges.Skip(1))
            {
                this.compositeContinuationTokens.Enqueue(StandByFeedContinuationToken.CreateCompositeContinuationTokenForRange(keyRange.MinInclusive, keyRange.MaxExclusive, this.currentToken.Token));
            }
        }
 public static string CreateForRange(
     string containerRid,
     string minInclusive,
     string maxExclusive)
 {
     if (string.IsNullOrWhiteSpace(containerRid))
     {
         throw new ArgumentNullException(nameof(containerRid));
     }
     // MinInclusive can be an empty string
     if (minInclusive == null)
     {
         throw new ArgumentNullException(nameof(minInclusive));
     }
     if (string.IsNullOrWhiteSpace(maxExclusive))
     {
         throw new ArgumentNullException(nameof(maxExclusive));
     }
     return(StandByFeedContinuationToken.SerializeTokens(new CompositeContinuationToken[1] {
         StandByFeedContinuationToken.CreateCompositeContinuationTokenForRange(minInclusive, maxExclusive, null)
     }));
 }