private async Task <DependencyVersionsFile> TryDownloadLineupPackage(MSBuildLogger logger, string tmpNupkgPath)
        {
            VersionRange versionRange;

            if (string.IsNullOrEmpty(LineupPackageVersion))
            {
                versionRange = VersionRange.AllFloating;
            }
            else if (!VersionRange.TryParse(LineupPackageVersion, out versionRange))
            {
                Log.LogError($"{LineupPackageVersion} is not a valid NuGet package version");
                return(null);
            }

            var packageVersion = await GetPackageVersion(versionRange);

            if (packageVersion == null)
            {
                Log.LogError($"Could not find a version of {LineupPackageId} in the version range {versionRange}.");
                return(null);
            }

            var packageId = new PackageIdentity(LineupPackageId, packageVersion);

            var request = new PackageDownloadRequest
            {
                Identity   = packageId,
                OutputPath = tmpNupkgPath,
                Sources    = new[] { LineupPackageRestoreSource },
            };

            var result = await new PackageDownloader(logger).DownloadPackagesAsync(new[] { request }, TimeSpan.FromSeconds(60), _cts.Token);

            if (!result)
            {
                Log.LogError("Could not download the lineup package");
                return(null);
            }

            using (var nupkgReader = new PackageArchiveReader(tmpNupkgPath))
            {
                using (var stream = nupkgReader.GetStream("build/dependencies.props"))
                {
                    using (var reader = new XmlTextReader(stream))
                    {
                        var projectRoot = ProjectRootElement.Create(reader);
                        return(DependencyVersionsFile.Load(projectRoot));
                    }
                }
            }
        }
        public async Task <bool> ExecuteAsync()
        {
            DestinationFolder = DestinationFolder.Replace('\\', '/');

            var requests      = new List <PackageDownloadRequest>();
            var files         = new List <ITaskItem>();
            var downloadCount = 0;

            foreach (var item in Packages)
            {
                var id         = item.ItemSpec;
                var rawVersion = item.GetMetadata("Version");
                if (!NuGetVersion.TryParse(rawVersion, out var version))
                {
                    Log.LogError($"Package '{id}' has an invalid 'Version' metadata value: '{rawVersion}'.");
                    return(false);
                }

                var source = item.GetMetadata("Source");
                if (string.IsNullOrEmpty(source))
                {
                    Log.LogError($"Package '{id}' is missing the 'Source' metadata value.");
                    return(false);
                }

                var outputPath = Path.Combine(DestinationFolder, $"{id.ToLowerInvariant()}.{version.ToNormalizedString()}.nupkg");

                files.Add(new TaskItem(outputPath));
                if (File.Exists(outputPath))
                {
                    Log.LogMessage($"Skipping {id} {version}. Already exists in '{outputPath}'");
                    continue;
                }
                else
                {
                    downloadCount++;

                    var request = new PackageDownloadRequest
                    {
                        Identity   = new PackageIdentity(id, version),
                        OutputPath = outputPath,
                        Sources    = source.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries),
                    };

                    requests.Add(request);
                }
            }

            Files = files.ToArray();

            if (downloadCount == 0)
            {
                Log.LogMessage("All packages are downloaded.");
                return(true);
            }

            Directory.CreateDirectory(DestinationFolder);
            var logger     = new MSBuildLogger(Log);
            var timeout    = TimeSpan.FromSeconds(TimeoutSeconds);
            var downloader = new PackageDownloader(logger);
            var timer      = Stopwatch.StartNew();

            var result = await downloader.DownloadPackagesAsync(requests, timeout, _cts.Token);

            timer.Stop();
            logger.LogMinimal($"Finished downloading {requests.Count} package(s) in {timer.ElapsedMilliseconds}ms");
            return(result);
        }