void Serialize(MegaloScriptModel model, IO.BitStream s, Proto.MegaloScriptProtoVariableReference protoType)
        {
            s.Stream(ref Type, protoType.TypeBitLength);
            if (Type < 0 || Type >= protoType.Members.Count)
            {
                throw new System.IO.InvalidDataException(string.Format(Util.InvariantCultureInfo,
                                                                       "{0}/{1}: Encountered invalid {2} type data",
                                                                       s.StreamName, model.MegaloVariant.BaseVariant.Header.Title, mReferenceKind));
            }

            var member = protoType.Members[Type];

            if (member.HasDataType)
            {
                MegaloScriptEnumValue.SerializeValue(model, s, member.EnumValueType, ref DataType);
            }
            else
            {
                DataType = TypeExtensions.kNone;
            }

            if (member.HasDataValue)
            {
                SerializeData(model, s, member.ValueType);
            }
            else
            {
                Data = TypeExtensions.kNone;
            }
        }
        void SerializeData(MegaloScriptModel model, IO.BitStream s, Proto.MegaloScriptValueType valueType)
        {
            var base_type = valueType.BaseType;

            switch (base_type)
            {
            case Proto.MegaloScriptValueBaseType.Int:
                s.Stream(ref Data, valueType.BitLength, signExtend: true);
                break;

            case Proto.MegaloScriptValueBaseType.UInt:
            case Proto.MegaloScriptValueBaseType.Var:
                s.Stream(ref Data, valueType.BitLength);
                break;

            case Proto.MegaloScriptValueBaseType.Enum:
                MegaloScriptEnumValue.SerializeValue(model, s, valueType, ref Data);
                break;

            case Proto.MegaloScriptValueBaseType.Index:
                MegaloScriptIndexValue.SerializeValue(model, s, valueType, ref Data);
                break;

            default: throw new KSoft.Debug.UnreachableException(base_type.ToString());
            }
        }
        void SerializeData <TDoc, TCursor>(MegaloScriptModel model, IO.TagElementStream <TDoc, TCursor, string> s,
                                           Proto.MegaloScriptValueType valueType)
            where TDoc : class
            where TCursor : class
        {
            var base_type = valueType.BaseType;

            switch (base_type)
            {
            case Proto.MegaloScriptValueBaseType.Int:
            case Proto.MegaloScriptValueBaseType.UInt:
                s.StreamCursor(ref Data);
                break;

            case Proto.MegaloScriptValueBaseType.Var:
                if ((model.TagElementStreamSerializeFlags & MegaloScriptModelTagElementStreamFlags.UseIndexNames) != 0)
                {
                    var resolving_ctxt = new MegaloScriptModelVariableSet.IndexNameResolvingContext(model, valueType);
                    s.StreamCursorIdAsString(ref Data, resolving_ctxt,
                                             MegaloScriptModelVariableSet.IndexNameResolvingContext.IdResolver,
                                             MegaloScriptModelVariableSet.IndexNameResolvingContext.NameResolver);
                }
                else
                {
                    s.StreamCursor(ref Data);
                }
                break;

            case Proto.MegaloScriptValueBaseType.Enum:
                MegaloScriptEnumValue.SerializeValue(model, s, valueType, ref Data, IO.TagElementNodeType.Text);
                break;

            case Proto.MegaloScriptValueBaseType.Index:
                MegaloScriptIndexValue.SerializeValue(model, s, valueType, ref Data, IO.TagElementNodeType.Text);
                break;

            default: throw new KSoft.Debug.UnreachableException(base_type.ToString());
            }
        }
        void Serialize <TDoc, TCursor>(MegaloScriptModel model, IO.TagElementStream <TDoc, TCursor, string> s,
                                       Proto.MegaloScriptProtoVariableReference protoType)
            where TDoc : class
            where TCursor : class
        {
            const string kTypeAttributeName = "varRefType";

            if ((model.TagElementStreamSerializeFlags & MegaloScriptModelTagElementStreamFlags.UseEnumNames) != 0)
            {
                s.StreamAttributeIdAsString(kTypeAttributeName, ref Type,
                                            protoType, ToMemberIndex, FromMemberIndex);
            }
            else
            {
                s.StreamAttribute(kTypeAttributeName, ref Type);
            }

            var member = protoType.Members[Type];

            if (member.HasDataType)
            {
                MegaloScriptEnumValue.SerializeValue(model, s, member.EnumValueType, ref DataType,
                                                     IO.TagElementNodeType.Attribute, "dataType");
            }
            else
            {
                DataType = TypeExtensions.kNone;
            }

            if (member.HasDataValue)
            {
                SerializeData(model, s, member.ValueType);
            }
            else
            {
                Data = TypeExtensions.kNone;
            }
        }