@Override
    protected String buildReadMethodBody() {
        resetStringBuilder();
        buildString("{ ");

        buildString("if(!$3 && $1.trySkipNil()) {");
        buildString("  return null;");
        buildString("}");

        buildString("%s _$$_t;", origName);
        buildString("if($2 == null) {");
        buildString("  _$$_t = new %s();", origName);
        buildString("} else {");
        buildString("  _$$_t = (%s)$2;", origName);
        buildString("}");

        buildString("$1.readArrayBegin();");

        for (int i = 0; i < entries.length; i++) {
            BeansFieldEntry e = entries[i];

            if (!e.isAvailable()) {
                buildString("$1.skip();"); // TODO #MN
                continue;
            }

            if (e.isOptional()) {
                buildString("if($1.trySkipNil()) {");
                buildString("_$$_t.%s(null);", e.getSetterName());
                buildString("} else {");
            }

            Class<?> type = e.getType();
            if (type.isPrimitive()) {
                buildString("_$$_t.%s( $1.%s() );", e.getSetterName(), primitiveReadName(type));
            } else {
                buildString(
                        "_$$_t.%s( (%s)this.templates[%d].read($1, _$$_t.%s()) );",
                        e.getSetterName(), e.getJavaTypeName(), i, e.getGetterName());
            }

            if (e.isOptional()) {
                buildString("}");
            }
        }

        buildString("$1.readArrayEnd();");
        buildString("return _$$_t;");

        buildString("}");

        return getBuiltString();
    }