// This will search for .nupkg files, identify the packages which are templates
        // and analyze them. If the path points to a .nupkg file, that will be analyzed
        // and results returned.
        // > templates analyze --packages --path c:\data\mycode\sample\templates

        // This will search for templates under the path specified
        // and analyze them.
        // > templates analyze --folders --path c:\data\mycode\sample\templates

        public override Command CreateCommand() =>
        new Command(name: "analyze", description: "template analyzer tool")
        {
            CommandHandler.Create <string[], string[], bool, bool>(
                (packages, folders, verbose, usePackageCache) => {
                _reporter.EnableVerbose = verbose;
                _reporter.WriteLine("analyzing...");

                _reporter.WriteVerboseLine(packages != null ?
                                           $"packages: {string.Join(',',packages)}" :
                                           "packages is null");

                _reporter.WriteVerboseLine(folders != null ?
                                           $"folders: {string.Join(',',folders)}" :
                                           "folders is null");

                var foldersList = new List <string>();
                if (folders != null && folders.Length > 0)
                {
                    foldersList.AddRange(folders);
                }

                if (packages != null && packages.Length > 0)
                {
                    foreach (var p in packages)
                    {
                        // check that the path exists and then extract to a folder
                        if (File.Exists(p))
                        {
                            _reporter.WriteVerbose($"extracting package '{p}'");
                            var packageFolder = _remoteFile.ExtractZipLocally(p, !usePackageCache);
                            foldersList.Add(packageFolder);
                        }
                        else
                        {
                            _reporter.WriteLine($"ERROR: package not found at '{p}'");
                        }
                    }
                }

                var analyzeResult = new AnalyzeResult();
                if (foldersList != null && foldersList.Count > 0)
                {
                    foreach (var f in foldersList)
                    {
                        // finding folders under f that has a .template.config folder
                        var foundDirs = Directory.GetDirectories(f, ".template.config", new EnumerationOptions {
                            RecurseSubdirectories = true, ReturnSpecialDirectories = true
                        });
                        foundDirs = Directory.GetDirectories(f, ".template.config", SearchOption.AllDirectories);

                        if (foundDirs == null || foundDirs.Length <= 0)
                        {
                            _reporter.WriteLine($"ERROR: No templates found under path '{f}'");
                        }
                        foreach (var fd in foundDirs)
                        {
                            // TODO: Is this correct?
                            analyzeResult = AnalyzeResult.Combine(
                                analyzeResult,
                                _templateAnalyzer.Analyze(Directory.GetParent(fd).FullName));

                            // analyzeResult = _templateAnalyzer.Analyze(Directory.GetParent(fd).FullName);
                        }
                    }
                }

                //return analyzeResult;
                return(analyzeResult.HasErrors() ? -1 : 0);
                // return foundIssues ? -1 : 0;
            }),
            OptionPackages(),
            OptionFolders(),
            OptionVerbose(),
            OptionUsePackageCache()
        };
        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));
        }