void (final ClassRepr fromClass, final Predicate<? super MethodRepr> predicate, final Collection<? super Pair<MethodRepr, ClassRepr>> container, IntSet visitedClasses, final ClassRepr visibilityScope) { if (visitedClasses == null) { visitedClasses = new IntOpenHashSet(); visitedClasses.add(fromClass.name); } for (TypeRepr.ClassType superName : fromClass.getSuperTypes()) { if (!visitedClasses.add(superName.className) || superName.className == myObjectClassName) { continue; // prevent SOE } Iterable<ClassRepr> superClasses = Iterators.collect(reprsByName(superName.className, ClassRepr.class), new SmartList<>()); if (!Iterators.isEmpty(superClasses)) { Iterable<Pair<MethodRepr, ClassRepr>> pairs = Iterators.flat( Iterators.map(superClasses, superClass -> Iterators.map(superClass.findMethods(mm -> predicate.test(mm) && isVisibleIn(superClass, mm, visibilityScope)), mm -> Pair.create(mm, superClass))) ); Set<ClassRepr> found = new SmartHashSet<>(); for (Pair<MethodRepr, ClassRepr> pair : pairs) { container.add(pair); found.add(pair.getSecond()); } for (ClassRepr superClass : Iterators.filter(superClasses, superClass -> !found.contains(superClass))) { // continue with those, for whom the matching method was not found addOverriddenMethods(superClass, predicate, container, visitedClasses, visibilityScope); } } else { container.add(Pair.create(MOCK_METHOD, MOCK_CLASS)); } } }