private void addOverridingMethods(MethodRepr m, ClassRepr methodClass, final ClassRepr fromClass, final Predicate<? super MethodRepr> predicate, final Collection<? super Pair<MethodRepr, ClassRepr>> container, IntSet visitedClasses) {
      if (m.name == myInitName) {
        return; // overriding is not defined for constructors
      }
      final IntSet subClasses = myClassToSubclasses.get(fromClass.name);
      if (subClasses == null) {
        return;
      }
      if (visitedClasses == null) {
        visitedClasses = new IntOpenHashSet();
      }
      if (!visitedClasses.add(fromClass.name)) {
        return;
      }
      final IntSet _visitedClasses = visitedClasses;
      subClasses.forEach(subClassName -> {
        Iterable<ClassRepr> reprs = Iterators.collect(reprsByName(subClassName, ClassRepr.class), new SmartList<>());
        if (!Iterators.isEmpty(reprs)) {
          Iterable<Pair<MethodRepr, ClassRepr>> overriding = Iterators.flat(Iterators.map(
            reprs,
            r -> isVisibleIn(methodClass, m, r)? Iterators.map(r.findMethods(predicate), mm -> Pair.create(mm, r)) : Collections.emptyList())
          );

          Set<ClassRepr> found = new SmartHashSet<>();
          for (Pair<MethodRepr, ClassRepr> pair : overriding) {
            container.add(pair);
            found.add(pair.getSecond());
          }

          for (ClassRepr r : Iterators.filter(reprs, r -> !found.contains(r))) {
            // continue with reprs, for those no overriding members were found
            addOverridingMethods(m, methodClass, r, predicate, container, _visitedClasses);
          }
        }
      });
    }
private void addOverridingMethods(MethodRepr m, ClassRepr methodClass, final ClassRepr fromClass, final Predicate<? super MethodRepr> predicate, final Collection<? super Pair<MethodRepr, ClassRepr>> container, IntSet visitedClasses)