public async Task <string[]> DownloadAsync(string packageFolder, string packageName, string packageVersion = null, bool includePrerelease = false,
                                                   NuGetFeed packageFeed = null, bool onlyDownload = false)
        {
            if (!Directory.Exists(packageFolder))
            {
                Directory.CreateDirectory(packageFolder);
            }

            var providers                = GetNugetResourceProviders();
            var settings                 = Settings.LoadDefaultSettings(packageFolder, null, new MachineWideSettings());
            var packageSourceProvider    = new PackageSourceProvider(settings);
            var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, providers);

            var dotNetFramework = Assembly
                                  .GetEntryAssembly()
                                  .GetCustomAttribute <TargetFrameworkAttribute>()?
                                  .FrameworkName;

            var frameworkNameProvider = new FrameworkNameProvider(
                new[] { DefaultFrameworkMappings.Instance },
                new[] { DefaultPortableFrameworkMappings.Instance });

            var nuGetFramework = NuGetFramework.ParseFrameworkName(dotNetFramework, frameworkNameProvider);

            IPackageSearchMetadata package    = null;
            SourceRepository       sourceRepo = null;

            if (!string.IsNullOrWhiteSpace(packageFeed?.Feed))
            {
                sourceRepo = GetSourceRepo(packageFeed, providers);

                package = await SearchPackageAsync(packageName, packageVersion, includePrerelease, sourceRepo);
            }
            else
            {
                foreach (var repo in sourceRepositoryProvider.GetRepositories())
                {
                    if (packageFeed != null && repo.PackageSource.Name != packageFeed.Name)
                    {
                        continue;
                    }

                    package = await SearchPackageAsync(packageName, packageVersion, includePrerelease, repo);

                    if (package != null)
                    {
                        sourceRepo = repo;

                        break;
                    }
                }
            }

            if (package == null)
            {
                throw new PackageNotFoundException($"Couldn't find package '{packageVersion}'.{packageVersion}.");
            }

            var project        = new PluginFolderNugetProject(packageFolder, package, nuGetFramework, onlyDownload);
            var packageManager = new NuGetPackageManager(sourceRepositoryProvider, settings, packageFolder)
            {
                PackagesFolderNuGetProject = project
            };

            var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, _logger);

            var projectContext = new FolderProjectContext(_logger)
            {
                PackageExtractionContext = new PackageExtractionContext(
                    PackageSaveMode.Defaultv2,
                    PackageExtractionBehavior.XmlDocFileSaveMode,
                    clientPolicyContext,
                    _logger)
            };

            var resolutionContext = new ResolutionContext(
                DependencyBehavior.Lowest,
                includePrerelease,
                includeUnlisted: false,
                VersionConstraints.None);

            var downloadContext = new PackageDownloadContext(
                resolutionContext.SourceCacheContext,
                packageFolder,
                resolutionContext.SourceCacheContext.DirectDownload);

            // We are waiting here instead of await as await actually doesn't seem to work correctly.
            packageManager.InstallPackageAsync(
                project,
                package.Identity,
                resolutionContext,
                projectContext,
                downloadContext,
                sourceRepo,
                new List <SourceRepository>(),
                CancellationToken.None).Wait();

            if (onlyDownload)
            {
                var versionFolder = Path.Combine(packageFolder, package.Identity.ToString());

                return(Directory.GetFiles(versionFolder, "*.*", SearchOption.AllDirectories));
            }

            return(await project.GetPluginAssemblyFilesAsync());
        }
        public async Task <string[]> DownloadAsync(IPackageSearchMetadata packageIdentity, SourceRepository repository,
                                                   string downloadFolder, bool onlyDownload = false)
        {
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

            var providers                = GetNugetResourceProviders();
            var settings                 = Settings.LoadDefaultSettings(downloadFolder, null, new MachineWideSettings());
            var packageSourceProvider    = new PackageSourceProvider(settings);
            var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, providers);

            var dotNetFramework = Assembly
                                  .GetEntryAssembly()
                                  .GetCustomAttribute <TargetFrameworkAttribute>()?
                                  .FrameworkName;

            var frameworkNameProvider = new FrameworkNameProvider(
                new[] { DefaultFrameworkMappings.Instance },
                new[] { DefaultPortableFrameworkMappings.Instance });

            var nuGetFramework = NuGetFramework.ParseFrameworkName(dotNetFramework, frameworkNameProvider);

            var project = new PluginFolderNugetProject(downloadFolder, packageIdentity, nuGetFramework, onlyDownload);

            var packageManager = new NuGetPackageManager(sourceRepositoryProvider, settings, downloadFolder)
            {
                PackagesFolderNuGetProject = project
            };

            var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, _logger);

            var projectContext = new FolderProjectContext(_logger)
            {
                PackageExtractionContext = new PackageExtractionContext(
                    PackageSaveMode.Defaultv2,
                    PackageExtractionBehavior.XmlDocFileSaveMode,
                    clientPolicyContext,
                    _logger)
            };

            var resolutionContext = new ResolutionContext(
                DependencyBehavior.Lowest,
                true,
                includeUnlisted: false,
                VersionConstraints.None);

            var downloadContext = new PackageDownloadContext(
                resolutionContext.SourceCacheContext,
                downloadFolder,
                resolutionContext.SourceCacheContext.DirectDownload);

            await packageManager.InstallPackageAsync(
                project,
                packageIdentity.Identity,
                resolutionContext,
                projectContext,
                downloadContext,
                repository,
                new List <SourceRepository>(),
                CancellationToken.None);

            var versionFolder = Path.Combine(downloadFolder, packageIdentity.Identity.ToString());

            return(Directory.GetFiles(versionFolder, "*.*", SearchOption.AllDirectories));
        }