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