/// <summary>
        /// Parses an XML plugin into a <see cref="TagLayout"/>.
        /// </summary>
        /// <param name="reader">The XmlReader to read the plugin XML from.</param>
        /// <param name="name">The name to give the resulting layout.</param>
        /// <param name="groupTag">The group tag to give to the resulting layout.</param>
        /// <returns>The results from loading the plugin.</returns>
        public static AssemblyPluginLoadResults LoadPlugin(XmlReader reader, string name, Tag groupTag)
        {
            if (!reader.ReadToNextSibling("plugin"))
                throw new ArgumentException("The XML file is missing a <plugin> tag.");

            int baseSize = 0;
            if (reader.MoveToAttribute("baseSize"))
                baseSize = ParseInt(reader.Value);

            var loader = new AssemblyPluginLoader(null);
            loader._results.Layout = new TagLayout(name, (uint)baseSize, groupTag);
            loader.ReadElements(reader, true);
            return loader._results;
        }
        /// <summary>
        /// Parses an XML plugin into a <see cref="TagLayout"/>.
        /// </summary>
        /// <param name="reader">The XmlReader to read the plugin XML from.</param>
        /// <param name="name">The name to give the resulting layout.</param>
        /// <param name="groupTag">The group tag to give to the resulting layout.</param>
        /// <returns>The results from loading the plugin.</returns>
        public static AssemblyPluginLoadResults LoadPlugin(XmlReader reader, string name, Tag groupTag)
        {
            if (!reader.ReadToNextSibling("plugin"))
            {
                throw new ArgumentException("The XML file is missing a <plugin> tag.");
            }

            int baseSize = 0;

            if (reader.MoveToAttribute("baseSize"))
            {
                baseSize = ParseInt(reader.Value);
            }

            var loader = new AssemblyPluginLoader(null);

            loader._results.Layout = new TagLayout(name, (uint)baseSize, groupTag);
            loader.ReadElements(reader, true);
            return(loader._results);
        }
        private void ReadReflexive(XmlReader reader, string name, uint offset, bool visible,
                                   uint pluginLine)
        {
            if (!reader.MoveToAttribute("entrySize"))
            {
                throw new ArgumentException("Reflexives must have an entrySize attribute." + PositionInfo(reader));
            }

            uint entrySize = ParseUInt(reader.Value);
            int  align     = 4;

            if (reader.MoveToAttribute("align"))
            {
                align = ParseInt(reader.Value);
            }

            reader.MoveToElement();
            XmlReader subtree = reader.ReadSubtree();

            subtree.ReadStartElement();

            // Singularize the last word in the block name to get the layout name
            var words = name.Split(' ');

            words[words.Length - 1] = Pluralization.Singularize(words[words.Length - 1]);
            var layoutName = string.Join(" ", words);

            // Read the layout using a new loader (to keep track of conflicts)
            var loader = new AssemblyPluginLoader(name);

            loader._results.Layout = new TagLayout(layoutName, entrySize);
            loader.ReadElements(subtree, false);
            _results.Layout.Add(new TagBlockTagLayoutField(name, loader._results.Layout));
            _results.Conflicts.AddRange(loader._results.Conflicts); // Merge in conflicts from the block
            RegisterField(offset, 0xC);
        }
        private void ReadReflexive(XmlReader reader, string name, uint offset, bool visible,
            uint pluginLine)
        {
            if (!reader.MoveToAttribute("entrySize"))
                throw new ArgumentException("Reflexives must have an entrySize attribute." + PositionInfo(reader));

            uint entrySize = ParseUInt(reader.Value);
            int align = 4;
            if (reader.MoveToAttribute("align"))
                align = ParseInt(reader.Value);

            reader.MoveToElement();
            XmlReader subtree = reader.ReadSubtree();
            subtree.ReadStartElement();

            // Singularize the last word in the block name to get the layout name
            var words = name.Split(' ');
            words[words.Length - 1] = Pluralization.Singularize(words[words.Length - 1]);
            var layoutName = string.Join(" ", words);

            // Read the layout using a new loader (to keep track of conflicts)
            var loader = new AssemblyPluginLoader(name);
            loader._results.Layout = new TagLayout(layoutName, entrySize);
            loader.ReadElements(subtree, false);
            _results.Layout.Add(new TagBlockTagLayoutField(name, loader._results.Layout));
            _results.Conflicts.AddRange(loader._results.Conflicts); // Merge in conflicts from the block
            RegisterField(offset, 0xC);
        }