&& (value.Equals(sortResource, nsCaseInsensitiveStringComparator())))
&& (value.Equals(sortResource)))
XULSortServiceImpl::Sort(nsIDOMNode* node, const nsAString& sortResource, const nsAString& sortDirection){  nsresult rv;  _sortStruct  sortInfo;  // get root content node  nsCOMPtr<nsIContent>  contentNode = do_QueryInterface(node);  if (!contentNode) return NS_ERROR_FAILURE;  nsCOMPtr<nsIContent> dbNode;  if (NS_FAILED(rv = FindDatabaseElement(contentNode, getter_AddRefs(dbNode))))    return rv;  nsCOMPtr<nsIDOMXULElement> dbXULNode = do_QueryInterface(dbNode);  if (!dbXULNode) return NS_ERROR_FAILURE;  // get composite db  sortInfo.db = nsnull;  sortInfo.mInner = nsnull;  sortInfo.parentContainer = dbNode;  sortInfo.inbetweenSeparatorSort = PR_FALSE;  sortInfo.cacheFirstHint = PR_FALSE;  // optimization - if we're about to merely invert the current sort  // then just reverse-index the current tree  PRBool invertTreeFlag = PR_FALSE;  nsAutoString value;  if (NS_SUCCEEDED(rv = dbNode->GetAttr(kNameSpaceID_None, nsXULAtoms::sortActive, value))      && (rv == NS_CONTENT_ATTR_HAS_VALUE)       && (value.EqualsIgnoreCase("true")))  {    if (NS_SUCCEEDED(rv = dbNode->GetAttr(kNameSpaceID_None, nsXULAtoms::sortResource, value))        && (rv == NS_CONTENT_ATTR_HAS_VALUE)         && (value.Equals(sortResource, nsCaseInsensitiveStringComparator())))    {      if (NS_SUCCEEDED(rv = dbNode->GetAttr(kNameSpaceID_None, nsXULAtoms::sortDirection, value))          && (rv == NS_CONTENT_ATTR_HAS_VALUE))      {        if ((value.Equals(*kDescendingStr) && sortDirection.Equals(*kAscendingStr))             || (value.Equals(*kAscendingStr) && sortDirection.Equals(*kDescendingStr)))         {          invertTreeFlag = PR_TRUE;        }      }    }  }  // remove any sort hints on tree root node  dbNode->UnsetAttr(kNameSpaceID_None, nsXULAtoms::sortActive, PR_FALSE);  dbNode->UnsetAttr(kNameSpaceID_None, nsXULAtoms::sortDirection, PR_FALSE);  dbNode->UnsetAttr(kNameSpaceID_None, nsXULAtoms::sortSeparators, PR_FALSE);  dbNode->UnsetAttr(kNameSpaceID_None, nsXULAtoms::sortResource, PR_FALSE);  dbNode->UnsetAttr(kNameSpaceID_None, nsXULAtoms::sortResource2, PR_FALSE);  nsCOMPtr<nsIRDFCompositeDataSource>  cds;  if (NS_SUCCEEDED(rv = dbXULNode->GetDatabase(getter_AddRefs(cds))))    sortInfo.db = cds;  // determine new sort resource and direction to use  if (sortDirection.Equals(*kNaturalStr)) {    sortInfo.naturalOrderSort = PR_TRUE;    sortInfo.descendingSort = PR_FALSE;  } else {    sortInfo.naturalOrderSort = PR_FALSE;    if (sortDirection.Equals(*kAscendingStr))      sortInfo.descendingSort = PR_FALSE;    else if (sortDirection.Equals(*kDescendingStr))      sortInfo.descendingSort = PR_TRUE;  }    // look for additional sort info from content  nsAutoString sortResource2, unused;  GetSortColumnInfo(contentNode, unused, unused, sortResource2, sortInfo.inbetweenSeparatorSort);  // build resource url for first sort resource  rv = gRDFService->GetUnicodeResource(sortResource, getter_AddRefs(sortInfo.sortProperty));  if (NS_FAILED(rv)) return rv;  nsAutoString resourceUrl;  resourceUrl.Assign(sortResource);  resourceUrl.Append(NS_LITERAL_STRING("?collation=true"));  rv = gRDFService->GetUnicodeResource(resourceUrl, getter_AddRefs(sortInfo.sortPropertyColl));  if (NS_FAILED(rv)) return rv;  resourceUrl.Assign(sortResource);  resourceUrl.Append(NS_LITERAL_STRING("?sort=true"));  rv = gRDFService->GetUnicodeResource(resourceUrl, getter_AddRefs(sortInfo.sortPropertySort));  if (NS_FAILED(rv)) return rv;  // build resource url for second sort resource  if (!sortResource2.IsEmpty()) {    rv = gRDFService->GetUnicodeResource(sortResource2, getter_AddRefs(sortInfo.sortProperty2));    if (NS_FAILED(rv)) return rv;    resourceUrl = sortResource2;    resourceUrl.Append(NS_LITERAL_STRING("?collation=true"));    rv = gRDFService->GetUnicodeResource(resourceUrl, getter_AddRefs(sortInfo.sortPropertyColl2));    if (NS_FAILED(rv)) return rv;    resourceUrl = sortResource2;    resourceUrl.Append(NS_LITERAL_STRING("?sort=true"));    rv = gRDFService->GetUnicodeResource(resourceUrl, getter_AddRefs(sortInfo.sortPropertySort2));    if (NS_FAILED(rv)) return rv;  }  // store sort info in attributes on content  SetSortHints(dbNode, sortResource, sortDirection, sortResource2, sortInfo.inbetweenSeparatorSort, PR_TRUE);  // start sorting the content depending on the tag  nsCOMPtr<nsIAtom> dbNodeTag;  dbNode->GetTag(getter_AddRefs(dbNodeTag));  nsCOMPtr<nsIContent> container;  if (NS_FAILED(rv = FindSortableContainer(dbNode, getter_AddRefs(container)))) return rv;  SortContainer(container, &sortInfo, invertTreeFlag);    // Now remove the db node and re-insert it to force the frames to be rebuilt.  nsCOMPtr<nsIContent> containerParent = container->GetParent();  PRInt32 containerIndex = containerParent->IndexOf(container);  PRInt32 childCount = containerParent->GetChildCount();  if (NS_FAILED(rv = containerParent->RemoveChildAt(containerIndex, PR_TRUE))) return rv;  if (containerIndex+1 < childCount) {    if (NS_FAILED(rv = containerParent->InsertChildAt(container, containerIndex, PR_TRUE, PR_TRUE))) return rv;  } else {    if (NS_FAILED(rv = containerParent->AppendChildTo(container, PR_TRUE, PR_TRUE))) return rv;  }    return NS_OK;}