/**
   * 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;
  }