static ElementInfo getCheckedElementInfo(
      MJIEnv env,
      int objRef,
      FieldInfo fi,
      int fobjRef,
      Class<?> fiType,
      String type,
      boolean isWrite,
      FeatureExpr ctx) {
    ElementInfo ei;

    if (!isAvailable(env, fi, fobjRef, ctx)) {
      return null;
    }

    if (fi.isStatic()) {
      ClassInfo fci = fi.getClassInfo();
      ei = isWrite ? fci.getModifiableStaticElementInfo() : fci.getStaticElementInfo();
    } else { // instance field
      ei = isWrite ? env.getModifiableElementInfo(fobjRef) : env.getElementInfo(fobjRef);
    }

    // our guards (still need IllegalAccessException)
    if (fi.isPrivate() && !env.getBooleanField(objRef, "isAccessible").getValue()) {
      env.throwException(ctx, IllegalAccessException.class.getName(), fi + "");
      return null;
    }

    if (ei == null) {
      env.throwException(ctx, "java.lang.NullPointerException");
      return null;
    }
    if (fiType != null) {
      if (fiType == ByteFieldInfo.class) {
        if (fi.isByteField()) {
          return ei;
        }
      } else if (fiType == ShortFieldInfo.class) {
        if (fi.isShortField()) {
          return ei;
        }
      } else if (fiType == IntegerFieldInfo.class) {
        if (fi.isIntField()) {
          return ei;
        }
      } else if (fiType == LongFieldInfo.class) {
        if (fi.isLongField()) {
          return ei;
        }
      } else if (fiType == FloatFieldInfo.class) {
        if (fi.isFloatField()) {
          return ei;
        }
      }
      if (!fiType.isInstance(fi)) {
        env.throwException(
            ctx,
            "java.lang.IllegalArgumentException",
            "field type " + fi.getType() + " incompatible with " + type);
        return null;
      }
    }

    return ei;
  }
  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;
    }
  }