/// <summary>
        /// Asynchronously downloads a package.
        /// </summary>
        /// <param name="identity">The package identity.</param>
        /// <param name="downloadContext">A package download context.</param>
        /// <param name="globalPackagesFolder">The path to the global packages folder.</param>
        /// <param name="logger">A logger.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.
        /// The task result (<see cref="Task{TResult}.Result" />) returns
        /// a <see cref="DownloadResourceResult" />.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="identity" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="downloadContext" />
        /// is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="logger" /> is <c>null</c>.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
        /// is cancelled.</exception>
        public async override Task <DownloadResourceResult> GetDownloadResourceResultAsync(
            PackageIdentity identity,
            PackageDownloadContext downloadContext,
            string globalPackagesFolder,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (identity == null)
            {
                throw new ArgumentNullException(nameof(identity));
            }

            if (downloadContext == null)
            {
                throw new ArgumentNullException(nameof(downloadContext));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            cancellationToken.ThrowIfCancellationRequested();

            AddOrUpdateLogger(_plugin, logger);

            await _utilities.DoOncePerPluginLifetimeAsync(
                MessageMethod.SetLogLevel.ToString(),
                () => SetLogLevelAsync(logger, cancellationToken),
                cancellationToken);

            var response = await _plugin.Connection.SendRequestAndReceiveResponseAsync <PrefetchPackageRequest, PrefetchPackageResponse>(
                MessageMethod.PrefetchPackage,
                new PrefetchPackageRequest(_packageSource.Source, identity.Id, identity.Version.ToNormalizedString()),
                cancellationToken);

            if (response != null)
            {
                if (response.ResponseCode == MessageResponseCode.Success)
                {
                    var packageReader = new PluginPackageReader(_plugin, identity, _packageSource.Source);

                    return(new DownloadResourceResult(packageReader, _packageSource.Source));
                }

                if (response.ResponseCode == MessageResponseCode.NotFound)
                {
                    return(new DownloadResourceResult(DownloadResourceResultStatus.NotFound));
                }
            }

            throw new PluginException(
                      string.Format(CultureInfo.CurrentCulture,
                                    Strings.Plugin_PackageDownloadFailed,
                                    _plugin.Name,
                                    $"{identity.Id}.{identity.Version.ToNormalizedString()}"));
        }