TreeElement addInternal(@NotNull TreeElement child, @Nullable ASTNode anchor, boolean before) throws IncorrectOperationException {
    if (anchor != null && child.getElementType() == XmlElementType.XML_TEXT) {
      XmlText psi = null;
      if (anchor.getPsi() instanceof XmlText) {
        psi = (XmlText)anchor.getPsi();
      }
      else {
        final ASTNode other = before ? anchor.getTreePrev() : anchor.getTreeNext();
        if (other != null && other.getPsi() instanceof XmlText) {
          before = !before;
          psi = (XmlText)other.getPsi();
        }
      }

      if (psi != null) {
        if (before) {
          psi.insertText(((XmlText)child.getPsi()).getValue(), 0);
        }
        else {
          psi.insertText(((XmlText)child.getPsi()).getValue(), psi.getValue().length());
        }
        return (TreeElement)psi.getNode();
      }
    }
    LOG.assertTrue(child.getPsi() instanceof XmlAttribute || child.getPsi() instanceof XmlTagChild);
    return child.getElementType() instanceof IXmlAttributeElementType ? insertAttribute(anchor, child, before) :
           anchor == null ? bodyInsert(child) :
           genericInsert(child, anchor, before);
  }
TreeElement addInternal(@NotNull TreeElement child, @Nullable ASTNode anchor, boolean before)