Bug 474369 - get rid of nsVoidArray, remaining parts; r=bz, sr=dbaron
authorArpad Borsos <arpad.borsos@googlemail.com>
Thu, 07 May 2009 17:15:26 +0200
changeset 29128 691dd3dcfbcadd47570db22a231a61b4752d46f5
parent 29127 04ed36482fa986f9c6d4911239b00c6c76790a37
child 29129 2f2586790f322c3e2c1f842a964c2a1c82603072
child 29159 66bd068b6a89a35f8198fd68070ae549859536cf
push idunknown
push userunknown
push dateunknown
reviewersbz, dbaron
bugs474369
milestone1.9.2a1pre
Bug 474369 - get rid of nsVoidArray, remaining parts; r=bz, sr=dbaron
caps/include/nsPrincipal.h
caps/src/nsPrincipal.cpp
chrome/src/nsChromeRegistry.cpp
chrome/src/nsChromeRegistry.h
db/morkreader/nsMorkReader.cpp
docshell/base/nsDocShell.cpp
dom/base/nsIDOMClassInfo.h
dom/src/storage/nsDOMStorage.h
editor/libeditor/base/nsSelectionState.cpp
editor/txmgr/src/nsTransactionManager.cpp
embedding/components/commandhandler/src/nsCommandGroup.h
extensions/java/xpcom/src/nsJavaXPTCStub.cpp
extensions/java/xpcom/src/nsJavaXPTCStub.h
extensions/layout-debug/src/nsRegressionTester.cpp
extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
extensions/pref/system-pref/src/gconf/nsSystemPrefService.h
extensions/spellcheck/src/mozPersonalDictionary.h
extensions/spellcheck/src/mozSpellChecker.h
intl/locale/src/nsLocale.cpp
layout/inspector/src/inCSSValueSearch.cpp
layout/style/nsCSSRuleProcessor.cpp
modules/libpref/src/nsPrefBranch.cpp
modules/libpref/src/nsPrefBranch.h
netwerk/cache/src/nsCacheService.cpp
security/manager/ssl/src/nsKeygenHandler.cpp
security/manager/ssl/src/nsKeygenHandler.h
tools/trace-malloc/leaksoup.cpp
uriloader/base/nsDocLoader.cpp
uriloader/base/nsDocLoader.h
view/src/nsViewManager.cpp
view/src/nsViewManager.h
xpcom/glue/nsTObserverArray.h
xpinstall/src/nsXPITriggerInfo.h
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -37,17 +37,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsPrincipal_h__
 #define nsPrincipal_h__
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
-#include "nsVoidArray.h"
 #include "nsHashtable.h"
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -44,17 +44,16 @@
 #include "nsReadableUtils.h"
 #include "plstr.h"
 #include "nsCRT.h"
 #include "nsIURI.h"
 #include "nsIFileURL.h"
 #include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
 #include "nsJSPrincipals.h"
-#include "nsVoidArray.h"
 #include "nsHashtable.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIClassInfoImpl.h"
 #include "nsDOMError.h"
 
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -238,25 +238,25 @@ CanLoadResource(nsIURI* aResourceURI)
                             nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
                             &isLocalResource);
   return isLocalResource;
 }
 
 nsChromeRegistry::ProviderEntry*
 nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
 {
-  PRInt32 i = mArray.Count();
+  PRInt32 i = mArray.Length();
   if (!i)
     return nsnull;
 
   ProviderEntry* found = nsnull;  // Only set if we find a partial-match locale
   ProviderEntry* entry;
 
   while (i--) {
-    entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    entry = &mArray[i];
     if (aPreferred.Equals(entry->provider))
       return entry;
 
     if (aType != LOCALE)
       continue;
 
     if (LanguagesMatch(aPreferred, entry->provider)) {
       found = entry;
@@ -301,42 +301,31 @@ nsChromeRegistry::nsProviderArray::SetBa
   ProviderEntry* provider = GetProvider(aProvider, EXACT);
 
   if (provider) {
     provider->baseURI = aBaseURL;
     return;
   }
 
   // no existing entries, add a new one
-  provider = new ProviderEntry(aProvider, aBaseURL);
-  if (!provider)
-    return; // It's safe to silently fail on OOM
-
-  mArray.AppendElement(provider);
+  mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
 }
 
 void
 nsChromeRegistry::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
 {
-  PRInt32 i = mArray.Count();
+  PRInt32 i = mArray.Length();
   while (i--) {
-    ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
-    a->AppendElement(entry->provider);
+    a->AppendElement(mArray[i].provider);
   }
 }
 
 void
 nsChromeRegistry::nsProviderArray::Clear()
 {
-  PRInt32 i = mArray.Count();
-  while (i--) {
-    ProviderEntry* entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
-    delete entry;
-  }
-
   mArray.Clear();
 }
 
 nsChromeRegistry::PackageEntry::PackageEntry(const nsACString& aPackage) :
   package(aPackage), flags(0)
 {
 }
 
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -47,17 +47,16 @@
 #endif
 
 #include "pldhash.h"
 
 #include "nsCOMArray.h"
 #include "nsString.h"
 #include "nsTHashtable.h"
 #include "nsURIHashKey.h"
-#include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsInterfaceHashtable.h"
 
 struct PRFileDesc;
 class nsIAtom;
 class nsICSSLoader;
 class nsICSSStyleSheet;
 class nsIDOMWindowInternal;
@@ -166,17 +165,17 @@ public:
     const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
     void    SetBase(const nsACString& aProvider, nsIURI* base);
     void    EnumerateToArray(nsTArray<nsCString> *a);
     void    Clear();
 
   private:
     ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
 
-    nsVoidArray mArray;
+    nsTArray<ProviderEntry> mArray;
   };
 
   struct PackageEntry : public PLDHashEntryHdr
   {
     PackageEntry(const nsACString& package);
     ~PackageEntry() { }
 
     // Available flags
--- a/db/morkreader/nsMorkReader.cpp
+++ b/db/morkreader/nsMorkReader.cpp
@@ -34,17 +34,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMorkReader.h"
 #include "prio.h"
 #include "nsNetUtil.h"
-#include "nsVoidArray.h"
 
 // A FixedString implementation that can hold 2 80-character lines
 class nsCLineString : public nsFixedCString
 {
 public:
   nsCLineString() : fixed_string_type(mStorage, sizeof(mStorage), 0) {}
   explicit nsCLineString(const substring_type& str)
     : fixed_string_type(mStorage, sizeof(mStorage), 0)
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -778,19 +778,19 @@ nsDocShell::Init()
                                      nsIWebProgress::NOTIFY_STATE_NETWORK);
     
 }
 
 void
 nsDocShell::DestroyChildren()
 {
     nsCOMPtr<nsIDocShellTreeItem> shell;
-    PRInt32 n = mChildList.Count();
-    for (PRInt32 i = 0; i < n; i++) {
-        shell = do_QueryInterface(ChildAt(i));
+    PRUint32 n = mChildList.Length();
+    for (PRUint32 i = 0; i < n; i++) {
+        shell = do_QueryInterface(mChildList[i]);
         NS_ASSERTION(shell, "docshell has null child");
 
         if (shell) {
             shell->SetTreeOwner(nsnull);
         }
     }
 
     nsDocLoader::DestroyChildren();
@@ -1438,20 +1438,20 @@ nsDocShell::FirePageHideNotification(PRB
         // Keep an explicit reference since calling PageHide could release
         // mContentViewer
         nsCOMPtr<nsIContentViewer> kungFuDeathGrip(mContentViewer);
         mFiredUnloadEvent = PR_TRUE;
 
         mContentViewer->PageHide(aIsUnload);
 
         nsAutoTArray<nsCOMPtr<nsIDocShell>, 8> kids;
-        PRInt32 i, n = mChildList.Count();
+        PRUint32 i, n = mChildList.Length();
         kids.SetCapacity(n);
         for (i = 0; i < n; i++) {
-            kids.AppendElement(do_QueryInterface(ChildAt(i)));
+            kids.AppendElement(do_QueryInterface(mChildList[i]));
         }
 
         n = kids.Length();
         for (i = 0; i < n; ++i) {
             if (kids[i]) {
                 kids[i]->FirePageHideNotification(aIsUnload);
             }
         }
@@ -2093,19 +2093,19 @@ nsDocShell::HistoryPurged(PRInt32 aNumEn
     // These indices are used for fastback cache eviction, to determine
     // which session history entries are candidates for content viewer
     // eviction.  We need to adjust by the number of entries that we
     // just purged from history, so that we look at the right session history
     // entries during eviction.
     mPreviousTransIndex = PR_MAX(-1, mPreviousTransIndex - aNumEntries);
     mLoadedTransIndex = PR_MAX(0, mLoadedTransIndex - aNumEntries);
 
-    PRInt32 count = mChildList.Count();
-    for (PRInt32 i = 0; i < count; ++i) {
-        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i));
+    PRUint32 count = mChildList.Length();
+    for (PRUint32 i = 0; i < count; ++i) {
+        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(mChildList[i]);
         if (shell) {
             shell->HistoryPurged(aNumEntries);
         }
     }
 
     return NS_OK;
 }
 
@@ -2834,19 +2834,19 @@ nsDocShell::SetTreeOwner(nsIDocShellTree
                 webProgress->AddProgressListener(newListener,
                                                  nsIWebProgress::NOTIFY_ALL);
             }
         }
     }
 
     mTreeOwner = aTreeOwner;    // Weak reference per API
 
-    PRInt32 i, n = mChildList.Count();
+    PRUint32 i, n = mChildList.Length();
     for (i = 0; i < n; i++) {
-        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(ChildAt(i));
+        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(mChildList[i]);
         NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
         PRInt32 childType = ~mItemType; // Set it to not us in case the get fails
         child->GetItemType(&childType); // We don't care if this fails, if it does we won't set the owner
         if (childType == mItemType)
             child->SetTreeOwner(aTreeOwner);
     }
 
     return NS_OK;
@@ -2869,17 +2869,17 @@ nsDocShell::GetIsInUnload(PRBool* aIsInU
 //*****************************************************************************
 // nsDocShell::nsIDocShellTreeNode
 //*****************************************************************************   
 
 NS_IMETHODIMP
 nsDocShell::GetChildCount(PRInt32 * aChildCount)
 {
     NS_ENSURE_ARG_POINTER(aChildCount);
-    *aChildCount = mChildList.Count();
+    *aChildCount = mChildList.Length();
     return NS_OK;
 }
 
 
 
 NS_IMETHODIMP
 nsDocShell::AddChild(nsIDocShellTreeItem * aChild)
 {
@@ -2904,36 +2904,36 @@ nsDocShell::AddChild(nsIDocShellTreeItem
     }
 
     // Make sure to clear the treeowner in case this child is a different type
     // from us.
     aChild->SetTreeOwner(nsnull);
     
     nsresult res = AddChildLoader(childAsDocLoader);
     NS_ENSURE_SUCCESS(res, res);
-    NS_ASSERTION(mChildList.Count() > 0,
+    NS_ASSERTION(!mChildList.IsEmpty(),
                  "child list must not be empty after a successful add");
 
     // Set the child's index in the parent's children list 
     // XXX What if the parent had different types of children?
     // XXX in that case docshell hierarchy and SH hierarchy won't match.
     {
         nsCOMPtr<nsIDocShell> childDocShell = do_QueryInterface(aChild);
         if (childDocShell) {
             // If there are frameloaders in the finalization list, reduce
             // the offset so that the SH hierarchy is more likely to match the
             // docshell hierarchy
             nsCOMPtr<nsIDOMDocument> domDoc =
               do_GetInterface(GetAsSupports(this));
             nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
-            PRUint32 offset = mChildList.Count() - 1;
+            PRUint32 offset = mChildList.Length() - 1;
             if (doc) {
                PRUint32 oldChildCount = offset; // Current child count - 1
                for (PRUint32 i = 0; i < oldChildCount; ++i) {
-                 nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i));
+                 nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
                  if (doc->FrameLoaderScheduledToBeFinalized(child)) {
                    --offset;
                  }
                }
             }
 
             childDocShell->SetChildOffset(offset);
         }
@@ -3043,22 +3043,22 @@ NS_IMETHODIMP
 nsDocShell::GetChildAt(PRInt32 aIndex, nsIDocShellTreeItem ** aChild)
 {
     NS_ENSURE_ARG_POINTER(aChild);
 
 #ifdef DEBUG
     if (aIndex < 0) {
       NS_WARNING("Negative index passed to GetChildAt");
     }
-    else if (aIndex >= mChildList.Count()) {
+    else if (PRUint32(aIndex) >= mChildList.Length()) {
       NS_WARNING("Too large an index passed to GetChildAt");
     }
 #endif
 
-    nsIDocumentLoader* child = SafeChildAt(aIndex);
+    nsIDocumentLoader* child = mChildList.SafeElementAt(aIndex);
     NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED);
     
     return CallQueryInterface(child, aChild);
 }
 
 NS_IMETHODIMP
 nsDocShell::FindChildWithName(const PRUnichar * aName,
                               PRBool aRecurse, PRBool aSameType,
@@ -3070,19 +3070,19 @@ nsDocShell::FindChildWithName(const PRUn
     NS_ENSURE_ARG_POINTER(_retval);
 
     *_retval = nsnull;          // if we don't find one, we return NS_OK and a null result 
 
     if (!*aName)
         return NS_OK;
 
     nsXPIDLString childName;
-    PRInt32 i, n = mChildList.Count();
+    PRUint32 i, n = mChildList.Length();
     for (i = 0; i < n; i++) {
-        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(ChildAt(i));
+        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(mChildList[i]);
         NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
         PRInt32 childType;
         child->GetItemType(&childType);
 
         if (aSameType && (childType != mItemType))
             continue;
 
         PRBool childNameEquals = PR_FALSE;
@@ -3970,20 +3970,20 @@ nsDocShell::Stop(PRUint32 aStopFlags)
         }
 
         // XXXbz We could also pass |this| to nsIURILoader::Stop.  That will
         // just call Stop() on us as an nsIDocumentLoader... We need fewer
         // redundant apis!
         Stop();
     }
 
-    PRInt32 n;
-    PRInt32 count = mChildList.Count();
+    PRUint32 n;
+    PRUint32 count = mChildList.Length();
     for (n = 0; n < count; n++) {
-        nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryInterface(ChildAt(n)));
+        nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryInterface(mChildList[n]));
         if (shellAsNav)
             shellAsNav->Stop(aStopFlags);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -5391,37 +5391,37 @@ nsDocShell::SuspendRefreshURIs()
             nsCOMPtr<nsITimerCallback> rt = do_QueryInterface(callback);
             NS_ASSERTION(rt, "RefreshURIList timer callbacks should only be RefreshTimer objects");
 
             mRefreshURIList->ReplaceElementAt(rt, i);
         }
     }
 
     // Suspend refresh URIs for our child shells as well.
-    PRInt32 n = mChildList.Count();
-
-    for (PRInt32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i));
+    PRUint32 n = mChildList.Length();
+
+    for (PRUint32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(mChildList[i]);
         if (shell)
             shell->SuspendRefreshURIs();
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::ResumeRefreshURIs()
 {
     RefreshURIFromQueue();
 
     // Resume refresh URIs for our child shells as well.
-    PRInt32 n = mChildList.Count();
-
-    for (PRInt32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i));
+    PRUint32 n = mChildList.Length();
+
+    for (PRUint32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(mChildList[i]);
         if (shell)
             shell->ResumeRefreshURIs();
     }
 
     return NS_OK;
 }
 
 nsresult
@@ -6354,19 +6354,19 @@ nsDocShell::CaptureState()
                 }
             }
         }
     }
 
     // Capture the docshell hierarchy.
     mOSHE->ClearChildShells();
 
-    PRInt32 childCount = mChildList.Count();
-    for (PRInt32 i = 0; i < childCount; ++i) {
-        nsCOMPtr<nsIDocShellTreeItem> childShell = do_QueryInterface(ChildAt(i));
+    PRUint32 childCount = mChildList.Length();
+    for (PRUint32 i = 0; i < childCount; ++i) {
+        nsCOMPtr<nsIDocShellTreeItem> childShell = do_QueryInterface(mChildList[i]);
         NS_ASSERTION(childShell, "null child shell");
 
         mOSHE->AddChildShell(childShell);
     }
 
     return NS_OK;
 }
 
@@ -6423,36 +6423,36 @@ nsDocShell::BeginRestore(nsIContentViewe
     }
 
     return NS_OK;
 }
 
 nsresult
 nsDocShell::BeginRestoreChildren()
 {
-    PRInt32 n = mChildList.Count();
-    for (PRInt32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i));
+    PRUint32 n = mChildList.Length();
+    for (PRUint32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
         if (child) {
             nsresult rv = child->BeginRestore(nsnull, PR_FALSE);
             NS_ENSURE_SUCCESS(rv, rv);
         }
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::FinishRestore()
 {
     // First we call finishRestore() on our children.  In the simulated load,
     // all of the child frames finish loading before the main document.
 
-    PRInt32 n = mChildList.Count();
-    for (PRInt32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i));
+    PRUint32 n = mChildList.Length();
+    for (PRUint32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
         if (child) {
             child->FinishRestore();
         }
     }
 
     if (mOSHE && mOSHE->HasDetachedEditor()) {
       ReattachEditorToWindow(mOSHE);
     }
@@ -6909,19 +6909,19 @@ nsDocShell::RestoreFromHistory()
     privWin->ResumeTimeouts();
 
     // Restore the refresh URI list.  The refresh timers will be restarted
     // when EndPageLoad() is called.
     mRefreshURIList = refreshURIList;
 
     // Meta-refresh timers have been restarted for this shell, but not
     // for our children.  Walk the child shells and restart their timers.
-    PRInt32 n = mChildList.Count();
+    PRInt32 n = mChildList.Length();
     for (i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i));
+        nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
         if (child)
             child->ResumeRefreshURIs();
     }
 
     // Make sure this presentation is the same size as the previous
     // presentation.  If this is not the same size we showed it at last time,
     // then we need to resize the widget.
 
@@ -9261,20 +9261,20 @@ nsDocShell::WalkHistoryEntries(nsISHEntr
             continue;
         }
 
         nsDocShell *childShell = nsnull;
         if (aRootShell) {
             // Walk the children of aRootShell and see if one of them
             // has srcChild as a SHEntry.
 
-            PRInt32 childCount = aRootShell->mChildList.Count();
-            for (PRInt32 j = 0; j < childCount; ++j) {
+            PRUint32 childCount = aRootShell->mChildList.Length();
+            for (PRUint32 j = 0; j < childCount; ++j) {
                 nsDocShell *child =
-                    static_cast<nsDocShell*>(aRootShell->ChildAt(j));
+                    static_cast<nsDocShell*>(aRootShell->mChildList[j]);
 
                 if (child->HasHistoryEntry(childEntry)) {
                     childShell = child;
                     break;
                 }
             }
         }
         nsresult rv = aCallback(childEntry, childShell, i, aData);
--- a/dom/base/nsIDOMClassInfo.h
+++ b/dom/base/nsIDOMClassInfo.h
@@ -35,17 +35,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsIDOMClassInfo_h___
 #define nsIDOMClassInfo_h___
 
 #include "nsIClassInfoImpl.h"
-#include "nsVoidArray.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIXPCScriptable.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMScriptObjectFactory.h"
 #include "nsDOMCID.h"
 
 #define DOM_BASE_SCRIPTABLE_FLAGS                                          \
   (nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY |                          \
--- a/dom/src/storage/nsDOMStorage.h
+++ b/dom/src/storage/nsDOMStorage.h
@@ -43,17 +43,16 @@
 
 #include "nscore.h"
 #include "nsAutoPtr.h"
 #include "nsIDOMStorageObsolete.h"
 #include "nsIDOMStorage.h"
 #include "nsIDOMStorageList.h"
 #include "nsIDOMStorageItem.h"
 #include "nsInterfaceHashtable.h"
-#include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsPIDOMStorage.h"
 #include "nsIDOMToString.h"
 #include "nsDOMEvent.h"
 #include "nsIDOMStorageEvent.h"
 #include "nsIDOMStorageManager.h"
 #include "nsCycleCollectionParticipant.h"
 
--- a/editor/libeditor/base/nsSelectionState.cpp
+++ b/editor/libeditor/base/nsSelectionState.cpp
@@ -71,37 +71,20 @@ nsSelectionState::DoTraverse(nsCycleColl
     cb.NoteXPCOMChild(item.endNode);
   }
 }
 
 nsresult  
 nsSelectionState::SaveSelection(nsISelection *aSel)
 {
   if (!aSel) return NS_ERROR_NULL_POINTER;
-  PRInt32 i,rangeCount, arrayCount = mArray.Length();
+  PRInt32 i,rangeCount;
   aSel->GetRangeCount(&rangeCount);
   
-  // if we need more items in the array, new them
-  if (arrayCount<rangeCount)
-  {
-    PRInt32 count = rangeCount-arrayCount;
-    for (i=0; i<count; i++)
-    {
-      mArray.AppendElement();
-    }
-  }
-  
-  // else if we have too many, delete them
-  else if (arrayCount>rangeCount)
-  {
-    for (i = arrayCount-1; i >= rangeCount; i--)
-    {
-      mArray.RemoveElementAt(i);
-    }
-  }
+  mArray.SetLength(rangeCount);
   
   // now store the selection ranges
   nsresult res = NS_OK;
   for (i=0; i<rangeCount; i++)
   {
     nsCOMPtr<nsIDOMRange> range;
     res = aSel->GetRangeAt(i, getter_AddRefs(range));
     mArray[i].StoreRange(range);
--- a/editor/txmgr/src/nsTransactionManager.cpp
+++ b/editor/txmgr/src/nsTransactionManager.cpp
@@ -35,17 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsITransaction.h"
 #include "nsITransactionListener.h"
 
 #include "nsTransactionItem.h"
 #include "nsTransactionStack.h"
-#include "nsVoidArray.h"
 #include "nsTransactionManager.h"
 #include "nsTransactionList.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 
 #define LOCK_TX_MANAGER(mgr)    (mgr)->Lock()
 #define UNLOCK_TX_MANAGER(mgr)  (mgr)->Unlock()
 
--- a/embedding/components/commandhandler/src/nsCommandGroup.h
+++ b/embedding/components/commandhandler/src/nsCommandGroup.h
@@ -70,16 +70,16 @@ protected:
 
 protected:
 
   static PRBool ClearEnumerator(nsHashKey *aKey, void *aData, void* closure);
 
 protected:
 
   nsHashtable       mGroupsHash;    // hash keyed on command group.
-                                    // Entries are nsVoidArrays of pointers to PRUnichar*
+                                    // Entries are nsTArrays of pointers to char*
                                     // This could be made more space-efficient, maybe with atoms
   
 };
 
 
 #endif // nsCommandGroup_h__
 
--- a/extensions/java/xpcom/src/nsJavaXPTCStub.cpp
+++ b/extensions/java/xpcom/src/nsJavaXPTCStub.cpp
@@ -172,19 +172,17 @@ nsJavaXPTCStub::Destroy()
   LOG(("- nsJavaXPTCStub (Java=%08x | XPCOM=%08x | IID=%s)\n",
       (PRUint32) mJavaRefHashCode, (PRUint32) this, iid_str));
   PR_Free(iid_str);
   nsMemory::Free(iid);
 #endif
 
   if (!mMaster) {
     // delete each child stub
-    for (PRInt32 i = 0; i < mChildren.Count(); i++) {
-      delete (nsJavaXPTCStub*) mChildren[i];
-    }
+    mChildren.Clear();
 
     // Since we are destroying this stub, also remove the mapping.
     // It is possible for mJavaStrongRef to be NULL here.  That is why we
     // store the hash code value earlier.
     if (gJavaXPCOMInitialized) {
       gJavaToXPTCStubMap->Remove(mJavaRefHashCode);
     }
   }
@@ -374,19 +372,19 @@ nsJavaXPTCStub::SupportsIID(const nsID &
 nsJavaXPTCStub *
 nsJavaXPTCStub::FindStubSupportingIID(const nsID &iid)
 {
   NS_ASSERTION(mMaster == nsnull, "this is not a master stub");
 
   if (SupportsIID(iid))
     return this;
 
-  for (PRInt32 i = 0; i < mChildren.Count(); i++)
+  for (PRUint32 i = 0; i < mChildren.Length(); i++)
   {
-    nsJavaXPTCStub *child = (nsJavaXPTCStub *) mChildren[i];
+    nsJavaXPTCStub *child = mChildren[i];
     if (child->SupportsIID(iid))
       return child;
   }
   return nsnull;
 }
 
 NS_IMETHODIMP
 nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex,
--- a/extensions/java/xpcom/src/nsJavaXPTCStub.h
+++ b/extensions/java/xpcom/src/nsJavaXPTCStub.h
@@ -35,17 +35,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsJavaXPTCStub_h_
 #define _nsJavaXPTCStub_h_
 
 #include "nsXPTCUtils.h"
 #include "jni.h"
-#include "nsVoidArray.h"
+#include "nsTArray.h"
+#include "nsAutoPtr.h"
 #include "nsIInterfaceInfo.h"
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 #include "nsJavaXPTCStubWeakRef.h"
 
 
 #define NS_JAVAXPTCSTUB_IID \
 {0x88dd8130, 0xebe6, 0x4431, {0x9d, 0xa7, 0xe6, 0xb7, 0x54, 0x74, 0xfb, 0x21}}
@@ -133,17 +134,17 @@ private:
                               jvalue &aJValue);
   nsresult SetXPCOMRetval();
 
   jobject                     mJavaWeakRef;
   jobject                     mJavaStrongRef;
   jint                        mJavaRefHashCode;
   nsCOMPtr<nsIInterfaceInfo>  mIInfo;
 
-  nsVoidArray     mChildren; // weak references (cleared by the children)
+  nsTArray<nsAutoPtr<nsJavaXPTCStub> > mChildren;
   nsJavaXPTCStub *mMaster;   // strong reference
 
   nsAutoRefCnt    mWeakRefCnt;  // count for number of associated weak refs
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsJavaXPTCStub, NS_JAVAXPTCSTUB_IID)
 
 #endif // _nsJavaXPTCStub_h_
--- a/extensions/layout-debug/src/nsRegressionTester.cpp
+++ b/extensions/layout-debug/src/nsRegressionTester.cpp
@@ -36,17 +36,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.h"
 #include "nsRegressionTester.h"
 
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsIWindowWatcher.h"
-#include "nsVoidArray.h"
 #include "prmem.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsPIDOMWindow.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIURI.h"
--- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
+++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
@@ -159,17 +159,17 @@ public:
 
 private:
     void *mGConfClient;
     PRLibrary *mGConfLib;
     PRBool mInitialized;
     nsSystemPrefService *mSysPrefService;
 
     //listeners
-    nsAutoVoidArray *mObservers;
+    nsAutoTArray<nsAutoPtr<GConfCallbackData>, 8> mObservers;
 
     void InitFuncPtrs();
     //gconf public func ptrs
 
     //gconf client funcs
     GConfClientGetDefaultType GConfClientGetDefault;
     GConfClientGetBoolType GConfClientGetBool;
     GConfClientGetStringType GConfClientGetString;
@@ -200,50 +200,36 @@ private:
 
     //const strings
     static const char sPrefGConfKey[];
     static const char sDefaultLibName1[];
     static const char sDefaultLibName2[];
 };
 
 struct SysPrefCallbackData {
-    nsISupports *observer;
+    nsCOMPtr<nsISupports> observer;
     PRBool bIsWeakRef;
     PRUint32 prefAtom;
 };
 
-PRBool
-sysPrefDeleteObserver(void *aElement, void *aData) {
-    SysPrefCallbackData *pElement =
-        static_cast<SysPrefCallbackData *>(aElement);
-    NS_RELEASE(pElement->observer);
-    nsMemory::Free(pElement);
-    return PR_TRUE;
-}
-
 NS_IMPL_ISUPPORTS2(nsSystemPrefService, nsIPrefBranch, nsIPrefBranch2)
 
 /* public */
 nsSystemPrefService::nsSystemPrefService()
     :mInitialized(PR_FALSE),
-     mGConf(nsnull),
-     mObservers(nsnull)
+     mGConf(nsnull)
 {
 }
 
 nsSystemPrefService::~nsSystemPrefService()
 {
     mInitialized = PR_FALSE;
 
     if (mGConf)
         delete mGConf;
-    if (mObservers) {
-        (void)mObservers->EnumerateForwards(sysPrefDeleteObserver, nsnull);
-        delete mObservers;
-    }
 }
 
 nsresult
 nsSystemPrefService::Init()
 {
     if (!gSysPrefLog) {
         gSysPrefLog = PR_NewLogModule("Syspref");
         if (!gSysPrefLog) return NS_ERROR_OUT_OF_MEMORY;
@@ -387,109 +373,91 @@ NS_IMETHODIMP nsSystemPrefService::AddOb
 
     NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
 
     PRUint32 prefAtom;
     // make sure the pref name is supported
     rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!mObservers) {
-        mObservers = new nsAutoVoidArray();
-        if (mObservers == nsnull)
-            return NS_ERROR_OUT_OF_MEMORY;
-    }
+    SysPrefCallbackData *cbData = new SysPrefCallbackData();
 
-    SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *)
-        nsMemory::Alloc(sizeof(SysPrefCallbackData));
-    if (pCallbackData == nsnull)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    pCallbackData->bIsWeakRef = aHoldWeak;
-    pCallbackData->prefAtom = prefAtom;
+    cbData->bIsWeakRef = aHoldWeak;
+    cbData->prefAtom = prefAtom;
     // hold a weak reference to the observer if so requested
     nsCOMPtr<nsISupports> observerRef;
     if (aHoldWeak) {
         nsCOMPtr<nsISupportsWeakReference> weakRefFactory = 
             do_QueryInterface(aObserver);
         if (!weakRefFactory) {
             // the caller didn't give us a object that supports weak reference.
             // ... tell them
-            nsMemory::Free(pCallbackData);
+            delete cbData;
             return NS_ERROR_INVALID_ARG;
         }
         nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory);
         observerRef = tmp;
     } else {
         observerRef = aObserver;
     }
 
-    rv = mGConf->NotifyAdd(prefAtom, pCallbackData);
+    rv = mGConf->NotifyAdd(prefAtom, cbData);
     if (NS_FAILED(rv)) {
-        nsMemory::Free(pCallbackData);
+        delete cbData;
         return rv;
     }
 
-    pCallbackData->observer = observerRef;
-    NS_ADDREF(pCallbackData->observer);
+    cbData->observer = observerRef;
+    mObservers.AppendElement(cbData);
 
-    mObservers->AppendElement(pCallbackData);
     return NS_OK;
 }
 
 /* void removeObserver (in string aDomain, in nsIObserver aObserver); */
 NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserver *aObserver)
 {
     nsresult rv;
 
     NS_ENSURE_ARG_POINTER(aDomain);
     NS_ENSURE_ARG_POINTER(aObserver);
     NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
-
-    if (!mObservers)
-        return NS_OK;
     
     PRUint32 prefAtom;
     // make sure the pref name is supported
     rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // need to find the index of observer, so we can remove it
-    PRIntn count = mObservers->Count();
-    if (count <= 0)
+    PRUint32 count = mObservers.Length();
+    if (!count)
         return NS_OK;
 
-    PRIntn i;
-    SysPrefCallbackData *pCallbackData;
+    PRUint32 i;
     for (i = 0; i < count; ++i) {
-        pCallbackData = (SysPrefCallbackData *)mObservers->ElementAt(i);
-        if (pCallbackData) {
-            nsCOMPtr<nsISupports> observerRef;
-            if (pCallbackData->bIsWeakRef) {
-                nsCOMPtr<nsISupportsWeakReference> weakRefFactory =
-                    do_QueryInterface(aObserver);
-                if (weakRefFactory) {
-                    nsCOMPtr<nsIWeakReference> tmp =
-                        do_GetWeakReference(aObserver);
-                    observerRef = tmp;
-                }
+        SysPrefCallbackData *cbData = mObservers[i];
+        nsCOMPtr<nsISupports> observerRef;
+        if (cbData->bIsWeakRef) {
+            nsCOMPtr<nsISupportsWeakReference> weakRefFactory =
+                do_QueryInterface(aObserver);
+            if (weakRefFactory) {
+                nsCOMPtr<nsIWeakReference> tmp =
+                    do_GetWeakReference(aObserver);
+                observerRef = tmp;
             }
-            if (!observerRef)
-                observerRef = aObserver;
+        }
+        if (!observerRef)
+            observerRef = aObserver;
 
-            if (pCallbackData->observer == observerRef &&
-                pCallbackData->prefAtom == prefAtom) {
-                rv = mGConf->NotifyRemove(prefAtom, pCallbackData);
-                if (NS_SUCCEEDED(rv)) {
-                    mObservers->RemoveElementAt(i);
-                    NS_RELEASE(pCallbackData->observer);
-                    nsMemory::Free(pCallbackData);
-                }
-                return rv;
+        if (cbData->observer == observerRef &&
+            cbData->prefAtom == prefAtom) {
+            rv = mGConf->NotifyRemove(prefAtom, cbData);
+            if (NS_SUCCEEDED(rv)) {
+                mObservers.RemoveElementAt(i);
             }
+            return rv;
         }
     }
     return NS_OK;
 }
 
 void
 nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData)
 {
@@ -505,19 +473,17 @@ nsSystemPrefService::OnPrefChange(PRUint
         nsCOMPtr<nsIWeakReference> weakRef =
             do_QueryInterface(pData->observer);
         if(weakRef)
             observer = do_QueryReferent(weakRef);
         if (!observer) {
             // this weak referenced observer went away, remove it from the list
             nsresult rv = mGConf->NotifyRemove(aPrefAtom, pData);
             if (NS_SUCCEEDED(rv)) {
-                mObservers->RemoveElement(pData);
-                NS_RELEASE(pData->observer);
-                nsMemory::Free(pData);
+                mObservers.RemoveElement(pData);
             }
             return;
         }
     }
     else
         observer = do_QueryInterface(pData->observer);
 
     if (observer)
@@ -582,41 +548,30 @@ GCONF_FUNCS_POINTER_END
 //       are really read.
 //////////////////////////////////////////////////////////////////////////////
 
 static const PrefNamePair sPrefNameMapping[] = {
 #include "gconf_pref_list.inc"
     {nsnull, nsnull},
 };
 
-PRBool
-gconfDeleteObserver(void *aElement, void *aData) {
-    nsMemory::Free(aElement);
-    return PR_TRUE;
-}
 
 GConfProxy::GConfProxy(nsSystemPrefService *aSysPrefService):
     mGConfClient(nsnull),
     mGConfLib(nsnull),
     mInitialized(PR_FALSE),
-    mSysPrefService(aSysPrefService),
-    mObservers(nsnull)
+    mSysPrefService(aSysPrefService)
 {
 }
 
 GConfProxy::~GConfProxy()
 {
     if (mGConfClient)
         g_object_unref(G_OBJECT(mGConfClient));
 
-    if (mObservers) {
-        (void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull);
-        delete mObservers;
-    }
-
     // bug 379666: can't unload GConf-2 since it registers atexit handlers
     //PR_UnloadLibrary(mGConfLib);
 }
 
 PRBool
 GConfProxy::Init()
 {
     SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n"));
@@ -759,60 +714,51 @@ nsresult
 GConfProxy::NotifyAdd (PRUint32 aAtom, void *aUserData)
 {
     NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
 
     const char *gconfKey = GetGConfKey(aAtom);
     if (!gconfKey)
         return NS_ERROR_FAILURE;
 
-    if (!mObservers) {
-        mObservers = new nsAutoVoidArray();
-        if (mObservers == nsnull)
-            return NS_ERROR_OUT_OF_MEMORY;
-    }
- 
-    GConfCallbackData *pData = (GConfCallbackData *)
-        nsMemory::Alloc(sizeof(GConfCallbackData));
+    GConfCallbackData *pData = new GConfCallbackData();
     NS_ENSURE_TRUE(pData, NS_ERROR_OUT_OF_MEMORY);
 
     pData->proxy = this;
     pData->userData = aUserData;
     pData->atom = aAtom;
-    mObservers->AppendElement(pData);
+    mObservers.AppendElement(pData);
 
     GConfClientAddDir(mGConfClient, gconfKey,
                       0, // GCONF_CLIENT_PRELOAD_NONE,  don't preload anything 
                       NULL);
 
     pData->notifyId = GConfClientNotifyAdd(mGConfClient, gconfKey,
                                            gconf_key_listener, pData,
                                            NULL, NULL);
     return NS_OK;
 }
 
 nsresult
 GConfProxy::NotifyRemove (PRUint32 aAtom, const void *aUserData)
 {
     NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
 
-    PRIntn count = mObservers->Count();
-    if (count <= 0)
+    PRUint32 count = mObservers.Length();
+    if (!count)
         return NS_OK;
 
-    PRIntn i;
-    GConfCallbackData *pData;
+    PRUint32 i;
     for (i = 0; i < count; ++i) {
-        pData = (GConfCallbackData *)mObservers->ElementAt(i);
-        if (pData && pData->atom == aAtom && pData->userData == aUserData) {
+        GConfCallbackData *pData = mObservers[i];
+        if (pData->atom == aAtom && pData->userData == aUserData) {
             GConfClientNotifyRemove(mGConfClient, pData->notifyId);
             GConfClientRemoveDir(mGConfClient,
                                  GetGConfKey(pData->atom), NULL);
-            mObservers->RemoveElementAt(i);
-            nsMemory::Free(pData);
+            mObservers.RemoveElementAt(i);
             break;
         }
     }
     return NS_OK;
 }
 
 void
 GConfProxy::InitFuncPtrs()
--- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h
+++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h
@@ -38,22 +38,24 @@
  * the terms of any one of the NPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __SYSTEM_PREF_SERVICE_H__
 #define __SYSTEM_PREF_SERVICE_H__
 
 #include "prlink.h"
-#include "nsVoidArray.h"
+#include "nsTArray.h"
+#include "nsAutoPtr.h"
 #include "nsWeakPtr.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefBranch2.h"
 
 class GConfProxy;
+struct SysPrefCallbackData;
 
 ////////////////////////////////////////////////////////////////////////////
 // nsSystemPrefService provide a interface for read system prefs. It is
 // platform related. This directory (system-pref/gconf) impls it for gconf
 // on the gconf platform.
 ////////////////////////////////////////////////////////////////////////////
 
 class nsSystemPrefService : public nsIPrefBranch2
@@ -69,17 +71,17 @@ public:
 
     void OnPrefChange(PRUint32 aPrefAtom, void *aData);
 
 private:
     PRBool mInitialized;
     GConfProxy *mGConf;
 
     //listeners
-    nsAutoVoidArray *mObservers;
+    nsAutoTArray<nsAutoPtr<SysPrefCallbackData>, 8> mObservers;
 };
 
 #define NS_SYSTEMPREF_SERVICE_CID                  \
   { /* {94f1de09-d0e5-4ca8-94c2-98b049316b7f} */       \
     0x94f1de09,                                        \
     0xd0e5,                                            \
     0x4ca8,                                            \
     { 0x94, 0xc2, 0x98, 0xb0, 0x49, 0x31, 0x6b, 0x7f } \
--- a/extensions/spellcheck/src/mozPersonalDictionary.h
+++ b/extensions/spellcheck/src/mozPersonalDictionary.h
@@ -35,17 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozPersonalDictionary_h__
 #define mozPersonalDictionary_h__
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
-#include "nsVoidArray.h"
 #include "mozIPersonalDictionary.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsTHashtable.h"
 #include "nsTArray.h"
 #include "nsCRT.h"
 
--- a/extensions/spellcheck/src/mozSpellChecker.h
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -40,17 +40,16 @@
 
 #include "nsCOMPtr.h"
 #include "nsISpellChecker.h"
 #include "nsString.h"
 #include "nsITextServicesDocument.h"
 #include "mozIPersonalDictionary.h"
 #include "mozISpellCheckingEngine.h"
 #include "nsClassHashtable.h"
-#include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "mozISpellI18NUtil.h"
 
 class mozSpellChecker : public nsISpellChecker
 {
 public:
   NS_DECL_ISUPPORTS
 
--- a/intl/locale/src/nsLocale.cpp
+++ b/intl/locale/src/nsLocale.cpp
@@ -39,17 +39,16 @@
 #include "nsReadableUtils.h"
 #include "pratom.h"
 #include "prtypes.h"
 #include "nsISupports.h"
 #include "nsILocale.h"
 #include "nsLocale.h"
 #include "nsLocaleCID.h"
 #include "nsCOMPtr.h"
-#include "nsVoidArray.h"
 #include "nsMemory.h"
 #include "nsCRT.h"
 
 #define LOCALE_HASH_SIZE  0xFF
 
 
 /* nsILocale */
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsLocale, nsILocale)
--- a/layout/inspector/src/inCSSValueSearch.cpp
+++ b/layout/inspector/src/inCSSValueSearch.cpp
@@ -34,17 +34,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "inCSSValueSearch.h"
 
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
-#include "nsVoidArray.h"
 #include "nsReadableUtils.h"
 #include "nsIDOMDocumentStyle.h"
 #include "nsIDOM3Node.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsIDOMCSSRuleList.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleDeclaration.h"
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -932,36 +932,35 @@ RuleProcessorData::RuleProcessorData(nsP
 
 RuleProcessorData::~RuleProcessorData()
 {
   MOZ_COUNT_DTOR(RuleProcessorData);
 
   // Destroy potentially long chains of previous sibling and parent data
   // without more than one level of recursion.
   if (mPreviousSiblingData || mParentData) {
-    nsAutoVoidArray destroyQueue;
+    nsAutoTArray<RuleProcessorData*, 8> destroyQueue;
     destroyQueue.AppendElement(this);
 
     do {
-      RuleProcessorData *d = static_cast<RuleProcessorData*>
-                                        (destroyQueue.FastElementAt(destroyQueue.Count() - 1));
-      destroyQueue.RemoveElementAt(destroyQueue.Count() - 1);
+      RuleProcessorData *d = destroyQueue[destroyQueue.Length() - 1];
+      destroyQueue.RemoveElementAt(destroyQueue.Length() - 1);
 
       if (d->mPreviousSiblingData) {
         destroyQueue.AppendElement(d->mPreviousSiblingData);
         d->mPreviousSiblingData = nsnull;
       }
       if (d->mParentData) {
         destroyQueue.AppendElement(d->mParentData);
         d->mParentData = nsnull;
       }
 
       if (d != this)
         d->Destroy();
-    } while (destroyQueue.Count());
+    } while (destroyQueue.Length());
   }
 
   delete mLanguage;
 }
 
 const nsString* RuleProcessorData::GetLang()
 {
   if (!mLanguage) {
--- a/modules/libpref/src/nsPrefBranch.cpp
+++ b/modules/libpref/src/nsPrefBranch.cpp
@@ -59,17 +59,17 @@
 #include "plstr.h"
 #include "nsCRT.h"
 
 #include "prefapi_private_data.h"
 
 // Definitions
 struct EnumerateData {
   const char  *parent;
-  nsVoidArray *pref_list;
+  nsTArray<const char*> *pref_list;
 };
 
 struct PrefCallbackData {
   nsPrefBranch     *pBranch;
   nsIObserver      *pObserver;
   nsIWeakReference *pWeakRef;
 };
 
@@ -557,21 +557,21 @@ NS_IMETHODIMP nsPrefBranch::DeleteBranch
     rv = PREF_DeleteBranch(pref);
   }
   return rv;
 }
 
 NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray)
 {
   char**          outArray;
-  char*           theElement;
-  PRInt32         numPrefs;
-  PRInt32         dwIndex;
+  const char*     theElement;
+  PRUint32        numPrefs;
+  PRUint32        dwIndex;
   EnumerateData   ed;
-  nsAutoVoidArray prefArray;
+  nsAutoTArray<const char*, 8> prefArray;
 
   NS_ENSURE_ARG_POINTER(aStartingAt);
   NS_ENSURE_ARG_POINTER(aCount);
   NS_ENSURE_ARG_POINTER(aChildArray);
 
   if (!gHashTable.ops) {
     *aChildArray = nsnull;
     *aCount = 0;
@@ -582,27 +582,27 @@ NS_IMETHODIMP nsPrefBranch::GetChildList
   // allocate on the stack for speed
 
   ed.parent = getPrefName(aStartingAt);
   ed.pref_list = &prefArray;
   PL_DHashTableEnumerate(&gHashTable, pref_enumChild, &ed);
 
   // now that we've built up the list, run the callback on
   // all the matching elements
-  numPrefs = prefArray.Count();
+  numPrefs = prefArray.Length();
 
   if (numPrefs) {
     outArray = (char **)nsMemory::Alloc(numPrefs * sizeof(char *));
     if (!outArray)
       return NS_ERROR_OUT_OF_MEMORY;
 
     for (dwIndex = 0; dwIndex < numPrefs; ++dwIndex) {
       // we need to lop off mPrefRoot in case the user is planning to pass this
       // back to us because if they do we are going to add mPrefRoot again.
-      theElement = ((char *)prefArray.ElementAt(dwIndex)) + mPrefRootLength;
+      theElement = (prefArray.ElementAt(dwIndex)) + mPrefRootLength;
       outArray[dwIndex] = (char *)nsMemory::Clone(theElement, strlen(theElement) + 1);
  
       if (!outArray[dwIndex]) {
         // we ran out of memory... this is annoying
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(dwIndex, outArray);
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
@@ -624,17 +624,17 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(
 {
   PrefCallbackData *pCallback;
   const char *pref;
 
   NS_ENSURE_ARG_POINTER(aDomain);
   NS_ENSURE_ARG_POINTER(aObserver);
 
   if (!mObservers) {
-    mObservers = new nsAutoVoidArray();
+    mObservers = new nsAutoTArray<PrefCallbackData*, 8>();
     if (nsnull == mObservers)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   pCallback = (PrefCallbackData *)nsMemory::Alloc(sizeof(PrefCallbackData));
   if (nsnull == pCallback)
     return NS_ERROR_OUT_OF_MEMORY;
 
@@ -664,34 +664,34 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(
   PREF_RegisterCallback(pref, NotifyObserver, pCallback);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aObserver)
 {
   const char *pref;
   PrefCallbackData *pCallback;
-  PRInt32 count;
-  PRInt32 i;
+  PRUint32 count;
+  PRUint32 i;
   nsresult rv;
   nsCAutoString domain;
 
   NS_ENSURE_ARG_POINTER(aDomain);
   NS_ENSURE_ARG_POINTER(aObserver);
 
   if (!mObservers)
     return NS_OK;
     
   // need to find the index of observer, so we can remove it from the domain list too
-  count = mObservers->Count();
+  count = mObservers->Length();
   if (count == 0)
     return NS_OK;
 
   for (i = 0; i < count; i++) {
-    pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
+    pCallback = mObservers->ElementAt(i);
     if (pCallback) {
       if (pCallback->pObserver == aObserver) {
         domain = mObserverDomains[i];
         if (domain.Equals(aDomain)) {
           // We must pass a fully qualified preference name to remove the callback
           pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
           rv = PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
           if (NS_SUCCEEDED(rv)) {
@@ -754,46 +754,46 @@ static nsresult NotifyObserver(const cha
 
 void nsPrefBranch::freeObserverList(void)
 {
   const char *pref;
   PrefCallbackData *pCallback;
 
   if (mObservers) {
     // unregister the observers
-    PRInt32 count;
+    PRUint32 count;
 
-    count = mObservers->Count();
+    count = mObservers->Length();
     if (count > 0) {
-      PRInt32 i;
+      PRUint32 i;
       nsCAutoString domain;
       for (i = 0; i < count; ++i) {
-        pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
+        pCallback = mObservers->ElementAt(i);
         if (pCallback) {
           domain = mObserverDomains[i];
           // We must pass a fully qualified preference name to remove the callback
           pref = getPrefName(domain.get()); // can't fail because domain must be valid
           // Remove this observer from our array so that nobody else can remove
           // what we're trying to remove right now.
-          mObservers->ReplaceElementAt(nsnull, i);
+          mObservers->ElementAt(i) = nsnull;
           PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
           if (pCallback->pWeakRef) {
             NS_RELEASE(pCallback->pWeakRef);
           } else {
             NS_RELEASE(pCallback->pObserver);
           }
           nsMemory::Free(pCallback);
         }
       }
 
       // now empty the observer domains array in bulk
       mObserverDomains.Clear();
     }
     delete mObservers;
-    mObservers = 0;
+    mObservers = nsnull;
   }
 }
  
 nsresult nsPrefBranch::GetDefaultFromPropertiesFile(const char *aPrefName, PRUnichar **return_buf)
 {
   nsresult rv;
 
   // the default value contains a URL to a .properties file
@@ -867,17 +867,17 @@ nsresult nsPrefBranch::getValidatedPrefN
 
 static PLDHashOperator
 pref_enumChild(PLDHashTable *table, PLDHashEntryHdr *heh,
                PRUint32 i, void *arg)
 {
   PrefHashEntry *he = static_cast<PrefHashEntry*>(heh);
   EnumerateData *d = reinterpret_cast<EnumerateData *>(arg);
   if (PL_strncmp(he->key, d->parent, PL_strlen(d->parent)) == 0) {
-    d->pref_list->AppendElement((void*)he->key);
+    d->pref_list->AppendElement(he->key);
   }
   return PL_DHASH_NEXT;
 }
 
 
 /*
  * nsISecurityPref methods
  *
--- a/modules/libpref/src/nsPrefBranch.h
+++ b/modules/libpref/src/nsPrefBranch.h
@@ -44,20 +44,21 @@
 #include "nsIPrefBranchInternal.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsISecurityPref.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIRelativeFilePref.h"
 #include "nsILocalFile.h"
 #include "nsString.h"
-#include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 
+struct PrefCallbackData;
+
 class nsPrefBranch : public nsIPrefBranchInternal,
                      public nsISecurityPref,
                      public nsIObserver,
                      public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPREFBRANCH
@@ -76,17 +77,17 @@ protected:
 
   nsresult   GetDefaultFromPropertiesFile(const char *aPrefName, PRUnichar **return_buf);
   const char *getPrefName(const char *aPrefName);
   nsresult   getValidatedPrefName(const char *aPrefName, const char **_retval);
   void       freeObserverList(void);
 
 private:
   PRInt32               mPrefRootLength;
-  nsAutoVoidArray       *mObservers;
+  nsAutoTArray<PrefCallbackData*, 8> *mObservers;
   nsCString             mPrefRoot;
   nsTArray<nsCString>   mObserverDomains;
   PRBool                mIsDefault;
 
 };
 
 
 class nsPrefLocalizedString : public nsIPrefLocalizedString,
--- a/netwerk/cache/src/nsCacheService.cpp
+++ b/netwerk/cache/src/nsCacheService.cpp
@@ -61,17 +61,16 @@
 #include "nsIPrefBranch.h"
 #include "nsIPrefBranch2.h"
 #include "nsILocalFile.h"
 #include "nsIOService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsThreadUtils.h"
 #include "nsProxyRelease.h"
-#include "nsVoidArray.h"
 #include "nsDeleteDir.h"
 #include "nsIPrivateBrowsingService.h"
 #include "nsNetCID.h"
 #include <math.h>  // for log()
 
 
 /******************************************************************************
  * nsCacheProfilePrefObserver
--- a/security/manager/ssl/src/nsKeygenHandler.cpp
+++ b/security/manager/ssl/src/nsKeygenHandler.cpp
@@ -48,17 +48,16 @@ extern "C" {
 #include "cryptohi.h"
 #include "base64.h"
 #include "secasn1.h"
 extern "C" {
 #include "pk11pqg.h"
 }
 #include "nsProxiedService.h"
 #include "nsKeygenHandler.h"
-#include "nsVoidArray.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMHTMLSelectElement.h"
 #include "nsIContent.h"
 #include "nsKeygenThread.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
 #include "nsITokenDialogs.h"
--- a/security/manager/ssl/src/nsKeygenHandler.h
+++ b/security/manager/ssl/src/nsKeygenHandler.h
@@ -36,17 +36,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSKEYGENHANDLER_H_
 #define _NSKEYGENHANDLER_H_
 // Form Processor 
 #include "nsIFormProcessor.h" 
-#include "nsVoidArray.h" 
 #include "nsTArray.h" 
 
 nsresult GetSlotWithMechanism(PRUint32 mechanism,
                               nsIInterfaceRequestor *ctx,
                               PK11SlotInfo **retSlot);
 
 #define DEFAULT_RSA_KEYGEN_PE 65537L
 #define DEFAULT_RSA_KEYGEN_ALG SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION
--- a/tools/trace-malloc/leaksoup.cpp
+++ b/tools/trace-malloc/leaksoup.cpp
@@ -35,37 +35,37 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "adreader.h"
 
 #include <stdio.h>
 #include "plhash.h"
 
-#include "nsVoidArray.h"
+#include "nsTArray.h"
 #include "nsQuickSort.h"
 
 /*
  * Read in an allocation dump, presumably one taken at shutdown (using
  * the --shutdown-leaks=file option, which must be used along with
  * --trace-malloc=tmlog), and treat the memory in the dump as leaks.
  * Find the leak roots, including cycles that are roots, by finding the
  * strongly connected components in the graph.  Print output to stdout
  * as HTML.
  */
 
 struct AllocationNode {
     const ADLog::Entry *entry;
 
     // Other |AllocationNode| objects whose memory has a pointer to
     // this object.
-    nsAutoVoidArray pointers_to;
+    nsAutoTArray<AllocationNode*, 8> pointers_to;
 
     // The reverse.
-    nsAutoVoidArray pointers_from;
+    nsAutoTArray<AllocationNode*, 8> pointers_from;
 
     // Early on in the algorithm, the pre-order index from a DFS.
     // Later on, set to the index of the strongly connected component to
     // which this node belongs.
     PRUint32 index;
 
     PRPackedBool reached;
     PRPackedBool is_root;
@@ -190,44 +190,43 @@ int main(int argc, char **argv)
             }
         }
     }
 
     // Do a depth-first search on the graph (i.e., by following
     // |pointers_to|) and assign the post-order index to |index|.
     {
         PRUint32 dfs_index = 0;
-        nsVoidArray stack;
+        nsAutoTArray<AllocationNode*, 8> stack;
 
         for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) {
             if (n->reached) {
                 continue;
             }
             stack.AppendElement(n);
 
             do {
-                PRUint32 pos = stack.Count() - 1;
-                AllocationNode *n =
-                    static_cast<AllocationNode*>(stack[pos]);
+                PRUint32 pos = stack.Length() - 1;
+                AllocationNode *n = stack[pos];
                 if (n->reached) {
                     n->index = dfs_index++;
                     stack.RemoveElementAt(pos);
                 } else {
                     n->reached = PR_TRUE;
 
                     // When doing post-order processing, we have to be
                     // careful not to put reached nodes into the stack.
-                    nsVoidArray &pt = n->pointers_to;
-                    for (PRInt32 i = pt.Count() - 1; i >= 0; --i) {
-                        if (!static_cast<AllocationNode*>(pt[i])->reached) {
+                    nsAutoTArray<AllocationNode*, 8> &pt = n->pointers_to;
+                    for (PRInt32 i = pt.Length() - 1; i >= 0; --i) {
+                        if (!pt[i]->reached) {
                             stack.AppendElement(pt[i]);
                         }
                     }
                 }
-            } while (stack.Count() > 0);
+            } while (stack.Length() > 0);
         }
     }
 
     // Sort the nodes by their DFS index, in reverse, so that the first
     // node is guaranteed to be in a root SCC.
     AllocationNode **sorted_nodes = new AllocationNode*[count];
     if (!sorted_nodes) {
         fprintf(stderr, "%s: Out of memory.\n", argv[0]);
@@ -243,69 +242,66 @@ int main(int argc, char **argv)
     }
 
     // Put the nodes into their strongly-connected components.
     PRUint32 num_sccs = 0;
     {
         for (size_t i = 0; i < count; ++i) {
             nodes[i].reached = PR_FALSE;
         }
-        nsVoidArray stack;
+        nsAutoTArray<AllocationNode*, 8> stack;
         for (AllocationNode **sn = sorted_nodes,
                         **sn_end = sorted_nodes + count; sn != sn_end; ++sn) {
             if ((*sn)->reached) {
                 continue;
             }
 
             // We found a new strongly connected index.
             stack.AppendElement(*sn);
             do {
-                PRUint32 pos = stack.Count() - 1;
-                AllocationNode *n =
-                    static_cast<AllocationNode*>(stack[pos]);
+                PRUint32 pos = stack.Length() - 1;
+                AllocationNode *n = stack[pos];
                 stack.RemoveElementAt(pos);
 
                 if (!n->reached) {
                     n->reached = PR_TRUE;
                     n->index = num_sccs;
                     stack.AppendElements(n->pointers_from);
                 }
-            } while (stack.Count() > 0);
+            } while (stack.Length() > 0);
             ++num_sccs;
         }
     }
 
     // Identify which nodes are leak roots by using DFS, and watching
     // for component transitions.
     PRUint32 num_root_nodes = count;
     {
         for (size_t i = 0; i < count; ++i) {
             nodes[i].is_root = PR_TRUE;
         }
 
-        nsVoidArray stack;
+        nsAutoTArray<AllocationNode*, 8> stack;
         for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) {
             if (!n->is_root) {
                 continue;
             }
 
             // Loop through pointers_to, and add any that are in a
             // different SCC to stack:
-            for (int i = n->pointers_to.Count() - 1; i >= 0; --i) {
-                AllocationNode *target =
-                    static_cast<AllocationNode*>(n->pointers_to[i]);
+            for (int i = n->pointers_to.Length() - 1; i >= 0; --i) {
+                AllocationNode *target = n->pointers_to[i];
                 if (n->index != target->index) {
                     stack.AppendElement(target);
                 }
             }
 
-            while (stack.Count() > 0) {
-                PRUint32 pos = stack.Count() - 1;
-                AllocationNode *n =
-                    static_cast<AllocationNode*>(stack[pos]);
+            while (stack.Length() > 0) {
+                PRUint32 pos = stack.Length() - 1;
+                AllocationNode *n = stack[pos];
                 stack.RemoveElementAt(pos);
 
                 if (n->is_root) {
                     n->is_root = PR_FALSE;
                     --num_root_nodes;
                     stack.AppendElements(n->pointers_to);
                 }
             }
@@ -393,22 +389,21 @@ int main(int argc, char **argv)
                         }
                         printf("\n");
                     } else {
                         printf("        0x%08X\n",
                                *(unsigned int*)(e->data + d));
                     }
                 }
 
-                if (n->pointers_from.Count()) {
+                if (n->pointers_from.Length()) {
                     printf("\nPointers from:\n");
-                    for (PRUint32 i = 0, i_end = n->pointers_from.Count();
+                    for (PRUint32 i = 0, i_end = n->pointers_from.Length();
                          i != i_end; ++i) {
-                        AllocationNode *t = static_cast<AllocationNode*>
-                                                       (n->pointers_from[i]);
+                        AllocationNode *t = n->pointers_from[i];
                         const ADLog::Entry *te = t->entry;
                         printf("    <a href=\"#o%d\">%s</a> (Object %d, ",
                                t - nodes, te->type, t - nodes);
                         if (t->index != n->index) {
                             printf("component %d, ", t->index);
                         }
                         if (t == n) {
                             printf("self)\n");
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
@@ -112,35 +112,30 @@ static PRBool
 RequestInfoHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
                          const void *key)
 {
   // Initialize the entry with placement new
   new (entry) nsRequestInfo(key);
   return PR_TRUE;
 }
 
-
-struct nsListenerInfo {
-  nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask) 
-    : mWeakListener(aListener),
-      mNotifyMask(aNotifyMask)
-  {
-  }
-
-  // Weak pointer for the nsIWebProgressListener...
-  nsWeakPtr mWeakListener;
-
-  // Mask indicating which notifications the listener wants to receive.
-  unsigned long mNotifyMask;
+// this is used for mListenerInfoList.Contains() and .RemoveElement()
+NS_SPECIALIZE_TEMPLATE
+class nsDefaultComparator <class nsDocLoader::nsListenerInfo, nsIWebProgressListener*> {
+  public:
+    PRBool Equals(const nsDocLoader::nsListenerInfo& aInfo,
+                  nsIWebProgressListener* const& aListener) const {
+      nsCOMPtr<nsIWebProgressListener> listener =
+                                       do_QueryReferent(aInfo.mWeakListener);
+      return aListener == listener;
+    }
 };
 
-
 nsDocLoader::nsDocLoader()
   : mParent(nsnull),
-    mListenerInfoList(8),
     mIsLoadingDocument(PR_FALSE),
     mIsRestoringDocument(PR_FALSE),
     mIsFlushingLayout(PR_FALSE)
 {
 #if defined(PR_LOGGING)
   if (nsnull == gDocLoaderLog) {
       gDocLoaderLog = PR_NewLogModule("DocLoader");
   }
@@ -288,26 +283,26 @@ nsDocLoader::AddDocLoaderAsChildOfRoot(n
 
   return rootDocLoader->AddChildLoader(aDocLoader);
 }
 
 NS_IMETHODIMP
 nsDocLoader::Stop(void)
 {
   nsresult rv = NS_OK;
-  PRInt32 count, i;
+  PRUint32 count, i;
 
   PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, 
          ("DocLoader:%p: Stop() called\n", this));
 
-  count = mChildList.Count();
+  count = mChildList.Length();
 
   nsCOMPtr<nsIDocumentLoader> loader;
   for (i=0; i < count; i++) {
-    loader = ChildAt(i);
+    loader = mChildList[i];
 
     if (loader) {
       (void) loader->Stop();
     }
   }
 
   if (mLoadGroup)
     rv = mLoadGroup->Cancel(NS_BINDING_ABORTED);
@@ -364,22 +359,22 @@ nsDocLoader::IsBusy()
   if (NS_FAILED(rv)) {
     return PR_FALSE;
   }
   if (busy) {
     return PR_TRUE;
   }
 
   /* check its child document loaders... */
-  PRInt32 count, i;
+  PRUint32 count, i;
 
-  count = mChildList.Count();
+  count = mChildList.Length();
 
   for (i=0; i < count; i++) {
-    nsIDocumentLoader* loader = ChildAt(i);
+    nsIDocumentLoader* loader = mChildList[i];
 
     // This is a safe cast, because we only put nsDocLoader objects into the
     // array
     if (loader && static_cast<nsDocLoader*>(loader)->IsBusy())
       return PR_TRUE;
   }
 
   return PR_FALSE;
@@ -416,48 +411,39 @@ nsDocLoader::Destroy()
   if (mParent) 
   {
     mParent->RemoveChildLoader(this);
   }
 
   // Release all the information about network requests...
   ClearRequestInfoHash();
 
-  // Release all the information about registered listeners...
-  PRInt32 count = mListenerInfoList.Count();
-  for(PRInt32 i = 0; i < count; i++) {
-    nsListenerInfo *info =
-      static_cast<nsListenerInfo*>(mListenerInfoList.ElementAt(i));
-
-    delete info;
-  }
-
   mListenerInfoList.Clear();
   mListenerInfoList.Compact();
 
   mDocumentRequest = 0;
 
   if (mLoadGroup)
     mLoadGroup->SetGroupObserver(nsnull);
 
   DestroyChildren();
 }
 
 void
 nsDocLoader::DestroyChildren()
 {
-  PRInt32 i, count;
+  PRUint32 i, count;
   
-  count = mChildList.Count();
+  count = mChildList.Length();
   // if the doc loader still has children...we need to enumerate the
   // children and make them null out their back ptr to the parent doc
   // loader
   for (i=0; i < count; i++)
   {
-    nsIDocumentLoader* loader = ChildAt(i);
+    nsIDocumentLoader* loader = mChildList[i];
 
     if (loader) {
       // This is a safe cast, as we only put nsDocLoader objects into the
       // array
       static_cast<nsDocLoader*>(loader)->SetDocLoaderParent(nsnull);
     }
   }
   mChildList.Clear();
@@ -892,54 +878,36 @@ void nsDocLoader::doStopDocumentLoad(nsI
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
 // The following section contains support for nsIWebProgress and related stuff
 ////////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsDocLoader::AddProgressListener(nsIWebProgressListener *aListener,
-                                     PRUint32 aNotifyMask)
+                                 PRUint32 aNotifyMask)
 {
-  nsresult rv;
-
-  nsListenerInfo* info = GetListenerInfo(aListener);
-  if (info) {
+  if (mListenerInfoList.Contains(aListener)) {
     // The listener is already registered!
     return NS_ERROR_FAILURE;
   }
 
   nsWeakPtr listener = do_GetWeakReference(aListener);
   if (!listener) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  info = new nsListenerInfo(listener, aNotifyMask);
-  if (!info) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  rv = mListenerInfoList.AppendElement(info) ? NS_OK : NS_ERROR_FAILURE;
-  return rv;
+  return mListenerInfoList.AppendElement(nsListenerInfo(listener, aNotifyMask)) ?
+         NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsDocLoader::RemoveProgressListener(nsIWebProgressListener *aListener)
 {
-  nsresult rv;
-
-  nsListenerInfo* info = GetListenerInfo(aListener);
-  if (info) {
-    rv = mListenerInfoList.RemoveElement(info) ? NS_OK : NS_ERROR_FAILURE;
-    delete info;
-  } else {
-    // The listener is not registered!
-    rv = NS_ERROR_FAILURE;
-  }
-  return rv;
+  return mListenerInfoList.RemoveElement(aListener) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsDocLoader::GetDOMWindow(nsIDOMWindow **aResult)
 {
   return CallGetInterface(this, aResult);
 }
 
@@ -950,22 +918,22 @@ nsDocLoader::GetIsLoadingDocument(PRBool
 
   return NS_OK;
 }
 
 PRInt64 nsDocLoader::GetMaxTotalProgress()
 {
   nsInt64 newMaxTotal = 0;
 
-  PRInt32 count = mChildList.Count();
+  PRUint32 count = mChildList.Length();
   nsCOMPtr<nsIWebProgress> webProgress;
-  for (PRInt32 i=0; i < count; i++) 
+  for (PRUint32 i=0; i < count; i++) 
   {
     nsInt64 individualProgress = 0;
-    nsIDocumentLoader* docloader = ChildAt(i);
+    nsIDocumentLoader* docloader = mChildList[i];
     if (docloader)
     {
       // Cast is safe since all children are nsDocLoader too
       individualProgress = ((nsDocLoader *) docloader)->GetMaxTotalProgress();
     }
     if (individualProgress < nsInt64(0)) // if one of the elements doesn't know it's size
                                          // then none of them do
     {
@@ -1150,47 +1118,38 @@ void nsDocLoader::FireOnProgressChange(n
   nsCAutoString buffer;
 
   GetURIStringFromRequest(request, buffer);
   PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, 
          ("DocLoader:%p: Progress (%s): curSelf: %d maxSelf: %d curTotal: %d maxTotal %d\n",
           this, buffer.get(), aProgress, aProgressMax, aTotalProgress, aMaxTotalProgress));
 #endif /* DEBUG */
 
-  /*
-   * First notify any listeners of the new progress info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
+  // First notify any listeners of the new progress info...
   nsCOMPtr<nsIWebProgressListener> listener;
-  PRInt32 count = mListenerInfoList.Count();
+  ListenerArray::BackwardIterator iter(mListenerInfoList);
 
-  while (--count >= 0) {
-    nsListenerInfo *info;
-
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
-    if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
+  while (iter.HasMore()) {
+    nsListenerInfo &info = iter.GetNext();
+    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
       continue;
     }
 
-    listener = do_QueryReferent(info->mWeakListener);
+    listener = do_QueryReferent(info.mWeakListener);
     if (!listener) {
       // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      delete info;
+      RemoveEmptyListeners();
       continue;
     }
 
     // XXX truncates 64-bit to 32-bit
     listener->OnProgressChange(aLoadInitiator,request,
                                PRInt32(aProgress), PRInt32(aProgressMax),
                                PRInt32(aTotalProgress), PRInt32(aMaxTotalProgress));
   }
-
   mListenerInfoList.Compact();
 
   // Pass the notification up to the parent...
   if (mParent) {
     mParent->FireOnProgressChange(aLoadInitiator, request,
                                   aProgress, aProgressMax,
                                   aProgressDelta,
                                   aTotalProgress, aMaxTotalProgress);
@@ -1226,130 +1185,104 @@ void nsDocLoader::FireOnStateChange(nsIW
   GetURIStringFromRequest(aRequest, buffer);
   PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, 
          ("DocLoader:%p: Status (%s): code: %x\n",
          this, buffer.get(), aStateFlags));
 #endif /* DEBUG */
 
   NS_ASSERTION(aRequest, "Firing OnStateChange(...) notification with a NULL request!");
 
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
+  // First notify any listeners of the new state info...
   nsCOMPtr<nsIWebProgressListener> listener;
-  PRInt32 count = mListenerInfoList.Count();
+  ListenerArray::BackwardIterator iter(mListenerInfoList);
 
-  while (--count >= 0) {
-    nsListenerInfo *info;
-
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
-    if (!info || !(info->mNotifyMask & (aStateFlags >>16))) {
+  while (iter.HasMore()) {
+    nsListenerInfo &info = iter.GetNext();
+    if (!(info.mNotifyMask & (aStateFlags >>16))) {
       continue;
     }
 
-    listener = do_QueryReferent(info->mWeakListener);
+    listener = do_QueryReferent(info.mWeakListener);
     if (!listener) {
       // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      delete info;
+      RemoveEmptyListeners();
       continue;
     }
 
     listener->OnStateChange(aProgress, aRequest, aStateFlags, aStatus);
   }
-
   mListenerInfoList.Compact();
 
   // Pass the notification up to the parent...
   if (mParent) {
     mParent->FireOnStateChange(aProgress, aRequest, aStateFlags, aStatus);
   }
 }
 
 
 
 void
 nsDocLoader::FireOnLocationChange(nsIWebProgress* aWebProgress,
                                   nsIRequest* aRequest,
                                   nsIURI *aUri)
 {
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
+  // First notify any listeners of the new state info...
   nsCOMPtr<nsIWebProgressListener> listener;
-  PRInt32 count = mListenerInfoList.Count();
+  ListenerArray::BackwardIterator iter(mListenerInfoList);
 
-  while (--count >= 0) {
-    nsListenerInfo *info;
-
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
-    if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
+  while (iter.HasMore()) {
+    nsListenerInfo &info = iter.GetNext();
+    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
       continue;
     }
 
-    listener = do_QueryReferent(info->mWeakListener);
+    listener = do_QueryReferent(info.mWeakListener);
     if (!listener) {
       // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      delete info;
+      RemoveEmptyListeners();
       continue;
     }
 
     listener->OnLocationChange(aWebProgress, aRequest, aUri);
   }
-
   mListenerInfoList.Compact();
 
   // Pass the notification up to the parent...
   if (mParent) {
     mParent->FireOnLocationChange(aWebProgress, aRequest, aUri);
   }
 }
 
 void
 nsDocLoader::FireOnStatusChange(nsIWebProgress* aWebProgress,
                                 nsIRequest* aRequest,
                                 nsresult aStatus,
                                 const PRUnichar* aMessage)
 {
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
+  // First notify any listeners of the new state info...
   nsCOMPtr<nsIWebProgressListener> listener;
-  PRInt32 count = mListenerInfoList.Count();
+  ListenerArray::BackwardIterator iter(mListenerInfoList);
 
-  while (--count >= 0) {
-    nsListenerInfo *info;
-
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
-    if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
+  while (iter.HasMore()) {
+    nsListenerInfo &info = iter.GetNext();
+    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
       continue;
     }
 
-    listener = do_QueryReferent(info->mWeakListener);
+    listener = do_QueryReferent(info.mWeakListener);
     if (!listener) {
       // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      delete info;
+      RemoveEmptyListeners();
       continue;
     }
 
     listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
   }
   mListenerInfoList.Compact();
-  
+
   // Pass the notification up to the parent...
   if (mParent) {
     mParent->FireOnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
   }
 }
 
 PRBool
 nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress,
@@ -1357,86 +1290,58 @@ nsDocLoader::RefreshAttempted(nsIWebProg
                               PRInt32 aDelay,
                               PRBool aSameURI)
 {
   /*
    * Returns true if the refresh may proceed,
    * false if the refresh should be blocked.
    *
    * First notify any listeners of the refresh attempt...
-   *
-   * Iterate the elements from back to front so that if items
-   * get removed from the list it won't affect our iteration
    */
   PRBool allowRefresh = PR_TRUE;
-  PRInt32 count = mListenerInfoList.Count();
+  ListenerArray::BackwardIterator iter(mListenerInfoList);
 
-  while (--count >= 0) {
-    nsListenerInfo *info;
-
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
-    if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
+  while (iter.HasMore()) {
+    nsListenerInfo &info = iter.GetNext();
+    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
       continue;
     }
 
     nsCOMPtr<nsIWebProgressListener> listener =
-      do_QueryReferent(info->mWeakListener);
+      do_QueryReferent(info.mWeakListener);
     if (!listener) {
       // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      delete info;
+      RemoveEmptyListeners();
       continue;
     }
 
     nsCOMPtr<nsIWebProgressListener2> listener2 =
-      do_QueryReferent(info->mWeakListener);
+      do_QueryReferent(info.mWeakListener);
     if (!listener2)
       continue;
 
     PRBool listenerAllowedRefresh;
     nsresult listenerRV = listener2->OnRefreshAttempted(
         aWebProgress, aURI, aDelay, aSameURI, &listenerAllowedRefresh);
     if (NS_FAILED(listenerRV))
       continue;
 
     allowRefresh = allowRefresh && listenerAllowedRefresh;
   }
-
   mListenerInfoList.Compact();
 
   // Pass the notification up to the parent...
   if (mParent) {
     allowRefresh = allowRefresh &&
       mParent->RefreshAttempted(aWebProgress, aURI, aDelay, aSameURI);
   }
 
   return allowRefresh;
 }
 
-nsListenerInfo * 
-nsDocLoader::GetListenerInfo(nsIWebProgressListener *aListener)
-{
-  PRInt32 i, count;
-  nsListenerInfo *info;
-
-  nsCOMPtr<nsISupports> listener1 = do_QueryInterface(aListener);
-  count = mListenerInfoList.Count();
-  for (i=0; i<count; i++) {
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(i));
-
-    NS_ASSERTION(info, "There should NEVER be a null listener in the list");
-    if (info) {
-      nsCOMPtr<nsISupports> listener2 = do_QueryReferent(info->mWeakListener);
-      if (listener1 == listener2)
-        return info;
-    }
-  }
-  return nsnull;
-}
-
 nsresult nsDocLoader::AddRequestInfo(nsIRequest *aRequest)
 {
   if (!PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_ADD)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
@@ -1479,16 +1384,27 @@ void nsDocLoader::ClearRequestInfoHash(v
     // No hash, or the hash is empty, nothing to do here then...
 
     return;
   }
 
   PL_DHashTableEnumerate(&mRequestInfoHash, RemoveInfoCallback, nsnull);
 }
 
+/**
+ * RemoveElement() only finds the first Listener that resolves to null and
+ * may leave such empty Listeners behind at the end of the Array.
+ * This method makes sure it removes every one of those null-Listeners.
+ */
+void nsDocLoader::RemoveEmptyListeners()
+{
+  while(mListenerInfoList.RemoveElement((nsIWebProgressListener*)nsnull)) {}
+}
+
+
 // PLDHashTable enumeration callback that calculates the max progress.
 static PLDHashOperator
 CalcMaxProgressCallback(PLDHashTable *table, PLDHashEntryHdr *hdr,
                         PRUint32 number, void *arg)
 {
   const nsRequestInfo *info = static_cast<const nsRequestInfo *>(hdr);
   nsInt64 *max = static_cast<nsInt64 *>(arg);
 
@@ -1549,44 +1465,35 @@ NS_IMETHODIMP nsDocLoader::OnSecurityCha
 {
   //
   // Fire progress notifications out to any registered nsIWebProgressListeners.  
   //
   
   nsCOMPtr<nsIRequest> request = do_QueryInterface(aContext);
   nsIWebProgress* webProgress = static_cast<nsIWebProgress*>(this);
 
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
+  // First notify any listeners of the new state info...
   nsCOMPtr<nsIWebProgressListener> listener;
-  PRInt32 count = mListenerInfoList.Count();
+  ListenerArray::BackwardIterator iter(mListenerInfoList);
 
-  while (--count >= 0) {
-    nsListenerInfo *info;
-
-    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
-    if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
+  while (iter.HasMore()) {
+    nsListenerInfo &info = iter.GetNext();
+    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
       continue;
     }
 
-    listener = do_QueryReferent(info->mWeakListener);
+    listener = do_QueryReferent(info.mWeakListener);
     if (!listener) {
       // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      delete info;
+      RemoveEmptyListeners();
       continue;
     }
 
     listener->OnSecurityChange(webProgress, request, aState);
   }
-
   mListenerInfoList.Compact();
 
   // Pass the notification up to the parent...
   if (mParent) {
     mParent->OnSecurityChange(aContext, aState);
   }
   return NS_OK;
 }
@@ -1614,21 +1521,21 @@ NS_IMETHODIMP nsDocLoader::SetPriority(P
 {
   PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, 
          ("DocLoader:%p: SetPriority(%d) called\n", this, aPriority));
 
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mLoadGroup);
   if (p)
     p->SetPriority(aPriority);
 
-  PRInt32 count = mChildList.Count();
+  PRUint32 count = mChildList.Length();
 
   nsDocLoader *loader;
-  for (PRInt32 i=0; i < count; i++) {
-    loader = static_cast<nsDocLoader*>(ChildAt(i));
+  for (PRUint32 i=0; i < count; i++) {
+    loader = static_cast<nsDocLoader*>(mChildList[i]);
     if (loader) {
       loader->SetPriority(aPriority);
     }
   }
 
   return NS_OK;
 }
 
@@ -1636,21 +1543,21 @@ NS_IMETHODIMP nsDocLoader::AdjustPriorit
 {
   PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, 
          ("DocLoader:%p: AdjustPriority(%d) called\n", this, aDelta));
 
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mLoadGroup);
   if (p)
     p->AdjustPriority(aDelta);
 
-  PRInt32 count = mChildList.Count();
+  PRUint32 count = mChildList.Length();
 
   nsDocLoader *loader;
-  for (PRInt32 i=0; i < count; i++) {
-    loader = static_cast<nsDocLoader*>(ChildAt(i));
+  for (PRUint32 i=0; i < count; i++) {
+    loader = static_cast<nsDocLoader*>(mChildList[i]);
     if (loader) {
       loader->AdjustPriority(aDelta);
     }
   }
 
   return NS_OK;
 }
 
--- a/uriloader/base/nsDocLoader.h
+++ b/uriloader/base/nsDocLoader.h
@@ -43,31 +43,31 @@
 
 #include "nsIDocumentLoader.h"
 #include "nsIWebProgress.h"
 #include "nsIWebProgressListener.h"
 #include "nsIRequestObserver.h"
 #include "nsWeakReference.h"
 #include "nsILoadGroup.h"
 #include "nsCOMArray.h"
-#include "nsVoidArray.h"
+#include "nsTPtrArray.h"
+#include "nsTObserverArray.h"
 #include "nsString.h"
 #include "nsIChannel.h"
 #include "nsIProgressEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIChannelEventSink.h"
 #include "nsISecurityEventSink.h"
 #include "nsISupportsPriority.h"
 #include "nsInt64.h"
 #include "nsCOMPtr.h"
 #include "pldhash.h"
 
 struct nsRequestInfo;
-struct nsListenerInfo;
 
 /****************************************************************************
  * nsDocLoader implementation...
  ****************************************************************************/
 
 #define NS_THIS_DOCLOADER_IMPL_CID                    \
  { /* b4ec8387-98aa-4c08-93b6-6d23069c06f2 */         \
      0xb4ec8387,                                      \
@@ -123,34 +123,40 @@ public:
     // Remove aChild from our childlist.  This nulls out the child's mParent
     // pointer.
     nsresult RemoveChildLoader(nsDocLoader *aChild);
     // Add aChild to our child list.  This will set aChild's mParent pointer to
     // |this|.
     nsresult AddChildLoader(nsDocLoader* aChild);
     nsDocLoader* GetParent() const { return mParent; }
 
+    struct nsListenerInfo {
+      nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask) 
+        : mWeakListener(aListener),
+          mNotifyMask(aNotifyMask)
+      {
+      }
+
+      // Weak pointer for the nsIWebProgressListener...
+      nsWeakPtr mWeakListener;
+
+      // Mask indicating which notifications the listener wants to receive.
+      unsigned long mNotifyMask;
+    };
+
 protected:
     virtual ~nsDocLoader();
 
     virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
 
     PRBool IsBusy();
 
     void Destroy();
     virtual void DestroyChildren();
 
-    nsIDocumentLoader* ChildAt(PRInt32 i) {
-        return static_cast<nsDocLoader*>(mChildList[i]);
-    }
-
-    nsIDocumentLoader* SafeChildAt(PRInt32 i) {
-        return static_cast<nsDocLoader*>(mChildList.SafeElementAt(i));
-    }
-
     void FireOnProgressChange(nsDocLoader* aLoadInitiator,
                               nsIRequest *request,
                               PRInt64 aProgress,
                               PRInt64 aProgressMax,
                               PRInt64 aProgressDelta,
                               PRInt64 aTotalProgress,
                               PRInt64 aMaxTotalProgress);
 
@@ -211,21 +217,22 @@ protected:
     // for owning pointers and raw COM interface pointers for weak
     // (ie, non owning) references. If you add any members to this
     // class, please make the ownership explicit (pinkerton, scc).
   
     nsCOMPtr<nsIRequest>       mDocumentRequest;       // [OWNER] ???compare with document
 
     nsDocLoader*               mParent;                // [WEAK]
 
-    nsVoidArray                mListenerInfoList;
+    typedef nsAutoTObserverArray<nsListenerInfo, 8> ListenerArray;
+    ListenerArray mListenerInfoList;
 
-    nsCOMPtr<nsILoadGroup>        mLoadGroup;
+    nsCOMPtr<nsILoadGroup>         mLoadGroup;
     // We hold weak refs to all our kids
-    nsVoidArray                   mChildList;
+    nsTPtrArray<nsIDocumentLoader> mChildList;
 
     // The following member variables are related to the new nsIWebProgress 
     // feedback interfaces that travis cooked up.
     PRInt32 mProgressStateFlags;
 
     nsInt64 mCurrentSelfProgress;
     nsInt64 mMaxSelfProgress;
 
@@ -258,24 +265,23 @@ private:
     
     // DocLoaderIsEmpty should be called whenever the docloader may be empty.
     // This method is idempotent and does nothing if the docloader is not in
     // fact empty.  This method _does_ make sure that layout is flushed if our
     // loadgroup has no active requests before checking for "real" emptiness if
     // aFlushLayout is true.
     void DocLoaderIsEmpty(PRBool aFlushLayout);
 
-    nsListenerInfo *GetListenerInfo(nsIWebProgressListener* aListener);
-
     PRInt64 GetMaxTotalProgress();
 
     nsresult AddRequestInfo(nsIRequest* aRequest);
     void RemoveRequestInfo(nsIRequest* aRequest);
     nsRequestInfo *GetRequestInfo(nsIRequest* aRequest);
     void ClearRequestInfoHash();
+    void RemoveEmptyListeners();
     PRInt64 CalculateMaxProgress();
 ///    void DumpChannelInfo(void);
 
     // used to clear our internal progress state between loads...
     void ClearInternalProgress(); 
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsDocLoader, NS_THIS_DOCLOADER_IMPL_CID)
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -137,45 +137,41 @@ nsViewManager::PostInvalidateEvent()
     } else {
       mInvalidateEvent = ev;
     }
   }
 }
 
 #undef DEBUG_MOUSE_LOCATION
 
-PRInt32 nsViewManager::mVMCount = 0;
 nsIRenderingContext* nsViewManager::gCleanupContext = nsnull;
 
 // Weakly held references to all of the view managers
-nsVoidArray* nsViewManager::gViewManagers = nsnull;
+nsTArray<nsViewManager*>* nsViewManager::gViewManagers = nsnull;
 PRUint32 nsViewManager::gLastUserEventTime = 0;
 
 nsViewManager::nsViewManager()
   : mMouseLocation(NSCOORD_NONE, NSCOORD_NONE)
   , mDelayedResize(NSCOORD_NONE, NSCOORD_NONE)
   , mRootViewManager(this)
 {
   if (gViewManagers == nsnull) {
-    NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect");
     // Create an array to hold a list of view managers
-    gViewManagers = new nsVoidArray;
+    gViewManagers = new nsTArray<nsViewManager*>;
   }
  
   if (gCleanupContext == nsnull) {
     /* XXX: This should use a device to create a matching |nsIRenderingContext| object */
     CallCreateInstance(kRenderingContextCID, &gCleanupContext);
     NS_ASSERTION(gCleanupContext,
                  "Wasn't able to create a graphics context for cleanup");
   }
 
   gViewManagers->AppendElement(this);
 
-  ++mVMCount;
-
   // NOTE:  we use a zeroing operator new, so all data members are
   // assumed to be cleared here.
   mHasPendingUpdates = PR_FALSE;
   mRecursiveRefreshPending = PR_FALSE;
   mUpdateBatchFlags = 0;
 }
 
 nsViewManager::~nsViewManager()
@@ -193,26 +189,23 @@ nsViewManager::~nsViewManager()
   
   if (!IsRootVM()) {
     // We have a strong ref to mRootViewManager
     NS_RELEASE(mRootViewManager);
   }
 
   mRootScrollable = nsnull;
 
-  NS_ASSERTION((mVMCount > 0), "underflow of viewmanagers");
-  --mVMCount;
-
 #ifdef DEBUG
   PRBool removed =
 #endif
     gViewManagers->RemoveElement(this);
-  NS_ASSERTION(removed, "Viewmanager instance not was not in the global list of viewmanagers");
+  NS_ASSERTION(removed, "Viewmanager instance was not in the global list of viewmanagers");
 
-  if (0 == mVMCount) {
+  if (gViewManagers->IsEmpty()) {
     // There aren't any more view managers so
     // release the global array of view managers
    
     NS_ASSERTION(gViewManagers != nsnull, "About to delete null gViewManagers");
     delete gViewManagers;
     gViewManagers = nsnull;
 
     // Cleanup all of the offscreen drawing surfaces if the last view manager
@@ -2088,19 +2081,19 @@ nsViewManager::FlushPendingInvalidates()
     // view update batches we don't reenter this code and so that we batch
     // all of them together.  We don't use
     // BeginUpdateViewBatch/EndUpdateViewBatch, since that would reenter this
     // exact code, but we want the effect of a single big update batch.
     PRBool refreshEnabled = mRefreshEnabled;
     mRefreshEnabled = PR_FALSE;
     ++mUpdateBatchCnt;
     
-    PRInt32 index;
-    for (index = 0; index < mVMCount; index++) {
-      nsViewManager* vm = (nsViewManager*)gViewManagers->ElementAt(index);
+    PRUint32 index;
+    for (index = 0; index < gViewManagers->Length(); index++) {
+      nsViewManager* vm = gViewManagers->ElementAt(index);
       if (vm->RootViewManager() == this) {
         // One of our kids
         nsIViewObserver* observer = vm->GetViewObserver();
         if (observer) {
           observer->WillPaint();
           NS_ASSERTION(mUpdateBatchCnt == 1,
                        "Observer did not end view batch?");
         }
--- a/view/src/nsViewManager.h
+++ b/view/src/nsViewManager.h
@@ -38,17 +38,17 @@
 #ifndef nsViewManager_h___
 #define nsViewManager_h___
 #include "nsCOMPtr.h"
 #include "nsIViewManager.h"
 #include "nsCRT.h"
 #include "nsITimer.h"
 #include "prtime.h"
 #include "prinrval.h"
-#include "nsVoidArray.h"
+#include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsIScrollableView.h"
 #include "nsIRegion.h"
 #include "nsView.h"
 #include "nsIViewObserver.h"
 
 //Uncomment the following line to enable generation of viewmanager performance data.
 #ifdef MOZ_PERF_METRICS
@@ -408,23 +408,22 @@ private:
   PRPackedBool      mRefreshEnabled;
   // Use IsPainting() and SetPainting() to access mPainting.
   PRPackedBool      mPainting;
   PRPackedBool      mRecursiveRefreshPending;
   PRPackedBool      mHasPendingUpdates;
   PRPackedBool      mInScroll;
 
   //from here to public should be static and locked... MMP
-  static PRInt32           mVMCount;        //number of viewmanagers
 
   //Rendering context used to cleanup the blending buffers
   static nsIRenderingContext* gCleanupContext;
 
   //list of view managers
-  static nsVoidArray       *gViewManagers;
+  static nsTArray<nsViewManager*> *gViewManagers;
 
   void PostInvalidateEvent();
 
 #ifdef NS_VM_PERF_METRICS
   MOZ_TIMER_DECLARE(mWatch) //  Measures compositing+paint time for current document
 #endif
 };
 
--- a/xpcom/glue/nsTObserverArray.h
+++ b/xpcom/glue/nsTObserverArray.h
@@ -180,17 +180,23 @@ class nsAutoTObserverArray : protected n
     //
 
     // Prepend an element to the array unless it already exists in the array.
     // 'operator==' must be defined for elem_type.
     // @param item   The item to prepend.
     // @return       PR_TRUE if the element was found, or inserted successfully.
     template<class Item>
     PRBool PrependElementUnlessExists(const Item& item) {
-      return Contains(item) || mArray.InsertElementAt(0, item) != nsnull;
+      if (Contains(item))
+        return PR_TRUE;
+      if (mArray.InsertElementAt(0, item) != nsnull) {
+        AdjustIterators(0, 1);
+        return PR_TRUE;
+      }
+      return PR_FALSE;
     }
 
     // Append an element to the array.
     // @param item   The item to append.
     // @return A pointer to the newly appended element, or null on OOM.
     template<class Item>
     elem_type* AppendElement(const Item& item) {
       return mArray.AppendElement(item);
@@ -238,16 +244,21 @@ class nsAutoTObserverArray : protected n
     // Removes all observers and collapses all iterators to the beginning of
     // the array. The result is that forward iterators will see all elements
     // in the array.
     void Clear() {
       mArray.Clear();
       ClearIterators();
     }
 
+    // Compact the array to minimize the memory it uses
+    void Compact() {
+      mArray.Compact();
+    }
+
     //
     // Iterators
     //
 
     // Base class for iterators. Do not use this directly.
     class Iterator : public Iterator_base {
       protected:
         friend class nsAutoTObserverArray;
@@ -339,16 +350,48 @@ class nsAutoTObserverArray : protected n
           NS_ASSERTION(HasMore(), "iterating beyond end of array");
           return base_type::mArray.ElementAt(base_type::mPosition++);
         }
 
       private:
         ForwardIterator mEnd;
     };
 
+    // Iterates the array backward from end to start. mPosition points
+    // to the element that was returned last.
+    // Elements:
+    // - prepended to the array during iteration *will* be traversed,
+    //   unless the iteration already arrived at the first element
+    // - appended during iteration *will not* be traversed
+    // - removed during iteration *will not* be traversed.
+    class BackwardIterator : protected Iterator {
+      public:
+        typedef nsAutoTObserverArray<T, N> array_type;
+        typedef Iterator                   base_type;
+
+        BackwardIterator(const array_type& aArray)
+          : Iterator(aArray.Length(), aArray) {
+        }
+
+        // Returns PR_TRUE if there are more elements to iterate.
+        // This must precede a call to GetNext(). If PR_FALSE is
+        // returned, GetNext() must not be called.
+        PRBool HasMore() const {
+          return base_type::mPosition > 0;
+        }
+
+        // Returns the next element and steps one step. This must
+        // be preceded by a call to HasMore().
+        // @return The next observer.
+        elem_type& GetNext() {
+          NS_ASSERTION(HasMore(), "iterating beyond start of array");
+          return base_type::mArray.ElementAt(--base_type::mPosition);
+        }
+    };
+
   protected:
     nsAutoTArray<T, N> mArray;
 };
 
 template<class T>
 class nsTObserverArray : public nsAutoTObserverArray<T, 0> {
   public:
     typedef nsAutoTObserverArray<T, 0>       base_type;
--- a/xpinstall/src/nsXPITriggerInfo.h
+++ b/xpinstall/src/nsXPITriggerInfo.h
@@ -36,17 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsXPITriggerInfo_h
 #define nsXPITriggerInfo_h
 
 #include "nsString.h"
-#include "nsVoidArray.h"
+#include "nsTArray.h"
 #include "nsCOMPtr.h"
 #include "nsISupportsUtils.h"
 #include "nsILocalFile.h"
 #include "nsIOutputStream.h"
 #include "jsapi.h"
 #include "prthread.h"
 #include "nsIXPConnect.h"
 #include "nsICryptoHash.h"
@@ -108,32 +108,32 @@ class nsXPITriggerItem
 
 class nsXPITriggerInfo
 {
   public:
     nsXPITriggerInfo();
     ~nsXPITriggerInfo();
 
     void                Add( nsXPITriggerItem *aItem )
-                        { if ( aItem ) mItems.AppendElement( (void*)aItem ); }
+                        { if ( aItem ) mItems.AppendElement( aItem ); }
 
     nsXPITriggerItem*   Get( PRUint32 aIndex )
-                        { return (nsXPITriggerItem*)mItems.ElementAt(aIndex);}
+                        { return mItems.ElementAt(aIndex);}
 
     void                SaveCallback( JSContext *aCx, jsval aVal );
 
-    PRUint32            Size() { return mItems.Count(); }
+    PRUint32            Size() { return mItems.Length(); }
 
     void                SendStatus(const PRUnichar* URL, PRInt32 status);
 
     void                SetPrincipal(nsIPrincipal* aPrinc) { mPrincipal = aPrinc; }
 
 
   private:
-    nsVoidArray mItems;
+    nsTArray<nsXPITriggerItem*> mItems;
     JSContext   *mCx;
     nsCOMPtr<nsISupports> mContextWrapper;
     jsval       mCbval;
     nsCOMPtr<nsIThread> mThread;
 
     nsCOMPtr<nsIPrincipal>      mPrincipal;
 
     //-- prevent inadvertent copies and assignments