/// <summary>
        /// Retrieve all version information for a package.
        /// </summary>
        /// <param name="id">Package ID.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task <IEnumerable <NuGetVersion> > GetVersionsAsync(string id, CancellationToken cancellationToken = default)
        {
            var resource = await _repository.GetResourceAsync <FindPackageByIdResource>(cancellationToken);

            using (var context = SourceCacheContextFactory.Create())
            {
                return(await resource.GetAllVersionsAsync(id, context, _logger, cancellationToken));
            }
        }
        /// <summary>
        /// Determine if a package version exists in nuget.
        /// </summary>
        /// <param name="id">Package ID.</param>
        /// <param name="version">Package version.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task <bool> ExistsAsync(string id, string version, CancellationToken cancellationToken = default)
        {
            var resource = await _repository.GetResourceAsync <FindPackageByIdResource>(cancellationToken);

            using (var context = SourceCacheContextFactory.Create())
            {
                return(await resource.DoesPackageExistAsync(id, NuGetVersion.Parse(version), context, _logger, cancellationToken));
            }
        }
        /// <summary>
        /// Retrieve a package's metadata.
        /// </summary>
        /// <param name="packageIdentity">Package identity.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task <IPackageSearchMetadata> GetAsync(PackageIdentity packageIdentity, CancellationToken cancellationToken = default)
        {
            var resource = await _repository.GetResourceAsync <PackageMetadataResource>(cancellationToken);

            using (var context = SourceCacheContextFactory.Create())
            {
                return(await resource.GetMetadataAsync(packageIdentity, context, _logger, cancellationToken));
            }
        }
        /// <summary>
        /// Retrieve metadata for all the versions of a given package.
        /// </summary>
        /// <param name="id">Package ID.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task <IEnumerable <IPackageSearchMetadata> > GetAsync(string id, CancellationToken cancellationToken = default)
        {
            var resource = await _repository.GetResourceAsync <PackageMetadataResource>(cancellationToken);

            using (var context = SourceCacheContextFactory.Create())
            {
                // TODO: add options
                return(await resource.GetMetadataAsync(id, true, true, context, _logger, cancellationToken));
            }
        }
        /// <summary>
        /// Download a package and return as a stream.
        /// </summary>
        /// <param name="id">Package ID.</param>
        /// <param name="version">Package version.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        /// <exception cref="T:ByteDev.Nuget.NugetPackageNotFoundException">Package could not be found.</exception>
        public async Task <Stream> DownloadToStreamAsync(string id, string version, CancellationToken cancellationToken = default)
        {
            var resource = await _repository.GetResourceAsync <FindPackageByIdResource>(cancellationToken);

            using (var context = SourceCacheContextFactory.Create())
            {
                Stream destinationStream = new MemoryStream();
                await resource.CopyNupkgToStreamAsync(id, NuGetVersion.Parse(version), destinationStream, context, _logger, cancellationToken);

                if (destinationStream.IsEmpty())
                {
                    destinationStream.Dispose();
                    throw new NugetPackageNotFoundException(id, version);
                }

                return(destinationStream);
            }
        }