/**
   * Check there is exactly one space around "as" keyword and "=>" punctuator in foreach statement.
   */
  private void checkForeachStatement(
      TokenVisitor tokenVisitor,
      ForEachStatementTree foreachLoop,
      SyntaxToken asKeyword,
      @Nullable SyntaxToken doubleArrow) {

    boolean isSpaceCorrectAs = isExactlyOneSpaceAround(tokenVisitor, asKeyword);
    boolean isSpaceCorrectDoubleArrow =
        doubleArrow == null || isExactlyOneSpaceAround(tokenVisitor, doubleArrow);

    String messageDetail = null;

    if (!isSpaceCorrectAs && isSpaceCorrectDoubleArrow) {
      messageDetail = "\"as\"";

    } else if (isSpaceCorrectAs && !isSpaceCorrectDoubleArrow) {
      messageDetail = "\"=>\"";

    } else if (!isSpaceCorrectAs && !isSpaceCorrectDoubleArrow) {
      messageDetail = "\"as\" and \"=>\"";
    }

    if (messageDetail != null) {
      check.reportIssue(String.format(FOREACH_MESSAGE, messageDetail), foreachLoop);
    }
  }
  /**
   * Check that there is exactly one space between a control structure keyword and a opening
   * parenthesis or curly brace.
   */
  private void checkSpaceBetweenKeywordAndNextNode(SyntaxToken keyword, SyntaxToken nextToken) {
    if (TokenUtils.isType(nextToken, PHPPunctuator.LCURLYBRACE, PHPPunctuator.LPARENTHESIS)
        && TokenUtils.isOnSameLine(keyword, nextToken)) {
      int nbSpace = TokenUtils.getNbSpaceBetween(keyword, nextToken);

      if (nbSpace != 1) {
        String endMessage =
            String.format(
                CONTROL_STRUCTURES_KEYWORD_MESSAGE,
                keyword.text(),
                TokenUtils.isType(nextToken, PHPPunctuator.LPARENTHESIS)
                    ? "parenthesis."
                    : "curly brace.");
        check.reportIssue(TokenUtils.buildIssueMsg(nbSpace, endMessage), keyword);
      }
    }
  }
  /** Check there is exactly one space after each ";" in for statement. */
  private void checkSpaceForStatement(Tree tree) {
    Iterator<Tree> iterator = ((PHPTree) tree).childrenIterator();
    Tree next;
    Tree previous = null;

    while (iterator.hasNext()) {
      next = iterator.next();

      if (isSemicolon(previous)) {
        SyntaxToken semicolonToken = (SyntaxToken) previous;
        SyntaxToken nextToken = ((PHPTree) next).getFirstToken();
        int nbSpace = TokenUtils.getNbSpaceBetween(semicolonToken, nextToken);

        if (nbSpace != 1 && TokenUtils.isOnSameLine(semicolonToken, nextToken)) {
          check.reportIssue(FOR_SEMICOLON_MESSAGE, tree);
          break;
        }
      }

      previous = next;
    }
  }