Bug 682367 - Call nsINode::GetChildAt less. r=smaug
authorDavid Zbarsky <dzbarsky@gmail.com>
Tue, 27 Sep 2011 09:54:58 +0200
changeset 78721 80ff402f2f7e9d4c42b4658febf1a252a89b6347
parent 78720 230ea0b16f035b2f47d2b0b54641dfd3a83a4f4c
child 78722 587115c590ff0da824e1248aa9052be002384f1c
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs682367
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;
                 }