/// <summary>
        /// Execute the tool mode
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            // Apply any command line arguments to this class
            Arguments.ApplyTo(this);

            // Apply the XML config to this class
            XmlConfig.ApplyTo(this);

            // Parse rocket-specific arguments.
            FileReference ProjectFile;

            TryParseProjectFileArgument(Arguments, out ProjectFile);

            // If there aren't any formats set, read the default project file format from the config file
            if (ProjectFileFormats.Count == 0)
            {
                // Read from the XML config
                if (!String.IsNullOrEmpty(ProjectFileGeneratorSettings.Format))
                {
                    ProjectFileFormats.UnionWith(ProjectFileGeneratorSettings.ParseFormatList(ProjectFileGeneratorSettings.Format));
                }

                // Read from the editor config
                ProjectFileFormat PreferredSourceCodeAccessor;
                if (ProjectFileGenerator.GetPreferredSourceCodeAccessor(ProjectFile, out PreferredSourceCodeAccessor))
                {
                    ProjectFileFormats.Add(PreferredSourceCodeAccessor);
                }

                // If there's still nothing set, get the default project file format for this platform
                if (ProjectFileFormats.Count == 0)
                {
                    ProjectFileFormats.UnionWith(BuildHostPlatform.Current.GetDefaultProjectFileFormats());
                }
            }

            // Register all the platform project generators
            PlatformProjectGeneratorCollection PlatformProjectGenerators = new PlatformProjectGeneratorCollection();

            foreach (Type CheckType in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (CheckType.IsClass && !CheckType.IsAbstract && CheckType.IsSubclassOf(typeof(PlatformProjectGenerator)))
                {
                    PlatformProjectGenerator Generator = (PlatformProjectGenerator)Activator.CreateInstance(CheckType, Arguments);
                    foreach (UnrealTargetPlatform Platform in Generator.GetPlatforms())
                    {
                        if (DisablePlatformProjectGenerators == null || !DisablePlatformProjectGenerators.Any(x => x.Equals(Platform.ToString(), StringComparison.OrdinalIgnoreCase)))
                        {
                            Log.TraceVerbose("Registering project generator {0} for {1}", CheckType, Platform);
                            PlatformProjectGenerators.RegisterPlatformProjectGenerator(Platform, Generator);
                        }
                    }
                }
            }

            // Create each project generator and run it
            List <ProjectFileGenerator> Generators = new List <ProjectFileGenerator>();

            foreach (ProjectFileFormat ProjectFileFormat in ProjectFileFormats.Distinct())
            {
                ProjectFileGenerator Generator;
                switch (ProjectFileFormat)
                {
                case ProjectFileFormat.Make:
                    Generator = new MakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CMake:
                    Generator = new CMakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.QMake:
                    Generator = new QMakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.KDevelop:
                    Generator = new KDevelopGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CodeLite:
                    Generator = new CodeLiteGenerator(ProjectFile, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.Default, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2012:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2012, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2013:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2013, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2015:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2015, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2017:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2017, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2019:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2019, Arguments);
                    break;

                case ProjectFileFormat.XCode:
                    Generator = new XcodeProjectFileGenerator(ProjectFile, Arguments);
                    break;

                case ProjectFileFormat.Eddie:
                    Generator = new EddieProjectFileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.VisualStudioCode:
                    Generator = new VSCodeProjectFileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CLion:
                    Generator = new CLionGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.VisualStudioMac:
                    Generator = new VCMacProjectFileGenerator(ProjectFile, Arguments);
                    break;

                default:
                    throw new BuildException("Unhandled project file type '{0}", ProjectFileFormat);
                }
                Generators.Add(Generator);
            }

            // Check there are no superfluous command line arguments
            // TODO (still pass raw arguments below)
            // Arguments.CheckAllArgumentsUsed();

            // Now generate project files
            ProjectFileGenerator.bGenerateProjectFiles = true;
            foreach (ProjectFileGenerator Generator in Generators)
            {
                if (!Generator.GenerateProjectFiles(PlatformProjectGenerators, Arguments.GetRawArray()))
                {
                    return((int)CompilationResult.OtherCompilationError);
                }
            }
            return((int)CompilationResult.Succeeded);
        }
        /// <summary>
        /// Gets the default compiler which should be used, if it's not set explicitly by the target, command line, or config file.
        /// </summary>
        /// <returns>The default compiler version</returns>
        internal static WindowsCompiler GetDefaultCompiler(FileReference ProjectFile)
        {
            // If there's no specific compiler set, try to pick the matching compiler for the selected IDE
            object ProjectFormatObject;

            if (XmlConfig.TryGetValue(typeof(VCProjectFileGenerator), "Version", out ProjectFormatObject))
            {
                VCProjectFileFormat ProjectFormat = (VCProjectFileFormat)ProjectFormatObject;
                if (ProjectFormat == VCProjectFileFormat.VisualStudio2017)
                {
                    return(WindowsCompiler.VisualStudio2017);
                }
                else if (ProjectFormat == VCProjectFileFormat.VisualStudio2015)
                {
                    return(WindowsCompiler.VisualStudio2015);
                }
            }

            // Check the editor settings too
            ProjectFileFormat PreferredAccessor;

            if (ProjectFileGenerator.GetPreferredSourceCodeAccessor(ProjectFile, out PreferredAccessor))
            {
                if (PreferredAccessor == ProjectFileFormat.VisualStudio2017)
                {
                    return(WindowsCompiler.VisualStudio2017);
                }
                else if (PreferredAccessor == ProjectFileFormat.VisualStudio2015)
                {
                    return(WindowsCompiler.VisualStudio2015);
                }
            }

            // Second, default based on what's installed, test for 2015 first
            DirectoryReference VCInstallDir;

            if (TryGetVCInstallDir(WindowsCompiler.VisualStudio2015, out VCInstallDir))
            {
                return(WindowsCompiler.VisualStudio2015);
            }
            if (TryGetVCInstallDir(WindowsCompiler.VisualStudio2017, out VCInstallDir))
            {
                return(WindowsCompiler.VisualStudio2017);
            }

            // If we do have a Visual Studio installation, but we're missing just the C++ parts, warn about that.
            DirectoryReference VSInstallDir;

            if (TryGetVSInstallDir(WindowsCompiler.VisualStudio2015, out VSInstallDir))
            {
                Log.TraceWarning("Visual Studio 2015 is installed, but is missing the C++ toolchain. Please verify that \"Common Tools for Visual C++ 2015\" are selected from the Visual Studio 2015 installation options.");
            }
            else if (TryGetVSInstallDir(WindowsCompiler.VisualStudio2017, out VSInstallDir))
            {
                Log.TraceWarning("Visual Studio 2017 is installed, but is missing the C++ toolchain. Please verify that the \"VC++ 2017 toolset\" component is selected in the Visual Studio 2017 installation options.");
            }
            else
            {
                Log.TraceWarning("No Visual C++ installation was found. Please download and install Visual Studio 2015 with C++ components.");
            }

            // Finally, default to VS2015 anyway
            return(WindowsCompiler.VisualStudio2015);
        }