code: ///////////////////////////////////////////////////////////////////////////////////////////////
  // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
  // Copyright (C) 2001-2023 the original author or authors.
  //
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  //
  // This library is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this library; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  ///////////////////////////////////////////////////////////////////////////////////////////////
  
  package com.puppycrawl.tools.checkstyle.internal.utils;
  
  import java.util.HashMap;
  import java.util.Map;
  
  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
  import com.puppycrawl.tools.checkstyle.api.DetailAST;
  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
  import com.puppycrawl.tools.checkstyle.xpath.RootNode;
  import net.sf.saxon.om.NodeInfo;
  
  /**
   * XpathIteratorUtil.
   *
   * @noinspection ClassOnlyUsedInOnePackage
   * @noinspectionreason ClassOnlyUsedInOnePackage - class is internal tool, and only used in testing
   */
  public final class XpathIteratorUtil {
  
      /**
       * Map from {@link NodeInfo#getLocalPart()} to {@link NodeInfo}.
       */
      private static final Map<String, NodeInfo> NODES_BY_LOCAL_PART = new HashMap<>();
  
      static {
          fillMap(new RootNode(createTree()));
      }
  
      private XpathIteratorUtil() {
      }
  
      /**
       * Finds node by its {@link NodeInfo#getLocalPart()} value.
       *
       * @param localPart text to be searched
       *
       * @return corresponding node
       */
      public static NodeInfo findNode(String localPart) {
          return NODES_BY_LOCAL_PART.get(localPart);
      }
  
      /**
       * Iterates Xpath tree nodes and fills the map.
       *
       * @param cur current {@link NodeInfo} node
       */
      private static void fillMap(NodeInfo cur) {
          NODES_BY_LOCAL_PART.put(cur.getLocalPart(), cur);
          for (NodeInfo node : cur.children()) {
              fillMap(node);
          }
      }
  
      /**
       * Creates AST tree for iteration tests and returns root.
       * <p>
       * PACKAGE_DEF -> package [1:0]
       * |--ANNOTATIONS -> ANNOTATIONS [1:8]
       *     `--ANNOTATION_DEF -> ANNOTATIONS [1:8]
       * `--CLASS_DEF -> CLASS_DEF [3:0]
       *     `--OBJBLOCK -> OBJBLOCK [3:19]
       *         |--LCURLY -> { [3:19]
       *         |--METHOD_DEF -> METHOD_DEF [4:4]
       *         |   |--PARAMETERS -> PARAMETERS [4:31]
       *         |   `--SLIST -> { [4:33]
       *         `--RCURLY -> } [8:0]
       * </p>
       *
       * @return {@link DetailAST} object.
       */
      private static DetailAST createTree() {
          final DetailAstImpl rootNode = createNode(TokenTypes.PACKAGE_DEF, 1, 0);
  
          final DetailAstImpl annotationsNode = createNode(rootNode, TokenTypes.ANNOTATIONS, 1, 8);
          createNode(annotationsNode, TokenTypes.ANNOTATION_DEF, 1, 8);
  
          final DetailAstImpl classDefNode = createNode(rootNode, TokenTypes.CLASS_DEF, 3, 0);
          final DetailAstImpl objblockNode = createNode(classDefNode, TokenTypes.OBJBLOCK, 3, 19);
          createNode(objblockNode, TokenTypes.LCURLY, 3, 19);
          final DetailAstImpl methodDefNode = createNode(objblockNode, TokenTypes.METHOD_DEF, 4, 4);
          createNode(objblockNode, TokenTypes.RCURLY, 8, 0);
  
          createNode(methodDefNode, TokenTypes.PARAMETERS, 4, 31);
          createNode(methodDefNode, TokenTypes.SLIST, 4, 33);
  
          return rootNode;
      }
  
      /**
       * Creates {@link DetailAstImpl} node with predefined parent.
       *
       * @param parent parent node
       * @param tokenType token type, see {@link TokenTypes}
       * @param lineNo line number
       * @param columnNo column number
       *
       * @return {@link DetailAstImpl} object.
       */
      private static DetailAstImpl createNode(DetailAstImpl parent, int tokenType, int lineNo,
                                              int columnNo) {
          final DetailAstImpl result = createNode(tokenType, lineNo, columnNo);
          parent.addChild(result);
          return result;
      }
  
      /**
       * Creates {@link DetailAstImpl} node.
       *
       * @param tokenType token type, see {@link TokenTypes}
       * @param lineNo line number
       * @param columnNo column number
       *
       * @return {@link DetailAstImpl} object.
       */
      private static DetailAstImpl createNode(int tokenType, int lineNo, int columnNo) {
          final DetailAstImpl result = new DetailAstImpl();
          result.setType(tokenType);
          result.setLineNo(lineNo);
          result.setColumnNo(columnNo);
          return result;
      }
  }
  