comptr-rewrite.patch
author Benjamin Smedberg <benjamin@smedbergs.us>
Sat, 26 Jul 2008 22:49:39 -0400
changeset 167 a4da40849f5436e629c5732f4368c6c48189637f
parent 163 1124940b811904ccbf0aa91533a7184843788d7b
permissions -rw-r--r--
State as of now

* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * *

diff --git a/accessible/src/base/nsAccessNode.cpp b/accessible/src/base/nsAccessNode.cpp
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -117,7 +117,6 @@ nsIAccessibilityService *nsAccessNode::G
 //-----------------------------------------------------
 NS_IMPL_QUERY_INTERFACE2(nsAccessNode, nsIAccessNode, nsPIAccessNode)
 NS_IMPL_ADDREF(nsAccessNode)
-NS_IMPL_RELEASE_WITH_DESTROY(nsAccessNode, LastRelease())
 
 nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell): 
   mDOMNode(aNode), mWeakShell(aShell)
@@ -132,18 +131,10 @@ nsAccessNode::nsAccessNode(nsIDOMNode *a
 //-----------------------------------------------------
 nsAccessNode::~nsAccessNode()
 {
-  NS_ASSERTION(!mWeakShell, "LastRelease was never called!?!");
-}
-
-void nsAccessNode::LastRelease()
-{
-  // First cleanup if needed...
   if (mWeakShell) {
     Shutdown();
     NS_ASSERTION(!mWeakShell, "A Shutdown() impl forgot to call its parent's Shutdown?");
   }
-  // ... then die.
-  NS_DELETEXPCOM(this);
 }
 
 NS_IMETHODIMP nsAccessNode::Init()
diff --git a/caps/include/nsPrincipal.h b/caps/include/nsPrincipal.h
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -51,7 +51,7 @@ class nsIObjectInputStream;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 
-class nsPrincipal : public nsIPrincipal
+class nsPrincipal : public XPCOMGCFinalizedObject, public nsIPrincipal
 {
 public:
   nsPrincipal();
diff --git a/caps/src/nsNullPrincipal.cpp b/caps/src/nsNullPrincipal.cpp
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -60,28 +60,6 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrinc
 NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal,
                              nsIPrincipal,
                              nsISerializable)
-
-NS_IMETHODIMP_(nsrefcnt) 
-nsNullPrincipal::AddRef()
-{
-  NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt");
-  nsrefcnt count = PR_AtomicIncrement((PRInt32 *)&mJSPrincipals.refcount);
-  NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this));
-  return count;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsNullPrincipal::Release()
-{
-  NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release");
-  nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
-  NS_LOG_RELEASE(this, count, "nsNullPrincipal");
-  if (count == 0) {
-    NS_DELETEXPCOM(this);
-  }
-
-  return count;
-}
 
 nsNullPrincipal::nsNullPrincipal()
 {
diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -81,29 +81,6 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsPrincipal
 NS_IMPL_CI_INTERFACE_GETTER2(nsPrincipal,
                              nsIPrincipal,
                              nsISerializable)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsPrincipal::AddRef()
-{
-  NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt");
-  // XXXcaa does this need to be threadsafe?  See bug 143559.
-  nsrefcnt count = PR_AtomicIncrement((PRInt32 *)&mJSPrincipals.refcount);
-  NS_LOG_ADDREF(this, count, "nsPrincipal", sizeof(*this));
-  return count;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsPrincipal::Release()
-{
-  NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release");
-  nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
-  NS_LOG_RELEASE(this, count, "nsPrincipal");
-  if (count == 0) {
-    NS_DELETEXPCOM(this);
-  }
-
-  return count;
-}
 
 nsPrincipal::nsPrincipal()
   : mCapabilities(nsnull),
diff --git a/caps/src/nsSystemPrincipal.cpp b/caps/src/nsSystemPrincipal.cpp
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -56,29 +56,6 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsSystemPri
 NS_IMPL_CI_INTERFACE_GETTER2(nsSystemPrincipal,
                              nsIPrincipal,
                              nsISerializable)
-
-NS_IMETHODIMP_(nsrefcnt) 
-nsSystemPrincipal::AddRef()
-{
-  NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt");
-  nsrefcnt count = PR_AtomicIncrement((PRInt32 *)&mJSPrincipals.refcount);
-  NS_LOG_ADDREF(this, count, "nsSystemPrincipal", sizeof(*this));
-  return count;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsSystemPrincipal::Release()
-{
-  NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release");
-  nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount);
-  NS_LOG_RELEASE(this, count, "nsSystemPrincipal");
-  if (count == 0) {
-    NS_DELETEXPCOM(this);
-  }
-
-  return count;
-}
-
 
 ///////////////////////////////////////
 // Methods implementing nsIPrincipal //
diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -111,7 +111,6 @@ class nsIDocument : public nsINode
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
-  NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
 #ifdef MOZILLA_INTERNAL_API
   nsIDocument()
diff --git a/content/base/src/nsCommentNode.cpp b/content/base/src/nsCommentNode.cpp
--- a/content/base/src/nsCommentNode.cpp
+++ b/content/base/src/nsCommentNode.cpp
@@ -178,7 +178,7 @@ nsCommentNode::List(FILE* out, PRInt32 a
   PRInt32 indx;
   for (indx = aIndent; --indx >= 0; ) fputs("  ", out);
 
-  fprintf(out, "Comment@%p refcount=%d<!--", (void*)this, mRefCnt.get());
+  fprintf(out, "Comment@%p<!--", (void*) this);
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
diff --git a/content/base/src/nsContentIterator.cpp b/content/base/src/nsContentIterator.cpp
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -121,7 +121,8 @@ ContentIsInTraversalRange(nsIContent *aC
 /*
  *  A simple iterator class for traversing the content in "close tag" order
  */
-class nsContentIterator : public nsIContentIterator //, public nsIEnumerator
+class nsContentIterator : public nsIContentIterator
+                      //, public nsIEnumerator
 {
 public:
   NS_DECL_ISUPPORTS
diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -881,14 +881,14 @@ nsNSElementTearoff::GetClientRects(nsIDO
 {
   *aResult = nsnull;
 
-  nsRefPtr<nsClientRectList> rectList = new nsClientRectList();
+  nsClientRectList *rectList = new nsClientRectList();
   if (!rectList)
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsIFrame* frame = mContent->GetPrimaryFrame(Flush_Layout);
   if (!frame) {
     // display:none, perhaps? Return an empty list
-    *aResult = rectList.forget().get();
+    *aResult = rectList;
     return NS_OK;
   }
 
@@ -897,7 +897,7 @@ nsNSElementTearoff::GetClientRects(nsIDO
           GetContainingBlockForClientRect(frame), &builder);
   if (NS_FAILED(builder.mRV))
     return builder.mRV;
-  *aResult = rectList.forget().get();
+  *aResult = rectList;
   return NS_OK;
 }
 
@@ -952,21 +952,6 @@ nsNodeSupportsWeakRefTearoff::GetWeakRef
 
 //----------------------------------------------------------------------
 
-nsDOMEventRTTearoff *
-nsDOMEventRTTearoff::mCachedEventTearoff[NS_EVENT_TEAROFF_CACHE_SIZE];
-
-PRUint32 nsDOMEventRTTearoff::mCachedEventTearoffCount = 0;
-
-
-nsDOMEventRTTearoff::nsDOMEventRTTearoff(nsIContent *aContent)
-  : mContent(aContent)
-{
-}
-
-nsDOMEventRTTearoff::~nsDOMEventRTTearoff()
-{
-}
-
 NS_IMPL_CYCLE_COLLECTION_1(nsDOMEventRTTearoff, mContent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventRTTearoff)
@@ -977,64 +962,6 @@ NS_INTERFACE_MAP_END_AGGREGATED(mContent
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsDOMEventRTTearoff,
                                           nsIDOMEventTarget)
-NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS_WITH_DESTROY(nsDOMEventRTTearoff,
-                                                        nsIDOMEventTarget,
-                                                        LastRelease())
-
-nsDOMEventRTTearoff *
-nsDOMEventRTTearoff::Create(nsIContent *aContent)
-{
-  if (mCachedEventTearoffCount) {
-    // We have cached unused instances of this class, return a cached
-    // instance in stead of always creating a new one.
-    nsDOMEventRTTearoff *tearoff =
-      mCachedEventTearoff[--mCachedEventTearoffCount];
-
-    // Set the back pointer to the content object
-    tearoff->mContent = aContent;
-
-    return tearoff;
-  }
-
-  // The cache is empty, this means we haveto create a new instance.
-  return new nsDOMEventRTTearoff(aContent);
-}
-
-// static
-void
-nsDOMEventRTTearoff::Shutdown()
-{
-  // Clear our cache.
-  while (mCachedEventTearoffCount) {
-    delete mCachedEventTearoff[--mCachedEventTearoffCount];
-  }
-}
-
-void
-nsDOMEventRTTearoff::LastRelease()
-{
-  if (mCachedEventTearoffCount < NS_EVENT_TEAROFF_CACHE_SIZE) {
-    // There's still space in the cache for one more instance, put
-    // this instance in the cache in stead of deleting it.
-    mCachedEventTearoff[mCachedEventTearoffCount++] = this;
-
-    // Don't set mContent to null directly since setting mContent to null
-    // could result in code that grabs a tearoff from the cache and we don't
-    // want to get reused while still being torn down.
-    // See bug 330526.
-    nsCOMPtr<nsIContent> kungFuDeathGrip;
-    kungFuDeathGrip.swap(mContent);
-
-    // The refcount balancing and destructor re-entrancy protection
-    // code in Release() sets mRefCnt to 1 so we have to set it to 0
-    // here to prevent leaks
-    mRefCnt = 0;
-
-    return;
-  }
-
-  delete this;
-}
 
 nsresult
 nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
@@ -4100,8 +4027,7 @@ nsGenericElement::List(FILE* out, PRInt3
 
   ListAttributes(out);
 
-  fprintf(out, " intrinsicstate=[%08x]", IntrinsicState());
-  fprintf(out, " refcount=%d<", mRefCnt.get());
+  fprintf(out, " intrinsicstate=[%08x]<", IntrinsicState());
 
   PRUint32 i, length = GetChildCount();
   if (length > 0) {
diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -206,7 +206,8 @@ private:
  * @see nsDOMEventRTTearoff::Create
  */
 
-class nsDOMEventRTTearoff : public nsIDOMEventTarget,
+class nsDOMEventRTTearoff : public XPCOMGCObject,
+                            public nsIDOMEventTarget,
                             public nsIDOM3EventTarget,
                             public nsIDOMNSEventTarget
 {
@@ -217,33 +218,19 @@ private:
   // nsDOMEventRTTearoff::Create(). That's why the constructor and
   // destrucor of this class is private.
 
-  nsDOMEventRTTearoff(nsIContent *aContent);
-
-  static nsDOMEventRTTearoff *mCachedEventTearoff[NS_EVENT_TEAROFF_CACHE_SIZE];
-  static PRUint32 mCachedEventTearoffCount;
-
-  /**
-   * This method gets called by Release() when it's time to delete the
-   * this object, in stead of always deleting the object we'll put the
-   * object in the cache if unless the cache is already full.
-   */
-  void LastRelease();
+  nsDOMEventRTTearoff(nsIContent *aContent) : mContent(aContent) { }
 
   nsresult GetDOM3EventTarget(nsIDOM3EventTarget **aTarget);
 
 public:
-  virtual ~nsDOMEventRTTearoff();
-
   /**
    * Use this static method to create instances of nsDOMEventRTTearoff.
    * @param aContent the content to create a tearoff for
    */
-  static nsDOMEventRTTearoff *Create(nsIContent *aContent);
-
-  /**
-   * Call before shutdown to clear the cache and free memory for this class.
-   */
-  static void Shutdown();
+  static nsDOMEventRTTearoff *Create(nsIContent *aContent)
+  {
+    return new nsDOMEventRTTearoff(aContent);
+  }
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
diff --git a/content/base/src/nsNodeInfo.cpp b/content/base/src/nsNodeInfo.cpp
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -55,39 +55,6 @@
 #include NEW_H
 #include "nsFixedSizeAllocator.h"
 
-static const size_t kNodeInfoPoolSizes[] = {
-  sizeof(nsNodeInfo)
-};
-
-static const PRInt32 kNodeInfoPoolInitialSize = 
-  (NS_SIZE_IN_HEAP(sizeof(nsNodeInfo))) * 64;
-
-// static
-nsFixedSizeAllocator* nsNodeInfo::sNodeInfoPool = nsnull;
-
-// static
-nsNodeInfo*
-nsNodeInfo::Create()
-{
-  if (!sNodeInfoPool) {
-    sNodeInfoPool = new nsFixedSizeAllocator();
-    if (!sNodeInfoPool)
-      return nsnull;
-
-    nsresult rv = sNodeInfoPool->Init("NodeInfo Pool", kNodeInfoPoolSizes,
-                                      1, kNodeInfoPoolInitialSize);
-    if (NS_FAILED(rv)) {
-      delete sNodeInfoPool;
-      sNodeInfoPool = nsnull;
-      return nsnull;
-    }
-  }
-
-  // Create a new one
-  void* place = sNodeInfoPool->Alloc(sizeof(nsNodeInfo));
-  return place ? new (place) nsNodeInfo() : nsnull;
-}
-
 nsNodeInfo::nsNodeInfo()
 {
 }
@@ -130,19 +97,8 @@ nsNodeInfo::Init(nsIAtom *aName, nsIAtom
 
 // nsISupports
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfo)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfo)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfo)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mOwnerManager,
-                                                  nsNodeInfoManager)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeInfo)
-NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
-NS_INTERFACE_TABLE_HEAD(nsNodeInfo)
-  NS_INTERFACE_TABLE1(nsNodeInfo, nsINodeInfo)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsNodeInfo)
-NS_INTERFACE_MAP_END
+NS_IMPL_ADDREF(nsNodeInfo)
+NS_IMPL_QUERY_INTERFACE1(nsNodeInfo, nsINodeInfo)
 
 // nsINodeInfo
 
@@ -287,27 +243,3 @@ nsNodeInfo::QualifiedNameEqualsInternal(
   // end of aQualifiedName
   return mInner.mName->EqualsUTF8(Substring(colon, end));
 }
-
-// static
-void
-nsNodeInfo::ClearCache()
-{
-  // Clear our cache.
-  delete sNodeInfoPool;
-  sNodeInfoPool = nsnull;
-}
-
-void
-nsNodeInfo::LastRelease()
-{
-  nsRefPtr<nsNodeInfoManager> kungFuDeathGrip = mOwnerManager;
-  this->~nsNodeInfo();
-
-  // The refcount balancing and destructor re-entrancy protection
-  // code in Release() sets mRefCnt to 1 so we have to set it to 0
-  // here to prevent leaks
-  mRefCnt = 0;
-
-  NS_ASSERTION(sNodeInfoPool, "No NodeInfoPool when deleting NodeInfo!!!");
-  sNodeInfoPool->Free(this, sizeof(nsNodeInfo));
-}
diff --git a/content/base/src/nsNodeInfo.h b/content/base/src/nsNodeInfo.h
--- a/content/base/src/nsNodeInfo.h
+++ b/content/base/src/nsNodeInfo.h
@@ -52,7 +52,7 @@
 
 class nsFixedSizeAllocator;
 
-class nsNodeInfo : public nsINodeInfo
+class nsNodeInfo : public XPCOMGCFinalizedObject, public nsINodeInfo
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -75,7 +75,9 @@ public:
   // nsNodeInfo
   // Create objects with Create
 public:
-  static nsNodeInfo *Create();
+  static nsNodeInfo *Create() {
+    return new nsNodeInfo();
+  }
 private:
   nsNodeInfo();
 protected:
@@ -91,21 +93,6 @@ public:
    */
   nsresult Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
                 nsNodeInfoManager *aOwnerManager);
-
-  /**
-   * Call before shutdown to clear the cache and free memory for this class.
-   */
-  static void ClearCache();
-
-private:
-  static nsFixedSizeAllocator* sNodeInfoPool;
-
-  /**
-   * This method gets called by Release() when it's time to delete 
-   * this object, instead of always deleting the object we'll put the
-   * object in the cache unless the cache is already full.
-   */
-   void LastRelease();
 };
 
 #endif /* nsNodeInfo_h___ */
diff --git a/content/base/src/nsNodeInfoManager.cpp b/content/base/src/nsNodeInfoManager.cpp
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -54,16 +54,6 @@
 #include "nsLayoutStatics.h"
 #include "nsBindingManager.h"
 
-#ifdef MOZ_LOGGING
-// so we can get logging even in release builds
-#define FORCE_PR_LOG 1
-#endif
-#include "prlog.h"
-
-#ifdef PR_LOGGING
-static PRLogModuleInfo* gNodeInfoManagerLeakPRLog;
-#endif
-
 PLHashNumber
 nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key)
 {
@@ -135,33 +125,6 @@ nsNodeInfoManager::~nsNodeInfoManager()
 #endif
 
   nsLayoutStatics::Release();
-}
-
-
-nsrefcnt
-nsNodeInfoManager::AddRef()
-{
-  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
-
-  nsrefcnt count = PR_AtomicIncrement((PRInt32*)&mRefCnt);
-  NS_LOG_ADDREF(this, count, "nsNodeInfoManager", sizeof(*this));
-
-  return count;
-}
-
-nsrefcnt
-nsNodeInfoManager::Release()
-{
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-
-  nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mRefCnt);
-  NS_LOG_RELEASE(this, count, "nsNodeInfoManager");
-  if (count == 0) {
-    mRefCnt = 1; /* stabilize */
-    delete this;
-  }
-
-  return count;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager)
diff --git a/content/base/src/nsNodeInfoManager.h b/content/base/src/nsNodeInfoManager.h
--- a/content/base/src/nsNodeInfoManager.h
+++ b/content/base/src/nsNodeInfoManager.h
@@ -60,16 +60,12 @@ class nsXULPrototypeDocument;
 class nsXULPrototypeDocument;
 class nsBindingManager;
 
-class nsNodeInfoManager
+class nsNodeInfoManager : public XPCOMGCFinalizedObject
+                        , public MMgc::GCFinalizable
 {
 public:
   nsNodeInfoManager();
   ~nsNodeInfoManager();
-
-  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager)
-
-  nsrefcnt AddRef(void);
-  nsrefcnt Release(void);
 
   /**
    * Initialize the nodeinfo manager with a document.
@@ -155,7 +151,6 @@ private:
                                                     const void *key2);
   static PLHashNumber PR_CALLBACK GetNodeInfoInnerHashValue(const void *key);
 
-  nsAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 
   PLHashTable *mNodeInfoHash;
diff --git a/content/base/src/nsTextNode.cpp b/content/base/src/nsTextNode.cpp
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -238,8 +238,7 @@ nsTextNode::List(FILE* out, PRInt32 aInd
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
   fprintf(out, "Text@%p", this);
-  fprintf(out, " intrinsicstate=[%08x]", IntrinsicState());
-  fprintf(out, " refcount=%d<", mRefCnt.get());
+  fprintf(out, " intrinsicstate=[%08x]<", IntrinsicState());
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -493,8 +493,6 @@ nsEventDispatcher::Dispatch(nsISupports*
   if (!externalDOMEvent && preVisitor.mDOMEvent) {
     // An nsDOMEvent was created while dispatching the event.
     // Duplicate private data if someone holds a pointer to it.
-    nsrefcnt rc = 0;
-    NS_RELEASE2(preVisitor.mDOMEvent, rc);
     nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
       do_QueryInterface(preVisitor.mDOMEvent);
     if (privateEvent) {
diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -77,9 +77,6 @@ public:
   virtual nsresult Init();
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
-
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
 
   virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
   virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
diff --git a/content/svg/content/src/nsSVGTSpanElement.cpp b/content/svg/content/src/nsSVGTSpanElement.cpp
--- a/content/svg/content/src/nsSVGTSpanElement.cpp
+++ b/content/svg/content/src/nsSVGTSpanElement.cpp
@@ -49,9 +49,10 @@
 
 typedef nsSVGStylableElement nsSVGTSpanElementBase;
 
-class nsSVGTSpanElement : public nsSVGTSpanElementBase,
-                          public nsIDOMSVGTSpanElement // : nsIDOMSVGTextPositioningElement
-                                                       // : nsIDOMSVGTextContentElement
+class nsSVGTSpanElement : public nsSVGTSpanElementBase
+                        , public nsIDOMSVGTSpanElement
+                     // , nsIDOMSVGTextPositioningElement
+                     // , nsIDOMSVGTextContentElement
 {
 protected:
   friend nsresult NS_NewSVGTSpanElement(nsIContent **aResult,
diff --git a/content/svg/content/src/nsSVGTextElement.cpp b/content/svg/content/src/nsSVGTextElement.cpp
--- a/content/svg/content/src/nsSVGTextElement.cpp
+++ b/content/svg/content/src/nsSVGTextElement.cpp
@@ -49,9 +49,10 @@
 
 typedef nsSVGGraphicElement nsSVGTextElementBase;
 
-class nsSVGTextElement : public nsSVGTextElementBase,
-                         public nsIDOMSVGTextElement // : nsIDOMSVGTextPositioningElement
-                                                     // : nsIDOMSVGTextContentElement
+class nsSVGTextElement : public nsSVGTextElementBase
+                       , public nsIDOMSVGTextElement
+                    // , nsIDOMSVGTextPositioningElement
+                    // , nsIDOMSVGTextContentElement
 {
 protected:
   friend nsresult NS_NewSVGTextElement(nsIContent **aResult,
diff --git a/content/xbl/src/nsXBLBinding.h b/content/xbl/src/nsXBLBinding.h
--- a/content/xbl/src/nsXBLBinding.h
+++ b/content/xbl/src/nsXBLBinding.h
@@ -77,25 +77,6 @@ public:
    *    which are queued to fire their constructors.
    */
 
-  nsrefcnt AddRef()
-  {
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "nsXBLBinding", sizeof(nsXBLBinding));
-    return mRefCnt;
-  }
-
-  nsrefcnt Release()
-  {
-    --mRefCnt;
-    NS_LOG_RELEASE(this, mRefCnt, "nsXBLBinding");
-    if (mRefCnt == 0) {
-      mRefCnt = 1;
-      delete this;
-      return 0;
-    }
-    return mRefCnt;
-  }
-
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding)
 
   nsXBLPrototypeBinding* PrototypeBinding() { return mPrototypeBinding; }
@@ -169,7 +150,6 @@ public:
 // MEMBER VARIABLES
 protected:
 
-  nsAutoRefCnt mRefCnt;
   nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
   nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
   nsRefPtr<nsXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
diff --git a/content/xbl/src/nsXBLContentSink.cpp b/content/xbl/src/nsXBLContentSink.cpp
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -891,13 +891,6 @@ nsXBLContentSink::CreateElement(const PR
   AddAttributesToXULPrototype(aAtts, aAttsCount, prototype);
 
   nsresult rv = nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult);
-
-  // XUL prototype elements start with a refcnt of 1 to represent
-  // ownership by the XUL prototype document.  In our case we have no
-  // prototype document, so release that reference.  The Create call
-  // above took a reference.
-  prototype->Release();
-
   return rv;
 #endif
 }
diff --git a/content/xbl/src/nsXBLInsertionPoint.cpp b/content/xbl/src/nsXBLInsertionPoint.cpp
--- a/content/xbl/src/nsXBLInsertionPoint.cpp
+++ b/content/xbl/src/nsXBLInsertionPoint.cpp
@@ -52,20 +52,6 @@ nsXBLInsertionPoint::~nsXBLInsertionPoin
 {
 }
 
-nsrefcnt
-nsXBLInsertionPoint::Release()
-{
-  --mRefCnt;
-  NS_LOG_RELEASE(this, mRefCnt, "nsXBLInsertionPoint");
-  if (mRefCnt == 0) {
-    mRefCnt = 1;
-    delete this;
-    return 0;
-  }
-  return mRefCnt;
-}
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPoint)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate)
diff --git a/content/xbl/src/nsXBLInsertionPoint.h b/content/xbl/src/nsXBLInsertionPoint.h
--- a/content/xbl/src/nsXBLInsertionPoint.h
+++ b/content/xbl/src/nsXBLInsertionPoint.h
@@ -44,21 +44,11 @@
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 
-class nsXBLInsertionPoint
+class nsXBLInsertionPoint : public XPCOMGCFinalizedObject
 {
 public:
   nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIContent* aDefContent);
   ~nsXBLInsertionPoint();
-
-  nsrefcnt AddRef()
-  {
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "nsXBLInsertionPoint",
-                  sizeof(nsXBLInsertionPoint));
-    return mRefCnt;
-  }
-
-  nsrefcnt Release();
 
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPoint)
 
@@ -88,7 +78,6 @@ public:
   void UnbindDefaultContent();
 
 protected:
-  nsAutoRefCnt mRefCnt;
   nsIContent* mParentElement;            // This ref is weak.  The parent of the <children> element.
   PRInt32 mIndex;                        // The index of this insertion point. -1 is a pseudo-point.
   nsCOMArray<nsIContent> mElements;      // An array of elements present at the insertion point.
diff --git a/content/xbl/src/nsXBLPrototypeBinding.cpp b/content/xbl/src/nsXBLPrototypeBinding.cpp
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -137,7 +137,7 @@ private:
 // The same insertion point may be in the insertion point table for multiple
 // keys, so we refcount the entries.
 
-class nsXBLInsertionPointEntry {
+class nsXBLInsertionPointEntry : public XPCOMGCFinalizedObject {
 public:
   ~nsXBLInsertionPointEntry() {
     if (mDefaultContent) {
@@ -158,92 +158,20 @@ public:
   nsIContent* GetDefaultContent() { return mDefaultContent; }
   void SetDefaultContent(nsIContent* aChildren) { mDefaultContent = aChildren; }
 
-
-  // We keep kPool alive as long as there is at least either a
-  // nsXBLPrototypeBinding or a nsXBLInsertionPointEntry alive.
-  // nsXBLPrototypeBinding has its own global refcount so it only adds 1 to
-  // nsXBLInsertionPointEntry::gRefCnt as long as there's at least one
-  // nsXBLPrototypeBinding alive.
-
-  static void InitPool(PRInt32 aInitialSize)
-  {
-    if (++gRefCnt == 1) {
-      kPool = new nsFixedSizeAllocator();
-      if (kPool) {
-        static const size_t kBucketSizes[] = {
-          sizeof(nsXBLInsertionPointEntry)
-        };
-        kPool->Init("XBL Insertion Point Entries", kBucketSizes,
-                    NS_ARRAY_LENGTH(kBucketSizes), aInitialSize);
-      }
-    }
-  }
-  static PRBool PoolInited()
-  {
-    return kPool != nsnull;
-  }
-  static void ReleasePool()
-  {
-    if (--gRefCnt == 0) {
-      delete kPool;
-    }
-  }
-
   static nsXBLInsertionPointEntry*
   Create(nsIContent* aParent) {
-    void* place = kPool->Alloc(sizeof(nsXBLInsertionPointEntry));
-    if (!place) {
-      return nsnull;
-    }
-    ++gRefCnt;
-    return ::new (place) nsXBLInsertionPointEntry(aParent);
-  }
-
-  static void
-  Destroy(nsXBLInsertionPointEntry* aSelf) {
-    aSelf->~nsXBLInsertionPointEntry();
-    kPool->Free(aSelf, sizeof(*aSelf));
-    nsXBLInsertionPointEntry::ReleasePool();
-  }
-
-  nsrefcnt AddRef() {
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "nsXBLInsertionPointEntry", sizeof(nsXBLInsertionPointEntry));
-    return mRefCnt;
-  }
-
-  nsrefcnt Release() {
-    --mRefCnt;
-    NS_LOG_RELEASE(this, mRefCnt, "nsXBLInsertionPointEntry");
-    if (mRefCnt == 0) {
-      Destroy(this);
-      return 0;
-    }
-    return mRefCnt;
+    return new nsXBLInsertionPointEntry(aParent);
   }
 
 protected:
   nsCOMPtr<nsIContent> mInsertionParent;
   nsCOMPtr<nsIContent> mDefaultContent;
   PRUint32 mInsertionIndex;
-  nsAutoRefCnt mRefCnt;
 
   nsXBLInsertionPointEntry(nsIContent* aParent)
     : mInsertionParent(aParent),
       mInsertionIndex(0) { }
-
-private:
-  // Hide so that only Create() and Destroy() can be used to
-  // allocate and deallocate from the heap
-  static void* operator new(size_t) CPP_THROW_NEW { return 0; }
-  static void operator delete(void*, size_t) {}
-
-  static nsFixedSizeAllocator* kPool;
-  static PRUint32 gRefCnt;
 };
-
-PRUint32 nsXBLInsertionPointEntry::gRefCnt = 0;
-nsFixedSizeAllocator* nsXBLInsertionPointEntry::kPool;
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXBLInsertionPointEntry)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInsertionParent)
@@ -292,7 +220,6 @@ nsXBLPrototypeBinding::nsXBLPrototypeBin
     if (kAttrPool) {
       kAttrPool->Init("XBL Attribute Entries", kAttrBucketSizes, kAttrNumBuckets, kAttrInitialSize);
     }
-    nsXBLInsertionPointEntry::InitPool(kInsInitialSize);
   }
 }
 
@@ -301,7 +228,7 @@ nsXBLPrototypeBinding::Init(const nsACSt
                             nsIXBLDocumentInfo* aInfo,
                             nsIContent* aElement)
 {
-  if (!kAttrPool || !nsXBLInsertionPointEntry::PoolInited()) {
+  if (!kAttrPool) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -343,7 +270,6 @@ nsXBLPrototypeBinding::~nsXBLPrototypeBi
   gRefCnt--;
   if (gRefCnt == 0) {
     delete kAttrPool;
-    nsXBLInsertionPointEntry::ReleasePool();
   }
   MOZ_COUNT_DTOR(nsXBLPrototypeBinding);
 }
@@ -1143,13 +1069,6 @@ nsXBLPrototypeBinding::ConstructAttribut
   }
 }
 
-static PRBool PR_CALLBACK
-DeleteInsertionPointEntry(nsHashKey* aKey, void* aData, void* aClosure)
-{
-  static_cast<nsXBLInsertionPointEntry*>(aData)->Release();
-  return PR_TRUE;
-}
-
 void 
 nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
 {
@@ -1162,7 +1081,7 @@ nsXBLPrototypeBinding::ConstructInsertio
     return;
 
   mInsertionPointTable = new nsObjectHashtable(nsnull, nsnull,
-                                               DeleteInsertionPointEntry,
+                                               nsnull,
                                                nsnull, 4);
   if (!mInsertionPointTable)
     return;
@@ -1179,7 +1098,6 @@ nsXBLPrototypeBinding::ConstructInsertio
     child->GetAttr(kNameSpaceID_None, nsGkAtoms::includes, includes);
     if (includes.IsEmpty()) {
       nsISupportsKey key(nsGkAtoms::children);
-      xblIns->AddRef();
       mInsertionPointTable->Put(&key, xblIns);
     }
     else {
@@ -1198,7 +1116,6 @@ nsXBLPrototypeBinding::ConstructInsertio
         nsCOMPtr<nsIAtom> atom = do_GetAtom(tok);
            
         nsISupportsKey key(atom);
-        xblIns->AddRef();
         mInsertionPointTable->Put(&key, xblIns);
           
         token = nsCRT::strtok( newStr, "| ", &newStr );
diff --git a/content/xml/content/src/nsXMLCDATASection.cpp b/content/xml/content/src/nsXMLCDATASection.cpp
--- a/content/xml/content/src/nsXMLCDATASection.cpp
+++ b/content/xml/content/src/nsXMLCDATASection.cpp
@@ -171,7 +171,7 @@ nsXMLCDATASection::List(FILE* out, PRInt
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
-  fprintf(out, "CDATASection refcount=%d<", mRefCnt.get());
+  fprintf(out, "CDATASection<");
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
diff --git a/content/xml/content/src/nsXMLProcessingInstruction.cpp b/content/xml/content/src/nsXMLProcessingInstruction.cpp
--- a/content/xml/content/src/nsXMLProcessingInstruction.cpp
+++ b/content/xml/content/src/nsXMLProcessingInstruction.cpp
@@ -188,7 +188,7 @@ nsXMLProcessingInstruction::List(FILE* o
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
-  fprintf(out, "Processing instruction refcount=%d<", mRefCnt.get());
+  fprintf(out, "Processing instruction <");
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
diff --git a/content/xslt/src/base/txNamespaceMap.cpp b/content/xslt/src/base/txNamespaceMap.cpp
--- a/content/xslt/src/base/txNamespaceMap.cpp
+++ b/content/xslt/src/base/txNamespaceMap.cpp
@@ -46,8 +46,8 @@ txNamespaceMap::txNamespaceMap()
 
 txNamespaceMap::txNamespaceMap(const txNamespaceMap& aOther)
     : mPrefixes(aOther.mPrefixes)
+    , mNamespaces(aOther.mNamespaces)
 {
-    mNamespaces = aOther.mNamespaces; //bah! I want a copy-constructor!
 }
 
 nsresult
@@ -79,7 +79,7 @@ txNamespaceMap::mapNamespace(nsIAtom* aP
     // Check if the mapping already exists
     PRInt32 index = mPrefixes.IndexOf(prefix);
     if (index >= 0) {
-        mNamespaces.ReplaceElementAt(NS_INT32_TO_PTR(nsId), index);
+        mNamespaces[index] = nsId;
 
         return NS_OK;
     }
@@ -89,7 +89,7 @@ txNamespaceMap::mapNamespace(nsIAtom* aP
         return NS_ERROR_OUT_OF_MEMORY;
     }
     
-    if (!mNamespaces.AppendElement(NS_INT32_TO_PTR(nsId))) {
+    if (!mNamespaces.AppendElement(nsId)) {
         mPrefixes.RemoveObjectAt(mPrefixes.Count() - 1);
 
         return NS_ERROR_OUT_OF_MEMORY;
@@ -109,7 +109,7 @@ txNamespaceMap::lookupNamespace(nsIAtom*
 
     PRInt32 index = mPrefixes.IndexOf(prefix);
     if (index >= 0) {
-        return NS_PTR_TO_INT32(mNamespaces.SafeElementAt(index));
+        return mNamespaces[index];
     }
 
     if (!prefix) {
diff --git a/content/xslt/src/base/txNamespaceMap.h b/content/xslt/src/base/txNamespaceMap.h
--- a/content/xslt/src/base/txNamespaceMap.h
+++ b/content/xslt/src/base/txNamespaceMap.h
@@ -41,26 +41,13 @@
 
 #include "nsIAtom.h"
 #include "nsCOMArray.h"
+#include "nsTArray.h"
 
-class txNamespaceMap
+class txNamespaceMap : public XPCOMGCObject
 {
 public:
     txNamespaceMap();
     txNamespaceMap(const txNamespaceMap& aOther);
-
-    nsrefcnt AddRef()
-    {
-        return ++mRefCnt;
-    }
-    nsrefcnt Release()
-    {
-        if (--mRefCnt == 0) {
-            mRefCnt = 1; //stabilize
-            delete this;
-            return 0;
-        }
-        return mRefCnt;
-    }
 
     nsresult mapNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI);
     PRInt32 lookupNamespace(nsIAtom* aPrefix);
@@ -68,9 +55,8 @@ public:
     PRInt32 lookupNamespaceWithDefault(const nsAString& aPrefix);
 
 private:
-    nsAutoRefCnt mRefCnt;
     nsCOMArray<nsIAtom> mPrefixes;
-    nsVoidArray mNamespaces;
+    nsTArray<PRInt32> mNamespaces;
 };
 
 #endif //TRANSFRMX_TXNAMESPACEMAP_H
diff --git a/content/xslt/src/xpath/nsXPathResult.cpp b/content/xslt/src/xpath/nsXPathResult.cpp
--- a/content/xslt/src/xpath/nsXPathResult.cpp
+++ b/content/xslt/src/xpath/nsXPathResult.cpp
@@ -389,7 +389,7 @@ nsXPathResult::GetExprResult(txAExprResu
         return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
 
-    nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
+    txNodeSet* nodeSet = new txNodeSet();
     if (!nodeSet) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
diff --git a/content/xslt/src/xpath/txBooleanExpr.cpp b/content/xslt/src/xpath/txBooleanExpr.cpp
--- a/content/xslt/src/xpath/txBooleanExpr.cpp
+++ b/content/xslt/src/xpath/txBooleanExpr.cpp
@@ -44,6 +44,7 @@
 
 #include "txExpr.h"
 #include "txIXPathContext.h"
+#include "txResultRecycler.h"
 
 /**
  * Evaluates this Expr based on the given context node and processor state
diff --git a/content/xslt/src/xpath/txBooleanResult.cpp b/content/xslt/src/xpath/txBooleanResult.cpp
--- a/content/xslt/src/xpath/txBooleanResult.cpp
+++ b/content/xslt/src/xpath/txBooleanResult.cpp
@@ -47,7 +47,6 @@
  * @param boolean the MBool to use for initialization of this BooleanResult's value
 **/
 BooleanResult::BooleanResult(PRBool boolean)
-    : txAExprResult(nsnull)
 {
     this->value = boolean;
 } //-- BooleanResult
diff --git a/content/xslt/src/xpath/txCoreFunctionCall.cpp b/content/xslt/src/xpath/txCoreFunctionCall.cpp
--- a/content/xslt/src/xpath/txCoreFunctionCall.cpp
+++ b/content/xslt/src/xpath/txCoreFunctionCall.cpp
@@ -46,6 +46,7 @@
 #include <math.h>
 #include "txStringUtils.h"
 #include "txXMLUtils.h"
+#include "txResultRecycler.h"
 
 struct txCoreFunctionDescriptor
 {
diff --git a/content/xslt/src/xpath/txExpr.h b/content/xslt/src/xpath/txExpr.h
--- a/content/xslt/src/xpath/txExpr.h
+++ b/content/xslt/src/xpath/txExpr.h
@@ -699,11 +699,11 @@ class txLiteralExpr : public Expr {
 class txLiteralExpr : public Expr {
 public:
     txLiteralExpr(double aDbl)
-        : mValue(new NumberResult(aDbl, nsnull))
+        : mValue(new NumberResult(aDbl))
     {
     }
     txLiteralExpr(const nsAString& aStr)
-        : mValue(new StringResult(aStr, nsnull))
+        : mValue(new StringResult(aStr))
     {
     }
     txLiteralExpr(txAExprResult* aValue)
diff --git a/content/xslt/src/xpath/txExprResult.h b/content/xslt/src/xpath/txExprResult.h
--- a/content/xslt/src/xpath/txExprResult.h
+++ b/content/xslt/src/xpath/txExprResult.h
@@ -54,11 +54,9 @@
  * Note: for NodeSet, see NodeSet.h
 */
 
-class txAExprResult
+class txAExprResult : public XPCOMGCFinalizedObject
 {
 public:
-    friend class txResultRecycler;
-
     // Update txLiteralExpr::getReturnType and sTypes in txEXSLTFunctions.cpp if
     // this enum is changed.
     enum ResultType {
@@ -69,20 +67,12 @@ public:
         RESULT_TREE_FRAGMENT
     };
 
-    txAExprResult(txResultRecycler* aRecycler) : mRecycler(aRecycler)
+    txAExprResult()
     {
     }
     virtual ~txAExprResult()
     {
     }
-
-    void AddRef()
-    {
-        ++mRefCnt;
-        NS_LOG_ADDREF(this, mRefCnt, "txAExprResult", sizeof(*this));
-    }
-    
-    void Release(); // Implemented in txResultRecycler.cpp
 
     /**
      * Returns the type of ExprResult represented
@@ -114,10 +104,6 @@ public:
      * @return the Number value
     **/
     virtual double numberValue()          = 0;
-
-private:
-    nsAutoRefCnt mRefCnt;
-    nsRefPtr<txResultRecycler> mRecycler;
 };
 
 #define TX_DECL_EXPRRESULT                                        \
@@ -142,7 +128,7 @@ class NumberResult : public txAExprResul
 class NumberResult : public txAExprResult {
 
 public:
-    NumberResult(double aValue, txResultRecycler* aRecycler);
+    NumberResult(double aValue);
 
     TX_DECL_EXPRRESULT
 
@@ -153,8 +139,8 @@ public:
 
 class StringResult : public txAExprResult {
 public:
-    StringResult(txResultRecycler* aRecycler);
-    StringResult(const nsAString& aValue, txResultRecycler* aRecycler);
+    StringResult();
+    StringResult(const nsAString& aValue);
 
     TX_DECL_EXPRRESULT
 
diff --git a/content/xslt/src/xpath/txNodeSet.cpp b/content/xslt/src/xpath/txNodeSet.cpp
--- a/content/xslt/src/xpath/txNodeSet.cpp
+++ b/content/xslt/src/xpath/txNodeSet.cpp
@@ -69,9 +69,8 @@ static const PRInt32 kTxNodeSetGrowFacto
 #define kForward   1
 #define kReversed -1
 
-txNodeSet::txNodeSet(txResultRecycler* aRecycler)
-    : txAExprResult(aRecycler),
-      mStart(nsnull),
+txNodeSet::txNodeSet()
+    : mStart(nsnull),
       mEnd(nsnull),
       mStartBuffer(nsnull),
       mEndBuffer(nsnull),
@@ -80,9 +79,8 @@ txNodeSet::txNodeSet(txResultRecycler* a
 {
 }
 
-txNodeSet::txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler)
-    : txAExprResult(aRecycler),
-      mStart(nsnull),
+txNodeSet::txNodeSet(const txXPathNode& aNode)
+    : mStart(nsnull),
       mEnd(nsnull),
       mStartBuffer(nsnull),
       mEndBuffer(nsnull),
@@ -97,9 +95,8 @@ txNodeSet::txNodeSet(const txXPathNode& 
     ++mEnd;
 }
 
-txNodeSet::txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler)
-    : txAExprResult(aRecycler),
-      mStart(nsnull),
+txNodeSet::txNodeSet(const txNodeSet& aSource)
+    : mStart(nsnull),
       mEnd(nsnull),
       mStartBuffer(nsnull),
       mEndBuffer(nsnull),
diff --git a/content/xslt/src/xpath/txNodeSet.h b/content/xslt/src/xpath/txNodeSet.h
--- a/content/xslt/src/xpath/txNodeSet.h
+++ b/content/xslt/src/xpath/txNodeSet.h
@@ -54,18 +54,18 @@ public:
     /**
      * Creates a new empty NodeSet
      */
-    txNodeSet(txResultRecycler* aRecycler);
+    txNodeSet();
 
     /**
      * Creates a new NodeSet with one node.
      */
-    txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler);
+    txNodeSet(const txXPathNode& aNode);
 
     /**
      * Creates a new txNodeSet, copying the node references from the source
      * NodeSet.
      */
-    txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler);
+    txNodeSet(const txNodeSet& aSource);
 
     /**
      * Destructor for txNodeSet, deletes the nodes.
diff --git a/content/xslt/src/xpath/txNodeSetAdaptor.cpp b/content/xslt/src/xpath/txNodeSetAdaptor.cpp
--- a/content/xslt/src/xpath/txNodeSetAdaptor.cpp
+++ b/content/xslt/src/xpath/txNodeSetAdaptor.cpp
@@ -59,7 +59,7 @@ txNodeSetAdaptor::Init()
 txNodeSetAdaptor::Init()
 {
     if (!mNodeSet) {
-        mNodeSet = new txNodeSet(nsnull);
+        mNodeSet = new txNodeSet();
     }
 
     return mNodeSet ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
diff --git a/content/xslt/src/xpath/txNumberResult.cpp b/content/xslt/src/xpath/txNumberResult.cpp
--- a/content/xslt/src/xpath/txNumberResult.cpp
+++ b/content/xslt/src/xpath/txNumberResult.cpp
@@ -51,8 +51,8 @@
  * Creates a new NumberResult with the value of the given double parameter
  * @param dbl the double to use for initialization of this NumberResult's value
 **/
-NumberResult::NumberResult(double aValue, txResultRecycler* aRecycler)
-    : txAExprResult(aRecycler), value(aValue)
+NumberResult::NumberResult(double aValue)
+    : value(aValue)
 {
 } //-- NumberResult
 
diff --git a/content/xslt/src/xpath/txRelationalExpr.cpp b/content/xslt/src/xpath/txRelationalExpr.cpp
--- a/content/xslt/src/xpath/txRelationalExpr.cpp
+++ b/content/xslt/src/xpath/txRelationalExpr.cpp
@@ -41,6 +41,7 @@
 #include "txNodeSet.h"
 #include "txIXPathContext.h"
 #include "txXPathTreeWalker.h"
+#include "txResultRecycler.h"
 
 /**
  *  Compares the two ExprResults based on XPath 1.0 Recommendation (section 3.4)
diff --git a/content/xslt/src/xpath/txResultRecycler.cpp b/content/xslt/src/xpath/txResultRecycler.cpp
--- a/content/xslt/src/xpath/txResultRecycler.cpp
+++ b/content/xslt/src/xpath/txResultRecycler.cpp
@@ -47,257 +47,87 @@ txResultRecycler::txResultRecycler()
 {
 }
 
-txResultRecycler::~txResultRecycler()
-{
-    txStackIterator stringIter(&mStringResults);
-    while (stringIter.hasNext()) {
-        delete static_cast<StringResult*>(stringIter.next());
-    }
-    txStackIterator nodesetIter(&mNodeSetResults);
-    while (nodesetIter.hasNext()) {
-        delete static_cast<txNodeSet*>(nodesetIter.next());
-    }
-    txStackIterator numberIter(&mNumberResults);
-    while (numberIter.hasNext()) {
-        delete static_cast<NumberResult*>(numberIter.next());
-    }
-
-    NS_IF_RELEASE(mEmptyStringResult);
-    NS_IF_RELEASE(mTrueResult);
-    NS_IF_RELEASE(mFalseResult);
-}
-
-
 nsresult
 txResultRecycler::init()
 {
     NS_ASSERTION(!mEmptyStringResult && !mTrueResult && !mFalseResult,
                  "Already inited");
-    mEmptyStringResult = new StringResult(nsnull);
+    mEmptyStringResult = new StringResult();
     NS_ENSURE_TRUE(mEmptyStringResult, NS_ERROR_OUT_OF_MEMORY);
-
-    NS_ADDREF(mEmptyStringResult);
 
     mTrueResult = new BooleanResult(PR_TRUE);
     NS_ENSURE_TRUE(mTrueResult, NS_ERROR_OUT_OF_MEMORY);
 
-    NS_ADDREF(mTrueResult);
-
     mFalseResult = new BooleanResult(PR_FALSE);
     NS_ENSURE_TRUE(mFalseResult, NS_ERROR_OUT_OF_MEMORY);
 
-    NS_ADDREF(mFalseResult);
-
     return NS_OK;
-}
-
-
-void
-txResultRecycler::recycle(txAExprResult* aResult)
-{
-    NS_ASSERTION(aResult->mRefCnt == 0, "In-use txAExprResult recycled");
-    nsRefPtr<txResultRecycler> kungFuDeathGrip;
-    aResult->mRecycler.swap(kungFuDeathGrip);
-
-    nsresult rv = NS_OK;
-    switch (aResult->getResultType()) {
-        case txAExprResult::STRING:
-        {
-            rv = mStringResults.push(static_cast<StringResult*>(aResult));
-            if (NS_FAILED(rv)) {
-                delete aResult;
-            }
-            return;
-        }
-        case txAExprResult::NODESET:
-        {
-            rv = mNodeSetResults.push(static_cast<txNodeSet*>(aResult));
-            if (NS_FAILED(rv)) {
-                delete aResult;
-            }
-            return;
-        }
-        case txAExprResult::NUMBER:
-        {
-            rv = mNumberResults.push(static_cast<NumberResult*>(aResult));
-            if (NS_FAILED(rv)) {
-                delete aResult;
-            }
-            return;
-        }
-        default:
-        {
-            delete aResult;
-        }
-    }
 }
 
 nsresult
 txResultRecycler::getStringResult(StringResult** aResult)
 {
-    if (mStringResults.isEmpty()) {
-        *aResult = new StringResult(this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        *aResult = static_cast<StringResult*>(mStringResults.pop());
-        (*aResult)->mValue.Truncate();
-        (*aResult)->mRecycler = this;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new StringResult();
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 nsresult
 txResultRecycler::getStringResult(const nsAString& aValue,
                                   txAExprResult** aResult)
 {
-    if (mStringResults.isEmpty()) {
-        *aResult = new StringResult(aValue, this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        StringResult* strRes =
-            static_cast<StringResult*>(mStringResults.pop());
-        strRes->mValue = aValue;
-        strRes->mRecycler = this;
-        *aResult = strRes;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new StringResult(aValue);
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 void
 txResultRecycler::getEmptyStringResult(txAExprResult** aResult)
 {
     *aResult = mEmptyStringResult;
-    NS_ADDREF(*aResult);
 }
 
 nsresult
 txResultRecycler::getNodeSet(txNodeSet** aResult)
 {
-    if (mNodeSetResults.isEmpty()) {
-        *aResult = new txNodeSet(this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
-        (*aResult)->clear();
-        (*aResult)->mRecycler = this;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new txNodeSet();
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 nsresult
 txResultRecycler::getNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult)
 {
-    if (mNodeSetResults.isEmpty()) {
-        *aResult = new txNodeSet(*aNodeSet, this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
-        (*aResult)->clear();
-        (*aResult)->append(*aNodeSet);
-        (*aResult)->mRecycler = this;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new txNodeSet(*aNodeSet);
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 nsresult
 txResultRecycler::getNodeSet(const txXPathNode& aNode, txAExprResult** aResult)
 {
-    if (mNodeSetResults.isEmpty()) {
-        *aResult = new txNodeSet(aNode, this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        txNodeSet* nodes = static_cast<txNodeSet*>(mNodeSetResults.pop());
-        nodes->clear();
-        nodes->append(aNode);
-        nodes->mRecycler = this;
-        *aResult = nodes;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new txNodeSet(aNode);
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 nsresult
 txResultRecycler::getNodeSet(const txXPathNode& aNode, txNodeSet** aResult)
 {
-    if (mNodeSetResults.isEmpty()) {
-        *aResult = new txNodeSet(aNode, this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
-        (*aResult)->clear();
-        (*aResult)->append(aNode);
-        (*aResult)->mRecycler = this;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new txNodeSet(aNode);
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 nsresult
 txResultRecycler::getNumberResult(double aValue, txAExprResult** aResult)
 {
-    if (mNumberResults.isEmpty()) {
-        *aResult = new NumberResult(aValue, this);
-        NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
-    }
-    else {
-        NumberResult* numRes =
-            static_cast<NumberResult*>(mNumberResults.pop());
-        numRes->value = aValue;
-        numRes->mRecycler = this;
-        *aResult = numRes;
-    }
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    *aResult = new NumberResult(aValue);
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 void
 txResultRecycler::getBoolResult(PRBool aValue, txAExprResult** aResult)
 {
     *aResult = aValue ? mTrueResult : mFalseResult;
-    NS_ADDREF(*aResult);
 }
 
 nsresult
 txResultRecycler::getNonSharedNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult)
 {
-    if (aNodeSet->mRefCnt > 1) {
-        return getNodeSet(aNodeSet, aResult);
-    }
-
-    *aResult = aNodeSet;
-    NS_ADDREF(*aResult);
-
-    return NS_OK;
+    return getNodeSet(aNodeSet, aResult);
 }
-
-void
-txAExprResult::Release()
-{
-    --mRefCnt;
-    NS_LOG_RELEASE(this, mRefCnt, "txAExprResult");
-    if (mRefCnt == 0) {
-        if (mRecycler) {
-            mRecycler->recycle(this);
-        }
-        else {
-            delete this;
-        }
-    }
-}
diff --git a/content/xslt/src/xpath/txResultRecycler.h b/content/xslt/src/xpath/txResultRecycler.h
--- a/content/xslt/src/xpath/txResultRecycler.h
+++ b/content/xslt/src/xpath/txResultRecycler.h
@@ -49,33 +49,12 @@ class NumberResult;
 class NumberResult;
 class BooleanResult;
 
-class txResultRecycler
+class txResultRecycler : public XPCOMGCObject
 {
 public:
     txResultRecycler();
-    ~txResultRecycler();
+    ~txResultRecycler() { }
     nsresult init();
-
-    void AddRef()
-    {
-        ++mRefCnt;
-        NS_LOG_ADDREF(this, mRefCnt, "txResultRecycler", sizeof(*this));
-    }
-    void Release()
-    {
-        --mRefCnt;
-        NS_LOG_RELEASE(this, mRefCnt, "txResultRecycler");
-        if (mRefCnt == 0) {
-            mRefCnt = 1; //stabilize
-            delete this;
-        }
-    }
-
-    /**
-     * Returns an txAExprResult to this recycler for reuse.
-     * @param aResult  result to recycle
-     */
-    void recycle(txAExprResult* aResult);
 
     /**
      * Functions to return results that will be fully used by the caller.
@@ -102,10 +81,6 @@ public:
     nsresult getNonSharedNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult);
 
 private:
-    nsAutoRefCnt mRefCnt;
-    txStack mStringResults;
-    txStack mNodeSetResults;
-    txStack mNumberResults;
     StringResult* mEmptyStringResult;
     BooleanResult* mTrueResult;
     BooleanResult* mFalseResult;
diff --git a/content/xslt/src/xpath/txStringResult.cpp b/content/xslt/src/xpath/txStringResult.cpp
--- a/content/xslt/src/xpath/txStringResult.cpp
+++ b/content/xslt/src/xpath/txStringResult.cpp
@@ -45,8 +45,7 @@
 /**
  * Default Constructor
 **/
-StringResult::StringResult(txResultRecycler* aRecycler)
-    : txAExprResult(aRecycler)
+StringResult::StringResult()
 {
 }
 
@@ -54,8 +53,8 @@ StringResult::StringResult(txResultRecyc
  * Creates a new StringResult with the value of the given String parameter
  * @param str the String to use for initialization of this StringResult's value
 **/
-StringResult::StringResult(const nsAString& aValue, txResultRecycler* aRecycler)
-    : txAExprResult(aRecycler), mValue(aValue)
+StringResult::StringResult(const nsAString& aValue)
+    : mValue(aValue)
 {
 }
 
diff --git a/content/xslt/src/xslt/txExecutionState.cpp b/content/xslt/src/xslt/txExecutionState.cpp
--- a/content/xslt/src/xslt/txExecutionState.cpp
+++ b/content/xslt/src/xslt/txExecutionState.cpp
@@ -183,7 +183,7 @@ txExecutionState::init(const txXPathNode
     
     // The actual value here doesn't really matter since noone should use this
     // value. But lets put something errorlike in just in case
-    mGlobalVarPlaceholderValue = new StringResult(NS_LITERAL_STRING("Error"), nsnull);
+    mGlobalVarPlaceholderValue = new StringResult(NS_LITERAL_STRING("Error"));
     NS_ENSURE_TRUE(mGlobalVarPlaceholderValue, NS_ERROR_OUT_OF_MEMORY);
 
     // Initiate first instruction. This has to be done last since findTemplate
diff --git a/content/xslt/src/xslt/txKey.h b/content/xslt/src/xslt/txKey.h
--- a/content/xslt/src/xslt/txKey.h
+++ b/content/xslt/src/xslt/txKey.h
@@ -70,7 +70,7 @@ struct txKeyValueHashEntry : public PLDH
 {
     txKeyValueHashEntry(const void* aKey)
         : mKey(*static_cast<const txKeyValueHashKey*>(aKey)),
-          mNodeSet(new txNodeSet(nsnull))
+          mNodeSet(new txNodeSet())
     {
     }
 
diff --git a/content/xslt/src/xslt/txKeyFunctionCall.cpp b/content/xslt/src/xslt/txKeyFunctionCall.cpp
--- a/content/xslt/src/xslt/txKeyFunctionCall.cpp
+++ b/content/xslt/src/xslt/txKeyFunctionCall.cpp
@@ -288,7 +288,7 @@ txKeyHash::init()
     rv = mIndexedKeys.Init(1);
     NS_ENSURE_SUCCESS(rv, rv);
     
-    mEmptyNodeSet = new txNodeSet(nsnull);
+    mEmptyNodeSet = new txNodeSet();
     NS_ENSURE_TRUE(mEmptyNodeSet, NS_ERROR_OUT_OF_MEMORY);
     
     return NS_OK;
diff --git a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
--- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
@@ -435,9 +435,6 @@ public:
     nsresult startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
                        nsIPrincipal* aSourcePrincipal);
 
-protected:
-    nsAutoRefCnt mRefCnt;
-
 private:
     nsRefPtr<txMozillaXSLTProcessor> mProcessor;
     nsCOMPtr<nsILoadGroup> mLoadGroup;
@@ -453,23 +450,6 @@ txCompileObserver::txCompileObserver(txM
     : mProcessor(aProcessor),
       mLoadGroup(aLoadGroup)
 {
-}
-
-nsrefcnt
-txCompileObserver::AddRef()
-{
-    return ++mRefCnt;
-}
-
-nsrefcnt
-txCompileObserver::Release()
-{
-    if (--mRefCnt == 0) {
-        mRefCnt = 1; //stabilize
-        delete this;
-        return 0;
-    }
-    return mRefCnt;
 }
 
 nsresult
@@ -669,29 +649,12 @@ public:
 
 protected:
     nsRefPtr<txMozillaXSLTProcessor> mProcessor;
-    nsAutoRefCnt mRefCnt;
+    nsCOMPtr<nsIPrincipal> mCallerPrincipal;
 };
 
 txSyncCompileObserver::txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor)
   : mProcessor(aProcessor)
 {
-}
-
-nsrefcnt
-txSyncCompileObserver::AddRef()
-{
-    return ++mRefCnt;
-}
-
-nsrefcnt
-txSyncCompileObserver::Release()
-{
-    if (--mRefCnt == 0) {
-        mRefCnt = 1; //stabilize
-        delete this;
-        return 0;
-    }
-    return mRefCnt;
 }
 
 nsresult
diff --git a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
@@ -503,7 +503,7 @@ txMozillaXSLTProcessor::AddXSLTParam(con
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
-        value = new StringResult(aValue, nsnull);
+        value = new StringResult(aValue);
         NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
     }
 
@@ -1319,7 +1319,7 @@ txVariable::Convert(nsIVariant *aValue, 
             nsresult rv = aValue->GetAsDouble(&value);
             NS_ENSURE_SUCCESS(rv, rv);
 
-            *aResult = new NumberResult(value, nsnull);
+            *aResult = new NumberResult(value);
             NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
 
             NS_ADDREF(*aResult);
@@ -1358,7 +1358,7 @@ txVariable::Convert(nsIVariant *aValue, 
             nsresult rv = aValue->GetAsAString(value);
             NS_ENSURE_SUCCESS(rv, rv);
 
-            *aResult = new StringResult(value, nsnull);
+            *aResult = new StringResult(value);
             NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
 
             NS_ADDREF(*aResult);
@@ -1381,7 +1381,7 @@ txVariable::Convert(nsIVariant *aValue, 
                     return NS_ERROR_FAILURE;
                 }
 
-                *aResult = new txNodeSet(*xpathNode, nsnull);
+                *aResult = new txNodeSet(*xpathNode);
                 if (!*aResult) {
                     return NS_ERROR_OUT_OF_MEMORY;
                 }
@@ -1398,7 +1398,7 @@ txVariable::Convert(nsIVariant *aValue, 
 
             nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
             if (nodeList) {
-                nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
+                nsRefPtr<txNodeSet> nodeSet = new txNodeSet();
                 if (!nodeSet) {
                     return NS_ERROR_OUT_OF_MEMORY;
                 }
@@ -1453,7 +1453,7 @@ txVariable::Convert(nsIVariant *aValue, 
                                     (::JS_GetStringChars(str));
                 nsDependentString value(strChars, ::JS_GetStringLength(str));
 
-                *aResult = new StringResult(value, nsnull);
+                *aResult = new StringResult(value);
                 if (!*aResult) {
                     return NS_ERROR_OUT_OF_MEMORY;
                 }
@@ -1481,7 +1481,7 @@ txVariable::Convert(nsIVariant *aValue, 
 
             nsISupports** values = static_cast<nsISupports**>(array);
 
-            nsRefPtr<txNodeSet> nodeSet = new txNodeSet(nsnull);
+            nsRefPtr<txNodeSet> nodeSet = new txNodeSet();
             if (!nodeSet) {
                 NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, values);
 
diff --git a/content/xslt/src/xslt/txRtfHandler.cpp b/content/xslt/src/xslt/txRtfHandler.cpp
--- a/content/xslt/src/xslt/txRtfHandler.cpp
+++ b/content/xslt/src/xslt/txRtfHandler.cpp
@@ -40,8 +40,7 @@
 #include "txRtfHandler.h"
 
 txResultTreeFragment::txResultTreeFragment(nsAutoPtr<txResultBuffer>& aBuffer)
-    : txAExprResult(nsnull),
-      mBuffer(aBuffer)
+    : mBuffer(aBuffer)
 {
 }
 
diff --git a/content/xslt/src/xslt/txStylesheet.h b/content/xslt/src/xslt/txStylesheet.h
--- a/content/xslt/src/xslt/txStylesheet.h
+++ b/content/xslt/src/xslt/txStylesheet.h
@@ -55,7 +55,7 @@ class txStripSpaceTest;
 class txStripSpaceTest;
 class txXSLKey;
 
-class txStylesheet
+class txStylesheet : public XPCOMGCFinalizedObject
 {
 public:
     class ImportFrame;
@@ -67,20 +67,6 @@ public:
     txStylesheet();
     ~txStylesheet();
     nsresult init();
-
-    nsrefcnt AddRef()
-    {
-        return ++mRefCnt;
-    }
-    nsrefcnt Release()
-    {
-        if (--mRefCnt == 0) {
-            mRefCnt = 1; //stabilize
-            delete this;
-            return 0;
-        }
-        return mRefCnt;
-    }
 
     txInstruction* findTemplate(const txXPathNode& aNode,
                                 const txExpandedName& aMode,
@@ -159,9 +145,6 @@ private:
                            nsTPtrArray<txStripSpaceTest>& aFrameStripSpaceTests);
     nsresult addAttributeSet(txAttributeSetItem* aAttributeSetItem);
 
-    // Refcount
-    nsAutoRefCnt mRefCnt;
-
     // List of ImportFrames
     txList mImportFrames;
     
diff --git a/content/xslt/src/xslt/txStylesheetCompiler.cpp b/content/xslt/src/xslt/txStylesheetCompiler.cpp
--- a/content/xslt/src/xslt/txStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txStylesheetCompiler.cpp
@@ -67,27 +67,6 @@ txStylesheetCompiler::txStylesheetCompil
     : txStylesheetCompilerState(aObserver)
 {
     mStatus = init(aStylesheetURI, aStylesheet, aInsertPosition);
-}
-
-nsrefcnt
-txStylesheetCompiler::AddRef()
-{
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "txStylesheetCompiler", sizeof(*this));
-    return mRefCnt;
-}
-
-nsrefcnt
-txStylesheetCompiler::Release()
-{
-    --mRefCnt;
-    NS_LOG_RELEASE(this, mRefCnt, "txStylesheetCompiler");
-    if (mRefCnt == 0) {
-        mRefCnt = 1; //stabilize
-        delete this;
-        return 0;
-    }
-    return mRefCnt;
 }
 
 void
diff --git a/content/xslt/src/xslt/txStylesheetCompiler.h b/content/xslt/src/xslt/txStylesheetCompiler.h
--- a/content/xslt/src/xslt/txStylesheetCompiler.h
+++ b/content/xslt/src/xslt/txStylesheetCompiler.h
@@ -75,9 +75,6 @@ class txACompileObserver
 class txACompileObserver
 {
 public:
-    virtual nsrefcnt AddRef() = 0;
-    virtual nsrefcnt Release() = 0;
-
     virtual nsresult loadURI(const nsAString& aUri,
                              const nsAString& aReferrerUri,
                              txStylesheetCompiler* aCompiler) = 0;
@@ -88,8 +85,6 @@ public:
 };
 
 #define TX_DECL_ACOMPILEOBSERVER \
-  nsrefcnt AddRef(); \
-  nsrefcnt Release(); \
   nsresult loadURI(const nsAString& aUri, const nsAString& aReferrerUri, \
                    txStylesheetCompiler* aCompiler); \
   void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, \
@@ -213,8 +208,6 @@ public:
                          txStylesheet* aStylesheet,
                          txListIterator* aInsertPosition,
                          txACompileObserver* aObserver);
-    virtual nsrefcnt AddRef();
-    virtual nsrefcnt Release();
 
     void setBaseURI(const nsString& aBaseURI);
 
@@ -251,7 +244,6 @@ private:
     nsresult ensureNewElementContext();
     nsresult maybeDoneCompiling();
 
-    nsAutoRefCnt mRefCnt;
     nsString mCharacters;
     nsresult mStatus;
 };
diff --git a/content/xul/content/src/nsXULElement.h b/content/xul/content/src/nsXULElement.h
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -184,14 +184,12 @@ public:
 
  */
 
-class nsXULPrototypeNode
+class nsXULPrototypeNode : public XPCOMGCFinalizedObject
 {
 public:
     enum Type { eType_Element, eType_Script, eType_Text, eType_PI };
 
     Type                     mType;
-
-    nsAutoRefCnt             mRefCnt;
 
     virtual ~nsXULPrototypeNode() {}
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
@@ -207,17 +205,6 @@ public:
     virtual PRUint32 ClassSize() = 0;
 #endif
 
-    void AddRef() {
-        ++mRefCnt;
-        NS_LOG_ADDREF(this, mRefCnt, ClassName(), ClassSize());
-    }
-    void Release()
-    {
-        --mRefCnt;
-        NS_LOG_RELEASE(this, mRefCnt, ClassName());
-        if (mRefCnt == 0)
-            delete this;
-    }
     /**
      * The prototype document must call ReleaseSubtree when it is going
      * away.  This makes the parents through the tree stop owning their
@@ -226,13 +213,13 @@ public:
      * those prototypes no longer remember their children to allow them
      * to be constructed.
      */
-    virtual void ReleaseSubtree() { Release(); }
+    virtual void ReleaseSubtree() { }
 
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsXULPrototypeNode)
 
 protected:
     nsXULPrototypeNode(Type aType)
-        : mType(aType), mRefCnt(1) {}
+        : mType(aType) {}
 };
 
 class nsXULPrototypeElement : public nsXULPrototypeNode
@@ -274,8 +261,6 @@ public:
         delete[] mChildren;
         mChildren = nsnull;
       }
-
-      nsXULPrototypeNode::ReleaseSubtree();
     }
 
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
diff --git a/content/xul/document/src/nsXULContentSink.cpp b/content/xul/document/src/nsXULContentSink.cpp
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -719,12 +719,10 @@ XULContentSinkImpl::HandleProcessingInst
     nsVoidArray* children;
     rv = mContextStack.GetTopChildren(&children);
     if (NS_FAILED(rv)) {
-        pi->Release();
         return rv;
     }
 
     if (!children->AppendElement(pi)) {
-        pi->Release();
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
@@ -900,7 +898,6 @@ XULContentSinkImpl::OpenRoot(const PRUni
     // containers will hook up to us as their parent.
     rv = mContextStack.Push(element, mState);
     if (NS_FAILED(rv)) {
-        element->Release();
         return rv;
     }
 
diff --git a/content/xul/document/src/nsXULPrototypeDocument.cpp b/content/xul/document/src/nsXULPrototypeDocument.cpp
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -177,12 +177,6 @@ nsXULPrototypeDocument::~nsXULPrototypeD
     if (mGlobalObject) {
         // cleaup cycles etc.
         mGlobalObject->ClearGlobalObjectOwner();
-    }
-
-    PRUint32 count = mProcessingInstructions.Length();
-    for (PRUint32 i = 0; i < count; i++)
-    {
-        mProcessingInstructions[i]->Release();
     }
 
     if (mRoot)
diff --git a/content/xul/templates/src/nsXMLBinding.h b/content/xul/templates/src/nsXMLBinding.h
--- a/content/xul/templates/src/nsXMLBinding.h
+++ b/content/xul/templates/src/nsXMLBinding.h
@@ -76,18 +76,10 @@ class nsXMLBindingSet
 {
 public:
 
-  // results hold a reference to a binding set in their
-  // nsXMLBindingValues fields
-  nsAutoRefCnt mRefCnt;
-
   // pointer to the first binding in a linked list
   nsAutoPtr<nsXMLBinding> mFirst;
 
 public:
-
-  NS_IMETHOD_(nsrefcnt) AddRef();
-  NS_IMETHOD_(nsrefcnt) Release();
-  NS_DECL_OWNINGTHREAD
 
   /**
    * Add a binding to the set
diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp
--- a/docshell/base/nsWebShell.cpp
+++ b/docshell/base/nsWebShell.cpp
@@ -560,9 +560,6 @@ nsWebShell::~nsWebShell()
 nsWebShell::~nsWebShell()
 {
    Destroy();
-
-  ++mRefCnt; // following releases can cause this destructor to be called
-             // recursively if the refcount is allowed to remain 0
 
   mContentViewer=nsnull;
 
diff --git a/dom/src/base/nsWindowRoot.cpp b/dom/src/base/nsWindowRoot.cpp
--- a/dom/src/base/nsWindowRoot.cpp
+++ b/dom/src/base/nsWindowRoot.cpp
@@ -67,10 +67,8 @@ nsWindowRoot::nsWindowRoot(nsIDOMWindow*
   nsFocusController::Create(getter_AddRefs(mFocusController));
 
   nsCOMPtr<nsIDOMFocusListener> focusListener(do_QueryInterface(mFocusController));
-  ++mRefCnt;
   AddEventListener(NS_LITERAL_STRING("focus"), focusListener, PR_TRUE);
   AddEventListener(NS_LITERAL_STRING("blur"), focusListener, PR_TRUE);
-  --mRefCnt;
 }
 
 nsWindowRoot::~nsWindowRoot()
diff --git a/editor/libeditor/base/IMETextTxn.h b/editor/libeditor/base/IMETextTxn.h
--- a/editor/libeditor/base/IMETextTxn.h
+++ b/editor/libeditor/base/IMETextTxn.h
@@ -120,9 +120,6 @@ protected:
   PRBool	mFixed;
 
   friend class TransactionFactory;
-
-  friend class nsDerivedSafe<IMETextTxn>; // work around for a compiler bug
-
 };
 
 #endif
diff --git a/editor/libeditor/base/InsertTextTxn.h b/editor/libeditor/base/InsertTextTxn.h
--- a/editor/libeditor/base/InsertTextTxn.h
+++ b/editor/libeditor/base/InsertTextTxn.h
@@ -104,9 +104,6 @@ protected:
   nsIEditor *mEditor;   
 
   friend class TransactionFactory;
-
-  friend class nsDerivedSafe<InsertTextTxn>; // work around for a compiler bug
-
 };
 
 #endif
diff --git a/editor/txtsvc/src/nsTSDNotifier.cpp b/editor/txtsvc/src/nsTSDNotifier.cpp
--- a/editor/txtsvc/src/nsTSDNotifier.cpp
+++ b/editor/txtsvc/src/nsTSDNotifier.cpp
@@ -48,32 +48,6 @@ nsTSDNotifier::~nsTSDNotifier()
 {
   mDoc = 0;
 }
-
-#define DEBUG_TSD_NOTIFIER_REFCNT 1
-
-#ifdef DEBUG_TSD_NOTIFIER_REFCNT
-
-nsrefcnt nsTSDNotifier::AddRef(void)
-{
-  return ++mRefCnt;
-}
-
-nsrefcnt nsTSDNotifier::Release(void)
-{
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-  if (--mRefCnt == 0) {
-    NS_DELETEXPCOM(this);
-    return 0;
-  }
-  return mRefCnt;
-}
-
-#else
-
-NS_IMPL_ADDREF(nsTSDNotifier)
-NS_IMPL_RELEASE(nsTSDNotifier)
-
-#endif
 
 NS_IMPL_QUERY_INTERFACE1(nsTSDNotifier, nsIEditActionListener)
 
diff --git a/editor/txtsvc/src/nsTextServicesDocument.cpp b/editor/txtsvc/src/nsTextServicesDocument.cpp
--- a/editor/txtsvc/src/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/src/nsTextServicesDocument.cpp
@@ -104,8 +104,6 @@ nsIRangeUtils* nsTextServicesDocument::s
 
 nsTextServicesDocument::nsTextServicesDocument()
 {
-  mRefCnt         = 0;
-
   mSelStartIndex  = -1;
   mSelStartOffset = -1;
   mSelEndIndex    = -1;
@@ -142,32 +140,6 @@ nsTextServicesDocument::Shutdown()
 {
   NS_IF_RELEASE(sRangeHelper);
 }
-
-#define DEBUG_TEXT_SERVICES__DOCUMENT_REFCNT 1
-
-#ifdef DEBUG_TEXT_SERVICES__DOCUMENT_REFCNT
-
-nsrefcnt nsTextServicesDocument::AddRef(void)
-{
-  return ++mRefCnt;
-}
-
-nsrefcnt nsTextServicesDocument::Release(void)
-{
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-  if (--mRefCnt == 0) {
-    NS_DELETEXPCOM(this);
-    return 0;
-  }
-  return mRefCnt;
-}
-
-#else
-
-NS_IMPL_ADDREF(nsTextServicesDocument)
-NS_IMPL_RELEASE(nsTextServicesDocument)
-
-#endif
 
 NS_IMPL_QUERY_INTERFACE1(nsTextServicesDocument, nsITextServicesDocument)
 
diff --git a/embedding/browser/gtk/src/EmbedPrivate.cpp b/embedding/browser/gtk/src/EmbedPrivate.cpp
--- a/embedding/browser/gtk/src/EmbedPrivate.cpp
+++ b/embedding/browser/gtk/src/EmbedPrivate.cpp
@@ -113,18 +113,6 @@ NS_IMPL_QUERY_INTERFACE2(GTKEmbedDirecto
 NS_IMPL_QUERY_INTERFACE2(GTKEmbedDirectoryProvider,
                          nsIDirectoryServiceProvider,
                          nsIDirectoryServiceProvider2)
-
-NS_IMETHODIMP_(nsrefcnt)
-GTKEmbedDirectoryProvider::AddRef()
-{
-  return 1;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-GTKEmbedDirectoryProvider::Release()
-{
-  return 1;
-}
 
 NS_IMETHODIMP
 GTKEmbedDirectoryProvider::GetFile(const char *aKey, PRBool *aPersist,
diff --git a/embedding/browser/webBrowser/nsWebBrowser.cpp b/embedding/browser/webBrowser/nsWebBrowser.cpp
--- a/embedding/browser/webBrowser/nsWebBrowser.cpp
+++ b/embedding/browser/webBrowser/nsWebBrowser.cpp
@@ -125,7 +125,7 @@ nsWebBrowser::~nsWebBrowser()
 
 PRBool PR_CALLBACK deleteListener(void *aElement, void *aData) {
     nsWebBrowserListenerState *state = (nsWebBrowserListenerState*)aElement;
-    NS_DELETEXPCOM(state);
+    delete state;
     return PR_TRUE;
 }
 
@@ -308,7 +308,7 @@ NS_IMETHODIMP nsWebBrowser::RemoveWebBro
         // if we've emptied the array, get rid of it.
         if (0 >= mListenerArray->Count()) {
             (void)mListenerArray->EnumerateForwards(deleteListener, nsnull);
-            NS_DELETEXPCOM(mListenerArray);
+            delete mListenerArray;
             mListenerArray = nsnull;
         }
 
@@ -1157,7 +1157,7 @@ NS_IMETHODIMP nsWebBrowser::Create()
           i++;
       }
       (void)mListenerArray->EnumerateForwards(deleteListener, nsnull);
-      NS_DELETEXPCOM(mListenerArray);
+      delete mListenerArray;
       mListenerArray = nsnull;
    }
 
diff --git a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -198,13 +198,11 @@ nsWatcherWindowEnumerator::nsWatcherWind
     mCurrentPosition(inWatcher->mOldestWindow)
 {
   mWindowWatcher->AddEnumerator(this);
-  mWindowWatcher->AddRef();
 }
 
 nsWatcherWindowEnumerator::~nsWatcherWindowEnumerator()
 {
   mWindowWatcher->RemoveEnumerator(this);
-  mWindowWatcher->Release();
 }
 
 NS_IMETHODIMP
diff --git a/gfx/src/thebes/nsThebesRegion.cpp b/gfx/src/thebes/nsThebesRegion.cpp
--- a/gfx/src/thebes/nsThebesRegion.cpp
+++ b/gfx/src/thebes/nsThebesRegion.cpp
@@ -43,7 +43,6 @@ NS_IMPL_ISUPPORTS1(nsThebesRegion, nsIRe
 
 nsThebesRegion::nsThebesRegion() 
 {  
-  NS_INIT_ISUPPORTS();
 }
 
 nsresult nsThebesRegion::Init (void)
diff --git a/intl/unicharutil/src/nsCaseConversionImp2.cpp b/intl/unicharutil/src/nsCaseConversionImp2.cpp
--- a/intl/unicharutil/src/nsCaseConversionImp2.cpp
+++ b/intl/unicharutil/src/nsCaseConversionImp2.cpp
@@ -168,16 +168,6 @@ nsCaseConversionImp2* nsCaseConversionIm
   return gCaseConv;
 }
 
-NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::AddRef(void)
-{
-  return (nsrefcnt)1;
-}
-
-NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::Release(void)
-{
-  return (nsrefcnt)1;
-}
-
 NS_IMPL_THREADSAFE_QUERY_INTERFACE1(nsCaseConversionImp2, nsICaseConversion)
 
 nsresult nsCaseConversionImp2::ToUpper(
diff --git a/intl/unicharutil/src/nsCategoryImp.cpp b/intl/unicharutil/src/nsCategoryImp.cpp
--- a/intl/unicharutil/src/nsCategoryImp.cpp
+++ b/intl/unicharutil/src/nsCategoryImp.cpp
@@ -42,19 +42,10 @@
 #include "nsCategoryImp.h"
 #include "cattable.h"
 
+// XXXbsmedberg this is bad, must go
 static nsCategoryImp gCategoryImp;
 
 NS_IMPL_THREADSAFE_QUERY_INTERFACE1(nsCategoryImp, nsIUGenCategory)
-
-NS_IMETHODIMP_(nsrefcnt) nsCategoryImp::AddRef(void)
-{
-  return nsrefcnt(1);
-}
-
-NS_IMETHODIMP_(nsrefcnt) nsCategoryImp::Release(void)
-{
-  return nsrefcnt(1);
-}
 
 nsCategoryImp* nsCategoryImp::GetInstance()
 {
diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -907,11 +907,11 @@ ProcessArgs(JSContext *cx, JSObject *obj
 
 /***************************************************************************/
 
-class FullTrustSecMan
+class FullTrustSecMan : public XPCOMGCFinalizedObject
 #ifndef XPCONNECT_STANDALONE
-  : public nsIScriptSecurityManager
+                      , public nsIScriptSecurityManager
 #else
-  : public nsIXPCSecurityManager
+                      , public nsIXPCSecurityManager
 #endif
 {
 public:
diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -244,14 +244,6 @@ nsXPConnect::ReleaseXPConnectSingleton()
         // NOTE: to see really interesting stuff turn on the prlog stuff.
         // See the comment at the top of xpclog.h to see how to do that.
         xpc->DebugDump(7);
-#endif
-        nsrefcnt cnt;
-        NS_RELEASE2(xpc, cnt);
-#ifdef XPC_DUMP_AT_SHUTDOWN
-        if(0 != cnt)
-            printf("*** dangling reference to nsXPConnect: refcnt=%d\n", cnt);
-        else
-            printf("+++ XPConnect had no dangling references.\n");
 #endif
     }
 }
@@ -1448,7 +1440,7 @@ nsXPConnect::DebugDump(PRInt16 depth)
 {
 #ifdef DEBUG
     depth-- ;
-    XPC_LOG_ALWAYS(("nsXPConnect @ %x with mRefCnt = %d", this, mRefCnt.get()));
+    XPC_LOG_ALWAYS(("nsXPConnect @ %x", this));
     XPC_LOG_INDENT();
         XPC_LOG_ALWAYS(("gSelf @ %x", gSelf));
         XPC_LOG_ALWAYS(("gOnceAliveNowDead is %d", (int)gOnceAliveNowDead));
diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -83,6 +83,8 @@ struct JSDyingJSObjectData
     nsVoidArray* array;
 };
 
+#if 0
+// Let's pretend this is unnecessary (it probably is)
 JS_STATIC_DLL_CALLBACK(JSDHashOperator)
 WrappedJSDyingJSObjectFinder(JSDHashTable *table, JSDHashEntryHdr *hdr,
                 uint32 number, void *arg)
@@ -103,6 +105,7 @@ WrappedJSDyingJSObjectFinder(JSDHashTabl
     }
     return JS_DHASH_NEXT;
 }
+#endif
 
 struct CX_AND_XPCRT_Data
 {
@@ -254,57 +257,6 @@ ContextCallback(JSContext *cx, uintN ope
 }
 
 // static
-void XPCJSRuntime::TraceJS(JSTracer* trc, void* data)
-{
-    XPCJSRuntime* self = (XPCJSRuntime*)data;
-
-    // Skip this part if XPConnect is shutting down. We get into
-    // bad locking problems with the thread iteration otherwise.
-    if(!self->GetXPConnect()->IsShuttingDown())
-    {
-        PRLock* threadLock = XPCPerThreadData::GetLock();
-        if(threadLock)
-        { // scoped lock
-            nsAutoLock lock(threadLock);
-
-            XPCPerThreadData* iterp = nsnull;
-            XPCPerThreadData* thread;
-
-            while(nsnull != (thread =
-                             XPCPerThreadData::IterateThreads(&iterp)))
-            {
-                // Trace those AutoMarkingPtr lists!
-                thread->TraceJS(trc);
-            }
-        }
-    }
-
-    // XPCJSObjectHolders don't participate in cycle collection, so always trace
-    // them here.
-    for(XPCRootSetElem *e = self->mObjectHolderRoots; e ; e = e->GetNextRoot())
-        static_cast<XPCJSObjectHolder*>(e)->TraceJS(trc);
-        
-    self->TraceXPConnectRoots(trc);
-}
-
-struct ClearedGlobalObject : public JSDHashEntryHdr
-{
-    JSContext* mContext;
-    JSObject* mGlobalObject;
-};
-
-void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc)
-{
-    XPCWrappedNativeScope::TraceJS(trc, this);
-
-    for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot())
-        static_cast<XPCTraceableVariant*>(e)->TraceJS(trc);
-
-    for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot())
-        static_cast<nsXPCWrappedJS*>(e)->TraceJS(trc);
-}
-
-// static
 JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
 {
     nsVoidArray* dyingWrappedJSArray;
@@ -344,8 +296,11 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                     // We add them to the array now and Release the array members
                     // later to avoid the posibility of doing any JS GCThing
                     // allocations during the gc cycle.
+#if 0
+                    // let's pretend this is unnecessary (it probably is)
                     self->mWrappedJSMap->
                         Enumerate(WrappedJSDyingJSObjectFinder, &data);
+#endif
                 }
 
                 // Do cleanup in NativeInterfaces. This part just finds 
@@ -670,7 +625,7 @@ XPCJSRuntime::~XPCJSRuntime()
     // count the total JSContexts in use
     JSContext* iter = nsnull;
     int count = 0;
-    while(JS_ContextIterator(mJSRuntime, &iter))
+    while(JS_ContextIterator(gJSRuntime, &iter))
         count ++;
     if(count)
         printf("deleting XPCJSRuntime with %d live JSContexts\n", count);
@@ -692,7 +647,7 @@ XPCJSRuntime::~XPCJSRuntime()
         if(count)
             printf("deleting XPCJSRuntime with %d live wrapped JSObject\n", (int)count);
 #endif
-        mWrappedJSMap->Enumerate(WrappedJSShutdownMarker, mJSRuntime);
+        mWrappedJSMap->Enumerate(WrappedJSShutdownMarker, gJSRuntime);
         delete mWrappedJSMap;
     }
 
@@ -814,7 +769,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
 XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect,
                            nsIJSRuntimeService* aJSRuntimeService)
  : mXPConnect(aXPConnect),
-   mJSRuntime(nsnull),
    mJSRuntimeService(aJSRuntimeService),
    mContextMap(JSContext2XPCContextMap::newMap(XPC_CONTEXT_MAP_SIZE)),
    mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)),
@@ -848,22 +802,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     if(mJSRuntimeService)
     {
         NS_ADDREF(mJSRuntimeService);
-        mJSRuntimeService->GetRuntime(&mJSRuntime);
     }
 
     NS_ASSERTION(!gOldJSGCCallback, "XPCJSRuntime created more than once");
-    if(mJSRuntime)
-    {
-        gOldJSContextCallback = JS_SetContextCallback(mJSRuntime,
-                                                      ContextCallback);
-        gOldJSGCCallback = JS_SetGCCallbackRT(mJSRuntime, GCCallback);
-        JS_SetExtraGCRoots(mJSRuntime, TraceJS, this);
-    }
+    gOldJSContextCallback = JS_SetContextCallback(gJSRuntime,
+                                                  ContextCallback);
+    gOldJSGCCallback = JS_SetGCCallbackRT(gJSRuntime, GCCallback);
 
     // Install a JavaScript 'debugger' keyword handler in debug builds only
 #ifdef DEBUG
-    if(mJSRuntime && !JS_GetGlobalDebugHooks(mJSRuntime)->debuggerHandler)
-        xpc_InstallJSDebuggerKeywordHandler(mJSRuntime);
+    if(!JS_GetGlobalDebugHooks(gJSRuntime)->debuggerHandler)
+        xpc_InstallJSDebuggerKeywordHandler(gJSRuntime);
 #endif
 }
 
@@ -945,7 +894,7 @@ XPCJSRuntime::SyncXPCContextList(JSConte
 
     // add XPCContexts that represent any JSContexts we have not seen before
     JSContext *cur, *iter = nsnull;
-    while(nsnull != (cur = JS_ContextIterator(mJSRuntime, &iter)))
+    while(nsnull != (cur = JS_ContextIterator(gJSRuntime, &iter)))
     {
         XPCContext* xpcc = mContextMap->Find(cur);
 
@@ -1078,7 +1027,7 @@ XPCJSRuntime::DebugDump(PRInt16 depth)
     XPC_LOG_ALWAYS(("XPCJSRuntime @ %x", this));
         XPC_LOG_INDENT();
         XPC_LOG_ALWAYS(("mXPConnect @ %x", mXPConnect));
-        XPC_LOG_ALWAYS(("mJSRuntime @ %x", mJSRuntime));
+        XPC_LOG_ALWAYS(("gJSRuntime @ %x", gJSRuntime));
         XPC_LOG_ALWAYS(("mMapLock @ %x", mMapLock));
         XPC_LOG_ALWAYS(("mJSRuntimeService @ %x", mJSRuntimeService));
 
diff --git a/js/src/xpconnect/src/xpcmodule.cpp b/js/src/xpconnect/src/xpcmodule.cpp
--- a/js/src/xpconnect/src/xpcmodule.cpp
+++ b/js/src/xpconnect/src/xpcmodule.cpp
@@ -130,7 +130,6 @@ xpcModuleDtor(nsIModule* self)
 {
     // Release our singletons
     nsXPConnect::ReleaseXPConnectSingleton();
-    nsXPCThreadJSContextStackImpl::FreeSingleton();
     nsJSRuntimeServiceImpl::FreeSingleton();
     xpc_DestroyJSxIDClassObjects();
 #ifdef XPC_IDISPATCH_SUPPORT
diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -52,6 +52,7 @@
 #include <math.h>
 #include "nscore.h"
 #include "nsXPCOM.h"
+#include "nsXPCOMPrivate.h" // for gJSRuntime
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupports.h"
@@ -576,7 +577,7 @@ public:
     static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect,
                                          nsIJSRuntimeService* aJSRuntimeService);
 
-    JSRuntime*     GetJSRuntime() const {return mJSRuntime;}
+    static JSRuntime* GetJSRuntime() {return gJSRuntime;}
     nsXPConnect*   GetXPConnect() const {return mXPConnect;}
 
     nsIJSRuntimeService* GetJSRuntimeService() const {return mJSRuntimeService;}
@@ -665,9 +666,6 @@ public:
         return mStrings[index];
     }
 
-    static void JS_DLL_CALLBACK TraceJS(JSTracer* trc, void* data);
-    void TraceXPConnectRoots(JSTracer *trc);
-
     static JSBool JS_DLL_CALLBACK GCCallback(JSContext *cx, JSGCStatus status);
 
     inline void AddVariantRoot(XPCTraceableVariant* variant);
@@ -716,7 +714,6 @@ private:
     jsval mStrJSVals[IDX_TOTAL_COUNT];
 
     nsXPConnect* mXPConnect;
-    JSRuntime*  mJSRuntime;
     nsIJSRuntimeService* mJSRuntimeService; // hold this to hold the JSRuntime
     JSContext2XPCContextMap* mContextMap;
     JSObject2WrappedJSMap*   mWrappedJSMap;
@@ -1209,9 +1206,6 @@ public:
 
     static void
     SystemIsBeingShutDown(JSContext* cx);
-
-    static void
-    TraceJS(JSTracer* trc, XPCJSRuntime* rt);
 
     static void
     FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt);
@@ -2239,8 +2233,6 @@ public:
                         nsIClassInfo* classInfo,
                         XPCNativeScriptableCreateInfo* sciProto);
 
-    JSBool HasExternalReference() const {return mRefCnt > 1;}
-
     JSObject* GetWrapper()              { return mWrapper; }
     void      SetWrapper(JSObject *obj) { mWrapper = obj; }
 
@@ -2470,21 +2462,8 @@ public:
     JSBool IsValid() const {return mJSObj != nsnull;}
     void SystemIsBeingShutDown(JSRuntime* rt);
 
-    // This is used by XPCJSRuntime::GCCallback to find wrappers that no
-    // longer root their JSObject and are only still alive because they
-    // were being used via nsSupportsWeakReference at the time when their
-    // last (outside) reference was released. Wrappers that fit into that
-    // category are only deleted when we see that their corresponding JSObject
-    // is to be finalized.
-    JSBool IsSubjectToFinalization() const {return IsValid() && mRefCnt == 1;}
-
     JSBool IsAggregatedToNative() const {return mRoot->mOuter != nsnull;}
     nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
-
-    void TraceJS(JSTracer* trc);
-#ifdef DEBUG
-    static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
-#endif
 
     virtual ~nsXPCWrappedJS();
 protected:
@@ -3172,7 +3151,6 @@ public:
     static nsXPCThreadJSContextStackImpl* GetSingleton();
 
     static void InitStatics() { gXPCThreadJSContextStack = nsnull; }
-    static void FreeSingleton();
 
     nsXPCThreadJSContextStackImpl();
     virtual ~nsXPCThreadJSContextStackImpl();
@@ -3250,12 +3228,11 @@ class nsJSRuntimeServiceImpl : public ns
 
     static void FreeSingleton();
 
-    nsJSRuntimeServiceImpl();
-    virtual ~nsJSRuntimeServiceImpl();
+    nsJSRuntimeServiceImpl() {}
+    ~nsJSRuntimeServiceImpl() {}
 
     static void InitStatics() { gJSRuntimeService = nsnull; }
  protected:
-    JSRuntime *mRuntime;
     static nsJSRuntimeServiceImpl* gJSRuntimeService;
     nsCOMPtr<nsIXPCScriptable> mBackstagePass;
 };
diff --git a/js/src/xpconnect/src/xpcruntimesvc.cpp b/js/src/xpconnect/src/xpcruntimesvc.cpp
--- a/js/src/xpconnect/src/xpcruntimesvc.cpp
+++ b/js/src/xpconnect/src/xpcruntimesvc.cpp
@@ -187,24 +187,6 @@ BackstagePass::GetClassIDNoAlloc(nsCID *
  * is using it.
  */
 
-nsJSRuntimeServiceImpl::nsJSRuntimeServiceImpl() :
-    mRuntime(0)
-{
-}
-
-nsJSRuntimeServiceImpl::~nsJSRuntimeServiceImpl() {
-    if(mRuntime)
-    {
-        JS_DestroyRuntime(mRuntime);
-        JS_ShutDown();
-#ifdef DEBUG_shaver_off
-        fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mRuntime);
-#endif
-    }
-
-    XPCPerThreadData::ShutDown();
-}
-
 NS_IMPL_THREADSAFE_ISUPPORTS2(nsJSRuntimeServiceImpl,
                               nsIJSRuntimeService,
                               nsISupportsWeakReference)
@@ -242,8 +224,8 @@ nsJSRuntimeServiceImpl::GetRuntime(JSRun
     if(!runtime)
         return NS_ERROR_NULL_POINTER;
 
-    if(!mRuntime)
-    {
+#if 0
+        // XXXbsmedberg: this comment is completely out of date
         // Call XPCPerThreadData::GetData to initialize 
         // XPCPerThreadData::gTLSIndex before initializing 
         // JSRuntime::threadTPIndex in JS_NewRuntime.
@@ -261,10 +243,6 @@ nsJSRuntimeServiceImpl::GetRuntime(JSRun
         // the same order of calling PR_NewThreadPrivateIndex.
         XPCPerThreadData::GetData(nsnull);
         
-        mRuntime = JS_NewRuntime(gGCSize);
-        if(!mRuntime)
-            return NS_ERROR_OUT_OF_MEMORY;
-
         // Unconstrain the runtime's threshold on nominal heap size, to avoid
         // triggering GC too often if operating continuously near an arbitrary
         // finite threshold (0xffffffff is infinity for uint32 parameters).
@@ -273,7 +251,8 @@ nsJSRuntimeServiceImpl::GetRuntime(JSRun
         // the GC's allocator.
         JS_SetGCParameter(mRuntime, JSGC_MAX_BYTES, 0xffffffff);
     }
-    *runtime = mRuntime;
+#endif
+    *runtime = gJSRuntime;
     return NS_OK;
 }
 
diff --git a/js/src/xpconnect/src/xpcthreadcontext.cpp b/js/src/xpconnect/src/xpcthreadcontext.cpp
--- a/js/src/xpconnect/src/xpcthreadcontext.cpp
+++ b/js/src/xpconnect/src/xpcthreadcontext.cpp
@@ -323,21 +323,6 @@ nsXPCThreadJSContextStackImpl::GetSingle
     return gXPCThreadJSContextStack;
 }
 
-void
-nsXPCThreadJSContextStackImpl::FreeSingleton()
-{
-    nsXPCThreadJSContextStackImpl* tcs = gXPCThreadJSContextStack;
-    if(tcs)
-    {
-        nsrefcnt cnt;
-        NS_RELEASE2(tcs, cnt);
-#ifdef XPC_DUMP_AT_SHUTDOWN
-        if(0 != cnt)
-            printf("*** dangling reference to nsXPCThreadJSContextStackImpl: refcnt=%d\n", cnt);
-#endif
-    }
-}
-
 /* readonly attribute PRInt32 Count; */
 NS_IMETHODIMP
 nsXPCThreadJSContextStackImpl::GetCount(PRInt32 *aCount)
diff --git a/js/src/xpconnect/src/xpcwrappedjs.cpp b/js/src/xpconnect/src/xpcwrappedjs.cpp
--- a/js/src/xpconnect/src/xpcwrappedjs.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjs.cpp
@@ -96,91 +96,6 @@ nsXPCWrappedJS::QueryInterface(REFNSIID 
 
     return mClass->DelegatedQueryInterface(this, aIID, aInstancePtr);
 }
-
-
-// Refcounting is now similar to that used in the chained (pre-flattening)
-// wrappednative system.
-//
-// We are now holding an extra refcount for nsISupportsWeakReference support.
-//
-// Non-root wrappers remove themselves from the chain in their destructors.
-// We root the JSObject as the refcount transitions from 1->2. And we unroot
-// the JSObject when the refcount transitions from 2->1.
-//
-// When the transition from 2->1 is made and no one holds a weak ref to the
-// (aggregated) object then we decrement the refcount again to 0 (and
-// destruct) . However, if a weak ref is held at the 2->1 transition, then we
-// leave the refcount at 1 to indicate that state. This leaves the JSObject
-// no longer rooted by us and (as far as we know) subject to possible
-// collection. Code in XPCJSRuntime watches for JS gc to happen and will do
-// the final release on wrappers whose JSObjects get finalized. Note that
-// even after tranistioning to this refcount-of-one state callers might do
-// an addref and cause us to re-root the JSObject and continue on more normally.
-
-nsrefcnt
-nsXPCWrappedJS::AddRef(void)
-{
-    nsrefcnt cnt = (nsrefcnt) PR_AtomicIncrement((PRInt32*)&mRefCnt);
-    NS_LOG_ADDREF(this, cnt, "nsXPCWrappedJS", sizeof(*this));
-
-    if(2 == cnt && IsValid())
-    {
-        XPCJSRuntime* rt = mClass->GetRuntime();
-        rt->AddWrappedJSRoot(this);
-    }
-
-    return cnt;
-}
-
-nsrefcnt
-nsXPCWrappedJS::Release(void)
-{
-    NS_PRECONDITION(0 != mRefCnt, "dup release");
-
-do_decrement:
-
-    nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt);
-    NS_LOG_RELEASE(this, cnt, "nsXPCWrappedJS");
-
-    if(0 == cnt)
-    {
-        NS_DELETEXPCOM(this);   // also unlinks us from chain
-        return 0;
-    }
-    if(1 == cnt)
-    {
-        if(IsValid())
-            RemoveFromRootSet(nsXPConnect::GetRuntime()->GetJSRuntime());
-
-        // If we are not the root wrapper or if we are not being used from a
-        // weak reference, then this extra ref is not needed and we can let
-        // ourself be deleted.
-        // Note: HasWeakReferences() could only return true for the root.
-        if(!HasWeakReferences())
-            goto do_decrement;
-    }
-    return cnt;
-}
-
-void
-nsXPCWrappedJS::TraceJS(JSTracer* trc)
-{
-    NS_ASSERTION(mRefCnt >= 2 && IsValid(), "must be strongly referenced");
-    JS_SET_TRACING_DETAILS(trc, PrintTraceName, this, 0);
-    JS_CallTracer(trc, mJSObj, JSTRACE_OBJECT);
-}
-
-#ifdef DEBUG
-// static
-void
-nsXPCWrappedJS::PrintTraceName(JSTracer* trc, char *buf, size_t bufsize)
-{
-    const nsXPCWrappedJS* self = static_cast<const nsXPCWrappedJS*>
-                                            (trc->debugPrintArg);
-    JS_snprintf(buf, bufsize, "nsXPCWrappedJS[%s,0x%p].mJSObj",
-                self->GetClass()->GetInterfaceName(), self);
-}
-#endif
 
 NS_IMETHODIMP
 nsXPCWrappedJS::GetWeakReference(nsIWeakReference** aInstancePtr)
@@ -353,15 +268,10 @@ nsXPCWrappedJS::nsXPCWrappedJS(XPCCallCo
 
 nsXPCWrappedJS::~nsXPCWrappedJS()
 {
-    NS_PRECONDITION(0 == mRefCnt, "refcounting error");
-
+    XPCJSRuntime* rt = nsXPConnect::GetRuntime();
     if(mRoot == this)
     {
-        // Let the nsWeakReference object (if present) know of our demise.
-        ClearWeakReferences();
-
-        // Remove this root wrapper from the map
-        XPCJSRuntime* rt = nsXPConnect::GetRuntime();
+        // remove this root wrapper from the map
         if(rt)
         {
             JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
@@ -533,7 +443,7 @@ nsXPCWrappedJS::DebugDump(PRInt16 depth)
 nsXPCWrappedJS::DebugDump(PRInt16 depth)
 {
 #ifdef DEBUG
-    XPC_LOG_ALWAYS(("nsXPCWrappedJS @ %x with mRefCnt = %d", this, mRefCnt.get()));
+    XPC_LOG_ALWAYS(("nsXPCWrappedJS @ %x", this));
         XPC_LOG_INDENT();
 
         PRBool isRoot = mRoot == this;
diff --git a/js/src/xpconnect/src/xpcwrappedjsclass.cpp b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
@@ -1795,7 +1795,7 @@ nsXPCWrappedJSClass::DebugDump(PRInt16 d
 {
 #ifdef DEBUG
     depth-- ;
-    XPC_LOG_ALWAYS(("nsXPCWrappedJSClass @ %x with mRefCnt = %d", this, mRefCnt.get()));
+    XPC_LOG_ALWAYS(("nsXPCWrappedJSClass @ %x", this));
     XPC_LOG_INDENT();
         char* name;
         mInfo->GetName(&name);
diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -837,12 +837,6 @@ XPCWrappedNative::Init(XPCCallContext& c
         mFlatJSObject = nsnull;
         return JS_FALSE;
     }
-
-    // This reference will be released when mFlatJSObject is finalized.
-    // Since this reference will push the refcount to 2 it will also root
-    // mFlatJSObject;
-    NS_ASSERTION(1 == mRefCnt, "unexpected refcount value");
-    NS_ADDREF(this);
 
     if(si && si->GetFlags().WantCreate() &&
        NS_FAILED(si->GetCallback()->Create(this, ccx, mFlatJSObject)))
@@ -2654,7 +2648,7 @@ NS_IMETHODIMP XPCWrappedNative::DebugDum
 {
 #ifdef DEBUG
     depth-- ;
-    XPC_LOG_ALWAYS(("XPCWrappedNative @ %x with mRefCnt = %d", this, mRefCnt.get()));
+    XPC_LOG_ALWAYS(("XPCWrappedNative @ %x", this));
     XPC_LOG_INDENT();
 
         if(HasProto())
diff --git a/js/src/xpconnect/src/xpcwrappednativescope.cpp b/js/src/xpconnect/src/xpcwrappednativescope.cpp
--- a/js/src/xpconnect/src/xpcwrappednativescope.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp
@@ -348,36 +348,6 @@ XPCWrappedNativeScope::GetPrototypeNoHel
     }
 
     return mPrototypeNoHelper;
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-WrappedNativeJSGCThingTracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                             uint32 number, void *arg)
-{
-    XPCWrappedNative* wrapper = ((Native2WrappedNativeMap::Entry*)hdr)->value;
-    if(wrapper->HasExternalReference() && !wrapper->IsWrapperExpired())
-    {
-        JSTracer* trc = (JSTracer *)arg;
-        JS_CALL_OBJECT_TRACER(trc, wrapper->GetFlatJSObject(),
-                              "XPCWrappedNative::mFlatJSObject");
-    }
-
-    return JS_DHASH_NEXT;
-}
-
-// static
-void
-XPCWrappedNativeScope::TraceJS(JSTracer* trc, XPCJSRuntime* rt)
-{
-    // FIXME The lock may not be necessary during tracing as that serializes
-    // access to JS runtime. See bug 380139.
-    XPCAutoLock lock(rt->GetMapLock());
-
-    // Do JS_CallTracer for all wrapped natives with external references.
-    for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext)
-    {
-        cur->mWrappedNativeMap->Enumerate(WrappedNativeJSGCThingTracer, trc);
-    }
 }
 
 // static
diff --git a/js/src/xpconnect/tests/components/xpctest_noisy.cpp b/js/src/xpconnect/tests/components/xpctest_noisy.cpp
--- a/js/src/xpconnect/tests/components/xpctest_noisy.cpp
+++ b/js/src/xpconnect/tests/components/xpctest_noisy.cpp
@@ -60,28 +60,6 @@ int xpctestNoisy::sID = 0;
 int xpctestNoisy::sID = 0;
 int xpctestNoisy::sCount = 0;
 
-
-NS_IMETHODIMP_(nsrefcnt) xpctestNoisy::AddRef(void)
-{
-  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
-  ++mRefCnt;
-  NS_LOG_ADDREF(this, mRefCnt, "xpctestNoisy", sizeof(*this));
-  printf("Noisy %d - incremented refcount to %d\n", mID, mRefCnt.get());
-  return mRefCnt;
-}
-
-NS_IMETHODIMP_(nsrefcnt) xpctestNoisy::Release(void)
-{
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-  --mRefCnt;
-  printf("Noisy %d - decremented refcount to %d\n", mID, mRefCnt.get());
-  NS_LOG_RELEASE(this, mRefCnt, "xpctestNoisy");
-  if (mRefCnt == 0) {
-    NS_DELETEXPCOM(this);
-    return 0;
-  }
-  return mRefCnt;
-}
 
 NS_IMETHODIMP
 xpctestNoisy::QueryInterface(REFNSIID iid, void** result)
diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -258,7 +258,6 @@ nsLayoutStatics::Shutdown()
   nsDOMStorageManager::Shutdown();
   txMozillaXSLTProcessor::Shutdown();
   nsDOMAttribute::Shutdown();
-  nsDOMEventRTTearoff::Shutdown();
   nsEventListenerManager::Shutdown();
   nsContentList::Shutdown();
   nsComputedDOMStyle::Shutdown();
@@ -305,7 +304,6 @@ nsLayoutStatics::Shutdown()
 
   nsAttrValue::Shutdown();
   nsContentUtils::Shutdown();
-  nsNodeInfo::ClearCache();
   nsLayoutStylesheetCache::Shutdown();
   NS_NameSpaceManagerShutdown();
   nsStyleSet::FreeGlobals();
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -849,18 +849,6 @@ nsHTMLScrollFrame::Reflow(nsPresContext*
   return rv;
 }
 
-NS_IMETHODIMP_(nsrefcnt) 
-nsHTMLScrollFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsHTMLScrollFrame::Release(void)
-{
-    return NS_OK;
-}
-
 #ifdef NS_DEBUG
 NS_IMETHODIMP
 nsHTMLScrollFrame::GetFrameName(nsAString& aResult) const
@@ -1195,18 +1183,6 @@ nsXULScrollFrame::GetMinWidth(nsIRenderi
 }
 #endif
 
-NS_IMETHODIMP_(nsrefcnt) 
-nsXULScrollFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsXULScrollFrame::Release(void)
-{
-    return NS_OK;
-}
-
 #ifdef NS_DEBUG
 NS_IMETHODIMP
 nsXULScrollFrame::GetFrameName(nsAString& aResult) const
@@ -1279,16 +1255,6 @@ nsGfxScrollFrameInner::nsGfxScrollFrameI
 
 nsGfxScrollFrameInner::~nsGfxScrollFrameInner()
 {
-}
-
-NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::AddRef(void)
-{
-  return 2;
-}
-
-NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::Release(void)
-{
-  return 1;
 }
 
 NS_IMPL_QUERY_INTERFACE1(nsGfxScrollFrameInner, nsIScrollPositionListener)
diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -66,8 +66,6 @@ class nsGfxScrollFrameInner : public nsI
                               public nsIReflowCallback {
 public:
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
 
   nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aIsRoot,
                         PRBool aIsXUL);
diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -4038,44 +4038,12 @@ NS_INTERFACE_MAP_END
 NS_INTERFACE_MAP_END
 
 
-NS_IMETHODIMP_(nsrefcnt)
-nsTypedSelection::AddRef()
-{
-  if (mFrameSelection) {
-    return mFrameSelection->AddRef();
-  }
-  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
-  NS_ASSERT_OWNINGTHREAD(nsTypedSelection);
-  ++mRefCnt;
-  NS_LOG_ADDREF(this, mRefCnt, "nsTypedSelection", sizeof(*this));
-  return mRefCnt;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsTypedSelection::Release()
-{
-  if (mFrameSelection) {
-    return mFrameSelection->Release();
-  }
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-  NS_ASSERT_OWNINGTHREAD(nsTypedSelection);
-  --mRefCnt;
-  NS_LOG_RELEASE(this, mRefCnt, "nsTypedSelection");
-  if (mRefCnt == 0) {
-    mRefCnt = 1; /* stabilize */
-    NS_DELETEXPCOM(this);
-    return 0;
-  }
-  return mRefCnt;
-}
-
 NS_IMETHODIMP
 nsTypedSelection::SetPresShell(nsIPresShell *aPresShell)
 {
   mPresShellWeak = do_GetWeakReference(aPresShell);
   return NS_OK;
 }
-
 
 
 NS_IMETHODIMP
diff --git a/layout/style/nsCSSDeclaration.h b/layout/style/nsCSSDeclaration.h
--- a/layout/style/nsCSSDeclaration.h
+++ b/layout/style/nsCSSDeclaration.h
@@ -55,7 +55,7 @@
 #include "nsCSSDataBlock.h"
 #include "nsCSSStruct.h"
 
-class nsCSSDeclaration {
+class nsCSSDeclaration : public XPCOMGCFinalizedObject {
 public:
   /**
    * Construct an |nsCSSDeclaration| that is in an invalid state (null
@@ -221,28 +221,19 @@ private:
                                           nsAString& aResult) const;
 
 private:
-    //
-    // Specialized ref counting.
-    // We do not want everyone to ref count us, only the rules which hold
-    //  onto us (our well defined lifetime is when the last rule releases
-    //  us).
     // It's worth a comment here that the main nsCSSDeclaration is refcounted,
     //  but it's |mImportant| is not refcounted, but just owned by the
     //  non-important declaration.
     //
     friend class CSSStyleRuleImpl;
     void AddRef(void) {
-      ++mRefCnt;
+      NS_NOTREACHED("Stop!");
     }
     void Release(void) {
-      NS_ASSERTION(0 < mRefCnt, "bad Release");
-      if (0 == --mRefCnt) {
-        delete this;
-      }
+      NS_NOTREACHED("Stop!");
     }
 public:
     void RuleAbort(void) {
-      NS_ASSERTION(0 == mRefCnt, "bad RuleAbort");
       delete this;
     }
 private:
@@ -255,7 +246,6 @@ private:
 
 private:
     nsAutoTArray<PRUint8, 8> mOrder;
-    nsAutoRefCnt mRefCnt;
     nsCSSCompressedDataBlock *mData; // never null, except while expanded
     nsCSSCompressedDataBlock *mImportantData; // may be null
 };
diff --git a/layout/style/nsCSSRule.cpp b/layout/style/nsCSSRule.cpp
--- a/layout/style/nsCSSRule.cpp
+++ b/layout/style/nsCSSRule.cpp
@@ -42,15 +42,13 @@
 #include "nsICSSStyleSheet.h"
 
 nsCSSRule::nsCSSRule(void)
-  : mRefCnt(0),
-    mSheet(nsnull),
+  : mSheet(nsnull),
     mParentRule(nsnull)
 {
 }
 
 nsCSSRule::nsCSSRule(const nsCSSRule& aCopy)
-  : mRefCnt(0),
-    mSheet(aCopy.mSheet),
+  : mSheet(aCopy.mSheet),
     mParentRule(aCopy.mParentRule)
 {
 }
diff --git a/layout/style/nsCSSRule.h b/layout/style/nsCSSRule.h
--- a/layout/style/nsCSSRule.h
+++ b/layout/style/nsCSSRule.h
@@ -48,17 +48,13 @@ struct nsRuleData;
 struct nsRuleData;
 class nsICSSGroupRule;
 
-class nsCSSRule {
+class nsCSSRule : public XPCOMGCFinalizedObject {
 public:
   nsCSSRule(void);
   nsCSSRule(const nsCSSRule& aCopy);
   virtual ~nsCSSRule(void);
 
-  // for implementing nsISupports
-  NS_IMETHOD_(nsrefcnt) AddRef();
-  NS_IMETHOD_(nsrefcnt) Release();
 protected:
-  nsAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 public:
 
diff --git a/layout/style/nsCSSStyleRule.cpp b/layout/style/nsCSSStyleRule.cpp
--- a/layout/style/nsCSSStyleRule.cpp
+++ b/layout/style/nsCSSStyleRule.cpp
@@ -864,11 +864,6 @@ public:
                                             nsICSSParser** aCSSParser);
   virtual nsresult DeclarationChanged();
 
-  // Override |AddRef| and |Release| for being a member of
-  // |DOMCSSStyleRuleImpl|.
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
-
   friend class DOMCSSStyleRuleImpl;
 
 protected:
diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp
--- a/layout/style/nsCSSStyleSheet.cpp
+++ b/layout/style/nsCSSStyleSheet.cpp
@@ -624,7 +624,6 @@ nsCSSStyleSheetInner::RebuildNameSpaces(
 
 nsCSSStyleSheet::nsCSSStyleSheet()
   : nsICSSStyleSheet(),
-    mRefCnt(0),
     mTitle(), 
     mMedia(nsnull),
     mFirstChild(nsnull), 
@@ -649,7 +648,6 @@ nsCSSStyleSheet::nsCSSStyleSheet(const n
                                  nsIDocument* aDocumentToUse,
                                  nsIDOMNode* aOwningNodeToUse)
   : nsICSSStyleSheet(),
-    mRefCnt(0),
     mTitle(aCopy.mTitle), 
     mMedia(nsnull),
     mFirstChild(nsnull), 
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -81,29 +81,15 @@
  * returned by the getComputedStyle() function.
  */
 
-static nsComputedDOMStyle *sCachedComputedDOMStyle;
-
 nsresult
 NS_NewComputedDOMStyle(nsIComputedDOMStyle** aComputedStyle)
 {
   NS_ENSURE_ARG_POINTER(aComputedStyle);
 
-  if (sCachedComputedDOMStyle) {
-    // There's an unused nsComputedDOMStyle cached, use it.
-    // But before we use it, re-initialize the object.
+  // No nsComputedDOMStyle cached, create a new one.
 
-    // Oh yeah baby, placement new!
-    *aComputedStyle = new (sCachedComputedDOMStyle) nsComputedDOMStyle();
-
-    sCachedComputedDOMStyle = nsnull;
-  } else {
-    // No nsComputedDOMStyle cached, create a new one.
-
-    *aComputedStyle = new nsComputedDOMStyle();
-    NS_ENSURE_TRUE(*aComputedStyle, NS_ERROR_OUT_OF_MEMORY);
-  }
-
-  NS_ADDREF(*aComputedStyle);
+  *aComputedStyle = new nsComputedDOMStyle();
+  NS_ENSURE_TRUE(*aComputedStyle, NS_ERROR_OUT_OF_MEMORY);
 
   return NS_OK;
 }
@@ -130,12 +116,6 @@ void
 void
 nsComputedDOMStyle::Shutdown()
 {
-  // We want to de-allocate without calling the dtor since we
-  // already did that manually in doDestroyComputedDOMStyle(),
-  // so cast our cached object to something that doesn't know
-  // about our dtor.
-  delete reinterpret_cast<char*>(sCachedComputedDOMStyle);
-  sCachedComputedDOMStyle = nsnull;
 }
 
 
@@ -149,26 +129,6 @@ NS_INTERFACE_MAP_BEGIN(nsComputedDOMStyl
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIComputedDOMStyle)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ComputedCSSStyleDeclaration)
 NS_INTERFACE_MAP_END
-
-
-static void doDestroyComputedDOMStyle(nsComputedDOMStyle *aComputedStyle)
-{
-  if (!sCachedComputedDOMStyle) {
-    // The cache is empty, store aComputedStyle in the cache.
-
-    sCachedComputedDOMStyle = aComputedStyle;
-    sCachedComputedDOMStyle->~nsComputedDOMStyle();
-  } else {
-    // The cache is full, delete aComputedStyle
-
-    delete aComputedStyle;
-  }
-}
-
-NS_IMPL_ADDREF(nsComputedDOMStyle)
-NS_IMPL_RELEASE_WITH_DESTROY(nsComputedDOMStyle,
-                             doDestroyComputedDOMStyle(this))
-
 
 NS_IMETHODIMP
 nsComputedDOMStyle::Init(nsIDOMElement *aElement,
diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -56,7 +56,7 @@
 #include "nsWeakReference.h"
 #include "nsAutoPtr.h"
 
-class nsComputedDOMStyle : public nsIComputedDOMStyle
+class nsComputedDOMStyle : public XPCOMGCFinalizedObject, public nsIComputedDOMStyle
 {
 public:
   NS_DECL_ISUPPORTS
diff --git a/layout/style/nsDOMCSSAttrDeclaration.h b/layout/style/nsDOMCSSAttrDeclaration.h
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -55,10 +55,6 @@ public:
   nsDOMCSSAttributeDeclaration(nsIContent *aContent);
   ~nsDOMCSSAttributeDeclaration();
 
-  // impl AddRef/Release; QI is implemented by our parent class
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
-
   virtual void DropReference();
   // If GetCSSDeclaration returns non-null, then the decl it returns
   // is owned by our current style rule.
@@ -74,9 +70,6 @@ protected:
 protected:
   virtual nsresult DeclarationChanged();
   
-  nsAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-
   nsIContent *mContent;
 };
 
diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -358,18 +358,6 @@ CSS2PropertiesTearoff::~CSS2PropertiesTe
 {
 }
 
-NS_IMETHODIMP_(nsrefcnt)
-CSS2PropertiesTearoff::AddRef(void)
-{
-  return mOuter->AddRef();
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-CSS2PropertiesTearoff::Release(void)
-{
-  return mOuter->Release();
-}
-
 NS_IMETHODIMP
 CSS2PropertiesTearoff::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -64,7 +64,7 @@ private:
   nsICSSDeclaration* mOuter;
 };
 
-class nsDOMCSSDeclaration : public nsICSSDeclaration
+class nsDOMCSSDeclaration : public XPCOMGCFinalizedObject, public nsICSSDeclaration
 {
 public:
   nsDOMCSSDeclaration();
diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp
--- a/layout/style/nsHTMLCSSStyleSheet.cpp
+++ b/layout/style/nsHTMLCSSStyleSheet.cpp
@@ -391,7 +391,6 @@ protected:
 
 HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl()
   : nsIHTMLCSSStyleSheet(),
-    mRefCnt(0),
     mURL(nsnull),
     mDocument(nsnull),
     mFirstLineRule(nsnull),
diff --git a/layout/svg/base/src/nsSVGGlyphFrame.h b/layout/svg/base/src/nsSVGGlyphFrame.h
--- a/layout/svg/base/src/nsSVGGlyphFrame.h
+++ b/layout/svg/base/src/nsSVGGlyphFrame.h
@@ -53,7 +53,8 @@ typedef nsSVGGeometryFrame nsSVGGlyphFra
 typedef nsSVGGeometryFrame nsSVGGlyphFrameBase;
 
 class nsSVGGlyphFrame : public nsSVGGlyphFrameBase,
-                        public nsISVGGlyphFragmentLeaf, // : nsISVGGlyphFragmentNode
+                        public nsISVGGlyphFragmentLeaf,
+                   // : nsISVGGlyphFragmentNode
                         public nsISVGChildFrame
 {
   friend nsIFrame*
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -65,15 +65,6 @@ nsTableRowGroupFrame::~nsTableRowGroupFr
 }
 
 /* ----------- nsTableRowGroupFrame ---------- */
-nsrefcnt nsTableRowGroupFrame::AddRef(void)
-{
-  return 1;//implementation of nsLineIterator
-}
-
-nsrefcnt nsTableRowGroupFrame::Release(void)
-{
-  return 1;//implementation of nsLineIterator
-}
 
 NS_IMETHODIMP
 nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
diff --git a/layout/xul/base/src/nsDocElementBoxFrame.cpp b/layout/xul/base/src/nsDocElementBoxFrame.cpp
--- a/layout/xul/base/src/nsDocElementBoxFrame.cpp
+++ b/layout/xul/base/src/nsDocElementBoxFrame.cpp
@@ -149,18 +149,6 @@ nsDocElementBoxFrame::CreateAnonymousCon
   return NS_OK;
 }
 
-NS_IMETHODIMP_(nsrefcnt) 
-nsDocElementBoxFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsDocElementBoxFrame::Release(void)
-{
-  return NS_OK;
-}
-
 NS_INTERFACE_MAP_BEGIN(nsDocElementBoxFrame)
   NS_INTERFACE_MAP_ENTRY(nsIAnonymousContentCreator)
 NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
diff --git a/layout/xul/base/src/nsListBoxBodyFrame.cpp b/layout/xul/base/src/nsListBoxBodyFrame.cpp
--- a/layout/xul/base/src/nsListBoxBodyFrame.cpp
+++ b/layout/xul/base/src/nsListBoxBodyFrame.cpp
@@ -204,20 +204,6 @@ nsListBoxBodyFrame::~nsListBoxBodyFrame(
   mAutoScrollTimer = nsnull;
 #endif
 
-}
-
-////////// nsISupports /////////////////
-
-NS_IMETHODIMP_(nsrefcnt) 
-nsListBoxBodyFrame::AddRef(void)
-{
-  return 2;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsListBoxBodyFrame::Release(void)
-{
-  return 1;
 }
 
 //
diff --git a/layout/xul/base/src/nsListItemFrame.cpp b/layout/xul/base/src/nsListItemFrame.cpp
--- a/layout/xul/base/src/nsListItemFrame.cpp
+++ b/layout/xul/base/src/nsListItemFrame.cpp
@@ -43,18 +43,6 @@
 #include "nsINameSpaceManager.h" 
 #include "nsGkAtoms.h"
 #include "nsDisplayList.h"
-
-NS_IMETHODIMP_(nsrefcnt) 
-nsListItemFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsListItemFrame::Release(void)
-{
-  return NS_OK;
-}
 
 NS_INTERFACE_MAP_BEGIN(nsListItemFrame)
 NS_INTERFACE_MAP_END_INHERITING(nsGridRowLeafFrame)
diff --git a/layout/xul/base/src/nsMenuFrame.cpp b/layout/xul/base/src/nsMenuFrame.cpp
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -165,18 +165,6 @@ NS_NewMenuFrame(nsIPresShell* aPresShell
     it->SetIsMenu(PR_TRUE);
 
   return it;
-}
-
-NS_IMETHODIMP_(nsrefcnt) 
-nsMenuFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsMenuFrame::Release(void)
-{
-    return NS_OK;
 }
 
 //
diff --git a/layout/xul/base/src/nsRootBoxFrame.cpp b/layout/xul/base/src/nsRootBoxFrame.cpp
--- a/layout/xul/base/src/nsRootBoxFrame.cpp
+++ b/layout/xul/base/src/nsRootBoxFrame.cpp
@@ -333,18 +333,6 @@ nsRootBoxFrame::RemoveTooltipSupport(nsI
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP_(nsrefcnt) 
-nsRootBoxFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsRootBoxFrame::Release(void)
-{
-  return NS_OK;
-}
-
 NS_INTERFACE_MAP_BEGIN(nsRootBoxFrame)
   NS_INTERFACE_MAP_ENTRY(nsIRootBox)
 NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
diff --git a/layout/xul/base/src/nsSplitterFrame.cpp b/layout/xul/base/src/nsSplitterFrame.cpp
--- a/layout/xul/base/src/nsSplitterFrame.cpp
+++ b/layout/xul/base/src/nsSplitterFrame.cpp
@@ -273,7 +273,6 @@ nsSplitterFrame::Destroy()
   if (mInner) {
     mInner->RemoveListener();
     mInner->Disconnect();
-    mInner->Release();
     mInner = nsnull;
   }
   nsBoxFrame::Destroy();
@@ -338,7 +337,6 @@ nsSplitterFrame::Init(nsIContent*      a
   if (!mInner)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  mInner->AddRef();
   mInner->mChildInfosAfter = nsnull;
   mInner->mChildInfosBefore = nsnull;
   mInner->mState = nsSplitterFrameInner::Open;
diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -176,18 +176,6 @@ nsTreeBodyFrame::~nsTreeBodyFrame()
   delete mSlots;
 }
 
-NS_IMETHODIMP_(nsrefcnt) 
-nsTreeBodyFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsTreeBodyFrame::Release(void)
-{
-  return NS_OK;
-}
-
 static void
 GetBorderPadding(nsStyleContext* aContext, nsMargin& aMargin)
 {
diff --git a/layout/xul/base/src/tree/src/nsTreeColFrame.cpp b/layout/xul/base/src/tree/src/nsTreeColFrame.cpp
--- a/layout/xul/base/src/tree/src/nsTreeColFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeColFrame.cpp
@@ -63,18 +63,6 @@ NS_NewTreeColFrame(nsIPresShell* aPresSh
 {
   return new (aPresShell) nsTreeColFrame(aPresShell, aContext, aIsRoot, aLayoutManager);
 } // NS_NewTreeColFrame
-
-NS_IMETHODIMP_(nsrefcnt) 
-nsTreeColFrame::AddRef(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsTreeColFrame::Release(void)
-{
-  return NS_OK;
-}
 
 //
 // QueryInterface
diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -133,32 +133,12 @@ nsJAR::nsJAR(): mManifestData(nsnull, ns
 
 nsJAR::~nsJAR()
 {
+  mCache->ReleaseZip(this);
   Close();
 }
 
 NS_IMPL_THREADSAFE_QUERY_INTERFACE2(nsJAR, nsIZipReader, nsIJAR)
 NS_IMPL_THREADSAFE_ADDREF(nsJAR)
-
-// Custom Release method works with nsZipReaderCache...
-nsrefcnt nsJAR::Release(void) 
-{
-  nsrefcnt count; 
-  NS_PRECONDITION(0 != mRefCnt, "dup release"); 
-  count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); 
-  NS_LOG_RELEASE(this, count, "nsJAR"); 
-  if (0 == count) {
-    mRefCnt = 1; /* stabilize */ 
-    /* enable this to find non-threadsafe destructors: */ 
-    /* NS_ASSERT_OWNINGTHREAD(nsJAR); */ 
-    NS_DELETEXPCOM(this); 
-    return 0; 
-  }
-  else if (1 == count && mCache) {
-    nsresult rv = mCache->ReleaseZip(this);
-    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to release zip file");
-  }
-  return count; 
-} 
 
 //----------------------------------------------
 // nsIZipReader implementation
diff --git a/modules/libpref/src/nsPrefBranch.cpp b/modules/libpref/src/nsPrefBranch.cpp
--- a/modules/libpref/src/nsPrefBranch.cpp
+++ b/modules/libpref/src/nsPrefBranch.cpp
@@ -95,10 +95,8 @@ nsPrefBranch::nsPrefBranch(const char *a
   nsCOMPtr<nsIObserverService> observerService = 
            do_GetService("@mozilla.org/observer-service;1");
   if (observerService) {
-    ++mRefCnt;    // Our refcnt must be > 0 when we call this, or we'll get deleted!
     // add weak so we don't have to clean up at shutdown
     observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
-    --mRefCnt;
   }
 }
 
diff --git a/modules/plugin/base/src/nsPluginHostImpl.cpp b/modules/plugin/base/src/nsPluginHostImpl.cpp
--- a/modules/plugin/base/src/nsPluginHostImpl.cpp
+++ b/modules/plugin/base/src/nsPluginHostImpl.cpp
@@ -1331,7 +1331,7 @@ private:
 
   // local cached file, we save the content into local cache if browser cache is not available,
   // or plugin asks stream as file and it expects file extension until bug 90558 got fixed
-  nsIFile                 *mLocalCachedFile;
+  nsCOMPtr<nsIFile>         mLocalCachedFile;
   nsCOMPtr<nsIOutputStream> mFileCacheOutputStream;
   nsHashtable             *mDataForwardToRequest;
 
@@ -1712,7 +1712,6 @@ nsPluginStreamListenerPeer::nsPluginStre
   mPendingRequests = 0;
   mHaveFiredOnStartRequest = PR_FALSE;
   mDataForwardToRequest = nsnull;
-  mLocalCachedFile = nsnull;
 }
 
 
@@ -1738,25 +1737,9 @@ nsPluginStreamListenerPeer::~nsPluginStr
   if (mFileCacheOutputStream)
     mFileCacheOutputStream = nsnull;
 
-  // if we have mLocalCachedFile lets release it
-  // and it'll be fiscally remove if refcnt == 1
-  if (mLocalCachedFile) {
-    nsrefcnt refcnt;
-    NS_RELEASE2(mLocalCachedFile, refcnt);
-
-#ifdef PLUGIN_LOGGING
-    nsCAutoString filePath;
-    mLocalCachedFile->GetNativePath(filePath);
-
-    PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
-      ("LocalyCachedFile=%s has %d refcnt and will %s be deleted now\n",filePath.get(),refcnt,refcnt==1?"":"NOT"));
-#endif
-
-    if (refcnt == 1) {
-      mLocalCachedFile->Remove(PR_FALSE);
-      NS_RELEASE(mLocalCachedFile);
-    }
-  }
+  // XXXbsmedberg: previously we would do dark magic to see if anyone else
+  // was holding a reference to mLocalCachedFile and if not, we'd remove it.
+  // Now we just punt
 
   delete mDataForwardToRequest;
 }
@@ -1926,7 +1909,7 @@ nsPluginStreamListenerPeer::SetupPluginC
             (useExistingCacheFile =
              lp->mPluginStreamInfo->UseExistingPluginCacheFile(mPluginStreamInfo)))
         {
-            NS_ADDREF(mLocalCachedFile = lp->mLocalCachedFile);
+            mLocalCachedFile = lp->mLocalCachedFile;
         }
         NS_RELEASE(lp);
       }
@@ -1972,10 +1955,7 @@ nsPluginStreamListenerPeer::SetupPluginC
       return rv;
 
     // save the file.
-    CallQueryInterface(pluginTmp, &mLocalCachedFile); // no need to check return value, just addref
-    // add one extra refcnt, we can use NS_RELEASE2(mLocalCachedFile...) in dtor
-    // to remove this file when refcnt == 1
-    NS_ADDREF(mLocalCachedFile);
+    mLocalCachedFile = do_QueryInterface(pluginTmp);
   }
 
   // add this listenerPeer to list of stream peers for this instance
@@ -2403,7 +2383,7 @@ NS_IMETHODIMP nsPluginStreamListenerPeer
 
   // call OnFileAvailable if plugin requests stream type StreamType_AsFile or StreamType_AsFileOnly
   if (mStreamType >= nsPluginStreamType_AsFile) {
-    nsCOMPtr<nsIFile> localFile = do_QueryInterface(mLocalCachedFile);
+    nsCOMPtr<nsIFile> localFile = mLocalCachedFile;
     if (!localFile) {
       nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
       if (cacheChannel) {
@@ -6484,7 +6464,6 @@ NS_IMETHODIMP nsPluginHostImpl::Observe(
     OnShutdown();
     Destroy();
     UnloadUnusedLibraries();
-    sInst->Release();
   }
   if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
     NS_ASSERTION(someData &&
diff --git a/modules/plugin/tools/sdk/samples/simple/Makefile.in b/modules/plugin/tools/sdk/samples/simple/Makefile.in
--- a/modules/plugin/tools/sdk/samples/simple/Makefile.in
+++ b/modules/plugin/tools/sdk/samples/simple/Makefile.in
@@ -52,11 +52,9 @@ NO_DIST_INSTALL = 1
 NO_DIST_INSTALL = 1
 NO_INSTALL = 1
 
-CPPSRCS = nsScriptablePeer.cpp \
+CPPSRCS = \
           plugin.cpp \
           $(NULL)
-
-XPIDLSRCS = nsISimplePlugin.idl
 
 SHARED_LIBRARY_LIBS = ../common/$(LIB_PREFIX)plugingate_s.$(LIB_SUFFIX)
 
diff --git a/modules/plugin/tools/sdk/samples/simple/nsISimplePlugin.idl b/modules/plugin/tools/sdk/samples/simple/nsISimplePlugin.idl
deleted file mode 100644
--- a/modules/plugin/tools/sdk/samples/simple/nsISimplePlugin.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 "nsISupports.idl"
-
-[scriptable, uuid(482e1890-1fe5-11d5-9cf8-0060b0fbd8ac)]
-interface nsISimplePlugin : nsISupports {
-  readonly attribute string version;
-};
diff --git a/modules/plugin/tools/sdk/samples/simple/nsScriptablePeer.cpp b/modules/plugin/tools/sdk/samples/simple/nsScriptablePeer.cpp
deleted file mode 100644
--- a/modules/plugin/tools/sdk/samples/simple/nsScriptablePeer.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 ***** */
-
-// ==============================
-// ! Scriptability related code !
-// ==============================
-
-/////////////////////////////////////////////////////
-//
-// This file implements the nsScriptablePeer object
-// The native methods of this class are supposed to
-// be callable from JavaScript
-//
-#include "plugin.h"
-
-static NS_DEFINE_IID(kISimplePluginIID, NS_ISIMPLEPLUGIN_IID);
-static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID);
-static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
-
-nsScriptablePeer::nsScriptablePeer(nsPluginInstance* aPlugin)
-{
-  mPlugin = aPlugin;
-  mRefCnt = 0;
-}
-
-nsScriptablePeer::~nsScriptablePeer()
-{
-}
-
-// AddRef, Release and QueryInterface are common methods and must 
-// be implemented for any interface
-NS_IMETHODIMP_(nsrefcnt) nsScriptablePeer::AddRef() 
-{ 
-  ++mRefCnt; 
-  return mRefCnt; 
-} 
-
-NS_IMETHODIMP_(nsrefcnt) nsScriptablePeer::Release() 
-{ 
-  --mRefCnt; 
-  if (mRefCnt == 0) { 
-    delete this;
-    return 0; 
-  } 
-  return mRefCnt; 
-} 
-
-// here nsScriptablePeer should return three interfaces it can be asked for by their iid's
-// static casts are necessary to ensure that correct pointer is returned
-NS_IMETHODIMP nsScriptablePeer::QueryInterface(const nsIID& aIID, void** aInstancePtr) 
-{ 
-  if(!aInstancePtr) 
-    return NS_ERROR_NULL_POINTER; 
-
-  if(aIID.Equals(kISimplePluginIID)) {
-    *aInstancePtr = static_cast<nsISimplePlugin*>(this); 
-    AddRef();
-    return NS_OK;
-  }
-
-  if(aIID.Equals(kIClassInfoIID)) {
-    *aInstancePtr = static_cast<nsIClassInfo*>(this); 
-    AddRef();
-    return NS_OK;
-  }
-
-  if(aIID.Equals(kISupportsIID)) {
-    *aInstancePtr = static_cast<nsISupports*>((static_cast<nsISimplePlugin*>(this))); 
-    AddRef();
-    return NS_OK;
-  }
-
-  return NS_NOINTERFACE; 
-}
-
-void nsScriptablePeer::SetInstance(nsPluginInstance* plugin)
-{
-  mPlugin = plugin;
-}
-
-//
-// the following method will be callable from JavaScript
-//
-NS_IMETHODIMP nsScriptablePeer::GetVersion(char * *aVersion)
-{
-  if (mPlugin)
-    mPlugin->getVersion(aVersion);
-  return NS_OK;
-}
diff --git a/modules/plugin/tools/sdk/samples/simple/nsScriptablePeer.h b/modules/plugin/tools/sdk/samples/simple/nsScriptablePeer.h
deleted file mode 100644
--- a/modules/plugin/tools/sdk/samples/simple/nsScriptablePeer.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 ***** */
-
-// ==============================
-// ! Scriptability related code !
-// ==============================
-//
-// nsScriptablePeer - xpconnect scriptable peer
-//
-
-#ifndef __nsScriptablePeer_h__
-#define __nsScriptablePeer_h__
-
-#include "nsISimplePlugin.h"
-#include "nsIClassInfo.h"
-#include "nsIProgrammingLanguage.h"
-
-class nsPluginInstance;
-
-// We must implement nsIClassInfo because it signals the
-// Mozilla Security Manager to allow calls from JavaScript.
-
-class nsClassInfoMixin : public nsIClassInfo
-{
-  // These flags are used by the DOM and security systems to signal that 
-  // JavaScript callers are allowed to call this object's scritable methods.
-  NS_IMETHOD GetFlags(PRUint32 *aFlags)
-    {*aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT;
-     return NS_OK;}
-  NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage)
-    {*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
-     return NS_OK;}
-  // The rest of the methods can safely return error codes...
-  NS_IMETHOD GetInterfaces(PRUint32 *count, nsIID * **array)
-    {return NS_ERROR_NOT_IMPLEMENTED;}
-  NS_IMETHOD GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
-    {return NS_ERROR_NOT_IMPLEMENTED;}
-  NS_IMETHOD GetContractID(char * *aContractID)
-    {return NS_ERROR_NOT_IMPLEMENTED;}
-  NS_IMETHOD GetClassDescription(char * *aClassDescription)
-    {return NS_ERROR_NOT_IMPLEMENTED;}
-  NS_IMETHOD GetClassID(nsCID * *aClassID)
-    {return NS_ERROR_NOT_IMPLEMENTED;}
-  NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
-    {return NS_ERROR_NOT_IMPLEMENTED;}
-};
-
-class nsScriptablePeer : public nsISimplePlugin,
-                         public nsClassInfoMixin
-{
-public:
-  nsScriptablePeer(nsPluginInstance* plugin);
-  ~nsScriptablePeer();
-
-public:
-  // methods from nsISupports
-  NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); 
-  NS_IMETHOD_(nsrefcnt) AddRef(); 
-  NS_IMETHOD_(nsrefcnt) Release(); 
-
-protected: 
-  nsrefcnt mRefCnt;  
-
-public:
-  // native methods callable from JavaScript
-  NS_DECL_NSISIMPLEPLUGIN
-
-  void SetInstance(nsPluginInstance* plugin);
-
-protected:
-  nsPluginInstance* mPlugin;
-};
-
-#endif
diff --git a/modules/plugin/tools/sdk/samples/simple/plugin.cpp b/modules/plugin/tools/sdk/samples/simple/plugin.cpp
--- a/modules/plugin/tools/sdk/samples/simple/plugin.cpp
+++ b/modules/plugin/tools/sdk/samples/simple/plugin.cpp
@@ -36,13 +36,7 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "plugin.h"
-#include "nsIServiceManager.h"
-#include "nsIMemory.h"
-#include "nsISupportsUtils.h" // this is where some useful macros defined
-
-// service manager which will give the access to all public browser services
-// we will use memory service as an illustration
-nsIServiceManager * gServiceManager = NULL;
+#include <string.h>
 
 // Unix needs this
 #ifdef XP_UNIX
@@ -81,28 +75,11 @@ NPError NS_PluginGetValue(NPPVariable aV
 //
 NPError NS_PluginInitialize()
 {
-  // this is probably a good place to get the service manager
-  // note that Mozilla will add reference, so do not forget to release
-  nsISupports * sm = NULL;
-  
-  NPN_GetValue(NULL, NPNVserviceManager, &sm);
-
-  // Mozilla returns nsIServiceManager so we can use it directly; doing QI on
-  // nsISupports here can still be more appropriate in case something is changed 
-  // in the future so we don't need to do casting of any sort.
-  if(sm) {
-    sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void**)&gServiceManager);
-    NS_RELEASE(sm);
-  }
-  
   return NPERR_NO_ERROR;
 }
 
 void NS_PluginShutdown()
 {
-  // we should release the service manager
-  NS_IF_RELEASE(gServiceManager);
-  gServiceManager = NULL;
 }
 
 /////////////////////////////////////////////////////////////
@@ -130,20 +107,13 @@ void NS_DestroyPluginInstance(nsPluginIn
 //
 nsPluginInstance::nsPluginInstance(NPP aInstance) : nsPluginInstanceBase(),
   mInstance(aInstance),
-  mInitialized(FALSE),
-  mScriptablePeer(NULL)
+  mInitialized(FALSE)
 {
   mString[0] = '\0';
 }
 
 nsPluginInstance::~nsPluginInstance()
 {
-  // mScriptablePeer may be also held by the browser 
-  // so releasing it here does not guarantee that it is over
-  // we should take precaution in case it will be called later
-  // and zero its mPlugin member
-  mScriptablePeer->SetInstance(NULL);
-  NS_IF_RELEASE(mScriptablePeer);
 }
 
 NPBool nsPluginInstance::init(NPWindow* aWindow)
@@ -168,86 +138,12 @@ void nsPluginInstance::getVersion(char* 
 void nsPluginInstance::getVersion(char* *aVersion)
 {
   const char *ua = NPN_UserAgent(mInstance);
-  char*& version = *aVersion;
-
-  // although we can use NPAPI NPN_MemAlloc call to allocate memory:
-  //    version = (char*)NPN_MemAlloc(strlen(ua) + 1);
-  // for illustration purposed we use the service manager to access 
-  // the memory service provided by Mozilla
-  nsIMemory * nsMemoryService = NULL;
-  
-  if (gServiceManager) {
-    // get service using its contract id and use it to allocate the memory
-    gServiceManager->GetServiceByContractID("@mozilla.org/xpcom/memory-service;1", NS_GET_IID(nsIMemory), (void **)&nsMemoryService);
-    if(nsMemoryService)
-      version = (char *)nsMemoryService->Alloc(strlen(ua) + 1);
-  }
-
-  if (version)
-    strcpy(version, ua);
-
-  // release service
-  NS_IF_RELEASE(nsMemoryService);
+  *aVersion = (char*)NPN_MemAlloc(strlen(ua) + 1);
+  if (*aVersion)
+    strcpy(*aVersion, ua);
 }
 
-// ==============================
-// ! Scriptability related code !
-// ==============================
-//
-// here the plugin is asked by Mozilla to tell if it is scriptable
-// we should return a valid interface id and a pointer to 
-// nsScriptablePeer interface which we should have implemented
-// and which should be defined in the corressponding *.xpt file
-// in the bin/components folder
 NPError	nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue)
 {
-  NPError rv = NPERR_NO_ERROR;
-
-  switch (aVariable) {
-    case NPPVpluginScriptableInstance: {
-      // addref happens in getter, so we don't addref here
-      nsISimplePlugin * scriptablePeer = getScriptablePeer();
-      if (scriptablePeer) {
-        *(nsISupports **)aValue = scriptablePeer;
-      } else
-        rv = NPERR_OUT_OF_MEMORY_ERROR;
-    }
-    break;
-
-    case NPPVpluginScriptableIID: {
-      static nsIID scriptableIID = NS_ISIMPLEPLUGIN_IID;
-      nsIID* ptr = (nsIID *)NPN_MemAlloc(sizeof(nsIID));
-      if (ptr) {
-          *ptr = scriptableIID;
-          *(nsIID **)aValue = ptr;
-      } else
-        rv = NPERR_OUT_OF_MEMORY_ERROR;
-    }
-    break;
-
-    default:
-      break;
-  }
-
-  return rv;
+  return NPERR_NO_ERROR;
 }
-
-// ==============================
-// ! Scriptability related code !
-// ==============================
-//
-// this method will return the scriptable object (and create it if necessary)
-nsScriptablePeer* nsPluginInstance::getScriptablePeer()
-{
-  if (!mScriptablePeer) {
-    mScriptablePeer = new nsScriptablePeer(this);
-    if(!mScriptablePeer)
-      return NULL;
-
-    NS_ADDREF(mScriptablePeer);
-  }
-
-  // add reference for the caller requesting the object
-  NS_ADDREF(mScriptablePeer);
-  return mScriptablePeer;
-}
diff --git a/modules/plugin/tools/sdk/samples/simple/plugin.h b/modules/plugin/tools/sdk/samples/simple/plugin.h
--- a/modules/plugin/tools/sdk/samples/simple/plugin.h
+++ b/modules/plugin/tools/sdk/samples/simple/plugin.h
@@ -39,7 +39,6 @@
 #define __PLUGIN_H__
 
 #include "pluginbase.h"
-#include "nsScriptablePeer.h"
 
 class nsPluginInstance : public nsPluginInstanceBase
 {
@@ -59,12 +58,9 @@ public:
   // locals
   void getVersion(char* *aVersion);
 
-  nsScriptablePeer* getScriptablePeer();
-
 private:
   NPP mInstance;
   NPBool mInitialized;
-  nsScriptablePeer * mScriptablePeer;
 
 public:
   char mString[128];
diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -221,6 +221,7 @@ nsSocketInputStream::nsSocketInputStream
 
 nsSocketInputStream::~nsSocketInputStream()
 {
+    Close();
 }
 
 // called on the socket transport thread...
@@ -259,21 +260,6 @@ NS_IMPL_QUERY_INTERFACE2(nsSocketInputSt
 NS_IMPL_QUERY_INTERFACE2(nsSocketInputStream,
                          nsIInputStream,
                          nsIAsyncInputStream)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsSocketInputStream::AddRef()
-{
-    PR_AtomicIncrement((PRInt32*)&mReaderRefCnt);
-    return mTransport->AddRef();
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsSocketInputStream::Release()
-{
-    if (PR_AtomicDecrement((PRInt32*)&mReaderRefCnt) == 0)
-        Close();
-    return mTransport->Release();
-}
 
 NS_IMETHODIMP
 nsSocketInputStream::Close()
@@ -480,6 +466,7 @@ nsSocketOutputStream::nsSocketOutputStre
 
 nsSocketOutputStream::~nsSocketOutputStream()
 {
+  Close();
 }
 
 // called on the socket transport thread...
@@ -518,21 +505,6 @@ NS_IMPL_QUERY_INTERFACE2(nsSocketOutputS
 NS_IMPL_QUERY_INTERFACE2(nsSocketOutputStream,
                          nsIOutputStream,
                          nsIAsyncOutputStream)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsSocketOutputStream::AddRef()
-{
-    PR_AtomicIncrement((PRInt32*)&mWriterRefCnt);
-    return mTransport->AddRef();
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsSocketOutputStream::Release()
-{
-    if (PR_AtomicDecrement((PRInt32*)&mWriterRefCnt) == 0)
-        Close();
-    return mTransport->Release();
-}
 
 NS_IMETHODIMP
 nsSocketOutputStream::Close()
diff --git a/netwerk/base/src/nsStandardURL.h b/netwerk/base/src/nsStandardURL.h
--- a/netwerk/base/src/nsStandardURL.h
+++ b/netwerk/base/src/nsStandardURL.h
@@ -102,7 +102,7 @@ public: /* internal -- HPUX compiler can
     //
     // Pref observer
     //
-    class nsPrefObserver : public nsIObserver
+    class nsPrefObserver : public XPCOMGCObject, public nsIObserver
     {
     public:
         NS_DECL_ISUPPORTS
diff --git a/netwerk/build/nsNetModule.cpp b/netwerk/build/nsNetModule.cpp
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -180,9 +180,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeAbo
 
 #ifdef NECKO_PROTOCOL_about
 // about
-#ifdef NS_BUILD_REFCNT_LOGGING
-#include "nsAboutBloat.h"
-#endif
 #include "nsAboutCache.h"
 #include "nsAboutCacheEntry.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutCacheEntry)
@@ -1002,13 +999,6 @@ static const nsModuleComponentInfo gNetM
       nsAboutBlank::Create
     },
 #ifdef NECKO_PROTOCOL_about
-#ifdef NS_BUILD_REFCNT_LOGGING
-    { "about:bloat", 
-      NS_ABOUT_BLOAT_MODULE_CID,
-      NS_ABOUT_MODULE_CONTRACTID_PREFIX "bloat", 
-      nsAboutBloat::Create
-    },
-#endif
     { "about:cache", 
       NS_ABOUT_CACHE_MODULE_CID,
       NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache", 
diff --git a/netwerk/cookie/src/nsCookie.cpp b/netwerk/cookie/src/nsCookie.cpp
--- a/netwerk/cookie/src/nsCookie.cpp
+++ b/netwerk/cookie/src/nsCookie.cpp
@@ -44,30 +44,47 @@
  * string helper impl
  ******************************************************************************/
 
-// copy aSource strings into contiguous storage provided in aDest1,
-// providing terminating nulls for each destination string.
-static inline void
-StrBlockCopy(const nsACString &aSource1,
-             const nsACString &aSource2,
-             const nsACString &aSource3,
-             const nsACString &aSource4,
-             char             *&aDest1,
-             char             *&aDest2,
-             char             *&aDest3,
-             char             *&aDest4,
-             char             *&aDestEnd)
+// copy a string into a pre-allocated buffer, updating the buffer pointer.
+static void
+WriteString(const nsACString &s,
+            char *&dbuf)
 {
-  char *toBegin = aDest1;
-  nsACString::const_iterator fromBegin, fromEnd;
+    const char *sbuf;
+    PRUint32 size = s.GetData(&sbuf);
+    memcpy(dbuf, sbuf, size);
+    dbuf[size] = '\0';
+    dbuf += size + 1;
+}
 
-  *copy_string(aSource1.BeginReading(fromBegin), aSource1.EndReading(fromEnd), toBegin) = char(0);
-  aDest2 = ++toBegin;
-  *copy_string(aSource2.BeginReading(fromBegin), aSource2.EndReading(fromEnd), toBegin) = char(0);
-  aDest3 = ++toBegin;
-  *copy_string(aSource3.BeginReading(fromBegin), aSource3.EndReading(fromEnd), toBegin) = char(0);
-  aDest4 = ++toBegin;
-  *copy_string(aSource4.BeginReading(fromBegin), aSource4.EndReading(fromEnd), toBegin) = char(0);
-  aDestEnd = toBegin;
+nsCookie::nsCookie(const nsACString &aName,
+                   const nsACString &aValue,
+                   const nsACString &aHost,
+                   const nsACString &aPath,
+                   PRInt64         aExpiry,
+                   PRInt64         aLastAccessed,
+                   PRInt64         aCreationID,
+                   PRBool          aIsSession,
+                   PRBool          aIsSecure,
+                   PRBool          aIsHttpOnly)
+    : mNext(nsnull)
+    , mExpiry(aExpiry)
+    , mLastAccessed(aLastAccessed)
+    , mCreationID(aCreationID)
+    , mIsSession(aIsSession != PR_FALSE)
+    , mIsSecure(aIsSecure != PR_FALSE)
+    , mIsHttpOnly(aIsHttpOnly != PR_FALSE)
+{
+    char *dest = mStringBuffer;
+
+    mName = dest;
+    WriteString(aName, dest);
+    mValue = dest;
+    WriteString(aValue, dest);
+    mHost = dest;
+    WriteString(aHost, dest);
+    mPath = dest;
+    WriteString(aPath, dest);
+    mEnd = dest - 1;
 }
 
 /******************************************************************************
@@ -95,21 +112,9 @@ nsCookie::Create(const nsACString &aName
                  PRBool            aIsSecure,
                  PRBool            aIsHttpOnly)
 {
-  // find the required string buffer size, adding 4 for the terminating nulls
+  // find the required string buffer size
   const PRUint32 stringLength = aName.Length() + aValue.Length() +
-                                aHost.Length() + aPath.Length() + 4;
-
-  // allocate contiguous space for the nsCookie and its strings -
-  // we store the strings in-line with the nsCookie to save allocations
-  void *place = ::operator new(sizeof(nsCookie) + stringLength);
-  if (!place)
-    return nsnull;
-
-  // assign string members
-  char *name, *value, *host, *path, *end;
-  name = static_cast<char *>(place) + sizeof(nsCookie);
-  StrBlockCopy(aName, aValue, aHost, aPath,
-               name, value, host, path, end);
+                                aHost.Length() + aPath.Length();
 
   // check if the creation id given to us is greater than the running maximum
   // (it should always be monotonically increasing). if it's not, make up our own.
@@ -119,9 +124,10 @@ nsCookie::Create(const nsACString &aName
     aCreationID = ++gLastCreationID;
 
   // construct the cookie. placement new, oh yeah!
-  return new (place) nsCookie(name, value, host, path, end,
-                              aExpiry, aLastAccessed, aCreationID,
-                              aIsSession, aIsSecure, aIsHttpOnly);
+  return new (NS_GetGC(), stringLength)
+      nsCookie(aName, aValue, aHost, aPath,
+               aExpiry, aLastAccessed, aCreationID,
+               aIsSession, aIsSecure, aIsHttpOnly);
 }
 
 /******************************************************************************
diff --git a/netwerk/cookie/src/nsCookie.h b/netwerk/cookie/src/nsCookie.h
--- a/netwerk/cookie/src/nsCookie.h
+++ b/netwerk/cookie/src/nsCookie.h
@@ -54,7 +54,7 @@
  * implementation
  ******************************************************************************/
 
-class nsCookie : public nsICookie2
+class nsCookie : public MMgc::GCObject, public nsICookie2
 {
   public:
     // nsISupports
@@ -64,35 +64,24 @@ class nsCookie : public nsICookie2
 
   private:
     // for internal use only. see nsCookie::Create().
-    nsCookie(const char     *aName,
-             const char     *aValue,
-             const char     *aHost,
-             const char     *aPath,
-             const char     *aEnd,
+    nsCookie(const nsACString &aName,
+             const nsACString &aValue,
+             const nsACString &aHost,
+             const nsACString &aPath,
              PRInt64         aExpiry,
              PRInt64         aLastAccessed,
              PRInt64         aCreationID,
              PRBool          aIsSession,
              PRBool          aIsSecure,
-             PRBool          aIsHttpOnly)
-     : mNext(nsnull)
-     , mName(aName)
-     , mValue(aValue)
-     , mHost(aHost)
-     , mPath(aPath)
-     , mEnd(aEnd)
-     , mExpiry(aExpiry)
-     , mLastAccessed(aLastAccessed)
-     , mCreationID(aCreationID)
-     , mIsSession(aIsSession != PR_FALSE)
-     , mIsSecure(aIsSecure != PR_FALSE)
-     , mIsHttpOnly(aIsHttpOnly != PR_FALSE)
-    {
+             PRBool          aIsHttpOnly);
+
+    // NOT IMPLEMENTED OR CALLED
+    ~nsCookie() {
+        NS_ERROR("Not called");
     }
 
   public:
-    // public helper to create an nsCookie object. use |operator delete|
-    // to destroy an object created by this method.
+    // public helper to create an nsCookie object
     static nsCookie * Create(const nsACString &aName,
                              const nsACString &aValue,
                              const nsACString &aHost,
@@ -103,8 +92,6 @@ class nsCookie : public nsICookie2
                              PRBool            aIsSession,
                              PRBool            aIsSecure,
                              PRBool            aIsHttpOnly);
-
-    virtual ~nsCookie() {}
 
     // fast (inline, non-xpcom) getters
     inline const nsDependentCString Name()  const { return nsDependentCString(mName, mValue - 1); }
@@ -152,6 +139,10 @@ class nsCookie : public nsICookie2
     PRPackedBool mIsSession;
     PRPackedBool mIsSecure;
     PRPackedBool mIsHttpOnly;
+
+    // The name/value/host/path data is allocated directly at the end of this
+    // object, with four bytes for terminating nulls
+    char mStringBuffer[4];
 };
 
 #endif // nsCookie_h__
diff --git a/netwerk/cookie/src/nsCookieService.cpp b/netwerk/cookie/src/nsCookieService.cpp
--- a/netwerk/cookie/src/nsCookieService.cpp
+++ b/netwerk/cookie/src/nsCookieService.cpp
@@ -948,15 +948,7 @@ nsCookieService::Read()
     if (!newCookie)
       return NS_ERROR_OUT_OF_MEMORY;
 
-    if (!AddCookieToList(newCookie, PR_FALSE))
-      // It is purpose that created us; purpose that connects us;
-      // purpose that pulls us; that guides us; that drives us.
-      // It is purpose that defines us; purpose that binds us.
-      // When a cookie no longer has purpose, it has a choice:
-      // it can return to the source to be deleted, or it can go
-      // into exile, and stay hidden inside the Matrix.
-      // Let's choose deletion.
-      delete newCookie;
+    (void) AddCookieToList(newCookie, PR_FALSE);
   }
 
   COOKIE_LOGSTRING(PR_LOG_DEBUG, ("Read(): %ld cookies read", mCookieCount));
@@ -1084,10 +1076,7 @@ nsCookieService::ImportCookies(nsIFile *
     // by successively decrementing the lastAccessed time
     lastAccessedCounter--;
 
-    if (originalCookieCount == 0)
-      AddCookieToList(newCookie);
-    else
-      AddInternal(newCookie, currentTime, nsnull, nsnull, PR_TRUE);
+    (void) AddCookieToList(newCookie);
   }
 
   COOKIE_LOGSTRING(PR_LOG_DEBUG, ("ImportCookies(): %ld cookies imported", mCookieCount));
diff --git a/netwerk/dns/src/nsHostResolver.cpp b/netwerk/dns/src/nsHostResolver.cpp
--- a/netwerk/dns/src/nsHostResolver.cpp
+++ b/netwerk/dns/src/nsHostResolver.cpp
@@ -166,7 +166,7 @@ nsHostRecord::Create(const nsHostKey *ke
     size_t hostLen = strlen(key->host) + 1;
     size_t size = hostLen + sizeof(nsHostRecord);
 
-    nsHostRecord *rec = (nsHostRecord*) ::operator new(size);
+    nsHostRecord *rec = (nsHostRecord*) MMgc::GCFinalizedObject::operator new(size, NS_GetGC());
     if (!rec) {
         PR_DestroyLock(lock);
         return NS_ERROR_OUT_OF_MEMORY;
@@ -176,8 +176,6 @@ nsHostRecord::Create(const nsHostKey *ke
     rec->flags = RES_KEY_FLAGS(key->flags);
     rec->af = key->af;
 
-    rec->_refc = 1; // addref
-    NS_LOG_ADDREF(rec, 1, "nsHostRecord", sizeof(nsHostRecord));
     rec->addr_info_lock = lock;
     rec->addr_info = nsnull;
     rec->addr_info_gencnt = 0;
diff --git a/netwerk/dns/src/nsHostResolver.h b/netwerk/dns/src/nsHostResolver.h
--- a/netwerk/dns/src/nsHostResolver.h
+++ b/netwerk/dns/src/nsHostResolver.h
@@ -51,22 +51,7 @@ class nsResolveHostCallback;
 class nsResolveHostCallback;
 
 /* XXX move this someplace more generic */
-#define NS_DECL_REFCOUNTED_THREADSAFE(classname)                             \
-  private:                                                                   \
-    nsAutoRefCnt _refc;                                                      \
-  public:                                                                    \
-    PRInt32 AddRef() {                                                       \
-        PRInt32 n = PR_AtomicIncrement((PRInt32*)&_refc);                    \
-        NS_LOG_ADDREF(this, n, #classname, sizeof(classname));               \
-        return n;                                                            \
-    }                                                                        \
-    PRInt32 Release() {                                                      \
-        PRInt32 n = PR_AtomicDecrement((PRInt32*)&_refc);                    \
-        NS_LOG_RELEASE(this, n, #classname);                                 \
-        if (n == 0)                                                          \
-            delete this;                                                     \
-        return n;                                                            \
-    }
+#define NS_DECL_REFCOUNTED_THREADSAFE(classname)
 
 struct nsHostKey
 {
@@ -78,7 +63,7 @@ struct nsHostKey
 /**
  * nsHostRecord - ref counted object type stored in host resolver cache.
  */
-class nsHostRecord : public PRCList, public nsHostKey
+class nsHostRecord : public XPCOMGCFinalizedObject, public PRCList, public nsHostKey
 {
 public:
     NS_DECL_REFCOUNTED_THREADSAFE(nsHostRecord)
@@ -155,7 +140,7 @@ public:
 /**
  * nsHostResolver - an asynchronous host name resolver.
  */
-class nsHostResolver
+class nsHostResolver : public XPCOMGCFinalizedObject
 {
 public:
     /**
diff --git a/netwerk/protocol/about/src/Makefile.in b/netwerk/protocol/about/src/Makefile.in
--- a/netwerk/protocol/about/src/Makefile.in
+++ b/netwerk/protocol/about/src/Makefile.in
@@ -54,7 +54,6 @@ CPPSRCS		= \
 CPPSRCS		= \
 		nsAboutProtocolHandler.cpp \
 		nsAboutBlank.cpp \
-		nsAboutBloat.cpp \
 		nsAboutCache.cpp \
 		nsAboutCacheEntry.cpp \
 		$(NULL)
diff --git a/netwerk/protocol/about/src/nsAboutBloat.cpp b/netwerk/protocol/about/src/nsAboutBloat.cpp
deleted file mode 100644
--- a/netwerk/protocol/about/src/nsAboutBloat.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 "nsTraceRefcntImpl.h"
-
-// if NS_BUILD_REFCNT_LOGGING isn't defined, don't try to build
-#ifdef NS_BUILD_REFCNT_LOGGING
-
-#include "nsAboutBloat.h"
-#include "nsIIOService.h"
-#include "nsIServiceManager.h"
-#include "nsStringStream.h"
-#include "nsXPIDLString.h"
-#include "nsIURI.h"
-#include "prtime.h"
-#include "nsCOMPtr.h"
-#include "nsIFileStreams.h"
-#include "nsNetUtil.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsILocalFile.h"
-
-#ifdef XP_MAC
-extern "C" void GC_gcollect(void);
-#else
-static void GC_gcollect() {}
-#endif
-
-NS_IMPL_ISUPPORTS1(nsAboutBloat, nsIAboutModule)
-
-NS_IMETHODIMP
-nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
-{
-    NS_ENSURE_ARG_POINTER(aURI);
-    nsresult rv;
-    nsCAutoString path;
-    rv = aURI->GetPath(path);
-    if (NS_FAILED(rv)) return rv;
-
-    nsTraceRefcntImpl::StatisticsType statType = nsTraceRefcntImpl::ALL_STATS;
-    PRBool clear = PR_FALSE;
-    PRBool leaks = PR_FALSE;
-
-    PRInt32 pos = path.Find("?");
-    if (pos > 0) {
-        nsCAutoString param;
-        (void)path.Right(param, path.Length() - (pos+1));
-        if (param.EqualsLiteral("new"))
-            statType = nsTraceRefcntImpl::NEW_STATS;
-        else if (param.EqualsLiteral("clear"))
-            clear = PR_TRUE;
-        else if (param.EqualsLiteral("leaks"))
-            leaks = PR_TRUE;
-    }
-
-    nsCOMPtr<nsIInputStream> inStr;
-    if (clear) {
-        nsTraceRefcntImpl::ResetStatistics();
-
-        const char* msg = "Bloat statistics cleared.";
-        rv = NS_NewCStringInputStream(getter_AddRefs(inStr), nsDependentCString(msg));
-        if (NS_FAILED(rv)) return rv;
-    }
-    else if (leaks) {
-        // dump the current set of leaks.
-        GC_gcollect();
-    	
-        const char* msg = "Memory leaks dumped.";
-        rv = NS_NewCStringInputStream(getter_AddRefs(inStr), nsDependentCString(msg));
-        if (NS_FAILED(rv)) return rv;
-    }
-    else {
-        nsCOMPtr<nsIFile> file;
-        rv = NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR, 
-                                    getter_AddRefs(file));       
-        if (NS_FAILED(rv)) return rv;
-
-        rv = file->AppendNative(NS_LITERAL_CSTRING("bloatlogs"));
-        if (NS_FAILED(rv)) return rv;
-
-        PRBool exists;
-        rv = file->Exists(&exists);
-        if (NS_FAILED(rv)) return rv;
-
-        if (!exists) {
-            // On all the platforms that I know use permissions,
-            // directories need to have the executable flag set
-            // if you want to do anything inside the directory.
-            rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
-            if (NS_FAILED(rv)) return rv;
-        }
-
-        nsCAutoString dumpFileName;
-        if (statType == nsTraceRefcntImpl::ALL_STATS)
-            dumpFileName.AssignLiteral("all-");
-        else
-            dumpFileName.AssignLiteral("new-");
-        PRExplodedTime expTime;
-        PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &expTime);
-        char time[128];
-        PR_FormatTimeUSEnglish(time, 128, "%Y-%m-%d-%H%M%S.txt", &expTime);
-        dumpFileName += time;
-        rv = file->AppendNative(dumpFileName);
-        if (NS_FAILED(rv)) return rv;
-
-        FILE* out;
-        nsCOMPtr<nsILocalFile> lfile = do_QueryInterface(file);
-        if (lfile == nsnull)
-            return NS_ERROR_FAILURE;
-        rv = lfile->OpenANSIFileDesc("w", &out);
-        if (NS_FAILED(rv)) return rv;
-
-        rv = nsTraceRefcntImpl::DumpStatistics(statType, out);
-        ::fclose(out);
-        if (NS_FAILED(rv)) return rv;
-
-        rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
-        if (NS_FAILED(rv)) return rv;
-    }
-
-    nsIChannel* channel;
-    rv = NS_NewInputStreamChannel(&channel, aURI, inStr,
-                                  NS_LITERAL_CSTRING("text/plain"),
-                                  NS_LITERAL_CSTRING("utf-8"));
-    if (NS_FAILED(rv)) return rv;
-
-    *result = channel;
-    return rv;
-}
-
-NS_IMETHODIMP
-nsAboutBloat::GetURIFlags(nsIURI *aURI, PRUint32 *result)
-{
-    *result = 0;
-    return NS_OK;
-}
-
-NS_METHOD
-nsAboutBloat::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
-{
-    nsAboutBloat* about = new nsAboutBloat();
-    if (about == nsnull)
-        return NS_ERROR_OUT_OF_MEMORY;
-    NS_ADDREF(about);
-    nsresult rv = about->QueryInterface(aIID, aResult);
-    NS_RELEASE(about);
-    return rv;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-#endif /* NS_BUILD_REFCNT_LOGGING */
diff --git a/netwerk/protocol/about/src/nsAboutBloat.h b/netwerk/protocol/about/src/nsAboutBloat.h
deleted file mode 100644
--- a/netwerk/protocol/about/src/nsAboutBloat.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 ***** */
-
-#ifndef nsAboutBloat_h__
-#define nsAboutBloat_h__
-
-#include "nsIAboutModule.h"
-
-class nsAboutBloat : public nsIAboutModule 
-{
-public:
-    NS_DECL_ISUPPORTS
-
-    NS_DECL_NSIABOUTMODULE
-
-    nsAboutBloat() {}
-    virtual ~nsAboutBloat() {}
-
-    static NS_METHOD
-    Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
-
-protected:
-};
-
-#define NS_ABOUT_BLOAT_MODULE_CID                    \
-{ /* f9666720-801f-11d3-9399-00104ba0fd40 */         \
-    0xf9666720,                                      \
-    0x801f,                                          \
-    0x11d3,                                          \
-    {0x93, 0x99, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
-}
-
-#endif // nsAboutBloat_h__
diff --git a/netwerk/protocol/http/src/nsHttpTransaction.cpp b/netwerk/protocol/http/src/nsHttpTransaction.cpp
--- a/netwerk/protocol/http/src/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/src/nsHttpTransaction.cpp
@@ -1032,62 +1032,10 @@ nsHttpTransaction::ProcessData(char *buf
 }
 
 //-----------------------------------------------------------------------------
-// nsHttpTransaction deletion event
-//-----------------------------------------------------------------------------
-
-class nsDeleteHttpTransaction : public nsRunnable {
-public:
-    nsDeleteHttpTransaction(nsHttpTransaction *trans)
-        : mTrans(trans)
-    {}
-
-    NS_IMETHOD Run()
-    {
-        delete mTrans;
-        return NS_OK;
-    }
-private:
-    nsHttpTransaction *mTrans;
-};
-
-void
-nsHttpTransaction::DeleteSelfOnConsumerThread()
-{
-    LOG(("nsHttpTransaction::DeleteSelfOnConsumerThread [this=%x]\n", this));
-    
-    PRBool val;
-    if (NS_SUCCEEDED(mConsumerTarget->IsOnCurrentThread(&val)) && val)
-        delete this;
-    else {
-        LOG(("proxying delete to consumer thread...\n"));
-        nsCOMPtr<nsIRunnable> event = new nsDeleteHttpTransaction(this);
-        if (NS_FAILED(mConsumerTarget->Dispatch(event, NS_DISPATCH_NORMAL)))
-            NS_WARNING("failed to dispatch nsHttpDeleteTransaction event");
-    }
-}
-
-//-----------------------------------------------------------------------------
 // nsHttpTransaction::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_THREADSAFE_ADDREF(nsHttpTransaction)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsHttpTransaction::Release()
-{
-    nsrefcnt count;
-    NS_PRECONDITION(0 != mRefCnt, "dup release");
-    count = PR_AtomicDecrement((PRInt32 *) &mRefCnt);
-    NS_LOG_RELEASE(this, count, "nsHttpTransaction");
-    if (0 == count) {
-        mRefCnt = 1; /* stablize */
-        // it is essential that the transaction be destroyed on the consumer 
-        // thread (we could be holding the last reference to our consumer).
-        DeleteSelfOnConsumerThread();
-        return 0;
-    }
-    return count;
-}
 
 NS_IMPL_THREADSAFE_QUERY_INTERFACE2(nsHttpTransaction,
                                     nsIInputStreamCallback,
diff --git a/rdf/base/src/nsCompositeDataSource.cpp b/rdf/base/src/nsCompositeDataSource.cpp
--- a/rdf/base/src/nsCompositeDataSource.cpp
+++ b/rdf/base/src/nsCompositeDataSource.cpp
@@ -146,7 +146,7 @@ protected:
 // CompositeEnumeratorImpl
 //
 
-class CompositeEnumeratorImpl : public nsISimpleEnumerator
+class CompositeEnumeratorImpl : public XPCOMGCObject, public nsISimpleEnumerator
 {
     // nsISupports
     NS_DECL_ISUPPORTS
@@ -160,8 +160,6 @@ class CompositeEnumeratorImpl : public n
 
     virtual nsresult
     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult) = 0;
-
-    virtual void Destroy() = 0;
 
 protected:
     CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
@@ -197,22 +195,9 @@ CompositeEnumeratorImpl::CompositeEnumer
 
 CompositeEnumeratorImpl::~CompositeEnumeratorImpl(void)
 {
-	if (mCoalesceDuplicateArcs == PR_TRUE)
-	{
-		for (PRInt32 i = mAlreadyReturned.Count() - 1; i >= 0; --i)
-		{
-			nsIRDFNode *node = (nsIRDFNode *) mAlreadyReturned[i];
-			NS_RELEASE(node);
-		}
-	}
-
-	NS_IF_RELEASE(mCurrent);
-	NS_IF_RELEASE(mResult);
-	NS_RELEASE(mCompositeDataSource);
 }
 
 NS_IMPL_ADDREF(CompositeEnumeratorImpl)
-NS_IMPL_RELEASE_WITH_DESTROY(CompositeEnumeratorImpl, Destroy())
 NS_IMPL_QUERY_INTERFACE1(CompositeEnumeratorImpl, nsISimpleEnumerator)
 
 NS_IMETHODIMP
@@ -375,20 +360,11 @@ public:
 public:
     enum Type { eArcsIn, eArcsOut };
 
-    static CompositeArcsInOutEnumeratorImpl*
-    Create(nsFixedSizeAllocator& aAllocator,
-           CompositeDataSourceImpl* aCompositeDataSource,
-           nsIRDFNode* aNode,
-           Type aType,
-           PRBool aAllowNegativeAssertions,
-           PRBool aCoalesceDuplicateArcs) {
-        void* place = aAllocator.Alloc(sizeof(CompositeArcsInOutEnumeratorImpl));
-        return place
-            ? ::new (place) CompositeArcsInOutEnumeratorImpl(aCompositeDataSource,
-                                                             aNode, aType,
-                                                             aAllowNegativeAssertions,
-                                                             aCoalesceDuplicateArcs)
-            : nsnull; }
+    CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
+                                     nsIRDFNode* aNode,
+                                     Type aType,
+                                     PRBool aAllowNegativeAssertions,
+                                     PRBool aCoalesceDuplicateArcs);
 
     virtual ~CompositeArcsInOutEnumeratorImpl();
 
@@ -398,25 +374,13 @@ public:
     virtual nsresult
     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult);
 
-    virtual void Destroy();
-
 protected:
-    CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
-                                     nsIRDFNode* aNode,
-                                     Type aType,
-                                     PRBool aAllowNegativeAssertions,
-                                     PRBool aCoalesceDuplicateArcs);
 
 private:
     nsIRDFNode* mNode;
     Type        mType;
     PRBool	    mAllowNegativeAssertions;
     PRBool      mCoalesceDuplicateArcs;
-
-    // Hide so that only Create() and Destroy() can be used to
-    // allocate and deallocate from the heap
-    static void* operator new(size_t) CPP_THROW_NEW { return 0; }
-    static void operator delete(void*, size_t) {}
 };
 
 
@@ -465,19 +429,6 @@ CompositeArcsInOutEnumeratorImpl::HasNeg
     return NS_OK;
 }
 
-void
-CompositeArcsInOutEnumeratorImpl::Destroy()
-{
-    // Keep the datasource alive for the duration of the stack
-    // frame so its allocator stays valid.
-    nsCOMPtr<nsIRDFCompositeDataSource> kungFuDeathGrip = mCompositeDataSource;
-
-    nsFixedSizeAllocator& pool = mCompositeDataSource->mAllocator;
-    this->~CompositeArcsInOutEnumeratorImpl();
-    pool.Free(this, sizeof(*this));
-}
-
-
 //----------------------------------------------------------------------
 //
 // CompositeAssertionEnumeratorImpl
@@ -486,23 +437,13 @@ class CompositeAssertionEnumeratorImpl :
 class CompositeAssertionEnumeratorImpl : public CompositeEnumeratorImpl
 {
 public:
-    static CompositeAssertionEnumeratorImpl*
-    Create(nsFixedSizeAllocator& aAllocator,
-           CompositeDataSourceImpl* aCompositeDataSource,
-           nsIRDFResource* aSource,
-           nsIRDFResource* aProperty,
-           nsIRDFNode* aTarget,
-           PRBool aTruthValue,
-           PRBool aAllowNegativeAssertions,
-           PRBool aCoalesceDuplicateArcs) {
-        void* place = aAllocator.Alloc(sizeof(CompositeAssertionEnumeratorImpl));
-        return place
-            ? ::new (place) CompositeAssertionEnumeratorImpl(aCompositeDataSource,
-                                                             aSource, aProperty, aTarget,
-                                                             aTruthValue,
-                                                             aAllowNegativeAssertions,
-                                                             aCoalesceDuplicateArcs)
-            : nsnull; }
+    CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
+                                     nsIRDFResource* aSource,
+                                     nsIRDFResource* aProperty,
+                                     nsIRDFNode* aTarget,
+                                     PRBool aTruthValue,
+                                     PRBool aAllowNegativeAssertions,
+                                     PRBool aCoalesceDuplicateArcs);
 
     virtual nsresult
     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
@@ -510,16 +451,7 @@ public:
     virtual nsresult
     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult);
 
-    virtual void Destroy();
-
 protected:
-    CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
-                                     nsIRDFResource* aSource,
-                                     nsIRDFResource* aProperty,
-                                     nsIRDFNode* aTarget,
-                                     PRBool aTruthValue,
-                                     PRBool aAllowNegativeAssertions,
-                                     PRBool aCoalesceDuplicateArcs);
 
     virtual ~CompositeAssertionEnumeratorImpl();
 
@@ -530,11 +462,6 @@ private:
     PRBool          mTruthValue;
     PRBool          mAllowNegativeAssertions;
     PRBool          mCoalesceDuplicateArcs;
-
-    // Hide so that only Create() and Destroy() can be used to
-    // allocate and deallocate from the heap
-    static void* operator new(size_t) CPP_THROW_NEW { return 0; }
-    static void operator delete(void*, size_t) {}
 };
 
 
@@ -593,18 +520,6 @@ CompositeAssertionEnumeratorImpl::HasNeg
         nsCOMPtr<nsIRDFResource> source( do_QueryInterface(aNode) );
         return aDataSource->HasAssertion(source, mProperty, mTarget, !mTruthValue, aResult);
     }
-}
-
-void
-CompositeAssertionEnumeratorImpl::Destroy()
-{
-    // Keep the datasource alive for the duration of the stack
-    // frame so its allocator stays valid.
-    nsCOMPtr<nsIRDFCompositeDataSource> kungFuDeathGrip = mCompositeDataSource;
-
-    nsFixedSizeAllocator& pool = mCompositeDataSource->mAllocator;
-    this->~CompositeAssertionEnumeratorImpl();
-    pool.Free(this, sizeof(*this));
 }
 
 ////////////////////////////////////////////////////////////////////////
@@ -727,11 +642,10 @@ CompositeDataSourceImpl::GetSources(nsIR
     if ((mAllowNegativeAssertions == PR_FALSE) && (aTruthValue == PR_FALSE))
         return(NS_RDF_NO_VALUE);
 
-    *aResult = CompositeAssertionEnumeratorImpl::Create(mAllocator,
-                                                        this, nsnull, aProperty,
-                                                        aTarget, aTruthValue,
-                                                        mAllowNegativeAssertions,
-                                                        mCoalesceDuplicateArcs);
+    *aResult = new CompositeAssertionEnumeratorImpl(this, nsnull, aProperty,
+                                                    aTarget, aTruthValue,
+                                                    mAllowNegativeAssertions,
+                                                    mCoalesceDuplicateArcs);
 
     if (! *aResult)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -834,11 +748,11 @@ CompositeDataSourceImpl::GetTargets(nsIR
         return(NS_RDF_NO_VALUE);
 
     *aResult =
-        CompositeAssertionEnumeratorImpl::Create(mAllocator, this,
-                                                 aSource, aProperty, nsnull,
-                                                 aTruthValue,
-                                                 mAllowNegativeAssertions,
-                                                 mCoalesceDuplicateArcs);
+        new CompositeAssertionEnumeratorImpl(this,
+                                             aSource, aProperty, nsnull,
+                                             aTruthValue,
+                                             mAllowNegativeAssertions,
+                                             mCoalesceDuplicateArcs);
 
     if (! *aResult)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1166,10 +1080,10 @@ CompositeDataSourceImpl::ArcLabelsIn(nsI
         return NS_ERROR_NULL_POINTER;
 
     nsISimpleEnumerator* result = 
-        CompositeArcsInOutEnumeratorImpl::Create(mAllocator, this, aTarget,
-                                                 CompositeArcsInOutEnumeratorImpl::eArcsIn,
-                                                 mAllowNegativeAssertions,
-                                                 mCoalesceDuplicateArcs);
+        new CompositeArcsInOutEnumeratorImpl(this, aTarget,
+                                             CompositeArcsInOutEnumeratorImpl::eArcsIn,
+                                             mAllowNegativeAssertions,
+                                             mCoalesceDuplicateArcs);
 
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1192,10 +1106,10 @@ CompositeDataSourceImpl::ArcLabelsOut(ns
         return NS_ERROR_NULL_POINTER;
 
     nsISimpleEnumerator* result =
-        CompositeArcsInOutEnumeratorImpl::Create(mAllocator, this, aSource,
-                                                 CompositeArcsInOutEnumeratorImpl::eArcsOut,
-                                                 mAllowNegativeAssertions,
-                                                 mCoalesceDuplicateArcs);
+        new CompositeArcsInOutEnumeratorImpl(this, aSource,
+                                             CompositeArcsInOutEnumeratorImpl::eArcsOut,
+                                             mAllowNegativeAssertions,
+                                             mCoalesceDuplicateArcs);
 
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
diff --git a/rdf/base/src/nsInMemoryDataSource.cpp b/rdf/base/src/nsInMemoryDataSource.cpp
--- a/rdf/base/src/nsInMemoryDataSource.cpp
+++ b/rdf/base/src/nsInMemoryDataSource.cpp
@@ -438,7 +438,8 @@ public:
 /**
  * InMemoryAssertionEnumeratorImpl
  */
-class InMemoryAssertionEnumeratorImpl : public nsISimpleEnumerator
+class InMemoryAssertionEnumeratorImpl : public XPCOMGCFinalizedObject
+                                      , public nsISimpleEnumerator
 {
 private:
     InMemoryDataSource* mDataSource;
@@ -451,44 +452,14 @@ private:
     Assertion*      mNextAssertion;
     nsCOMPtr<nsISupportsArray> mHashArcs;
 
-    // Hide so that only Create() and Destroy() can be used to
-    // allocate and deallocate from the heap
-    static void* operator new(size_t) CPP_THROW_NEW { return 0; }
-    static void operator delete(void*, size_t) {}
+    virtual ~InMemoryAssertionEnumeratorImpl();
 
+public:
     InMemoryAssertionEnumeratorImpl(InMemoryDataSource* aDataSource,
                                     nsIRDFResource* aSource,
                                     nsIRDFResource* aProperty,
                                     nsIRDFNode* aTarget,
                                     PRBool aTruthValue);
-
-    virtual ~InMemoryAssertionEnumeratorImpl();
-
-public:
-    static InMemoryAssertionEnumeratorImpl*
-    Create(InMemoryDataSource* aDataSource,
-           nsIRDFResource* aSource,
-           nsIRDFResource* aProperty,
-           nsIRDFNode* aTarget,
-           PRBool aTruthValue) {
-        void* place = aDataSource->mAllocator.Alloc(sizeof(InMemoryAssertionEnumeratorImpl));
-        return place
-            ? ::new (place) InMemoryAssertionEnumeratorImpl(aDataSource,
-                                                            aSource, aProperty, aTarget,
-                                                            aTruthValue)
-            : nsnull; }
-
-    static void
-    Destroy(InMemoryAssertionEnumeratorImpl* aEnumerator) {
-        // Keep the datasource alive for the duration of the stack
-        // frame so its allocator stays valid.
-        nsCOMPtr<nsIRDFDataSource> kungFuDeathGrip = aEnumerator->mDataSource;
-
-        // Grab the pool from the datasource; since we keep the
-        // datasource alive, this has to be safe.
-        nsFixedSizeAllocator& pool = aEnumerator->mDataSource->mAllocator;
-        aEnumerator->~InMemoryAssertionEnumeratorImpl();
-        pool.Free(aEnumerator, sizeof(*aEnumerator)); }
 
     // nsISupports interface
     NS_DECL_ISUPPORTS
@@ -559,7 +530,6 @@ InMemoryAssertionEnumeratorImpl::~InMemo
 }
 
 NS_IMPL_ADDREF(InMemoryAssertionEnumeratorImpl)
-NS_IMPL_RELEASE_WITH_DESTROY(InMemoryAssertionEnumeratorImpl, Destroy(this))
 NS_IMPL_QUERY_INTERFACE1(InMemoryAssertionEnumeratorImpl, nsISimpleEnumerator)
 
 NS_IMETHODIMP
@@ -642,11 +612,6 @@ class InMemoryArcsEnumeratorImpl : publi
 class InMemoryArcsEnumeratorImpl : public nsISimpleEnumerator
 {
 private:
-    // Hide so that only Create() and Destroy() can be used to
-    // allocate and deallocate from the heap
-    static void* operator new(size_t) CPP_THROW_NEW { return 0; }
-    static void operator delete(void*, size_t) {}
-
     InMemoryDataSource* mDataSource;
     nsIRDFResource*     mSource;
     nsIRDFNode*         mTarget;
@@ -654,10 +619,6 @@ private:
     nsIRDFResource*     mCurrent;
     Assertion*          mAssertion;
     nsCOMPtr<nsISupportsArray> mHashArcs;
-
-    InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource,
-                               nsIRDFResource* aSource,
-                               nsIRDFNode* aTarget);
 
     virtual ~InMemoryArcsEnumeratorImpl();
 
@@ -672,26 +633,9 @@ public:
     // nsISimpleEnumerator interface
     NS_DECL_NSISIMPLEENUMERATOR
 
-    static InMemoryArcsEnumeratorImpl*
-    Create(InMemoryDataSource* aDataSource,
-           nsIRDFResource* aSource,
-           nsIRDFNode* aTarget) {
-        void* place = aDataSource->mAllocator.Alloc(sizeof(InMemoryArcsEnumeratorImpl));
-        return place
-            ? ::new (place) InMemoryArcsEnumeratorImpl(aDataSource, aSource, aTarget)
-            : nsnull; }
-
-    static void
-    Destroy(InMemoryArcsEnumeratorImpl* aEnumerator) {
-        // Keep the datasource alive for the duration of the stack
-        // frame so its allocator stays valid.
-        nsCOMPtr<nsIRDFDataSource> kungFuDeathGrip = aEnumerator->mDataSource;
-
-        // Grab the pool from the datasource; since we keep the
-        // datasource alive, this has to be safe.
-        nsFixedSizeAllocator& pool = aEnumerator->mDataSource->mAllocator;
-        aEnumerator->~InMemoryArcsEnumeratorImpl();
-        pool.Free(aEnumerator, sizeof(*aEnumerator)); }
+    InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource,
+                               nsIRDFResource* aSource,
+                               nsIRDFNode* aTarget);
 };
 
 
@@ -758,7 +702,6 @@ InMemoryArcsEnumeratorImpl::~InMemoryArc
 }
 
 NS_IMPL_ADDREF(InMemoryArcsEnumeratorImpl)
-NS_IMPL_RELEASE_WITH_DESTROY(InMemoryArcsEnumeratorImpl, Destroy(this))
 NS_IMPL_QUERY_INTERFACE1(InMemoryArcsEnumeratorImpl, nsISimpleEnumerator)
 
 NS_IMETHODIMP
@@ -1218,8 +1161,8 @@ InMemoryDataSource::GetSources(nsIRDFRes
         return NS_ERROR_NULL_POINTER;
 
     InMemoryAssertionEnumeratorImpl* result =
-        InMemoryAssertionEnumeratorImpl::Create(this, nsnull, aProperty,
-                                                  aTarget, aTruthValue);
+        new InMemoryAssertionEnumeratorImpl(this, nsnull, aProperty,
+                                            aTarget, aTruthValue);
 
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1249,8 +1192,8 @@ InMemoryDataSource::GetTargets(nsIRDFRes
         return NS_ERROR_NULL_POINTER;
 
     InMemoryAssertionEnumeratorImpl* result =
-        InMemoryAssertionEnumeratorImpl::Create(this, aSource, aProperty,
-                                                nsnull, aTruthValue);
+        new InMemoryAssertionEnumeratorImpl(this, aSource, aProperty,
+                                            nsnull, aTruthValue);
 
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1755,7 +1698,7 @@ InMemoryDataSource::ArcLabelsIn(nsIRDFNo
         return NS_ERROR_NULL_POINTER;
 
     InMemoryArcsEnumeratorImpl* result =
-        InMemoryArcsEnumeratorImpl::Create(this, nsnull, aTarget);
+        new InMemoryArcsEnumeratorImpl(this, nsnull, aTarget);
 
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
@@ -1774,7 +1717,7 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFR
         return NS_ERROR_NULL_POINTER;
 
     InMemoryArcsEnumeratorImpl* result =
-        InMemoryArcsEnumeratorImpl::Create(this, aSource, nsnull);
+        new InMemoryArcsEnumeratorImpl(this, aSource, nsnull);
 
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
diff --git a/rdf/base/src/nsRDFContentSink.cpp b/rdf/base/src/nsRDFContentSink.cpp
--- a/rdf/base/src/nsRDFContentSink.cpp
+++ b/rdf/base/src/nsRDFContentSink.cpp
@@ -437,12 +437,10 @@ RDFContentSinkImpl::QueryInterface(REFNS
         iid.Equals(kIContentSinkIID) ||
         iid.Equals(kISupportsIID)) {
         *result = static_cast<nsIXMLContentSink*>(this);
-        AddRef();
         return NS_OK;
     }
     else if (iid.Equals(kIExpatSinkIID)) {
       *result = static_cast<nsIExpatSink*>(this);
-       AddRef();
        return NS_OK;
     }
     return NS_NOINTERFACE;
diff --git a/rdf/base/src/nsRDFService.cpp b/rdf/base/src/nsRDFService.cpp
--- a/rdf/base/src/nsRDFService.cpp
+++ b/rdf/base/src/nsRDFService.cpp
@@ -318,39 +318,38 @@ static PLDHashTableOps gDateTableOps = {
     nsnull
 };
 
-class BlobImpl : public nsIRDFBlob
+class BlobImpl : public MMgc::GCFinalizedObject, public nsIRDFBlob
 {
 public:
     struct Data {
-        PRInt32  mLength;
+        PRInt32 mLength;
         PRUint8 *mBytes;
     };
+
+    static void* operator new(size_t size, size_t extra)
+    {
+        return MMgc::GCObject::operator new(size, NS_GetGC(), extra);
+    }
 
     BlobImpl(const PRUint8 *aBytes, PRInt32 aLength)
     {
         mData.mLength = aLength;
-        mData.mBytes = new PRUint8[aLength];
-        memcpy(mData.mBytes, aBytes, aLength);
-        NS_ADDREF(RDFServiceImpl::gRDFService);
+        mData.mBytes = mBytes;
+        memcpy(mBytes, aBytes, aLength);
         RDFServiceImpl::gRDFService->RegisterBlob(this);
     }
 
-    virtual ~BlobImpl()
+    ~BlobImpl()
     {
         RDFServiceImpl::gRDFService->UnregisterBlob(this);
-        // Use NS_RELEASE2() here, because we want to decrease the
-        // refcount, but not null out the gRDFService pointer (which is
-        // what a vanilla NS_RELEASE() would do).
-        nsrefcnt refcnt;
-        NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
-        delete[] mData.mBytes;
     }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIRDFNODE
     NS_DECL_NSIRDFBLOB
 
-    Data mData;
+    Data    mData;
+    PRUint8 mBytes[1];
 };
 
 NS_IMPL_ISUPPORTS2(BlobImpl, nsIRDFNode, nsIRDFBlob)
@@ -367,7 +366,7 @@ BlobImpl::EqualsNode(nsIRDFNode *aNode, 
             const PRUint8 *bytes;
             blob->GetValue(&bytes);
 
-            if (0 == memcmp(bytes, mData.mBytes, length)) {
+            if (0 == memcmp(bytes, mBytes, length)) {
                 *aEquals = PR_TRUE;
                 return NS_OK;
             }
@@ -381,7 +380,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 BlobImpl::GetValue(const PRUint8 **aResult)
 {
-    *aResult = mData.mBytes;
+    *aResult = mBytes;
     return NS_OK;
 }
 
@@ -448,7 +447,7 @@ static PLDHashTableOps gBlobTableOps = {
 //   i.e., there is are no resource factories to allow you to generate
 //   customer resources. I doubt that makes sense, anyway.
 //
-class LiteralImpl : public nsIRDFLiteral {
+class LiteralImpl : public XPCOMGCFinalizedObject, public nsIRDFLiteral {
 public:
     static nsresult
     Create(const PRUnichar* aValue, nsIRDFLiteral** aResult);
@@ -463,51 +462,41 @@ public:
     NS_DECL_NSIRDFLITERAL
 
 protected:
-    LiteralImpl(const PRUnichar* s);
+    static void* operator new(size_t size, size_t extra) NS_GCALLOCATOR
+    {
+        return MMgc::GCObject::operator new(size, NS_GetGC(), extra);
+    }
+
+    LiteralImpl(const PRUnichar* s, size_t length);
     virtual ~LiteralImpl();
 
-    const PRUnichar* GetValue() const {
-        size_t objectSize = ((sizeof(LiteralImpl) + sizeof(PRUnichar) - 1) / sizeof(PRUnichar)) * sizeof(PRUnichar);
-        return reinterpret_cast<const PRUnichar*>(reinterpret_cast<const unsigned char*>(this) + objectSize);
+    const PRUnichar* GetValue() const
+    {
+        return mBuffer;
     }
+
+    PRUnichar mBuffer[1];
 };
 
 
 nsresult
 LiteralImpl::Create(const PRUnichar* aValue, nsIRDFLiteral** aResult)
 {
-    // Goofy math to get alignment right. Copied from nsSharedString.h.
-    size_t objectSize = ((sizeof(LiteralImpl) + sizeof(PRUnichar) - 1) / sizeof(PRUnichar)) * sizeof(PRUnichar);
-    size_t stringLen = nsCharTraits<PRUnichar>::length(aValue);
-    size_t stringSize = (stringLen + 1) * sizeof(PRUnichar);
-
-    void* objectPtr = operator new(objectSize + stringSize);
-    if (! objectPtr)
-        return NS_ERROR_NULL_POINTER;
-
-    PRUnichar* buf = reinterpret_cast<PRUnichar*>(static_cast<unsigned char*>(objectPtr) + objectSize);
-    nsCharTraits<PRUnichar>::copy(buf, aValue, stringLen + 1);
-
-    NS_ADDREF(*aResult = new (objectPtr) LiteralImpl(buf));
-    return NS_OK;
+    size_t stringLen = NS_strlen(aValue);
+    *aResult = new(stringLen * sizeof(PRUnichar)) LiteralImpl(aValue, stringLen);
+    return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 
-LiteralImpl::LiteralImpl(const PRUnichar* s)
+LiteralImpl::LiteralImpl(const PRUnichar* s, size_t length)
 {
+    nsCharTraits<PRUnichar>::copy(mBuffer, s, length + 1);
     RDFServiceImpl::gRDFService->RegisterLiteral(this);
-    NS_ADDREF(RDFServiceImpl::gRDFService);
 }
 
 LiteralImpl::~LiteralImpl()
 {
     RDFServiceImpl::gRDFService->UnregisterLiteral(this);
-
-    // Use NS_RELEASE2() here, because we want to decrease the
-    // refcount, but not null out the gRDFService pointer (which is
-    // what a vanilla NS_RELEASE() would do).
-    nsrefcnt refcnt;
-    NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
 }
 
 NS_IMPL_THREADSAFE_ADDREF(LiteralImpl)
@@ -524,7 +513,6 @@ LiteralImpl::QueryInterface(REFNSIID iid
         iid.Equals(kIRDFNodeIID) ||
         iid.Equals(kISupportsIID)) {
         *result = static_cast<nsIRDFLiteral*>(this);
-        AddRef();
         return NS_OK;
     }
     return NS_NOINTERFACE;
@@ -604,12 +592,6 @@ DateImpl::~DateImpl()
 DateImpl::~DateImpl()
 {
     RDFServiceImpl::gRDFService->UnregisterDate(this);
-
-    // Use NS_RELEASE2() here, because we want to decrease the
-    // refcount, but not null out the gRDFService pointer (which is
-    // what a vanilla NS_RELEASE() would do).
-    nsrefcnt refcnt;
-    NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
 }
 
 NS_IMPL_ADDREF(DateImpl)
@@ -626,7 +608,6 @@ DateImpl::QueryInterface(REFNSIID iid, v
         iid.Equals(kIRDFNodeIID) ||
         iid.Equals(kISupportsIID)) {
         *result = static_cast<nsIRDFDate*>(this);
-        AddRef();
         return NS_OK;
     }
     return NS_NOINTERFACE;
@@ -710,12 +691,6 @@ IntImpl::~IntImpl()
 IntImpl::~IntImpl()
 {
     RDFServiceImpl::gRDFService->UnregisterInt(this);
-
-    // Use NS_RELEASE2() here, because we want to decrease the
-    // refcount, but not null out the gRDFService pointer (which is
-    // what a vanilla NS_RELEASE() would do).
-    nsrefcnt refcnt;
-    NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
 }
 
 NS_IMPL_ADDREF(IntImpl)
@@ -1188,7 +1163,7 @@ RDFServiceImpl::GetBlobLiteral(const PRU
         return NS_OK;
     }
 
-    BlobImpl *result = new BlobImpl(aBytes, aLength);
+    BlobImpl *result = new (aLength) BlobImpl(aBytes, aLength);
     if (! result)
         return NS_ERROR_OUT_OF_MEMORY;
 
diff --git a/toolkit/components/places/src/nsNavHistoryQuery.cpp b/toolkit/components/places/src/nsNavHistoryQuery.cpp
--- a/toolkit/components/places/src/nsNavHistoryQuery.cpp
+++ b/toolkit/components/places/src/nsNavHistoryQuery.cpp
@@ -1147,7 +1147,6 @@ NS_IMETHODIMP nsNavHistoryQuery::Clone(n
   nsNavHistoryQuery *clone = new nsNavHistoryQuery(*this);
   NS_ENSURE_TRUE(clone, NS_ERROR_OUT_OF_MEMORY);
 
-  clone->mRefCnt = 0; // the clone doesn't inherit our refcount
   NS_ADDREF(*_retval = clone);
   return NS_OK;
 }
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -565,7 +565,8 @@ PRBool gSafeMode = PR_FALSE;
  * The nsXULAppInfo object implements nsIFactory so that it can be its own
  * singleton.
  */
-class nsXULAppInfo : public nsIXULAppInfo,
+class nsXULAppInfo : public XPCOMGCObject,
+                     public nsIXULAppInfo,
 #ifdef XP_WIN
                      public nsIWinAppHelper,
 #endif
@@ -600,18 +601,6 @@ NS_INTERFACE_MAP_BEGIN(nsXULAppInfo)
 #endif
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIXULAppInfo, gAppData)
 NS_INTERFACE_MAP_END
-
-NS_IMETHODIMP_(nsrefcnt)
-nsXULAppInfo::AddRef()
-{
-  return 1;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsXULAppInfo::Release()
-{
-  return 1;
-}
 
 NS_IMETHODIMP
 nsXULAppInfo::GetVendor(nsACString& aResult)
@@ -847,14 +836,12 @@ nsXULAppInfo::WriteMinidumpForException(
 }
 #endif
 
-static const nsXULAppInfo kAppInfo;
 static NS_METHOD AppInfoConstructor(nsISupports* aOuter,
                                     REFNSIID aIID, void **aResult)
 {
   NS_ENSURE_NO_AGGREGATION(aOuter);
 
-  return const_cast<nsXULAppInfo*>(&kAppInfo)->
-    QueryInterface(aIID, aResult);
+  return (new nsXULAppInfo())->QueryInterface(aIID, aResult);
 }
 
 PRBool gLogConsoleErrors
@@ -1111,8 +1098,8 @@ static void DumpArbitraryHelp()
   ScopedLogging log;
 
   {
-    nsXREDirProvider dirProvider;
-    dirProvider.Initialize(nsnull, gAppData->xreDirectory);
+    nsXREDirProvider *dirProvider = new nsXREDirProvider();
+    dirProvider->Initialize(nsnull, gAppData->xreDirectory);
 
     ScopedXPCOMStartup xpcom;
     xpcom.Initialize();
@@ -2621,12 +2608,12 @@ XRE_main(int argc, char* argv[], const n
     CrashReporter::SetRestartArgs(argc, argv);
 
     // annotate other data (user id etc)
-    nsXREDirProvider dirProvider;
+    nsXREDirProvider *dirProvider = new nsXREDirProvider();
     nsCOMPtr<nsILocalFile> userAppDataDir;
-    rv = dirProvider.Initialize(gAppData->directory, gAppData->xreDirectory);
+    rv = dirProvider->Initialize(gAppData->directory, gAppData->xreDirectory);
     if (NS_SUCCEEDED(rv) &&
-        NS_SUCCEEDED(dirProvider.GetUserAppDataDirectory(
-                                                         getter_AddRefs(userAppDataDir)))) {
+        NS_SUCCEEDED(dirProvider->GetUserAppDataDirectory(
+                                  getter_AddRefs(userAppDataDir)))) {
       CrashReporter::SetupExtraData(userAppDataDir,
                                     nsDependentCString(appData.buildID));
 
@@ -2634,7 +2621,7 @@ XRE_main(int argc, char* argv[], const n
       nsCOMPtr<nsIFile> overrideini;
       PRBool exists;
       static char overrideEnv[MAXPATHLEN];
-      if (NS_SUCCEEDED(dirProvider.GetAppDir()->Clone(getter_AddRefs(overrideini))) &&
+      if (NS_SUCCEEDED(dirProvider->GetAppDir()->Clone(getter_AddRefs(overrideini))) &&
           NS_SUCCEEDED(overrideini->AppendNative(NS_LITERAL_CSTRING("crashreporter-override.ini"))) &&
           NS_SUCCEEDED(overrideini->Exists(&exists)) &&
           exists) {
@@ -2743,8 +2730,8 @@ XRE_main(int argc, char* argv[], const n
 #endif
 
   {
-    nsXREDirProvider dirProvider;
-    rv = dirProvider.Initialize(gAppData->directory, gAppData->xreDirectory);
+    nsXREDirProvider *dirProvider = new nsXREDirProvider();
+    rv = dirProvider->Initialize(gAppData->directory, gAppData->xreDirectory);
     if (NS_FAILED(rv))
       return 1;
 
@@ -2883,14 +2870,14 @@ XRE_main(int argc, char* argv[], const n
   // Check for and process any available updates
   nsCOMPtr<nsIFile> updRoot;
   PRBool persistent;
-  rv = dirProvider.GetFile(XRE_UPDATE_ROOT_DIR, &persistent,
-                           getter_AddRefs(updRoot));
+  rv = dirProvider->GetFile(XRE_UPDATE_ROOT_DIR, &persistent,
+                            getter_AddRefs(updRoot));
   // XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed
   if (NS_FAILED(rv))
-    updRoot = dirProvider.GetAppDir();
+    updRoot = dirProvider->GetAppDir();
 
-  ProcessUpdates(dirProvider.GetGREDir(),
-                 dirProvider.GetAppDir(),
+  ProcessUpdates(dirProvider->GetGREDir(),
+                 dirProvider->GetAppDir(),
                  updRoot,
                  gRestartArgc,
                  gRestartArgv);
@@ -2914,7 +2901,7 @@ XRE_main(int argc, char* argv[], const n
     rv = profileLock->GetLocalDirectory(getter_AddRefs(profLD));
     NS_ENSURE_SUCCESS(rv, 1);
 
-    rv = dirProvider.SetProfile(profD, profLD);
+    rv = dirProvider->SetProfile(profD, profLD);
     NS_ENSURE_SUCCESS(rv, 1);
 
     //////////////////////// NOW WE HAVE A PROFILE ////////////////////////
@@ -2940,7 +2927,7 @@ XRE_main(int argc, char* argv[], const n
     // profile was started with.  The format of the version stamp is defined
     // by the BuildVersion function.
     PRBool versionOK = CheckCompatibility(profD, version, osABI,
-                                          dirProvider.GetGREDir(),
+                                          dirProvider->GetGREDir(),
                                           gAppData->directory);
 
     // Every time a profile is loaded by a build with a different version,
@@ -2953,7 +2940,7 @@ XRE_main(int argc, char* argv[], const n
     if (gSafeMode) {
       RemoveComponentRegistries(profD, profLD, PR_FALSE);
       WriteVersion(profD, NS_LITERAL_CSTRING("Safe Mode"), osABI,
-                   dirProvider.GetGREDir(), gAppData->directory);
+                   dirProvider->GetGREDir(), gAppData->directory);
     }
     else if (versionOK) {
       if (ComponentsListChanged(profD)) {
@@ -2977,7 +2964,7 @@ XRE_main(int argc, char* argv[], const n
 
       // Write out version
       WriteVersion(profD, version, osABI,
-                   dirProvider.GetGREDir(), gAppData->directory);
+                   dirProvider->GetGREDir(), gAppData->directory);
     }
 
     PRBool needsRestart = PR_FALSE;
@@ -3020,7 +3007,7 @@ XRE_main(int argc, char* argv[], const n
 
         if (gDoMigration) {
           nsCOMPtr<nsIFile> file;
-          dirProvider.GetAppDir()->Clone(getter_AddRefs(file));
+          dirProvider->GetAppDir()->Clone(getter_AddRefs(file));
           file->AppendNative(NS_LITERAL_CSTRING("override.ini"));
           nsINIParser parser;
           nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
@@ -3042,9 +3029,9 @@ XRE_main(int argc, char* argv[], const n
           nsCOMPtr<nsIProfileMigrator> pm
             (do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID));
           if (pm)
-            pm->Migrate(&dirProvider);
+            pm->Migrate(dirProvider);
         }
-        dirProvider.DoStartup();
+        dirProvider->DoStartup();
 
         nsCOMPtr<nsICommandLineRunner> cmdLine
           (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
diff --git a/toolkit/xre/nsNativeAppSupportCocoa.mm b/toolkit/xre/nsNativeAppSupportCocoa.mm
--- a/toolkit/xre/nsNativeAppSupportCocoa.mm
+++ b/toolkit/xre/nsNativeAppSupportCocoa.mm
@@ -80,7 +80,8 @@ enum {
         eCarbonLibVersTooOldExplanationIndex
      };
 
-class nsNativeAppSupportCocoa : public nsNativeAppSupportBase
+class nsNativeAppSupportCocoa : public XPCOMGCFinalizedObject
+                              , public nsNativeAppSupportBase
 {
 public:
   nsNativeAppSupportCocoa() :
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1024,14 +1024,10 @@ nsExternalAppHandler::nsExternalAppHandl
   
   // Make sure extension is correct.
   EnsureSuggestedFileName();
-
-  gExtProtSvc->AddRef();
 }
 
 nsExternalAppHandler::~nsExternalAppHandler()
 {
-  // Not using NS_RELEASE, since we don't want to set gExtProtSvc to NULL
-  gExtProtSvc->Release();
 }
 
 NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListener2 * aWebProgressListener)
diff --git a/xpcom/base/Makefile.in b/xpcom/base/Makefile.in
--- a/xpcom/base/Makefile.in
+++ b/xpcom/base/Makefile.in
@@ -49,6 +49,7 @@ MOZILLA_INTERNAL_API =1
 MOZILLA_INTERNAL_API =1
 
 REQUIRES	= string \
+		  js \
 		  $(NULL)
 
 CPPSRCS		= \
@@ -106,7 +107,6 @@ SDK_XPIDLSRCS   = \
 		nsIMemory.idl		   \
 		nsIProgrammingLanguage.idl \
 		nsISupports.idl		   \
-		nsITraceRefcnt.idl         \
 		nsIWeakReference.idl	   \
 		nsrootidl.idl		   \
 		$(NULL)
@@ -147,6 +147,8 @@ FORCE_USE_PIC	= 1
 
 include $(topsrcdir)/config/rules.mk
 
+LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
+
 DEFINES		+= -D_IMPL_NS_COM
 
 ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
diff --git a/xpcom/base/nsAgg.h b/xpcom/base/nsAgg.h
--- a/xpcom/base/nsAgg.h
+++ b/xpcom/base/nsAgg.h
@@ -86,8 +86,6 @@ private:                                
         Internal() {}                                                       \
                                                                             \
         NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);  \
-        NS_IMETHOD_(nsrefcnt) AddRef(void);                                 \
-        NS_IMETHOD_(nsrefcnt) Release(void);                                \
                                                                             \
         NS_DECL_OWNINGTHREAD                                                \
     };                                                                      \
@@ -110,35 +108,7 @@ public:                                 
 
 // Put this in your class's implementation file:
 #define NS_IMPL_AGGREGATED(_class)                                          \
-                                                                            \
-NS_IMPL_AGGREGATED_HELPER(_class)                                           \
-                                                                            \
-NS_IMETHODIMP_(nsrefcnt)                                                    \
-_class::Internal::AddRef(void)                                              \
-{                                                                           \
-    _class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
-    NS_PRECONDITION(PRInt32(agg->mRefCnt) >= 0, "illegal refcnt");          \
-    NS_ASSERT_OWNINGTHREAD(_class);                                         \
-    ++agg->mRefCnt;                                                         \
-    NS_LOG_ADDREF(this, agg->mRefCnt, #_class, sizeof(*this));              \
-    return agg->mRefCnt;                                                    \
-}                                                                           \
-                                                                            \
-NS_IMETHODIMP_(nsrefcnt)                                                    \
-_class::Internal::Release(void)                                             \
-{                                                                           \
-    _class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
-    NS_PRECONDITION(0 != agg->mRefCnt, "dup release");                      \
-    NS_ASSERT_OWNINGTHREAD(_class);                                         \
-    --agg->mRefCnt;                                                         \
-    NS_LOG_RELEASE(this, agg->mRefCnt, #_class);                            \
-    if (agg->mRefCnt == 0) {                                                \
-        agg->mRefCnt = 1; /* stabilize */                                   \
-        NS_DELETEXPCOM(agg);                                                \
-        return 0;                                                           \
-    }                                                                       \
-    return agg->mRefCnt;                                                    \
-}                                                                           \
+  NS_IMPL_AGGREGATED_HELPER(_class)
 
 #define NS_IMPL_CYCLE_COLLECTING_AGGREGATED(_class)                         \
   NS_IMPL_AGGREGATED(_class)
@@ -148,18 +118,6 @@ _class::QueryInterface(const nsIID& aIID
 _class::QueryInterface(const nsIID& aIID, void** aInstancePtr)              \
 {                                                                           \
     return fOuter->QueryInterface(aIID, aInstancePtr);                      \
-}                                                                           \
-                                                                            \
-NS_IMETHODIMP_(nsrefcnt)                                                    \
-_class::AddRef(void)                                                        \
-{                                                                           \
-    return fOuter->AddRef();                                                \
-}                                                                           \
-                                                                            \
-NS_IMETHODIMP_(nsrefcnt)                                                    \
-_class::Release(void)                                                       \
-{                                                                           \
-    return fOuter->Release();                                               \
 }                                                                           \
                                                                             \
 NS_IMETHODIMP                                                               \
diff --git a/xpcom/base/nsAutoPtr.h b/xpcom/base/nsAutoPtr.h
--- a/xpcom/base/nsAutoPtr.h
+++ b/xpcom/base/nsAutoPtr.h
@@ -42,7 +42,7 @@
 
   // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
 #ifndef nsCOMPtr_h___
-  // For |already_AddRefed|, |nsDerivedSafe|, |NSCAP_Zero|,
+  // For
   // |NSCAP_DONT_PROVIDE_NONCONST_OPEQ|,
   // |NSCAP_FEATURE_INLINE_STARTASSIGNMENT|
 #include "nsCOMPtr.h"
@@ -333,7 +333,7 @@ getter_Transfers( nsAutoPtr<T>& aSmartPt
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
   {
     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
@@ -342,7 +342,7 @@ operator==( const nsAutoPtr<T>& lhs, con
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
   {
     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
@@ -353,7 +353,7 @@ operator!=( const nsAutoPtr<T>& lhs, con
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const nsAutoPtr<T>& lhs, const U* rhs )
   {
     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
@@ -361,7 +361,7 @@ operator==( const nsAutoPtr<T>& lhs, con
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const U* lhs, const nsAutoPtr<T>& rhs )
   {
     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
@@ -369,7 +369,7 @@ operator==( const U* lhs, const nsAutoPt
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const nsAutoPtr<T>& lhs, const U* rhs )
   {
     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
@@ -377,7 +377,7 @@ operator!=( const nsAutoPtr<T>& lhs, con
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const U* lhs, const nsAutoPtr<T>& rhs )
   {
     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
@@ -393,7 +393,7 @@ operator!=( const U* lhs, const nsAutoPt
 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const nsAutoPtr<T>& lhs, U* rhs )
   {
     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
@@ -401,7 +401,7 @@ operator==( const nsAutoPtr<T>& lhs, U* 
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( U* lhs, const nsAutoPtr<T>& rhs )
   {
     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
@@ -409,7 +409,7 @@ operator==( U* lhs, const nsAutoPtr<T>& 
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const nsAutoPtr<T>& lhs, U* rhs )
   {
     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
@@ -417,7 +417,7 @@ operator!=( const nsAutoPtr<T>& lhs, U* 
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( U* lhs, const nsAutoPtr<T>& rhs )
   {
     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
@@ -430,8 +430,8 @@ operator!=( U* lhs, const nsAutoPtr<T>& 
 
 template <class T>
 inline
-NSCAP_BOOL
-operator==( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
+bool
+operator==( const nsAutoPtr<T>& lhs, void* rhs )
     // specifically to allow |smartPtr == 0|
   {
     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
@@ -439,8 +439,8 @@ operator==( const nsAutoPtr<T>& lhs, NSC
 
 template <class T>
 inline
-NSCAP_BOOL
-operator==( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
+bool
+operator==( void* lhs, const nsAutoPtr<T>& rhs )
     // specifically to allow |0 == smartPtr|
   {
     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
@@ -448,8 +448,8 @@ operator==( NSCAP_Zero* lhs, const nsAut
 
 template <class T>
 inline
-NSCAP_BOOL
-operator!=( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
+bool
+operator!=( const nsAutoPtr<T>& lhs, void* rhs )
     // specifically to allow |smartPtr != 0|
   {
     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
@@ -457,38 +457,13 @@ operator!=( const nsAutoPtr<T>& lhs, NSC
 
 template <class T>
 inline
-NSCAP_BOOL
-operator!=( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
+bool
+operator!=( void* lhs, const nsAutoPtr<T>& rhs )
     // specifically to allow |0 != smartPtr|
   {
     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
   }
 
-
-#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
-
-  // We need to explicitly define comparison operators for `int'
-  // because the compiler is lame.
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( const nsAutoPtr<T>& lhs, int rhs )
-    // specifically to allow |smartPtr == 0|
-  {
-    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( int lhs, const nsAutoPtr<T>& rhs )
-    // specifically to allow |0 == smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
-  }
-
-#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
 
 /*****************************************************************************/
 
@@ -753,7 +728,7 @@ getter_Transfers( nsAutoArrayPtr<T>& aSm
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
   {
     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
@@ -762,7 +737,7 @@ operator==( const nsAutoArrayPtr<T>& lhs
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
   {
     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
@@ -773,7 +748,7 @@ operator!=( const nsAutoArrayPtr<T>& lhs
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const nsAutoArrayPtr<T>& lhs, const U* rhs )
   {
     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
@@ -781,7 +756,7 @@ operator==( const nsAutoArrayPtr<T>& lhs
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const U* lhs, const nsAutoArrayPtr<T>& rhs )
   {
     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
@@ -789,7 +764,7 @@ operator==( const U* lhs, const nsAutoAr
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const nsAutoArrayPtr<T>& lhs, const U* rhs )
   {
     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
@@ -797,7 +772,7 @@ operator!=( const nsAutoArrayPtr<T>& lhs
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const U* lhs, const nsAutoArrayPtr<T>& rhs )
   {
     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
@@ -813,7 +788,7 @@ operator!=( const U* lhs, const nsAutoAr
 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( const nsAutoArrayPtr<T>& lhs, U* rhs )
   {
     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
@@ -821,7 +796,7 @@ operator==( const nsAutoArrayPtr<T>& lhs
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator==( U* lhs, const nsAutoArrayPtr<T>& rhs )
   {
     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
@@ -829,7 +804,7 @@ operator==( U* lhs, const nsAutoArrayPtr
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( const nsAutoArrayPtr<T>& lhs, U* rhs )
   {
     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
@@ -837,7 +812,7 @@ operator!=( const nsAutoArrayPtr<T>& lhs
 
 template <class T, class U>
 inline
-NSCAP_BOOL
+bool
 operator!=( U* lhs, const nsAutoArrayPtr<T>& rhs )
   {
     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
@@ -850,8 +825,8 @@ operator!=( U* lhs, const nsAutoArrayPtr
 
 template <class T>
 inline
-NSCAP_BOOL
-operator==( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
+bool
+operator==( const nsAutoArrayPtr<T>& lhs, void* rhs )
     // specifically to allow |smartPtr == 0|
   {
     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
@@ -859,8 +834,8 @@ operator==( const nsAutoArrayPtr<T>& lhs
 
 template <class T>
 inline
-NSCAP_BOOL
-operator==( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
+bool
+operator==( void* lhs, const nsAutoArrayPtr<T>& rhs )
     // specifically to allow |0 == smartPtr|
   {
     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
@@ -868,8 +843,8 @@ operator==( NSCAP_Zero* lhs, const nsAut
 
 template <class T>
 inline
-NSCAP_BOOL
-operator!=( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
+bool
+operator!=( const nsAutoArrayPtr<T>& lhs, void* rhs )
     // specifically to allow |smartPtr != 0|
   {
     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
@@ -877,528 +852,15 @@ operator!=( const nsAutoArrayPtr<T>& lhs
 
 template <class T>
 inline
-NSCAP_BOOL
-operator!=( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
+bool
+operator!=( void* lhs, const nsAutoArrayPtr<T>& rhs )
     // specifically to allow |0 != smartPtr|
   {
     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
   }
 
-
-#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
-
-  // We need to explicitly define comparison operators for `int'
-  // because the compiler is lame.
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( const nsAutoArrayPtr<T>& lhs, int rhs )
-    // specifically to allow |smartPtr == 0|
-  {
-    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( int lhs, const nsAutoArrayPtr<T>& rhs )
-    // specifically to allow |0 == smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
-  }
-
-#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
-
-
 /*****************************************************************************/
 
-// template <class T> class nsRefPtrGetterAddRefs;
-
-template <class T>
-class nsRefPtr
-  {
-    private:
-
-      void
-      assign_with_AddRef( T* rawPtr )
-        {
-          if ( rawPtr )
-            rawPtr->AddRef();
-          assign_assuming_AddRef(rawPtr);
-        }
-
-      void**
-      begin_assignment()
-        {
-          assign_assuming_AddRef(0);
-          return reinterpret_cast<void**>(&mRawPtr);
-        }
-
-      void
-      assign_assuming_AddRef( T* newPtr )
-        {
-          T* oldPtr = mRawPtr;
-          mRawPtr = newPtr;
-          if ( oldPtr )
-            oldPtr->Release();
-        }
-
-    private:
-      T* mRawPtr;
-
-    public:
-      typedef T element_type;
-      
-     ~nsRefPtr()
-        {
-          if ( mRawPtr )
-            mRawPtr->Release();
-        }
-
-        // Constructors
-
-      nsRefPtr()
-            : mRawPtr(0)
-          // default constructor
-        {
-        }
-
-      nsRefPtr( const nsRefPtr<T>& aSmartPtr )
-            : mRawPtr(aSmartPtr.mRawPtr)
-          // copy-constructor
-        {
-          if ( mRawPtr )
-            mRawPtr->AddRef();
-        }
-
-      nsRefPtr( T* aRawPtr )
-            : mRawPtr(aRawPtr)
-          // construct from a raw pointer (of the right type)
-        {
-          if ( mRawPtr )
-            mRawPtr->AddRef();
-        }
-
-      nsRefPtr( const already_AddRefed<T>& aSmartPtr )
-            : mRawPtr(aSmartPtr.mRawPtr)
-          // construct from |dont_AddRef(expr)|
-        {
-        }
-
-        // Assignment operators
-
-      nsRefPtr<T>&
-      operator=( const nsRefPtr<T>& rhs )
-          // copy assignment operator
-        {
-          assign_with_AddRef(rhs.mRawPtr);
-          return *this;
-        }
-
-      nsRefPtr<T>&
-      operator=( T* rhs )
-          // assign from a raw pointer (of the right type)
-        {
-          assign_with_AddRef(rhs);
-          return *this;
-        }
-
-      nsRefPtr<T>&
-      operator=( const already_AddRefed<T>& rhs )
-          // assign from |dont_AddRef(expr)|
-        {
-          assign_assuming_AddRef(rhs.mRawPtr);
-          return *this;
-        }
-
-        // Other pointer operators
-
-      void
-      swap( nsRefPtr<T>& rhs )
-          // ...exchange ownership with |rhs|; can save a pair of refcount operations
-        {
-          T* temp = rhs.mRawPtr;
-          rhs.mRawPtr = mRawPtr;
-          mRawPtr = temp;
-        }
-
-      void
-      swap( T*& rhs )
-          // ...exchange ownership with |rhs|; can save a pair of refcount operations
-        {
-          T* temp = rhs;
-          rhs = mRawPtr;
-          mRawPtr = temp;
-        }
-
-      already_AddRefed<T>
-      forget()
-          // return the value of mRawPtr and null out mRawPtr. Useful for
-          // already_AddRefed return values.
-        {
-          T* temp = 0;
-          swap(temp);
-          return temp;
-        }
-
-      void
-      forget( T** rhs )
-          // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
-          // Useful to avoid unnecessary AddRef/Release pairs with "out"
-          // parameters.
-        {
-          NS_ASSERTION(rhs, "Null pointer passed to forget!");
-          *rhs = 0;
-          swap(*rhs);
-        }
-
-      T*
-      get() const
-          /*
-            Prefer the implicit conversion provided automatically by |operator nsDerivedSafe<T>*() const|.
-             Use |get()| to resolve ambiguity or to get a castable pointer.
-
-            Returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|.
-          */
-        {
-          return const_cast<T*>(mRawPtr);
-        }
-
-      operator nsDerivedSafe<T>*() const
-          /*
-            ...makes an |nsRefPtr| act like its underlying raw pointer type (except against |AddRef()|, |Release()|,
-              and |delete|) whenever it is used in a context where a raw pointer is expected.  It is this operator
-              that makes an |nsRefPtr| substitutable for a raw pointer.
-
-            Prefer the implicit use of this operator to calling |get()|, except where necessary to resolve ambiguity.
-          */
-        {
-          return get_DerivedSafe();
-        }
-
-      nsDerivedSafe<T>*
-      operator->() const
-        {
-          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->().");
-          return get_DerivedSafe();
-        }
-
-#ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
-  // broken version for IRIX
-
-      nsRefPtr<T>*
-      get_address() const
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return const_cast<nsRefPtr<T>*>(this);
-        }
-
-#else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-      nsRefPtr<T>*
-      get_address()
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return this;
-        }
-
-      const nsRefPtr<T>*
-      get_address() const
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return this;
-        }
-
-#endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-    public:
-      nsDerivedSafe<T>&
-      operator*() const
-        {
-          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator*().");
-          return *get_DerivedSafe();
-        }
-
-      T**
-      StartAssignment()
-        {
-#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
-          return reinterpret_cast<T**>(begin_assignment());
-#else
-          assign_assuming_AddRef(0);
-          return reinterpret_cast<T**>(&mRawPtr);
-#endif
-        }
-
-    private:
-      nsDerivedSafe<T>*
-      get_DerivedSafe() const
-        {
-          return const_cast<nsDerivedSafe<T>*>
-                           (reinterpret_cast<const nsDerivedSafe<T>*>(mRawPtr));
-        }
-      
-  };
-
-#ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-// This is the broken version for IRIX, which can't handle the version below.
-
-template <class T>
-inline
-nsRefPtr<T>*
-address_of( const nsRefPtr<T>& aPtr )
-  {
-    return aPtr.get_address();
-  }
-
-#else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-template <class T>
-inline
-nsRefPtr<T>*
-address_of( nsRefPtr<T>& aPtr )
-  {
-    return aPtr.get_address();
-  }
-
-template <class T>
-inline
-const nsRefPtr<T>*
-address_of( const nsRefPtr<T>& aPtr )
-  {
-    return aPtr.get_address();
-  }
-
-#endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-template <class T>
-class nsRefPtrGetterAddRefs
-    /*
-      ...
-
-      This class is designed to be used for anonymous temporary objects in the
-      argument list of calls that return COM interface pointers, e.g.,
-
-        nsRefPtr<IFoo> fooP;
-        ...->GetAddRefedPointer(getter_AddRefs(fooP))
-
-      DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
-
-      When initialized with a |nsRefPtr|, as in the example above, it returns
-      a |void**|, a |T**|, or an |nsISupports**| as needed, that the
-      outer call (|GetAddRefedPointer| in this case) can fill in.
-
-      This type should be a nested class inside |nsRefPtr<T>|.
-    */
-  {
-    public:
-      explicit
-      nsRefPtrGetterAddRefs( nsRefPtr<T>& aSmartPtr )
-          : mTargetSmartPtr(aSmartPtr)
-        {
-          // nothing else to do
-        }
-
-      operator void**()
-        {
-          return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
-        }
-
-      operator T**()
-        {
-          return mTargetSmartPtr.StartAssignment();
-        }
-
-      T*&
-      operator*()
-        {
-          return *(mTargetSmartPtr.StartAssignment());
-        }
-
-    private:
-      nsRefPtr<T>& mTargetSmartPtr;
-  };
-
-template <class T>
-inline
-nsRefPtrGetterAddRefs<T>
-getter_AddRefs( nsRefPtr<T>& aSmartPtr )
-    /*
-      Used around a |nsRefPtr| when 
-      ...makes the class |nsRefPtrGetterAddRefs<T>| invisible.
-    */
-  {
-    return nsRefPtrGetterAddRefs<T>(aSmartPtr);
-  }
-
-
-
-  // Comparing two |nsRefPtr|s
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
-  {
-    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
-  }
-
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
-  {
-    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
-  }
-
-
-  // Comparing an |nsRefPtr| to a raw pointer
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const nsRefPtr<T>& lhs, const U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const U* lhs, const nsRefPtr<T>& rhs )
-  {
-    return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const nsRefPtr<T>& lhs, const U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const U* lhs, const nsRefPtr<T>& rhs )
-  {
-    return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
-  }
-
-  // To avoid ambiguities caused by the presence of builtin |operator==|s
-  // creating a situation where one of the |operator==| defined above
-  // has a better conversion for one argument and the builtin has a
-  // better conversion for the other argument, define additional
-  // |operator==| without the |const| on the raw pointer.
-  // See bug 65664 for details.
-
-#ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const nsRefPtr<T>& lhs, U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( U* lhs, const nsRefPtr<T>& rhs )
-  {
-    return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const nsRefPtr<T>& lhs, U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( U* lhs, const nsRefPtr<T>& rhs )
-  {
-    return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
-  }
-#endif
-
-
-
-  // Comparing an |nsRefPtr| to |0|
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
-    // specifically to allow |smartPtr == 0|
-  {
-    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
-    // specifically to allow |0 == smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator!=( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
-    // specifically to allow |smartPtr != 0|
-  {
-    return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator!=( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
-    // specifically to allow |0 != smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
-  }
-
-
-#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
-
-  // We need to explicitly define comparison operators for `int'
-  // because the compiler is lame.
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( const nsRefPtr<T>& lhs, int rhs )
-    // specifically to allow |smartPtr == 0|
-  {
-    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( int lhs, const nsRefPtr<T>& rhs )
-    // specifically to allow |0 == smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
-  }
-
-#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
-
-/*****************************************************************************/
+#define nsRefPtr nsCOMPtr
 
 #endif // !defined(nsAutoPtr_h___)
diff --git a/xpcom/base/nsDebugImpl.cpp b/xpcom/base/nsDebugImpl.cpp
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -119,18 +119,6 @@ PRBool InDebugger()
 #endif /* WIN32*/
 
 NS_IMPL_QUERY_INTERFACE1(nsDebugImpl, nsIDebug)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsDebugImpl::AddRef()
-{
-  return 2;
-}
-
-NS_IMETHODIMP_(nsrefcnt)
-nsDebugImpl::Release()
-{
-  return 1;
-}
 
 NS_IMETHODIMP
 nsDebugImpl::Assertion(const char *aStr, const char *aExpr,
diff --git a/xpcom/base/nsISupportsBase.h b/xpcom/base/nsISupportsBase.h
--- a/xpcom/base/nsISupportsBase.h
+++ b/xpcom/base/nsISupportsBase.h
@@ -36,6 +36,8 @@
 #ifndef nsISupportsBase_h__
 #define nsISupportsBase_h__
 
+#include "MMgc.h"
+
 #ifndef nscore_h___
 #include "nscore.h"
 #endif
@@ -44,6 +46,9 @@
 #include "nsID.h"
 #endif
 
+#ifndef nsDebug_h__
+#include "nsDebug.h"
+#endif
 
 /*@{*/
 /**
@@ -63,7 +68,7 @@
  * and a reference counted memory model (AddRef/Release). This is
  * modelled after the win32 IUnknown API.
  */
-class NS_NO_VTABLE nsISupports {
+class NS_NO_VTABLE nsISupports : public MMgc::GCFinalizable {
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISUPPORTS_IID)
@@ -91,7 +96,10 @@ public:
    *
    * @return The resulting reference count.
    */
-  NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
+  NS_IMETHOD_(nsrefcnt) AddRef(void) {
+    NS_WARNING("Don't call AddRef, stupid");
+    return 1;
+  }
 
   /**
    * Decreases the reference count for this interface.
@@ -100,7 +108,10 @@ public:
    *
    * @return The resulting reference count.
    */
-  NS_IMETHOD_(nsrefcnt) Release(void) = 0;
+  NS_IMETHOD_(nsrefcnt) Release(void) {
+    NS_WARNING("Don't call Release, stupid");
+    return 1;
+  }
 
   //@}
 };
diff --git a/xpcom/base/nsITraceRefcnt.idl b/xpcom/base/nsITraceRefcnt.idl
deleted file mode 100644
--- a/xpcom/base/nsITraceRefcnt.idl
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPCOM
- *
- * The Initial Developer of the Original Code is Doug Turner <dougt@meer.net>
- *
- * Portions created by the Initial Developer are Copyright (C) 2003
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 "nsISupports.idl"
-
-/**  
- * nsITraceRefcnt is an interface between XPCOM Glue and XPCOM.
- *
- * @status DEPRECATED  Replaced by the NS_Log* functions.
- * @status FROZEN
- */
-
-[uuid(273dc92f-0fe6-4545-96a9-21be77828039)]
-interface nsITraceRefcnt : nsISupports
-{
-  void logAddRef(in voidPtr aPtr,
-                 in nsrefcnt aNewRefcnt,
-                 in string aTypeName,
-                 in unsigned long aInstanceSize);
-
-  void logRelease(in voidPtr aPtr,
-                  in nsrefcnt aNewRefcnt,
-                  in string aTypeName);
-
-  void logCtor(in voidPtr aPtr,
-               in string aTypeName,
-               in unsigned long aInstanceSize);
-
-  void logDtor(in voidPtr aPtr,
-               in string aTypeName,
-               in unsigned long aInstanceSize);
-
-
-  void logAddCOMPtr(in voidPtr aPtr, in nsISupports aObject);
-
-  void logReleaseCOMPtr(in voidPtr aPtr, in nsISupports aObject);
-};
diff --git a/xpcom/base/nsMemoryImpl.cpp b/xpcom/base/nsMemoryImpl.cpp
--- a/xpcom/base/nsMemoryImpl.cpp
+++ b/xpcom/base/nsMemoryImpl.cpp
@@ -150,7 +150,7 @@ static MemoryFlusher sGlobalMemoryFlushe
 
 #endif // NS_MEMORY_FLUSHER
 
-static nsMemoryImpl sGlobalMemory;
+static nsMemoryImpl *sGlobalMemory;
 
 NS_IMPL_QUERY_INTERFACE1(nsMemoryImpl, nsIMemory)
 
@@ -209,8 +209,11 @@ nsMemoryImpl::InitFlusher()
 /*static*/ nsresult
 nsMemoryImpl::Create(nsISupports* outer, const nsIID& aIID, void **aResult)
 {
+    if (!sGlobalMemory)
+        sGlobalMemory = new nsMemoryImpl();
+
     NS_ENSURE_NO_AGGREGATION(outer);
-    return sGlobalMemory.QueryInterface(aIID, aResult);
+    return sGlobalMemory->QueryInterface(aIID, aResult);
 }
 
 nsresult
@@ -258,14 +261,12 @@ nsMemoryImpl::RunFlushers(const PRUnicha
 }
 
 // XXX need NS_IMPL_STATIC_ADDREF/RELEASE
-NS_IMETHODIMP_(nsrefcnt) nsMemoryImpl::FlushEvent::AddRef() { return 2; }
-NS_IMETHODIMP_(nsrefcnt) nsMemoryImpl::FlushEvent::Release() { return 1; }
 NS_IMPL_QUERY_INTERFACE1(nsMemoryImpl::FlushEvent, nsIRunnable)
 
 NS_IMETHODIMP
 nsMemoryImpl::FlushEvent::Run()
 {
-    sGlobalMemory.RunFlushers(mReason);
+    sGlobalMemory->RunFlushers(mReason);
     return NS_OK;
 }
 
@@ -281,7 +282,7 @@ NS_Alloc(PRSize size)
     void* result = MALLOC1(size);
     if (! result) {
         // Request an asynchronous flush
-        sGlobalMemory.FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE);
+        sGlobalMemory->FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE);
     }
     return result;
 }
@@ -292,7 +293,7 @@ NS_Realloc(void* ptr, PRSize size)
     void* result = REALLOC1(ptr, size);
     if (! result && size != 0) {
         // Request an asynchronous flush
-        sGlobalMemory.FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE);
+        sGlobalMemory->FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE);
     }
     return result;
 }
@@ -311,7 +312,7 @@ MemoryFlusher::Notify(nsITimer *timer)
 MemoryFlusher::Notify(nsITimer *timer)
 {
     PRBool isLowMemory;
-    sGlobalMemory.IsLowMemory(&isLowMemory);
+    sGlobalMemory->IsLowMemory(&isLowMemory);
 
 #ifdef NS_TEST_MEMORY_FLUSHER
     // Fire the flusher *every* time
@@ -319,8 +320,8 @@ MemoryFlusher::Notify(nsITimer *timer)
 #endif
 
     if (isLowMemory)
-        sGlobalMemory.FlushMemory(NS_LITERAL_STRING("low-memory").get(),
-                                  PR_FALSE);
+        sGlobalMemory->FlushMemory(NS_LITERAL_STRING("low-memory").get(),
+                                   PR_FALSE);
     return NS_OK;
 }
 
@@ -343,5 +344,9 @@ nsresult
 nsresult
 NS_GetMemoryManager(nsIMemory* *result)
 {
-    return sGlobalMemory.QueryInterface(NS_GET_IID(nsIMemory), (void**) result);
+    if (!sGlobalMemory)
+        sGlobalMemory = new nsMemoryImpl();
+
+    *result = sGlobalMemory;
+    return NS_OK;
 }
diff --git a/xpcom/base/nsMemoryImpl.h b/xpcom/base/nsMemoryImpl.h
--- a/xpcom/base/nsMemoryImpl.h
+++ b/xpcom/base/nsMemoryImpl.h
@@ -45,7 +45,7 @@
 // a constructor/destructor or any instance members. Please don't add
 // instance member variables, only static member variables.
 
-class nsMemoryImpl : public nsIMemory
+class nsMemoryImpl : public XPCOMGCObject, public nsIMemory
 {
 public:
     // We don't use the generic macros because we are a special static object
diff --git a/xpcom/base/nsTraceRefcntImpl.cpp b/xpcom/base/nsTraceRefcntImpl.cpp
--- a/xpcom/base/nsTraceRefcntImpl.cpp
+++ b/xpcom/base/nsTraceRefcntImpl.cpp
@@ -49,59 +49,11 @@
 #include "nsCRT.h"
 #include <math.h>
 #include "nsStackWalk.h"
+#include "nsXPCOMPrivate.h"
 
 #ifdef HAVE_LIBDL
 #include <dlfcn.h>
 #endif
-
-////////////////////////////////////////////////////////////////////////////////
-
-NS_COM void 
-NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues,
-                 double *meanResult, double *stdDevResult)
-{
-  double mean = 0.0, var = 0.0, stdDev = 0.0;
-  if (n > 0.0 && sumOfValues >= 0) {
-    mean = sumOfValues / n;
-    double temp = (n * sumOfSquaredValues) - (sumOfValues * sumOfValues);
-    if (temp < 0.0 || n <= 1)
-      var = 0.0;
-    else
-      var = temp / (n * (n - 1));
-    // for some reason, Windows says sqrt(0.0) is "-1.#J" (?!) so do this:
-    stdDev = var != 0.0 ? sqrt(var) : 0.0;
-  }
-  *meanResult = mean;
-  *stdDevResult = stdDev;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-#define NS_IMPL_REFCNT_LOGGING
-
-#ifdef NS_IMPL_REFCNT_LOGGING
-#include "plhash.h"
-#include "prmem.h"
-
-#include "prlock.h"
-
-static PRLock* gTraceLock;
-
-#define LOCK_TRACELOG()   PR_Lock(gTraceLock)
-#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
-
-static PLHashTable* gBloatView;
-static PLHashTable* gTypesToLog;
-static PLHashTable* gObjectsToLog;
-static PLHashTable* gSerialNumbers;
-static PRInt32 gNextSerialNumber;
-
-static PRBool gLogging;
-static PRBool gLogToLeaky;
-static PRBool gLogLeaksOnly;
-
-static void (*leakyLogAddRef)(void* p, int oldrc, int newrc);
-static void (*leakyLogRelease)(void* p, int oldrc, int newrc);
 
 #define BAD_TLS_INDEX ((PRUintn) -1)
 
@@ -111,712 +63,11 @@ static void (*leakyLogRelease)(void* p, 
 // activity is ok, otherwise not!
 static PRUintn gActivityTLS = BAD_TLS_INDEX;
 
-static PRBool gInitialized;
-static nsrefcnt gInitCount;
-
-static FILE *gBloatLog = nsnull;
-static FILE *gRefcntsLog = nsnull;
-static FILE *gAllocLog = nsnull;
-static FILE *gLeakyLog = nsnull;
-static FILE *gCOMPtrLog = nsnull;
-
-struct serialNumberRecord {
-  PRInt32 serialNumber;
-  PRInt32 refCount;
-  PRInt32 COMPtrCount;
-};
-
-struct nsTraceRefcntStats {
-  nsrefcnt mAddRefs;
-  nsrefcnt mReleases;
-  nsrefcnt mCreates;
-  nsrefcnt mDestroys;
-  double mRefsOutstandingTotal;
-  double mRefsOutstandingSquared;
-  double mObjsOutstandingTotal;
-  double mObjsOutstandingSquared;
-};
-
   // I hope to turn this on for everybody once we hit it a little less.
 #define ASSERT_ACTIVITY_IS_LEGAL                                             \
   NS_WARN_IF_FALSE(gActivityTLS != BAD_TLS_INDEX &&                          \
              NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0,        \
              "XPCOM objects created/destroyed from static ctor/dtor");
-
-// These functions are copied from nsprpub/lib/ds/plhash.c, with changes
-// to the functions not called Default* to free the serialNumberRecord or
-// the BloatEntry.
-
-static void * PR_CALLBACK
-DefaultAllocTable(void *pool, PRSize size)
-{
-    return PR_MALLOC(size);
-}
-
-static void PR_CALLBACK
-DefaultFreeTable(void *pool, void *item)
-{
-    PR_Free(item);
-}
-
-static PLHashEntry * PR_CALLBACK
-DefaultAllocEntry(void *pool, const void *key)
-{
-    return PR_NEW(PLHashEntry);
-}
-
-static void PR_CALLBACK
-SerialNumberFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
-    if (flag == HT_FREE_ENTRY) {
-        PR_Free(reinterpret_cast<serialNumberRecord*>(he->value));
-        PR_Free(he);
-    }
-}
-
-static void PR_CALLBACK
-TypesToLogFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
-    if (flag == HT_FREE_ENTRY) {
-        nsCRT::free(const_cast<char*>
-                              (reinterpret_cast<const char*>(he->key)));
-        PR_Free(he);
-    }
-}
-
-static const PLHashAllocOps serialNumberHashAllocOps = {
-    DefaultAllocTable, DefaultFreeTable,
-    DefaultAllocEntry, SerialNumberFreeEntry
-};
-
-static const PLHashAllocOps typesToLogHashAllocOps = {
-    DefaultAllocTable, DefaultFreeTable,
-    DefaultAllocEntry, TypesToLogFreeEntry
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-class BloatEntry {
-public:
-  BloatEntry(const char* className, PRUint32 classSize)
-    : mClassSize(classSize) { 
-    mClassName = PL_strdup(className);
-    Clear(&mNewStats);
-    Clear(&mAllStats);
-    mTotalLeaked = 0;
-  }
-
-  ~BloatEntry() {
-    PL_strfree(mClassName);
-  }
-
-  PRUint32 GetClassSize() { return (PRUint32)mClassSize; }
-  const char* GetClassName() { return mClassName; }
-
-  static void Clear(nsTraceRefcntStats* stats) {
-    stats->mAddRefs = 0;
-    stats->mReleases = 0;
-    stats->mCreates = 0;
-    stats->mDestroys = 0;
-    stats->mRefsOutstandingTotal = 0;
-    stats->mRefsOutstandingSquared = 0;
-    stats->mObjsOutstandingTotal = 0;
-    stats->mObjsOutstandingSquared = 0;
-  }
-
-  void Accumulate() {
-      mAllStats.mAddRefs += mNewStats.mAddRefs;
-      mAllStats.mReleases += mNewStats.mReleases;
-      mAllStats.mCreates += mNewStats.mCreates;
-      mAllStats.mDestroys += mNewStats.mDestroys;
-      mAllStats.mRefsOutstandingTotal += mNewStats.mRefsOutstandingTotal;
-      mAllStats.mRefsOutstandingSquared += mNewStats.mRefsOutstandingSquared;
-      mAllStats.mObjsOutstandingTotal += mNewStats.mObjsOutstandingTotal;
-      mAllStats.mObjsOutstandingSquared += mNewStats.mObjsOutstandingSquared;
-      Clear(&mNewStats);
-  }
-
-  void AddRef(nsrefcnt refcnt) {
-    mNewStats.mAddRefs++;
-    if (refcnt == 1) {
-      Ctor();
-    }
-    AccountRefs();
-  }
-
-  void Release(nsrefcnt refcnt) {
-    mNewStats.mReleases++;
-    if (refcnt == 0) {
-      Dtor();
-    }
-    AccountRefs();
-  }
-
-  void Ctor() {
-    mNewStats.mCreates++;
-    AccountObjs();
-  }
-
-  void Dtor() {
-    mNewStats.mDestroys++;
-    AccountObjs();
-  }
-
-  void AccountRefs() {
-    PRInt32 cnt = (mNewStats.mAddRefs - mNewStats.mReleases);
-    mNewStats.mRefsOutstandingTotal += cnt;
-    mNewStats.mRefsOutstandingSquared += cnt * cnt;
-  }
-
-  void AccountObjs() {
-    PRInt32 cnt = (mNewStats.mCreates - mNewStats.mDestroys);
-    mNewStats.mObjsOutstandingTotal += cnt;
-    mNewStats.mObjsOutstandingSquared += cnt * cnt;
-  }
-
-  static PRIntn PR_CALLBACK DumpEntry(PLHashEntry *he, PRIntn i, void *arg) {
-    BloatEntry* entry = (BloatEntry*)he->value;
-    if (entry) {
-      entry->Accumulate();
-      static_cast<nsVoidArray*>(arg)->AppendElement(entry);
-    }
-    return HT_ENUMERATE_NEXT;
-  }
-
-  static PRIntn PR_CALLBACK TotalEntries(PLHashEntry *he, PRIntn i, void *arg) {
-    BloatEntry* entry = (BloatEntry*)he->value;
-    if (entry && nsCRT::strcmp(entry->mClassName, "TOTAL") != 0) {
-      entry->Total((BloatEntry*)arg);
-    }
-    return HT_ENUMERATE_NEXT;
-  }
-
-  void Total(BloatEntry* total) {
-    total->mAllStats.mAddRefs += mNewStats.mAddRefs + mAllStats.mAddRefs;
-    total->mAllStats.mReleases += mNewStats.mReleases + mAllStats.mReleases;
-    total->mAllStats.mCreates += mNewStats.mCreates + mAllStats.mCreates;
-    total->mAllStats.mDestroys += mNewStats.mDestroys + mAllStats.mDestroys;
-    total->mAllStats.mRefsOutstandingTotal += mNewStats.mRefsOutstandingTotal + mAllStats.mRefsOutstandingTotal;
-    total->mAllStats.mRefsOutstandingSquared += mNewStats.mRefsOutstandingSquared + mAllStats.mRefsOutstandingSquared;
-    total->mAllStats.mObjsOutstandingTotal += mNewStats.mObjsOutstandingTotal + mAllStats.mObjsOutstandingTotal;
-    total->mAllStats.mObjsOutstandingSquared += mNewStats.mObjsOutstandingSquared + mAllStats.mObjsOutstandingSquared;
-    PRInt32 count = (mNewStats.mCreates + mAllStats.mCreates);
-    total->mClassSize += mClassSize * count;    // adjust for average in DumpTotal
-    total->mTotalLeaked += (PRInt32)(mClassSize *
-                                     ((mNewStats.mCreates + mAllStats.mCreates)
-                                      -(mNewStats.mDestroys + mAllStats.mDestroys)));
-  }
-
-  nsresult DumpTotal(PRUint32 nClasses, FILE* out) {
-    mClassSize /= mAllStats.mCreates;
-    return Dump(-1, out, nsTraceRefcntImpl::ALL_STATS);
-  }
-
-  static PRBool HaveLeaks(nsTraceRefcntStats* stats) {
-    return ((stats->mAddRefs != stats->mReleases) ||
-            (stats->mCreates != stats->mDestroys));
-  }
-
-  static nsresult PrintDumpHeader(FILE* out, const char* msg) {
-    fprintf(out, "\n== BloatView: %s\n\n", msg);
-    fprintf(out, 
-        "     |<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->|\n");
-    fprintf(out,
-        "                                              Per-Inst   Leaked    Total      Rem      Mean       StdDev     Total      Rem      Mean       StdDev\n");
-    return NS_OK;
-  }
-
-  nsresult Dump(PRIntn i, FILE* out, nsTraceRefcntImpl::StatisticsType type) {
-    nsTraceRefcntStats* stats = (type == nsTraceRefcntImpl::NEW_STATS) ? &mNewStats : &mAllStats;
-    if (gLogLeaksOnly && !HaveLeaks(stats)) {
-      return NS_OK;
-    }
-
-    double meanRefs, stddevRefs;
-    NS_MeanAndStdDev(stats->mAddRefs + stats->mReleases, 
-                     stats->mRefsOutstandingTotal, 
-                     stats->mRefsOutstandingSquared,
-                     &meanRefs, &stddevRefs);
-
-    double meanObjs, stddevObjs;
-    NS_MeanAndStdDev(stats->mCreates + stats->mDestroys,
-                     stats->mObjsOutstandingTotal, 
-                     stats->mObjsOutstandingSquared,
-                     &meanObjs, &stddevObjs);
-
-    if ((stats->mAddRefs - stats->mReleases) != 0 ||
-        stats->mAddRefs != 0 ||
-        meanRefs != 0 ||
-        stddevRefs != 0 ||
-        (stats->mCreates - stats->mDestroys) != 0 ||
-        stats->mCreates != 0 ||
-        meanObjs != 0 ||
-        stddevObjs != 0) {
-      fprintf(out, "%4d %-40.40s %8d %8d %8d %8d (%8.2f +/- %8.2f) %8d %8d (%8.2f +/- %8.2f)\n",
-              i+1, mClassName,
-              (PRInt32)mClassSize,
-              (nsCRT::strcmp(mClassName, "TOTAL"))
-                  ?(PRInt32)((stats->mCreates - stats->mDestroys) * mClassSize)
-                  :mTotalLeaked,
-              stats->mCreates,
-              (stats->mCreates - stats->mDestroys),
-              meanObjs,
-              stddevObjs, 
-              stats->mAddRefs,
-              (stats->mAddRefs - stats->mReleases),
-              meanRefs,
-              stddevRefs);
-    }
-    return NS_OK;
-  }
-
-protected:
-  char*         mClassName;
-  double        mClassSize;     // this is stored as a double because of the way we compute the avg class size for total bloat
-  PRInt32       mTotalLeaked; // used only for TOTAL entry
-  nsTraceRefcntStats mNewStats;
-  nsTraceRefcntStats mAllStats;
-};
-
-static void PR_CALLBACK
-BloatViewFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
-    if (flag == HT_FREE_ENTRY) {
-        BloatEntry* entry = reinterpret_cast<BloatEntry*>(he->value);
-        delete entry;
-        PR_Free(he);
-    }
-}
-
-const static PLHashAllocOps bloatViewHashAllocOps = {
-    DefaultAllocTable, DefaultFreeTable,
-    DefaultAllocEntry, BloatViewFreeEntry
-};
-
-static void
-RecreateBloatView()
-{
-  gBloatView = PL_NewHashTable(256, 
-                               PL_HashString,
-                               PL_CompareStrings,
-                               PL_CompareValues,
-                               &bloatViewHashAllocOps, NULL);
-}
-
-static BloatEntry*
-GetBloatEntry(const char* aTypeName, PRUint32 aInstanceSize)
-{
-  if (!gBloatView) {
-    RecreateBloatView();
-  }
-  BloatEntry* entry = NULL;
-  if (gBloatView) {
-    entry = (BloatEntry*)PL_HashTableLookup(gBloatView, aTypeName);
-    if (entry == NULL && aInstanceSize > 0) {
-
-      entry = new BloatEntry(aTypeName, aInstanceSize);
-      PLHashEntry* e = PL_HashTableAdd(gBloatView, aTypeName, entry);
-      if (e == NULL) {
-        delete entry;
-        entry = NULL;
-      }
-    } else {
-      NS_ASSERTION(aInstanceSize == 0 || 
-                   entry->GetClassSize() == aInstanceSize, 
-                   "bad size recorded");
-    }
-  }
-  return entry;
-}
-
-static PRIntn PR_CALLBACK DumpSerialNumbers(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosure)
-{
-  serialNumberRecord* record = reinterpret_cast<serialNumberRecord *>(aHashEntry->value);
-#ifdef HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR
-  fprintf((FILE*) aClosure, "%d @%p (%d references; %d from COMPtrs)\n",
-                            record->serialNumber,
-                            NS_INT32_TO_PTR(aHashEntry->key),
-                            record->refCount,
-                            record->COMPtrCount);
-#else
-  fprintf((FILE*) aClosure, "%d @%p (%d references)\n",
-                            record->serialNumber,
-                            NS_INT32_TO_PTR(aHashEntry->key),
-                            record->refCount);
-#endif
-  return HT_ENUMERATE_NEXT;
-}
-
-
-#endif /* NS_IMPL_REFCNT_LOGGING */
-
-NS_COM nsresult
-nsTraceRefcntImpl::DumpStatistics(StatisticsType type, FILE* out)
-{
-  nsresult rv = NS_OK;
-#ifdef NS_IMPL_REFCNT_LOGGING
-  if (gBloatLog == nsnull || gBloatView == nsnull) {
-    return NS_ERROR_FAILURE;
-  }
-  if (out == nsnull) {
-    out = gBloatLog;
-  }
-
-  LOCK_TRACELOG();
-
-  PRBool wasLogging = gLogging;
-  gLogging = PR_FALSE;  // turn off logging for this method
-  
-  const char* msg;
-  if (type == NEW_STATS) {
-    if (gLogLeaksOnly)
-      msg = "NEW (incremental) LEAK STATISTICS";
-    else
-      msg = "NEW (incremental) LEAK AND BLOAT STATISTICS";
-  }
-  else {
-    if (gLogLeaksOnly)
-      msg = "ALL (cumulative) LEAK STATISTICS";
-    else
-      msg = "ALL (cumulative) LEAK AND BLOAT STATISTICS";
-  }
-  rv = BloatEntry::PrintDumpHeader(out, msg);
-  if (NS_FAILED(rv)) goto done;
-
-  {
-    BloatEntry total("TOTAL", 0);
-    PL_HashTableEnumerateEntries(gBloatView, BloatEntry::TotalEntries, &total);
-    total.DumpTotal(gBloatView->nentries, out);
-
-    nsVoidArray entries;
-    PL_HashTableEnumerateEntries(gBloatView, BloatEntry::DumpEntry, &entries);
-
-    fprintf(stdout, "nsTraceRefcntImpl::DumpStatistics: %d entries\n",
-           entries.Count());
-
-    // Sort the entries alphabetically by classname.
-    PRInt32 i, j;
-    for (i = entries.Count() - 1; i >= 1; --i) {
-      for (j = i - 1; j >= 0; --j) {
-        BloatEntry* left  = static_cast<BloatEntry*>(entries[i]);
-        BloatEntry* right = static_cast<BloatEntry*>(entries[j]);
-
-        if (PL_strcmp(left->GetClassName(), right->GetClassName()) < 0) {
-          entries.ReplaceElementAt(right, i);
-          entries.ReplaceElementAt(left, j);
-        }
-      }
-    }
-
-    // Enumerate from back-to-front, so things come out in alpha order
-    for (i = 0; i < entries.Count(); ++i) {
-      BloatEntry* entry = static_cast<BloatEntry*>(entries[i]);
-      entry->Dump(i, out, type);
-    }
-  }
-
-  if (gSerialNumbers) {
-    fprintf(out, "\n\nSerial Numbers of Leaked Objects:\n");
-    PL_HashTableEnumerateEntries(gSerialNumbers, DumpSerialNumbers, out);
-  }
-
-done:
-  gLogging = wasLogging;
-  UNLOCK_TRACELOG();
-#endif
-  return rv;
-}
-
-NS_COM void
-nsTraceRefcntImpl::ResetStatistics()
-{
-#ifdef NS_IMPL_REFCNT_LOGGING
-  LOCK_TRACELOG();
-  if (gBloatView) {
-    PL_HashTableDestroy(gBloatView);
-    gBloatView = nsnull;
-  }
-  UNLOCK_TRACELOG();
-#endif
-}
-
-#ifdef NS_IMPL_REFCNT_LOGGING
-static PRBool LogThisType(const char* aTypeName)
-{
-  void* he = PL_HashTableLookup(gTypesToLog, aTypeName);
-  return nsnull != he;
-}
-
-static PRInt32 GetSerialNumber(void* aPtr, PRBool aCreate)
-{
-#ifdef GC_LEAK_DETECTOR
-  // need to disguise this pointer, so the table won't keep the object alive.
-  aPtr = (void*) ~PLHashNumber(aPtr);
-#endif
-  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr);
-  if (hep && *hep) {
-    return PRInt32((reinterpret_cast<serialNumberRecord*>((*hep)->value))->serialNumber);
-  }
-  else if (aCreate) {
-    serialNumberRecord *record = PR_NEW(serialNumberRecord);
-    record->serialNumber = ++gNextSerialNumber;
-    record->refCount = 0;
-    record->COMPtrCount = 0;
-    PL_HashTableRawAdd(gSerialNumbers, hep, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr, reinterpret_cast<void*>(record));
-    return gNextSerialNumber;
-  }
-  else {
-    return 0;
-  }
-}
-
-static PRInt32* GetRefCount(void* aPtr)
-{
-#ifdef GC_LEAK_DETECTOR
-  // need to disguise this pointer, so the table won't keep the object alive.
-  aPtr = (void*) ~PLHashNumber(aPtr);
-#endif
-  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr);
-  if (hep && *hep) {
-    return &((reinterpret_cast<serialNumberRecord*>((*hep)->value))->refCount);
-  } else {
-    return nsnull;
-  }
-}
-
-static PRInt32* GetCOMPtrCount(void* aPtr)
-{
-#ifdef GC_LEAK_DETECTOR
-  // need to disguise this pointer, so the table won't keep the object alive.
-  aPtr = (void*) ~PLHashNumber(aPtr);
-#endif
-  PLHashEntry** hep = PL_HashTableRawLookup(gSerialNumbers, PLHashNumber(NS_PTR_TO_INT32(aPtr)), aPtr);
-  if (hep && *hep) {
-    return &((reinterpret_cast<serialNumberRecord*>((*hep)->value))->COMPtrCount);
-  } else {
-    return nsnull;
-  }
-}
-
-static void RecycleSerialNumberPtr(void* aPtr)
-{
-#ifdef GC_LEAK_DETECTOR
-  // need to disguise this pointer, so the table won't keep the object alive.
-  aPtr = (void*) ~PLHashNumber(aPtr);
-#endif
-  PL_HashTableRemove(gSerialNumbers, aPtr);
-}
-
-static PRBool LogThisObj(PRInt32 aSerialNumber)
-{
-  return nsnull != PL_HashTableLookup(gObjectsToLog, (const void*)(aSerialNumber));
-}
-
-static PRBool InitLog(const char* envVar, const char* msg, FILE* *result)
-{
-  const char* value = getenv(envVar);
-  if (value) {
-    if (nsCRT::strcmp(value, "1") == 0) {
-      *result = stdout;
-      fprintf(stdout, "### %s defined -- logging %s to stdout\n", 
-              envVar, msg);
-      return PR_TRUE;
-    }
-    else if (nsCRT::strcmp(value, "2") == 0) {
-      *result = stderr;
-      fprintf(stdout, "### %s defined -- logging %s to stderr\n", 
-              envVar, msg);
-      return PR_TRUE;
-    }
-    else {
-      FILE *stream = ::fopen(value, "w");
-      if (stream != NULL) {
-        *result = stream;
-        fprintf(stdout, "### %s defined -- logging %s to %s\n", 
-                envVar, msg, value);
-        return PR_TRUE;
-      }
-      else {
-        fprintf(stdout, "### %s defined -- unable to log %s to %s\n", 
-                envVar, msg, value);
-        return PR_FALSE;
-      }
-    }
-  }
-  return PR_FALSE;
-}
-
-
-static PLHashNumber PR_CALLBACK HashNumber(const void* aKey)
-{
-  return PLHashNumber(NS_PTR_TO_INT32(aKey));
-}
-
-static void InitTraceLog(void)
-{
-  if (gInitialized) return;
-  gInitialized = PR_TRUE;
-
-  PRBool defined;
-  defined = InitLog("XPCOM_MEM_BLOAT_LOG", "bloat/leaks", &gBloatLog);
-  if (!defined)
-    gLogLeaksOnly = InitLog("XPCOM_MEM_LEAK_LOG", "leaks", &gBloatLog);
-  if (defined || gLogLeaksOnly) {
-    RecreateBloatView();
-    if (!gBloatView) {
-      NS_WARNING("out of memory");
-      gBloatLog = nsnull;
-      gLogLeaksOnly = PR_FALSE;
-    }
-  }
-
-  (void)InitLog("XPCOM_MEM_REFCNT_LOG", "refcounts", &gRefcntsLog);
-
-  (void)InitLog("XPCOM_MEM_ALLOC_LOG", "new/delete", &gAllocLog);
-
-  defined = InitLog("XPCOM_MEM_LEAKY_LOG", "for leaky", &gLeakyLog);
-  if (defined) {
-    gLogToLeaky = PR_TRUE;
-    PRFuncPtr p = nsnull, q = nsnull;
-#ifdef HAVE_LIBDL
-    {
-      PRLibrary *lib = nsnull;
-      p = PR_FindFunctionSymbolAndLibrary("__log_addref", &lib);
-      if (lib) {
-        PR_UnloadLibrary(lib);
-        lib = nsnull;
-      }
-      q = PR_FindFunctionSymbolAndLibrary("__log_release", &lib);
-      if (lib) {
-        PR_UnloadLibrary(lib);
-      }
-    }
-#endif
-    if (p && q) {
-      leakyLogAddRef = (void (*)(void*,int,int)) p;
-      leakyLogRelease = (void (*)(void*,int,int)) q;
-    }
-    else {
-      gLogToLeaky = PR_FALSE;
-      fprintf(stdout, "### ERROR: XPCOM_MEM_LEAKY_LOG defined, but can't locate __log_addref and __log_release symbols\n");
-      fflush(stdout);
-    }
-  }
-
-  const char* classes = getenv("XPCOM_MEM_LOG_CLASSES");
-
-#ifdef HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR
-  if (classes) {
-    (void)InitLog("XPCOM_MEM_COMPTR_LOG", "nsCOMPtr", &gCOMPtrLog);
-  } else {
-    if (getenv("XPCOM_MEM_COMPTR_LOG")) {
-      fprintf(stdout, "### XPCOM_MEM_COMPTR_LOG defined -- but XPCOM_MEM_LOG_CLASSES is not defined\n");
-    }
-  }
-#else
-  const char* comptr_log = getenv("XPCOM_MEM_COMPTR_LOG");
-  if (comptr_log) {
-    fprintf(stdout, "### XPCOM_MEM_COMPTR_LOG defined -- but it will not work without dynamic_cast\n");
-  }
-#endif
-
-  if (classes) {
-    // if XPCOM_MEM_LOG_CLASSES was set to some value, the value is interpreted
-    // as a list of class names to track
-    gTypesToLog = PL_NewHashTable(256,
-                                  PL_HashString,
-                                  PL_CompareStrings,
-                                  PL_CompareValues,
-                                  &typesToLogHashAllocOps, NULL);
-    if (!gTypesToLog) {
-      NS_WARNING("out of memory");
-      fprintf(stdout, "### XPCOM_MEM_LOG_CLASSES defined -- unable to log specific classes\n");
-    }
-    else {
-      fprintf(stdout, "### XPCOM_MEM_LOG_CLASSES defined -- only logging these classes: ");
-      const char* cp = classes;
-      for (;;) {
-        char* cm = (char*) strchr(cp, ',');
-        if (cm) {
-          *cm = '\0';
-        }
-        PL_HashTableAdd(gTypesToLog, nsCRT::strdup(cp), (void*)1);
-        fprintf(stdout, "%s ", cp);
-        if (!cm) break;
-        *cm = ',';
-        cp = cm + 1;
-      }
-      fprintf(stdout, "\n");
-    }
-
-    gSerialNumbers = PL_NewHashTable(256,
-                                     HashNumber,
-                                     PL_CompareValues,
-                                     PL_CompareValues,
-                                     &serialNumberHashAllocOps, NULL);
-
-
-  }
-
-  const char* objects = getenv("XPCOM_MEM_LOG_OBJECTS");
-  if (objects) {
-    gObjectsToLog = PL_NewHashTable(256,
-                                    HashNumber,
-                                    PL_CompareValues,
-                                    PL_CompareValues,
-                                    NULL, NULL);
-
-    if (!gObjectsToLog) {
-      NS_WARNING("out of memory");
-      fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- unable to log specific objects\n");
-    }
-    else if (! (gRefcntsLog || gAllocLog || gCOMPtrLog)) {
-      fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- but none of XPCOM_MEM_(REFCNT|ALLOC|COMPTR)_LOG is defined\n");
-    }
-    else {
-      fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- only logging these objects: ");
-      const char* cp = objects;
-      for (;;) {
-        char* cm = (char*) strchr(cp, ',');
-        if (cm) {
-          *cm = '\0';
-        }
-        PRInt32 top = 0;
-        PRInt32 bottom = 0;
-        while (*cp) {
-          if (*cp == '-') {
-            bottom = top;
-            top = 0;
-            ++cp;
-          }
-          top *= 10;
-          top += *cp - '0';
-          ++cp;
-        }
-        if (!bottom) {
-          bottom = top;
-        }
-        for(PRInt32 serialno = bottom; serialno <= top; serialno++) {
-          PL_HashTableAdd(gObjectsToLog, (const void*)serialno, (void*)1);
-          fprintf(stdout, "%d ", serialno);
-        }
-        if (!cm) break;
-        *cm = ',';
-        cp = cm + 1;
-      }
-      fprintf(stdout, "\n");
-    }
-  }
-
-
-  if (gBloatLog || gRefcntsLog || gAllocLog || gLeakyLog || gCOMPtrLog) {
-    gLogging = PR_TRUE;
-  }
-
-  gTraceLock = PR_NewLock();
-}
-
-#endif
 
 extern "C" {
 
@@ -874,13 +125,26 @@ nsTraceRefcntImpl::DemangleSymbol(const 
 
 //----------------------------------------------------------------------
 
+static int gInitCount;
+NS_COM JSRuntime *gJSRuntime;
+
+const uint32 kGCSize = 32L * 1024L * 1024L;
+
 EXPORT_XPCOM_API(void)
 NS_LogInit()
 {
-#ifdef NS_IMPL_REFCNT_LOGGING
-  if (++gInitCount)
-    nsTraceRefcntImpl::SetActivityIsLegal(PR_TRUE);
-#endif
+  if (++gInitCount == 1) {
+    NS_ASSERTION(!gJSRuntime, "gJSRuntime already initialized");
+    gJSRuntime = JS_NewRuntime(kGCSize);
+    
+    // Unconstrain the runtime's threshold on nominal heap size, to avoid
+    // triggering GC too often if operating continuously near an arbitrary
+    // finite threshold (0xffffffff is infinity for uint32 parameters).
+    // This leaves the maximum-JS_malloc-bytes threshold still in effect
+    // to cause period, and we hope hygienic, last-ditch GCs from within
+    // the GC's allocator.
+    JS_SetGCParameter(gJSRuntime, JSGC_MAX_BYTES, 0xffffffff);
+  }
 }
 
 EXPORT_XPCOM_API(void)
@@ -888,18 +152,26 @@ NS_LogTerm()
 {
   NS_ASSERTION(gInitCount > 0,
                "NS_LogTerm without matching NS_LogInit");
+  NS_ASSERTION(gJSRuntime,
+               "gJSRuntime null in NS_LogTerm");
 
   if (--gInitCount == 0) {
-    if (gInitialized) {
-      nsTraceRefcntImpl::DumpStatistics();
-      nsTraceRefcntImpl::ResetStatistics();
-    }
-    nsTraceRefcntImpl::Shutdown();
 #ifdef NS_IMPL_REFCNT_LOGGING
     nsTraceRefcntImpl::SetActivityIsLegal(PR_FALSE);
     gActivityTLS = BAD_TLS_INDEX;
 #endif
+    JS_DestroyRuntime(gJSRuntime);
+    gJSRuntime = NULL;
   }
+}
+
+EXPORT_XPCOM_API(MMgc::GC*)
+NS_GetGC()
+{
+  if (!gJSRuntime)
+    return NULL;
+
+  return gJSRuntime->gc;
 }
 
 EXPORT_XPCOM_API(void)
@@ -1221,68 +493,3 @@ nsTraceRefcntImpl::SetActivityIsLegal(PR
   PR_SetThreadPrivate(gActivityTLS, NS_INT32_TO_PTR(!aLegal));
 #endif
 }
-
-NS_IMPL_QUERY_INTERFACE1(nsTraceRefcntImpl, nsITraceRefcnt)
-
-NS_IMETHODIMP_(nsrefcnt) nsTraceRefcntImpl::AddRef(void)
-{
-  return 2;
-}
-
-NS_IMETHODIMP_(nsrefcnt) nsTraceRefcntImpl::Release(void)                                
-{                                                                             
-  return 1;
-}
-
-NS_IMETHODIMP
-nsTraceRefcntImpl::LogAddRef(void *aPtr, nsrefcnt aNewRefcnt,
-                             const char *aTypeName, PRUint32 aSize)
-{
-  NS_LogAddRef(aPtr, aNewRefcnt, aTypeName, aSize);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTraceRefcntImpl::LogRelease(void *aPtr, nsrefcnt aNewRefcnt,
-                              const char *aTypeName)
-{
-  NS_LogRelease(aPtr, aNewRefcnt, aTypeName);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTraceRefcntImpl::LogCtor(void *aPtr, const char *aTypeName, PRUint32 aSize)
-{
-  NS_LogCtor(aPtr, aTypeName, aSize);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTraceRefcntImpl::LogDtor(void *aPtr, const char *aTypeName, PRUint32 aSize)
-{
-  NS_LogDtor(aPtr, aTypeName, aSize);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTraceRefcntImpl::LogAddCOMPtr(void *aCOMPtr, nsISupports* aObject)
-{
-  NS_LogCOMPtrAddRef(aCOMPtr, aObject);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTraceRefcntImpl::LogReleaseCOMPtr(void *aCOMPtr, nsISupports* aObject)
-{
-  NS_LogCOMPtrRelease(aCOMPtr, aObject);
-  return NS_OK;
-}
-
-static const nsTraceRefcntImpl kTraceRefcntImpl;
-
-NS_METHOD
-nsTraceRefcntImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
-{
-  return const_cast<nsTraceRefcntImpl*>(&kTraceRefcntImpl)->
-    QueryInterface(aIID, aInstancePtr);
-}
diff --git a/xpcom/base/nsTraceRefcntImpl.h b/xpcom/base/nsTraceRefcntImpl.h
--- a/xpcom/base/nsTraceRefcntImpl.h
+++ b/xpcom/base/nsTraceRefcntImpl.h
@@ -39,51 +39,26 @@
 #define nsTraceRefcntImpl_h___
 
 #include <stdio.h> // for FILE
-#include "nsITraceRefcnt.h"
+#include "nscore.h"
 
-class nsTraceRefcntImpl : public nsITraceRefcnt
+namespace nsTraceRefcntImpl
 {
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSITRACEREFCNT
+  NS_COM void Startup();  
+  NS_COM void Shutdown();
 
-  static NS_COM void Startup();  
-  static NS_COM void Shutdown();
+  NS_COM void DemangleSymbol(const char * aSymbol, 
+                             char * aBuffer,
+                             int aBufLen);
 
-  enum StatisticsType {
-    ALL_STATS,
-    NEW_STATS
-  };
+  NS_COM void WalkTheStack(FILE* aStream);
 
-  static NS_COM nsresult DumpStatistics(StatisticsType type = ALL_STATS,
-                                        FILE* out = 0);
-  
-  static NS_COM void ResetStatistics(void);
-
-  static NS_COM void DemangleSymbol(const char * aSymbol, 
-                                    char * aBuffer,
-                                    int aBufLen);
-
-  static NS_COM void WalkTheStack(FILE* aStream);
   /**
    * Tell nsTraceRefcnt whether refcounting, allocation, and destruction
    * activity is legal.  This is used to trigger assertions for any such
    * activity that occurs because of static constructors or destructors.
    */
-  static NS_COM void SetActivityIsLegal(PRBool aLegal);
-
-  static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
-};
-
-#define NS_TRACE_REFCNT_CONTRACTID "@mozilla.org/xpcom/trace-refcnt;1"
-#define NS_TRACE_REFCNT_CLASSNAME  "nsTraceRefcnt Interface"
-#define NS_TRACE_REFCNT_CID                          \
-{ /* e3e7511e-a395-4924-94b1-d527861cded4 */         \
-    0xe3e7511e,                                      \
-    0xa395,                                          \
-    0x4924,                                          \
-    {0x94, 0xb1, 0xd5, 0x27, 0x86, 0x1c, 0xde, 0xd4} \
-}                                                    \
+  NS_COM void SetActivityIsLegal(PRBool aLegal);
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // And now for that utility that you've all been asking for...
diff --git a/xpcom/build/Makefile.in b/xpcom/build/Makefile.in
--- a/xpcom/build/Makefile.in
+++ b/xpcom/build/Makefile.in
@@ -71,6 +71,7 @@ MOZILLA_INTERNAL_API = 1
 MOZILLA_INTERNAL_API = 1
 
 REQUIRES	= string \
+		  js \
 		  $(NULL)
 
 # pull in MoreFiles for MacOSX
@@ -150,6 +151,7 @@ SDK_HEADERS =  \
 
 EXPORTS	= \
 		nsXPCOMCIDInternal.h \
+		nsXPCOMPrivate.h \
 		$(NULL)
 
 # Force use of PIC
@@ -172,7 +174,7 @@ DEFINES		+= \
 		-DEXPORT_XPT_API \
 		-DEXPORT_XPTC_API
 
-EXTRA_DSO_LDOPTS += $(NSPR_LIBS) $(MMGC_LIBS)
+EXTRA_DSO_LDOPTS += $(MOZ_JS_LIBS) $(NSPR_LIBS) $(MMGC_LIBS)
 
 ifdef GC_LEAK_DETECTOR
 DEFINES += -DGC_LEAK_DETECTOR
diff --git a/xpcom/build/dlldeps.cpp b/xpcom/build/dlldeps.cpp
--- a/xpcom/build/dlldeps.cpp
+++ b/xpcom/build/dlldeps.cpp
@@ -164,8 +164,6 @@ void XXXNeverCalled()
     a.Free(0, 0);
     nsDeque d(nsnull);
     nsDequeIterator di(d);
-    nsTraceRefcnt::LogAddCOMPtr(nsnull, nsnull);
-    nsTraceRefcntImpl::DumpStatistics();
     NS_NewEmptyEnumerator(nsnull);
     NS_QuickSort(nsnull, 0, 0, nsnull, nsnull);
     nsString();
diff --git a/xpcom/build/nsXPCOM.h b/xpcom/build/nsXPCOM.h
--- a/xpcom/build/nsXPCOM.h
+++ b/xpcom/build/nsXPCOM.h
@@ -51,7 +51,6 @@
 # define NS_NewLocalFile             NS_NewLocalFile_P
 # define NS_NewNativeLocalFile       NS_NewNativeLocalFile_P
 # define NS_GetDebug                 NS_GetDebug_P
-# define NS_GetTraceRefcnt           NS_GetTraceRefcnt_P
 # define NS_Alloc                    NS_Alloc_P
 # define NS_Realloc                  NS_Realloc_P
 # define NS_Free                     NS_Free_P
@@ -66,6 +65,7 @@
 # define NS_LogCOMPtrRelease         NS_LogCOMPtrRelease_P
 # define NS_CycleCollectorSuspect    NS_CycleCollectorSuspect_P
 # define NS_CycleCollectorForget     NS_CycleCollectorForget_P
+# define NS_GetGC                    NS_GetGC_P
 #endif
 
 #include "nscore.h"
@@ -467,6 +467,19 @@ NS_CycleCollectorForget(nsISupports *n);
 NS_CycleCollectorForget(nsISupports *n);
 
 /**
+ * Get a reference to the one-and-only GC used by XPCOM:
+ */
+#ifdef __cplusplus
+namespace MMgc
+{
+    class GC;
+}
+
+XPCOM_API(MMgc::GC*)
+NS_GetGC();
+#endif
+
+/**
  * Categories (in the category manager service) used by XPCOM:
  */
 
@@ -550,7 +563,4 @@ XPCOM_API(nsresult)
 XPCOM_API(nsresult)
 NS_GetDebug(nsIDebug* *result);
 
-XPCOM_API(nsresult)
-NS_GetTraceRefcnt(nsITraceRefcnt* *result);
-
 #endif
diff --git a/xpcom/build/nsXPCOMPrivate.h b/xpcom/build/nsXPCOMPrivate.h
--- a/xpcom/build/nsXPCOMPrivate.h
+++ b/xpcom/build/nsXPCOMPrivate.h
@@ -43,6 +43,11 @@
 #include "nsXPCOM.h"
 #include "nsXPCOMStrings.h"
 #include "xptcall.h"
+
+#include "jsapi.h"
+#include "jscntxt.h"
+
+extern NS_COM JSRuntime *gJSRuntime;
 
 class nsStringContainer;
 class nsCStringContainer;
diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -467,14 +467,6 @@ NS_GetDebug(nsIDebug** result)
 }
 
 EXPORT_XPCOM_API(nsresult)
-NS_GetTraceRefcnt(nsITraceRefcnt** result)
-{
-    return nsTraceRefcntImpl::Create(nsnull, 
-                                     NS_GET_IID(nsITraceRefcnt), 
-                                     (void**) result);
-}
-
-EXPORT_XPCOM_API(nsresult)
 NS_InitXPCOM(nsIServiceManager* *result,
                              nsIFile* binDirectory)
 {
@@ -820,11 +812,6 @@ NS_ShutdownXPCOM(nsIServiceManager* serv
 
     // Finally, release the component manager last because it unloads the
     // libraries:
-    if (nsComponentManagerImpl::gComponentManager) {
-      nsrefcnt cnt;
-      NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
-      NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
-    }
     nsComponentManagerImpl::gComponentManager = nsnull;
 
 #ifdef DEBUG
diff --git a/xpcom/components/Makefile.in b/xpcom/components/Makefile.in
--- a/xpcom/components/Makefile.in
+++ b/xpcom/components/Makefile.in
@@ -49,6 +49,7 @@ MOZILLA_INTERNAL_API = 1
 MOZILLA_INTERNAL_API = 1
 
 REQUIRES	= string \
+		  js \
 		  $(NULL)
 
 CPPSRCS		= \
diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -163,12 +163,13 @@ static void GetIDString(const nsID& aCID
                 (PRUint32) aCID.m3[6], (PRUint32) aCID.m3[7]);
 }
 
-nsresult
-nsGetServiceFromCategory::operator()(const nsIID& aIID, void** aInstancePtr) const
+void*
+nsGetServiceFromCategory::get(const nsIID& aIID) const
 {
     nsresult rv;
     nsXPIDLCString value;
     nsCOMPtr<nsICategoryManager> catman;
+    void *result = NULL;
     nsComponentManagerImpl *compMgr = nsComponentManagerImpl::gComponentManager;
     if (!compMgr) {
         rv = NS_ERROR_NOT_INITIALIZED;
@@ -197,14 +198,14 @@ nsGetServiceFromCategory::operator()(con
 
     rv = compMgr->
         nsComponentManagerImpl::GetServiceByContractID(value,
-                                                       aIID, aInstancePtr);
+                                                       aIID, &result);
     if (NS_FAILED(rv)) {
     error:
-        *aInstancePtr = 0;
+        result = NULL;
     }
     if (mErrorPtr)
         *mErrorPtr = rv;
-    return rv;
+    return result;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -3230,9 +3231,12 @@ nsComponentManagerImpl::AutoRegister(nsI
     nsresult rv;
 
     if (!mCategoryManager) {
-        mCategoryManager = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
+        nsICategoryManager* catMan =
+            do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
         if (NS_FAILED(rv))
             return rv;
+
+        mCategoryManager = static_cast<nsCategoryManager*>(catMan);
     }
 
     GetAllLoaders();
diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -454,7 +454,6 @@ PermanentAtomImpl::~PermanentAtomImpl()
 PermanentAtomImpl::~PermanentAtomImpl()
 {
   // So we can tell if we were permanent while running the base class dtor.
-  mRefCnt = REFCNT_PERMANENT_SENTINEL;
 }
 
 NS_IMETHODIMP_(nsrefcnt) PermanentAtomImpl::AddRef()
diff --git a/xpcom/ds/nsAtomTable.h b/xpcom/ds/nsAtomTable.h
--- a/xpcom/ds/nsAtomTable.h
+++ b/xpcom/ds/nsAtomTable.h
@@ -65,7 +65,8 @@ public:
 
   // We can't use the virtual function in the base class destructor.
   PRBool IsPermanentInDestructor() {
-    return mRefCnt == REFCNT_PERMANENT_SENTINEL;
+    // XXXbsmedberg: going away next!
+    return PR_TRUE;
   }
 
   void* operator new(size_t size, const nsACString& aString) CPP_THROW_NEW;
@@ -75,7 +76,7 @@ public:
   }
 
   // for |#ifdef NS_BUILD_REFCNT_LOGGING| access to reference count
-  nsrefcnt GetRefCount() { return mRefCnt; }
+  nsrefcnt GetRefCount() { return 1; }
 
   // The length of the string in the atom.
   PRUint32 mLength;
diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -113,9 +113,9 @@ extern NS_COM nsIAtom* NS_NewAtom(const 
 extern NS_COM nsIAtom* NS_NewAtom(const char* aUTF8String);
 extern NS_COM nsIAtom* NS_NewPermanentAtom(const char* aUTF8String);
 
-inline already_AddRefed<nsIAtom> do_GetAtom(const char* aUTF8String)
+inline nsIAtom* do_GetAtom(const char* aUTF8String)
     { return NS_NewAtom(aUTF8String); }
-inline already_AddRefed<nsIAtom> do_GetPermanentAtom(const char* aUTF8String)
+inline nsIAtom* do_GetPermanentAtom(const char* aUTF8String)
     { return NS_NewPermanentAtom(aUTF8String); }
  
 /**
@@ -124,9 +124,9 @@ extern NS_COM nsIAtom* NS_NewAtom(const 
 extern NS_COM nsIAtom* NS_NewAtom(const nsACString& aUTF8String);
 extern NS_COM nsIAtom* NS_NewPermanentAtom(const nsACString& aUTF8String);
 
-inline already_AddRefed<nsIAtom> do_GetAtom(const nsACString& aUTF8String)
+inline nsIAtom* do_GetAtom(const nsACString& aUTF8String)
     { return NS_NewAtom(aUTF8String); }
-inline already_AddRefed<nsIAtom> do_GetPermanentAtom(const nsACString& aUTF8String)
+inline nsIAtom* do_GetPermanentAtom(const nsACString& aUTF8String)
     { return NS_NewPermanentAtom(aUTF8String); }
 
 /**
@@ -136,9 +136,9 @@ extern NS_COM nsIAtom* NS_NewAtom(const 
 extern NS_COM nsIAtom* NS_NewAtom(const PRUnichar* aUTF16String);
 extern NS_COM nsIAtom* NS_NewPermanentAtom(const PRUnichar* aUTF16String);
 
-inline already_AddRefed<nsIAtom> do_GetAtom(const PRUnichar* aUTF16String)
+inline nsIAtom* do_GetAtom(const PRUnichar* aUTF16String)
     { return NS_NewAtom(aUTF16String); }
-inline already_AddRefed<nsIAtom> do_GetPermanentAtom(const PRUnichar* aUTF16String)
+inline nsIAtom* do_GetPermanentAtom(const PRUnichar* aUTF16String)
     { return NS_NewPermanentAtom(aUTF16String); }
 
 /**
@@ -147,9 +147,9 @@ extern NS_COM nsIAtom* NS_NewAtom(const 
 extern NS_COM nsIAtom* NS_NewAtom(const nsAString& aUTF16String);
 extern NS_COM nsIAtom* NS_NewPermanentAtom(const nsAString& aUTF16String);
 
-inline already_AddRefed<nsIAtom> do_GetAtom(const nsAString& aUTF16String)
+inline nsIAtom* do_GetAtom(const nsAString& aUTF16String)
     { return NS_NewAtom(aUTF16String); }
-inline already_AddRefed<nsIAtom> do_GetPermanentAtom(const nsAString& aUTF16String)
+inline nsIAtom* do_GetPermanentAtom(const nsAString& aUTF16String)
     { return NS_NewPermanentAtom(aUTF16String); }
 
 /**
diff --git a/xpcom/ds/nsICollection.idl b/xpcom/ds/nsICollection.idl
--- a/xpcom/ds/nsICollection.idl
+++ b/xpcom/ds/nsICollection.idl
@@ -63,7 +63,7 @@ interface nsICollection : nsISerializabl
 #include "nsCOMPtr.h"
 #endif
 
-class NS_COM nsQueryElementAt : public nsCOMPtr_helper
+class NS_COM nsQueryElementAt
   {
     public:
       nsQueryElementAt( nsICollection* aCollection, PRUint32 aIndex, nsresult* aErrorPtr )
@@ -74,9 +74,15 @@ class NS_COM nsQueryElementAt : public n
           // nothing else to do here
         }
 
-      virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** ) const;
+      template<class D>
+      operator D*() const
+      {
+          return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
+      }
 
     private:
+      void* get(const nsIID &aIID) const;
+
       nsICollection*  mCollection;
       PRUint32        mIndex;
       nsresult*       mErrorPtr;
diff --git a/xpcom/ds/nsSupportsArray.cpp b/xpcom/ds/nsSupportsArray.cpp
--- a/xpcom/ds/nsSupportsArray.cpp
+++ b/xpcom/ds/nsSupportsArray.cpp
@@ -112,17 +112,18 @@ SupportsStats gSupportsStats;
 SupportsStats gSupportsStats;
 #endif
 
-nsresult
-nsQueryElementAt::operator()( const nsIID& aIID, void** aResult ) const
+void*
+nsQueryElementAt::get(const nsIID &aIID) const
   {
+    void *result = NULL;
     nsresult status = mCollection
-                        ? mCollection->QueryElementAt(mIndex, aIID, aResult)
+                        ? mCollection->QueryElementAt(mIndex, aIID, &result)
                         : NS_ERROR_NULL_POINTER;
 
     if ( mErrorPtr )
       *mErrorPtr = status;
 
-    return status;
+    return result;
   }
 
 static const PRInt32 kGrowArrayBy = 8;
diff --git a/xpcom/glue/Makefile.in b/xpcom/glue/Makefile.in
--- a/xpcom/glue/Makefile.in
+++ b/xpcom/glue/Makefile.in
@@ -51,6 +51,7 @@ DIST_INSTALL	= 1
 
 REQUIRES = \
 		string \
+		js \
 		$(NULL)
 
 ifdef NS_TRACE_MALLOC
diff --git a/xpcom/glue/nsArrayEnumerator.cpp b/xpcom/glue/nsArrayEnumerator.cpp
--- a/xpcom/glue/nsArrayEnumerator.cpp
+++ b/xpcom/glue/nsArrayEnumerator.cpp
@@ -136,14 +136,10 @@ public:
     NS_DECL_NSISIMPLEENUMERATOR
 
     // nsSimpleArrayEnumerator methods
-    nsCOMArrayEnumerator() : mIndex(0) {
-    }
+    nsCOMArrayEnumerator(const nsCOMArray_base &array);
 
     // specialized operator to make sure we make room for mValues
-    void* operator new (size_t size, const nsCOMArray_base& aArray) CPP_THROW_NEW;
-    void operator delete(void* ptr) {
-        ::operator delete(ptr);
-    }
+    void* operator new (size_t size, PRUint32 item_count) CPP_THROW_NEW;
 
 private:
     ~nsCOMArrayEnumerator(void);
@@ -157,6 +153,18 @@ protected:
 };
 
 NS_IMPL_ISUPPORTS1(nsCOMArrayEnumerator, nsISimpleEnumerator)
+
+nsCOMArrayEnumerator::nsCOMArrayEnumerator(const nsCOMArray_base &array)
+    : mIndex(0)
+    , mArraySize(array.Count())
+{
+    for (PRInt32 i = mArraySize - 1; i >= 0; --i) {
+        if (array[i])
+            NS_GetGC()->WriteBarrier(&mValueArray[i], array[i]);
+        else
+            mValueArray[i] = NULL;
+    }
+}
 
 nsCOMArrayEnumerator::~nsCOMArrayEnumerator()
 {
@@ -200,38 +208,22 @@ nsCOMArrayEnumerator::GetNext(nsISupport
 }
 
 void*
-nsCOMArrayEnumerator::operator new (size_t size, const nsCOMArray_base& aArray)
+nsCOMArrayEnumerator::operator new (size_t size, PRUint32 item_count)
     CPP_THROW_NEW
 {
     // create enough space such that mValueArray points to a large
     // enough value. Note that the initial value of size gives us
     // space for mValueArray[0], so we must subtract
-    size += (aArray.Count() - 1) * sizeof(aArray[0]);
+    size += (item_count - 1) * sizeof(nsISupports*);
 
-    // do the actual allocation
-    nsCOMArrayEnumerator * result =
-        static_cast<nsCOMArrayEnumerator*>(::operator new(size));
-    NS_ENSURE_TRUE(result, nsnull);
-
-    // now need to copy over the values, and addref each one
-    // now this might seem like a lot of work, but we're actually just
-    // doing all our AddRef's ahead of time since GetNext() doesn't
-    // need to AddRef() on the way out
-    PRUint32 i;
-    PRUint32 max = result->mArraySize = aArray.Count();
-    for (i = 0; i<max; i++) {
-        result->mValueArray[i] = aArray[i];
-        NS_IF_ADDREF(result->mValueArray[i]);
-    }
-
-    return result;
+    return MMgc::GCFinalizedObject::operator new(size, NS_GetGC());
 }
 
 nsresult
 NS_NewArrayEnumerator(nsISimpleEnumerator* *aResult,
                       const nsCOMArray_base& aArray)
 {
-    nsCOMArrayEnumerator *enumerator = new (aArray) nsCOMArrayEnumerator();
+    nsCOMArrayEnumerator *enumerator = new (aArray.Count()) nsCOMArrayEnumerator(aArray);
     if (!enumerator) return NS_ERROR_OUT_OF_MEMORY;
 
     NS_ADDREF(*aResult = enumerator);
diff --git a/xpcom/glue/nsArrayUtils.cpp b/xpcom/glue/nsArrayUtils.cpp
--- a/xpcom/glue/nsArrayUtils.cpp
+++ b/xpcom/glue/nsArrayUtils.cpp
@@ -41,15 +41,16 @@
 //
 // do_QueryElementAt helper stuff
 //
-nsresult
-nsQueryArrayElementAt::operator()(const nsIID& aIID, void** aResult) const
-  {
+void*
+nsQueryArrayElementAt::get(const nsIID& aIID) const
+{
+    void *result = NULL;
     nsresult status = mArray
-        ? mArray->QueryElementAt(mIndex, aIID, aResult)
+        ? mArray->QueryElementAt(mIndex, aIID, &result)
         : NS_ERROR_NULL_POINTER;
 
     if (mErrorPtr)
       *mErrorPtr = status;
 
-    return status;
-  }
+    return result;
+}
diff --git a/xpcom/glue/nsArrayUtils.h b/xpcom/glue/nsArrayUtils.h
--- a/xpcom/glue/nsArrayUtils.h
+++ b/xpcom/glue/nsArrayUtils.h
@@ -43,25 +43,31 @@
 #include "nsIArray.h"
 
 // helper class for do_QueryElementAt
-class NS_COM_GLUE nsQueryArrayElementAt : public nsCOMPtr_helper
-  {
-    public:
-      nsQueryArrayElementAt(nsIArray* aArray, PRUint32 aIndex,
-                            nsresult* aErrorPtr)
-          : mArray(aArray),
-            mIndex(aIndex),
-            mErrorPtr(aErrorPtr)
-        {
-          // nothing else to do here
-        }
+class NS_COM_GLUE nsQueryArrayElementAt
+{
+public:
+    nsQueryArrayElementAt(nsIArray* aArray, PRUint32 aIndex,
+                          nsresult* aErrorPtr) :
+        mArray(aArray),
+        mIndex(aIndex),
+        mErrorPtr(aErrorPtr)
+    {
+        // nothing else to do here
+    }
 
-      virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const;
+    template<class D>
+    operator D*() const
+    {
+        return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
+    }
 
-    private:
-      nsIArray*  mArray;
-      PRUint32   mIndex;
-      nsresult*  mErrorPtr;
-  };
+private:
+    void* get(const nsIID &aIID) const;
+
+    nsIArray*  mArray;
+    PRUint32   mIndex;
+    nsresult*  mErrorPtr;
+};
 
 inline
 const nsQueryArrayElementAt
diff --git a/xpcom/glue/nsCOMPtr.cpp b/xpcom/glue/nsCOMPtr.cpp
deleted file mode 100644
--- a/xpcom/glue/nsCOMPtr.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Scott Collins <scc@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * 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 "nsCOMPtr.h"
-
-nsresult
-nsQueryInterface::operator()( const nsIID& aIID, void** answer ) const
-	{
-		nsresult status;
-		if ( mRawPtr )
-			{
-				status = mRawPtr->QueryInterface(aIID, answer);
-#ifdef NSCAP_FEATURE_TEST_NONNULL_QUERY_SUCCEEDS
-				NS_ASSERTION(NS_SUCCEEDED(status), "interface not found---were you expecting that?");
-#endif
-			}
-		else
-			status = NS_ERROR_NULL_POINTER;
-		
-		return status;
-	}
-
-nsresult
-nsQueryInterfaceWithError::operator()( const nsIID& aIID, void** answer ) const
-	{
-		nsresult status;
-		if ( mRawPtr )
-			{
-				status = mRawPtr->QueryInterface(aIID, answer);
-#ifdef NSCAP_FEATURE_TEST_NONNULL_QUERY_SUCCEEDS
-				NS_ASSERTION(NS_SUCCEEDED(status), "interface not found---were you expecting that?");
-#endif
-			}
-		else
-			status = NS_ERROR_NULL_POINTER;
-		
-		if ( mErrorPtr )
-			*mErrorPtr = status;
-		return status;
-	}
-
-nsCOMPtr_base::~nsCOMPtr_base()
-	{
-	  NSCAP_LOG_RELEASE(this, mRawPtr);
-		if ( mRawPtr )
-			NSCAP_RELEASE(this, mRawPtr);
-	}
-
-void
-nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
-	{
-    if ( rawPtr )
-    	NSCAP_ADDREF(this, rawPtr);
-    assign_assuming_AddRef(rawPtr);
-	}
-
-void
-nsCOMPtr_base::assign_from_qi( const nsQueryInterface qi, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( qi(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void
-nsCOMPtr_base::assign_from_qi_with_error( const nsQueryInterfaceWithError& qi, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( qi(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void
-nsCOMPtr_base::assign_from_gs_cid( const nsGetServiceByCID gs, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void
-nsCOMPtr_base::assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError& gs, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void
-nsCOMPtr_base::assign_from_gs_contractid( const nsGetServiceByContractID gs, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void
-nsCOMPtr_base::assign_from_gs_contractid_with_error( const nsGetServiceByContractIDWithError& gs, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void
-nsCOMPtr_base::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& iid )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( helper(iid, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
-  }
-
-void**
-nsCOMPtr_base::begin_assignment()
-  {
-    assign_assuming_AddRef(0);
-    return reinterpret_cast<void**>(&mRawPtr);
-  }
diff --git a/xpcom/glue/nsCOMPtr.h b/xpcom/glue/nsCOMPtr.h
--- a/xpcom/glue/nsCOMPtr.h
+++ b/xpcom/glue/nsCOMPtr.h
@@ -22,6 +22,7 @@
  * Contributor(s):
  *   Scott Collins <scc@mozilla.org> (original author)
  *   L. David Baron <dbaron@dbaron.org>
+ *   Benjamin Smedberg <benjamin@smedbergs.us>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -41,18 +42,12 @@
 #define nsCOMPtr_h___
 
 /*
-  Having problems?
-  
-  See the User Manual at:
-    http://www.mozilla.org/projects/xpcom/nsCOMPtr.html
+  nsCOMPtr -- a code-compatibility wrapper for MMgc write barriers.
 
-
-  nsCOMPtr
-    better than a raw pointer
-  for owning objects
-                       -- scc
+  New code should use MMgc::WriteBarrier<type> instead.
 */
 
+#include "MMgc.h"
 
   // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
 #ifndef nsDebug_h___
@@ -65,1641 +60,516 @@
   // for |nsresult|, |NS_ADDREF|, |NS_GET_TEMPLATE_IID| et al
 #endif
 
-#ifndef nscore_h___
-#include "nscore.h"
-  // for |NS_COM_GLUE|
+// DEPRECATED: DO NOT USE THESE METHODS IN NEW CODE
+
+template<class T>
+inline
+T*
+getter_AddRefs(T *aRawPtr)
+{
+  return aRawPtr;
+}
+
+template<class T>
+inline
+T*
+dont_AddRef(T *aRawPtr)
+{
+  return aRawPtr;
+}
+
+// END DEPRECATED
+
+class FakeForNull;
+
+/**
+ * nsCOMPtr Helper classes transform commonly called non-typesafe
+ * getters into typesafe forms that are convenient to call.
+ *
+ * Here are the rules for a helper:
+ *   - it implements a templated |operator()| to produce an interface pointer
+ *   - the helper is responsible for returning NULL if the underlying
+ *     method fails
+ *
+ * See |class nsQueryInterface| for an example.
+ */
+
+template<class T>
+class
+  NS_FINAL_CLASS
+  NS_GC_TYPE
+nsCOMPtr
+{
+public:
+  nsCOMPtr() :
+    mRawPtr(NULL)
+  {
+    ASSERT_GCObject(this);
+  }
+
+  nsCOMPtr(T *t) :
+    mRawPtr(NULL)
+  {
+    ASSERT_GCObject(this);
+    set(t);
+  }
+
+  nsCOMPtr(T *t, const void *container) :
+    mRawPtr(NULL)
+  {
+    ASSERT_GCObject(this);
+    set(t, container);
+  }
+
+  template<class Helper>
+  nsCOMPtr(const Helper &helper) :
+    mRawPtr(NULL)
+  {
+    ASSERT_GCObject(this);
+    set((T*) helper);
+  }
+
+  T*
+  operator=(T *t)
+  {
+    set(t);
+    return mRawPtr;
+  }
+
+  template<class Helper>
+  T*
+  operator=(const Helper &helper)
+  {
+    set((T*) helper);
+    return mRawPtr;
+  }
+
+  ~nsCOMPtr()
+  {
+    mRawPtr = NULL;
+  }
+
+  void
+  swap(nsCOMPtr<T> &rhs)
+  {
+    T *temp = rhs;
+    rhs = mRawPtr;
+    set(temp);
+  }
+
+  void
+  swap(T *&rhs)
+  {
+    T *temp = rhs;
+    rhs = mRawPtr;
+    set(temp);
+  }
+
+  T*
+  forget()
+  {
+    T* temp = mRawPtr;
+    mRawPtr = NULL;
+    return temp;
+  }
+
+  void
+  forget(T **rhs)
+  {
+    *rhs = mRawPtr;
+    mRawPtr = NULL;
+  }
+
+  T*
+  get() const
+  {
+    return mRawPtr;
+  }
+
+  operator T*() const
+  {
+    return mRawPtr;
+  }
+
+  T*
+  operator->() const
+  {
+    NS_ASSERTION(mRawPtr, "Dereferencing a NULL nsCOMPtr with operator->().");
+    return mRawPtr;
+  }
+
+private:
+  void set(T *t)
+  {
+    if (!t || t == mRawPtr) {
+      mRawPtr = t;
+      return;
+    }
+
+    ASSERT_GCObject(t);
+
+#if 1
+    MMgc::GC::WriteBarrier(this, t);
+#else
+    // XXXbsmedberg: until there are no more stack nsCOMPtrs, do a slow check
+    if (NS_GetGC()->IsPointerToGCPage(this))
+      MMgc::GC::WriteBarrier(this, t);
+    else
+      mRawPtr = t;
 #endif
+  }
 
+  void set(T *t, const void *container)
+  {
+    if (!t || t == mRawPtr) {
+      mRawPtr = t;
+      return;
+    }
 
-/*
-  WARNING:
-    This file defines several macros for internal use only.  These macros begin with the
-    prefix |NSCAP_|.  Do not use these macros in your own code.  They are for internal use
-    only for cross-platform compatibility, and are subject to change without notice.
-*/
+    ASSERT_GCObject(t);
 
+    WB(NS_GetGC(), container, &mRawPtr, t);
+  }
 
-#ifdef _MSC_VER
-  #define NSCAP_FEATURE_INLINE_STARTASSIGNMENT
-    // under VC++, we win by inlining StartAssignment
+  T *mRawPtr;
+};
 
-    // Also under VC++, at the highest warning level, we are overwhelmed  with warnings
-    //  about (unused) inline functions being removed.  This is to be expected with
-    //  templates, so we disable the warning.
-  #pragma warning( disable: 4514 )
-#endif
+template<class T>
+nsCOMPtr<T>*
+address_of(nsCOMPtr<T> &p)
+{
+  return &p;
+}
 
-#define NSCAP_FEATURE_USE_BASE
+// There are many permutations of operator== and operator!= needed to avoid
+// ambiguities.
 
-#ifdef NS_DEBUG
-  #define NSCAP_FEATURE_TEST_DONTQUERY_CASES
-  #undef NSCAP_FEATURE_USE_BASE
-//#define NSCAP_FEATURE_TEST_NONNULL_QUERY_SUCCEEDS
-#endif
+template<class T, class U>
+inline bool
+operator==(const nsCOMPtr<T> &lhs, const nsCOMPtr<U> &rhs)
+{
+  return lhs.get() == rhs.get();
+}
 
-  /*
-    |...TEST_DONTQUERY_CASES| and |...DEBUG_PTR_TYPES| introduce some code that is 
-    problematic on a select few of our platforms, e.g., QNX.  Therefore, I'm providing
-    a mechanism by which these features can be explicitly disabled from the command-line.
-  */
+template<class T, class U>
+inline bool
+operator!=(const nsCOMPtr<T> &lhs, const nsCOMPtr<U> &rhs)
+{
+  return lhs.get() != rhs.get();
+}
 
-#ifdef NSCAP_DISABLE_TEST_DONTQUERY_CASES
-  #undef NSCAP_FEATURE_TEST_DONTQUERY_CASES
-#endif
+template<class T, class U>
+inline bool
+operator==(const nsCOMPtr<T> &lhs, const U *rhs)
+{
+  return lhs.get() == rhs;
+}
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-  // Our use of nsCOMPtr_base::mRawPtr violates the C++ standard's aliasing
-  // rules. Mark it with the may_alias attribute so that gcc 3.3 and higher
-  // don't reorder instructions based on aliasing assumptions for
-  // this variable.  Fortunately, gcc versions < 3.3 do not do any
-  // optimizations that break nsCOMPtr.
+template<class T, class U>
+inline bool
+operator!=(const nsCOMPtr<T> &lhs, const U *rhs)
+{
+  return lhs.get() != rhs;
+}
 
-  #define NS_MAY_ALIAS_PTR(t)    t*  __attribute__((__may_alias__))
-#else
-  #define NS_MAY_ALIAS_PTR(t)    t*
-#endif
+template<class T, class U>
+inline bool
+operator==(const T *lhs, const nsCOMPtr<U> &rhs)
+{
+  return lhs == rhs.get();
+}
 
-#if defined(NSCAP_DISABLE_DEBUG_PTR_TYPES)
-  #define NSCAP_FEATURE_USE_BASE
-#endif
+template<class T, class U>
+inline bool
+operator!=(const T *lhs, const nsCOMPtr<U> &rhs)
+{
+  return lhs != rhs.get();
+}
 
+// To avoid ambiguities caused by the presence of builtin |operator==|s
+// creating a situation where one of the |operator==| defined above
+// has a better conversion for one argument and the builtin has a
+// better conversion for the other argument, define additional
+// |operator==| without the |const| on the raw pointer.
+// See bug 65664 for details.
 
-#ifdef HAVE_CPP_BOOL
-  typedef bool NSCAP_BOOL;
-#else
-  typedef PRBool NSCAP_BOOL;
-#endif
+template<class T, class U>
+inline bool
+operator==(const nsCOMPtr<T> &lhs, U *rhs)
+{
+  return lhs.get() == rhs;
+}
 
+template<class T, class U>
+inline bool
+operator!=(const nsCOMPtr<T> &lhs, U *rhs)
+{
+  return lhs.get() != rhs;
+}
 
+template<class T, class U>
+inline bool
+operator==(T *lhs, const nsCOMPtr<U> &rhs)
+{
+  return lhs == rhs.get();
+}
 
+template<class T, class U>
+inline bool
+operator!=(T *lhs, const nsCOMPtr<U> &rhs)
+{
+  return lhs != rhs.get();
+}
 
-  /*
-    The following three macros (|NSCAP_ADDREF|, |NSCAP_RELEASE|, and |NSCAP_LOG_ASSIGNMENT|)
-      allow external clients the ability to add logging or other interesting debug facilities.
-      In fact, if you want |nsCOMPtr| to participate in the standard logging facility, you
-      provide (e.g., in "nsTraceRefcnt.h") suitable definitions
-
-        #define NSCAP_ADDREF(this, ptr)         NS_ADDREF(ptr)
-        #define NSCAP_RELEASE(this, ptr)        NS_RELEASE(ptr)
-  */
-
-#ifndef NSCAP_ADDREF
-  #define NSCAP_ADDREF(this, ptr)     (ptr)->AddRef()
-#endif
-
-#ifndef NSCAP_RELEASE
-  #define NSCAP_RELEASE(this, ptr)    (ptr)->Release()
-#endif
-
-  // Clients can define |NSCAP_LOG_ASSIGNMENT| to perform logging.
-#ifdef NSCAP_LOG_ASSIGNMENT
-    // Remember that |NSCAP_LOG_ASSIGNMENT| was defined by some client so that we know
-    //  to instantiate |~nsGetterAddRefs| in turn to note the external assignment into
-    //  the |nsCOMPtr|.
-  #define NSCAP_LOG_EXTERNAL_ASSIGNMENT
-#else
-    // ...otherwise, just strip it out of the code
-  #define NSCAP_LOG_ASSIGNMENT(this, ptr)
-#endif
-
-#ifndef NSCAP_LOG_RELEASE
-  #define NSCAP_LOG_RELEASE(this, ptr)
-#endif
-
-
-
-
-  /*
-    WARNING:
-      VC++4.2 is very picky.  To compile under VC++4.2, the classes must be defined
-      in an order that satisfies:
-    
-        nsDerivedSafe < nsCOMPtr
-        already_AddRefed < nsCOMPtr
-        nsCOMPtr < nsGetterAddRefs
-
-      The other compilers probably won't complain, so please don't reorder these
-      classes, on pain of breaking 4.2 compatibility.
-  */
-
-
+/**
+ * nsGetterAddRefs is used for XPCOM out parameters that need to be assigned
+ * to nsCOMPtr members. We can't pass the address of nsCOMPtr.mRawPtr directly
+ * because of the need to set the write barrier.
+ */
 template <class T>
 class
+  NS_STACK_CLASS
   NS_FINAL_CLASS
-  NS_STACK_CLASS
-nsDerivedSafe : public T
-    /*
-      No client should ever see or have to type the name of this class.  It is the
-      artifact that makes it a compile-time error to call |AddRef| and |Release|
-      on a |nsCOMPtr|.  DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.
-
-      See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
-
-      This type should be a nested class inside |nsCOMPtr<T>|.
-    */
+nsGetterAddRefs
+{
+public:
+  explicit
+  nsGetterAddRefs(nsCOMPtr<T> &aSmartPtr) :
+    mTempPtr(aSmartPtr),
+    mTargetSmartPtr(aSmartPtr)
   {
-    private:
-#ifdef HAVE_CPP_ACCESS_CHANGING_USING
-      using T::AddRef;
-      using T::Release;
-#else
-      nsrefcnt AddRef(void);
-      nsrefcnt Release(void);
-#endif
-
-#if !defined(AIX) && !defined(IRIX)
-      void operator delete( void*, size_t );                  // NOT TO BE IMPLEMENTED
-        // declaring |operator delete| private makes calling delete on an interface pointer a compile error
-#endif
-
-      nsDerivedSafe<T>& operator=( const T& );                // NOT TO BE IMPLEMENTED
-        // you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
-
-        /*
-          Compiler warnings and errors: nsDerivedSafe operator=() hides inherited operator=().
-          If you see that, that means somebody checked in a [XP]COM interface class that declares an
-          |operator=()|, and that's _bad_.  So bad, in fact, that this declaration exists explicitly
-          to stop people from doing it.
-        */
-
-    protected:
-      nsDerivedSafe();                                        // NOT TO BE IMPLEMENTED
-        /*
-          This ctor exists to avoid compile errors and warnings about nsDeriviedSafe using the
-          default ctor but inheriting classes without an empty ctor. See bug 209667.
-        */
-  };
-
-#if !defined(HAVE_CPP_ACCESS_CHANGING_USING) && defined(NEED_CPP_UNUSED_IMPLEMENTATIONS)
-template <class T>
-nsrefcnt
-nsDerivedSafe<T>::AddRef()
-  {
-    return 0;
+    // nothing else to do
   }
 
-template <class T>
-nsrefcnt
-nsDerivedSafe<T>::Release()
+  ~nsGetterAddRefs()
   {
-    return 0;
+    mTargetSmartPtr = mTempPtr;
   }
 
-#endif
+  operator void**()
+  {
+    return reinterpret_cast<void**>(&mTempPtr);
+  }
 
+  // bsmedberg asserts this signature shouldn't ever be necessary
+  operator nsISupports**()
+  {
+    return reinterpret_cast<nsISupports**>(&mTempPtr);
+  }
 
+  operator T**()
+  {
+    return &mTempPtr;
+  }
 
-template <class T>
-struct already_AddRefed
-    /*
-      ...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
-      |AddRef|ing it.  You might want to use this as a return type from a function
-      that produces an already |AddRef|ed pointer as a result.
+  T*&
+  operator*()
+  {
+    return mTempPtr;
+  }
 
-      See also |getter_AddRefs()|, |dont_AddRef()|, and |class nsGetterAddRefs|.
+private:
+  T* mTempPtr;
+  nsCOMPtr<T> &mTargetSmartPtr;
+};
 
-      This type should be a nested class inside |nsCOMPtr<T>|.
+NS_SPECIALIZE_TEMPLATE
+class
+  NS_STACK_CLASS
+  NS_FINAL_CLASS
+nsGetterAddRefs<nsISupports>
+{
+public:
+  explicit
+  nsGetterAddRefs(nsCOMPtr<nsISupports> &aSmartPtr) :
+    mTempPtr(aSmartPtr),
+    mTargetSmartPtr(aSmartPtr)
+  {
+    // nothing else to do
+  }
 
-      Yes, |already_AddRefed| could have been implemented as an |nsCOMPtr_helper| to
-      avoid adding specialized machinery to |nsCOMPtr| ... but this is the simplest
-      case, and perhaps worth the savings in time and space that its specific
-      implementation affords over the more general solution offered by
-      |nsCOMPtr_helper|.
-    */
+  ~nsGetterAddRefs()
   {
-    already_AddRefed( T* aRawPtr )
-        : mRawPtr(aRawPtr)
-      {
-        // nothing else to do here
-      }
+    mTargetSmartPtr = mTempPtr;
+  }
 
-    T* get() const { return mRawPtr; }
+  operator void**()
+  {
+    return reinterpret_cast<void**>(&mTempPtr);
+  }
 
-    T* mRawPtr;
-  };
+  operator nsISupports**()
+  {
+    return &mTempPtr;
+  }
+
+  nsISupports*&
+  operator*()
+  {
+    return mTempPtr;
+  }
+
+private:
+  nsISupports* mTempPtr;
+  nsCOMPtr<nsISupports> &mTargetSmartPtr;
+};
 
 template <class T>
 inline
-const already_AddRefed<T>
-getter_AddRefs( T* aRawPtr )
-    /*
-      ...makes typing easier, because it deduces the template type, e.g., 
-      you write |dont_AddRef(fooP)| instead of |already_AddRefed<IFoo>(fooP)|.
-    */
-  {
-    return already_AddRefed<T>(aRawPtr);
-  }
+nsGetterAddRefs<T>
+getter_AddRefs(nsCOMPtr<T> &aSmartPtr)
+/*
+  Used around a |nsCOMPtr| when 
+  ...makes the class |nsGetterAddRefs<T>| invisible.
+*/
+{
+  return nsGetterAddRefs<T>(aSmartPtr);
+}
 
-template <class T>
-inline
-const already_AddRefed<T>
-getter_AddRefs( const already_AddRefed<T> aAlreadyAddRefedPtr )
-  {
-    return aAlreadyAddRefedPtr;
-  }
-
-template <class T>
-inline
-const already_AddRefed<T>
-dont_AddRef( T* aRawPtr )
-  {
-    return already_AddRefed<T>(aRawPtr);
-  }
-
-template <class T>
-inline
-const already_AddRefed<T>
-dont_AddRef( const already_AddRefed<T> aAlreadyAddRefedPtr )
-  {
-    return aAlreadyAddRefedPtr;
-  }
-
-
-
-class nsCOMPtr_helper
-    /*
-      An |nsCOMPtr_helper| transforms commonly called getters into typesafe forms
-      that are more convenient to call, and more efficient to use with |nsCOMPtr|s.
-      Good candidates for helpers are |QueryInterface()|, |CreateInstance()|, etc.
-
-      Here are the rules for a helper:
-        - it implements |operator()| to produce an interface pointer
-        - (except for its name) |operator()| is a valid [XP]COM `getter'
-        - the interface pointer that it returns is already |AddRef()|ed (as from any good getter)
-        - it matches the type requested with the supplied |nsIID| argument
-        - its constructor provides an optional |nsresult*| that |operator()| can fill
-          in with an error when it is executed
-          
-      See |class nsGetInterface| for an example.
-    */
-  {
-    public:
-      virtual nsresult NS_FASTCALL operator()( const nsIID&, void** ) const = 0;
-  };
-
-/*
-  |nsQueryInterface| could have been implemented as an |nsCOMPtr_helper| to
-  avoid adding specialized machinery in |nsCOMPtr|, But |do_QueryInterface|
-  is called often enough that the codesize savings are big enough to
-  warrant the specialcasing.
-*/
+////////////////////////////////////////////////////////////////////////////
+// Using QueryInterface with COMPtrs
 
 class
   NS_COM_GLUE
   NS_STACK_CLASS
   NS_FINAL_CLASS
 nsQueryInterface
+{
+public:
+  explicit
+  nsQueryInterface(nsISupports *aRawPtr) :
+    mRawPtr(aRawPtr)
   {
-    public:
-      explicit
-      nsQueryInterface( nsISupports* aRawPtr )
-          : mRawPtr(aRawPtr)
-        {
-          // nothing else to do here
-        }
+    // nothing else to do here
+  }
 
-      nsresult NS_FASTCALL operator()( const nsIID& aIID, void** ) const;
+  template<class D>
+  operator D*() const
+  {
+    return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
+  }
 
-    private:
-      nsISupports*  mRawPtr;
-  };
+ private:
+  void* NS_FASTCALL get(const nsIID &aIID) const
+  {
+    if (!mRawPtr)
+      return NULL;
 
-class NS_COM_GLUE nsQueryInterfaceWithError
+    void *result = nsnull;
+    nsresult rv = mRawPtr->QueryInterface(aIID, &result);
+    if (NS_FAILED(rv))
+      return NULL;
+
+    return result;
+  }
+
+  nsISupports *mRawPtr;
+};
+
+class
+  NS_COM_GLUE
+  NS_STACK_CLASS
+  NS_FINAL_CLASS
+nsQueryInterfaceWithError
+{
+public:
+  nsQueryInterfaceWithError(nsISupports *aRawPtr, nsresult *error) :
+    mRawPtr(aRawPtr),
+    mErrorPtr(error)
   {
-    public:
-      nsQueryInterfaceWithError( nsISupports* aRawPtr, nsresult* error )
-          : mRawPtr(aRawPtr),
-            mErrorPtr(error)
-        {
-          // nothing else to do here
-        }
+    NS_ASSERTION(mErrorPtr, "NULL nsresult* passed to do_QueryInterface");
+    // nothing else to do here
+  }
 
-      nsresult NS_FASTCALL operator()( const nsIID& aIID, void** ) const;
+  template<class D>
+  operator D*() const
+  {
+    return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
+  }
 
-    private:
-      nsISupports*  mRawPtr;
-      nsresult*     mErrorPtr;
-  };
+private:
+  void* NS_FASTCALL get(const nsIID &aIID) const
+  {
+    if (!mRawPtr) {
+      *mErrorPtr = NS_ERROR_NULL_POINTER;
+      return NULL;
+    }
+
+    void *result = nsnull;
+    *mErrorPtr = mRawPtr->QueryInterface(aIID, &result);
+    if (NS_FAILED(*mErrorPtr))
+      return NULL;
+
+    return result;
+  }
+
+  nsISupports *mRawPtr;
+  nsresult    *mErrorPtr;
+};
 
 inline
 nsQueryInterface
-do_QueryInterface( nsISupports* aRawPtr )
-  {
-    return nsQueryInterface(aRawPtr);
-  }
+do_QueryInterface(nsISupports *aRawPtr)
+{
+  return nsQueryInterface(aRawPtr);
+}
 
 inline
 nsQueryInterfaceWithError
-do_QueryInterface( nsISupports* aRawPtr, nsresult* error )
+do_QueryInterface(nsISupports *aRawPtr, nsresult *error)
+{
+  return nsQueryInterfaceWithError(aRawPtr, error);
+}
+
+// Comparing any two [XP]COM objects for identity
+
+template<class T, class DestinationType>
+inline
+nsresult
+CallQueryInterface( const nsCOMPtr<T> &aSource, DestinationType** aDestination )
+{
+  return CallQueryInterface((T*) aSource, aDestination);
+}
+
+inline
+bool
+SameCOMIdentity(nsISupports *lhs, nsISupports *rhs)
+{
+  nsISupports *reallhs = do_QueryInterface(lhs);
+  nsISupports *realrhs = do_QueryInterface(rhs);
+  return reallhs == realrhs;
+}
+
+// This is a deprecated wrapper for code compatibility. Don't use it!
+
+template<class T>
+class
+  NS_STACK_CLASS
+  NS_FINAL_CLASS
+already_AddRefed
+{
+public:
+  already_AddRefed(T* t = NULL) :
+    mRawPtr(t) { }
+
+  T* get() const
   {
-    return nsQueryInterfaceWithError(aRawPtr, error);
+    return mRawPtr;
   }
 
-template <class T>
-inline
-void
-do_QueryInterface( already_AddRefed<T>& )
+  operator T*() const
   {
-    // This signature exists solely to _stop_ you from doing the bad thing.
-    //  Saying |do_QueryInterface()| on a pointer that is not otherwise owned by
-    //  someone else is an automatic leak.  See <http://bugzilla.mozilla.org/show_bug.cgi?id=8221>.
+    return mRawPtr;
   }
 
-template <class T>
-inline
-void
-do_QueryInterface( already_AddRefed<T>&, nsresult* )
+  T* operator->() const
   {
-    // This signature exists solely to _stop_ you from doing the bad thing.
-    //  Saying |do_QueryInterface()| on a pointer that is not otherwise owned by
-    //  someone else is an automatic leak.  See <http://bugzilla.mozilla.org/show_bug.cgi?id=8221>.
+    return mRawPtr;
   }
 
-
-////////////////////////////////////////////////////////////////////////////
-// Using servicemanager with COMPtrs
-class NS_COM_GLUE nsGetServiceByCID
-{
- public:
-    explicit nsGetServiceByCID(const nsCID& aCID)
-        : mCID(aCID)
-        {
-            // nothing else to do
-        }
-    
-    nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
-    
- private:
-    const nsCID&                mCID;
+private:
+  T *mRawPtr;
 };
-
-class NS_COM_GLUE nsGetServiceByCIDWithError
-{
- public:
-    nsGetServiceByCIDWithError( const nsCID& aCID, nsresult* aErrorPtr )
-        : mCID(aCID),
-          mErrorPtr(aErrorPtr)
-        {
-            // nothing else to do
-        }
-    
-    nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
-    
- private:
-    const nsCID&                mCID;
-    nsresult*                   mErrorPtr;
-};
-
-class NS_COM_GLUE nsGetServiceByContractID
-{
- public:
-    explicit nsGetServiceByContractID(const char* aContractID)
-        : mContractID(aContractID)
-        {
-            // nothing else to do
-        }
-    
-    nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
-    
- private:
-    const char*                 mContractID;
-};
-
-class NS_COM_GLUE nsGetServiceByContractIDWithError
-{
- public:
-    nsGetServiceByContractIDWithError(const char* aContractID, nsresult* aErrorPtr)
-        : mContractID(aContractID),
-          mErrorPtr(aErrorPtr)
-        {
-            // nothing else to do
-        }
-    
-    nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
-    
- private:
-    const char*                 mContractID;
-    nsresult*                   mErrorPtr;
-};
-
-class
-nsCOMPtr_base
-    /*
-      ...factors implementation for all template versions of |nsCOMPtr|.
-
-      This should really be an |nsCOMPtr<nsISupports>|, but this wouldn't work
-      because unlike the
-
-      Here's the way people normally do things like this
-      
-        template <class T> class Foo { ... };
-        template <> class Foo<void*> { ... };
-        template <class T> class Foo<T*> : private Foo<void*> { ... };
-    */
-  {
-    public:
-
-      nsCOMPtr_base( nsISupports* rawPtr = 0 )
-          : mRawPtr(rawPtr)
-        {
-          // nothing else to do here
-        }
-
-      NS_COM_GLUE NS_CONSTRUCTOR_FASTCALL ~nsCOMPtr_base();
-
-      NS_COM_GLUE void NS_FASTCALL   assign_with_AddRef( nsISupports* );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_qi( const nsQueryInterface, const nsIID& );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_qi_with_error( const nsQueryInterfaceWithError&, const nsIID& );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_gs_cid( const nsGetServiceByCID, const nsIID& );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError&, const nsIID& );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_gs_contractid( const nsGetServiceByContractID, const nsIID& );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_gs_contractid_with_error( const nsGetServiceByContractIDWithError&, const nsIID& );
-      NS_COM_GLUE void NS_FASTCALL   assign_from_helper( const nsCOMPtr_helper&, const nsIID& );
-      NS_COM_GLUE void** NS_FASTCALL begin_assignment();
-
-    protected:
-      NS_MAY_ALIAS_PTR(nsISupports) mRawPtr;
-
-      void
-      assign_assuming_AddRef( nsISupports* newPtr )
-        {
-            /*
-              |AddRef()|ing the new value (before entering this function) before
-              |Release()|ing the old lets us safely ignore the self-assignment case.
-              We must, however, be careful only to |Release()| _after_ doing the
-              assignment, in case the |Release()| leads to our _own_ destruction,
-              which would, in turn, cause an incorrect second |Release()| of our old
-              pointer.  Thank <waterson@netscape.com> for discovering this.
-            */
-          nsISupports* oldPtr = mRawPtr;
-          mRawPtr = newPtr;
-          NSCAP_LOG_ASSIGNMENT(this, newPtr);
-          NSCAP_LOG_RELEASE(this, oldPtr);
-          if ( oldPtr )
-            NSCAP_RELEASE(this, oldPtr);
-        }
-  };
-
-// template <class T> class nsGetterAddRefs;
-
-template <class T>
-class
-  NS_FINAL_CLASS
-nsCOMPtr
-#ifdef NSCAP_FEATURE_USE_BASE
-    : private nsCOMPtr_base
-#endif
-  {
-
-#ifdef NSCAP_FEATURE_USE_BASE
-  #define NSCAP_CTOR_BASE(x) nsCOMPtr_base(x)
-#else
-  #define NSCAP_CTOR_BASE(x) mRawPtr(x)
-
-    private:
-      void    assign_with_AddRef( nsISupports* );
-      void    assign_from_qi( const nsQueryInterface, const nsIID& );
-      void    assign_from_qi_with_error( const nsQueryInterfaceWithError&, const nsIID& );
-      void    assign_from_gs_cid( const nsGetServiceByCID, const nsIID& );
-      void    assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError&, const nsIID& );
-      void    assign_from_gs_contractid( const nsGetServiceByContractID, const nsIID& );
-      void    assign_from_gs_contractid_with_error( const nsGetServiceByContractIDWithError&, const nsIID& );
-      void    assign_from_helper( const nsCOMPtr_helper&, const nsIID& );
-      void**  begin_assignment();
-
-      void
-      assign_assuming_AddRef( T* newPtr )
-        {
-          T* oldPtr = mRawPtr;
-          mRawPtr = newPtr;
-          NSCAP_LOG_ASSIGNMENT(this, newPtr);
-          NSCAP_LOG_RELEASE(this, oldPtr);
-          if ( oldPtr )
-            NSCAP_RELEASE(this, oldPtr);
-        }
-
-    private:
-      T* mRawPtr;
-#endif
-
-    public:
-      typedef T element_type;
-      
-#ifndef NSCAP_FEATURE_USE_BASE
-     ~nsCOMPtr()
-        {
-          NSCAP_LOG_RELEASE(this, mRawPtr);
-          if ( mRawPtr )
-            NSCAP_RELEASE(this, mRawPtr);
-        }
-#endif
-
-#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
-      void
-      Assert_NoQueryNeeded()
-        {
-          if ( mRawPtr )
-            {
-              nsCOMPtr<T> query_result( do_QueryInterface(mRawPtr) );
-              NS_ASSERTION(query_result.get() == mRawPtr, "QueryInterface needed");
-            }
-        }
-
-  #define NSCAP_ASSERT_NO_QUERY_NEEDED() Assert_NoQueryNeeded();
-#else
-  #define NSCAP_ASSERT_NO_QUERY_NEEDED()
-#endif
-
-
-        // Constructors
-
-      nsCOMPtr()
-            : NSCAP_CTOR_BASE(0)
-          // default constructor
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-        }
-
-      nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
-            : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
-          // copy-constructor
-        {
-          if ( mRawPtr )
-            NSCAP_ADDREF(this, mRawPtr);
-          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
-        }
-
-      nsCOMPtr( T* aRawPtr )
-            : NSCAP_CTOR_BASE(aRawPtr)
-          // construct from a raw pointer (of the right type)
-        {
-          if ( mRawPtr )
-            NSCAP_ADDREF(this, mRawPtr);
-          NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-        }
-
-      nsCOMPtr( const already_AddRefed<T>& aSmartPtr )
-            : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
-          // construct from |dont_AddRef(expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-        }
-
-      nsCOMPtr( const nsQueryInterface qi )
-            : NSCAP_CTOR_BASE(0)
-          // construct from |do_QueryInterface(expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_qi(qi, NS_GET_TEMPLATE_IID(T));
-        }
-
-      nsCOMPtr( const nsQueryInterfaceWithError& qi )
-            : NSCAP_CTOR_BASE(0)
-          // construct from |do_QueryInterface(expr, &rv)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_qi_with_error(qi, NS_GET_TEMPLATE_IID(T));
-        }
-
-      nsCOMPtr( const nsGetServiceByCID gs )
-            : NSCAP_CTOR_BASE(0)
-          // construct from |do_GetService(cid_expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_cid(gs, NS_GET_TEMPLATE_IID(T));
-        }
-
-      nsCOMPtr( const nsGetServiceByCIDWithError& gs )
-            : NSCAP_CTOR_BASE(0)
-          // construct from |do_GetService(cid_expr, &rv)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_cid_with_error(gs, NS_GET_TEMPLATE_IID(T));
-        }
-
-      nsCOMPtr( const nsGetServiceByContractID gs )
-            : NSCAP_CTOR_BASE(0)
-          // construct from |do_GetService(contractid_expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_contractid(gs, NS_GET_TEMPLATE_IID(T));
-        }
-
-      nsCOMPtr( const nsGetServiceByContractIDWithError& gs )
-            : NSCAP_CTOR_BASE(0)
-          // construct from |do_GetService(contractid_expr, &rv)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_contractid_with_error(gs, NS_GET_TEMPLATE_IID(T));
-        }
-
-      nsCOMPtr( const nsCOMPtr_helper& helper )
-            : NSCAP_CTOR_BASE(0)
-          // ...and finally, anything else we might need to construct from
-          //  can exploit the |nsCOMPtr_helper| facility
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_helper(helper, NS_GET_TEMPLATE_IID(T));
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-        }
-
-
-        // Assignment operators
-
-      nsCOMPtr<T>&
-      operator=( const nsCOMPtr<T>& rhs )
-          // copy assignment operator
-        {
-          assign_with_AddRef(rhs.mRawPtr);
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( T* rhs )
-          // assign from a raw pointer (of the right type)
-        {
-          assign_with_AddRef(rhs);
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const already_AddRefed<T>& rhs )
-          // assign from |dont_AddRef(expr)|
-        {
-          assign_assuming_AddRef(rhs.mRawPtr);
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsQueryInterface rhs )
-          // assign from |do_QueryInterface(expr)|
-        {
-          assign_from_qi(rhs, NS_GET_TEMPLATE_IID(T));
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsQueryInterfaceWithError& rhs )
-          // assign from |do_QueryInterface(expr, &rv)|
-        {
-          assign_from_qi_with_error(rhs, NS_GET_TEMPLATE_IID(T));
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsGetServiceByCID rhs )
-          // assign from |do_GetService(cid_expr)|
-        {
-          assign_from_gs_cid(rhs, NS_GET_TEMPLATE_IID(T));
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsGetServiceByCIDWithError& rhs )
-          // assign from |do_GetService(cid_expr, &rv)|
-        {
-          assign_from_gs_cid_with_error(rhs, NS_GET_TEMPLATE_IID(T));
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsGetServiceByContractID rhs )
-          // assign from |do_GetService(contractid_expr)|
-        {
-          assign_from_gs_contractid(rhs, NS_GET_TEMPLATE_IID(T));
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsGetServiceByContractIDWithError& rhs )
-          // assign from |do_GetService(contractid_expr, &rv)|
-        {
-          assign_from_gs_contractid_with_error(rhs, NS_GET_TEMPLATE_IID(T));
-          return *this;
-        }
-
-      nsCOMPtr<T>&
-      operator=( const nsCOMPtr_helper& rhs )
-          // ...and finally, anything else we might need to assign from
-          //  can exploit the |nsCOMPtr_helper| facility.
-        {
-          assign_from_helper(rhs, NS_GET_TEMPLATE_IID(T));
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-          return *this;
-        }
-
-      void
-      swap( nsCOMPtr<T>& rhs )
-          // ...exchange ownership with |rhs|; can save a pair of refcount operations
-        {
-#ifdef NSCAP_FEATURE_USE_BASE
-          nsISupports* temp = rhs.mRawPtr;
-#else
-          T* temp = rhs.mRawPtr;
-#endif
-          NSCAP_LOG_ASSIGNMENT(&rhs, mRawPtr);
-          NSCAP_LOG_ASSIGNMENT(this, temp);
-          NSCAP_LOG_RELEASE(this, mRawPtr);
-          NSCAP_LOG_RELEASE(&rhs, temp);
-          rhs.mRawPtr = mRawPtr;
-          mRawPtr = temp;
-          // |rhs| maintains the same invariants, so we don't need to |NSCAP_ASSERT_NO_QUERY_NEEDED|
-        }
-
-      void
-      swap( T*& rhs )
-          // ...exchange ownership with |rhs|; can save a pair of refcount operations
-        {
-#ifdef NSCAP_FEATURE_USE_BASE
-          nsISupports* temp = rhs;
-#else
-          T* temp = rhs;
-#endif
-          NSCAP_LOG_ASSIGNMENT(this, temp);
-          NSCAP_LOG_RELEASE(this, mRawPtr);
-          rhs = reinterpret_cast<T*>(mRawPtr);
-          mRawPtr = temp;
-          NSCAP_ASSERT_NO_QUERY_NEEDED();
-        }
-
-
-        // Other pointer operators
-
-      already_AddRefed<T>
-      forget()
-          // return the value of mRawPtr and null out mRawPtr. Useful for
-          // already_AddRefed return values.
-        {
-          T* temp = 0;
-          swap(temp);
-          return temp;
-        }
-
-      void
-      forget( T** rhs )
-          // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
-          // Useful to avoid unnecessary AddRef/Release pairs with "out"
-          // parameters.
-        {
-          NS_ASSERTION(rhs, "Null pointer passed to forget!");
-          *rhs = 0;
-          swap(*rhs);
-        }
-
-      T*
-      get() const
-          /*
-            Prefer the implicit conversion provided automatically by |operator nsDerivedSafe<T>*() const|.
-             Use |get()| to resolve ambiguity or to get a castable pointer.
-          */
-        {
-          return reinterpret_cast<T*>(mRawPtr);
-        }
-
-      operator nsDerivedSafe<T>*() const
-          /*
-            ...makes an |nsCOMPtr| act like its underlying raw pointer type (except against |AddRef()|, |Release()|,
-              and |delete|) whenever it is used in a context where a raw pointer is expected.  It is this operator
-              that makes an |nsCOMPtr| substitutable for a raw pointer.
-
-            Prefer the implicit use of this operator to calling |get()|, except where necessary to resolve ambiguity.
-          */
-        {
-          return get_DerivedSafe();
-        }
-
-      nsDerivedSafe<T>*
-      operator->() const
-        {
-          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
-          return get_DerivedSafe();
-        }
-
-#ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
-  // broken version for IRIX
-
-      nsCOMPtr<T>*
-      get_address() const
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return const_cast<nsCOMPtr<T>*>(this);
-        }
-
-#else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-      nsCOMPtr<T>*
-      get_address()
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return this;
-        }
-
-      const nsCOMPtr<T>*
-      get_address() const
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return this;
-        }
-
-#endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-    public:
-      nsDerivedSafe<T>&
-      operator*() const
-        {
-          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
-          return *get_DerivedSafe();
-        }
-
-#if 0
-    private:
-      friend class nsGetterAddRefs<T>;
-#endif
-
-      T**
-      StartAssignment()
-        {
-#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
-          return reinterpret_cast<T**>(begin_assignment());
-#else
-          assign_assuming_AddRef(0);
-          return reinterpret_cast<T**>(&mRawPtr);
-#endif
-        }
-
-    private:
-      nsDerivedSafe<T>*
-      get_DerivedSafe() const
-        {
-          return reinterpret_cast<nsDerivedSafe<T>*>(mRawPtr);
-        }
-
-  };
-
-
-
-  /*
-    Specializing |nsCOMPtr| for |nsISupports| allows us to use |nsCOMPtr<nsISupports>| the
-    same way people use |nsISupports*| and |void*|, i.e., as a `catch-all' pointer pointing
-    to any valid [XP]COM interface.  Otherwise, an |nsCOMPtr<nsISupports>| would only be able
-    to point to the single [XP]COM-correct |nsISupports| instance within an object; extra
-    querying ensues.  Clients need to be able to pass around arbitrary interface pointers,
-    without hassles, through intermediary code that doesn't know the exact type.
-  */
-
-NS_SPECIALIZE_TEMPLATE
-class nsCOMPtr<nsISupports>
-    : private nsCOMPtr_base
-  {
-    public:
-      typedef nsISupports element_type;
-
-        // Constructors
-
-      nsCOMPtr()
-            : nsCOMPtr_base(0)
-          // default constructor
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-        }
-
-      nsCOMPtr( const nsCOMPtr<nsISupports>& aSmartPtr )
-            : nsCOMPtr_base(aSmartPtr.mRawPtr)
-          // copy constructor
-        {
-          if ( mRawPtr )
-            NSCAP_ADDREF(this, mRawPtr);
-          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
-        }
-
-      nsCOMPtr( nsISupports* aRawPtr )
-            : nsCOMPtr_base(aRawPtr)
-          // construct from a raw pointer (of the right type)
-        {
-          if ( mRawPtr )
-            NSCAP_ADDREF(this, mRawPtr);
-          NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
-        }
-
-      nsCOMPtr( const already_AddRefed<nsISupports>& aSmartPtr )
-            : nsCOMPtr_base(aSmartPtr.mRawPtr)
-          // construct from |dont_AddRef(expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
-        }
-
-      nsCOMPtr( const nsQueryInterface qi )
-            : nsCOMPtr_base(0)
-          // assign from |do_QueryInterface(expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_qi(qi, NS_GET_IID(nsISupports));
-        }
-
-      nsCOMPtr( const nsQueryInterfaceWithError& qi )
-            : nsCOMPtr_base(0)
-          // assign from |do_QueryInterface(expr, &rv)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_qi_with_error(qi, NS_GET_IID(nsISupports));
-        }
-
-      nsCOMPtr( const nsGetServiceByCID gs )
-            : nsCOMPtr_base(0)
-          // assign from |do_GetService(cid_expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_cid(gs, NS_GET_IID(nsISupports));
-        }
-
-      nsCOMPtr( const nsGetServiceByCIDWithError& gs )
-            : nsCOMPtr_base(0)
-          // assign from |do_GetService(cid_expr, &rv)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_cid_with_error(gs, NS_GET_IID(nsISupports));
-        }
-
-      nsCOMPtr( const nsGetServiceByContractID gs )
-            : nsCOMPtr_base(0)
-          // assign from |do_GetService(contractid_expr)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_contractid(gs, NS_GET_IID(nsISupports));
-        }
-
-      nsCOMPtr( const nsGetServiceByContractIDWithError& gs )
-            : nsCOMPtr_base(0)
-          // assign from |do_GetService(contractid_expr, &rv)|
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_gs_contractid_with_error(gs, NS_GET_IID(nsISupports));
-        }
-
-      nsCOMPtr( const nsCOMPtr_helper& helper )
-            : nsCOMPtr_base(0)
-          // ...and finally, anything else we might need to construct from
-          //  can exploit the |nsCOMPtr_helper| facility
-        {
-          NSCAP_LOG_ASSIGNMENT(this, 0);
-          assign_from_helper(helper, NS_GET_IID(nsISupports));
-        }
-
-
-        // Assignment operators
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsCOMPtr<nsISupports>& rhs )
-          // copy assignment operator
-        {
-          assign_with_AddRef(rhs.mRawPtr);
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( nsISupports* rhs )
-          // assign from a raw pointer (of the right type)
-        {
-          assign_with_AddRef(rhs);
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const already_AddRefed<nsISupports>& rhs )
-          // assign from |dont_AddRef(expr)|
-        {
-          assign_assuming_AddRef(rhs.mRawPtr);
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsQueryInterface rhs )
-          // assign from |do_QueryInterface(expr)|
-        {
-          assign_from_qi(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsQueryInterfaceWithError& rhs )
-          // assign from |do_QueryInterface(expr, &rv)|
-        {
-          assign_from_qi_with_error(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsGetServiceByCID rhs )
-          // assign from |do_GetService(cid_expr)|
-        {
-          assign_from_gs_cid(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsGetServiceByCIDWithError& rhs )
-          // assign from |do_GetService(cid_expr, &rv)|
-        {
-          assign_from_gs_cid_with_error(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsGetServiceByContractID rhs )
-          // assign from |do_GetService(contractid_expr)|
-        {
-          assign_from_gs_contractid(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsGetServiceByContractIDWithError& rhs )
-          // assign from |do_GetService(contractid_expr, &rv)|
-        {
-          assign_from_gs_contractid_with_error(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      nsCOMPtr<nsISupports>&
-      operator=( const nsCOMPtr_helper& rhs )
-          // ...and finally, anything else we might need to assign from
-          //  can exploit the |nsCOMPtr_helper| facility.
-        {
-          assign_from_helper(rhs, NS_GET_IID(nsISupports));
-          return *this;
-        }
-
-      void
-      swap( nsCOMPtr<nsISupports>& rhs )
-          // ...exchange ownership with |rhs|; can save a pair of refcount operations
-        {
-          nsISupports* temp = rhs.mRawPtr;
-          NSCAP_LOG_ASSIGNMENT(&rhs, mRawPtr);
-          NSCAP_LOG_ASSIGNMENT(this, temp);
-          NSCAP_LOG_RELEASE(this, mRawPtr);
-          NSCAP_LOG_RELEASE(&rhs, temp);
-          rhs.mRawPtr = mRawPtr;
-          mRawPtr = temp;
-        }
-
-      void
-      swap( nsISupports*& rhs )
-          // ...exchange ownership with |rhs|; can save a pair of refcount operations
-        {
-          nsISupports* temp = rhs;
-          NSCAP_LOG_ASSIGNMENT(this, temp);
-          NSCAP_LOG_RELEASE(this, mRawPtr);
-          rhs = mRawPtr;
-          mRawPtr = temp;
-        }
-
-      void
-      forget( nsISupports** rhs )
-          // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
-          // Useful to avoid unnecessary AddRef/Release pairs with "out"
-          // parameters.
-        {
-          NS_ASSERTION(rhs, "Null pointer passed to forget!");
-          *rhs = 0;
-          swap(*rhs);
-        }
-
-        // Other pointer operators
-
-      nsISupports*
-      get() const
-          /*
-            Prefer the implicit conversion provided automatically by |operator nsDerivedSafe<nsISupports>*() const|.
-             Use |get()| to resolve ambiguity or to get a castable pointer.
-          */
-        {
-          return reinterpret_cast<nsISupports*>(mRawPtr);
-        }
-
-      operator nsDerivedSafe<nsISupports>*() const
-          /*
-            ...makes an |nsCOMPtr| act like its underlying raw pointer type (except against |AddRef()|, |Release()|,
-              and |delete|) whenever it is used in a context where a raw pointer is expected.  It is this operator
-              that makes an |nsCOMPtr| substitutable for a raw pointer.
-
-            Prefer the implicit use of this operator to calling |get()|, except where necessary to resolve ambiguity.
-          */
-        {
-          return get_DerivedSafe();
-        }
-
-      nsDerivedSafe<nsISupports>*
-      operator->() const
-        {
-          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
-          return get_DerivedSafe();
-        }
-
-#ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
-  // broken version for IRIX
-
-      nsCOMPtr<nsISupports>*
-      get_address() const
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return const_cast<nsCOMPtr<nsISupports>*>(this);
-        }
-
-#else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-      nsCOMPtr<nsISupports>*
-      get_address()
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return this;
-        }
-
-      const nsCOMPtr<nsISupports>*
-      get_address() const
-          // This is not intended to be used by clients.  See |address_of|
-          // below.
-        {
-          return this;
-        }
-
-#endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-    public:
-
-      nsDerivedSafe<nsISupports>&
-      operator*() const
-        {
-          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
-          return *get_DerivedSafe();
-        }
-
-#if 0
-    private:
-      friend class nsGetterAddRefs<nsISupports>;
-#endif
-
-      nsISupports**
-      StartAssignment()
-        {
-#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
-          return reinterpret_cast<nsISupports**>(begin_assignment());
-#else
-          assign_assuming_AddRef(0);
-          return reinterpret_cast<nsISupports**>(&mRawPtr);
-#endif
-        }
-
-    private:
-      nsDerivedSafe<nsISupports>*
-      get_DerivedSafe() const
-        {
-          return reinterpret_cast<nsDerivedSafe<nsISupports>*>(mRawPtr);
-        }
-
-  };
-
-#ifndef NSCAP_FEATURE_USE_BASE
-template <class T>
-void
-nsCOMPtr<T>::assign_with_AddRef( nsISupports* rawPtr )
-  {
-    if ( rawPtr )
-      NSCAP_ADDREF(this, rawPtr);
-    assign_assuming_AddRef(reinterpret_cast<T*>(rawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_qi( const nsQueryInterface qi, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( qi(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_qi_with_error( const nsQueryInterfaceWithError& qi, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( qi(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_gs_cid( const nsGetServiceByCID gs, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError& gs, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_gs_contractid( const nsGetServiceByContractID gs, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_gs_contractid_with_error( const nsGetServiceByContractIDWithError& gs, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( gs(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void
-nsCOMPtr<T>::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& aIID )
-  {
-    void* newRawPtr;
-    if ( NS_FAILED( helper(aIID, &newRawPtr) ) )
-      newRawPtr = 0;
-    assign_assuming_AddRef(static_cast<T*>(newRawPtr));
-  }
-
-template <class T>
-void**
-nsCOMPtr<T>::begin_assignment()
-  {
-    assign_assuming_AddRef(0);
-    union { T** mT; void** mVoid; } result;
-    result.mT = &mRawPtr;
-    return result.mVoid;
-  }
-#endif
-
-#ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-// This is the broken version for IRIX, which can't handle the version below.
-
-template <class T>
-inline
-nsCOMPtr<T>*
-address_of( const nsCOMPtr<T>& aPtr )
-  {
-    return aPtr.get_address();
-  }
-
-#else // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-template <class T>
-inline
-nsCOMPtr<T>*
-address_of( nsCOMPtr<T>& aPtr )
-  {
-    return aPtr.get_address();
-  }
-
-template <class T>
-inline
-const nsCOMPtr<T>*
-address_of( const nsCOMPtr<T>& aPtr )
-  {
-    return aPtr.get_address();
-  }
-
-#endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY
-
-template <class T>
-class nsGetterAddRefs
-    /*
-      ...
-
-      This class is designed to be used for anonymous temporary objects in the
-      argument list of calls that return COM interface pointers, e.g.,
-
-        nsCOMPtr<IFoo> fooP;
-        ...->QueryInterface(iid, getter_AddRefs(fooP))
-
-      DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
-
-      When initialized with a |nsCOMPtr|, as in the example above, it returns
-      a |void**|, a |T**|, or an |nsISupports**| as needed, that the outer call (|QueryInterface| in this
-      case) can fill in.
-
-      This type should be a nested class inside |nsCOMPtr<T>|.
-    */
-  {
-    public:
-      explicit
-      nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
-          : mTargetSmartPtr(aSmartPtr)
-        {
-          // nothing else to do
-        }
-
-#if defined(NSCAP_FEATURE_TEST_DONTQUERY_CASES) || defined(NSCAP_LOG_EXTERNAL_ASSIGNMENT)
-     ~nsGetterAddRefs()
-        {
-#ifdef NSCAP_LOG_EXTERNAL_ASSIGNMENT
-          NSCAP_LOG_ASSIGNMENT(reinterpret_cast<void *>(address_of(mTargetSmartPtr)), mTargetSmartPtr.get());
-#endif
-
-#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
-          mTargetSmartPtr.Assert_NoQueryNeeded();
-#endif
-        }
-#endif
-
-      operator void**()
-        {
-          return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
-        }
-
-      operator nsISupports**()
-        {
-          return reinterpret_cast<nsISupports**>(mTargetSmartPtr.StartAssignment());
-        }
-
-      operator T**()
-        {
-          return mTargetSmartPtr.StartAssignment();
-        }
-
-      T*&
-      operator*()
-        {
-          return *(mTargetSmartPtr.StartAssignment());
-        }
-
-    private:
-      nsCOMPtr<T>& mTargetSmartPtr;
-  };
-
-
-NS_SPECIALIZE_TEMPLATE
-class nsGetterAddRefs<nsISupports>
-  {
-    public:
-      explicit
-      nsGetterAddRefs( nsCOMPtr<nsISupports>& aSmartPtr )
-          : mTargetSmartPtr(aSmartPtr)
-        {
-          // nothing else to do
-        }
-
-#ifdef NSCAP_LOG_EXTERNAL_ASSIGNMENT
-     ~nsGetterAddRefs()
-        {
-          NSCAP_LOG_ASSIGNMENT(reinterpret_cast<void *>(address_of(mTargetSmartPtr)), mTargetSmartPtr.get());
-        }
-#endif
-
-      operator void**()
-        {
-          return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
-        }
-
-      operator nsISupports**()
-        {
-          return mTargetSmartPtr.StartAssignment();
-        }
-
-      nsISupports*&
-      operator*()
-        {
-          return *(mTargetSmartPtr.StartAssignment());
-        }
-
-    private:
-      nsCOMPtr<nsISupports>& mTargetSmartPtr;
-  };
-
-
-template <class T>
-inline
-nsGetterAddRefs<T>
-getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
-    /*
-      Used around a |nsCOMPtr| when 
-      ...makes the class |nsGetterAddRefs<T>| invisible.
-    */
-  {
-    return nsGetterAddRefs<T>(aSmartPtr);
-  }
-
-
-
-  // Comparing two |nsCOMPtr|s
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
-  {
-    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
-  }
-
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
-  {
-    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
-  }
-
-
-  // Comparing an |nsCOMPtr| to a raw pointer
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const nsCOMPtr<T>& lhs, const U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) == rhs;
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const U* lhs, const nsCOMPtr<T>& rhs )
-  {
-    return lhs == static_cast<const T*>(rhs.get());
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const nsCOMPtr<T>& lhs, const U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) != rhs;
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const U* lhs, const nsCOMPtr<T>& rhs )
-  {
-    return lhs != static_cast<const T*>(rhs.get());
-  }
-
-  // To avoid ambiguities caused by the presence of builtin |operator==|s
-  // creating a situation where one of the |operator==| defined above
-  // has a better conversion for one argument and the builtin has a
-  // better conversion for the other argument, define additional
-  // |operator==| without the |const| on the raw pointer.
-  // See bug 65664 for details.
-
-// This is defined by an autoconf test, but VC++ also has a bug that
-// prevents us from using these.  (It also, fortunately, has the bug
-// that we don't need them either.)
-#if defined(_MSC_VER) && (_MSC_VER < 1310)
-#ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
-#define NSCAP_DONT_PROVIDE_NONCONST_OPEQ
-#endif
-#endif
-
-#ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( const nsCOMPtr<T>& lhs, U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator==( U* lhs, const nsCOMPtr<T>& rhs )
-  {
-    return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( const nsCOMPtr<T>& lhs, U* rhs )
-  {
-    return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
-  }
-
-template <class T, class U>
-inline
-NSCAP_BOOL
-operator!=( U* lhs, const nsCOMPtr<T>& rhs )
-  {
-    return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
-  }
-#endif
-
-
-
-  // Comparing an |nsCOMPtr| to |0|
-
-class NSCAP_Zero;
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( const nsCOMPtr<T>& lhs, NSCAP_Zero* rhs )
-    // specifically to allow |smartPtr == 0|
-  {
-    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( NSCAP_Zero* lhs, const nsCOMPtr<T>& rhs )
-    // specifically to allow |0 == smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator!=( const nsCOMPtr<T>& lhs, NSCAP_Zero* rhs )
-    // specifically to allow |smartPtr != 0|
-  {
-    return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator!=( NSCAP_Zero* lhs, const nsCOMPtr<T>& rhs )
-    // specifically to allow |0 != smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
-  }
-
-
-#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
-
-  // We need to explicitly define comparison operators for `int'
-  // because the compiler is lame.
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( const nsCOMPtr<T>& lhs, int rhs )
-    // specifically to allow |smartPtr == 0|
-  {
-    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
-  }
-
-template <class T>
-inline
-NSCAP_BOOL
-operator==( int lhs, const nsCOMPtr<T>& rhs )
-    // specifically to allow |0 == smartPtr|
-  {
-    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
-  }
-
-#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
-
-  // Comparing any two [XP]COM objects for identity
-
-inline
-NSCAP_BOOL
-SameCOMIdentity( nsISupports* lhs, nsISupports* rhs )
-  {
-    return nsCOMPtr<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
-  }
-
-
-
-template <class SourceType, class DestinationType>
-inline
-nsresult
-CallQueryInterface( nsCOMPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr )
-  {
-    return CallQueryInterface(aSourcePtr.get(), aDestPtr);
-  }
 
 
 
diff --git a/xpcom/glue/nsComponentManagerUtils.cpp b/xpcom/glue/nsComponentManagerUtils.cpp
--- a/xpcom/glue/nsComponentManagerUtils.cpp
+++ b/xpcom/glue/nsComponentManagerUtils.cpp
@@ -193,103 +193,62 @@ CallGetClassObject(const char *aContract
 
 #endif
 
-nsresult
-nsCreateInstanceByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const
+void*
+nsCreateInstanceByCID::get(const nsIID& aIID) const
 {
-    nsresult status = CallCreateInstance(mCID, mOuter, aIID, aInstancePtr);
-    if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
+    void *result = NULL;
+    nsresult status = CallCreateInstance(mCID, mOuter, aIID, &result);
+    if (NS_FAILED(status))
+        result = NULL;
     if ( mErrorPtr )
         *mErrorPtr = status;
-    return status;
+    return result;
 }
 
-nsresult
-nsCreateInstanceByContractID::operator()( const nsIID& aIID, void** aInstancePtr ) const
+void*
+nsCreateInstanceByContractID::get(const nsIID& aIID) const
 {
-    nsresult status = CallCreateInstance(mContractID, mOuter, aIID, aInstancePtr);
+    void *result = NULL;
+    nsresult status = CallCreateInstance(mContractID, mOuter, aIID, &result);
     if (NS_FAILED(status))
-        *aInstancePtr = 0;
+        result = NULL;
     if ( mErrorPtr )
         *mErrorPtr = status;
-    return status;
+    return result;
 }
 
-nsresult
-nsCreateInstanceFromFactory::operator()( const nsIID& aIID, void** aInstancePtr ) const
+void*
+nsCreateInstanceFromFactory::get(const nsIID& aIID) const
 {
-    nsresult status = mFactory->CreateInstance(mOuter, aIID, aInstancePtr);
+    void *result = NULL;
+    nsresult status = mFactory->CreateInstance(mOuter, aIID, &result);
     if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
+        result = NULL;
     if ( mErrorPtr )
         *mErrorPtr = status;
-    return status;
+    return result;
 }
 
-
-nsresult
-nsGetClassObjectByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const
+void*
+nsGetClassObjectByCID::get(const nsIID& aIID) const
 {
-    nsresult status = CallGetClassObject(mCID, aIID, aInstancePtr);
+    void *result = NULL;
+    nsresult status = CallGetClassObject(mCID, aIID, &result);
     if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
+        result = NULL;
     if ( mErrorPtr )
         *mErrorPtr = status;
-    return status;
+    return result;
 }
 
-nsresult
-nsGetClassObjectByContractID::operator()( const nsIID& aIID, void** aInstancePtr ) const
+void*
+nsGetClassObjectByContractID::get(const nsIID& aIID) const
 {
-    nsresult status = CallGetClassObject(mContractID, aIID, aInstancePtr);
+    void *result = NULL;
+    nsresult status = CallGetClassObject(mContractID, aIID, &result);
     if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
+        result = NULL;
     if ( mErrorPtr )
         *mErrorPtr = status;
-    return status;
+    return result;
 }
-
-
-nsresult
-nsGetServiceByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const
-{
-    nsresult status = CallGetService(mCID, aIID, aInstancePtr);
-    if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
-
-    return status;
-}
-
-nsresult
-nsGetServiceByCIDWithError::operator()( const nsIID& aIID, void** aInstancePtr ) const
-{
-    nsresult status = CallGetService(mCID, aIID, aInstancePtr);
-    if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
-
-    if ( mErrorPtr )
-        *mErrorPtr = status;
-    return status;
-}
-
-nsresult
-nsGetServiceByContractID::operator()( const nsIID& aIID, void** aInstancePtr ) const
-{
-    nsresult status = CallGetService(mContractID, aIID, aInstancePtr);
-    if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
-    
-    return status;
-}
-
-nsresult
-nsGetServiceByContractIDWithError::operator()( const nsIID& aIID, void** aInstancePtr ) const
-{
-    nsresult status = CallGetService(mContractID, aIID, aInstancePtr);
-    if ( NS_FAILED(status) )
-        *aInstancePtr = 0;
-    
-    if ( mErrorPtr )
-        *mErrorPtr = status;
-    return status;
-}
diff --git a/xpcom/glue/nsComponentManagerUtils.h b/xpcom/glue/nsComponentManagerUtils.h
--- a/xpcom/glue/nsComponentManagerUtils.h
+++ b/xpcom/glue/nsComponentManagerUtils.h
@@ -68,7 +68,7 @@ CallGetClassObject
   (const char *aContractID, const nsIID &aIID, void **aResult);
 
 
-class NS_COM_GLUE nsCreateInstanceByCID : public nsCOMPtr_helper
+class NS_COM_GLUE nsCreateInstanceByCID
 {
 public:
     nsCreateInstanceByCID( const nsCID& aCID, nsISupports* aOuter, nsresult* aErrorPtr )
@@ -79,15 +79,21 @@ public:
         // nothing else to do here
     }
     
-    virtual nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
-    
+    template<class D>
+    operator D*() const
+    {
+        return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
+    }
+
 private:
+    void* get(const nsIID &aIID) const;
+
     const nsCID&    mCID;
     nsISupports*    mOuter;
     nsresult*       mErrorPtr;
 };
 
-class NS_COM_GLUE nsCreateInstanceByContractID : public nsCOMPtr_helper
+class NS_COM_GLUE nsCreateInstanceByContractID
 {
 public:
     nsCreateInstanceByContractID( const char* aContractID, nsISupports* aOuter, nsresult* aErrorPtr )
@@ -98,15 +104,21 @@ public:
         // nothing else to do here
     }
     
-    virtual nsresult NS_FASTCALL operator()( const nsIID&, void** ) const;
+    template<class D>
+    operator D*() const
+    {
+        return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
+    }
     
 private:
+    void* get(const nsIID &aIID) const;
+
     const char*   mContractID;
     nsISupports*  mOuter;
     nsresult*     mErrorPtr;
 };
 
-class NS_COM_GLUE nsCreateInstanceFromFactory : public nsCOMPtr_helper