docs: public Object callMethod(Object o, String methodName, Object... args)
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
  
      Method method = null;
      
      if (args == null || args.length == 0) {
        method = o.getClass().getDeclaredMethod(methodName);
      } else {
        Class<?>[] types = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
          types[i] = args[i].getClass();
        }
        try {
          method = o.getClass().getDeclaredMethod(methodName, types);
        } catch (NoSuchMethodException e) {
          // Try more complex comparison for matching args to supertypes in the params
          method = findSupertypeMethod(o, methodName, types);
        }
      }
      
      if (method == null) {
        throw new NoSuchMethodException("Found no method named" + methodName + " with matching params");
      }
      
      method.setAccessible(true);
      
      return method.invoke(o, args);
    }