private static boolean switchStatementMayCompleteNormally(@NotNull PsiSwitchStatement switchStatement, @Nullable PsiMethod method) {
    if (statementIsBreakTarget(switchStatement)) {
      return true;
    }
    final PsiExpression selectorExpression = switchStatement.getExpression();
    if (selectorExpression == null) {
      return true;
    }
    final PsiType selectorType = selectorExpression.getType();
    if (selectorType == null) {
      return true;
    }
    final PsiCodeBlock body = switchStatement.getBody();
    if (body == null) {
      return true;
    }
    final PsiStatement[] statements = body.getStatements();
    if (statements.length == 0) {
      return true;
    }
    int numCases = 0;
    boolean hasDefaultCase = false, hasUnconditionalPattern = false;
    for (PsiStatement statement : statements) {
      if (statement instanceof PsiSwitchLabelStatementBase switchLabelStatement) {
        if (statement instanceof PsiSwitchLabelStatement) {
          numCases++;
        }
        if (hasDefaultCase || hasUnconditionalPattern) {
          continue;
        }
        if (switchLabelStatement.isDefaultCase()) {
          hasDefaultCase = true;
          continue;
        }
        // this information doesn't exist in spec draft (14.22) for pattern in switch as expected
        // but for now javac considers the switch statement containing at least either case default label element or an unconditional pattern "incomplete normally"
        PsiCaseLabelElementList labelElementList = switchLabelStatement.getCaseLabelElementList();
        if (labelElementList == null) {
          continue;
        }
        for (PsiCaseLabelElement labelElement : labelElementList.getElements()) {
          if (labelElement instanceof PsiDefaultCaseLabelElement) {
            hasDefaultCase = true;
          }
          else if (labelElement instanceof PsiPattern) {
            hasUnconditionalPattern = JavaPsiPatternUtil.isUnconditionalForType(labelElement, selectorType);
          }
        }
      }
      else if (statement instanceof final PsiBreakStatement breakStatement && breakStatement.getLabelIdentifier() == null) {
        return true;
      }
    }
    // todo actually there is no information about an impact of enum constants on switch statements being complete normally in spec (Unreachable statements)
    // todo comparing to javac that produces some false-negative highlighting in enum switch statements containing all possible constants
    final boolean isEnum = isEnumSwitch(switchStatement);
    if (!hasDefaultCase && !hasUnconditionalPattern && !isEnum) {
      return true;
    }
    if (!hasDefaultCase && !hasUnconditionalPattern) {
      final PsiClass aClass = ((PsiClassType)selectorType).resolve();
      if (aClass == null) {
        return true;
      }
      if (!hasChildrenOfTypeCount(aClass, numCases, PsiEnumConstant.class)) {
        return true;
      }
    }
    // todo replace the code and comments below with the method that helps to understand whether
    // todo we need to check every statement or only the last statement in the code block
    // 14.22. Unreachable Statements
    // We need to check every rule's body not just the last one if the switch block includes the switch rules
    boolean isLabeledRuleSwitch = statements[0] instanceof PsiSwitchLabeledRuleStatement;
    if (isLabeledRuleSwitch) {
      for (PsiStatement statement : statements) {
        if (statementMayCompleteNormally(statement, method)) {
          return true;
        }
      }
      return false;
    }
    return statementMayCompleteNormally(statements[statements.length - 1], method);
  }
private static boolean switchStatementMayCompleteNormally(@NotNull PsiSwitchStatement switchStatement, @Nullable PsiMethod method)