static FieldInfo getFieldInfo(MJIEnv env, int objRef) {
    int fidx = env.getIntField(objRef, "regIdx");
    assert ((fidx >= 0) || (fidx < nRegistered))
        : "illegal FieldInfo request: " + fidx + ", " + nRegistered;

    return registered[fidx];
  }
  static FieldInfo getFieldInfo(FeatureExpr ctx, MJIEnv env, int objRef) {
    int fidx = env.getIntField(objRef, "regIdx").simplify(ctx).getValue().intValue();
    assert ((fidx >= 0) || (fidx < nRegistered))
        : "illegal FieldInfo request: " + fidx + ", " + nRegistered;

    return registered[fidx];
  }
  @MJI
  public int delete__II__Ljava_lang_StringBuilder_2(
      final MJIEnv env,
      final int objref,
      final Integer beginIndex,
      final Integer endIndex,
      FeatureExpr ctx) {
    final Integer aref = env.getReferenceField(ctx, objref, "value").getValue();
    Conditional<Integer> count = env.getIntField(objref, "count");
    final int diff = endIndex - beginIndex;
    count.mapf(
        ctx,
        new VoidBiFunction<FeatureExpr, Integer>() {

          @Override
          public void apply(FeatureExpr ctx, Integer count) {
            for (int i = beginIndex, j = endIndex; i < count; i++, j++) {
              if (j < count) {
                env.setCharArrayElement(ctx, aref, i, env.getCharArrayElement(aref, j));
              } else {
                env.setCharArrayElement(ctx, aref, i, new One<>(' '));
              }
            }

            env.setIntField(ctx, objref, "count", new One<>(count - diff));
          }
        });
    return objref;
  }
 public static boolean equals__Ljava_lang_Object_2__Z(MJIEnv env, int objRef, int fobjRef) {
   int fidx = env.getIntField(fobjRef, "regIdx");
   if (fidx >= 0 && fidx < nRegistered) {
     FieldInfo fi1 = getFieldInfo(env, objRef);
     FieldInfo fi2 = getFieldInfo(env, fobjRef);
     return ((fi1.getClassInfo() == fi2.getClassInfo())
         && fi1.getName().equals(fi2.getName())
         && fi1.getType().equals(fi2.getType()));
   }
   return false;
 }
  private static boolean setValue(MJIEnv env, FieldInfo fi, int obj, int value, Object attr) {
    ClassInfo fieldClassInfo = fi.getClassInfo();

    String className = fieldClassInfo.getName();
    String fieldType = fi.getType();

    try {
      ClassInfo tci = fi.getTypeClassInfo();

      if (tci.isPrimitive()) {
        if (value == MJIEnv.NULL) {
          return false;
        }

        // checks whether unboxing can be done by accessing the field "value"
        final String fieldName = "value";
        FieldInfo finfo = env.getElementInfo(value).getFieldInfo(fieldName);
        if (finfo == null) {
          return false;
        }

        ElementInfo ei =
            fi.isStatic() ? fi.getClassInfo().getStaticElementInfo() : env.getElementInfo(obj);
        ei.setFieldAttr(fi, attr);

        if ("boolean".equals(fieldType)) {
          boolean val = env.getBooleanField(value, fieldName);
          ei.setBooleanField(fi, val);
          return true;
        } else if ("byte".equals(fieldType)) {
          byte val = env.getByteField(value, fieldName);
          ei.setByteField(fi, val);
          return true;
        } else if ("char".equals(fieldType)) {
          char val = env.getCharField(value, fieldName);
          ei.setCharField(fi, val);
          return true;
        } else if ("short".equals(fieldType)) {
          short val = env.getShortField(value, fieldName);
          ei.setShortField(fi, val);
          return true;
        } else if ("int".equals(fieldType)) {
          int val = env.getIntField(value, fieldName);
          ei.setIntField(fi, val);
          return true;
        } else if ("long".equals(fieldType)) {
          long val = env.getLongField(value, fieldName);
          ei.setLongField(fi, val);
          return true;
        } else if ("float".equals(fieldType)) {
          float val = env.getFloatField(value, fieldName);
          ei.setFloatField(fi, val);
          return true;
        } else if ("double".equals(fieldType)) {
          double val = env.getDoubleField(value, fieldName);
          ei.setDoubleField(fi, val);
          return true;
        } else {
          return false;
        }

      } else { // it's a reference
        if (value != MJIEnv.NULL) {
          String type = env.getTypeName(value);
          // this is an instance so the ClassInfo has to be registered
          ClassInfo valueCI = ClassInfo.getResolvedClassInfo(type);
          if (!valueCI.isInstanceOf(tci)) {
            return false;
          }
        }

        ElementInfo ei =
            fi.isStatic() ? fi.getClassInfo().getStaticElementInfo() : env.getElementInfo(obj);
        ei.setFieldAttr(fi, attr);

        if (fi.isStatic()) {
          env.setStaticReferenceField(className, fi.getName(), value);
        } else {
          env.setReferenceField(obj, fi.getName(), value);
        }
        return true;
      }

    } catch (NoClassInfoException cx) {
      env.throwException("java.lang.NoClassDefFoundError", cx.getMessage());
      return false;
    }
  }
  private static boolean setValue(
      FeatureExpr ctx, MJIEnv env, FieldInfo fi, int obj, int value, Object attr) {
    ClassInfo fieldClassInfo = fi.getClassInfo();
    String className = fieldClassInfo.getName();
    String fieldType = fi.getType();
    ClassInfo tci = fi.getTypeClassInfo();

    ElementInfo ei = null;
    if (fi.isStatic()) {
      ei = fi.getClassInfo().getModifiableStaticElementInfo();
    } else {
      ei = env.getModifiableElementInfo(obj);
    }

    if (tci.isPrimitive()) {
      if (value == MJIEnv.NULL) {
        return false;
      }

      // checks whether unboxing can be done by accessing the field "value"
      final String fieldName = "value";
      FieldInfo finfo = env.getElementInfo(value).getFieldInfo(fieldName);
      if (finfo == null) {
        return false;
      }

      ei.setFieldAttr(fi, attr);

      if ("boolean".equals(fieldType)) {
        Conditional<Boolean> val = env.getBooleanField(value, fieldName);
        ei.setBooleanField(ctx, fi, val);
        return true;
      } else if ("byte".equals(fieldType)) {
        Conditional<Byte> val = env.getByteField(value, fieldName);
        ei.setByteField(ctx, fi, val);
        return true;
      } else if ("char".equals(fieldType)) {
        Conditional<Character> val = env.getCharField(value, fieldName);
        ei.setCharField(ctx, fi, val);
        return true;
      } else if ("short".equals(fieldType)) {
        Conditional<Short> val = env.getShortField(value, fieldName);
        ei.setShortField(ctx, fi, val);
        return true;
      } else if ("int".equals(fieldType)) {
        Conditional<Integer> val = env.getIntField(value, fieldName);
        ei.setIntField(ctx, fi, val);
        return true;
      } else if ("long".equals(fieldType)) {
        Conditional<Long> val = env.getLongField(value, fieldName);
        ei.setLongField(ctx, fi, val);
        return true;
      } else if ("float".equals(fieldType)) {
        Conditional<Float> val = env.getFloatField(value, fieldName);
        ei.setFloatField(ctx, fi, val);
        return true;
      } else if ("double".equals(fieldType)) {
        Conditional<Double> val = env.getDoubleField(value, fieldName);
        ei.setDoubleField(ctx, fi, val);
        return true;
      } else {
        return false;
      }

    } else { // it's a reference
      if (value != MJIEnv.NULL) {
        ClassInfo ciValue = env.getClassInfo(value);
        if (!ciValue.isInstanceOf(tci)) {
          return false;
        }
      }

      ei.setFieldAttr(fi, attr);

      if (fi.isStatic()) {
        env.setStaticReferenceField(ctx, className, fi.getName(), value);
      } else {
        env.setReferenceField(ctx, obj, fi.getName(), value);
      }
      return true;
    }
  }