public static void LoadBundleConfig <TPlatformBundleSettings>(DirectoryReference ProjectDir, UnrealTargetPlatform Platform,
                                                                      out IReadOnlyDictionary <string, TPlatformBundleSettings> Bundles,
                                                                      Action <TPlatformBundleSettings, ConfigHierarchy, string> GetPlatformSettings)
            where TPlatformBundleSettings : BundleSettings, new()
        {
            var Results = new List <TPlatformBundleSettings>();

            ConfigHierarchy BundleConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.InstallBundle, ProjectDir, Platform);

            const string BundleDefinitionPrefix = "InstallBundleDefinition ";

            foreach (string SectionName in BundleConfig.SectionNames)
            {
                if (!SectionName.StartsWith(BundleDefinitionPrefix))
                {
                    continue;
                }

                TPlatformBundleSettings Bundle = new TPlatformBundleSettings();
                Bundle.Name = SectionName.Substring(BundleDefinitionPrefix.Length);
                {
                    int Order;
                    if (BundleConfig.GetInt32(SectionName, "Order", out Order))
                    {
                        Bundle.Order = Order;
                    }
                    else
                    {
                        Bundle.Order = int.MaxValue;
                    }
                }
                {
                    List <string> Tags;
                    if (BundleConfig.GetArray(SectionName, "Tags", out Tags))
                    {
                        Bundle.Tags = Tags;
                    }
                    else
                    {
                        Bundle.Tags = new List <string>();
                    }
                }
                {
                    List <string> Dependencies;
                    if (BundleConfig.GetArray(SectionName, "Dependencies", out Dependencies))
                    {
                        Bundle.Dependencies = Dependencies;
                    }
                    else
                    {
                        Bundle.Dependencies = new List <string>();
                    }
                }
                {
                    List <string> FileRegex;
                    if (BundleConfig.GetArray(SectionName, "FileRegex", out FileRegex))
                    {
                        Bundle.FileRegex = FileRegex;
                    }
                    else
                    {
                        Bundle.FileRegex = new List <string>();
                    }
                }
                {
                    bool bContainsShaderLibrary;
                    if (BundleConfig.GetBool(SectionName, "ContainsShaderLibrary", out bContainsShaderLibrary))
                    {
                        Bundle.bContainsShaderLibrary = bContainsShaderLibrary;
                    }
                    else
                    {
                        Bundle.bContainsShaderLibrary = false;
                    }
                }

                GetPlatformSettings(Bundle, BundleConfig, BundleDefinitionPrefix + Bundle.Name);

                Results.Add(Bundle);
            }

            // Use OrderBy and not Sort because OrderBy is stable
            Bundles = Results.OrderBy(b => b.Order).ToDictionary(b => b.Name, b => b);
        }
        public static void LoadBundleConfig <TPlatformBundleSettings>(DirectoryReference ProjectDir, UnrealTargetPlatform Platform,
                                                                      out List <TPlatformBundleSettings> Bundles,
                                                                      Action <TPlatformBundleSettings, ConfigHierarchy, string> GetPlatformSettings)
            where TPlatformBundleSettings : BundleSettings, new()
        {
            Bundles = new List <TPlatformBundleSettings>();

            ConfigHierarchy BundleConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.InstallBundle, ProjectDir, Platform);

            const string BundleDefinitionPrefix = "InstallBundleDefinition ";

            foreach (string SectionName in BundleConfig.SectionNames)
            {
                if (!SectionName.StartsWith(BundleDefinitionPrefix))
                {
                    continue;
                }

                TPlatformBundleSettings Bundle = new TPlatformBundleSettings();
                Bundle.Name = SectionName.Substring(BundleDefinitionPrefix.Length);
                {
                    int Order;
                    if (BundleConfig.GetInt32(SectionName, "Order", out Order))
                    {
                        Bundle.Order = Order;
                    }
                    else
                    {
                        Bundle.Order = int.MaxValue;
                    }
                }
                {
                    string ExecFileName;
                    BundleConfig.GetString(SectionName, "ExecFileName", out ExecFileName);
                    Bundle.ExecFileName = ExecFileName;
                }
                {
                    List <string> Tags;
                    BundleConfig.GetArray(SectionName, "Tags", out Tags);
                    Bundle.Tags = Tags;
                }
                {
                    List <string> FileRegex;
                    BundleConfig.GetArray(SectionName, "FileRegex", out FileRegex);
                    Bundle.FileRegex = FileRegex;
                }
                {
                    bool bContainsShaderLibrary;
                    BundleConfig.GetBool(SectionName, "ContainsShaderLibrary", out bContainsShaderLibrary);
                    Bundle.bContainsShaderLibrary = bContainsShaderLibrary;
                }
                if (Bundle.Tags == null)
                {
                    Bundle.Tags = new List <string>();
                }

                GetPlatformSettings(Bundle, BundleConfig, BundleDefinitionPrefix + Bundle.Name);

                Bundles.Add(Bundle);
            }

            // Use OrderBy and not Sort because OrderBy is stable
            Bundles = Bundles.OrderBy(Bundle => Bundle.Order).ToList();
        }