private void addOverriddenMethods(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));  
        }
      }
    }
private void addOverriddenMethods(final ClassRepr fromClass, final Predicate<? super MethodRepr> predicate, final Collection<? super Pair<MethodRepr, ClassRepr>> container, IntSet visitedClasses, final ClassRepr visibilityScope)