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