code: @GwtIncompatible("incompatible method")
      public static Method getPublicMethod(final Class<?> cls, final String methodName, final Class<?>... parameterTypes)
              throws SecurityException, NoSuchMethodException {
  
          final Method declaredMethod = cls.getMethod(methodName, parameterTypes);
          if (Modifier.isPublic(declaredMethod.getDeclaringClass().getModifiers())) {
              return declaredMethod;
          }
  
          final List<Class<?>> candidateClasses = new ArrayList<>();
          candidateClasses.addAll(getAllInterfaces(cls));
          candidateClasses.addAll(getAllSuperclasses(cls));
  
          for (final Class<?> candidateClass : candidateClasses) {
              if (!Modifier.isPublic(candidateClass.getModifiers())) {
                  continue;
              }
              Method candidateMethod;
              try {
                  candidateMethod = candidateClass.getMethod(methodName, parameterTypes);
              } catch (final NoSuchMethodException ex) {
                  continue;
              }
              if (Modifier.isPublic(candidateMethod.getDeclaringClass().getModifiers())) {
                  return candidateMethod;
              }
          }
  
          throw new NoSuchMethodException("Can't find a public method for " +
                  methodName + " " + ArrayUtils.toString(parameterTypes));
      }
docs: <p>Returns the desired Method much like {@code Class.getMethod}, however
  it ensures that the returned Method is from a public class or interface and not
  from an anonymous inner class. This means that the Method is invokable and
  doesn't fall foul of Java bug
  <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957">4071957</a>).</p>
  
  <pre>
  <code>Set set = Collections.unmodifiableSet(...);
  Method method = ClassUtils.getPublicMethod(set.getClass(), "isEmpty",  new Class[0]);
  Object result = method.invoke(set, new Object[]);</code>
  </pre>
  
  @param cls  the class to check, not null
  @param methodName  the name of the method
  @param parameterTypes  the list of parameters
  @return the method
  @throws NullPointerException if the class is null
  @throws SecurityException if a security violation occurred
  @throws NoSuchMethodException if the method is not found in the given class
  or if the method doesn't conform with the requirements