code: private Method findSupertypeMethod(Object o, String methodName, Class<?>[] types) {
      
      Method matchingMethod = null;
      Method[] methods = o.getClass().getDeclaredMethods();
      
      methodloop:
      for (Method method : methods) {
        if (methodName.equals(method.getName())) {
          Class<?>[] params = method.getParameterTypes();
          if (params.length == types.length) {
            for (int i = 0; i < params.length; i++) {
              // Check if param is supertype of arg in the same position
              if (!params[i].isAssignableFrom(types[i])) {
                break methodloop;
              }
            }
          }
          // If we reach here, then all params and args were compatible
          matchingMethod = method;
          break;
        }
      }
      
      return matchingMethod;
    }
docs: Examines each argument to see if a param in the same position is a supertype. This method is
  needed because getDeclaredMethod() does a formal type match. For example, if the method takes
  a java.util.List as a parameter, getDeclaredMethod() will never match, since the formal type
  of whatever you pass will be a concrete class.
  
  @param o
  @param methodName
  @param types
  @return A matching Method or null