public Object invokeMethod(Reference ref, boolean isVirtual, Object cls, Object[] params)
      throws InterpreterException, InvocationTargetException {
    if (!isVirtual && cls != null) /* XXX */
      throw new InterpreterException("Can't invoke nonvirtual Method " + ref + ".");

    Method m;
    try {
      String[] paramTypeSigs = TypeSignature.getParameterTypes(ref.getType());
      Class clazz = TypeSignature.getClass(ref.getClazz());
      Class[] paramTypes = new Class[paramTypeSigs.length];
      for (int i = 0; i < paramTypeSigs.length; i++) {
        params[i] = toReflectType(paramTypeSigs[i], params[i]);
        paramTypes[i] = TypeSignature.getClass(paramTypeSigs[i]);
      }
      try {
        m = clazz.getMethod(ref.getName(), paramTypes);
      } catch (NoSuchMethodException ex) {
        m = clazz.getDeclaredMethod(ref.getName(), paramTypes);
      }
    } catch (ClassNotFoundException ex) {
      throw new InterpreterException(ref + ": Class not found");
    } catch (NoSuchMethodException ex) {
      throw new InterpreterException("Method " + ref + " not found");
    } catch (SecurityException ex) {
      throw new InterpreterException(ref + ": Security exception");
    }
    String retType = TypeSignature.getReturnType(ref.getType());
    try {
      return fromReflectType(retType, m.invoke(cls, params));
    } catch (IllegalAccessException ex) {
      throw new InterpreterException("Method " + ref + " not accessible");
    }
  }
  public Object invokeConstructor(Reference ref, Object[] params)
      throws InterpreterException, InvocationTargetException {
    Constructor c;
    try {
      String[] paramTypeSigs = TypeSignature.getParameterTypes(ref.getType());
      Class clazz = TypeSignature.getClass(ref.getClazz());
      Class[] paramTypes = new Class[paramTypeSigs.length];
      for (int i = 0; i < paramTypeSigs.length; i++) {
        params[i] = toReflectType(paramTypeSigs[i], params[i]);
        paramTypes[i] = TypeSignature.getClass(paramTypeSigs[i]);
      }
      try {
        c = clazz.getConstructor(paramTypes);
      } catch (NoSuchMethodException ex) {
        c = clazz.getDeclaredConstructor(paramTypes);
      }
    } catch (ClassNotFoundException ex) {
      throw new InterpreterException(ref + ": Class not found");
    } catch (NoSuchMethodException ex) {
      throw new InterpreterException("Constructor " + ref + " not found");
    } catch (SecurityException ex) {
      throw new InterpreterException(ref + ": Security exception");
    }

    try {
      return c.newInstance(params);
    } catch (IllegalAccessException ex) {
      throw new InterpreterException("Constructor " + ref + " not accessible");
    } catch (InstantiationException ex) {
      throw new InterpreterException("InstantiationException in " + ref + ".");
    }
  }
 public void putField(Reference ref, Object obj, Object value) throws InterpreterException {
   Field f;
   try {
     Class clazz = TypeSignature.getClass(ref.getClazz());
     try {
       f = clazz.getField(ref.getName());
     } catch (NoSuchFieldException ex) {
       f = clazz.getDeclaredField(ref.getName());
     }
   } catch (ClassNotFoundException ex) {
     throw new InterpreterException(ref + ": Class not found");
   } catch (NoSuchFieldException ex) {
     throw new InterpreterException("Constructor " + ref + " not found");
   } catch (SecurityException ex) {
     throw new InterpreterException(ref + ": Security exception");
   }
   try {
     f.set(obj, toReflectType(ref.getType(), value));
   } catch (IllegalAccessException ex) {
     throw new InterpreterException("Field " + ref + " not accessible");
   }
 }