@Nullable
      @Override
      public SwitchOnStringCandidate recognize(@NotNull SwitchStatement switchStatement, @NotNull InvocationExprent switchSelector) {
        if (!switchSelector.isInstanceCall(ClassNameConstants.JAVA_LANG_STRING, "hashCode", 0)) return null;
        Set<Object> realCaseValueHashCodes = findRealCaseValuesHashCodes(switchStatement);
        Exprent switchSelectorQualifier = switchSelector.getInstance();
        Map<Integer, String> mappedCaseLabelValues = new HashMap<>();
        Map<Integer, IfStatement> ifBodyStatements = new HashMap<>();
        VarExprent tempVar = null;
        for (Statement statement : switchStatement.getCaseStatements()) {
          if (statement.type != StatementType.IF) {
            Statement defaultStatement = switchStatement.getDefaultEdge().getDestination();
            if (defaultStatement != statement) return null;
            continue;
          }
          Exprent tempSwitchSelectorQualifier = switchSelectorQualifier;
          if (switchSelectorQualifier.type == Exprent.EXPRENT_ASSIGNMENT) {
            tempSwitchSelectorQualifier = ((AssignmentExprent)switchSelectorQualifier).getLeft();
          }
          else if (switchSelectorQualifier.type == Exprent.EXPRENT_CONST && switchStatement.getFirst().getExprents() != null) {
            // Ecj inlines compile constants, so we try to find a temp variable assigned to the same const value.
            // It should be in the first basic block.
            Exprent finalSwitchSelectorQualifier = switchSelectorQualifier;
            tempSwitchSelectorQualifier = switchStatement.getFirst().getExprents().stream()
              .filter(exprent -> exprent instanceof AssignmentExprent)
              .map(exprent -> (AssignmentExprent)exprent)
              .filter(exprent -> exprent.getRight().equals(finalSwitchSelectorQualifier))
              .map(AssignmentExprent::getLeft)
              .findFirst()
              .orElse(null);
            if (tempSwitchSelectorQualifier == null) return null;
          }
          if (tempVar != null && !tempVar.equals(tempSwitchSelectorQualifier)) return null;
          tempVar = (VarExprent)tempSwitchSelectorQualifier;
          IfStatement ifStatement = (IfStatement)statement;
          String caseLabelValue = findRealCaseValue(ifStatement, tempVar);
          if (caseLabelValue == null) return null;
          int caseLabelHash = caseLabelValue.hashCode();
          if (!realCaseValueHashCodes.remove(caseLabelHash)) return null;
          mappedCaseLabelValues.put(caseLabelHash, caseLabelValue);
          ifBodyStatements.put(caseLabelHash, ifStatement);
        }
        if (tempVar == null || !realCaseValueHashCodes.isEmpty()) return null;
        if (switchSelectorQualifier instanceof AssignmentExprent) {
          switchSelectorQualifier = ((AssignmentExprent)switchSelectorQualifier).getRight();
        }
        return new SwitchOnStringCandidate.EcjSwitchCandidate(switchStatement, switchSelectorQualifier, tempVar, ifBodyStatements,
                                                              mappedCaseLabelValues);
      }
@Nullable
      @Override
      public SwitchOnStringCandidate recognize(@NotNull SwitchStatement switchStatement, @NotNull InvocationExprent switchSelector)