@Nullable
    private List<PatternVariableCandidate> tryToFindNestedSwitch(@NotNull PatternVariableCandidate previousCandidate,
                                                                 @NotNull Statement caseStatement,
                                                                 @NotNull Set<AssignmentExprent> usedAssignmentExprents,
                                                                 @NotNull VarTracker varTracker) {
      Set<AssignmentExprent> toAddAssignmentExprent = new HashSet<>();
      List<PatternVariableCandidate> defaultValue = new ArrayList<>();
      defaultValue.add(previousCandidate);

      Statement currentStatement = previousCandidate.getNextStatement();
      VBStyleCollection<Statement, Integer> currentStats = currentStatement.getStats();
      if (currentStats.isEmpty()) {
        return defaultValue;
      }
      SwitchStatement nestedSwitchStatement = null;
      if (!caseStatement.getLabelEdges().isEmpty()) {
        //example:
        //Sequence
        //  Switch
        //    case default
        //    case pattern
        //      initializers
        //  DoStatement
        //    DoStatement
        //      nested Switch
        Statement nextStatement = previousCandidate.getNextStatement();
        if (!(nextStatement instanceof SequenceStatement sequenceStatement && sequenceStatement.getStats().size() == 1 &&
              sequenceStatement.getStats().get(0) instanceof BasicBlockStatement && caseStatement.getLabelEdges().size() == 1)) {
          return defaultValue;
        }
        StatEdge edge = caseStatement.getLabelEdges().iterator().next();
        if (!(edge.getType() == EdgeType.BREAK && edge.getDestination() instanceof DoStatement upperDoStatement &&
              upperDoStatement.getConditionExprent() == null && upperDoStatement.getStats().size() == 1 &&
              upperDoStatement.getStats().get(0) instanceof DoStatement nestedDoStatement &&
              nestedDoStatement.getConditionExprent() == null && nestedDoStatement.getStats().size() == 1 &&
              nestedDoStatement.getStats().get(0) instanceof SwitchStatement switchStatement)) {
          return defaultValue;
        }
        if (!(caseStatement.getParent() instanceof SwitchStatement upperSwitchStatement &&
              upperSwitchStatement.getCaseStatements().size() == 2)) {
          return defaultValue;
        }
        int indexCurrentStat = upperSwitchStatement.getCaseStatements().indexOf(caseStatement);
        if (indexCurrentStat == -1) {
          return defaultValue;
        }
        int indexDefaultStatement = indexCurrentStat == 0 ? 1 : 0;
        if (!upperSwitchStatement.getCaseEdges()
          .get(indexDefaultStatement)
          .contains(upperSwitchStatement.getDefaultEdge())) {
          return defaultValue;
        }
        Statement defaultStatement = upperSwitchStatement.getCaseStatements().get(indexDefaultStatement);
        if (defaultStatement.getExprents() == null) {
          return defaultValue;
        }
        for (Exprent defaultExprent : defaultStatement.getExprents()) {
          if (defaultExprent instanceof AssignmentExprent assignmentExprent) {
            toAddAssignmentExprent.add(assignmentExprent);
          }
        }
        nestedSwitchStatement = switchStatement;
      }
      //current is switch
      else if (currentStats.get(0) instanceof SwitchStatement switchStatement) {
        nestedSwitchStatement = switchStatement;
      }
      else {
        if (currentStats.size() < 2) {
          return defaultValue;
        }
        if (!(currentStats.get(0) instanceof BasicBlockStatement)) {
          return defaultValue;
        }
        //Example:
        //Sequence
        //  BasicBlock
        //  Switch
        if (currentStats.get(1) instanceof SwitchStatement switchStatement) {
          nestedSwitchStatement = switchStatement;
        }
        //Example:
        //Sequence
        //  BasicBlock
        //  Do
        //    Switch
        if (currentStats.get(1) instanceof DoStatement doStatement && !doStatement.getStats().isEmpty() &&
            doStatement.getStats().get(0) instanceof SwitchStatement switchStatement) {
          nestedSwitchStatement = switchStatement;
        }
        //Example:
        //Sequence
        //  BasicBlock
        //  Do
        //    Sequence
        //      Switch
        if (currentStats.get(1) instanceof DoStatement doStatement && doStatement.getStats().size() == 1 &&
            doStatement.getStats().get(0) instanceof SequenceStatement sequenceStatement &&
            sequenceStatement.getStats().size() == 2 &&
            sequenceStatement.getStats().get(0) instanceof SwitchStatement newSwitchStatement) {
          nestedSwitchStatement = newSwitchStatement;
        }
        if (currentStats.get(1) instanceof DoStatement doStatement && doStatement.getStats().size() == 1 &&
            doStatement.getStats().get(0) instanceof DoStatement nestedDoStatement &&
            nestedDoStatement.getStats().size() == 1 &&
            nestedDoStatement.getStats().get(0) instanceof SwitchStatement newSwitchStatement) {
          nestedSwitchStatement = newSwitchStatement;
        }
      }

      if (nestedSwitchStatement == null) {
        return defaultValue;
      }
      if (!(nestedSwitchStatement.getHeadExprent() instanceof SwitchExprent switchExprent &&
            switchExprent.getValue() instanceof InvocationExprent invocationExprent)) {
        return defaultValue;
      }

      SwitchOnReferenceCandidate recognized =
        new JavacReferenceFinder(varTracker, myTypeVars, nestedSwitchStatement, invocationExprent).findCandidate();
      if (recognized == null) {
        return defaultValue;
      }
      VarExprent exprent = previousCandidate.getVarExprent();
      if (!(exprent instanceof RecordVarExprent currentRecordDeconstruction)) {
        return defaultValue;
      }
      RecordVarExprent component = currentRecordDeconstruction.getDirectComponent(recognized.myPreviousSelector.getInstance());
      if (component == null) {
        return defaultValue;
      }
      ArrayList<PatternVariableCandidate> candidates = new ArrayList<>();
      Map<Integer, String> classes = getMapCaseClasses(recognized.myPreviousSelector.getBootstrapArguments());
      for (FullCase fullCase : recognized.mySortedCasesFromRoot) {
        List<Exprent> fullCaseExprents = fullCase.exprents;
        Statement nestedStatement = fullCase.statement;
        List<StatEdge> edges = nestedStatement.getSuccessorEdges(EdgeType.DIRECT_ALL);
        if (edges.size() == 1) {
          StatEdge edge = edges.get(0);
          //not accurate, but it is hard to track all labels here
          if ((edge.getType() == EdgeType.CONTINUE || edge.getType() == EdgeType.BREAK) &&
              nestedStatement.getExprents() != null) {
            for (Exprent nestedExprent : nestedStatement.getExprents()) {
              if (nestedExprent instanceof AssignmentExprent assignmentExprent &&
                  assignmentExprent.getLeft() instanceof VarExprent left &&
                  myTypeVars.contains(left)) {
                toAddAssignmentExprent.add(assignmentExprent);
              }
            }
          }
        }
        List<PatternContainer.PatternStatement> nestedPatterns = recognized.myPatternContainer.getPatterns(nestedStatement);
        //process literals
        if (nestedPatterns == null || nestedPatterns.isEmpty()) {
          if (fullCaseExprents.size() == 2) {
            //delete null
            if (fullCaseExprents.get(0) instanceof ConstExprent constExprent && constExprent.getIntValue() == -1) {
              fullCaseExprents.remove(fullCaseExprents.get(0));
            }
          }
          if (fullCaseExprents.size() != 1) {
            return null;
          }
          if (fullCaseExprents.get(0) == null) {
            continue;
          }
          if (!(fullCaseExprents.get(0) instanceof ConstExprent constExprent)) {
            return null;
          }
          String newClassName = classes.get(constExprent.getIntValue());
          if (newClassName == null) {
            return null;
          }
          RecordVarExprent copy = currentRecordDeconstruction.copy();
          RecordVarExprent toReplace = copy.getDirectComponent(recognized.myPreviousSelector.getInstance());
          if (toReplace == null) {
            return null;
          }
          toReplace.setVarType(new VarType(newClassName));
          PatternVariableCandidate nestedPatternVariableCandidate =
            new PatternVariableCandidate(copy, fullCase.statement(), previousCandidate.getUsedIfStatement(),
                                         previousCandidate.getTempVarAssignments(), previousCandidate.getCleaner());
          candidates.add(nestedPatternVariableCandidate);
        }
        else {
          //process patterns
          for (PatternContainer.PatternStatement nestedPattern : nestedPatterns) {
            RecordVarExprent copy;
            if (nestedPattern.variable instanceof RecordVarExprent recordVarExprent) {
              copy = recordVarExprent;
            }
            else {
              if (nestedPattern.variable == null) {
                return null;
              }
              copy = currentRecordDeconstruction.copy();
              RecordVarExprent toReplace = copy.getDirectComponent(recognized.myPreviousSelector.getInstance());
              if (toReplace == null) {
                return null;
              }
              if (!toReplace.copyFrom(nestedPattern.variable)) {
                return null;
              }
            }
            PatternVariableCandidate nestedPatternVariableCandidate =
              new PatternVariableCandidate(copy, nestedPattern.caseStatement, previousCandidate.getUsedIfStatement(),
                                           previousCandidate.getTempVarAssignments(), previousCandidate.getCleaner());
            nestedPatternVariableCandidate.setGuards(nestedPattern.guard);
            candidates.add(nestedPatternVariableCandidate);
          }
        }
      }

      if (!candidates.isEmpty()) {
        candidates.get(0).getTempAssignments().addAll(recognized.myTempVarAssignments);
      }
      usedAssignmentExprents.addAll(recognized.myUsedTypeVarAssignments);
      usedAssignmentExprents.addAll(toAddAssignmentExprent);
      myUsedSwitch.add(nestedSwitchStatement);
      return candidates;
    }
@Nullable
    private List<PatternVariableCandidate> tryToFindNestedSwitch(@NotNull PatternVariableCandidate previousCandidate,
                                                                 @NotNull Statement caseStatement,
                                                                 @NotNull Set<AssignmentExprent> usedAssignmentExprents,
                                                                 @NotNull VarTracker varTracker)