/// <summary>
        /// Get an InteractivePackage with populated assembly references from a restored NuGet package.
        /// </summary>
        /// <param name="inputPackages">Input to RestorePackagesAsync, used to ensure the returned package
        /// has the same SupportedVersionRange as the requested package, and to determine if this is a
        /// user-specified package or a dependency.</param>
        static InteractivePackage GetInteractivePackageFromReader(
            PackageReaderBase packageReader,
            InteractiveNuGetProject project,
            IEnumerable <InteractivePackage> inputPackages)
        {
            ImmutableList <FilePath> assemblyReferences = null;
            var fx = project.TargetFramework;
            var packageIdentity = packageReader.GetIdentity();

            if (packageReader
                .GetSupportedFrameworks()
                .Any(f => DefaultCompatibilityProvider.Instance.IsCompatible(fx, f)))
            {
                assemblyReferences =
                    project.GetPackageAssemblyReferences(packageReader, packageIdentity);
            }

            var originalInputPackage = inputPackages.FirstOrDefault(
                p => PackageIdComparer.Equals(p.Identity, packageIdentity));

            // Persist original VersionRange to what gets in the installed package list so that
            // the same original version range string gets written to the manifest on save
            return(new InteractivePackage(
                       packageIdentity,
                       isExplicit: originalInputPackage?.IsExplicit == true,
                       assemblyReferences: assemblyReferences,
                       supportedVersionRange: originalInputPackage?.SupportedVersionRange));
        }
        /// <summary>
        /// Get an InteractivePackage for a restored NuGet package, populated with assembly references from the
        /// user's global package cache.
        /// </summary>
        /// <returns>An InteractivePackage with populated assembly references, or null if the LockFileLibrary
        /// is not of type "package".</returns>
        /// <param name="inputPackages">Input to RestorePackagesAsync, used to ensure the returned package
        /// has the same SupportedVersionRange as the requested package and to determine if this is a
        /// user-specified package or a dependency.</param>
        static InteractivePackage GetInteractivePackageFromLibrary(
            LockFileLibrary library,
            InteractiveNuGetProject project,
            IEnumerable <InteractivePackage> inputPackages)
        {
            if (library.Type != "package") // TODO: where does this string come from?
            {
                return(null);
            }

            var packageIdentity = new PackageIdentity(library.Name, library.Version);

            // All package files are listed within result.LockFile.Libraries[i].Files, but there are no
            // utilities to pick out framework-specific files. Using package readers probably slows
            // restore down but for now it's less code and more consistency.
            using (var packageReader = new PackageFolderReader(project.GetInstalledPath(packageIdentity)))
                return(GetInteractivePackageFromReader(packageReader, project, inputPackages));
        }
        /// <param name="packageConfigDirectory">A directory where the package manager can store temporary
        /// files, and where nuget.config settings files could be placed specific to Workbooks.</param>
        public InteractivePackageManager(
            FrameworkName targetFramework,
            FilePath packageConfigDirectory)
        {
            if (targetFramework == null)
            {
                throw new ArgumentNullException(nameof(targetFramework));
            }
            if (packageConfigDirectory.IsNull)
            {
                throw new ArgumentNullException(nameof(packageConfigDirectory));
            }

            TargetFramework = NuGetFramework.ParseFrameworkName(
                targetFramework.FullName,
                DefaultFrameworkNameProvider.Instance);
            this.packageConfigDirectory = packageConfigDirectory;

            Logger = new InteractivePackageLogger();

            var primarySourceUrl = NuGetConstants.V3FeedUrl;

            settings = Settings.LoadDefaultSettings(packageConfigDirectory);
            var packageSourceProvider    = new PackageSourceProvider(settings);
            var configuredPackageSources = packageSourceProvider.LoadPackageSources();
            var v3Providers = Repository.Provider.GetCoreV3();

            void LogPackageSource(PackageSource source, bool isPrimary = false, bool isIgnored = false)
            => Log.Info(
                TAG,
                $"    [{source.Name}] {source.Source}" +
                (source.IsEnabled ? "" : " (disabled)") +
                (isIgnored ? " (ignored)" : "") +
                (isPrimary ? " (primary)" : ""));

            Log.Info(TAG, "Enumerating NuGet source repositories");

            SourceRepository primarySource = null;
            var sourcesBuilder             = ImmutableArray.CreateBuilder <SourceRepository> ();

            foreach (var packageSource in configuredPackageSources)
            {
                if (!packageSource.IsEnabled)
                {
                    LogPackageSource(packageSource);
                    continue;
                }

                var sourceRepo = new SourceRepository(packageSource, v3Providers);
                var sourceHost = packageSource.TrySourceAsUri?.Host;

                // Ignore nuget.org sources that are not the expected v3 source
                if (string.Equals(sourceHost, "nuget.org", StringComparison.OrdinalIgnoreCase) ||
                    sourceHost.EndsWith(".nuget.org", StringComparison.OrdinalIgnoreCase))
                {
                    if (packageSource.Source == primarySourceUrl)
                    {
                        primarySource = sourceRepo;
                    }
                    else
                    {
                        LogPackageSource(packageSource, isIgnored: true);
                    }
                }
                else
                {
                    sourcesBuilder.Add(sourceRepo);
                    LogPackageSource(packageSource);
                }
            }

            if (primarySource == null)
            {
                primarySource = new SourceRepository(
                    new PackageSource(primarySourceUrl, "nuget.org"),
                    v3Providers);
            }
            LogPackageSource(primarySource.PackageSource, isPrimary: true);
            sourcesBuilder.Insert(0, primarySource);

            SourceRepositories = sourcesBuilder.ToImmutable();

            // NOTE: NuGetPackageManager requires a directory, even though ultimately it is not used
            //       by the methods we call.
            packageManager = new NuGetPackageManager(
                new SourceRepositoryProvider(packageSourceProvider, v3Providers),
                settings,
                packageConfigDirectory);
            projectContext = new InteractivePackageProjectContext(Logger);
            project        = new InteractiveNuGetProject(TargetFramework, settings);
        }