/// <summary>
        ///   Gets all Projects INCLUDING their N-Order Dependencies based off
        /// a project listing. Also Includes RuntimeReference Tags.
        /// </summary>
        /// <param name="projectList">A list of MSBuild Projects.</param>
        /// <returns>All Projects in the List INCLUDING their N-Order Dependencies AND Runtime References.</returns>
        public static IEnumerable <string> ProjectsIncludingNOrderDependencies(IEnumerable <string> projectList)
        {
            // Have our Resolved References
            SortedSet <string> resolvedReferences = new SortedSet <string>(StringComparer.InvariantCultureIgnoreCase);

            // Start Spinning for References
            Stack <string> projectsToResolve = new Stack <string>(projectList.Distinct());

            while (projectsToResolve.Count > 0)
            {
                // Start resolving the current project
                string currentProjectToResolve = projectsToResolve.Pop();

                // Don't attempt to resolve projects which have already been resolved
                if (!resolvedReferences.Contains(currentProjectToResolve))
                {
                    // Add the current project to the list of resolved projects
                    resolvedReferences.Add(currentProjectToResolve);

                    // Get a list of all MSBuild ProjectReferences
                    IEnumerable <string> projectReferences = GetMSBuildProjectReferencesFullPath(currentProjectToResolve);

                    // But only add those which have not already been resolved
                    foreach (string projectReference in projectReferences)
                    {
                        if (!resolvedReferences.Contains(projectReference))
                        {
                            projectsToResolve.Push(projectReference);
                        }
                    }

                    // Also get a list of all RuntimeReferences
                    IEnumerable <string> runtimeReferences = MSBuildUtilities.GetRuntimeReferences(currentProjectToResolve);

                    // But only add those which have not already been resolved
                    foreach (string runtimeReference in runtimeReferences)
                    {
                        if (!resolvedReferences.Contains(runtimeReference))
                        {
                            projectsToResolve.Push(runtimeReference);
                        }
                    }
                }
            }

            return(resolvedReferences);
        }
        public static IEnumerable <string> IdentifyStaleDependencies(string targetSolution)
        {
            // First Grab a list of all projects in the Dependencies Folder
            ISet <string> dependenciesProjects = new HashSet <string>(SolutionUtilities.GetDependenciesProjects(targetSolution), StringComparer.InvariantCultureIgnoreCase);

            // Now Grab a list of all projects in the solution
            ISet <string> projectsInSolution = new HashSet <string>(SolutionUtilities.GetProjectsFromSolutionFullPath(targetSolution), StringComparer.InvariantCultureIgnoreCase);

            // Remove any Projects that were in the Dependencies Folder
            IEnumerable <string> projectsInSolutionThatAreNotDependencies = projectsInSolution.Except(dependenciesProjects);

            // Now rescan for dependencies
            IEnumerable <string> currentNOrderDependencies = MSBuildUtilities.ProjectsIncludingNOrderDependencies(projectsInSolutionThatAreNotDependencies);

            IEnumerable <string> result = projectsInSolution.Except(currentNOrderDependencies);

            return(result);
        }
        /// <summary>
        /// Removes Projects from the target solution file.
        /// </summary>
        /// <param name="targetSolution">The solution file to modify.</param>
        /// <param name="projectsToRemove">The fully qualified path to the projects to remove.</param>
        /// <remarks>
        /// This works by extracting the GUID From the target project files;
        /// if the projects have already been deleted then you must use
        /// <see cref="RemoveProjectsByGuidFromSolution(string, string[])"/>
        /// and extract the guids some other way.
        /// </remarks>
        internal static void RemoveProjectsFromSolution(string targetSolution, IEnumerable <string> projectsToRemove)
        {
            if (projectsToRemove.Any())
            {
                // For Each Project Grab the ProjectGuid
                string[] guidsOfProjectsToRemove = projectsToRemove.Select(projectToRemove => MSBuildUtilities.GetMSBuildProjectGuid(projectToRemove)).ToArray();

                RemoveProjectsByGuidFromSolution(targetSolution, guidsOfProjectsToRemove);
            }
        }