@Nullable
    private Root getRoot() {
      Statement first = myRootSwitchStatement.getFirst();
      if (first == null) {
        return null;
      }
      List<Exprent> firstExprents = first.getExprents();

      DoStatement doParentStatement = null;

      //possible structure (only for nested switch):
      //SequenceStatement
      //  ....
      //  Basic
      //  DoStatement
      //    DoStatement
      //      Switch
      if (myVarTracker != null && myRootSwitchStatement.getParent() instanceof DoStatement nestedDoStatement &&
          nestedDoStatement.getConditionExprent() == null &&
          nestedDoStatement.getParent() instanceof DoStatement upperDoStatement &&
          upperDoStatement.getConditionExprent() == null &&
          upperDoStatement.getParent() instanceof SequenceStatement sequenceStatement &&
          sequenceStatement.getStats().size() >= 2 && sequenceStatement.getStats().getLast() == upperDoStatement &&
          sequenceStatement.getStats().get(sequenceStatement.getStats().size() - 2) instanceof BasicBlockStatement basicBlockStatement) {
        firstExprents = basicBlockStatement.getExprents();
        first = basicBlockStatement;
        doParentStatement = nestedDoStatement;
      }
      //possible structure (only for nested switch):
      //SequenceStatement
      //  Switch
      //    default
      //    case
      //  DoStatement
      //    DoStatement
      //      Switch
      else if (myVarTracker != null && myRootSwitchStatement.getParent() instanceof DoStatement nestedDoStatement &&
               nestedDoStatement.getConditionExprent() == null &&
               nestedDoStatement.getParent() instanceof DoStatement upperDoStatement &&
               upperDoStatement.getConditionExprent() == null &&
               upperDoStatement.getParent() instanceof SequenceStatement sequenceStatement &&
               sequenceStatement.getStats().size() == 2 && sequenceStatement.getStats().get(1) == upperDoStatement &&
               sequenceStatement.getStats().get(0) instanceof SwitchStatement upperSwitchStatement &&
               upperSwitchStatement.getCaseStatements().size() == 2) {
        int indexDefault = upperSwitchStatement.getCaseEdges().get(0).contains(upperSwitchStatement.getDefaultEdge()) ? 0 :
                           (upperSwitchStatement.getCaseEdges().get(1).contains(upperSwitchStatement.getDefaultEdge()) ? 1 : -1);
        if (indexDefault == -1) {
          return null;
        }
        int other = indexDefault == 0 ? 1 : 0;
        Statement statement = upperSwitchStatement.getCaseStatements().get(other);
        if (statement.getStats().isEmpty()) {
          return null;
        }

        Statement last = statement.getStats().getLast();
        firstExprents = last.getExprents();
        first = last;
        doParentStatement = nestedDoStatement;
      }

      //possible structure (main case):
      //SequenceStatement
      //  ....
      //  BasicBlockStatement
      //    exprents with init values
      //  DoStatement
      //    SwitchStatement
      //  ....
      else if (firstExprents == null || firstExprents.stream().noneMatch(t -> t instanceof AssignmentExprent)) {
        Statement parent = myRootSwitchStatement.getParent();
        DoStatement doStatement = null;
        if (parent instanceof DoStatement) {
          doStatement = (DoStatement)parent;
        }
        if (doStatement == null && myRootSwitchStatement.getParent().getParent() instanceof DoStatement nextStatement) {
          doStatement = nextStatement;
        }
        if (doStatement == null ||
            doStatement.getLoopType() != DoStatement.LoopType.DO ||
            doStatement.getStats().size() != 1 ||
            !(doStatement.getParent() instanceof SequenceStatement upperStatement) ||
            upperStatement.getExprents() != null) {
          return null;
        }
        VBStyleCollection<Statement, Integer> upperStatementStats = upperStatement.getStats();
        int indexOfDo = upperStatementStats.indexOf(doStatement);
        if (indexOfDo == -1 || indexOfDo == 0) {
          return null;
        }
        if (upperStatementStats.get(indexOfDo) == doStatement &&
            upperStatementStats.get(indexOfDo - 1) instanceof BasicBlockStatement basicBlockStatement &&
            basicBlockStatement.getStats().isEmpty() &&
            basicBlockStatement.getExprents() != null &&
            !basicBlockStatement.getExprents().isEmpty()) {
          firstExprents = basicBlockStatement.getExprents();
          doParentStatement = doStatement;
          first = basicBlockStatement;
        }
        //if previous is CatchStatement and initializers are inside CatchStatement
        else if (upperStatementStats.get(indexOfDo) == doStatement &&
                 upperStatementStats.get(indexOfDo - 1) instanceof CatchStatement catchStatement &&
                 catchStatement.getStats().size() >= 2 &&
                 catchStatement.getStats().get(1).getExprents() != null &&
                 !Objects.requireNonNull(catchStatement.getStats().get(1).getExprents()).isEmpty()) {
          firstExprents = catchStatement.getStats().get(1).getExprents();
          doParentStatement = doStatement;
          first = catchStatement.getStats().get(1);
        }
        else {
          return null;
        }
      }

      //check that this doParentStatement is not refered outside
      if (doParentStatement != null) {
        for (StatEdge edge : doParentStatement.getLabelEdges()) {
          if (edge.labeled && edge.explicit) {
            Statement source = edge.getSource();
            if (myRootSwitchStatement.containsStatement(source)) {
              continue;
            }
            Statement parent = myRootSwitchStatement.getParent();
            if (!(parent instanceof SequenceStatement sequenceStatement && sequenceStatement.getStats().size() == 2)) {
              return null;
            }
            int index = sequenceStatement.getStats().indexOf(myRootSwitchStatement);
            if (index != 0) {
              return null;
            }
            if (!(sequenceStatement.getStats().get(1) instanceof DoStatement firstDo &&
                  firstDo.getStats().size() == 1 && firstDo.getStats().get(0) instanceof DoStatement nestedDo)) {
              return null;
            }
            if (nestedDo.containsStatement(source)) {
              continue;
            }
            return null;
          }
        }
      }
      return new Root(first, firstExprents, doParentStatement);
    }
@Nullable
    private Root getRoot()