private static void addNewLineToTag(CompositeElement tag, Project project) {
    LOG.assertTrue(tag != null && tag.getElementType() == DOC_TAG);
    ASTNode current = tag.getLastChildNode();
    while (current != null
        && current.getElementType() == DOC_COMMENT_DATA
        && isWhitespaceCommentData(current)) {
      current = current.getTreePrev();
    }
    if (current != null && current.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) return;
    final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(tag);
    final ASTNode newLine =
        Factory.createSingleLeafElement(
            DOC_COMMENT_DATA, "\n", 0, 1, treeCharTab, SharedImplUtil.getManagerByTree(tag));
    tag.addChild(newLine, null);

    ASTNode leadingWhitespaceAnchor = null;
    if (JavaCodeStyleSettingsFacade.getInstance(project).isJavaDocLeadingAsterisksEnabled()) {
      final TreeElement leadingAsterisk =
          Factory.createSingleLeafElement(
              DOC_COMMENT_LEADING_ASTERISKS,
              "*",
              0,
              1,
              treeCharTab,
              SharedImplUtil.getManagerByTree(tag));

      leadingWhitespaceAnchor =
          tag.addInternal(leadingAsterisk, leadingAsterisk, null, Boolean.TRUE);
    }

    final TreeElement commentData =
        Factory.createSingleLeafElement(
            DOC_COMMENT_DATA, " ", 0, 1, treeCharTab, SharedImplUtil.getManagerByTree(tag));
    tag.addInternal(commentData, commentData, leadingWhitespaceAnchor, Boolean.TRUE);
  }
  @Override
  public void deleteChildInternal(@NotNull ASTNode child) {
    if (child.getElementType() == DOC_TAG) {
      if (child.getTreeNext() == null || child.getTreeNext().getElementType() != DOC_TAG) {
        ASTNode prev = child.getTreePrev();
        while (prev != null && prev.getElementType() == DOC_COMMENT_DATA) {
          prev = prev.getTreePrev();
        }
        ASTNode next = child.getTreeNext();
        while (next != null
            && (next.getElementType() == DOC_COMMENT_DATA
                || next.getElementType() == WHITE_SPACE)) {
          next = next.getTreeNext();
        }

        if (prev != null
            && prev.getElementType() == DOC_COMMENT_LEADING_ASTERISKS
            && !(next instanceof PsiDocTag)) {
          ASTNode leadingAsterisk = prev;
          if (leadingAsterisk.getTreePrev() != null) {
            super.deleteChildInternal(leadingAsterisk.getTreePrev());
            super.deleteChildInternal(leadingAsterisk);
          }
        } else if (prev != null && prev.getElementType() == DOC_TAG) {
          final CompositeElement compositePrev = (CompositeElement) prev;
          final ASTNode lastPrevChild = compositePrev.getLastChildNode();
          ASTNode prevChild = lastPrevChild;
          while (prevChild != null && prevChild.getElementType() == DOC_COMMENT_DATA) {
            prevChild = prevChild.getTreePrev();
          }
          if (prevChild != null && prevChild.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) {
            ASTNode current = prevChild;
            while (current != null) {
              final ASTNode nextChild = current.getTreeNext();
              compositePrev.deleteChildInternal(current);
              current = nextChild;
            }
          }
        } else {
          next = child.getTreeNext();
          if (next != null && next.getElementType() == WHITE_SPACE) {
            next.getTreeParent().removeChild(next);
          }
        }
      }
    }
    super.deleteChildInternal(child);
  }
 private static void removeEndingAsterisksFromTag(CompositeElement tag) {
   ASTNode current = tag.getLastChildNode();
   while (current != null && current.getElementType() == DOC_COMMENT_DATA) {
     current = current.getTreePrev();
   }
   if (current != null && current.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) {
     final ASTNode prevWhiteSpace =
         TreeUtil.skipElementsBack(current.getTreePrev(), ElementType.JAVA_WHITESPACE_BIT_SET);
     ASTNode toBeDeleted = prevWhiteSpace.getTreeNext();
     while (toBeDeleted != null) {
       ASTNode next = toBeDeleted.getTreeNext();
       tag.deleteChildInternal(toBeDeleted);
       toBeDeleted = next;
     }
   }
 }