public void Deserialize(Stream input, Endian endian, StringTable strings)
        {
            this.Name = strings.ReadString(input, endian);
            this.Type = strings.ReadString(input, endian);

            var childCount = input.ReadValueU16(endian);

            var unknown08      = input.ReadValueU8();
            var baselineOffset = input.ReadValueU32(endian);
            var overrideCount  = input.ReadValueU8();

            if (overrideCount > 0)
            {
                var infos = new List <KeyValuePair <string, uint> >();
                for (byte i = 0; i < overrideCount; i++)
                {
                    var name   = strings.ReadString(input, endian);
                    var offset = input.ReadValueU32(endian);

                    infos.Add(new KeyValuePair <string, uint>(
                                  name, offset));
                }

                foreach (var info in infos)
                {
                    if (input.Position != info.Value)
                    {
                        throw new FormatException();
                    }

                    if (this.Overrides.ContainsKey(info.Key) == true)
                    {
                        throw new FormatException();
                    }

                    var OVERRIDE = new PropertyList();
                    OVERRIDE.Deserialize(input, endian, strings);
                    this.Overrides.Add(info.Key, OVERRIDE);
                }
            }

            if (baselineOffset != input.Position)
            {
                throw new FormatException();
            }

            this.Baseline = new PropertyList();
            this.Baseline.Deserialize(input, endian, strings);

            for (ushort i = 0; i < childCount; i++)
            {
                var element = new Object();
                element.Deserialize(input, endian, strings);
                this.Children.Add(element);
            }
        }
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != Signature && magic.Swap() != Signature)
            {
                throw new FormatException();
            }
            var endian = magic == Signature ? Endian.Little : Endian.Big;

            var nameIndex             = input.ReadValueS32(endian);
            var version               = input.ReadValueU16(endian);
            var animationTime         = input.ReadValueF32(endian);
            var metadataCount         = input.ReadValueU32(endian);
            var criticalResourceCount = input.ReadValueU32(endian);
            var stringTableOffset     = input.ReadValueU32(endian);
            var elementCount          = input.ReadValueU16(endian);
            var animationCount        = input.ReadValueU16(endian);

            if (version != 1 && version != 2)
            {
                throw new FormatException();
            }

            if (stringTableOffset >= input.Length)
            {
                throw new FormatException();
            }

            var position = input.Position;

            input.Seek(stringTableOffset, SeekOrigin.Begin);
            var strings = new Interface.StringTable();

            strings.Deserialize(input, endian);
            input.Seek(position, SeekOrigin.Begin);

            if (nameIndex != 0)
            {
                throw new FormatException();
            }

            var fileName = strings.ReadString(nameIndex);

            var criticalResources = new Interface.CriticalResource[criticalResourceCount];

            for (uint i = 0; i < criticalResourceCount; i++)
            {
                var type = input.ReadValueEnum <Interface.CriticalResourceType>();
                if (type != Interface.CriticalResourceType.Peg &&
                    type != Interface.CriticalResourceType.Document)
                {
                    throw new FormatException();
                }

                var name     = strings.ReadString(input, endian);
                var autoload = this._Version >= 2 && input.ReadValueB8() == true;

                if (autoload == true &&
                    type != Interface.CriticalResourceType.Peg)
                {
                    throw new FormatException();
                }

                criticalResources[i] = new Interface.CriticalResource()
                {
                    Type     = type,
                    Name     = name,
                    Autoload = autoload,
                };
            }

            var metadatas = new Interface.Metadata[metadataCount];

            for (uint i = 0; i < metadataCount; i++)
            {
                var name  = strings.ReadString(input, endian);
                var value = strings.ReadString(input, endian);
                metadatas[i] = new Interface.Metadata(name, value);
            }

            var elements = new Interface.Object[elementCount];

            for (ushort i = 0; i < elementCount; i++)
            {
                var element = new Interface.Object();
                element.Deserialize(input, endian, strings);
                elements[i] = element;
            }

            var animations = new Interface.Object[animationCount];

            for (ushort i = 0; i < animationCount; i++)
            {
                var animation = new Interface.Object();
                animation.Deserialize(input, endian, strings);
                animations[i] = animation;
            }

            if (input.Position != stringTableOffset)
            {
                throw new FormatException();
            }

            this._Endian        = endian;
            this._Name          = fileName;
            this._Version       = version;
            this._AnimationTime = animationTime;
            this._CriticalResources.Clear();
            this._CriticalResources.AddRange(criticalResources);
            this._Metadata.Clear();
            this._Metadata.AddRange(metadatas);
            this._Elements.Clear();
            this._Elements.AddRange(elements);
            this._Animations.Clear();
            this._Animations.AddRange(animations);
        }