/// <summary>
        /// Get warning message for missing minimum dependencies.
        /// </summary>
        public static RestoreLogMessage GetMissingLowerBoundMessage(ResolvedDependencyKey dependency, params string[] targetGraphs)
        {
            NuGetLogCode code;
            var          message         = string.Empty;
            var          parent          = DiagnosticUtility.FormatIdentity(dependency.Parent);
            var          dependencyRange = DiagnosticUtility.FormatDependency(dependency.Child.Name, dependency.Range);
            var          missingChild    = DiagnosticUtility.FormatExpectedIdentity(dependency.Child.Name, dependency.Range);
            var          resolvedChild   = DiagnosticUtility.FormatIdentity(dependency.Child);

            if (HasMissingLowerBound(dependency.Range))
            {
                // Range does not have a lower bound, the best match can only be approximate.
                message = string.Format(CultureInfo.CurrentCulture, Strings.Warning_MinVersionNonInclusive,
                                        parent,
                                        dependencyRange,
                                        resolvedChild);

                code = NuGetLogCode.NU1602;
            }
            else
            {
                // The minimum version does not exist.
                message = string.Format(CultureInfo.CurrentCulture, Strings.Warning_MinVersionDoesNotExist,
                                        parent,
                                        dependencyRange,
                                        missingChild,
                                        resolvedChild);

                code = NuGetLogCode.NU1603;
            }

            return(RestoreLogMessage.CreateWarning(code, message, dependency.Child.Name, targetGraphs));
        }
        /// <summary>
        /// True if the dependency version range has a min version that matches the resolved version.
        /// </summary>
        public static bool DependencyRangeHasMissingExactMatch(ResolvedDependencyKey dependency)
        {
            // Ignore floating
            if (dependency.Range.IsFloating)
            {
                return(false);
            }

            // Ignore projects
            if (dependency.Child.Type != LibraryType.Package)
            {
                return(false);
            }

            return(!dependency.Range.IsMinInclusive || dependency.Range.MinVersion != dependency.Child.Version);
        }
        public static RestoreTargetGraph Create(
            RuntimeGraph runtimeGraph,
            IEnumerable <GraphNode <RemoteResolveResult> > graphs,
            RemoteWalkContext context,
            ILogger log,
            NuGetFramework framework,
            string runtimeIdentifier)
        {
            var install    = new HashSet <RemoteMatch>();
            var flattened  = new HashSet <GraphItem <RemoteResolveResult> >();
            var unresolved = new HashSet <LibraryRange>();

            var conflicts            = new Dictionary <string, HashSet <ResolverRequest> >();
            var analyzeResult        = new AnalyzeResult <RemoteResolveResult>();
            var resolvedDependencies = new HashSet <ResolvedDependencyKey>();

            foreach (var graph in graphs)
            {
                var result = graph.Analyze();

                analyzeResult.Combine(result);
            }

            graphs.ForEach(node =>
            {
                if (node == null || node.Key == null)
                {
                    return;
                }

                if (node.Disposition != Disposition.Rejected)
                {
                    if (node.Disposition == Disposition.Acceptable)
                    {
                        // This wasn't resolved. It's a conflict.
                        HashSet <ResolverRequest> ranges;
                        if (!conflicts.TryGetValue(node.Key.Name, out ranges))
                        {
                            ranges = new HashSet <ResolverRequest>();
                            conflicts[node.Key.Name] = ranges;
                        }

                        // OuterNode may be null if the project itself conflicts with a package name
                        var requestor = node.OuterNode == null ? node.Item.Key : node.OuterNode.Item.Key;

                        ranges.Add(new ResolverRequest(requestor, node.Key));
                    }

                    if (node?.Item?.Key?.Type == LibraryType.Unresolved)
                    {
                        if (node.Key.VersionRange != null)
                        {
                            unresolved.Add(node.Key);
                        }

                        return;
                    }

                    // Don't add rejected nodes since we only want to write reduced nodes
                    // to the lock file
                    flattened.Add(node.Item);
                }

                if (node?.OuterNode != null && node.Item.Key.Type != LibraryType.Unresolved)
                {
                    var dependencyKey = new ResolvedDependencyKey(
                        parent: node.OuterNode.Item.Key,
                        range: node.Key.VersionRange,
                        child: node.Item.Key);

                    resolvedDependencies.Add(dependencyKey);
                }

                // If the package came from a remote library provider, it needs to be installed locally
                // Rejected nodes are included here to avoid downloading them from remote sources
                // each time the lock file is generated.
                var isRemote = context.RemoteLibraryProviders.Contains(node.Item.Data.Match.Provider);
                if (isRemote)
                {
                    install.Add(node.Item.Data.Match);
                }
            });

            return(new RestoreTargetGraph(
                       conflicts.Select(p => new ResolverConflict(p.Key, p.Value)),
                       framework,
                       runtimeIdentifier,
                       runtimeGraph,
                       graphs,
                       install,
                       flattened,
                       unresolved,
                       analyzeResult,
                       resolvedDependencies));
        }