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