private static List<Method> findAllMethodsInternal( Class<?> target, Spec<Method> predicate, MultiMap<String, Method> seen, List<Method> collector, boolean stopAtFirst) { for (final Method method : target.getDeclaredMethods()) { List<Method> seenWithName = seen.get(method.getName()); Method override = CollectionUtils.findFirst( seenWithName, new Spec<Method>() { public boolean isSatisfiedBy(Method potentionOverride) { return potentionOverride.getName().equals(method.getName()) && Arrays.equals( potentionOverride.getParameterTypes(), method.getParameterTypes()); } }); if (override == null) { seenWithName.add(method); if (predicate.isSatisfiedBy(method)) { collector.add(method); if (stopAtFirst) { return collector; } } } } Class<?> parent = target.getSuperclass(); if (parent != null) { return findAllMethodsInternal(parent, predicate, seen, collector, stopAtFirst); } return collector; }