@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();
  }