private void processSwitch(@NotNull PsiSwitchBlock switchBlock) {
    PsiExpression selector = PsiUtil.skipParenthesizedExprDown(switchBlock.getExpression());
    DfaVariableValue expressionValue = null;
    boolean syntheticVar = true;
    PsiType targetType = null;
    if (selector != null) {
      targetType = selector.getType();
      DfaValue selectorValue = JavaDfaValueFactory.getExpressionDfaValue(myFactory, selector);
      if (selectorValue instanceof DfaVariableValue dfaVar && !dfaVar.isFlushableByCalls()) {
        expressionValue = dfaVar;
        syntheticVar = false;
      }
      selector.accept(this);
      if (syntheticVar) {
        expressionValue = createTempVariable(targetType);
        addInstruction(new SimpleAssignmentInstruction(null, expressionValue));
      }
      addInstruction(new PopInstruction());
    }

    PsiCodeBlock body = switchBlock.getBody();

    if (body != null) {
      PsiStatement[] statements = body.getStatements();
      PsiElement defaultLabel = null;
      for (PsiStatement statement : statements) {
        if (!(statement instanceof PsiSwitchLabelStatementBase psiLabelStatement)) {
          continue;
        }
        if (psiLabelStatement.isDefaultCase()) {
          defaultLabel = psiLabelStatement;
          continue;
        }
        try {
          PsiExpression guard = psiLabelStatement.getGuardExpression();
          ControlFlowOffset offset = getStartOffset(statement);
          ControlFlowOffset targetOffset = guard == null ? offset : new DeferredOffset();
          PsiCaseLabelElementList labelElementList = psiLabelStatement.getCaseLabelElementList();
          if (labelElementList != null) {
            for (PsiCaseLabelElement labelElement : labelElementList.getElements()) {
              if (labelElement instanceof PsiDefaultCaseLabelElement) {
                defaultLabel = labelElement;
                continue;
              }
              if (labelElement instanceof PsiExpression expr) {
                boolean enumConstant = expr instanceof PsiReferenceExpression ref &&
                                       ref.resolve() instanceof PsiEnumConstant;
                if (expressionValue != null && (enumConstant || PsiUtil.isConstantExpression(expr))) {
                  if (PsiPrimitiveType.getUnboxedType(targetType) == null) {
                    addInstruction(new JvmPushInstruction(expressionValue, null));
                    expr.accept(this);
                    addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr)));
                    addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE));
                  }
                  else {
                    addInstruction(new JvmPushInstruction(expressionValue, null));
                    DeferredOffset condGotoOffset = new DeferredOffset();
                    addInstruction(new ConditionalGotoInstruction(condGotoOffset, DfTypes.NULL));

                    addInstruction(new JvmPushInstruction(expressionValue, null));
                    generateBoxingUnboxingInstructionFor(selector, PsiPrimitiveType.getUnboxedType(targetType));
                    expr.accept(this);
                    addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr)));
                    DeferredOffset gotoOffset = new DeferredOffset();
                    addInstruction(new GotoInstruction(gotoOffset));

                    PushValueInstruction pushValInstr = new PushValueInstruction(DfTypes.FALSE, new JavaSwitchLabelTakenAnchor(expr));
                    addInstruction(pushValInstr);
                    condGotoOffset.setOffset(pushValInstr.getIndex());

                    ConditionalGotoInstruction exitFromSwitchBranchInstr = new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE);
                    addInstruction(exitFromSwitchBranchInstr);
                    gotoOffset.setOffset(exitFromSwitchBranchInstr.getIndex());
                  }
                }
                else if (expressionValue != null && ExpressionUtils.isNullLiteral(expr)) {
                  addInstruction(new JvmPushInstruction(expressionValue, null));
                  expr.accept(this);
                  addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr)));
                  addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE));
                }
                else {
                  pushUnknown();
                  addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE));
                }
              }
              else if (expressionValue != null && targetType != null) {
                if (labelElement instanceof PsiPattern pattern) {
                  processPatternInSwitch(pattern, expressionValue, targetType);
                  addInstruction(new ResultOfInstruction(new JavaSwitchLabelTakenAnchor(pattern)));
                  addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE));
                }
              }
            }
          }
          if (guard != null) {
            DeferredOffset endGuardOffset = new DeferredOffset();
            addInstruction(new GotoInstruction(endGuardOffset));
            ((DeferredOffset)targetOffset).setOffset(getInstructionCount());
            guard.accept(this);
            addInstruction(new ResultOfInstruction(new JavaSwitchLabelTakenAnchor(guard)));
            addInstruction(new ConditionalGotoInstruction(offset, DfTypes.TRUE));
            endGuardOffset.setOffset(getInstructionCount());
          }
        }
        catch (IncorrectOperationException e) {
          LOG.error(e);
        }
      }

      if (defaultLabel != null) {
        addInstruction(new GotoInstruction(getStartOffset(defaultLabel)));
      }
      else if (switchBlock instanceof PsiSwitchExpression) {
        addInstruction(new ThrowInstruction(myTrapTracker.transferValue("java.lang.IncompatibleClassChangeError"), null));
      }
      else {
        addInstruction(new GotoInstruction(getEndOffset(body)));
      }

      body.accept(this);
    }

    if (syntheticVar && expressionValue != null) {
      addInstruction(new FlushVariableInstruction(expressionValue));
    }
  }
private void processSwitch(@NotNull PsiSwitchBlock switchBlock)