/// <summary>
        /// Wrap the provided search result task via a lazy enumerable. The search is continued
        /// until the <see cref="SearchResult{T}.NextToken"/> is <code>null</code>, indicating that
        /// there are no more results.
        /// </summary>
        /// <param name="packageFeed">The package feed to perform the search on.</param>
        /// <param name="searchTask">The initial search result task to operate on.</param>
        /// <param name="handleException">
        /// A callback for handling exceptions during enumeration. The first parameter is the
        /// source that encountered the exception. The second parameter is the exception itself.
        /// This callback is never called from multiple threads at once.
        /// </param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The lazy enumerable of package search metadata.</returns>
        public static IEnumerable <IPackageSearchMetadata> Enumerate(
            IPackageFeed packageFeed,
            Task <SearchResult <IPackageSearchMetadata> > searchTask,
            Action <string, Exception> handleException,
            CancellationToken cancellationToken)
        {
            var enumerator = new PackageFeedEnumerator(packageFeed, searchTask, handleException, cancellationToken);

            return(new PackageFeedEnumerable(enumerator));
        }
        private PackageFeedEnumerator(PackageFeedEnumerator other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            _packageFeed       = other._packageFeed;
            _startFromTask     = other._startFromTask;
            _handleException   = other._handleException;
            _cancellationToken = other._cancellationToken;

            Reset();
        }
 public PackageFeedEnumerable(PackageFeedEnumerator enumerator)
 {
     _enumerator = enumerator;
 }