@Override
  public boolean processRemovedMethods(DifferentiateContext context, Difference.Change<JvmClass, JvmClass.Diff> change, Iterable<JvmMethod> removed, Utils future, Utils present) {
    JvmClass changedClass = change.getPast();
    debug("Processing removed methods: ");
    Supplier<Boolean> extendsLibraryClass = Utils.lazyValue(() -> {
      return future.inheritsFromLibraryClass(changedClass);
    });
    for (JvmMethod removedMethod : removed) {
      debug("Method ", removedMethod.getName());

      Iterable<JvmNodeReferenceID> propagated = lazy(() -> {
        return future.collectSubclassesWithoutMethod(changedClass.getReferenceID(), removedMethod);
      });

      if (!removedMethod.isPrivate() && removedMethod.isStatic() && !removedMethod.isStaticInitializer()) {
        debug("The method was static --- affecting static method import usages");
        affectStaticMemberImportUsages(context, changedClass.getReferenceID(), removedMethod.getName(), propagated);
      }

      if (removedMethod.isPackageLocal()) {
        if (!removedMethod.isStaticInitializer()) {
          // Sometimes javac cannot find an overridden package local method in superclasses, when superclasses are defined in different packages.
          // This results in compilation error when the code is compiled from the very beginning.
          // So even if we correctly find a corresponding overridden method and the bytecode compatibility remains,
          // we still need to affect package local method usages to behave similar to javac.
          debug("Removed method is package-local, affecting method usages");
          affectMemberUsages(context, changedClass.getReferenceID(), removedMethod, propagated);
        }
      }
      else {
        Iterable<Pair<JvmClass, JvmMethod>> overridden = removedMethod.isConstructor()? Collections.emptyList() : lazy(() -> {
          return future.getOverriddenMethods(changedClass, removedMethod::isSameByJavaRules);
        });
        boolean isClearlyOverridden = removedMethod.getSignature().isEmpty() && !extendsLibraryClass.get() && !isEmpty(overridden) && isEmpty(
          filter(overridden, p -> !p.getSecond().getType().equals(removedMethod.getType()) || !p.getSecond().getSignature().isEmpty() || removedMethod.isMoreAccessibleThan(p.getSecond()))
        );
        if (!isClearlyOverridden) {
          debug("No overridden methods found, affecting method usages");
          affectMemberUsages(context, changedClass.getReferenceID(), removedMethod, propagated);
        }
      }

      if (removedMethod.isOverridable()) {
        for (Pair<JvmClass, JvmMethod> overriding : future.getOverridingMethods(changedClass, removedMethod, removedMethod::isSameByJavaRules)) {
          affectNodeSources(context, overriding.getFirst().getReferenceID(), "Affecting file by overriding: ", future);
        }
      }

      if (!removedMethod.isConstructor() && !removedMethod.isAbstract() && !removedMethod.isStatic()) {
        for (JvmNodeReferenceID id : propagated) {
          for (JvmClass subClass : future.getNodes(id, JvmClass.class)) {
            Iterable<Pair<JvmClass, JvmMethod>> overriddenForSubclass = filter(future.getOverriddenMethods(subClass, removedMethod::isSameByJavaRules), p -> p.getSecond().isAbstract() || removedMethod.isSame(p.getSecond()));
            boolean allOverriddenAbstract = !isEmpty(overriddenForSubclass) && isEmpty(filter(overriddenForSubclass, p -> !p.getSecond().isAbstract()));
            if (allOverriddenAbstract || future.inheritsFromLibraryClass(subClass)) {
              debug("Removed method is not abstract & overrides some abstract method which is not then over-overridden in subclass ", subClass.getName());
              affectNodeSources(context, subClass.getReferenceID(), "Affecting subclass source file: ", future);
              break;
            }
          }
        }
      }
    }
    debug("End of removed methods processing");
    return true;
  }
@Override
  public boolean processRemovedMethods(DifferentiateContext context, Difference.Change<JvmClass, JvmClass.Diff> change, Iterable<JvmMethod> removed, Utils future, Utils present)