NS_ASSERTION(rv != NS_RDF_NO_VALUE, "arc-out with no target: fix your arcs-out cursor");
RDFTreeBuilderImpl::AddWidgetItem(nsIContent* aElement,                                  nsIRDFResource* aProperty,                                  nsIRDFResource* aValue,                                  PRInt32 aNaturalOrderPos){    // If it's a tree property, then we need to add the new child    // element to a special "children" element in the parent.  The    // child element's value will be the value of the    // property. We'll also attach an "ID=" attribute to the new    // child; e.g.,    //    // <xul:treeitem>    //   ...    //   <xul:treechildren>    //     <xul:treeitem id="value" rdf:property="property">    //        <xul:treecell>    //           <!-- value not specified until SetWidgetAttribute() -->    //        </xul:treecell>    //    //        <xul:treecell>    //           <!-- value not specified until SetWidgetAttribute() -->    //        </xul:treecell>    //    //        ...    //    //        <!-- Other content recursively generated -->    //    //     </xul:treeitem>    //   </xul:treechildren>    //   ...    // </xul:treeitem>    //    // We can also handle the case where they've specified RDF    // contents on the <xul:treebody> tag, in which case we'll just    // dangle the new row directly off the treebody.    nsresult rv;    nsCOMPtr<nsIContent> treeChildren;    if (IsItemOrFolder(aElement)) {        // Ensure that the <xul:treechildren> element exists on the parent.        if (NS_FAILED(rv = EnsureElementHasGenericChild(aElement,                                                        kNameSpaceID_XUL,                                                        kTreeChildrenAtom,                                                        getter_AddRefs(treeChildren))))            return rv;    }    else if (IsWidgetInsertionRootElement(aElement)) {        // We'll just use the <xul:treebody> as the element onto which        // we'll dangle a new row.        treeChildren = do_QueryInterface(aElement);        if (! treeChildren) {            NS_ERROR("aElement is not nsIContent!?!");            return NS_ERROR_UNEXPECTED;        }    }    else {        NS_ERROR("new tree row doesn't fit here!");        return NS_ERROR_UNEXPECTED;    }    // Find out if we're a container or not.    PRBool markAsContainer = PR_FALSE;    // Create the <xul:treeitem> element    nsCOMPtr<nsIContent> treeItem;    if (NS_FAILED(rv = CreateResourceElement(kNameSpaceID_XUL,                                             kTreeItemAtom,                                             aValue,                                             getter_AddRefs(treeItem))))        return rv;    // Set the rdf:property attribute to be the arc label from the    // parent. This indicates how it got generated, so we can keep any    // subsequent changes via the DOM in sink. This property should be    // immutable.    {        nsXPIDLCString uri;        aProperty->GetValue( getter_Copies(uri) );        treeItem->SetAttribute(kNameSpaceID_RDF, kPropertyAtom, (const char*) uri, PR_FALSE);    }    // Create the cell substructure    if (NS_FAILED(rv = CreateTreeItemCells(treeItem)))        return rv;    // Add the <xul:treeitem> to the <xul:treechildren> element.	if (nsnull != XULSortService)	{		XULSortService->InsertContainerNode(treeChildren, treeItem);	}	else	{		treeChildren->AppendChildTo(treeItem, PR_TRUE);	}    // Add miscellaneous attributes by iterating _all_ of the    // properties out of the resource.    nsCOMPtr<nsISimpleEnumerator> arcs;    rv = mDB->ArcLabelsOut(aValue, getter_AddRefs(arcs));    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get arcs out");    if (NS_FAILED(rv)) return rv;    while (1) {        PRBool hasMore;        rv = arcs->HasMoreElements(&hasMore);        if (NS_FAILED(rv)) return rv;        if (! hasMore)            break;        nsCOMPtr<nsISupports> isupports;        rv = arcs->GetNext(getter_AddRefs(isupports));        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get cursor value");        if (NS_FAILED(rv)) return rv;        nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports);        // Ignore properties that are used to indicate "tree-ness"        if (IsContainmentProperty(aElement, property))        {            markAsContainer = PR_TRUE;            continue;        }        PRInt32 nameSpaceID;        nsCOMPtr<nsIAtom> tag;        rv = mDocument->SplitProperty(property, &nameSpaceID, getter_AddRefs(tag));        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to split property");        if (NS_FAILED(rv)) return rv;        nsCOMPtr<nsIRDFNode> value;        rv = mDB->GetTarget(aValue, property, PR_TRUE, getter_AddRefs(value));        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get target");        if (NS_FAILED(rv)) return rv;        NS_ASSERTION(rv != NS_RDF_NO_VALUE, "arc-out with no target: fix your arcs-out cursor");        if (rv == NS_RDF_NO_VALUE)            continue;        nsCOMPtr<nsIRDFResource> resource;        nsCOMPtr<nsIRDFLiteral> literal;        nsAutoString s;        if (NS_SUCCEEDED(rv = value->QueryInterface(kIRDFResourceIID, getter_AddRefs(resource)))) {            nsXPIDLCString uri;            resource->GetValue( getter_Copies(uri) );            s = uri;        }        else if (NS_SUCCEEDED(rv = value->QueryInterface(kIRDFLiteralIID, getter_AddRefs(literal)))) {            nsXPIDLString p;            literal->GetValue( getter_Copies(p) );            s = p;        }        else {            NS_ERROR("not a resource or a literal");            return NS_ERROR_UNEXPECTED;        }        treeItem->SetAttribute(nameSpaceID, tag, s, PR_FALSE);        if (aNaturalOrderPos > 0)	    {            // XXX Add this to menu builder as well, or better yet, abstract out.		    nsAutoString	pos, zero("0000");		    pos.Append(aNaturalOrderPos, 10);		    if (pos.Length() < 4)		    {			    pos.Insert(zero, 0, 4-pos.Length()); 		    }		    treeItem->SetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos, PR_FALSE);	    }    }    if (markAsContainer)    {        // Finally, mark this as a "container" so that we know to        // recursively generate kids if they're asked for.        if (NS_FAILED(rv = treeItem->SetAttribute(kNameSpaceID_RDF, kContainerAtom, "true", PR_FALSE)))            return rv;    }    return NS_OK;}