Bug 682367 - Call nsINode::GetChildAt less. r=smaug
authorDavid Zbarsky <dzbarsky@gmail.com>
Tue, 27 Sep 2011 09:54:58 +0200
changeset 77683 80ff402f2f7e9d4c42b4658febf1a252a89b6347
parent 77682 230ea0b16f035b2f47d2b0b54641dfd3a83a4f4c
child 77684 587115c590ff0da824e1248aa9052be002384f1c
push id191
push userrcampbell@mozilla.com
push dateWed, 28 Sep 2011 12:54:12 +0000
treeherderfx-team@4d27c6c86de6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs682367
milestone9.0a1
Bug 682367 - Call nsINode::GetChildAt less. r=smaug
content/base/src/nsContentIterator.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsNodeUtils.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsXHTMLContentSerializer.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLTableElement.cpp
content/html/content/src/nsTextEditorState.cpp
content/html/document/src/nsHTMLDocument.cpp
content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGSwitchElement.cpp
content/svg/content/src/nsSVGUseElement.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xbl/src/nsXBLWindowKeyHandler.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
content/xul/content/src/nsXULPopupListener.cpp
content/xul/document/src/nsXULDocument.cpp
content/xul/templates/src/nsContentSupportMap.cpp
content/xul/templates/src/nsTemplateMap.h
content/xul/templates/src/nsXULContentBuilder.cpp
content/xul/templates/src/nsXULContentUtils.cpp
content/xul/templates/src/nsXULSortService.cpp
content/xul/templates/src/nsXULTemplateBuilder.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorStorage.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
content/xul/templates/src/nsXULTemplateResultXML.cpp
content/xul/templates/src/nsXULTreeBuilder.cpp
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -564,27 +564,27 @@ nsINode*
 nsContentIterator::GetDeepFirstChild(nsINode *aRoot,
                                      nsTArray<PRInt32> *aIndexes)
 {
   if (!aRoot) {
     return nsnull;
   }
 
   nsINode *n = aRoot;
-  nsINode *nChild = n->GetChildAt(0);
+  nsINode *nChild = n->GetFirstChild();
 
   while (nChild)
   {
     if (aIndexes)
     {
       // Add this node to the stack of indexes
       aIndexes->AppendElement(0);
     }
     n = nChild;
-    nChild = n->GetChildAt(0);
+    nChild = n->GetFirstChild();
   }
 
   return n;
 }
 
 nsINode*
 nsContentIterator::GetDeepLastChild(nsINode *aRoot, nsTArray<PRInt32> *aIndexes)
 {
@@ -742,17 +742,17 @@ nsContentIterator::NextNode(nsINode *aNo
   nsINode *n = aNode;
   nsINode *nextNode = nsnull;
 
   if (mPre)  // if we are a Pre-order iterator, use pre-order
   {
     // if it has children then next node is first child
     if (NodeHasChildren(n))
     {
-      nsINode *nFirstChild = n->GetChildAt(0);
+      nsINode *nFirstChild = n->GetFirstChild();
 
       // update cache
       if (aIndexes)
       {
         // push an entry on the index stack
         aIndexes->AppendElement(0);
       }
       else mCachedIndex = 0;
@@ -884,17 +884,18 @@ nsContentIterator::PrevNode(nsINode *aNo
   }
   else  // post-order
   {
     PRInt32 numChildren = n->GetChildCount();
   
     // if it has children then prev node is last child
     if (numChildren)
     {
-      nsINode *nLastChild = n->GetChildAt(--numChildren);
+      nsINode *nLastChild = n->GetLastChild();
+      numChildren--;
 
       // update cache
       if (aIndexes)
       {
         // push an entry on the index stack
         aIndexes->AppendElement(numChildren);
       }
       else mCachedIndex = numChildren;
@@ -1295,17 +1296,17 @@ nsresult nsContentSubtreeIterator::Init(
   if (NS_FAILED(aRange->GetEndContainer(getter_AddRefs(endParent))) || !endParent)
     return NS_ERROR_FAILURE;
   nEndP = do_QueryInterface(endParent);
   aRange->GetEndOffset(&endIndx);
 
   // short circuit when start node == end node
   if (startParent == endParent)
   {
-    nsINode* nChild = nStartP->GetChildAt(0);
+    nsINode* nChild = nStartP->GetFirstChild();
   
     if (!nChild) // no children, must be a text node or empty container
     {
       // all inside one text node - empty subtree iterator
       MakeEmpty();
       return NS_OK;
     }
     else
@@ -1485,17 +1486,17 @@ nsContentSubtreeIterator::Next()
   nextNode = GetDeepFirstChild(nextNode);
   return GetTopAncestorInRange(nextNode, address_of(mCurNode));
 */
   PRInt32 i = mEndNodes.IndexOf(nextNode);
   while (i != -1)
   {
     // as long as we are finding ancestors of the endpoint of the range,
     // dive down into their children
-    nextNode = nextNode->GetChildAt(0);
+    nextNode = nextNode->GetFirstChild();
     NS_ASSERTION(nextNode, "Iterator error, expected a child node!");
 
     // should be impossible to get a null pointer.  If we went all the way
     // down the child chain to the bottom without finding an interior node, 
     // then the previous node should have been the last, which was
     // was tested at top of routine.
     i = mEndNodes.IndexOf(nextNode);
   }
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3777,19 +3777,19 @@ nsContentUtils::SetNodeTextContent(nsICo
 
   textContent->SetText(aValue, PR_TRUE);
 
   return aContent->AppendChildTo(textContent, PR_TRUE);
 }
 
 static void AppendNodeTextContentsRecurse(nsINode* aNode, nsAString& aResult)
 {
-  nsIContent* child;
-  PRUint32 i;
-  for (i = 0; (child = aNode->GetChildAt(i)); ++i) {
+  for (nsIContent* child = aNode->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->IsElement()) {
       AppendNodeTextContentsRecurse(child, aResult);
     }
     else if (child->IsNodeOfType(nsINode::eTEXT)) {
       child->AppendTextTo(aResult);
     }
   }
 }
@@ -3801,32 +3801,32 @@ nsContentUtils::AppendNodeTextContent(ns
 {
   if (aNode->IsNodeOfType(nsINode::eTEXT)) {
     static_cast<nsIContent*>(aNode)->AppendTextTo(aResult);
   }
   else if (aDeep) {
     AppendNodeTextContentsRecurse(aNode, aResult);
   }
   else {
-    nsIContent* child;
-    PRUint32 i;
-    for (i = 0; (child = aNode->GetChildAt(i)); ++i) {
+    for (nsIContent* child = aNode->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
       if (child->IsNodeOfType(nsINode::eTEXT)) {
         child->AppendTextTo(aResult);
       }
     }
   }
 }
 
 PRBool
 nsContentUtils::HasNonEmptyTextContent(nsINode* aNode)
 {
-  nsIContent* child;
-  PRUint32 i;
-  for (i = 0; (child = aNode->GetChildAt(i)); ++i) {
+  for (nsIContent* child = aNode->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->IsNodeOfType(nsINode::eTEXT) &&
         child->TextLength() > 0) {
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4928,22 +4928,21 @@ GetElementByAttribute(nsIContent* aConte
                       nsIDOMElement** aResult)
 {
   if (aUniversalMatch ? aContent->HasAttr(kNameSpaceID_None, aAttrName) :
                         aContent->AttrValueIs(kNameSpaceID_None, aAttrName,
                                               aAttrValue, eCaseMatters)) {
     return CallQueryInterface(aContent, aResult);
   }
 
-  PRUint32 childCount = aContent->GetChildCount();
-
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent *current = aContent->GetChildAt(i);
-
-    GetElementByAttribute(current, aAttrName, aAttrValue, aUniversalMatch,
+  for (nsIContent* child = aContent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+
+    GetElementByAttribute(child, aAttrName, aAttrValue, aUniversalMatch,
                           aResult);
 
     if (*aResult)
       return NS_OK;
   }
 
   return NS_OK;
 }
@@ -5110,20 +5109,21 @@ Element*
 nsIDocument::GetHtmlChildElement(nsIAtom* aTag)
 {
   Element* html = GetHtmlElement();
   if (!html)
     return nsnull;
 
   // Look for the element with aTag inside html. This needs to run
   // forwards to find the first such element.
-  for (PRUint32 i = 0; i < html->GetChildCount(); ++i) {
-    nsIContent* result = html->GetChildAt(i);
-    if (result->Tag() == aTag && result->IsHTML())
-      return result->AsElement();
+  for (nsIContent* child = html->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    if (child->IsHTML(aTag))
+      return child->AsElement();
   }
   return nsnull;
 }
 
 nsIContent*
 nsDocument::GetTitleContent(PRUint32 aNamespace)
 {
   // mMayHaveTitleElement will have been set to true if any HTML or SVG
@@ -6008,17 +6008,17 @@ BlastSubtreeToPieces(nsINode *aNode)
         // XXX Should we abort here?
         NS_ASSERTION(NS_SUCCEEDED(rv), "Uhoh, UnsetAttr shouldn't fail!");
       }
     }
   }
 
   count = aNode->GetChildCount();
   for (i = 0; i < count; ++i) {
-    BlastSubtreeToPieces(aNode->GetChildAt(0));
+    BlastSubtreeToPieces(aNode->GetFirstChild());
 #ifdef DEBUG
     nsresult rv =
 #endif
       aNode->RemoveChildAt(0, PR_FALSE);
 
     // XXX Should we abort here?
     NS_ASSERTION(NS_SUCCEEDED(rv), "Uhoh, RemoveChildAt shouldn't fail!");
   }
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -453,17 +453,17 @@ nsINode::GetChildNodes(nsIDOMNodeList** 
   NS_ADDREF(*aChildNodes);
 
   return NS_OK;
 }
 
 nsresult
 nsINode::GetFirstChild(nsIDOMNode** aNode)
 {
-  nsIContent* child = GetChildAt(0);
+  nsIContent* child = GetFirstChild();
   if (child) {
     return CallQueryInterface(child, aNode);
   }
 
   *aNode = nsnull;
 
   return NS_OK;
 }
@@ -2870,19 +2870,19 @@ BindNodesInInsertPoints(nsXBLBinding* aB
 #ifdef MOZ_XUL
     nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(aDocument);
 #endif
     PRUint32 i;
     for (i = 0; i < inserts->Length(); ++i) {
       nsCOMPtr<nsIContent> insertRoot =
         inserts->ElementAt(i)->GetDefaultContent();
       if (insertRoot) {
-        PRUint32 j;
-        for (j = 0; j < insertRoot->GetChildCount(); ++j) {
-          nsCOMPtr<nsIContent> child = insertRoot->GetChildAt(j);
+        for (nsCOMPtr<nsIContent> child = insertRoot->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
           rv = child->BindToTree(aDocument, aInsertParent,
                                  aBinding->GetBoundElement(), allowScripts);
           NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef MOZ_XUL
           if (xulDoc) {
             xulDoc->AddSubtreeToDocument(child);
           }
@@ -3004,19 +3004,19 @@ nsGenericElement::BindToTree(nsIDocument
       nsBindingManager* bmgr = ownerDoc->BindingManager();
 
       // First check if we have a binding...
       nsXBLBinding* contBinding =
         GetFirstBindingWithContent(bmgr, this);
       if (contBinding) {
         nsCOMPtr<nsIContent> anonRoot = contBinding->GetAnonymousContent();
         PRBool allowScripts = contBinding->AllowScripts();
-        PRUint32 i;
-        for (i = 0; i < anonRoot->GetChildCount(); ++i) {
-          nsCOMPtr<nsIContent> child = anonRoot->GetChildAt(i);
+        for (nsCOMPtr<nsIContent> child = anonRoot->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
           rv = child->BindToTree(aDocument, this, this, allowScripts);
           NS_ENSURE_SUCCESS(rv, rv);
         }
 
         // ...then check if we have content in insertion points that are
         // direct children of the <content>
         rv = BindNodesInInsertPoints(contBinding, this, aDocument);
         NS_ENSURE_SUCCESS(rv, rv);
@@ -3936,30 +3936,29 @@ PRBool IsAllowedAsChild(nsIContent* aNew
       // they're allowed inside elements.  If we ever change this to allow
       // doctype nodes in document fragments, we'll need to update this code
       if (!aParent->IsNodeOfType(nsINode::eDOCUMENT)) {
         // All good here
         return PR_TRUE;
       }
 
       PRBool sawElement = PR_FALSE;
-      PRUint32 count = aNewChild->GetChildCount();
-      for (PRUint32 index = 0; index < count; ++index) {
-        nsIContent* childContent = aNewChild->GetChildAt(index);
-        NS_ASSERTION(childContent, "Something went wrong");
-        if (childContent->IsElement()) {
+      for (nsIContent* child = aNewChild->GetFirstChild();
+           child;
+           child = child->GetNextSibling()) {
+        if (child->IsElement()) {
           if (sawElement) {
             // Can't put two elements into a document
             return PR_FALSE;
           }
           sawElement = PR_TRUE;
         }
         // If we can put this content at the the right place, we might be ok;
         // if not, we bail out.
-        if (!IsAllowedAsChild(childContent, aParent, aIsReplace, aRefChild)) {
+        if (!IsAllowedAsChild(child, aParent, aIsReplace, aRefChild)) {
           return PR_FALSE;
         }
       }
 
       // Everything in the fragment checked out ok, so we can stick it in here
       return PR_TRUE;
     }
   default:
@@ -4123,18 +4122,19 @@ nsINode::ReplaceOrInsertBefore(PRBool aR
     if (!count) {
       return NS_OK;
     }
 
     // Copy the children into a separate array to avoid having to deal with
     // mutations to the fragment while we're inserting.
     nsAutoTArray<nsCOMPtr<nsIContent>, 50> fragChildren;
     fragChildren.SetCapacity(count);
-    for (PRUint32 i = 0; i < count; i++) {
-      nsIContent* child = newContent->GetChildAt(i);
+    for (nsIContent* child = newContent->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
       NS_ASSERTION(child->GetCurrentDoc() == nsnull,
                    "How did we get a child with a current doc?");
       fragChildren.AppendElement(child);
     }
 
     // Remove the children from the fragment.
     for (PRUint32 i = count; i > 0;) {
       newContent->RemoveChildAt(--i, PR_TRUE);
@@ -4995,23 +4995,22 @@ nsGenericElement::List(FILE* out, PRInt3
 
   ListAttributes(out);
 
   fprintf(out, " state=[%llx]", State().GetInternalValue());
   fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
   fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
   fprintf(out, " refcount=%d<", mRefCnt.get());
 
-  PRUint32 i, length = GetChildCount();
-  if (length > 0) {
+  nsIContent* child = GetFirstChild();
+  if (child) {
     fputs("\n", out);
-
-    for (i = 0; i < length; ++i) {
-      nsIContent *kid = GetChildAt(i);
-      kid->List(out, aIndent + 1);
+    
+    for (; child; child = child->GetNextSibling()) {
+      child->List(out, aIndent + 1);
     }
 
     for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
   }
 
   fputs(">\n", out);
   
   nsGenericElement* nonConstThis = const_cast<nsGenericElement*>(this);
@@ -5022,22 +5021,23 @@ nsGenericElement::List(FILE* out, PRInt3
     // Note: not listing nsIAnonymousContentCreator-created content...
 
     nsBindingManager* bindingManager = document->BindingManager();
     nsCOMPtr<nsIDOMNodeList> anonymousChildren;
     bindingManager->GetAnonymousNodesFor(nonConstThis,
                                          getter_AddRefs(anonymousChildren));
 
     if (anonymousChildren) {
+      PRUint32 length;
       anonymousChildren->GetLength(&length);
       if (length > 0) {
         for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
         fputs("anonymous-children<\n", out);
 
-        for (i = 0; i < length; ++i) {
+        for (PRUint32 i = 0; i < length; ++i) {
           nsCOMPtr<nsIDOMNode> node;
           anonymousChildren->Item(i, getter_AddRefs(node));
           nsCOMPtr<nsIContent> child = do_QueryInterface(node);
           child->List(out, aIndent + 1);
         }
 
         for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
         fputs(">\n", out);
@@ -5045,23 +5045,24 @@ nsGenericElement::List(FILE* out, PRInt3
     }
 
     if (bindingManager->HasContentListFor(nonConstThis)) {
       nsCOMPtr<nsIDOMNodeList> contentList;
       bindingManager->GetContentListFor(nonConstThis,
                                         getter_AddRefs(contentList));
 
       NS_ASSERTION(contentList != nsnull, "oops, binding manager lied");
-
+      
+      PRUint32 length;
       contentList->GetLength(&length);
       if (length > 0) {
         for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
         fputs("content-list<\n", out);
 
-        for (i = 0; i < length; ++i) {
+        for (PRUint32 i = 0; i < length; ++i) {
           nsCOMPtr<nsIDOMNode> node;
           contentList->Item(i, getter_AddRefs(node));
           nsCOMPtr<nsIContent> child = do_QueryInterface(node);
           child->List(out, aIndent + 1);
         }
 
         for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
         fputs(">\n", out);
@@ -5082,21 +5083,21 @@ nsGenericElement::DumpContent(FILE* out,
   fputs(NS_LossyConvertUTF16toASCII(buf).get(), out);
 
   if(aDumpAll) ListAttributes(out);
 
   fputs(">", out);
 
   if(aIndent) fputs("\n", out);
 
-  PRInt32 index, kids = GetChildCount();
-  for (index = 0; index < kids; index++) {
-    nsIContent *kid = GetChildAt(index);
+  for (nsIContent* child = GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     PRInt32 indent = aIndent ? aIndent + 1 : 0;
-    kid->DumpContent(out, indent, aDumpAll);
+    child->DumpContent(out, indent, aDumpAll);
   }
   for (indent = aIndent; --indent >= 0; ) fputs("  ", out);
   fputs("</", out);
   fputs(NS_LossyConvertUTF16toASCII(buf).get(), out);
   fputs(">", out);
 
   if(aIndent) fputs("\n", out);
 }
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -654,20 +654,21 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
                     aNodesWithProperties.AppendObject(clonedAttrChildNode);
         NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
       }
     }
   }
   // XXX End of workaround for broken attribute nodes.
   else if (aDeep || aNode->IsNodeOfType(nsINode::eATTRIBUTE)) {
     // aNode's children.
-    PRUint32 i, length = aNode->GetChildCount();
-    for (i = 0; i < length; ++i) {
+    for (nsIContent* cloneChild = aNode->GetFirstChild();
+         cloneChild;
+       cloneChild = cloneChild->GetNextSibling()) {
       nsCOMPtr<nsINode> child;
-      rv = CloneAndAdopt(aNode->GetChildAt(i), aClone, PR_TRUE, nodeInfoManager,
+      rv = CloneAndAdopt(cloneChild, aClone, PR_TRUE, nodeInfoManager,
                          aCx, aNewScope, aNodesWithProperties, clone,
                          getter_AddRefs(child));
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   // XXX setting document on some nodes not in a document so XBL will bind
   // and chrome won't break. Make XBL bind to document-less nodes!
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1921,23 +1921,20 @@ nsObjectLoadingContent::GetPluginSupport
   if (aContent->Tag() == nsGkAtoms::embed ||
       aContent->Tag() == nsGkAtoms::applet) {
     return GetPluginDisabledState(aContentType);
   }
 
   PRBool hasAlternateContent = PR_FALSE;
 
   // Search for a child <param> with a pluginurl name
-  PRUint32 count = aContent->GetChildCount();
-  for (PRUint32 i = 0; i < count; ++i) {
-    nsIContent* child = aContent->GetChildAt(i);
-    NS_ASSERTION(child, "GetChildCount lied!");
-
-    if (child->IsHTML() &&
-        child->Tag() == nsGkAtoms::param) {
+  for (nsIContent* child = aContent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    if (child->IsHTML(nsGkAtoms::param)) {
       if (child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                              NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) {
         return GetPluginDisabledState(aContentType);
       }
     } else if (!hasAlternateContent) {
       hasAlternateContent =
         nsStyleUtil::IsSignificantChild(child, PR_TRUE, PR_FALSE);
     }
--- a/content/base/src/nsXHTMLContentSerializer.cpp
+++ b/content/base/src/nsXHTMLContentSerializer.cpp
@@ -493,21 +493,20 @@ nsXHTMLContentSerializer::AfterElementSt
   if (aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
       mRewriteEncodingDeclaration &&
       name == nsGkAtoms::head) {
 
     // Check if there already are any content-type meta children.
     // If there are, they will be modified to use the correct charset.
     // If there aren't, we'll insert one here.
     PRBool hasMeta = PR_FALSE;
-    PRUint32 i, childCount = aContent->GetChildCount();
-    for (i = 0; i < childCount; ++i) {
-      nsIContent* child = aContent->GetChildAt(i);
-      if (child->IsHTML() &&
-          child->Tag() == nsGkAtoms::meta &&
+    for (nsIContent* child = aContent->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
+      if (child->IsHTML(nsGkAtoms::meta) &&
           child->HasAttr(kNameSpaceID_None, nsGkAtoms::content)) {
         nsAutoString header;
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
 
         if (header.LowerCaseEqualsLiteral("content-type")) {
           hasMeta = PR_TRUE;
           break;
         }
@@ -1014,22 +1013,20 @@ nsXHTMLContentSerializer::IsFirstChildOf
   }
   else
     return PR_FALSE;
 }
 
 PRBool
 nsXHTMLContentSerializer::HasNoChildren(nsIContent * aContent) {
 
-  PRUint32 i, childCount = aContent->GetChildCount();
-
-  for (i = 0; i < childCount; ++i) {
-
-    nsIContent* child = aContent->GetChildAt(i);
-
+  for (nsIContent* child = aContent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+       
     if (!child->IsNodeOfType(nsINode::eTEXT))
       return PR_FALSE;
 
     if (child->TextLength())
       return PR_FALSE;
   }
 
   return PR_TRUE;
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -3656,24 +3656,20 @@ nsGenericHTMLElement::SyncEditorsOnSubtr
   if (element) {
     nsCOMPtr<nsIEditor> editor = element->GetAssociatedEditor();
     if (editor) {
       editor->SyncRealTimeSpell();
     }
   }
 
   /* Sync all children */
-  PRUint32 childCount = content->GetChildCount();
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent* childContent = content->GetChildAt(i);
-    NS_ASSERTION(childContent,
-                 "DOM mutated unexpectedly while syncing editors!");
-    if (childContent) {
-      SyncEditorsOnSubtree(childContent);
-    }
+  for (nsIContent* child = content->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    SyncEditorsOnSubtree(child);
   }
 }
 
 void
 nsGenericHTMLElement::RecompileScriptEventListeners()
 {
     PRInt32 i, count = mAttrsAndChildren.AttrCount();
     for (i = 0; i < count; ++i) {
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -598,23 +598,20 @@ NS_IMETHODIMP nsHTMLMediaElement::Load()
   AbortExistingLoads();
   QueueSelectResourceTask();
   mIsRunningLoadMethod = PR_FALSE;
   return NS_OK;
 }
 
 static PRBool HasSourceChildren(nsIContent *aElement)
 {
-  PRUint32 count = aElement->GetChildCount();
-  for (PRUint32 i = 0; i < count; ++i) {
-    nsIContent* child = aElement->GetChildAt(i);
-    NS_ASSERTION(child, "GetChildCount lied!");
-    if (child &&
-        child->Tag() == nsGkAtoms::source &&
-        child->IsHTML())
+  for (nsIContent* child = aElement->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    if (child->IsHTML(nsGkAtoms::source))
     {
       return PR_TRUE;
     }
   }
   return PR_FALSE;
 }
 
 void nsHTMLMediaElement::SelectResource()
@@ -2523,19 +2520,17 @@ nsIContent* nsHTMLMediaElement::GetNextS
 
     // Advance the range to the next child.
     rv = mSourcePointer->SetStart(thisDomNode, startOffset+1);
     NS_ENSURE_SUCCESS(rv, nsnull);
 
     nsIContent* child = GetChildAt(startOffset);
 
     // If child is a <source> element, it is the next candidate.
-    if (child &&
-        child->Tag() == nsGkAtoms::source &&
-        child->IsHTML())
+    if (child && child->IsHTML(nsGkAtoms::source))
     {
       mSourceLoadCandidate = child;
       return child;
     }
   }
   NS_NOTREACHED("Execution should not reach here!");
   return nsnull;
 }
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -386,19 +386,20 @@ nsHTMLSelectElement::InsertOptionsIntoLi
   if (aDepth == 0) {
     mNonOptionChildren++;
   }
 
   // Recurse down into optgroups
   if (aOptions->IsHTML(nsGkAtoms::optgroup)) {
     mOptGroupCount++;
 
-    PRUint32 numChildren = aOptions->GetChildCount();
-    for (PRUint32 i = 0; i < numChildren; ++i) {
-      nsresult rv = InsertOptionsIntoListRecurse(aOptions->GetChildAt(i),
+    for (nsIContent* child = aOptions->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
+      nsresult rv = InsertOptionsIntoListRecurse(child,
                                                  aInsertIndex, aDepth+1);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
 }
 
@@ -430,19 +431,21 @@ nsHTMLSelectElement::RemoveOptionsFromLi
   if (aDepth == 0) {
     mNonOptionChildren--;
   }
 
   // Recurse down deeper for options
   if (mOptGroupCount && aOptions->IsHTML(nsGkAtoms::optgroup)) {
     mOptGroupCount--;
 
-    PRUint32 numChildren = aOptions->GetChildCount();
-    for (PRUint32 i = 0; i < numChildren; ++i) {
-      nsresult rv = RemoveOptionsFromListRecurse(aOptions->GetChildAt(i),
+    for (nsIContent* child = aOptions->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
+
+      nsresult rv = RemoveOptionsFromListRecurse(child,
                                                  aRemoveIndex,
                                                  aNumRemoved,
                                                  aDepth + 1);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -405,22 +405,21 @@ nsHTMLTableElement::SetCaption(nsIDOMHTM
   }
 
   return rv;
 }
 
 already_AddRefed<nsIDOMHTMLTableSectionElement>
 nsHTMLTableElement::GetSection(nsIAtom *aTag)
 {
-  PRUint32 childCount = GetChildCount();
-
   nsCOMPtr<nsIDOMHTMLTableSectionElement> section;
 
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent *child = GetChildAt(i);
+  for (nsIContent* child = nsINode::GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
 
     section = do_QueryInterface(child);
 
     if (section && child->NodeInfo()->Equals(aTag)) {
       nsIDOMHTMLTableSectionElement *result = section;
       NS_ADDREF(result);
 
       return result;
@@ -762,19 +761,19 @@ nsHTMLTableElement::InsertRow(PRInt32 aI
     }
   }
   else
   { // the row count was 0, so 
     // find the first row group and insert there as first child
     nsCOMPtr<nsIDOMNode> rowGroup;
 
     PRInt32 namespaceID = mNodeInfo->NamespaceID();
-    PRUint32 childCount = GetChildCount();
-    for (PRUint32 i = 0; i < childCount; ++i) {
-      nsIContent* child = GetChildAt(i);
+    for (nsIContent* child = nsINode::GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
       nsINodeInfo *childInfo = child->NodeInfo();
       nsIAtom *localName = childInfo->NameAtom();
       if (childInfo->NamespaceID() == namespaceID &&
           (localName == nsGkAtoms::thead ||
            localName == nsGkAtoms::tbody ||
            localName == nsGkAtoms::tfoot)) {
         rowGroup = do_QueryInterface(child);
         NS_ASSERTION(rowGroup, "HTML node did not QI to nsIDOMNode");
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -526,17 +526,17 @@ nsTextInputSelectionImpl::CompleteMove(P
   {
     offset = parentDIV->GetChildCount();
 
     // Prevent the caret from being placed after the last
     // BR node in the content tree!
 
     if (offset > 0)
     {
-      nsIContent *child = parentDIV->GetChildAt(offset - 1);
+      nsIContent *child = parentDIV->GetLastChild();
 
       if (child->Tag() == nsGkAtoms::br)
       {
         --offset;
         hint = nsFrameSelection::HINTRIGHT; // for Bug 106855
       }
     }
   }
@@ -1748,17 +1748,17 @@ nsTextEditorState::SetValue(const nsAStr
     }
 #endif
 
     nsAutoString currentValue;
     if (!mEditorInitialized && IsSingleLineTextControl()) {
       // Grab the current value directly from the text node to make sure that we
       // deal with stale data correctly.
       NS_ASSERTION(mRootNode, "We should have a root node here");
-      nsIContent *textContent = mRootNode->GetChildAt(0);
+      nsIContent *textContent = mRootNode->GetFirstChild();
       nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(textContent);
       if (textNode) {
         textNode->GetData(currentValue);
       }
     } else {
       mBoundFrame->GetText(currentValue);
     }
 
@@ -1973,18 +1973,18 @@ nsTextEditorState::UpdatePlaceholderText
   if (!mPlaceholderDiv)
     return;
 
   nsAutoString placeholderValue;
 
   nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
   content->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderValue);
   nsContentUtils::RemoveNewlines(placeholderValue);
-  NS_ASSERTION(mPlaceholderDiv->GetChildAt(0), "placeholder div has no child");
-  mPlaceholderDiv->GetChildAt(0)->SetText(placeholderValue, aNotify);
+  NS_ASSERTION(mPlaceholderDiv->GetFirstChild(), "placeholder div has no child");
+  mPlaceholderDiv->GetFirstChild()->SetText(placeholderValue, aNotify);
   ValueWasChanged(aNotify);
 }
 
 void
 nsTextEditorState::SetPlaceholderClass(PRBool aVisible,
                                        PRBool aNotify)
 {
   NS_ASSERTION(mPlaceholderDiv, "This function should not be called if "
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2695,19 +2695,19 @@ nsHTMLDocument::GetDocumentAllResult(con
 
   return cont;
 }
 
 static void
 NotifyEditableStateChange(nsINode *aNode, nsIDocument *aDocument,
                           PRBool aEditable)
 {
-  PRUint32 i, n = aNode->GetChildCount();
-  for (i = 0; i < n; ++i) {
-    nsIContent *child = aNode->GetChildAt(i);
+  for (nsIContent* child = aNode->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->HasFlag(NODE_IS_EDITABLE) != aEditable &&
         child->IsElement()) {
       child->AsElement()->UpdateState(true);
     }
     NotifyEditableStateChange(child, aDocument, aEditable);
   }
 }
 
--- a/content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
+++ b/content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
@@ -152,19 +152,19 @@ SVGMotionSMILAnimationFunction::GetCalcM
 
 /*
  * Returns the first <mpath> child of the given element
  */
 
 static nsSVGMpathElement*
 GetFirstMpathChild(nsIContent* aElem)
 {
-  PRUint32 childCount = aElem->GetChildCount();
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent* child = aElem->GetChildAt(i);
+  for (nsIContent* child = aElem->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->Tag() == nsGkAtoms::mpath &&
         child->GetNameSpaceID() == kNameSpaceID_SVG) {
       return static_cast<nsSVGMpathElement*>(child);
     }
   }
 
   return nsnull;
 }
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -1821,20 +1821,22 @@ nsSVGFEComponentTransferElement::Filter(
   PRUint8* sourceData = aSources[0]->mImage->Data();
   PRUint8* targetData = aTarget->mImage->Data();
   PRUint32 stride = aTarget->mImage->Stride();
 
   PRUint8 tableR[256], tableG[256], tableB[256], tableA[256];
   for (int i=0; i<256; i++)
     tableR[i] = tableG[i] = tableB[i] = tableA[i] = i;
   PRUint8* tables[] = { tableR, tableG, tableB, tableA };
-  PRUint32 count = GetChildCount();
-  for (PRUint32 k = 0; k < count; k++) {
+  for (nsIContent* childContent = nsINode::GetFirstChild();
+       childContent;
+       childContent = childContent->GetNextSibling()) {
+
     nsRefPtr<nsSVGComponentTransferFunctionElement> child;
-    CallQueryInterface(GetChildAt(k),
+    CallQueryInterface(childContent,
             (nsSVGComponentTransferFunctionElement**)getter_AddRefs(child));
     if (child) {
       child->GenerateLookupTable(tables[child->GetChannel()]);
     }
   }
 
   for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
     for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
@@ -2372,19 +2374,19 @@ nsSVGFEMergeElement::Filter(nsSVGFilterI
     ctx.Paint();
   }
   return NS_OK;
 }
 
 void
 nsSVGFEMergeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
 {
-  PRUint32 count = GetChildCount();
-  for (PRUint32 i = 0; i < count; i++) {
-    nsIContent* child = GetChildAt(i);
+  for (nsIContent* child = nsINode::GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     nsRefPtr<nsSVGFEMergeNodeElement> node;
     CallQueryInterface(child, (nsSVGFEMergeNodeElement**)getter_AddRefs(node));
     if (node) {
       aSources.AppendElement(nsSVGStringInfo(node->In1(), node));
     }
   }
 }
 
@@ -4863,20 +4865,20 @@ nsSVGFELightingElement::Filter(nsSVGFilt
   nsCOMPtr<nsIDOMSVGFESpotLightElement> spotLight;
 
   nsIFrame* frame = GetPrimaryFrame();
   if (!frame) return NS_ERROR_FAILURE;
   nsStyleContext* style = frame->GetStyleContext();
 
   nscolor lightColor = style->GetStyleSVGReset()->mLightingColor;
 
-  // find specified light
-  PRUint32 count = GetChildCount();
-  for (PRUint32 k = 0; k < count; k++) {
-    nsCOMPtr<nsIContent> child = GetChildAt(k);
+  // find specified light  
+  for (nsCOMPtr<nsIContent> child = nsINode::GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     distantLight = do_QueryInterface(child);
     pointLight = do_QueryInterface(child);
     spotLight = do_QueryInterface(child);
     if (distantLight || pointLight || spotLight)
       break;
   }
 
   if (!distantLight && !pointLight && !spotLight)
--- a/content/svg/content/src/nsSVGSwitchElement.cpp
+++ b/content/svg/content/src/nsSVGSwitchElement.cpp
@@ -162,23 +162,22 @@ nsSVGSwitchElement::FindActiveChild() co
 {
   PRBool allowReorder = AttrValueIs(kNameSpaceID_None,
                                     nsGkAtoms::allowReorder,
                                     nsGkAtoms::yes, eCaseMatters);
 
   const nsAdoptingString& acceptLangs =
     Preferences::GetLocalizedString("intl.accept_languages");
 
-  PRUint32 count = GetChildCount();
-
   if (allowReorder && !acceptLangs.IsEmpty()) {
     PRInt32 bestLanguagePreferenceRank = -1;
     nsIContent *bestChild = nsnull;
-    for (PRUint32 i = 0; i < count; i++) {
-      nsIContent *child = GetChildAt(i);
+    for (nsIContent* child = nsINode::GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
       if (nsSVGFeatures::PassesConditionalProcessingTests(
             child, nsSVGFeatures::kIgnoreSystemLanguage)) {
         nsAutoString value;
         if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::systemLanguage,
                            value)) {
           PRInt32 languagePreferenceRank =
             nsSVGFeatures::GetBestLanguagePreferenceRank(value, acceptLangs);
           switch (languagePreferenceRank) {
@@ -199,16 +198,17 @@ nsSVGSwitchElement::FindActiveChild() co
         } else if (!bestChild) {
           bestChild = child;
         }
       }
     }
     return bestChild;
   }
 
-  for (PRUint32 i = 0; i < count; i++) {
-    nsIContent *child = GetChildAt(i);
+  for (nsIContent* child = nsINode::GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (nsSVGFeatures::PassesConditionalProcessingTests(child, &acceptLangs)) {
       return child;
     }
   }
   return nsnull;
 }
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -361,17 +361,17 @@ nsSVGUseElement::CreateAnonymousContent(
 
       newcontent->GetAttr(nsID, lname, value);
       svgNode->SetAttr(nsID, lname, name->GetPrefix(), value, PR_FALSE);
     }
 
     // move the children over
     PRUint32 num = newcontent->GetChildCount();
     for (i = 0; i < num; i++) {
-      nsCOMPtr<nsIContent> child = newcontent->GetChildAt(0);
+      nsCOMPtr<nsIContent> child = newcontent->GetFirstChild();
       newcontent->RemoveChildAt(0, PR_FALSE);
       svgNode->InsertChildAt(child, i, PR_TRUE);
     }
 
     newcontent = svgNode;
   }
 
   if (symbol || svg) {
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -344,20 +344,19 @@ nsXBLBinding::InstallAnonymousContent(ns
   // to all its kids, which are anonymous content from the point of view of
   // aElement.
   // (2) The children's parent back pointer should not be to this synthetic root
   // but should instead point to the enclosing parent element.
   nsIDocument* doc = aElement->GetCurrentDoc();
   PRBool allowScripts = AllowScripts();
 
   nsAutoScriptBlocker scriptBlocker;
-
-  PRUint32 childCount = aAnonParent->GetChildCount();
-  for (PRUint32 i = 0; i < childCount; i++) {
-    nsIContent *child = aAnonParent->GetChildAt(i);
+  for (nsIContent* child = aAnonParent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     child->UnbindFromTree();
     nsresult rv =
       child->BindToTree(doc, aElement, mBoundElement, allowScripts);
     if (NS_FAILED(rv)) {
       // Oh, well... Just give up.
       // XXXbz This really shouldn't be a void method!
       child->UnbindFromTree();
       return;
@@ -382,19 +381,19 @@ nsXBLBinding::UninstallAnonymousContent(
 {
   nsAutoScriptBlocker scriptBlocker;
   // Hold a strong ref while doing this, just in case.
   nsCOMPtr<nsIContent> anonParent = aAnonParent;
 #ifdef MOZ_XUL
   nsCOMPtr<nsIXULDocument> xuldoc =
     do_QueryInterface(aDocument);
 #endif
-  PRUint32 childCount = aAnonParent->GetChildCount();
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent* child = aAnonParent->GetChildAt(i);
+  for (nsIContent* child = aAnonParent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     child->UnbindFromTree();
 #ifdef MOZ_XUL
     if (xuldoc) {
       xuldoc->RemoveSubtreeFromDocument(child);
     }
 #endif
   }
 }
@@ -571,21 +570,21 @@ RealizeDefaultContent(nsISupports* aKey,
         binding->InstallAnonymousContent(clonedContent, insParent);
 
         // Cache the clone so that it can be properly destroyed if/when our
         // other anonymous content is destroyed.
         currPoint->SetDefaultContent(clonedContent);
 
         // Now make sure the kids of the clone are added to the insertion point as
         // children.
-        PRUint32 cloneKidCount = clonedContent->GetChildCount();
-        for (PRUint32 k = 0; k < cloneKidCount; k++) {
-          nsIContent *cloneChild = clonedContent->GetChildAt(k);
-          bm->SetInsertionParent(cloneChild, insParent);
-          currPoint->AddChild(cloneChild);
+        for (nsIContent* child = clonedContent->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
+          bm->SetInsertionParent(child, insParent);
+          currPoint->AddChild(child);
         }
       }
     }
   }
 
   return PL_DHASH_NEXT;
 }
 
@@ -1173,21 +1172,20 @@ nsXBLBinding::ChangeDocument(nsIDocument
                                           nsnull);
 
         nsXBLBinding::UninstallAnonymousContent(aOldDocument, anonymous);
       }
 
       // Make sure that henceforth we don't claim that mBoundElement's children
       // have insertion parents in the old document.
       nsBindingManager* bindingManager = aOldDocument->BindingManager();
-      for (PRUint32 i = mBoundElement->GetChildCount(); i > 0; --i) {
-        NS_ASSERTION(mBoundElement->GetChildAt(i-1),
-                     "Must have child at i for 0 <= i < GetChildCount()!");
-        bindingManager->SetInsertionParent(mBoundElement->GetChildAt(i-1),
-                                           nsnull);
+      for (nsIContent* child = mBoundElement->GetLastChild();
+           child;
+           child = child->GetPreviousSibling()) {
+        bindingManager->SetInsertionParent(child, nsnull);
       }
     }
   }
 }
 
 PRBool
 nsXBLBinding::InheritsStyle() const
 {
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -809,20 +809,19 @@ nsXBLPrototypeBinding::ImplementsInterfa
   return PR_FALSE;
 }
 
 // Internal helpers ///////////////////////////////////////////////////////////////////////
 
 nsIContent*
 nsXBLPrototypeBinding::GetImmediateChild(nsIAtom* aTag)
 {
-  PRUint32 childCount = mBinding->GetChildCount();
-
-  for (PRUint32 i = 0; i < childCount; i++) {
-    nsIContent* child = mBinding->GetChildAt(i);
+  for (nsIContent* child = mBinding->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->NodeInfo()->Equals(aTag, kNameSpaceID_XBL)) {
       return child;
     }
   }
 
   return nsnull;
 }
  
@@ -1175,19 +1174,20 @@ nsXBLPrototypeBinding::ConstructAttribut
         token = nsCRT::strtok( newStr, ", ", &newStr );
       }
 
       nsMemory::Free(str);
     }
   }
 
   // Recur into our children.
-  PRUint32 childCount = aElement->GetChildCount();
-  for (PRUint32 i = 0; i < childCount; i++) {
-    ConstructAttributeTable(aElement->GetChildAt(i));
+  for (nsIContent* child = aElement->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    ConstructAttributeTable(child);
   }
 }
 
 static PRBool
 DeleteInsertionPointEntry(nsHashKey* aKey, void* aData, void* aClosure)
 {
   static_cast<nsXBLInsertionPointEntry*>(aData)->Release();
   return PR_TRUE;
@@ -1357,20 +1357,19 @@ nsXBLPrototypeBinding::ConstructInterfac
   return NS_OK;
 }
 
 void
 nsXBLPrototypeBinding::GetNestedChildren(nsIAtom* aTag, PRInt32 aNamespace,
                                          nsIContent* aContent,
                                          nsCOMArray<nsIContent> & aList)
 {
-  PRUint32 childCount = aContent->GetChildCount();
-
-  for (PRUint32 i = 0; i < childCount; i++) {
-    nsIContent *child = aContent->GetChildAt(i);
+  for (nsIContent* child = aContent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
 
     if (child->NodeInfo()->Equals(aTag, aNamespace)) {
       aList.AppendObject(child);
     }
     else
       GetNestedChildren(aTag, aNamespace, child, aList);
   }
 }
--- a/content/xbl/src/nsXBLWindowKeyHandler.cpp
+++ b/content/xbl/src/nsXBLWindowKeyHandler.cpp
@@ -206,18 +206,19 @@ NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler
 static void
 BuildHandlerChain(nsIContent* aContent, nsXBLPrototypeHandler** aResult)
 {
   *aResult = nsnull;
 
   // Since we chain each handler onto the next handler,
   // we'll enumerate them here in reverse so that when we
   // walk the chain they'll come out in the original order
-  for (PRUint32 j = aContent->GetChildCount(); j--; ) {
-    nsIContent *key = aContent->GetChildAt(j);
+  for (nsIContent* key = aContent->GetLastChild();
+       key;
+       key = key->GetPreviousSibling()) {
 
     if (key->NodeInfo()->Equals(nsGkAtoms::key, kNameSpaceID_XUL)) {
       // Check whether the key element has empty value at key/char attribute.
       // Such element is used by localizers for alternative shortcut key
       // definition on the locale. See bug 426501.
       nsAutoString valKey, valCharCode, valKeyCode;
       PRBool attrExists =
         key->GetAttr(kNameSpaceID_None, nsGkAtoms::key, valKey) ||
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -301,19 +301,19 @@ nsXMLContentSink::DidBuildModel(PRBool a
   DidBuildModelImpl(aTerminated);
 
   if (mXSLTProcessor) {
     // stop observing in order to avoid crashing when replacing content
     mDocument->RemoveObserver(this);
     mIsDocumentObserver = PR_FALSE;
 
     // Check for xslt-param and xslt-param-namespace PIs
-    PRUint32 i;
-    nsIContent* child;
-    for (i = 0; (child = mDocument->GetChildAt(i)); ++i) {
+    for (nsIContent* child = mDocument->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
       if (child->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
         nsCOMPtr<nsIDOMProcessingInstruction> pi = do_QueryInterface(child);
         CheckXSLTParamPI(pi, mXSLTProcessor, mDocument);
       }
       else if (child->IsElement()) {
         // Only honor PIs in the prolog
         break;
       }
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -204,17 +204,17 @@ txXPathTreeWalker::moveToFirstChild()
     }
 
     NS_ASSERTION(!mPosition.isDocument() ||
                  (mCurrentIndex == kUnknownIndex && mDescendants.IsEmpty()),
                  "we shouldn't have any position info at the document");
     NS_ASSERTION(mCurrentIndex != kUnknownIndex || mDescendants.IsEmpty(),
                  "Index should be known if parents index are");
 
-    nsIContent* child = mPosition.mNode->GetChildAt(0);
+    nsIContent* child = mPosition.mNode->GetFirstChild();
     if (!child) {
         return PR_FALSE;
     }
     mPosition.mIndex = txXPathNode::eContent;
     mPosition.mNode = child;
 
     if (mCurrentIndex != kUnknownIndex &&
         !mDescendants.AppendValue(mCurrentIndex)) {
@@ -237,17 +237,17 @@ txXPathTreeWalker::moveToLastChild()
                  "we shouldn't have any position info at the document");
     NS_ASSERTION(mCurrentIndex != kUnknownIndex || mDescendants.IsEmpty(),
                  "Index should be known if parents index are");
 
     PRUint32 total = mPosition.mNode->GetChildCount();
     if (!total) {
         return PR_FALSE;
     }
-    mPosition.mNode = mPosition.mNode->GetChildAt(total - 1);
+    mPosition.mNode = mPosition.mNode->GetLastChild();
 
     if (mCurrentIndex != kUnknownIndex &&
         !mDescendants.AppendValue(mCurrentIndex)) {
         mDescendants.Clear();
     }
     mCurrentIndex = total - 1;
 
     return PR_TRUE;
--- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
@@ -599,41 +599,38 @@ handleNode(nsINode* aNode, txStylesheetC
                                      ni->NameAtom(),
                                      ni->GetPrefixAtom(), atts,
                                      attsCount);
         NS_ENSURE_SUCCESS(rv, rv);
 
         // explicitly destroy the attrs here since we no longer need it
         atts = nsnull;
 
-        PRUint32 childCount = element->GetChildCount();
-        if (childCount > 0) {
-            PRUint32 counter = 0;
-            nsIContent *child;
-            while ((child = element->GetChildAt(counter++))) {
-                rv = handleNode(child, aCompiler);
-                NS_ENSURE_SUCCESS(rv, rv);
-            }
+        for (nsIContent* child = element->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
+             
+            rv = handleNode(child, aCompiler);
+            NS_ENSURE_SUCCESS(rv, rv);
         }
 
         rv = aCompiler->endElement();
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else if (aNode->IsNodeOfType(nsINode::eTEXT)) {
         nsAutoString chars;
         static_cast<nsIContent*>(aNode)->AppendTextTo(chars);
         rv = aCompiler->characters(chars);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
-        nsIDocument* document = static_cast<nsIDocument*>(aNode);
-
-        PRUint32 counter = 0;
-        nsIContent *child;
-        while ((child = document->GetChildAt(counter++))) {
+        for (nsIContent* child = aNode->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
+             
             rv = handleNode(child, aCompiler);
             NS_ENSURE_SUCCESS(rv, rv);
         }
     }
 
     return NS_OK;
 }
 
--- a/content/xul/content/src/nsXULPopupListener.cpp
+++ b/content/xul/content/src/nsXULPopupListener.cpp
@@ -311,31 +311,29 @@ nsXULPopupListener::ClosePopup()
     // fire events during destruction.  
     nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     if (pm)
       pm->HidePopup(mPopupContent, PR_FALSE, PR_TRUE, PR_TRUE);
     mPopupContent = nsnull;  // release the popup
   }
 } // ClosePopup
 
-static void
-GetImmediateChild(nsIContent* aContent, nsIAtom *aTag, nsIContent** aResult) 
+static already_AddRefed<nsIContent>
+GetImmediateChild(nsIContent* aContent, nsIAtom *aTag) 
 {
-  *aResult = nsnull;
-  PRInt32 childCount = aContent->GetChildCount();
-  for (PRInt32 i = 0; i < childCount; i++) {
-    nsIContent *child = aContent->GetChildAt(i);
+  for (nsIContent* child = aContent->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->Tag() == aTag) {
-      *aResult = child;
-      NS_ADDREF(*aResult);
-      return;
+      NS_ADDREF(child);
+      return child;
     }
   }
 
-  return;
+  return nsnull;
 }
 
 //
 // LaunchPopup
 //
 // Given the element on which the event was triggered and the mouse locations in
 // Client and widget coordinates, popup a new window showing the appropriate 
 // content.
@@ -379,19 +377,17 @@ nsXULPopupListener::LaunchPopup(nsIDOMEv
     NS_ERROR("Popup attached to an element that isn't in XUL!");
     return NS_ERROR_FAILURE;
   }
 
   // Handle the _child case for popups and context menus
   nsCOMPtr<nsIDOMElement> popupElement;
 
   if (identifier.EqualsLiteral("_child")) {
-    nsCOMPtr<nsIContent> popup;
-
-    GetImmediateChild(content, nsGkAtoms::menupopup, getter_AddRefs(popup));
+    nsCOMPtr<nsIContent> popup = GetImmediateChild(content, nsGkAtoms::menupopup);
     if (popup)
       popupElement = do_QueryInterface(popup);
     else {
       nsCOMPtr<nsIDOMDocumentXBL> nsDoc(do_QueryInterface(domDocument));
       nsCOMPtr<nsIDOMNodeList> list;
       nsDoc->GetAnonymousNodes(mElement, getter_AddRefs(list));
       if (list) {
         PRUint32 ctr,listLength;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -925,24 +925,24 @@ nsXULDocument::ExecuteOnBroadcastHandler
                                             nsIDOMElement* aListener,
                                             nsIAtom* aAttr)
 {
     // Now we execute the onchange handler in the context of the
     // observer. We need to find the observer in order to
     // execute the handler.
 
     nsCOMPtr<nsIContent> listener = do_QueryInterface(aListener);
-    PRUint32 count = listener->GetChildCount();
-    for (PRUint32 i = 0; i < count; ++i) {
+    for (nsIContent* child = listener->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
+
         // Look for an <observes> element beneath the listener. This
         // ought to have an |element| attribute that refers to
         // aBroadcaster, and an |attribute| element that tells us what
         // attriubtes we're listening for.
-        nsIContent *child = listener->GetChildAt(i);
-
         if (!child->NodeInfo()->Equals(nsGkAtoms::observes, kNameSpaceID_XUL))
             continue;
 
         // Is this the element that was listening to us?
         nsAutoString listeningToID;
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::element, listeningToID);
 
         nsAutoString broadcasterID;
@@ -1759,20 +1759,21 @@ nsXULDocument::AddSubtreeToDocument(nsIC
 
     Element* aElement = aContent->AsElement();
 
     // Do pre-order addition magic
     nsresult rv = AddElementToDocumentPre(aElement);
     if (NS_FAILED(rv)) return rv;
 
     // Recurse to children
-    PRUint32 count = aElement->GetChildCount();
-
-    while (count-- > 0) {
-        rv = AddSubtreeToDocument(aElement->GetChildAt(count));
+    for (nsIContent* child = aElement->GetLastChild();
+         child;
+         child = child->GetPreviousSibling()) {
+
+        rv = AddSubtreeToDocument(child);
         if (NS_FAILED(rv))
             return rv;
     }
 
     // Do post-order addition magic
     return AddElementToDocumentPost(aElement);
 }
 
@@ -1793,20 +1794,21 @@ nsXULDocument::RemoveSubtreeFromDocument
     if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
         nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
         if (xblService) {
             xblService->DetachGlobalKeyHandler(aElement);
         }
     }
 
     // 1. Remove any children from the document.
-    PRUint32 count = aElement->GetChildCount();
-
-    while (count-- > 0) {
-        rv = RemoveSubtreeFromDocument(aElement->GetChildAt(count));
+    for (nsIContent* child = aElement->GetLastChild();
+         child;
+         child = child->GetPreviousSibling()) {
+
+        rv = RemoveSubtreeFromDocument(child);
         if (NS_FAILED(rv))
             return rv;
     }
 
     // 2. Remove the element from the resource-to-element map.
     // Also remove it from the id map, since we added it in
     // AddElementToDocumentPre().
     RemoveElementFromRefMap(aElement);
@@ -4072,17 +4074,17 @@ nsXULDocument::OverlayForwardReference::
 
     PRUint32 childCount = aOverlayNode->GetChildCount();
 
     // This must be a strong reference since it will be the only
     // reference to a content object during part of this loop.
     nsCOMPtr<nsIContent> currContent;
 
     for (i = 0; i < childCount; ++i) {
-        currContent = aOverlayNode->GetChildAt(0);
+        currContent = aOverlayNode->GetFirstChild();
 
         nsIAtom *idAtom = currContent->GetID();
 
         nsIContent *elementInDocument = nsnull;
         if (idAtom) {
             nsDependentAtomString id(idAtom);
 
             if (!id.IsEmpty()) {
--- a/content/xul/templates/src/nsContentSupportMap.cpp
+++ b/content/xul/templates/src/nsContentSupportMap.cpp
@@ -54,20 +54,19 @@ nsContentSupportMap::Finish()
         PL_DHashTableFinish(&mMap);
 }
 
 nsresult
 nsContentSupportMap::Remove(nsIContent* aElement)
 {
     if (!mMap.ops)
         return NS_ERROR_NOT_INITIALIZED;
-
-    PL_DHashTableOperate(&mMap, aElement, PL_DHASH_REMOVE);
-
-    PRUint32 count = aElement->GetChildCount();
-    for (PRUint32 i = 0; i < count; ++i) {
-        Remove(aElement->GetChildAt(i));
-    }
+    
+    nsIContent* child = aElement;    
+    do {
+        PL_DHashTableOperate(&mMap, child, PL_DHASH_REMOVE);
+        child = child->GetNextNode(aElement);
+    } while(child);
 
     return NS_OK;
 }
 
 
--- a/content/xul/templates/src/nsTemplateMap.h
+++ b/content/xul/templates/src/nsTemplateMap.h
@@ -76,19 +76,20 @@ public:
             entry->mTemplate = aTemplate;
         }
     }
 
     void
     Remove(nsIContent* aContent) {
         PL_DHashTableOperate(&mTable, aContent, PL_DHASH_REMOVE);
 
-        PRUint32 count = aContent->GetChildCount();
-        for (PRUint32 i = 0; i < count; ++i) {
-            Remove(aContent->GetChildAt(i));
+        for (nsIContent* child = aContent->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
+            Remove(child);
         }
     }
 
 
     void
     GetTemplateFor(nsIContent* aContent, nsIContent** aResult) {
         Entry* entry =
             reinterpret_cast<Entry*>(PL_DHashTableOperate(&mTable, aContent, PL_DHASH_LOOKUP));
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -493,20 +493,19 @@ nsXULContentBuilder::BuildContentFromTem
                 nsAtomCString(aTemplateNode->Tag()).get(), 
                 nsAtomCString(aResourceNode->Tag()).get(),
                 nsAtomCString(aRealNode->Tag()).get(), NS_ConvertUTF16toUTF8(id).get()));
     }
 #endif
 
     // Iterate through all of the template children, constructing
     // "real" content model nodes for each "template" child.
-    PRUint32 count = aTemplateNode->GetChildCount();
-
-    for (PRUint32 kid = 0; kid < count; kid++) {
-        nsIContent *tmplKid = aTemplateNode->GetChildAt(kid);
+    for (nsIContent* tmplKid = aTemplateNode->GetFirstChild();
+         tmplKid;
+         tmplKid = tmplKid->GetNextSibling()) {
 
         PRInt32 nameSpaceID = tmplKid->GetNameSpaceID();
 
         // Check whether this element is the generation element. The generation
         // element is the element that is cookie-cutter copied once for each
         // different result specified by |aChild|.
         //
         // Nodes that appear -above- the generation element
@@ -1930,18 +1929,20 @@ nsXULContentBuilder::InsertSortedNode(ns
         {
             // found "static" XUL element count hint
             PRInt32 strErr = 0;
             staticCount = staticValue.ToInteger(&strErr);
             if (strErr)
                 staticCount = 0;
         } else {
             // compute the "static" XUL element count
-            for (PRUint32 childLoop = 0; childLoop < numChildren; ++childLoop) {
-                child = aContainer->GetChildAt(childLoop);
+            for (nsIContent* child = aContainer->GetFirstChild();
+                 child;
+                 child = child->GetNextSibling()) {
+                 
                 if (nsContentUtils::HasNonEmptyAttr(child, kNameSpaceID_None,
                                                     nsGkAtoms::_template))
                     break;
                 else
                     ++staticCount;
             }
 
             if (mSortState.sortStaticsLast) {
--- a/content/xul/templates/src/nsXULContentUtils.cpp
+++ b/content/xul/templates/src/nsXULContentUtils.cpp
@@ -196,23 +196,22 @@ nsXULContentUtils::GetCollation()
 //------------------------------------------------------------------------
 
 nsresult
 nsXULContentUtils::FindChildByTag(nsIContent* aElement,
                                   PRInt32 aNameSpaceID,
                                   nsIAtom* aTag,
                                   nsIContent** aResult)
 {
-    PRUint32 count = aElement->GetChildCount();
+    for (nsIContent* child = aElement->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
 
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsIContent *kid = aElement->GetChildAt(i);
-
-        if (kid->NodeInfo()->Equals(aTag, aNameSpaceID)) {
-            NS_ADDREF(*aResult = kid);
+        if (child->NodeInfo()->Equals(aTag, aNameSpaceID)) {
+            NS_ADDREF(*aResult = child);
 
             return NS_OK;
         }
     }
 
     *aResult = nsnull;
     return NS_RDF_NO_VALUE; // not found
 }
--- a/content/xul/templates/src/nsXULSortService.cpp
+++ b/content/xul/templates/src/nsXULSortService.cpp
@@ -104,21 +104,19 @@ XULSortServiceImpl::SetSortHints(nsICont
 
 void
 XULSortServiceImpl::SetSortColumnHints(nsIContent *content,
                                        const nsAString &sortResource,
                                        const nsAString &sortDirection)
 {
   // set sort info on current column. This ensures that the
   // column header sort indicator is updated properly.
-  PRUint32 numChildren = content->GetChildCount();
-
-  for (PRUint32 childIndex = 0; childIndex < numChildren; ++childIndex) {
-    nsIContent *child = content->GetChildAt(childIndex);
-
+  for (nsIContent* child = content->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     if (child->IsXUL()) {
       nsIAtom *tag = child->Tag();
 
       if (tag == nsGkAtoms::treecols) {
         SetSortColumnHints(child, sortResource, sortDirection);
       } else if (tag == nsGkAtoms::treecol) {
         nsAutoString value;
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::sort, value);
@@ -172,21 +170,20 @@ XULSortServiceImpl::GetItemsToSort(nsICo
                                       kNameSpaceID_XUL,
                                       nsGkAtoms::treechildren,
                                       getter_AddRefs(treechildren));
     if (!treechildren)
       return NS_OK;
   
     aContainer = treechildren;
   }
-
-  PRUint32 count = aContainer->GetChildCount();
-  for (PRUint32 c = 0; c < count; c++) {
-    nsIContent *child = aContainer->GetChildAt(c);
-
+  
+  for (nsIContent* child = aContainer->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
     contentSortInfo* cinfo = aSortItems.AppendElement();
     if (!cinfo)
       return NS_ERROR_OUT_OF_MEMORY;
 
     cinfo->content = child;
   }
 
   return NS_OK;
@@ -194,19 +191,19 @@ XULSortServiceImpl::GetItemsToSort(nsICo
 
 
 nsresult
 XULSortServiceImpl::GetTemplateItemsToSort(nsIContent* aContainer,
                                            nsIXULTemplateBuilder* aBuilder,
                                            nsSortState* aSortState,
                                            nsTArray<contentSortInfo>& aSortItems)
 {
-  PRUint32 numChildren = aContainer->GetChildCount();
-  for (PRUint32 childIndex = 0; childIndex < numChildren; childIndex++) {
-    nsIContent *child = aContainer->GetChildAt(childIndex);
+  for (nsIContent* child = aContainer->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
   
     nsCOMPtr<nsIDOMElement> childnode = do_QueryInterface(child);
 
     nsCOMPtr<nsIXULTemplateResult> result;
     nsresult rv = aBuilder->GetResultForContent(childnode, getter_AddRefs(result));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (result) {
@@ -342,19 +339,19 @@ XULSortServiceImpl::SortContainer(nsICon
       parent->AppendChildTo(child, PR_TRUE);
 
       // if it's a container in a tree or menu, find its children,
       // and sort those also
       if (!child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::container,
                               nsGkAtoms::_true, eCaseMatters))
         continue;
         
-      PRUint32 numChildren = child->GetChildCount();
-      for (PRUint32 gcindex = 0; gcindex < numChildren; gcindex++) {
-        nsIContent *grandchild = child->GetChildAt(gcindex);
+      for (nsIContent* grandchild = child->GetFirstChild();
+           grandchild;
+           grandchild = grandchild->GetNextSibling()) {
         nsINodeInfo *ni = grandchild->NodeInfo();
         nsIAtom *localName = ni->NameAtom();
         if (ni->NamespaceID() == kNameSpaceID_XUL &&
             (localName == nsGkAtoms::treechildren ||
              localName == nsGkAtoms::menupopup)) {
           SortContainer(grandchild, aSortState);
         }
       }
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -1694,20 +1694,19 @@ nsXULTemplateBuilder::GetTemplateRoot(ns
             return NS_OK;
         }
     }
 
 #if 1 // XXX hack to workaround bug with XBL insertion/removal?
     {
         // If root node has no template attribute, then look for a child
         // node which is a template tag
-        PRUint32 count = mRoot->GetChildCount();
-
-        for (PRUint32 i = 0; i < count; ++i) {
-            nsIContent *child = mRoot->GetChildAt(i);
+        for (nsIContent* child = mRoot->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
 
             if (IsTemplateElement(child)) {
                 NS_ADDREF(*aResult = child);
                 return NS_OK;
             }
         }
     }
 #endif
@@ -1851,20 +1850,20 @@ nsXULTemplateBuilder::CompileTemplate(ns
 {
     NS_ASSERTION(aQuerySet, "No queryset supplied");
 
     nsresult rv = NS_OK;
 
     PRBool isQuerySetMode = PR_FALSE;
     PRBool hasQuerySet = PR_FALSE, hasRule = PR_FALSE, hasQuery = PR_FALSE;
 
-    PRUint32 count = aTemplate->GetChildCount();
-
-    for (PRUint32 i = 0; i < count; i++) {
-        nsIContent *rulenode = aTemplate->GetChildAt(i);
+    for (nsIContent* rulenode = aTemplate->GetFirstChild();
+         rulenode;
+         rulenode = rulenode->GetNextSibling()) {
+
         nsINodeInfo *ni = rulenode->NodeInfo();
 
         // don't allow more queries than can be supported
         if (*aPriority == PR_INT16_MAX)
             return NS_ERROR_FAILURE;
 
         // XXXndeakin queryset isn't a good name for this tag since it only
         //            ever contains one query
@@ -2238,22 +2237,21 @@ nsXULTemplateBuilder::CompileConditions(
     nsAutoString tag;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::parent, tag);
 
     if (!tag.IsEmpty()) {
         nsCOMPtr<nsIAtom> tagatom = do_GetAtom(tag);
         aRule->SetTag(tagatom);
     }
 
-    PRUint32 count = aCondition->GetChildCount();
-
     nsTemplateCondition* currentCondition = nsnull;
 
-    for (PRUint32 i = 0; i < count; i++) {
-        nsIContent *node = aCondition->GetChildAt(i);
+    for (nsIContent* node = aCondition->GetFirstChild();
+         node;
+         node = node->GetNextSibling()) {
 
         if (node->NodeInfo()->Equals(nsGkAtoms::where, kNameSpaceID_XUL)) {
             nsresult rv = CompileWhereCondition(aRule, node, &currentCondition);
             if (NS_FAILED(rv))
                 return rv;
         }
     }
 
@@ -2361,20 +2359,19 @@ nsXULTemplateBuilder::CompileWhereCondit
 }
 
 nsresult
 nsXULTemplateBuilder::CompileBindings(nsTemplateRule* aRule, nsIContent* aBindings)
 {
     // Add an extended rule's bindings.
     nsresult rv;
 
-    PRUint32 count = aBindings->GetChildCount();
-
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsIContent *binding = aBindings->GetChildAt(i);
+    for (nsIContent* binding = aBindings->GetFirstChild();
+         binding;
+         binding = binding->GetNextSibling()) {
 
         if (binding->NodeInfo()->Equals(nsGkAtoms::binding,
                                         kNameSpaceID_XUL)) {
             rv = CompileBinding(aRule, binding);
             if (NS_FAILED(rv))
                 return rv;
         }
     }
@@ -2476,20 +2473,21 @@ nsXULTemplateBuilder::AddSimpleRuleBindi
 
                 // Scan the attribute for variables, adding a binding for
                 // each one.
                 ParseAttribute(value, AddBindingsFor, nsnull, aRule);
             }
         }
 
         // Push kids onto the stack, and search them next.
-        count = element->GetChildCount();
-
-        while (count-- > 0) {
-            if (elements.AppendElement(element->GetChildAt(count)) == nsnull)
+        for (nsIContent* child = element->GetLastChild();
+             child;
+             child = child->GetPreviousSibling()) {
+
+            if (!elements.AppendElement(child))
                 return NS_ERROR_OUT_OF_MEMORY;
         }
     }
 
     aRule->AddBindingsToQueryProcessor(mQueryProcessor);
 
     return NS_OK;
 }
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -1268,24 +1268,23 @@ nsXULTemplateQueryProcessorRDF::CompileE
     nsresult rv = mAllTests.Add(idnode);
     if (NS_FAILED(rv)) {
         delete idnode;
         return rv;
     }
 
     TestNode* prevnode = idnode;
 
-    PRUint32 count = aConditions->GetChildCount();
-
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsIContent *condition = aConditions->GetChildAt(i);
+    for (nsIContent* condition = aConditions->GetFirstChild();
+         condition;
+         condition = condition->GetNextSibling()) {
 
         // the <content> condition should always be the first child
         if (condition->Tag() == nsGkAtoms::content) {
-            if (i) {
+            if (condition != aConditions->GetFirstChild()) {
                 nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_CONTENT_NOT_FIRST);
                 continue;
             }
 
             // check for <content tag='tag'/> which indicates that matches
             // should only be generated for items inside content with that tag
             nsAutoString tagstr;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::tag, tagstr);
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorStorage.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorStorage.cpp
@@ -323,20 +323,19 @@ nsXULTemplateQueryProcessorStorage::Comp
     nsresult rv = mStorageConnection->CreateStatement(NS_ConvertUTF16toUTF8(sqlQuery),
                                                               getter_AddRefs(statement));
     if (NS_FAILED(rv)) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_BAD_QUERY);
         return rv;
     }
 
     PRUint32 parameterCount = 0;
-    PRUint32 count = queryContent->GetChildCount();
-
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsIContent *child = queryContent->GetChildAt(i);
+    for (nsIContent* child = queryContent->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
 
         if (child->NodeInfo()->Equals(nsGkAtoms::param, kNameSpaceID_XUL)) {
             nsAutoString value;
             nsContentUtils::GetNodeTextContent(child, PR_FALSE, value);
 
             PRUint32 index = parameterCount;
             nsAutoString name, indexValue;
 
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
@@ -300,19 +300,20 @@ nsXULTemplateQueryProcessorXML::CompileQ
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_XPATH);
         return rv;
     }
 
     nsRefPtr<nsXMLQuery> query =
         new nsXMLQuery(this, aMemberVariable, compiledexpr);
     NS_ENSURE_TRUE(query, NS_ERROR_OUT_OF_MEMORY);
 
-    PRUint32 count = content->GetChildCount();
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsIContent *condition = content->GetChildAt(i);
+    for (nsIContent* condition = content->GetFirstChild();
+         condition;
+         condition = condition->GetNextSibling()) {
+
         if (condition->NodeInfo()->Equals(nsGkAtoms::assign,
                                           kNameSpaceID_XUL)) {
             nsAutoString var;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::var, var);
 
             nsAutoString expr;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::expr, expr);
 
--- a/content/xul/templates/src/nsXULTemplateResultXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateResultXML.cpp
@@ -91,19 +91,20 @@ nsXULTemplateResultXML::GetIsContainer(P
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultXML::GetIsEmpty(PRBool* aIsEmpty)
 {
     // a node is considered empty if it has no elements as children
     nsCOMPtr<nsIContent> content = do_QueryInterface(mNode);
     if (content) {
-        PRUint32 count = content->GetChildCount();
-        for (PRUint32 c = 0; c < count; c++) {
-            if (content->GetChildAt(c)->IsElement()) {
+        for (nsIContent* child = content->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
+            if (child->IsElement()) {
                 *aIsEmpty = PR_FALSE;
                 return NS_OK;
             }
         }
     }
 
     *aIsEmpty = PR_TRUE;
     return NS_OK;
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -1357,20 +1357,20 @@ nsXULTreeBuilder::EnsureSortVariables()
     nsCOMPtr<nsIContent> treecols;
  
     nsXULContentUtils::FindChildByTag(mRoot, kNameSpaceID_XUL,
                                       nsGkAtoms::treecols,
                                       getter_AddRefs(treecols));
 
     if (!treecols)
         return NS_OK;
-
-    PRUint32 count = treecols->GetChildCount();
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsIContent *child = treecols->GetChildAt(i);
+        
+    for (nsIContent* child = treecols->GetFirstChild();
+         child;
+         child = child->GetNextSibling()) {
 
         if (child->NodeInfo()->Equals(nsGkAtoms::treecol,
                                       kNameSpaceID_XUL)) {
             if (child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::sortActive,
                                    nsGkAtoms::_true, eCaseMatters)) {
                 nsAutoString sort;
                 child->GetAttr(kNameSpaceID_None, nsGkAtoms::sort, sort);
                 if (! sort.IsEmpty()) {
@@ -1496,21 +1496,21 @@ nsXULTreeBuilder::GetTemplateActionCellF
     nsCOMPtr<nsIContent> row;
     GetTemplateActionRowFor(aRow, getter_AddRefs(row));
     if (row) {
         nsCOMPtr<nsIAtom> colAtom;
         PRInt32 colIndex;
         aCol->GetAtom(getter_AddRefs(colAtom));
         aCol->GetIndex(&colIndex);
 
-        PRUint32 count = row->GetChildCount();
         PRUint32 j = 0;
-        for (PRUint32 i = 0; i < count; ++i) {
-            nsIContent *child = row->GetChildAt(i);
-
+        for (nsIContent* child = row->GetFirstChild();
+             child;
+             child = child->GetNextSibling()) {
+            
             if (child->NodeInfo()->Equals(nsGkAtoms::treecell,
                                           kNameSpaceID_XUL)) {
                 if (colAtom &&
                     child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::ref,
                                        colAtom, eCaseMatters)) {
                     *aResult = child;
                     break;
                 }