@Override
  public void visitForStatement(ForStatementTree tree) {
    scan(tree.init());
    scan(tree.condition());

    currentLoopCounters = new HashSet<>();
    inUpdate = true;
    scan(tree.update());
    inUpdate = false;

    enterLoopBody();
    scan(tree.statement());
    leaveLoopBody();
  }
  @Override
  public void visitForStatement(ForStatementTree tree) {
    newBlockScope(tree);

    skipBlock(tree.statement());
    super.visitForStatement(tree);

    leaveScope();
  }
  private static boolean hasPredecessorInsideLoopBody(
      CfgBranchingBlock conditionBlock, IterationStatementTree loopTree) {
    for (CfgBlock loopPredecessor : conditionBlock.predecessors()) {
      List<Tree> predecessorElements = loopPredecessor.elements();
      Tree predecessorLastElement = predecessorElements.get(predecessorElements.size() - 1);

      if (loopTree.is(Kind.FOR_STATEMENT)) {
        ForStatementTree forTree = (ForStatementTree) loopTree;
        if (forTree.update() != null && forTree.update().equals(predecessorLastElement)) {
          return !loopPredecessor.predecessors().isEmpty();
        }
      }

      StatementTree loopBody = loopTree.statement();
      if (isDescendant(predecessorLastElement, loopBody)) {
        return true;
      }
    }
    return false;
  }