/// <summary>
        /// Asynchronously iterates over the input sequence and performs the specified action on each element of the <see cref="IAsyncQueryable{T}"/>.
        /// Return <see langword="true"/> from <paramref name="action"/> to cause the loop to gracefully break; <see langword="false"/> to continue looping.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
        /// <param name="source">An <see cref="IAsyncQueryable{T}"/> containing items to operate on.</param>
        /// <param name="action">The action to perform each element. Return <see langword="true"/> to cause the loop to gracefully break.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
        public static async Task ForEachAsync <TSource>(this IAsyncQueryable <TSource> source, Func <TSource, bool> action, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            while (await source.MoveNextAsync(cancellationToken).ConfigureAwait(false))
            {
                bool breakRequested = false;

                foreach (var item in source.CurrentPage)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    breakRequested |= action(item);

                    if (breakRequested)
                    {
                        break;
                    }
                }

                if (breakRequested)
                {
                    break;
                }
            }
        }
        /// <summary>
        /// Asynchronously returns the only element of a sequence, or a default value if the sequence is
        /// empty; this method throws an exception if there is more than one element in the sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
        /// <param name="source">An <see cref="IAsyncQueryable{T}"/> to return the single element of.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The single element of the input sequence, or <c>default(TSource)</c> if the sequence contains no elements.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        /// <exception cref="System.InvalidOperationException"><paramref name="source"/> has more than one element.</exception>
        public static async Task <TSource> SingleOrDefaultAsync <TSource>(this IAsyncQueryable <TSource> source, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (!await source.MoveNextAsync(cancellationToken).ConfigureAwait(false))
            {
                return(default(TSource));
            }

            return(source.CurrentPage.SingleOrDefault());
        }
        /// <summary>
        /// Asynchronously returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
        /// <param name="source">An <see cref="IAsyncQueryable{T}"/> to return the single element of.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The single element of the input sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        /// <exception cref="System.InvalidOperationException"><paramref name="source"/> has more than one element.</exception>
        public static async Task <TSource> SingleAsync <TSource>(this IAsyncQueryable <TSource> source, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (!await source.MoveNextAsync(cancellationToken).ConfigureAwait(false))
            {
                throw new InvalidOperationException("The sequence has no elements.");
            }

            return(source.CurrentPage.Single());
        }
        /// <summary>
        /// Asynchronously returns the input sequence as a <see cref="List{T}"/>.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
        /// <param name="source">An <see cref="IAsyncQueryable{T}"/> to get items from.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A list of all items from the input sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static async Task <List <TSource> > ToListAsync <TSource>(this IAsyncQueryable <TSource> source, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            var results = new List <TSource>();

            while (await source.MoveNextAsync(cancellationToken).ConfigureAwait(false))
            {
                results.AddRange(source.CurrentPage);
            }

            return(results);
        }