nsCRT::free(tag);
delete [] tag;
nsHTMLEditor::ReParentContentOfNode(nsIDOMNode *aNode,                                     nsString &aParentTag,                                    BlockTransformationType aTransformation){  if (!aNode) { return NS_ERROR_NULL_POINTER; }  if (gNoisy)   {     char *tag = aParentTag.ToNewCString();    printf("---------- ReParentContentOfNode(%p,%s,%d) -----------\n", aNode, tag, aTransformation);     nsCRT::free(tag);  }  // find the current block parent, or just use aNode if it is a block node  nsCOMPtr<nsIDOMElement>blockParentElement;  nsCOMPtr<nsIDOMNode>nodeToReParent; // this is the node we'll operate on, by default it's aNode  nsresult res = aNode->QueryInterface(NS_GET_IID(nsIDOMNode), getter_AddRefs(nodeToReParent));  PRBool nodeIsInline;  PRBool nodeIsBlock=PR_FALSE;  IsNodeInline(aNode, nodeIsInline);  if (PR_FALSE==nodeIsInline)  {    nsresult QIResult;    nsCOMPtr<nsIDOMCharacterData>nodeAsText;    QIResult = aNode->QueryInterface(NS_GET_IID(nsIDOMCharacterData), getter_AddRefs(nodeAsText));    if (NS_FAILED(QIResult) || !nodeAsText) {      nodeIsBlock=PR_TRUE;    }  }  // if aNode is the block parent, then the node to reparent is one of its children  if (PR_TRUE==nodeIsBlock)   {    res = aNode->QueryInterface(NS_GET_IID(nsIDOMNode), getter_AddRefs(blockParentElement));    if (NS_SUCCEEDED(res) && blockParentElement) {      res = aNode->GetFirstChild(getter_AddRefs(nodeToReParent));    }  }  else { // we just need to get the block parent of aNode    res = GetBlockParent(aNode, getter_AddRefs(blockParentElement));  }  // at this point, we must have a good res, a node to reparent, and a block parent  if (!nodeToReParent) { return NS_ERROR_UNEXPECTED;}  if (!blockParentElement) { return NS_ERROR_NULL_POINTER;}  if (NS_SUCCEEDED(res))  {    nsCOMPtr<nsIDOMNode> newParentNode;    nsCOMPtr<nsIDOMNode> blockParentNode = do_QueryInterface(blockParentElement);    // we need to treat nodes directly inside the body differently    nsAutoString parentTag;    blockParentElement->GetTagName(parentTag);    PRBool isRoot;    IsRootTag(parentTag, isRoot);    if (PR_TRUE==isRoot)        {      // if nodeToReParent is a text node, we have <ROOT>Text.      // re-parent Text into a new <aTag> at the offset of Text in <ROOT>      // so we end up with <ROOT><aTag>Text      // ignore aTransformation, replaces act like inserts      nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(nodeToReParent);      if (nodeAsText)      {        res = ReParentBlockContent(nodeToReParent, aParentTag, blockParentNode, parentTag,                                       aTransformation, getter_AddRefs(newParentNode));      }      else      { // this is the case of an insertion point between 2 non-text objects        // XXX: how to you know it's an insertion point???        PRInt32 offsetInParent=0;        res = GetChildOffset(nodeToReParent, blockParentNode, offsetInParent);        NS_ASSERTION((NS_SUCCEEDED(res)), "bad res from GetChildOffset");        // otherwise, just create the block parent at the selection        res = CreateNode(aParentTag, blockParentNode, offsetInParent,                                           getter_AddRefs(newParentNode));        // XXX: need to move some of the children of blockParentNode into the newParentNode?        // XXX: need to create a bogus text node inside this new block?        //      that means, I need to generalize bogus node handling      }    }    else    { // the block parent is not a ROOT,       // for the selected block content, transform blockParentNode       if (((eReplaceParent==aTransformation) && (PR_FALSE==parentTag.EqualsIgnoreCase(aParentTag))) ||           (eInsertParent==aTransformation))      {        if (gNoisy) { DebugDumpContent(); } // DEBUG        res = ReParentBlockContent(nodeToReParent, aParentTag, blockParentNode, parentTag,                                       aTransformation, getter_AddRefs(newParentNode));        if ((NS_SUCCEEDED(res)) && (newParentNode) && (eReplaceParent==aTransformation))        {          PRBool hasChildren;          blockParentNode->HasChildNodes(&hasChildren);          if (PR_FALSE==hasChildren)          {            res = nsEditor::DeleteNode(blockParentNode);            if (gNoisy)             {              printf("deleted old block parent node %p\n", blockParentNode.get());              DebugDumpContent(); // DEBUG            }          }        }      }      else { // otherwise, it's a no-op        if (gNoisy) { printf("AddBlockParent is a no-op for this collapsed selection.\n"); }      }    }  }  return res;}