docs: public Method findBestMethodWithSignature( String methodName,
                                                 boolean caseSensitive,
                                                 Class<?>... argumentsClasses ) throws NoSuchMethodException, SecurityException {
  
          // Attempt to find the method
          Method result;
  
          // -------------------------------------------------------------------------------
          // First try to find the method with EXACTLY the argument classes as specified ...
          // -------------------------------------------------------------------------------
          Class<?>[] classArgs = null;
          try {
              classArgs = argumentsClasses != null ? argumentsClasses : new Class[] {};
              result = this.targetClass.getMethod(methodName, classArgs); // this may throw an exception if not found
              return result;
          } catch (NoSuchMethodException e) {
              // No method found, so continue ...
          }
  
          // ---------------------------------------------------------------------------------------------
          // Then try to find a method with the argument classes converted to a primitive, if possible ...
          // ---------------------------------------------------------------------------------------------
          List<Class<?>> argumentsClassList = convertArgumentClassesToPrimitives(argumentsClasses);
          try {
              classArgs = argumentsClassList.toArray(new Class[argumentsClassList.size()]);
              result = this.targetClass.getMethod(methodName, classArgs); // this may throw an exception if not found
              return result;
          } catch (NoSuchMethodException e) {
              // No method found, so continue ...
          }
  
          // ---------------------------------------------------------------------------------------------
          // Still haven't found anything. So far, the "getMethod" logic only finds methods that EXACTLY
          // match the argument classes (i.e., not methods declared with superclasses or interfaces of
          // the arguments). There is no canned algorithm in Java to do this, so we have to brute-force it.
          // The following algorithm will find the first method that matches by doing "instanceof", so it
          // may not be the best method. Since there is some overhead to this algorithm, the first time
          // caches some information in class members.
          // ---------------------------------------------------------------------------------------------
          Method method;
          LinkedList<Method> methodsWithSameName;
          if (this.methodMap == null) {
              // This is idempotent, so no need to lock or synchronize ...
              this.methodMap = new HashMap<String, LinkedList<Method>>();
              Method[] methods = this.targetClass.getMethods();
              for (int i = 0; i != methods.length; ++i) {
                  method = methods[i];
                  methodsWithSameName = this.methodMap.get(method.getName());
                  if (methodsWithSameName == null) {
                      methodsWithSameName = new LinkedList<Method>();
                      this.methodMap.put(method.getName(), methodsWithSameName);
                  }
                  methodsWithSameName.addFirst(method); // add lower methods first
              }
          }
  
          // ------------------------------------------------------------------------
          // Find the set of methods with the same name (do this twice, once with the
          // original methods and once with the primitives) ...
          // ------------------------------------------------------------------------
          // List argClass = argumentsClasses;
          for (int j = 0; j != 2; ++j) {
  
              if (caseSensitive) {
                  methodsWithSameName = this.methodMap.get(methodName);
              } else {
                  methodsWithSameName = new LinkedList<Method>();
                  Pattern pattern = Pattern.compile(methodName, Pattern.CASE_INSENSITIVE);
  
                  for (Map.Entry<String, LinkedList<Method>> entry : this.methodMap.entrySet()) {
                      // entry.getKey() is the method name
                      if (pattern.matcher(entry.getKey()).matches()) {
                          methodsWithSameName.addAll(entry.getValue());
                      }
                  }
              }
  
              if (methodsWithSameName == null) {
                  throw new NoSuchMethodException(methodName);
              }
              Iterator<Method> iter = methodsWithSameName.iterator();
              Class<?>[] args;
              Class<?> clazz;
              boolean allMatch;
              while (iter.hasNext()) {
                  method = iter.next();
                  args = method.getParameterTypes();
                  if (args.length == argumentsClassList.size()) {
                      allMatch = true; // assume they all match
                      for (int i = 0; i < args.length; ++i) {
                          clazz = argumentsClassList.get(i);
                          if (clazz != null) {
                              Class<?> argClass = args[i];
                              if (argClass.isAssignableFrom(clazz)) {
                                  // It's a match
                              } else if (argClass.isArray() && clazz.isArray()
                                         && argClass.getComponentType().isAssignableFrom(clazz.getComponentType())) {
                                  // They're both arrays, and they're castable, so we're good ...
                              } else {
                                  allMatch = false; // found one that doesn't match
                                  i = args.length; // force completion
                              }
                          } else {
                              // a null is assignable for everything except a primitive
                              if (args[i].isPrimitive()) {
                                  allMatch = false; // found one that doesn't match
                                  i = args.length; // force completion
                              }
                          }
                      }
                      if (allMatch) {
                          return method;
                      }
                  }
              }
          }
  
          throw new NoSuchMethodException(methodName);
      }