private static void ProcessSetElement(XElement element, StringIDSetResolver resolver)
        {
            int id = XMLUtil.GetNumericAttribute(element, "id");
            int min = XMLUtil.GetNumericAttribute(element, "min", 0);
            int globalIndex = XMLUtil.GetNumericAttribute(element, "startIndex");

            resolver.RegisterSet(id, min, globalIndex);
        }
        /// <summary>
        /// Loads stringID set definitions from an XML document.
        /// </summary>
        /// <param name="container">The XML document to load set definitions from.</param>
        /// <param name="resolver">The StringIDSetResolver to store sets to.</param>
        public static void LoadStringIDSets(XDocument document, StringIDSetResolver resolver)
        {
            // Make sure there is a root <stringIDs> tag
            XContainer stringIDContainer = document.Element("stringIDs");
            if (stringIDContainer == null)
                throw new ArgumentException("Invalid stringID definition document");

            // Process <set> elements
            foreach (XElement element in stringIDContainer.Elements("set"))
                ProcessSetElement(element, resolver);
        }
        /// <summary>
        ///     Loads stringID set definitions from an XML document.
        /// </summary>
        /// <param name="document">The XML document to load set definitions from.</param>
        /// <returns>The StringIDSetResolver that was created.</returns>
        public static StringIDSetResolver LoadStringIDSets(XDocument document)
        {
            // Make sure there is a root <stringIDs> tag
            XElement container = document.Element("stringIDs");
            if (container == null)
                throw new ArgumentException("Invalid stringID definition document");

            StringIDLayout idLayout = ProcessIDLayoutInfo(container);

            // Process <set> elements
            var resolver = new StringIDSetResolver(idLayout);
            foreach (XElement element in container.Elements("set"))
                ProcessSetElement(element, resolver);

            return resolver;
        }
        /// <summary>
        /// Loads all of the structure layouts defined for a specified build.
        /// </summary>
        /// <param name="buildName">The build version to load structure layouts for.</param>
        /// <returns>The build's information, or null if it was not found.</returns>
        public BuildInformation LoadBuild(string buildName)
        {
            // Find the first build tag whose version matches and load its file.
            XElement buildElement = _builds.Elements("build").FirstOrDefault(e => XMLUtil.GetStringAttribute(e, "version", "") == buildName);
            if (buildElement == null)
                return null;

            // Read attributes
            string gameName = XMLUtil.GetStringAttribute(buildElement, "name");
            string shortName = XMLUtil.GetStringAttribute(buildElement, "shortName");
            string pluginFolder = XMLUtil.GetStringAttribute(buildElement, "pluginFolder");
            string layoutsPath = XMLUtil.GetStringAttribute(buildElement, "filename");
            bool loadStrings = XMLUtil.GetBoolAttribute(buildElement, "loadStrings", true);
            string localeKey = XMLUtil.GetStringAttribute(buildElement, "localeKey", null);
            string stringidKey = XMLUtil.GetStringAttribute(buildElement, "stringidKey", null);
            string filenameKey = XMLUtil.GetStringAttribute(buildElement, "filenameKey", null);
            string localeSymbolsPath = XMLUtil.GetStringAttribute(buildElement, "localeSymbols", null);
            string scriptDefinitionsPath = XMLUtil.GetStringAttribute(buildElement, "scriptDefinitions", null);
            int segmentAlignment = XMLUtil.GetNumericAttribute(buildElement, "segmentAlignment", 0x1000);
            int headerSize = XMLUtil.GetNumericAttribute(buildElement, "headerSize");
            string stringidModifiers = XMLUtil.GetStringAttribute(buildElement, "stringidModifiers", null);
            string stringidDefinitionsPath = XMLUtil.GetStringAttribute(buildElement, "stringidDefinitions", null);
            string vertexLayoutsPath = XMLUtil.GetStringAttribute(buildElement, "vertexLayouts", null);

            // Load structure layouts
            layoutsPath = Path.Combine(_basePath, layoutsPath);
            StructureLayoutCollection layouts = XMLLayoutLoader.LoadLayouts(layoutsPath);

            // StringID Modifers, this is a bitch
            IStringIDResolver stringIdResolver = null;
            if (stringidModifiers != null)
            {
                StringIDModifierResolver modifierResolver = new StringIDModifierResolver();
                stringIdResolver = modifierResolver;

                string[] sets = stringidModifiers.Split('|');
                foreach (string set in sets)
                {
                    string[] parts = set.Split(',');
                    /*
                     Format:
                     * Identifier
                     * Modifier
                     * MathSymbol (+/-)
                     * Direction (>/<)
                     */

                    int identifier = int.Parse(parts[0].Replace("0x", ""), NumberStyles.AllowHexSpecifier);
                    int modifier = int.Parse(parts[1].Replace("0x", ""), NumberStyles.AllowHexSpecifier);
                    bool isAddition = parts[2] == "+";
                    bool isGreaterThan = parts[3] == ">";

                    modifierResolver.AddModifier(identifier, modifier, isGreaterThan, isAddition);
                }
            }
            else if (stringidDefinitionsPath != null)
            {
                StringIDSetResolver setResolver = new StringIDSetResolver();
                stringIdResolver = setResolver;

                stringidDefinitionsPath = Path.Combine(_basePath, "StringIDs", stringidDefinitionsPath);
                StringIDSetLoader.LoadStringIDSets(stringidDefinitionsPath, setResolver);
            }
            else
            {
                // Use a blank modifier
                stringIdResolver = new StringIDModifierResolver();
            }

            if (scriptDefinitionsPath != null)
                scriptDefinitionsPath = Path.Combine(_basePath, "Scripting", scriptDefinitionsPath);

            BuildInformation info = new BuildInformation(gameName, localeKey, stringidKey, stringIdResolver, filenameKey, headerSize, loadStrings, layouts, shortName, pluginFolder, scriptDefinitionsPath, segmentAlignment);

            if (localeSymbolsPath != null)
            {
                localeSymbolsPath = Path.Combine(_basePath, "LocaleSymbols", localeSymbolsPath);
                info.LocaleSymbols.AddSymbols(LocaleSymbolLoader.LoadLocaleSymbols(localeSymbolsPath));
            }

            if (vertexLayoutsPath != null)
            {
                vertexLayoutsPath = Path.Combine(_basePath, "Vertices", vertexLayoutsPath);
                info.VertexLayouts.AddLayouts(VertexLayoutLoader.LoadLayouts(vertexLayoutsPath));
            }

            return info;
        }
 /// <summary>
 /// Loads stringID set definitions from an XML document.
 /// </summary>
 /// <param name="documentPath">The path to the XML document to load.</param>
 /// <param name="resolver">The StringIDSetResolver to store sets to.</param>
 /// <returns>The definitions that were loaded.</returns>
 public static void LoadStringIDSets(string documentPath, StringIDSetResolver resolver)
 {
     LoadStringIDSets(XDocument.Load(documentPath), resolver);
 }