protected TreeElement bodyInsert(TreeElement child) {
    final ASTNode anchor = expandTag();
    if (child.getElementType() == XmlElementType.XML_TAG) {
      // compute where to insert tag according to DTD or XSD
      final XmlTag[] subTags = myTag.getSubTags();
      XmlElementDescriptor parentDescriptor = myTag.getDescriptor();
      final PsiElement declaration = parentDescriptor != null ? parentDescriptor.getDeclaration() : null;
      // filtering out generated dtds
      if (declaration != null &&
          declaration.getContainingFile() != null &&
          declaration.getContainingFile().isPhysical() &&
          subTags.length > 0) {
        final XmlElementDescriptor[] childElementDescriptors = parentDescriptor.getElementsDescriptors(myTag);
        int subTagNum = -1;
        for (final XmlElementDescriptor childElementDescriptor : childElementDescriptors) {
          final String childElementName = childElementDescriptor.getName();
          while (subTagNum < subTags.length - 1 && subTags[subTagNum + 1].getName().equals(childElementName)) {
            subTagNum++;
          }
          ASTNode startTagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(child);
          if (startTagName != null && childElementName.equals(startTagName.getText())) {
            // insert child just after anchor
            // insert into the position specified by index
            if (subTagNum >= 0) {
              final ASTNode subTag = subTags[subTagNum].getNode();
              if (subTag.getTreeParent() != myTag.getNode()) {
                // in entity
                final XmlEntityRef entityRef = PsiTreeUtil.getParentOfType(subTags[subTagNum], XmlEntityRef.class);
                throw new IncorrectOperationException(
                  "Can't insert subtag to the entity. Entity reference text: " + (entityRef == null ? "" : entityRef.getText()));
              }
              return addInternalSuper(child, child, subTag, Boolean.FALSE);
            }
            else {
              ASTNode startTagEnd = XmlChildRole.START_TAG_END_FINDER.findChild(myTag.getNode());
              return addInternalSuper(child, child, startTagEnd, Boolean.FALSE);
            }
          }
        }
      }
      else {
        ASTNode closingTagStart = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(myTag.getNode());
        return addInternalSuper(child, child, closingTagStart, Boolean.TRUE);
      }
    }
    return addInternalSuper(child, child, anchor, Boolean.TRUE);
  }
protected TreeElement bodyInsert(TreeElement child)