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