@Override
  public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
    boolean needToAddNewline = false;
    if (last.getElementType() == DOC_TAG && first.getElementType() == DOC_TAG) {
      if (anchor == null) {
        anchor = getLastChildNode(); // this is a '*/'
        ASTNode prevBeforeWS = TreeUtil.skipElementsBack(anchor.getTreePrev(), TokenSet.WHITE_SPACE);
        if (prevBeforeWS != null) {
          anchor = prevBeforeWS;
          before = Boolean.FALSE;
        }
        else {
          before = Boolean.TRUE;
        }
        needToAddNewline = true;
      }

      if (anchor.getElementType() != DOC_TAG) {
        if (nodeOnSameLineWithCommentStartBlock(anchor) ||
            !nodeIsNextAfterAsterisks(anchor) ||
            !docTagEndsWithLineFeedAndAsterisks(first)) {
          CharTable charTable = SharedImplUtil.findCharTableByTree(this);
          PsiManager psiManager = getManager();

          if (JavaFileCodeStyleFacade.forContext(getContainingFile()).isJavaDocLeadingAsterisksEnabled()) {
            TreeElement newLine = Factory.createSingleLeafElement(TokenType.WHITE_SPACE, "\n ", charTable, psiManager);
            TreeElement leadingAsterisk = Factory.createSingleLeafElement(DOC_COMMENT_LEADING_ASTERISKS, "*", charTable, psiManager);
            TreeElement commentData = Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", charTable, psiManager);
            newLine.getTreeParent().addChild(leadingAsterisk);
            newLine.getTreeParent().addChild(commentData);
            super.addInternal(newLine, commentData, anchor, Boolean.FALSE);
            anchor = commentData;
          }
          else {
            TreeElement newLine = Factory.createSingleLeafElement(TokenType.WHITE_SPACE, "\n ", charTable, psiManager);
            anchor = super.addInternal(newLine, newLine, anchor, Boolean.FALSE);
          }
          before = Boolean.FALSE;
        }
      }
      else {
        needToAddNewline = true;
      }
    }

    if (before) {
      anchor.getTreeParent().addChildren(first, last.getTreeNext(), anchor);
    }
    else {
      anchor.getTreeParent().addChildren(first, last.getTreeNext(), anchor.getTreeNext());
    }

    if (needToAddNewline) {
      if (first.getTreePrev() != null && first.getTreePrev().getElementType() == DOC_TAG) {
        addNewLineToTag((CompositeElement)first.getTreePrev(), getContainingFile(), getManager());
      }
      if (first.getTreeNext() != null && first.getTreeNext().getElementType() == DOC_TAG) {
        addNewLineToTag((CompositeElement)first, getContainingFile(), getManager());
      }
      else {
        removeEndingAsterisksFromTagIfNeeded((CompositeElement)first);
      }
    }

    return first;
  }
@Override
  public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before)