public void applyRule(
      final SNode classifier,
      final TypeCheckingContext typeCheckingContext,
      IsApplicableStatus status) {
    OverridingMethodsFinder finder = new OverridingMethodsFinder(classifier);
    for (SNode overridingMethod : SetSequence.fromSet(finder.getOverridingMethods())) {
      Set<Tuples._2<SNode, SNode>> overridenMethods = finder.getOverridenMethods(overridingMethod);
      for (Iterator<Tuples._2<SNode, SNode>> it = SetSequence.fromSet(overridenMethods).iterator();
          it.hasNext(); ) {
        SNode overridenMethod = it.next()._0();
        SNode returnType = SLinkOperations.getTarget(overridenMethod, "returnType", true);
        SNode ancestor =
            SNodeOperations.cast(
                SNodeOperations.getParent(overridenMethod),
                "jetbrains.mps.baseLanguage.structure.Classifier");
        SNode overridingMethodParent = SNodeOperations.getParent(overridingMethod);
        SNode resolvedReturnType;
        if (SNodeOperations.isInstanceOf(
            overridingMethodParent, "jetbrains.mps.baseLanguage.structure.Classifier")) {
          resolvedReturnType =
              Classifier_Behavior.call_getWithResolvedTypevars_3305065273710852527(
                  SNodeOperations.cast(
                      overridingMethodParent, "jetbrains.mps.baseLanguage.structure.Classifier"),
                  returnType,
                  ancestor,
                  overridingMethod,
                  overridenMethod);
        } else if (SNodeOperations.isInstanceOf(
            overridingMethodParent,
            "jetbrains.mps.baseLanguage.structure.EnumConstantDeclaration")) {
          SNode enumClass =
              SNodeOperations.cast(
                  SNodeOperations.getParent(
                      SNodeOperations.cast(
                          overridingMethodParent,
                          "jetbrains.mps.baseLanguage.structure.EnumConstantDeclaration")),
                  "jetbrains.mps.baseLanguage.structure.EnumClass");
          SNode dummy =
              SConceptOperations.createNewNode(
                  "jetbrains.mps.baseLanguage.structure.AnonymousClass", null);
          SLinkOperations.setTarget(dummy, "classifier", enumClass, false);
          resolvedReturnType =
              Classifier_Behavior.call_getWithResolvedTypevars_3305065273710852527(
                  dummy, returnType, ancestor, overridingMethod, overridenMethod);
        } else {
          {
            MessageTarget errorTarget = new NodeMessageTarget();
            IErrorReporter _reporter_2309309498 =
                typeCheckingContext.reportTypeError(
                    overridingMethodParent,
                    "This node is not supposed to override methods",
                    "r:00000000-0000-4000-0000-011c895902c5(jetbrains.mps.baseLanguage.typesystem)",
                    "6207253590661761584",
                    null,
                    errorTarget);
          }
          return;
        }

        if (!(TypeChecker.getInstance()
            .getSubtypingManager()
            .isSubtype(
                SLinkOperations.getTarget(overridingMethod, "returnType", true),
                resolvedReturnType))) {
          {
            MessageTarget errorTarget = new NodeMessageTarget();
            IErrorReporter _reporter_2309309498 =
                typeCheckingContext.reportTypeError(
                    SLinkOperations.getTarget(overridingMethod, "returnType", true),
                    "method's return type is incompatible with overridden method ",
                    "r:00000000-0000-4000-0000-011c895902c5(jetbrains.mps.baseLanguage.typesystem)",
                    "2792291462223216211",
                    null,
                    errorTarget);
          }
          break;
        }
      }
    }
  }