public static async Task <IEnumerable <NuGetProjectAction> > GetInstallProjectActionsAsync(
            this NuGetPackageManager packageManager,
            NugetFolderProject nuGetProject,
            PackageIdentity packageIdentity,
            ResolutionContext resolutionContext,
            INuGetProjectContext nuGetProjectContext,
            IEnumerable <SourceRepository> primarySourceRepositories,
            IEnumerable <SourceRepository> secondarySourceRepositories,
            CancellationToken token)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException(nameof(nuGetProject));
            }
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }
            if (resolutionContext == null)
            {
                throw new ArgumentNullException(nameof(resolutionContext));
            }
            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException(nameof(nuGetProjectContext));
            }
            if (primarySourceRepositories == null)
            {
                throw new ArgumentNullException(nameof(primarySourceRepositories));
            }
            if (!primarySourceRepositories.Any())
            {
                throw new ArgumentException(nameof(primarySourceRepositories));
            }
            if (secondarySourceRepositories == null)
            {
                throw new ArgumentNullException(nameof(secondarySourceRepositories));
            }
            if (packageIdentity.Version == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

            var localSources = new HashSet <SourceRepository>(new SourceRepositoryComparer());

            localSources.Add(packageManager.PackagesFolderSourceRepository);
            localSources.AddRange(packageManager.GlobalPackageFolderRepositories);

            if (resolutionContext.DependencyBehavior == DependencyBehavior.Ignore)
            {
                var logger = new ProjectContextLogger(nuGetProjectContext);

                // First, check only local sources.
                var sourceRepository = await GetSourceRepositoryAsync(packageIdentity, localSources, resolutionContext.SourceCacheContext, logger, token);

                if (sourceRepository == null)
                {
                    // Else, check provided sources. We use only primary sources when we don't care about dependencies.
                    sourceRepository = await GetSourceRepositoryAsync(packageIdentity, primarySourceRepositories, resolutionContext.SourceCacheContext, logger, token);
                }

                // If still not found, we just throw an exception.
                if (sourceRepository == null)
                {
                    throw new InvalidOperationException($"Unable to find version '{packageIdentity.Version}' of package '{packageIdentity.Id}'.");
                }

                return(new[] { NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository, nuGetProject) });
            }

            var primarySources = new HashSet <SourceRepository>(new SourceRepositoryComparer());

            primarySources.AddRange(localSources);
            primarySources.AddRange(primarySourceRepositories);

            var allSources = new HashSet <SourceRepository>(new SourceRepositoryComparer());

            allSources.AddRange(primarySources);
            allSources.AddRange(secondarySourceRepositories);

            // Get the available package dependencies.
            var packageDependencies = await GetAvailablePackageDependencies(
                packageManager,
                nuGetProject,
                packageIdentity,
                resolutionContext,
                nuGetProjectContext,
                primarySources,
                allSources,
                token);

            if (!packageDependencies.Any())
            {
                throw new InvalidOperationException($"Unable to gather dependency information for package '{packageIdentity}'");
            }

            // Prune the results down to only what we would allow to be installed.
            packageDependencies = PruneAvailablePackageDependencies(packageIdentity, resolutionContext, packageDependencies);

            // Get the actual packages to install.
            var packagesToInstall = GetPackagesToInstall(
                packageIdentity,
                resolutionContext,
                nuGetProjectContext,
                packageDependencies,
                allSources,
                token);

            if (packagesToInstall == null || !packagesToInstall.Any())
            {
                throw new InvalidOperationException($"Unable to resolve dependencies for package '{packageIdentity}' with DependencyBehavior '{resolutionContext.DependencyBehavior}'");
            }

            // Create the install actions.
            return(GetProjectActions(
                       packageIdentity,
                       packagesToInstall,
                       packageDependencies,
                       nuGetProject));
        }
        public static async Task <IEnumerable <NuGetProjectAction> > GetInstallProjectActionsAsync(
            this NuGetPackageManager packageManager,
            NugetFolderProject nuGetProject,
            PackageIdentity packageIdentity,
            ResolutionContext resolutionContext,
            INuGetProjectContext nuGetProjectContext,
            IEnumerable <SourceRepository> primarySourceRepositories,
            IEnumerable <SourceRepository> secondarySourceRepositories,
            CancellationToken token)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException(nameof(nuGetProject));
            }
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }
            if (resolutionContext == null)
            {
                throw new ArgumentNullException(nameof(resolutionContext));
            }
            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException(nameof(nuGetProjectContext));
            }
            if (primarySourceRepositories == null)
            {
                throw new ArgumentNullException(nameof(primarySourceRepositories));
            }
            if (!primarySourceRepositories.Any())
            {
                throw new ArgumentException(nameof(primarySourceRepositories));
            }
            if (secondarySourceRepositories == null)
            {
                throw new ArgumentNullException(nameof(secondarySourceRepositories));
            }
            if (packageIdentity.Version == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

            var localSources = new HashSet <SourceRepository>(new SourceRepositoryComparer());

            localSources.Add(packageManager.PackagesFolderSourceRepository);
            localSources.AddRange(packageManager.GlobalPackageFolderRepositories);

            if (resolutionContext.DependencyBehavior == DependencyBehavior.Ignore)
            {
                var logger = new ProjectContextLogger(nuGetProjectContext);

                // First, check only local sources.
                var sourceRepository = await GetSourceRepositoryAsync(packageIdentity, localSources, resolutionContext.SourceCacheContext, logger, token);

                if (sourceRepository == null)
                {
                    // Else, check provided sources. We use only primary sources when we don't care about dependencies.
                    sourceRepository = await GetSourceRepositoryAsync(packageIdentity, primarySourceRepositories, resolutionContext.SourceCacheContext, logger, token);
                }

                // If still not found, we just throw an exception.
                if (sourceRepository == null)
                {
                    throw new InvalidOperationException($"Unable to find version '{packageIdentity.Version}' of package '{packageIdentity.Id}'.");
                }

                return(new[] { NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository, nuGetProject) });
            }

            var primarySources = new HashSet <SourceRepository>(new SourceRepositoryComparer());
            var allSources     = new HashSet <SourceRepository>(new SourceRepositoryComparer());

            Tuple <IReadOnlyCollection <PackageIdentity>, IReadOnlyCollection <SourcePackageDependencyInfo> > packageAndDependencies = null;
            var allDependenciesResolved = false;

            // If target package is already installed, there's a slight chance that all packages are already installed.
            if (await PackageExistsInSourceRepository(
                    packageIdentity,
                    packageManager.PackagesFolderSourceRepository,
                    resolutionContext.SourceCacheContext,
                    new ProjectContextLogger(nuGetProjectContext),
                    token))
            {
                primarySources.Add(packageManager.PackagesFolderSourceRepository);
                allSources.Add(packageManager.PackagesFolderSourceRepository);

                try
                {
                    // Try get all dependencies from local sources only.
                    packageAndDependencies = await GetPackageAndDependenciesToInstall(
                        packageManager,
                        nuGetProject,
                        packageIdentity,
                        resolutionContext,
                        nuGetProjectContext,
                        primarySources,
                        allSources,
                        token);

                    allDependenciesResolved = true;
                }
                catch (NuGetResolverConstraintException)
                {
                    // We didn't manage to find all dependencies in the local packages folder.
                    allDependenciesResolved = false;
                }
            }

            // If we didn't manage to resolve all dependencies from the local sources, check in all sources.
            if (!allDependenciesResolved)
            {
                primarySources.AddRange(localSources);
                primarySources.AddRange(primarySourceRepositories);
                allSources.AddRange(primarySources);
                allSources.AddRange(secondarySourceRepositories);

                packageAndDependencies = await GetPackageAndDependenciesToInstall(
                    packageManager,
                    nuGetProject,
                    packageIdentity,
                    resolutionContext,
                    nuGetProjectContext,
                    primarySources,
                    allSources,
                    token);
            }

            // Create the install actions.
            return(GetProjectActions(
                       packageIdentity,
                       packageAndDependencies.Item1,
                       packageAndDependencies.Item2,
                       nuGetProject));
        }