Back out b8e531a6c961 (Bug 474369), it really did cause the windows dhtml regression
authorArpad Borsos <arpad.borsos@googlemail.com>
Tue, 16 Jun 2009 14:38:51 +0200
changeset 29263 f9c14b122aa2ead4b62b6c3329c28d014cf711a3
parent 29262 72f6372d784a147d2335c0371aca0602ae0678d7
child 29264 719dec02c3a5bb56dd4450751b5e772d0493e9c2
push idunknown
push userunknown
push dateunknown
bugs474369
milestone1.9.2a1pre
backs outb8e531a6c961d7e4814efb7a0bb24c3ebfd3aacd
Back out b8e531a6c961 (Bug 474369), it really did cause the windows dhtml regression
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,16 +37,17 @@
  *
  * ***** 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,16 +44,17 @@
 #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 "nsIPrefBranch2.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.Length();
+  PRInt32 i = mArray.Count();
   if (!i)
     return nsnull;
 
   ProviderEntry* found = nsnull;  // Only set if we find a partial-match locale
   ProviderEntry* entry;
 
   while (i--) {
-    entry = &mArray[i];
+    entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
     if (aPreferred.Equals(entry->provider))
       return entry;
 
     if (aType != LOCALE)
       continue;
 
     if (LanguagesMatch(aPreferred, entry->provider)) {
       found = entry;
@@ -301,31 +301,42 @@ nsChromeRegistry::nsProviderArray::SetBa
   ProviderEntry* provider = GetProvider(aProvider, EXACT);
 
   if (provider) {
     provider->baseURI = aBaseURL;
     return;
   }
 
   // no existing entries, add a new one
-  mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
+  provider = new ProviderEntry(aProvider, aBaseURL);
+  if (!provider)
+    return; // It's safe to silently fail on OOM
+
+  mArray.AppendElement(provider);
 }
 
 void
 nsChromeRegistry::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
 {
-  PRInt32 i = mArray.Length();
+  PRInt32 i = mArray.Count();
   while (i--) {
-    a->AppendElement(mArray[i].provider);
+    ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    a->AppendElement(entry->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,16 +47,17 @@
 #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;
@@ -165,17 +166,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);
 
-    nsTArray<ProviderEntry> mArray;
+    nsVoidArray mArray;
   };
 
   struct PackageEntry : public PLDHashEntryHdr
   {
     PackageEntry(const nsACString& package);
     ~PackageEntry() { }
 
     // Available flags
--- a/db/morkreader/nsMorkReader.cpp
+++ b/db/morkreader/nsMorkReader.cpp
@@ -34,16 +34,17 @@
  * 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;
-    PRUint32 n = mChildList.Length();
-    for (PRUint32 i = 0; i < n; i++) {
-        shell = do_QueryInterface(mChildList[i]);
+    PRInt32 n = mChildList.Count();
+    for (PRInt32 i = 0; i < n; i++) {
+        shell = do_QueryInterface(ChildAt(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;
-        PRUint32 i, n = mChildList.Length();
+        PRInt32 i, n = mChildList.Count();
         kids.SetCapacity(n);
         for (i = 0; i < n; i++) {
-            kids.AppendElement(do_QueryInterface(mChildList[i]));
+            kids.AppendElement(do_QueryInterface(ChildAt(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);
 
-    PRUint32 count = mChildList.Length();
-    for (PRUint32 i = 0; i < count; ++i) {
-        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(mChildList[i]);
+    PRInt32 count = mChildList.Count();
+    for (PRInt32 i = 0; i < count; ++i) {
+        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(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
 
-    PRUint32 i, n = mChildList.Length();
+    PRInt32 i, n = mChildList.Count();
     for (i = 0; i < n; i++) {
-        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(mChildList[i]);
+        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(ChildAt(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.Length();
+    *aChildCount = mChildList.Count();
     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.IsEmpty(),
+    NS_ASSERTION(mChildList.Count() > 0,
                  "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.Length() - 1;
+            PRUint32 offset = mChildList.Count() - 1;
             if (doc) {
                PRUint32 oldChildCount = offset; // Current child count - 1
                for (PRUint32 i = 0; i < oldChildCount; ++i) {
-                 nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
+                 nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(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 (PRUint32(aIndex) >= mChildList.Length()) {
+    else if (aIndex >= mChildList.Count()) {
       NS_WARNING("Too large an index passed to GetChildAt");
     }
 #endif
 
-    nsIDocumentLoader* child = mChildList.SafeElementAt(aIndex);
+    nsIDocumentLoader* child = SafeChildAt(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;
-    PRUint32 i, n = mChildList.Length();
+    PRInt32 i, n = mChildList.Count();
     for (i = 0; i < n; i++) {
-        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(mChildList[i]);
+        nsCOMPtr<nsIDocShellTreeItem> child = do_QueryInterface(ChildAt(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();
     }
 
-    PRUint32 n;
-    PRUint32 count = mChildList.Length();
+    PRInt32 n;
+    PRInt32 count = mChildList.Count();
     for (n = 0; n < count; n++) {
-        nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryInterface(mChildList[n]));
+        nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryInterface(ChildAt(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.
-    PRUint32 n = mChildList.Length();
-
-    for (PRUint32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(mChildList[i]);
+    PRInt32 n = mChildList.Count();
+
+    for (PRInt32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i));
         if (shell)
             shell->SuspendRefreshURIs();
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::ResumeRefreshURIs()
 {
     RefreshURIFromQueue();
 
     // Resume refresh URIs for our child shells as well.
-    PRUint32 n = mChildList.Length();
-
-    for (PRUint32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(mChildList[i]);
+    PRInt32 n = mChildList.Count();
+
+    for (PRInt32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i));
         if (shell)
             shell->ResumeRefreshURIs();
     }
 
     return NS_OK;
 }
 
 nsresult
@@ -6354,19 +6354,19 @@ nsDocShell::CaptureState()
                 }
             }
         }
     }
 
     // Capture the docshell hierarchy.
     mOSHE->ClearChildShells();
 
-    PRUint32 childCount = mChildList.Length();
-    for (PRUint32 i = 0; i < childCount; ++i) {
-        nsCOMPtr<nsIDocShellTreeItem> childShell = do_QueryInterface(mChildList[i]);
+    PRInt32 childCount = mChildList.Count();
+    for (PRInt32 i = 0; i < childCount; ++i) {
+        nsCOMPtr<nsIDocShellTreeItem> childShell = do_QueryInterface(ChildAt(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()
 {
-    PRUint32 n = mChildList.Length();
-    for (PRUint32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
+    PRInt32 n = mChildList.Count();
+    for (PRInt32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(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.
 
-    PRUint32 n = mChildList.Length();
-    for (PRUint32 i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
+    PRInt32 n = mChildList.Count();
+    for (PRInt32 i = 0; i < n; ++i) {
+        nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(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.Length();
+    PRInt32 n = mChildList.Count();
     for (i = 0; i < n; ++i) {
-        nsCOMPtr<nsIDocShell> child = do_QueryInterface(mChildList[i]);
+        nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(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.
 
-            PRUint32 childCount = aRootShell->mChildList.Length();
-            for (PRUint32 j = 0; j < childCount; ++j) {
+            PRInt32 childCount = aRootShell->mChildList.Count();
+            for (PRInt32 j = 0; j < childCount; ++j) {
                 nsDocShell *child =
-                    static_cast<nsDocShell*>(aRootShell->mChildList[j]);
+                    static_cast<nsDocShell*>(aRootShell->ChildAt(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,16 +35,17 @@
  * 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,16 +43,17 @@
 
 #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,20 +71,37 @@ nsSelectionState::DoTraverse(nsCycleColl
     cb.NoteXPCOMChild(item.endNode);
   }
 }
 
 nsresult  
 nsSelectionState::SaveSelection(nsISelection *aSel)
 {
   if (!aSel) return NS_ERROR_NULL_POINTER;
-  PRInt32 i,rangeCount;
+  PRInt32 i,rangeCount, arrayCount = mArray.Length();
   aSel->GetRangeCount(&rangeCount);
   
-  mArray.SetLength(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);
+    }
+  }
   
   // 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,16 +35,17 @@
  *
  * ***** 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 nsTArrays of pointers to char*
+                                    // Entries are nsVoidArrays of pointers to PRUnichar*
                                     // 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,17 +172,19 @@ 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
-    mChildren.Clear();
+    for (PRInt32 i = 0; i < mChildren.Count(); i++) {
+      delete (nsJavaXPTCStub*) mChildren[i];
+    }
 
     // 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);
     }
   }
@@ -372,19 +374,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 (PRUint32 i = 0; i < mChildren.Length(); i++)
+  for (PRInt32 i = 0; i < mChildren.Count(); i++)
   {
-    nsJavaXPTCStub *child = mChildren[i];
+    nsJavaXPTCStub *child = (nsJavaXPTCStub *) 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,18 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsJavaXPTCStub_h_
 #define _nsJavaXPTCStub_h_
 
 #include "nsXPTCUtils.h"
 #include "jni.h"
-#include "nsTArray.h"
-#include "nsAutoPtr.h"
+#include "nsVoidArray.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}}
@@ -134,17 +133,17 @@ private:
                               jvalue &aJValue);
   nsresult SetXPCOMRetval();
 
   jobject                     mJavaWeakRef;
   jobject                     mJavaStrongRef;
   jint                        mJavaRefHashCode;
   nsCOMPtr<nsIInterfaceInfo>  mIInfo;
 
-  nsTArray<nsAutoPtr<nsJavaXPTCStub> > mChildren;
+  nsVoidArray     mChildren; // weak references (cleared by the children)
   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,16 +36,17 @@
  * ***** 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
-    nsAutoTArray<nsAutoPtr<GConfCallbackData>, 8> mObservers;
+    nsAutoVoidArray *mObservers;
 
     void InitFuncPtrs();
     //gconf public func ptrs
 
     //gconf client funcs
     GConfClientGetDefaultType GConfClientGetDefault;
     GConfClientGetBoolType GConfClientGetBool;
     GConfClientGetStringType GConfClientGetString;
@@ -200,36 +200,50 @@ private:
 
     //const strings
     static const char sPrefGConfKey[];
     static const char sDefaultLibName1[];
     static const char sDefaultLibName2[];
 };
 
 struct SysPrefCallbackData {
-    nsCOMPtr<nsISupports> observer;
+    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)
+     mGConf(nsnull),
+     mObservers(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;
@@ -373,91 +387,109 @@ 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);
 
-    SysPrefCallbackData *cbData = new SysPrefCallbackData();
+    if (!mObservers) {
+        mObservers = new nsAutoVoidArray();
+        if (mObservers == nsnull)
+            return NS_ERROR_OUT_OF_MEMORY;
+    }
 
-    cbData->bIsWeakRef = aHoldWeak;
-    cbData->prefAtom = prefAtom;
+    SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *)
+        nsMemory::Alloc(sizeof(SysPrefCallbackData));
+    if (pCallbackData == nsnull)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    pCallbackData->bIsWeakRef = aHoldWeak;
+    pCallbackData->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
-            delete cbData;
+            nsMemory::Free(pCallbackData);
             return NS_ERROR_INVALID_ARG;
         }
         nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory);
         observerRef = tmp;
     } else {
         observerRef = aObserver;
     }
 
-    rv = mGConf->NotifyAdd(prefAtom, cbData);
+    rv = mGConf->NotifyAdd(prefAtom, pCallbackData);
     if (NS_FAILED(rv)) {
-        delete cbData;
+        nsMemory::Free(pCallbackData);
         return rv;
     }
 
-    cbData->observer = observerRef;
-    mObservers.AppendElement(cbData);
+    pCallbackData->observer = observerRef;
+    NS_ADDREF(pCallbackData->observer);
 
+    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
-    PRUint32 count = mObservers.Length();
-    if (!count)
+    PRIntn count = mObservers->Count();
+    if (count <= 0)
         return NS_OK;
 
-    PRUint32 i;
+    PRIntn i;
+    SysPrefCallbackData *pCallbackData;
     for (i = 0; i < count; ++i) {
-        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;
+        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;
+                }
             }
-        }
-        if (!observerRef)
-            observerRef = aObserver;
+            if (!observerRef)
+                observerRef = aObserver;
 
-        if (cbData->observer == observerRef &&
-            cbData->prefAtom == prefAtom) {
-            rv = mGConf->NotifyRemove(prefAtom, cbData);
-            if (NS_SUCCEEDED(rv)) {
-                mObservers.RemoveElementAt(i);
+            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;
             }
-            return rv;
         }
     }
     return NS_OK;
 }
 
 void
 nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData)
 {
@@ -473,17 +505,19 @@ 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);
+                mObservers->RemoveElement(pData);
+                NS_RELEASE(pData->observer);
+                nsMemory::Free(pData);
             }
             return;
         }
     }
     else
         observer = do_QueryInterface(pData->observer);
 
     if (observer)
@@ -548,30 +582,41 @@ 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)
+    mSysPrefService(aSysPrefService),
+    mObservers(nsnull)
 {
 }
 
 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"));
@@ -714,51 +759,60 @@ 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;
 
-    GConfCallbackData *pData = new GConfCallbackData();
+    if (!mObservers) {
+        mObservers = new nsAutoVoidArray();
+        if (mObservers == nsnull)
+            return NS_ERROR_OUT_OF_MEMORY;
+    }
+ 
+    GConfCallbackData *pData = (GConfCallbackData *)
+        nsMemory::Alloc(sizeof(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);
 
-    PRUint32 count = mObservers.Length();
-    if (!count)
+    PRIntn count = mObservers->Count();
+    if (count <= 0)
         return NS_OK;
 
-    PRUint32 i;
+    PRIntn i;
+    GConfCallbackData *pData;
     for (i = 0; i < count; ++i) {
-        GConfCallbackData *pData = mObservers[i];
-        if (pData->atom == aAtom && pData->userData == aUserData) {
+        pData = (GConfCallbackData *)mObservers->ElementAt(i);
+        if (pData && pData->atom == aAtom && pData->userData == aUserData) {
             GConfClientNotifyRemove(mGConfClient, pData->notifyId);
             GConfClientRemoveDir(mGConfClient,
                                  GetGConfKey(pData->atom), NULL);
-            mObservers.RemoveElementAt(i);
+            mObservers->RemoveElementAt(i);
+            nsMemory::Free(pData);
             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,24 +38,22 @@
  * 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 "nsTArray.h"
-#include "nsAutoPtr.h"
+#include "nsVoidArray.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
@@ -71,17 +69,17 @@ public:
 
     void OnPrefChange(PRUint32 aPrefAtom, void *aData);
 
 private:
     PRBool mInitialized;
     GConfProxy *mGConf;
 
     //listeners
-    nsAutoTArray<nsAutoPtr<SysPrefCallbackData>, 8> mObservers;
+    nsAutoVoidArray *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,16 +35,17 @@
  *
  * ***** 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,16 +40,17 @@
 
 #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,16 +39,17 @@
 #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,16 +34,17 @@
  * 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,35 +932,36 @@ 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) {
-    nsAutoTArray<RuleProcessorData*, 8> destroyQueue;
+    nsAutoVoidArray destroyQueue;
     destroyQueue.AppendElement(this);
 
     do {
-      RuleProcessorData *d = destroyQueue[destroyQueue.Length() - 1];
-      destroyQueue.RemoveElementAt(destroyQueue.Length() - 1);
+      RuleProcessorData *d = static_cast<RuleProcessorData*>
+                                        (destroyQueue.FastElementAt(destroyQueue.Count() - 1));
+      destroyQueue.RemoveElementAt(destroyQueue.Count() - 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.Length());
+    } while (destroyQueue.Count());
   }
 
   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;
-  nsTArray<const char*> *pref_list;
+  nsVoidArray *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;
-  const char*     theElement;
-  PRUint32        numPrefs;
-  PRUint32        dwIndex;
+  char*           theElement;
+  PRInt32         numPrefs;
+  PRInt32         dwIndex;
   EnumerateData   ed;
-  nsAutoTArray<const char*, 8> prefArray;
+  nsAutoVoidArray 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.Length();
+  numPrefs = prefArray.Count();
 
   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 = (prefArray.ElementAt(dwIndex)) + mPrefRootLength;
+      theElement = ((char *)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 nsAutoTArray<PrefCallbackData*, 8>();
+    mObservers = new nsAutoVoidArray();
     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;
-  PRUint32 count;
-  PRUint32 i;
+  PRInt32 count;
+  PRInt32 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->Length();
+  count = mObservers->Count();
   if (count == 0)
     return NS_OK;
 
   for (i = 0; i < count; i++) {
-    pCallback = mObservers->ElementAt(i);
+    pCallback = (PrefCallbackData *)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
-    PRUint32 count;
+    PRInt32 count;
 
-    count = mObservers->Length();
+    count = mObservers->Count();
     if (count > 0) {
-      PRUint32 i;
+      PRInt32 i;
       nsCAutoString domain;
       for (i = 0; i < count; ++i) {
-        pCallback = mObservers->ElementAt(i);
+        pCallback = (PrefCallbackData *)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->ElementAt(i) = nsnull;
+          mObservers->ReplaceElementAt(nsnull, i);
           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 = nsnull;
+    mObservers = 0;
   }
 }
  
 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(he->key);
+    d->pref_list->AppendElement((void*)he->key);
   }
   return PL_DHASH_NEXT;
 }
 
 
 /*
  * nsISecurityPref methods
  *
--- a/modules/libpref/src/nsPrefBranch.h
+++ b/modules/libpref/src/nsPrefBranch.h
@@ -44,21 +44,20 @@
 #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
@@ -77,17 +76,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;
-  nsAutoTArray<PrefCallbackData*, 8> *mObservers;
+  nsAutoVoidArray       *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,16 +61,17 @@
 #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,16 +48,17 @@ 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,16 +36,17 @@
  * 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 "nsTArray.h"
+#include "nsVoidArray.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.
-    nsAutoTArray<AllocationNode*, 8> pointers_to;
+    nsAutoVoidArray pointers_to;
 
     // The reverse.
-    nsAutoTArray<AllocationNode*, 8> pointers_from;
+    nsAutoVoidArray 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,43 +190,44 @@ 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;
-        nsAutoTArray<AllocationNode*, 8> stack;
+        nsVoidArray stack;
 
         for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) {
             if (n->reached) {
                 continue;
             }
             stack.AppendElement(n);
 
             do {
-                PRUint32 pos = stack.Length() - 1;
-                AllocationNode *n = stack[pos];
+                PRUint32 pos = stack.Count() - 1;
+                AllocationNode *n =
+                    static_cast<AllocationNode*>(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.
-                    nsAutoTArray<AllocationNode*, 8> &pt = n->pointers_to;
-                    for (PRInt32 i = pt.Length() - 1; i >= 0; --i) {
-                        if (!pt[i]->reached) {
+                    nsVoidArray &pt = n->pointers_to;
+                    for (PRInt32 i = pt.Count() - 1; i >= 0; --i) {
+                        if (!static_cast<AllocationNode*>(pt[i])->reached) {
                             stack.AppendElement(pt[i]);
                         }
                     }
                 }
-            } while (stack.Length() > 0);
+            } while (stack.Count() > 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]);
@@ -242,66 +243,69 @@ 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;
         }
-        nsAutoTArray<AllocationNode*, 8> stack;
+        nsVoidArray 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.Length() - 1;
-                AllocationNode *n = stack[pos];
+                PRUint32 pos = stack.Count() - 1;
+                AllocationNode *n =
+                    static_cast<AllocationNode*>(stack[pos]);
                 stack.RemoveElementAt(pos);
 
                 if (!n->reached) {
                     n->reached = PR_TRUE;
                     n->index = num_sccs;
                     stack.AppendElements(n->pointers_from);
                 }
-            } while (stack.Length() > 0);
+            } while (stack.Count() > 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;
         }
 
-        nsAutoTArray<AllocationNode*, 8> stack;
+        nsVoidArray 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.Length() - 1; i >= 0; --i) {
-                AllocationNode *target = n->pointers_to[i];
+            for (int i = n->pointers_to.Count() - 1; i >= 0; --i) {
+                AllocationNode *target =
+                    static_cast<AllocationNode*>(n->pointers_to[i]);
                 if (n->index != target->index) {
                     stack.AppendElement(target);
                 }
             }
 
-            while (stack.Length() > 0) {
-                PRUint32 pos = stack.Length() - 1;
-                AllocationNode *n = stack[pos];
+            while (stack.Count() > 0) {
+                PRUint32 pos = stack.Count() - 1;
+                AllocationNode *n =
+                    static_cast<AllocationNode*>(stack[pos]);
                 stack.RemoveElementAt(pos);
 
                 if (n->is_root) {
                     n->is_root = PR_FALSE;
                     --num_root_nodes;
                     stack.AppendElements(n->pointers_to);
                 }
             }
@@ -389,21 +393,22 @@ int main(int argc, char **argv)
                         }
                         printf("\n");
                     } else {
                         printf("        0x%08X\n",
                                *(unsigned int*)(e->data + d));
                     }
                 }
 
-                if (n->pointers_from.Length()) {
+                if (n->pointers_from.Count()) {
                     printf("\nPointers from:\n");
-                    for (PRUint32 i = 0, i_end = n->pointers_from.Length();
+                    for (PRUint32 i = 0, i_end = n->pointers_from.Count();
                          i != i_end; ++i) {
-                        AllocationNode *t = n->pointers_from[i];
+                        AllocationNode *t = static_cast<AllocationNode*>
+                                                       (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,30 +112,35 @@ static PRBool
 RequestInfoHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
                          const void *key)
 {
   // Initialize the entry with placement new
   new (entry) nsRequestInfo(key);
   return PR_TRUE;
 }
 
-// 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;
-    }
+
+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;
 };
 
+
 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");
   }
@@ -283,26 +288,26 @@ nsDocLoader::AddDocLoaderAsChildOfRoot(n
 
   return rootDocLoader->AddChildLoader(aDocLoader);
 }
 
 NS_IMETHODIMP
 nsDocLoader::Stop(void)
 {
   nsresult rv = NS_OK;
-  PRUint32 count, i;
+  PRInt32 count, i;
 
   PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, 
          ("DocLoader:%p: Stop() called\n", this));
 
-  count = mChildList.Length();
+  count = mChildList.Count();
 
   nsCOMPtr<nsIDocumentLoader> loader;
   for (i=0; i < count; i++) {
-    loader = mChildList[i];
+    loader = ChildAt(i);
 
     if (loader) {
       (void) loader->Stop();
     }
   }
 
   if (mLoadGroup)
     rv = mLoadGroup->Cancel(NS_BINDING_ABORTED);
@@ -359,22 +364,22 @@ nsDocLoader::IsBusy()
   if (NS_FAILED(rv)) {
     return PR_FALSE;
   }
   if (busy) {
     return PR_TRUE;
   }
 
   /* check its child document loaders... */
-  PRUint32 count, i;
+  PRInt32 count, i;
 
-  count = mChildList.Length();
+  count = mChildList.Count();
 
   for (i=0; i < count; i++) {
-    nsIDocumentLoader* loader = mChildList[i];
+    nsIDocumentLoader* loader = ChildAt(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;
@@ -411,39 +416,48 @@ 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()
 {
-  PRUint32 i, count;
+  PRInt32 i, count;
   
-  count = mChildList.Length();
+  count = mChildList.Count();
   // 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 = mChildList[i];
+    nsIDocumentLoader* loader = ChildAt(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();
@@ -878,36 +892,54 @@ void nsDocLoader::doStopDocumentLoad(nsI
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
 // The following section contains support for nsIWebProgress and related stuff
 ////////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsDocLoader::AddProgressListener(nsIWebProgressListener *aListener,
-                                 PRUint32 aNotifyMask)
+                                     PRUint32 aNotifyMask)
 {
-  if (mListenerInfoList.Contains(aListener)) {
+  nsresult rv;
+
+  nsListenerInfo* info = GetListenerInfo(aListener);
+  if (info) {
     // The listener is already registered!
     return NS_ERROR_FAILURE;
   }
 
   nsWeakPtr listener = do_GetWeakReference(aListener);
   if (!listener) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  return mListenerInfoList.AppendElement(nsListenerInfo(listener, aNotifyMask)) ?
-         NS_OK : NS_ERROR_OUT_OF_MEMORY;
+  info = new nsListenerInfo(listener, aNotifyMask);
+  if (!info) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  rv = mListenerInfoList.AppendElement(info) ? NS_OK : NS_ERROR_FAILURE;
+  return rv;
 }
 
 NS_IMETHODIMP
 nsDocLoader::RemoveProgressListener(nsIWebProgressListener *aListener)
 {
-  return mListenerInfoList.RemoveElement(aListener) ? NS_OK : NS_ERROR_FAILURE;
+  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;
 }
 
 NS_IMETHODIMP
 nsDocLoader::GetDOMWindow(nsIDOMWindow **aResult)
 {
   return CallGetInterface(this, aResult);
 }
 
@@ -918,22 +950,22 @@ nsDocLoader::GetIsLoadingDocument(PRBool
 
   return NS_OK;
 }
 
 PRInt64 nsDocLoader::GetMaxTotalProgress()
 {
   nsInt64 newMaxTotal = 0;
 
-  PRUint32 count = mChildList.Length();
+  PRInt32 count = mChildList.Count();
   nsCOMPtr<nsIWebProgress> webProgress;
-  for (PRUint32 i=0; i < count; i++) 
+  for (PRInt32 i=0; i < count; i++) 
   {
     nsInt64 individualProgress = 0;
-    nsIDocumentLoader* docloader = mChildList[i];
+    nsIDocumentLoader* docloader = ChildAt(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
     {
@@ -1118,38 +1150,47 @@ 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...
+  /*
+   * 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
+   */
   nsCOMPtr<nsIWebProgressListener> listener;
-  ListenerArray::BackwardIterator iter(mListenerInfoList);
+  PRInt32 count = mListenerInfoList.Count();
 
-  while (iter.HasMore()) {
-    nsListenerInfo &info = iter.GetNext();
-    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
+  while (--count >= 0) {
+    nsListenerInfo *info;
+
+    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
+    if (!info || !(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.
-      RemoveEmptyListeners();
+      mListenerInfoList.RemoveElementAt(count);
+      delete info;
       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);
@@ -1185,104 +1226,130 @@ 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...
+  /*                                                                           
+   * 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
+   */
   nsCOMPtr<nsIWebProgressListener> listener;
-  ListenerArray::BackwardIterator iter(mListenerInfoList);
+  PRInt32 count = mListenerInfoList.Count();
 
-  while (iter.HasMore()) {
-    nsListenerInfo &info = iter.GetNext();
-    if (!(info.mNotifyMask & (aStateFlags >>16))) {
+  while (--count >= 0) {
+    nsListenerInfo *info;
+
+    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
+    if (!info || !(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.
-      RemoveEmptyListeners();
+      mListenerInfoList.RemoveElementAt(count);
+      delete info;
       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...
+  /*                                                                           
+   * 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
+   */
   nsCOMPtr<nsIWebProgressListener> listener;
-  ListenerArray::BackwardIterator iter(mListenerInfoList);
+  PRInt32 count = mListenerInfoList.Count();
 
-  while (iter.HasMore()) {
-    nsListenerInfo &info = iter.GetNext();
-    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
+  while (--count >= 0) {
+    nsListenerInfo *info;
+
+    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
+    if (!info || !(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.
-      RemoveEmptyListeners();
+      mListenerInfoList.RemoveElementAt(count);
+      delete info;
       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...
+  /*                                                                           
+   * 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
+   */
   nsCOMPtr<nsIWebProgressListener> listener;
-  ListenerArray::BackwardIterator iter(mListenerInfoList);
+  PRInt32 count = mListenerInfoList.Count();
 
-  while (iter.HasMore()) {
-    nsListenerInfo &info = iter.GetNext();
-    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
+  while (--count >= 0) {
+    nsListenerInfo *info;
+
+    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
+    if (!info || !(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.
-      RemoveEmptyListeners();
+      mListenerInfoList.RemoveElementAt(count);
+      delete info;
       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,
@@ -1290,58 +1357,86 @@ 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;
-  ListenerArray::BackwardIterator iter(mListenerInfoList);
+  PRInt32 count = mListenerInfoList.Count();
 
-  while (iter.HasMore()) {
-    nsListenerInfo &info = iter.GetNext();
-    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
+  while (--count >= 0) {
+    nsListenerInfo *info;
+
+    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
+    if (!info || !(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.
-      RemoveEmptyListeners();
+      mListenerInfoList.RemoveElementAt(count);
+      delete info;
       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;
 }
@@ -1384,27 +1479,16 @@ 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);
 
@@ -1465,35 +1549,44 @@ 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...
+  /*                                                                           
+   * 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
+   */
   nsCOMPtr<nsIWebProgressListener> listener;
-  ListenerArray::BackwardIterator iter(mListenerInfoList);
+  PRInt32 count = mListenerInfoList.Count();
 
-  while (iter.HasMore()) {
-    nsListenerInfo &info = iter.GetNext();
-    if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
+  while (--count >= 0) {
+    nsListenerInfo *info;
+
+    info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
+    if (!info || !(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.
-      RemoveEmptyListeners();
+      mListenerInfoList.RemoveElementAt(count);
+      delete info;
       continue;
     }
 
     listener->OnSecurityChange(webProgress, request, aState);
   }
+
   mListenerInfoList.Compact();
 
   // Pass the notification up to the parent...
   if (mParent) {
     mParent->OnSecurityChange(aContext, aState);
   }
   return NS_OK;
 }
@@ -1521,21 +1614,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);
 
-  PRUint32 count = mChildList.Length();
+  PRInt32 count = mChildList.Count();
 
   nsDocLoader *loader;
-  for (PRUint32 i=0; i < count; i++) {
-    loader = static_cast<nsDocLoader*>(mChildList[i]);
+  for (PRInt32 i=0; i < count; i++) {
+    loader = static_cast<nsDocLoader*>(ChildAt(i));
     if (loader) {
       loader->SetPriority(aPriority);
     }
   }
 
   return NS_OK;
 }
 
@@ -1543,21 +1636,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);
 
-  PRUint32 count = mChildList.Length();
+  PRInt32 count = mChildList.Count();
 
   nsDocLoader *loader;
-  for (PRUint32 i=0; i < count; i++) {
-    loader = static_cast<nsDocLoader*>(mChildList[i]);
+  for (PRInt32 i=0; i < count; i++) {
+    loader = static_cast<nsDocLoader*>(ChildAt(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 "nsTPtrArray.h"
-#include "nsTObserverArray.h"
+#include "nsVoidArray.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,40 +123,34 @@ 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);
 
@@ -217,22 +211,21 @@ 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]
 
-    typedef nsAutoTObserverArray<nsListenerInfo, 8> ListenerArray;
-    ListenerArray mListenerInfoList;
+    nsVoidArray                mListenerInfoList;
 
-    nsCOMPtr<nsILoadGroup>         mLoadGroup;
+    nsCOMPtr<nsILoadGroup>        mLoadGroup;
     // We hold weak refs to all our kids
-    nsTPtrArray<nsIDocumentLoader> mChildList;
+    nsVoidArray                   mChildList;
 
     // The following member variables are related to the new nsIWebProgress 
     // feedback interfaces that travis cooked up.
     PRInt32 mProgressStateFlags;
 
     nsInt64 mCurrentSelfProgress;
     nsInt64 mMaxSelfProgress;
 
@@ -265,23 +258,24 @@ 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,41 +137,45 @@ 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
-nsTArray<nsViewManager*>* nsViewManager::gViewManagers = nsnull;
+nsVoidArray* 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 nsTArray<nsViewManager*>;
+    gViewManagers = new nsVoidArray;
   }
  
   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()
@@ -189,23 +193,26 @@ 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 was not in the global list of viewmanagers");
+  NS_ASSERTION(removed, "Viewmanager instance not was not in the global list of viewmanagers");
 
-  if (gViewManagers->IsEmpty()) {
+  if (0 == mVMCount) {
     // 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
@@ -2081,19 +2088,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;
     
-    PRUint32 index;
-    for (index = 0; index < gViewManagers->Length(); index++) {
-      nsViewManager* vm = gViewManagers->ElementAt(index);
+    PRInt32 index;
+    for (index = 0; index < mVMCount; index++) {
+      nsViewManager* vm = (nsViewManager*)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 "nsTArray.h"
+#include "nsVoidArray.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,22 +408,23 @@ 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 nsTArray<nsViewManager*> *gViewManagers;
+  static nsVoidArray       *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,23 +180,17 @@ 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) {
-      if (Contains(item))
-        return PR_TRUE;
-      if (mArray.InsertElementAt(0, item) != nsnull) {
-        AdjustIterators(0, 1);
-        return PR_TRUE;
-      }
-      return PR_FALSE;
+      return Contains(item) || mArray.InsertElementAt(0, item) != nsnull;
     }
 
     // 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);
@@ -244,21 +238,16 @@ 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;
@@ -350,48 +339,16 @@ 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 "nsTArray.h"
+#include "nsVoidArray.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( aItem ); }
+                        { if ( aItem ) mItems.AppendElement( (void*)aItem ); }
 
     nsXPITriggerItem*   Get( PRUint32 aIndex )
-                        { return mItems.ElementAt(aIndex);}
+                        { return (nsXPITriggerItem*)mItems.ElementAt(aIndex);}
 
     void                SaveCallback( JSContext *aCx, jsval aVal );
 
-    PRUint32            Size() { return mItems.Length(); }
+    PRUint32            Size() { return mItems.Count(); }
 
     void                SendStatus(const PRUnichar* URL, PRInt32 status);
 
     void                SetPrincipal(nsIPrincipal* aPrinc) { mPrincipal = aPrinc; }
 
 
   private:
-    nsTArray<nsXPITriggerItem*> mItems;
+    nsVoidArray mItems;
     JSContext   *mCx;
     nsCOMPtr<nsISupports> mContextWrapper;
     jsval       mCbval;
     nsCOMPtr<nsIThread> mThread;
 
     nsCOMPtr<nsIPrincipal>      mPrincipal;
 
     //-- prevent inadvertent copies and assignments