private void processAddedMethods(final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) {
      final Collection<MethodRepr> added = diff.methods().added();
      if (added.isEmpty()) {
        return;
      }
      debug("Processing added methods: ");
      if (it.isAnnotation()) {
        debug("Class is annotation, skipping method analysis");
        return;
      }

      assert myFuture != null;
      assert myPresent != null;
      assert myAffectedFiles != null;

      for (final MethodRepr m : added) {
        if (!m.isPrivate() && (it.isInterface() || it.isAbstract() || m.isAbstract())) {
          debug("Method: ", m.name);
          debug("Class is abstract, or is interface, or added non-private method is abstract => affecting all subclasses");
          myFuture.affectSubclasses(it.name, myAffectedFiles, state.myAffectedUsages, state.myDependants, false, myCompiledFiles, null);
          break;
        }
      }

      if (it.isInterface()) {
        for (final MethodRepr m : added) {
          if (!m.isPrivate() && m.isAbstract()) {
            debug("Added non-private abstract method: ", m.name);
            myPresent.affectLambdaInstantiations(state, it.name);
            break;
          }
        }
      }

      for (final MethodRepr addedMethod : added) {
        debug("Method: ", addedMethod.name);

        final Supplier<IntSet> propagated = lazy(()-> myFuture.propagateMethodAccess(addedMethod, it.name));

        if (!addedMethod.isPrivate() && addedMethod.myArgumentTypes.length > 0 && !myPresent.hasOverriddenMethods(it, MethodRepr.equalByJavaRules(addedMethod), null, it)) {
          debug("Conservative case on overriding methods, affecting method usages");
          // do not propagate constructors access, since constructors are always concrete and not accessible via references to subclasses
          myFuture.affectMethodUsages(addedMethod, addedMethod.name == myInitName? null : propagated.get(), addedMethod.createMetaUsage(myContext, it.name), state.myAffectedUsages, state.myDependants);
        }

        if (!addedMethod.isPrivate()) {
          if (addedMethod.isStatic()) {
            myFuture.affectStaticMemberOnDemandUsages(it.name, propagated.get(), state.myAffectedUsages, state.myDependants);
          }

          Predicate<MethodRepr> lessSpecificCond = myFuture.lessSpecific(addedMethod);
          
          final Collection<MethodRepr> removed = diff.methods().removed();
          for (final MethodRepr lessSpecific : it.findMethods(lessSpecificCond)) {
            if (!lessSpecific.equals(addedMethod) && !removed.contains(lessSpecific))  {
              debug("Found less specific method, affecting method usages");
              myFuture.affectMethodUsages(lessSpecific, propagated.get(), lessSpecific.createUsage(myContext, it.name), state.myAffectedUsages, state.myDependants);
            }
          }

          debug("Processing overridden by specificity methods");

          final Collection<Pair<MethodRepr, ClassRepr>> overridden = new HashSet<>();
          myFuture.addOverriddenMethods(it, lessSpecificCond, overridden, null, it);
          for (final Pair<MethodRepr, ClassRepr> pair : overridden) {
            final MethodRepr method = pair.first;
            final ClassRepr methodClass = pair.second;

            if (methodClass == MOCK_CLASS) {
              continue; 
            }

            debug("Method: ", method.name);
            debug("Class : ", methodClass.name);
            debug("Affecting method usages for that found");
            myFuture.affectMethodUsages(method, myPresent.propagateMethodAccess(method, it.name), method.createUsage(myContext, it.name), state.myAffectedUsages, state.myDependants);
          }

          debug("Processing overriding by specificity methods");

          final Predicate<MethodRepr> overrides = MethodRepr.equalByJavaRules(addedMethod);
          final Collection<Pair<MethodRepr, ClassRepr>> overriding = new HashSet<>();
          myFuture.addOverridingMethods(addedMethod, it, it, lessSpecificCond, overriding, null);
          for (final Pair<MethodRepr, ClassRepr> pair : overriding) {
            final MethodRepr method = pair.first;
            final ClassRepr methodClass = pair.second;

            debug("Method: ", method.name);
            debug("Class : ", methodClass.name);

            if (overrides.test(method)) {
              debug("Current method overrides the added method");

              final Iterable<File> files = classToSourceFileGet(methodClass.name);
              if (files != null && !containsAll(myFilesToCompile, files)) {
                ContainerUtil.addAll(myAffectedFiles, files);
                if (myDebugS.isDebugEnabled()) {
                  for (File file : files) {
                    debug("Affecting file ", file);
                  }
                }
              }

            }
            else {
              debug("Current method does not override the added method");
              debug("Affecting method usages for the method");

              myPresent.appendDependents(methodClass, state.myDependants);
              myFuture.affectMethodUsages(method, myPresent.propagateMethodAccess(method, methodClass.name), method.createUsage(myContext, methodClass.name), state.myAffectedUsages, state.myDependants);
            }
          }

          getAllSubclasses(it.name).forEach(subClass -> {
            Iterable<ClassRepr> reprs = Iterators.collect(myFuture.reprsByName(subClass, ClassRepr.class), new SmartList<>());
            if (Iterators.isEmpty(reprs)) {
              return;
            }
            final Iterable<File> sourceFileNames = classToSourceFileGet(subClass);
            if (sourceFileNames != null && !containsAll(myCompiledFiles, sourceFileNames)) {
              for (ClassRepr outerClassRepr : Iterators.flat(Iterators.map(reprs, r -> isEmpty(r.getOuterClassName())? Collections.emptyList() : myFuture.reprsByName(r.getOuterClassName(), ClassRepr.class)))) {
                if (myFuture.isMethodVisible(outerClassRepr, addedMethod) || myFuture.extendsLibraryClass(outerClassRepr, null)) {
                  ContainerUtil.addAll(myAffectedFiles, sourceFileNames);
                  for (File sourceFileName : sourceFileNames) {
                    debug("Affecting file due to local overriding: ", sourceFileName);
                  }
                  break;
                }
              }
            }
          });
        }
      }
      debug("End of added methods processing");
    }
private void processAddedMethods(final DiffState state, final ClassRepr.Diff diff, final ClassRepr it)