/// <summary>
        /// Generates the PackageReference Section of the DOT Graph.
        /// </summary>
        /// <param name="anonymizer">The Anonymizer (if used) to anonymize names</param>
        /// <param name="packageReferences">The Dictionary from <see cref="ResolvePackageReferenceDependencies(IEnumerable{string})"/></param>
        /// <returns>An <see cref="IEnumerable{T}"/> that contains the lines to add to the DOT Graph</returns>
        internal static IEnumerable <string> GeneratePackageReferenceSection(Anonymizer <string> anonymizer, Dictionary <string, IEnumerable <string> > packageReferences)
        {
            // First we need to create the nodes for each of the Packages
            IEnumerable <string> distinctPackageReferences = packageReferences.SelectMany(kvp => kvp.Value).Distinct();

            foreach (string distinctPackageReference in distinctPackageReferences)
            {
                string packageReference = distinctPackageReference;

                if (anonymizer != null)
                {
                    packageReference = anonymizer.Anonymoize(packageReference);
                }

                yield return($"\"{packageReference}\" [style = filled, fillcolor = goldenrod, fontname=\"consolas\", fontcolor=black]");
            }

            // Now Create the Connections
            foreach (KeyValuePair <string, IEnumerable <string> > kvp in packageReferences)
            {
                string projectName = Path.GetFileName(kvp.Key);

                if (anonymizer != null)
                {
                    projectName = anonymizer.Anonymoize(projectName);
                }

                IEnumerable <string> packageReferencesForCurrentProject = kvp.Value;

                foreach (string packageReference in packageReferencesForCurrentProject)
                {
                    string packageReferenceName = packageReference;

                    if (anonymizer != null)
                    {
                        packageReferenceName = anonymizer.Anonymoize(packageReferenceName);
                    }

                    yield return($"\"{projectName}\" -> \"{packageReferenceName}\"");
                }
            }
        }
        /// <summary>
        /// Generates the AssemblyReference Section of the DOT Graph.
        /// </summary>
        /// <param name="anonymizer">The Anonymizer (if used) to anonymize names</param>
        /// <param name="assemblyReferences">The Dictionary from <see cref="ResolveAssemblyReferenceDependencies(IEnumerable{string})"/></param>
        /// <returns>An <see cref="IEnumerable{T}"/> that contains the lines to add to the DOT Graph</returns>
        internal static IEnumerable <string> GenerateAssemblyReferenceSection(Anonymizer <string> anonymizer, Dictionary <string, IEnumerable <string> > assemblyReferences)
        {
            // First we need to create nodes for each of the Assemblies
            IEnumerable <string> distinctAssemblyReferences = assemblyReferences.SelectMany(kvp => kvp.Value).Distinct();

            foreach (string distinctAssemblyReference in distinctAssemblyReferences)
            {
                string assemblyName = distinctAssemblyReference;

                if (anonymizer != null)
                {
                    assemblyName = anonymizer.Anonymoize(assemblyName);
                }

                yield return($"\"{assemblyName}\" [class=\"AssemblyReference\"]");
            }

            // Now Create the Connections
            foreach (KeyValuePair <string, IEnumerable <string> > kvp in assemblyReferences)
            {
                string projectName = Path.GetFileName(kvp.Key);

                if (anonymizer != null)
                {
                    projectName = anonymizer.Anonymoize(projectName);
                }

                IEnumerable <string> assemblyReferencesForCurrentProject = kvp.Value;

                foreach (string assemblyReference in assemblyReferencesForCurrentProject)
                {
                    string assemblyReferenceName = assemblyReference;

                    if (anonymizer != null)
                    {
                        assemblyReferenceName = anonymizer.Anonymoize(assemblyReferenceName);
                    }

                    yield return($"\"{projectName}\" -> \"{assemblyReferenceName}\"");
                }
            }
        }
        /// <summary>
        /// Given a Dictionary in which the Key Represents the Project and the Value represents the list Project Dependencies, generate a DOT Graph.
        /// </summary>
        /// <param name="projectReferenceDependencies">The dictionary to generate the graph for.</param>
        /// <param name="targetProject">Determines the project (based on name) to be highlighted</param>
        /// <param name="anonymizeNames">Determines if the names should be anonymized.</param>
        /// <param name="sortProjects">Determines if the output of the DOT Graph should be sorted.</param>
        /// <param name="showAssemblyReferences">Determines if Assembly/PackageReferences should be shown on the graph.</param>
        /// <returns>A string that represents a DOT Graph</returns>
        internal static string CreateDOTGraph(IDictionary <string, IEnumerable <string> > projectReferenceDependencies, string targetProject, bool anonymizeNames, bool sortProjects, bool showAssemblyReferences)
        {
            // If we are going to use a anonymizer initialize it
            Anonymizer <string> anonymizer = null;

            if (anonymizeNames)
            {
                anonymizer = new Anonymizer <string>();
            }

            // If we have a target project set a flag
            (string TargetProject, HashSet <string> NOrderDependencies)directNOrderDependencies = (string.Empty, new HashSet <string>());
            bool highlightNonNOrderDependencies = !string.IsNullOrWhiteSpace(targetProject);

            if (highlightNonNOrderDependencies)
            {
                directNOrderDependencies = GenerateDirectNOrderDependencies(targetProject, projectReferenceDependencies);
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("digraph {");

            // If we need to sort the projects do so at this time
            IEnumerable <KeyValuePair <string, IEnumerable <string> > > projectReferenceDependenciesToPrint = projectReferenceDependencies;

            if (sortProjects)
            {
                projectReferenceDependenciesToPrint = projectReferenceDependencies.OrderBy(kvp => Path.GetFileName(kvp.Key));
            }

            // Perform the ProjectReference Results
            foreach (KeyValuePair <string, IEnumerable <string> > kvp in projectReferenceDependenciesToPrint)
            {
                string projectName = Path.GetFileName(kvp.Key);

                if (anonymizeNames)
                {
                    projectName = anonymizer.Anonymoize(projectName);
                }

                IEnumerable <string> projectReferences = kvp.Value;

                if (sortProjects)
                {
                    projectReferences = projectReferences.OrderBy(filePath => Path.GetFileName(filePath));
                }

                if (highlightNonNOrderDependencies)
                {
                    // If we are being asked to highlight non-norder
                    // dependencies then we need to perform special
                    // formatting on the graph
                    if (directNOrderDependencies.TargetProject.Equals(kvp.Key))
                    {
                        sb.AppendLine($"\"{projectName}\" [style = filled, fillcolor = yellow, fontname=\"consolas\", fontcolor=black]");
                    }
                    else if (directNOrderDependencies.NOrderDependencies.Contains(kvp.Key))
                    {
                        sb.AppendLine($"\"{projectName}\" [style = filled, fillcolor = green, fontname=\"consolas\", fontcolor=black]");
                    }
                    else
                    {
                        sb.AppendLine($"\"{projectName}\" [style = filled, fillcolor = red, fontname=\"consolas\", fontcolor=black]");
                    }
                }
                else
                {
                    sb.AppendLine($"\"{projectName}\"");
                }

                foreach (string projectDependency in projectReferences)
                {
                    string projectDependencyName = Path.GetFileName(projectDependency);

                    if (anonymizeNames)
                    {
                        projectDependencyName = anonymizer.Anonymoize(projectDependencyName);
                    }

                    sb.AppendLine($"\"{projectName}\" -> \"{projectDependencyName}\"");
                }
            }

            // If we need to show assembly references find them
            if (showAssemblyReferences)
            {
                sb.AppendLine("//--------------------------");
                sb.AppendLine("// AssemblyReference Section");
                sb.AppendLine("//--------------------------");
                Dictionary <string, IEnumerable <string> > assemblyReferenceDependencies = ResolveAssemblyReferenceDependencies(projectReferenceDependencies.Keys);
                IEnumerable <string> assemblyReferenceSection = GenerateAssemblyReferenceSection(anonymizer, assemblyReferenceDependencies);

                if (sortProjects)
                {
                    assemblyReferenceSection = assemblyReferenceSection.OrderBy(x => x);
                }

                foreach (string line in assemblyReferenceSection)
                {
                    sb.AppendLine(line);
                }

                sb.AppendLine("//--------------------------");
                sb.AppendLine("// PackageReference Section");
                sb.AppendLine("//--------------------------");
                Dictionary <string, IEnumerable <string> > packageReferenceDependencies = ResolvePackageReferenceDependencies(projectReferenceDependencies.Keys);
                IEnumerable <string> packageReferenceSection = GeneratePackageReferenceSection(anonymizer, packageReferenceDependencies);

                if (sortProjects)
                {
                    packageReferenceSection = packageReferenceSection.OrderBy(x => x);
                }

                foreach (string line in packageReferenceSection)
                {
                    sb.AppendLine(line);
                }
            }

            sb.AppendLine("}");

            return(sb.ToString());
        }
        /// <summary>
        /// Given a Dictionary in which the Key Represents the Project and the Value represents the list Project Dependencies, generate a DOT Graph.
        /// </summary>
        /// <param name="projectReferenceDependencies">The dictionary to generate the graph for.</param>
        /// <param name="anonymizeNames">Determines if the names should be anonymized.</param>
        /// <param name="sortProjects">Determines if the output of the DOT Graph should be sorted.</param>
        /// <param name="showAssemblyReferences">Determines if Assembly/PackageReferences should be shown on the graph.</param>
        /// <returns>A string that represents a DOT Graph</returns>
        internal static string CreateDOTGraph(IDictionary <string, IEnumerable <string> > projectReferenceDependencies, MSBPROptions options)
        {
            // If we are going to use a anonymizer initialize it
            Anonymizer <string> anonymizer = null;

            if (options.AnonymizeNames)
            {
                anonymizer = new Anonymizer <string>();
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("digraph {");

            // If we need to sort the projects do so at this time
            IEnumerable <KeyValuePair <string, IEnumerable <string> > > projectReferenceDependenciesToPrint = projectReferenceDependencies;

            if (options.SortProjects)
            {
                projectReferenceDependenciesToPrint = projectReferenceDependencies.OrderBy(kvp => Path.GetFileName(kvp.Key));
            }

            // Perform the ProjectReference Results
            foreach (KeyValuePair <string, IEnumerable <string> > kvp in projectReferenceDependenciesToPrint)
            {
                string projectName = Path.GetFileName(kvp.Key);

                if (options.AnonymizeNames)
                {
                    projectName = anonymizer.Anonymoize(projectName);
                }

                IEnumerable <string> projectReferences = kvp.Value;

                if (options.SortProjects)
                {
                    projectReferences = projectReferences.OrderBy(filePath => Path.GetFileName(filePath));
                }

                sb.AppendLine($"\"{projectName}\"");

                foreach (string projectDependency in projectReferences)
                {
                    string projectDependencyName = Path.GetFileName(projectDependency);

                    if (options.AnonymizeNames)
                    {
                        projectDependencyName = anonymizer.Anonymoize(projectDependencyName);
                    }

                    sb.AppendLine($"\"{projectName}\" -> \"{projectDependencyName}\"");
                }
            }

            // If we need to show assembly references find them
            if (options.ShowAssemblyReferences)
            {
                sb.AppendLine("//--------------------------");
                sb.AppendLine("// AssemblyReference Section");
                sb.AppendLine("//--------------------------");
                Dictionary <string, IEnumerable <string> > assemblyReferenceDependencies = ResolveAssemblyReferenceDependencies(projectReferenceDependencies.Keys);
                IEnumerable <string> assemblyReferenceSection = GenerateAssemblyReferenceSection(anonymizer, assemblyReferenceDependencies);

                if (options.SortProjects)
                {
                    assemblyReferenceSection = assemblyReferenceSection.OrderBy(x => x);
                }

                foreach (string line in assemblyReferenceSection)
                {
                    sb.AppendLine(line);
                }
            }

            if (options.ShowPackageReferences)
            {
                sb.AppendLine("//--------------------------");
                sb.AppendLine("// PackageReference Section");
                sb.AppendLine("//--------------------------");
                Dictionary <string, IEnumerable <string> > packageReferenceDependencies = ResolvePackageReferenceDependencies(projectReferenceDependencies.Keys);
                IEnumerable <string> packageReferenceSection = GeneratePackageReferenceSection(anonymizer, packageReferenceDependencies);

                if (options.SortProjects)
                {
                    packageReferenceSection = packageReferenceSection.OrderBy(x => x);
                }

                foreach (string line in packageReferenceSection)
                {
                    sb.AppendLine(line);
                }
            }

            sb.AppendLine("}");

            return(sb.ToString());
        }