private void visitSwitchBlockSelector(PsiSwitchBlock switchBlock) {
      PsiExpression selector = deparenthesizeExpression(switchBlock.getExpression());
      if (selector instanceof PsiTypeCastExpression cast) {
        PsiExpression operand = cast.getOperand();
        if (operand != null) {
          PsiType opType = operand.getType();
          if (opType instanceof PsiClassType && PsiPrimitiveType.getUnboxedType(opType) == null && !opType.equalsToText(JAVA_LANG_STRING)) {
            PsiClass aClass = ((PsiClassType)opType).resolve();
            if (aClass != null && !aClass.isEnum()) {
              return;
            }
          }
          if (opType instanceof PsiPrimitiveType) {
            if (PsiUtil.isAvailable(JavaFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS, switchBlock)) {
              for (PsiElement branch : SwitchUtils.getSwitchBranches(switchBlock)) {
                // 14.11.1 A null case element is switch compatible with T if T is a reference type (JEP 427)
                if (branch instanceof PsiExpression expression && TypeConversionUtil.isNullType(expression.getType())) return;
                // 14.30.3 A type pattern that declares a pattern variable of a reference type U is
                // applicable at another reference type T if T is checkcast convertible to U (JEP 427)
                // There is no rule that says that a reference type applies to a primitive type
                if (branch instanceof PsiPattern) return;
              }
            }
            else if (PsiUtil.isAvailable(JavaFeature.PATTERNS_IN_SWITCH, switchBlock)) {
              boolean needToCheckCompleteness = switchBlock instanceof PsiSwitchExpression;
              boolean hasDefault = false;
              for (PsiElement branch : SwitchUtils.getSwitchBranches(switchBlock)) {
                // 14.11.1. A null case label element is compatible with e if the type of e is a reference type (JEP 406 and JEP 420)
                if (branch instanceof PsiExpression expression && TypeConversionUtil.isNullType(expression.getType())) return;
                needToCheckCompleteness |= branch instanceof PsiPattern;
                hasDefault |= branch instanceof PsiDefaultCaseLabelElement ||
                              branch instanceof PsiSwitchLabelStatementBase label && label.isDefaultCase();
              }
              if (needToCheckCompleteness && !hasDefault) return;
            }
          }
          if (opType != null) {
            PsiCodeBlock body = switchBlock.getBody();
            boolean hasInconvertibleLabel = false;
            if (body != null) {
              hasInconvertibleLabel = StreamEx.of(body.getStatements()).select(PsiSwitchLabelStatementBase.class)
                .map(PsiSwitchLabelStatementBase::getCaseLabelElementList)
                .nonNull().flatArray(PsiCaseLabelElementList::getElements)
                .select(PsiExpression.class)
                .map(PsiExpression::getType)
                .nonNull()
                .anyMatch(t -> !t.isConvertibleFrom(opType));
            }
            if (!hasInconvertibleLabel) {
              addIfNarrowing(cast, opType, null);
            }
          }
        }
      }
    }
private void visitSwitchBlockSelector(PsiSwitchBlock switchBlock)