public BaseType deserialize(
                JsonElement src, 
                java.lang.reflect.Type type, 
                JsonDeserializationContext context) throws JsonParseException {
            
            JsonObject object = src.getAsJsonObject();
            BaseType result = null;
            
            BaseType.Type typeType = 
                    BaseType.Type.values()[
                        (Integer)context.deserialize(
                            object.get("typeType"),
                            Integer.class
                        )
                    ];
            
            boolean constancy =
                (Boolean)context.deserialize(
                    object.get("constancy"),
                    Boolean.class
                );
            
            JsonPrimitive primitive = null;
            JsonObject obj = null;
            switch(typeType) {
                case ARRAY:
                {
                    obj = object.getAsJsonObject("elementType");
                    assert obj == null;
                    BaseType elementType =
                        context.deserialize(obj, BaseType.class);
                    
                    primitive = object.getAsJsonPrimitive("lenght");
                    if(primitive == null) {
                        result = new ArrayType(elementType, constancy);
                    } else {
                        int lenght =
                            (Integer)context.deserialize(
                                primitive,
                                Integer.class
                            );
                        result = new ArrayType(elementType, lenght, constancy);
                    }
                    
                    break;
                }
                case STRUCT:
                {
                    primitive = object.getAsJsonPrimitive("name");
                    assert primitive == null;
                    String name = context.deserialize(primitive, String.class);

                    JsonArray f = object.getAsJsonArray("fields");
                    assert f == null;
                    List<StructType.Field> fields = context.deserialize(
                        f,
                        new TypeToken<List<StructType.Field>>(){}.getType());
                    
                    result = new StructType(name, fields, constancy);
                    
                    break;
                }
                case FUNCTION:
                {
                    obj = object.getAsJsonObject("returnValue");
                    assert obj == null;
                    BaseType returnValue = context.deserialize(obj, BaseType.class);
                    
                    JsonArray a = object.getAsJsonArray("arguments");
                    assert a == null;
                    List<FunctionType.Argument> args = context.deserialize(
                        a, 
                        new TypeToken<List<FunctionType.Argument>>(){}.getType());
                    
                    result = new FunctionType(returnValue, args, constancy);
                    
                    break;
                }
                case PRIMITIVE_TYPE:
                {
                    primitive = object.getAsJsonPrimitive("primitive");
                    assert primitive == null;
                    PrimitiveType.Type t = PrimitiveType.Type.values()[
                            (Integer)context.deserialize(primitive, Integer.class)];
                    
                    switch(t) {
                        case POINTER:
                        {
                            obj = object.getAsJsonObject("type");
                            assert obj == null;
                            BaseType pType = context.deserialize(obj, BaseType.class);
                            
                            result = new PointerType(pType, constancy);
                            
                            break;
                        }
                        default:
                        {
                            result = new PrimitiveType(t, constancy);
                            break;
                        }
                    }
                    
                    break;
                }
                case INVALID:
                {
                    result = new InvalidType();
                    
                    break;
                }
            }
            
            return result;
        }