private void arrayDemarshallCode(
      MetaClass toMap, int dim, AnonymousClassStructureBuilder anonBuilder) {
    Object[] dimParms = new Object[dim];
    dimParms[0] = Stmt.loadVariable("a0").invoke("size");

    final MetaClass arrayType = toMap.asArrayOf(dim);

    MetaClass outerType = toMap.getOuterComponentType();
    if (!outerType.isArray() && outerType.isPrimitive()) {
      outerType = outerType.asBoxed();
    }

    Statement outerAccessorStatement =
        loadVariable("newArray", loadVariable("i"))
            .assignValue(Cast.to(outerType, loadVariable("a0").invoke("get", loadVariable("i"))));

    //    /**
    //     * Special case for handling char elements.
    //     */
    //    if (outerType.getFullyQualifiedName().equals(Character.class.getName())) {
    //      outerAccessorStatement =
    //              loadVariable("newArray", loadVariable("i"))
    //                      .assignValue(
    //                              Stmt.nestedCall(Cast.to(String.class,
    // loadVariable("a0").invoke("get", loadVariable("i"))))
    //                                      .invoke("charAt", 0));
    //    }

    final BlockBuilder<?> dmBuilder =
        anonBuilder
            .privateMethod(arrayType, "_demarshall" + dim)
            .parameters(List.class, MarshallingSession.class)
            .body();

    dmBuilder.append(
        Stmt.declareVariable(arrayType)
            .named("newArray")
            .initializeWith(Stmt.newArray(toMap, dimParms)));

    dmBuilder
        .append(
            autoForLoop("i", Stmt.loadVariable("newArray").loadField("length"))
                .append(
                    dim == 1
                        ? outerAccessorStatement
                        : loadVariable("newArray", loadVariable("i"))
                            .assignValue(
                                Stmt.invokeStatic(
                                    anonBuilder.getClassDefinition(),
                                    "_demarshall" + (dim - 1),
                                    Cast.to(
                                        List.class,
                                        Stmt.loadVariable("a0")
                                            .invoke("get", Stmt.loadVariable("i"))),
                                    Stmt.loadVariable("a1"))))
                .finish())
        .append(Stmt.loadVariable("newArray").returnValue());

    dmBuilder.finish();

    final BlockBuilder<?> mBuilder =
        anonBuilder
            .privateMethod(String.class, "_marshall" + dim)
            .parameters(arrayType, MarshallingSession.class)
            .body();

    mBuilder
        .append(
            Stmt.declareVariable(StringBuilder.class)
                .named("sb")
                .initializeWith(Stmt.newObject(StringBuilder.class).withParameters("[")))
        .append(
            autoForLoop("i", Stmt.loadVariable("a0").loadField("length"))
                .append(
                    Stmt.if_(Bool.greaterThan(Stmt.loadVariable("i"), 0))
                        .append(Stmt.loadVariable("sb").invoke("append", ","))
                        .finish())
                .append(
                    Stmt.loadVariable("sb")
                        .invoke(
                            "append",
                            dim == 1
                                ? Stmt.loadVariable(MarshallingGenUtil.getVarName(outerType))
                                    .invoke(
                                        "marshall",
                                        Stmt.loadVariable("a0", Stmt.loadVariable("i")),
                                        Stmt.loadVariable("a1"))
                                : Stmt.invokeStatic(
                                    anonBuilder.getClassDefinition(),
                                    "_marshall" + (dim - 1),
                                    Stmt.loadVariable("a0", Stmt.loadVariable("i")),
                                    loadVariable("a1"))))
                .finish())
        .append(Stmt.loadVariable("sb").invoke("append", "]").invoke("toString").returnValue())
        .finish();

    if (dim > 1) {
      arrayDemarshallCode(toMap, dim - 1, anonBuilder);
    }
  }
  private Statement generateArrayMarshaller(MetaClass arrayType) {
    MetaClass toMap = arrayType;
    while (toMap.isArray()) {
      toMap = toMap.getComponentType();
    }
    int dimensions = GenUtil.getArrayDimensions(arrayType);

    AnonymousClassStructureBuilder classStructureBuilder =
        Stmt.create(mappingContext.getCodegenContext())
            .newObject(parameterizedAs(Marshaller.class, typeParametersOf(List.class, arrayType)))
            .extend();

    MetaClass anonClass = classStructureBuilder.getClassDefinition();

    classStructureBuilder
        .publicOverridesMethod("getTypeHandled")
        .append(Stmt.load(toMap).returnValue())
        .finish();

    classStructureBuilder
        .publicOverridesMethod("getEncodingType")
        .append(Stmt.load("json").returnValue())
        .finish();

    BlockBuilder<?> bBuilder =
        classStructureBuilder.publicOverridesMethod(
            "demarshall",
            Parameter.of(Object.class, "a0"),
            Parameter.of(MarshallingSession.class, "a1"));

    bBuilder.append(
        Stmt.if_(Bool.isNull(loadVariable("a0")))
            .append(Stmt.load(null).returnValue())
            .finish()
            .else_()
            .append(
                Stmt.invokeStatic(
                        anonClass,
                        "_demarshall" + dimensions,
                        loadVariable("a0"),
                        loadVariable("a1"))
                    .returnValue())
            .finish());
    bBuilder.finish();

    arrayDemarshallCode(toMap, dimensions, classStructureBuilder);

    BlockBuilder<?> marshallMethodBlock =
        classStructureBuilder.publicOverridesMethod(
            "marshall",
            Parameter.of(Object.class, "a0"),
            Parameter.of(MarshallingSession.class, "a1"));

    marshallMethodBlock.append(
        Stmt.if_(Bool.isNull(loadVariable("a0")))
            .append(Stmt.load(null).returnValue())
            .finish()
            .else_()
            .append(
                Stmt.invokeStatic(
                        anonClass, "_marshall" + dimensions, loadVariable("a0"), loadVariable("a1"))
                    .returnValue())
            .finish());

    classStructureBuilder
        .publicOverridesMethod("handles", Parameter.of(JSONValue.class, "a0"))
        .append(Stmt.load(true).returnValue())
        .finish();

    marshallMethodBlock.finish();

    return classStructureBuilder.finish();
  }