public Task <bool> NominateProjectAsync(string projectUniqueName, IVsProjectRestoreInfo projectRestoreInfo, CancellationToken token)
        {
            if (string.IsNullOrEmpty(projectUniqueName))
            {
                throw new ArgumentException(Resources.Argument_Cannot_Be_Null_Or_Empty, nameof(projectUniqueName));
            }

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

            if (projectRestoreInfo.TargetFrameworks == null)
            {
                throw new InvalidOperationException("TargetFrameworks cannot be null.");
            }

            try
            {
                _logger.LogInformation(
                    $"The nominate API is called for '{projectUniqueName}'.");

                var projectNames = ProjectNames.FromFullProjectPath(projectUniqueName);

                var dgSpec = ToDependencyGraphSpec(projectNames, projectRestoreInfo);
#if DEBUG
                DumpProjectRestoreInfo(projectUniqueName, dgSpec);
#endif
                _projectSystemCache.AddProjectRestoreInfo(projectNames, dgSpec);

                // returned task completes when scheduled restore operation completes.
                var restoreTask = _restoreWorker.ScheduleRestoreAsync(
                    SolutionRestoreRequest.OnUpdate(),
                    token);

                return(restoreTask);
            }
            catch (Exception e)
                when(e is InvalidOperationException || e is ArgumentException || e is FormatException)
                {
                    _logger.LogError(e.ToString());
                    return(Task.FromResult(false));
                }
            catch (Exception e)
            {
                _logger.LogError(e.ToString());
                throw;
            }
        }
        public async Task <bool> DownloadPackagesAsync(ICollection <PackageDownloadRequest> requests, TimeSpan timeout, CancellationToken cancellationToken)
        {
            logger.LogMinimal($"Downloading {requests.Count} package(s)");

            var cts = new CancellationTokenSource(timeout);

            cancellationToken.Register(() => cts.Cancel());

            using (var cacheContext = new SourceCacheContext())
                using (var throttle = new SemaphoreSlim(8))
                {
                    var defaultSettings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null);
                    var sourceProvider  = new CachingSourceProvider(new PackageSourceProvider(defaultSettings));
                    var tasks           = new List <Task <bool> >();

                    foreach (var request in requests)
                    {
                        var feeds = request.Sources
                                    .Select(s => s?.Trim())
                                    .Where(s => !string.IsNullOrEmpty(s))
                                    .Distinct()
                                    .Select(sourceProvider.CreateRepository);
                        tasks.Add(DownloadPackageAsync(request, feeds, cacheContext, throttle, logger, cts.Token));
                    }

                    var all   = Task.WhenAll(tasks);
                    var delay = Task.Delay(timeout);

                    var finished = await Task.WhenAny(all, delay);

                    if (ReferenceEquals(delay, finished))
                    {
                        logger.LogError($"Timed out after {timeout.TotalSeconds}s");
                        cts.Cancel();
                        return(false);
                    }

                    if (!tasks.All(a => a.Result))
                    {
                        logger.LogError("Failed to download all packages");
                        return(false);
                    }

                    return(true);
                }
        }
        private async Task <bool> DownloadPackageAsync(
            PackageDownloadRequest request,
            IEnumerable <SourceRepository> repositories,
            SourceCacheContext cacheContext,
            SemaphoreSlim throttle,
            NuGet.Common.ILogger logger,
            CancellationToken cancellationToken)
        {
            foreach (var repo in repositories)
            {
                var findPackageByIdResource = await repo.GetResourceAsync <FindPackageByIdResource>(cancellationToken);

                if (findPackageByIdResource == null)
                {
                    logger.LogError($"{nameof(FindPackageByIdResource)} for '{repo}' could not be loaded.");
                    return(false);
                }

                using (var downloader = await findPackageByIdResource.GetPackageDownloaderAsync(request.Identity, cacheContext, logger, cancellationToken))
                {
                    if (downloader == null)
                    {
                        logger.LogInformation($"Package {request.Identity.Id} {request.Identity.Version} is not available on '{repo}'");

                        // Skip to the next source if a package cannot be found in a given source.
                        continue;
                    }

                    downloader.SetThrottle(throttle);
                    if (!await downloader.CopyNupkgFileToAsync(request.OutputPath, cancellationToken))
                    {
                        logger.LogError($"Could not download {request.Identity.Id} {request.Identity.Version} from {repo}.");
                        return(false);
                    }
                }

                return(true);
            }

            logger.LogError($"{request.Identity.Id} {request.Identity.Version} is not available.'");
            return(false);
        }