/// <summary>
        /// Generates a Visual Studio solution file and Visual C++ project files for all known engine and game targets.
        /// Does not actually build anything.
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <param name="bSuccess">True if everything went OK</param>
        public virtual void GenerateProjectFiles(String[] Arguments, out bool bSuccess)
        {
            bSuccess = true;

            // Parse project generator options
            bool IncludeAllPlatforms = true;
            ConfigureProjectFileGeneration(Arguments, ref IncludeAllPlatforms);

            if (bGeneratingGameProjectFiles)
            {
                Log.TraceInformation("Discovering modules, targets and source code for game...");

                MasterProjectRelativePath = STBuildTool.GetUProjectPath();

                // Set the project file name
                MasterProjectName = Path.GetFileNameWithoutExtension(STBuildTool.GetUProjectFile());

                if (!Directory.Exists(MasterProjectRelativePath + "/Source"))
                {
                    if (BuildHostPlatform.Current.Platform == STTargetPlatform.Mac)
                    {
                        MasterProjectRelativePath = Path.GetFullPath(Path.Combine(Utils.GetExecutingAssemblyDirectory(), "..", "..", "..", "Engine"));
                        GameProjectName = "UE4Game";
                    }
                    if (!Directory.Exists(MasterProjectRelativePath + "/Source"))
                    {
                        throw new BuildException("Directory '{0}' is missing 'Source' folder.", MasterProjectRelativePath);
                    }
                }
                IntermediateProjectFilesPath = Path.Combine(MasterProjectRelativePath, "Intermediate", "ProjectFiles");
            }
            else if (bGeneratingRocketProjectFiles)
            {
                Log.TraceInformation("Discovering modules, targets and source code for project...");

                // NOTE: Realistically, the distro that the Rocket user is generating projects FROM won't have NoRedist files in it.  But when
                //       testing from a developer branch, this is useful to get authentic projects. This only really matters when
                //       bIncludeEngineModulesInRocketProjects=true (defaults to false.)
                bExcludeNoRedistFiles = true;

                MasterProjectRelativePath = STBuildTool.GetUProjectPath();
                IntermediateProjectFilesPath = Path.Combine(MasterProjectRelativePath, "Intermediate", "ProjectFiles");

                // Set the project file name
                MasterProjectName = Path.GetFileNameWithoutExtension(STBuildTool.GetUProjectFile());

                if (!Directory.Exists(MasterProjectRelativePath + "/Source"))
                {
                    throw new BuildException("Directory '{0}' is missing 'Source' folder.", MasterProjectRelativePath);
                }
            }

            // Modify the name if specific platforms were given
            if (ProjectPlatforms.Count > 0)
            {
                // Sort the platforms names so we get consistent names
                List<string> SortedPlatformNames = new List<string>();
                foreach (STTargetPlatform SpecificPlatform in ProjectPlatforms)
                {
                    SortedPlatformNames.Add(SpecificPlatform.ToString());
                }
                SortedPlatformNames.Sort();

                MasterProjectName += "_";
                foreach (string SortedPlatform in SortedPlatformNames)
                {
                    MasterProjectName += SortedPlatform;
                    IntermediateProjectFilesPath += SortedPlatform;
                }
            }

            bool bCleanProjectFiles = STBuildTool.CommandLineContains("-CleanProjects");
            if (bCleanProjectFiles)
            {
                CleanProjectFiles(MasterProjectRelativePath, MasterProjectName, IntermediateProjectFilesPath);
            }

            // Figure out which platforms we should generate project files for.
            string SupportedPlatformNames;
            SetupSupportedPlatformsAndConfigurations(IncludeAllPlatforms: IncludeAllPlatforms, SupportedPlatformNames: out SupportedPlatformNames);

            Log.TraceVerbose("Detected supported platforms: " + SupportedPlatformNames);

            RootFolder = AllocateMasterProjectFolder(this, "<Root>");

            // Build the list of games to generate projects for
            var AllGameProjects = UProjectInfo.FilterGameProjects(true, bGeneratingGameProjectFiles ? GameProjectName : null);

            var AssemblyName = "ProjectFileGenerator";
            if (bGeneratingGameProjectFiles)
            {
                AssemblyName = GameProjectName + "ProjectFileGenerator";
            }
            else if (bGeneratingRocketProjectFiles)
            {
                AssemblyName = "RocketProjectFileGenerator";
            }

            List<string> AssemblyGameFolders = new List<string>();
            foreach (UProjectInfo Project in AllGameProjects)
            {
                AssemblyGameFolders.Add(Project.Folder);
            }
            RulesCompiler.SetAssemblyNameAndGameFolders(AssemblyName, AssemblyGameFolders);

            ProjectFile EngineProject = null;
            Dictionary<string, ProjectFile> GameProjects = null;
            Dictionary<string, ProjectFile> ProgramProjects = null;
            HashSet<ProjectFile> TemplateGameProjects = null;
            {
                // Setup buildable projects for all targets
                AddProjectsForAllTargets(AllGameProjects, out EngineProject, out GameProjects, out ProgramProjects, out TemplateGameProjects);

                // Add all game projects and game config files
                AddAllGameProjects(GameProjects, SupportedPlatformNames, RootFolder);

                // Set the game to be the default project
                if (bGeneratingGameProjectFiles && GameProjects.Count > 0)
                {
                    DefaultProject = GameProjects.Values.First();
                }

                // Place projects into root level solution folders
                if (IncludeEngineSource)
                {
                    // If we're still missing an engine project because we don't have any targets for it, make one up.
                    if (EngineProject == null)
                    {
                        string ProjectFilePath = Path.Combine(IntermediateProjectFilesPath, "UE4" + ProjectFileExtension);

                        bool bAlreadyExisted;
                        EngineProject = FindOrAddProject(Utils.MakePathRelativeTo(ProjectFilePath, MasterProjectRelativePath), true, out bAlreadyExisted);

                        EngineProject.IsForeignProject = false;
                        EngineProject.IsGeneratedProject = true;
                        EngineProject.IsStubProject = true;
                    }

                    if (EngineProject != null)
                    {
                        RootFolder.AddSubFolder("Engine").ChildProjects.Add(EngineProject);

                        // Engine config files
                        if (IncludeConfigFiles)
                        {
                            AddEngineConfigFiles(EngineProject);
                            if (IncludeEnginePrograms)
                            {
                                AddUnrealHeaderToolConfigFiles(EngineProject);
                                AddUBTConfigFilesToEngineProject(EngineProject);
                            }
                        }

                        // Engine localization files
                        if (IncludeLocalizationFiles)
                        {
                            AddEngineLocalizationFiles(EngineProject);
                        }

                        // Engine template files
                        if (IncludeTemplateFiles)
                        {
                            AddEngineTemplateFiles(EngineProject);
                        }

                        if (IncludeShaderSource)
                        {
                            Log.TraceVerbose("Adding shader source code...");

                            // Find shader source files and generate stub project
                            AddEngineShaderSource(EngineProject);
                        }

                        if (IncludeBuildSystemFiles)
                        {
                            Log.TraceVerbose("Adding build system files...");

                            AddEngineBuildFiles(EngineProject);
                        }

                        if (IncludeDocumentation)
                        {
                            AddEngineDocumentation(EngineProject);
                        }
                    }

                    foreach (var CurGameProject in GameProjects.Values)
                    {
                        // Templates go under a different solution folder than games
                        if (TemplateGameProjects.Contains(CurGameProject))
                        {
                            RootFolder.AddSubFolder("Templates").ChildProjects.Add(CurGameProject);
                        }
                        else
                        {
                            RootFolder.AddSubFolder("Games").ChildProjects.Add(CurGameProject);
                        }
                    }

                    foreach (var CurProgramProject in ProgramProjects.Values)
                    {
                        RootFolder.AddSubFolder("Programs").ChildProjects.Add(CurProgramProject);
                    }

                    // Add all of the config files for generated program targets
                    AddEngineProgramConfigFiles(ProgramProjects);
                }
            }

            // Find all of the module files.  This will filter out any modules or targets that don't belong to platforms
            // we're generating project files for.
            var AllModuleFiles = DiscoverModules();

            // Setup "stub" projects for all modules
            AddProjectsForAllModules(AllGameProjects, ProgramProjects, AllModuleFiles, bGatherThirdPartySource);

            {
                if (IncludeEnginePrograms)
                {
                    MasterProjectFolder ProgramsFolder = RootFolder.AddSubFolder("Programs");

                    // Add STBuildTool to the master project
                    AddSTBuildToolProject(ProgramsFolder);

                    // Add AutomationTool to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("AutomationTool", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add UnrealAutomationTool (launcher) to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("AutomationToolLauncher", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add automation.csproj files to the master project
                    AddAutomationModules(ProgramsFolder);

                    // Add Distill to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("Distill"));

                    // Add DotNETUtilities to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("DotNETCommon/DotNETUtilities", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add the Git dependencies project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("GitDependencies", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add all of the IOS C# projects
                    AddIOSProjects(ProgramsFolder);

                    // Add all of the Android C# projects
                    AddAndroidProjects(ProgramsFolder);

                    // Add all of the PS4 C# projects
                    AddPS4Projects(ProgramsFolder);
                }

                // Eliminate all redundant master project folders.  E.g., folders which contain only one project and that project
                // has the same name as the folder itself.  To the user, projects "feel like" folders already in the IDE, so we
                // want to collapse them down where possible.
                EliminateRedundantMasterProjectSubFolders(RootFolder, "");

                bool bWriteFileManifest = STBuildTool.CommandLineContains("-filemanifest");

                if (bWriteFileManifest == false)
                {
                    // Figure out which targets we need about IntelliSense for.  We only need to worry about targets for projects
                    // that we're actually generating in this session.
                    var IntelliSenseTargetFiles = new List<Tuple<ProjectFile, string>>();
                    {
                        // Engine targets
                        if (EngineProject != null && !bGeneratingRocketProjectFiles)
                        {
                            foreach (var ProjectTarget in EngineProject.ProjectTargets)
                            {
                                if (!String.IsNullOrEmpty(ProjectTarget.TargetFilePath))
                                {
                                    // Only bother with the editor target.  We want to make sure that definitions are setup to be as inclusive as possible
                                    // for good quality IntelliSense.  For example, we want WITH_EDITORONLY_DATA=1, so using the editor targets works well.
                                    if (ProjectTarget.TargetRules.Type == TargetRules.TargetType.Editor)
                                    {
                                        IntelliSenseTargetFiles.Add(Tuple.Create(EngineProject, ProjectTarget.TargetFilePath));
                                    }
                                }
                            }
                        }

                        // Program targets
                        foreach (var ProgramProject in ProgramProjects.Values)
                        {
                            foreach (var ProjectTarget in ProgramProject.ProjectTargets)
                            {
                                if (!String.IsNullOrEmpty(ProjectTarget.TargetFilePath))
                                {
                                    IntelliSenseTargetFiles.Add(Tuple.Create(ProgramProject, ProjectTarget.TargetFilePath));
                                }
                            }
                        }

                        // Game/template targets
                        foreach (var GameProject in GameProjects.Values)
                        {
                            foreach (var ProjectTarget in GameProject.ProjectTargets)
                            {
                                if (!String.IsNullOrEmpty(ProjectTarget.TargetFilePath))
                                {
                                    // Only bother with the editor target.  We want to make sure that definitions are setup to be as inclusive as possible
                                    // for good quality IntelliSense.  For example, we want WITH_EDITORONLY_DATA=1, so using the editor targets works well.
                                    if (ProjectTarget.TargetRules.Type == TargetRules.TargetType.Editor)
                                    {
                                        IntelliSenseTargetFiles.Add(Tuple.Create(GameProject, ProjectTarget.TargetFilePath));
                                    }
                                }
                            }
                        }
                    }

                    // Generate IntelliSense data if we need to.  This involves having UBT simulate the action compilation of
                    // the targets so that we can extra the compiler defines, include paths, etc.
                    bSuccess = GenerateIntelliSenseData(Arguments, IntelliSenseTargetFiles);
                }

                // If everything went OK, we'll now save out all of the new project files
                if (bSuccess)
                {
                    if (bWriteFileManifest == false)
                    {
                        // Save new project files
                        WriteProjectFiles();

                        Log.TraceVerbose("Project generation complete ({0} generated, {1} imported)", GeneratedProjectFiles.Count, OtherProjectFiles.Count);
                    }
                    else
                    {
                        WriteProjectFileManifest();
                    }
                }
            }
        }
        /// <summary>
        /// Adds all .automation.csproj files to the solution.
        /// </summary>
        void AddAutomationModules(MasterProjectFolder ProgramsFolder)
        {
            var Folder = ProgramsFolder.AddSubFolder("Automation");
            var AllGameFolders = STBuildTarget.DiscoverAllGameFolders();
            var BuildFolders = new List<string>(AllGameFolders.Count);
            foreach (var GameFolder in AllGameFolders)
            {
                var GameBuildFolder = Path.Combine(GameFolder, "Build");
                if (Directory.Exists(GameBuildFolder))
                {
                    BuildFolders.Add(GameBuildFolder);
                }
            }

            // Find all the automation modules .csproj files to add
            var ModuleFiles = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.AutomationModule, BuildFolders);
            foreach (var ProjectFile in ModuleFiles)
            {
                FileInfo Info = new FileInfo(Path.Combine(ProjectFile));
                if (Info.Exists)
                {
                    var RelativeFileName = Utils.MakePathRelativeTo(ProjectFile, MasterProjectRelativePath);
                    var Project = new VCSharpProjectFile(RelativeFileName);
                    Project.ShouldBuildForAllSolutionTargets = true;
                    AddExistingProjectFile(Project, bForceDevelopmentConfiguration: true);

                    Folder.ChildProjects.Add(Project);
                }
            }
        }