@Override
  public boolean processAddedField(DifferentiateContext context, Difference.Change<JvmClass, JvmClass.Diff> change, JvmField addedField, Utils future, Utils present) {
    JvmClass changedClass = change.getPast();
    debug("Field: " + addedField.getName());
    Set<JvmNodeReferenceID> changedClassWithSubclasses = future.collectSubclassesWithoutField(changedClass.getReferenceID(), addedField);
    changedClassWithSubclasses.add(changedClass.getReferenceID());
    for (JvmNodeReferenceID subClass : changedClassWithSubclasses) {
      String affectReason = null;
      if (!addedField.isPrivate()) {
        for (JvmClass cl : future.getNodes(subClass, JvmClass.class)) {
          if (cl.isLocal()) {
            affectReason = "Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ";
            break;
          }
          else {
            String outerClassName = cl.getOuterFqName();
            if (!outerClassName.isEmpty()) {
              Iterable<JvmClass> outerClasses = collect(future.getClassesByName(outerClassName), new SmartList<>());
              if (isEmpty(outerClasses) || !isEmpty(filter(outerClasses, ocl -> {
                return future.isFieldVisible(ocl, addedField);
              }))) {
                affectReason = "Affecting inner subclass (introduced field can potentially hide surrounding class fields): ";
                break;
              }
            }
          }
        }
      }

      if (affectReason != null) {
        affectNodeSources(context, subClass, affectReason, future);
      }

      if (!addedField.isPrivate() && addedField.isStatic()) {
        affectStaticMemberOnDemandUsages(context, subClass, Collections.emptyList());
      }
    }

    context.affectUsage(changedClassWithSubclasses, node -> {
      if (node instanceof JvmClass) {
        for (Usage usage : node.getUsages()) {
          // affect all clients that access fields with the same name via subclasses,
          // if the added field is not visible to the client
          if (usage instanceof FieldUsage) {
            if (Objects.equals(((FieldUsage)usage).getName(), addedField.getName()) && changedClassWithSubclasses.contains(usage.getElementOwner())) {
              return true;
            }
          }
        }
      }
      return false;
    });
    return true;
  }
@Override
  public boolean processAddedField(DifferentiateContext context, Difference.Change<JvmClass, JvmClass.Diff> change, JvmField addedField, Utils future, Utils present)