public override void Write(IBitWriter writer)
        {
            base.Write(writer);

            writer.WriteUInt64(ExportTimestamp(this._Timestamp));
            writer.WriteString(this._SaveFileName);
            writer.WriteUInt16(3);  // gameVersion
            writer.WriteUInt16(22); // saveVersion
            writer.WriteUInt16(10); // ??
            writer.WriteUInt16(0);  // ??
            writer.WriteUInt32(this._UserBuildInfo);
            writer.WriteString(this._LevelName);
            writer.WriteUInt32(this._Unknown1);
            writer.WriteStringList(this._PreloadedBundleNames);
            writer.WriteStringDictionary(this._LayerInclusion);

            writer.WriteUInt16((ushort)this._BundleHeaps.Count, 12);
            foreach (var instance in this._BundleHeaps)
            {
                writer.PushFrameLength(24);
                writer.WriteString(instance.Unknown1);
                writer.WriteUInt32(instance.Unknown2);
                writer.WriteUInt32(instance.Unknown3);
                writer.WriteUInt8((byte)instance.Type);
                writer.WriteUInt32(instance.Unknown4);
                writer.WriteBoolean(instance.Unknown5);
                writer.WriteUInt8(instance.Unknown6);
                writer.WriteUInt8(instance.Unknown7);
                writer.WriteUInt32(instance.Unknown8);
                writer.PopFrameLength();
            }

            writer.WriteUInt16((ushort)this._Unknown2.Count, 12);
            foreach (var instance in this._Unknown2)
            {
                writer.PushFrameLength(24);
                writer.WriteUInt16(instance.Unknown1);
                writer.WriteUInt16(instance.Unknown2);
                writer.WriteUInt8(instance.Unknown3);
                writer.PopFrameLength();
            }

            writer.WriteGuid(this._LevelHash);

            writer.WriteUInt32(0, 20); // unknown5

            writer.WriteUInt16(this._Unknown3);
            if (this._Unknown3 >= 5)
            {
                writer.WriteUInt16(this._Unknown4);
            }
            writer.WriteBoolean(this._Unknown5);

            writer.PushFramePosition(26);

            var componentDataPositionPosition = writer.Position;

            writer.WriteUInt32(0, 26);

            var entityDataOffsets = new List <Tuple <Entities.RawEntity, uint?, uint?> >();

            writer.PushFrameLength(32);
            foreach (var rawEntity in this._Entities)
            {
                uint?entityData0Offset = null;
                if (rawEntity.Data0Bytes != null)
                {
                    entityData0Offset = (uint)writer.Position;
                    writer.PushFrameLength(24);
                    writer.WriteBits(rawEntity.Data0Bytes, rawEntity.Data0Length);
                    writer.PopFrameLength();
                }
                uint?entityData1Offset = null;
                if (rawEntity.Data1Bytes != null)
                {
                    entityData1Offset = (uint)writer.Position;
                    writer.PushFrameLength(24);
                    writer.WriteBits(rawEntity.Data1Bytes, rawEntity.Data1Length);
                    writer.PopFrameLength();
                }
                entityDataOffsets.Add(
                    new Tuple <Entities.RawEntity, uint?, uint?>(
                        rawEntity,
                        entityData0Offset,
                        entityData1Offset));
            }
            writer.PopFrameLength();

            var unknown9 = writer.Position;

            writer.PushFrameLength(24);
            writer.PushFrameLength(24);
            writer.WriteString(this._Unknown6);
            writer.WriteString(this._Unknown7);
            writer.WriteString(this._SaveName);
            writer.PopFrameLength();
            writer.WriteUInt32(this._Unknown8);
            writer.WriteGuid(this._Unknown9);
            writer.WriteUInt32(this._Unknown10);
            writer.PopFrameLength();
            writer.WriteUInt32((uint)unknown9, 26);

            var agentDataOffsetLookup = new Dictionary <byte, uint[]>();

            writer.PushFrameLength(32);
            WriteAgentData(writer, this._Agents, agentDataOffsetLookup, 0, (w, t) => t.Write1(w, this._Unknown4));
            WriteAgentData(writer, this._Agents, agentDataOffsetLookup, 1, (w, t) => t.Write2(w));
            WriteAgentData(writer, this._Agents, agentDataOffsetLookup, 2, (w, t) => t.Write3(w, this._Unknown4));
            WriteAgentData(writer, this._Agents, agentDataOffsetLookup, 3, (w, t) => t.Write4(w));
            WriteAgentData(writer, this._Agents, agentDataOffsetLookup, 4, (w, t) => t.Write5(w));
            writer.PopFrameLength();

            writer.WriteUInt8((byte)agentDataOffsetLookup.Count, 4);
            foreach (var kv in agentDataOffsetLookup)
            {
                writer.WriteUInt8(kv.Key);
                for (int j = 0; j < 5; j++)
                {
                    writer.WriteUInt32(kv.Value[j], 26);
                }
            }

            writer.PushFrameLength(24);

            writer.WriteUInt16((ushort)entityDataOffsets.Count);
            foreach (var tuple in entityDataOffsets)
            {
                var rawEntity         = tuple.Item1;
                var entityData0Offset = tuple.Item2;
                var entityData1Offset = tuple.Item3;
                writer.WriteUInt32(rawEntity.Id);
                writer.WriteBoolean(entityData0Offset.HasValue);
                if (entityData0Offset.HasValue == true)
                {
                    writer.WriteUInt32(entityData0Offset.Value, 26);
                }
                writer.WriteBoolean(entityData1Offset.HasValue);
                if (entityData1Offset.HasValue == true)
                {
                    writer.WriteUInt32(entityData1Offset.Value, 26);
                }
            }

            writer.WriteUInt16((ushort)this._Unknown11.Count);
            foreach (var unknown17 in this._Unknown11)
            {
                writer.WriteUInt32(unknown17);
            }

            writer.WriteUInt16(0); // unknown18

            writer.WriteUInt16((ushort)this._Unknown12.Count);
            foreach (var unknown21 in this._Unknown12)
            {
                writer.WriteUInt32(unknown21);
            }

            writer.PopFrameLength();

            writer.PopFramePosition();

            writer.PushFrameLength(24);
            writer.WriteUInt8((byte)this._Agents.Count, 4);
            foreach (var kv in this._Agents)
            {
                var index    = kv.Key;
                var agent    = kv.Value;
                var nameHash = AgentFactory.GetNameHash(agent.AgentName);
                writer.WriteUInt32(nameHash);
                writer.WriteUInt8(index);
                agent.Write0(writer, index);
            }
            writer.PopFrameLength();

            if (writer.FrameCount != 0)
            {
                throw new SaveFormatException();
            }

            var componentDataPosition = writer.Position;

            writer.Position = componentDataPositionPosition;
            writer.WriteUInt32((uint)componentDataPosition, 26);
            writer.Position = componentDataPosition;

            writer.PushFrameLength(32);
            writer.WriteUInt16(this._Unknown13);
            if (this._Unknown13 == 1)
            {
                writer.WriteUInt16((ushort)this._ComponentContainerAgents.Count);
                foreach (var component in this._ComponentContainerAgents)
                {
                    writer.PushFrameLength(24);
                    var componentNameHash = ComponentContainerAgentFactory.GetNameHash(component.AgentName);
                    writer.WriteUInt32(componentNameHash);
                    writer.WriteUInt16(component.AgentVersion);
                    component.Write(writer);
                    writer.PopFrameLength();
                }
            }
            writer.PopFrameLength();

            if (writer.FrameCount != 0)
            {
                throw new SaveFormatException();
            }
        }