/**
  * Creates child nodes for each node from 'nodes' array.
  *
  * @param parseTreeParent original ParseTree parent node
  * @param nodes array of JavadocNodeImpl nodes
  */
 private void insertChildrenNodes(final JavadocNodeImpl[] nodes, ParseTree parseTreeParent) {
   for (int i = 0; i < nodes.length; i++) {
     final JavadocNodeImpl currentJavadocNode = nodes[i];
     final ParseTree currentParseTreeNodeChild = parseTreeParent.getChild(i);
     final JavadocNodeImpl[] subChildren =
         createChildrenNodes(currentJavadocNode, currentParseTreeNodeChild);
     currentJavadocNode.setChildren((DetailNode[]) subChildren);
   }
 }
  /**
   * Creates root JavadocNodeImpl node base on ParseTree root node.
   *
   * @param parseTreeNode ParseTree root node
   * @return root Javadoc node
   */
  private JavadocNodeImpl createRootJavadocNode(ParseTree parseTreeNode) {
    final JavadocNodeImpl rootJavadocNode = createJavadocNode(parseTreeNode, null, -1);

    final int childCount = parseTreeNode.getChildCount();
    final JavadocNodeImpl[] children = new JavadocNodeImpl[childCount];

    for (int i = 0; i < childCount; i++) {
      final JavadocNodeImpl child =
          createJavadocNode(parseTreeNode.getChild(i), rootJavadocNode, i);
      children[i] = child;
    }
    rootJavadocNode.setChildren((DetailNode[]) children);
    return rootJavadocNode;
  }
 /**
  * Creates JavadocNodeImpl node on base of ParseTree node.
  *
  * @param parseTree ParseTree node
  * @param parent DetailNode that will be parent of new node
  * @param index child index that has new node
  * @return JavadocNodeImpl node on base of ParseTree node.
  */
 private JavadocNodeImpl createJavadocNode(ParseTree parseTree, DetailNode parent, int index) {
   final JavadocNodeImpl node = new JavadocNodeImpl();
   node.setText(parseTree.getText());
   node.setColumnNumber(getColumn(parseTree));
   node.setLineNumber(getLine(parseTree) + blockCommentLineNumber);
   node.setIndex(index);
   node.setType(getTokenType(parseTree));
   node.setParent(parent);
   node.setChildren((DetailNode[]) new JavadocNodeImpl[parseTree.getChildCount()]);
   return node;
 }
  /**
   * Converts ParseTree (that is generated by ANTLRv4) to DetailNode tree.
   *
   * @param parseTreeNode root node of ParseTree
   * @return root of DetailNode tree
   */
  private DetailNode convertParseTreeToDetailNode(ParseTree parseTreeNode) {
    final JavadocNodeImpl rootJavadocNode = createRootJavadocNode(parseTreeNode);

    JavadocNodeImpl currentJavadocParent = rootJavadocNode;
    ParseTree parseTreeParent = parseTreeNode;

    while (currentJavadocParent != null) {
      // remove unnecessary children tokens
      if (currentJavadocParent.getType() == JavadocTokenTypes.TEXT) {
        currentJavadocParent.setChildren((DetailNode[]) JavadocNodeImpl.EMPTY_DETAIL_NODE_ARRAY);
      }

      final JavadocNodeImpl[] children = (JavadocNodeImpl[]) currentJavadocParent.getChildren();

      insertChildrenNodes(children, parseTreeParent);

      if (children.length > 0) {
        currentJavadocParent = children[0];
        parseTreeParent = parseTreeParent.getChild(0);
      } else {
        JavadocNodeImpl nextJavadocSibling =
            (JavadocNodeImpl) JavadocUtils.getNextSibling(currentJavadocParent);

        ParseTree nextParseTreeSibling = getNextSibling(parseTreeParent);

        if (nextJavadocSibling == null) {
          JavadocNodeImpl tempJavadocParent = (JavadocNodeImpl) currentJavadocParent.getParent();

          ParseTree tempParseTreeParent = parseTreeParent.getParent();

          while (nextJavadocSibling == null && tempJavadocParent != null) {

            nextJavadocSibling = (JavadocNodeImpl) JavadocUtils.getNextSibling(tempJavadocParent);

            nextParseTreeSibling = getNextSibling(tempParseTreeParent);

            tempJavadocParent = (JavadocNodeImpl) tempJavadocParent.getParent();
            tempParseTreeParent = tempParseTreeParent.getParent();
          }
        }
        currentJavadocParent = nextJavadocSibling;
        parseTreeParent = nextParseTreeSibling;
      }
    }

    return rootJavadocNode;
  }