Backed out 18 changesets (bug 1313469, bug 1313468, bug 1313474, bug 1313472, bug 1313473, bug 1313470, bug 1313471, bug 1313467, bug 1313466) for OS X gtest crashes
authorPhil Ringnalda <philringnalda@gmail.com>
Thu, 03 Nov 2016 23:00:47 -0700
changeset 347703 561b87e98adacbd47769a71a0e6c72c5dcf66a9d
parent 347702 c9308740eeb796ca1b534751c94ed5b2cb51e1fb
child 347704 2a361181d313dc4e7308a705cd6bc3e0fe35ac68
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1313469, 1313468, 1313474, 1313472, 1313473, 1313470, 1313471, 1313467, 1313466
milestone52.0a1
backs out5b5686e1bcd1a736f9d6f48f29122c8bd5148501
e8d20bdd13d447998e73974644d42787afe2dc43
643bdd25166eef38dafe3428eca0a2b0c2e62946
9a33c84ab30a6e67a605b73337feb9ab7744458f
4d84926813e91fc3c6c3fc95d2aca5436cf89d05
c85e7a7a5a9963fb7b11158c6887967b1757f864
5d82bc9436abbb89a05ae727027a78f5e9492fec
00f7b342bb29c4f26c7e78fade11b631054aadc4
f012923cfd8b903bc342910ec81cff508624906a
e7d5b8135ae61384a51c0b909e5eb2aac9e6e035
82bf00ff65052d93ec3dbc337bf223df9bb8b75d
5364fc8db9b0e29c209f58ea6e06fd9d980436d9
02959aa60196a5d1ea833f1d21052ec50b99058a
3c25a6ed5914b926e5c554c5f38a2e71ee0673e7
0acc0a131101e59d9b6dbc1dded254ebf6707104
6fae1bbd3819833d07fd47f7b9b15b8e42e12452
107eb264a40d19ecdcb1af3d09959a547d397b9d
9b60e295a885d16b15bb3ae0b902182709e7a964
Backed out 18 changesets (bug 1313469, bug 1313468, bug 1313474, bug 1313472, bug 1313473, bug 1313470, bug 1313471, bug 1313467, bug 1313466) for OS X gtest crashes CLOSED TREE Backed out changeset 5b5686e1bcd1 (bug 1313474) Backed out changeset e8d20bdd13d4 (bug 1313473) Backed out changeset 643bdd25166e (bug 1313473) Backed out changeset 9a33c84ab30a (bug 1313472) Backed out changeset 4d84926813e9 (bug 1313472) Backed out changeset c85e7a7a5a99 (bug 1313471) Backed out changeset 5d82bc9436ab (bug 1313471) Backed out changeset 00f7b342bb29 (bug 1313470) Backed out changeset f012923cfd8b (bug 1313470) Backed out changeset e7d5b8135ae6 (bug 1313470) Backed out changeset 82bf00ff6505 (bug 1313469) Backed out changeset 5364fc8db9b0 (bug 1313469) Backed out changeset 02959aa60196 (bug 1313468) Backed out changeset 3c25a6ed5914 (bug 1313467) Backed out changeset 0acc0a131101 (bug 1313467) Backed out changeset 6fae1bbd3819 (bug 1313467) Backed out changeset 107eb264a40d (bug 1313467) Backed out changeset 9b60e295a885 (bug 1313466) MozReview-Commit-ID: IKsAZxBYMfv
testing/cppunittest.ini
xpcom/tests/ShowAlignments.cpp
xpcom/tests/TestAutoPtr.cpp
xpcom/tests/TestAutoRef.cpp
xpcom/tests/TestCOMArray.cpp
xpcom/tests/TestCOMPtr.cpp
xpcom/tests/TestCOMPtrEq.cpp
xpcom/tests/TestFile.cpp
xpcom/tests/TestHashtables.cpp
xpcom/tests/TestID.cpp
xpcom/tests/gtest/TestAutoPtr.cpp
xpcom/tests/gtest/TestAutoRef.cpp
xpcom/tests/gtest/TestCOMArray.cpp
xpcom/tests/gtest/TestCOMPtr.cpp
xpcom/tests/gtest/TestCOMPtrEq.cpp
xpcom/tests/gtest/TestFile.cpp
xpcom/tests/gtest/TestHashtables.cpp
xpcom/tests/gtest/TestID.cpp
xpcom/tests/gtest/TestStorageStream.cpp
xpcom/tests/gtest/TestStringStream.cpp
xpcom/tests/gtest/moz.build
xpcom/tests/moz.build
xpcom/threads/StateWatching.h
xpcom/threads/TaskDispatcher.h
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -1,21 +1,27 @@
+[ShowAlignments]
 [ShowSSEConfig]
 [TestAppShellSteadyState]
 [TestArray]
 [TestArrayUtils]
 [TestAtomics]
 [TestAudioBuffers]
 skip-if = os == 'b2g'  # Bug 1062937
 [TestAudioMixer]
+[TestAutoPtr]
+[TestAutoRef]
 [TestBinarySearch]
 [TestBind]
 [TestBloomFilter]
 [TestCOM]
 skip-if = os != 'win'
+[TestCOMArray]
+[TestCOMPtr]
+[TestCOMPtrEq]
 [TestCSPParser]
 skip-if = os == 'b2g' || (os == 'android' && debug) # Bug 1054246
 [TestCasting]
 [TestCeilingFloor]
 [TestCertDB]
 [TestCheckedInt]
 [TestCookie]
 [TestCountPopulation]
@@ -25,19 +31,22 @@ skip-if = os == 'b2g' || (os == 'android
 [TestDeadlockDetectorScalability]
 [TestDllInterceptor]
 skip-if = os != 'win'
 [TestEndian]
 [TestEnumeratedArray]
 [TestEnumSet]
 [TestEnumTypeTraits]
 [TestFastBernoulliTrial]
+[TestFile]
 [TestFloatingPoint]
 [TestFunction]
 [TestGetURL]
+[TestHashtables]
+[TestID]
 [TestIntegerPrintfMacros]
 [TestIntegerRange]
 [TestIsCertBuiltInRoot]
 [TestJSONWriter]
 [TestJemalloc]
 [TestLinkedList]
 [TestMacroArgs]
 [TestMacroForEach]
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/ShowAlignments.cpp
@@ -0,0 +1,38 @@
+/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* show the size and alignment requirements of various types */
+
+#include "nsMemory.h"
+#include <stdio.h>
+
+struct S {
+  double d;
+  char c;
+  short s;
+};
+
+int main()
+{
+  static const char str[] =
+    "Type %s has size %u and alignment requirement %u\n";
+  #define SHOW_TYPE(t_) \
+    printf(str, #t_, unsigned(sizeof(t_)), unsigned(NS_ALIGNMENT_OF(t_)))
+
+  SHOW_TYPE(char);
+  SHOW_TYPE(unsigned short);
+  SHOW_TYPE(int);
+  SHOW_TYPE(long);
+  SHOW_TYPE(uint8_t);
+  SHOW_TYPE(int16_t);
+  SHOW_TYPE(uint32_t);
+  SHOW_TYPE(void*);
+  SHOW_TYPE(double);
+  SHOW_TYPE(short[7]);
+  SHOW_TYPE(S);
+  SHOW_TYPE(double S::*);
+
+  return 0;
+}
rename from xpcom/tests/gtest/TestAutoPtr.cpp
rename to xpcom/tests/TestAutoPtr.cpp
--- a/xpcom/tests/gtest/TestAutoPtr.cpp
+++ b/xpcom/tests/TestAutoPtr.cpp
@@ -1,220 +1,495 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 // vim:cindent:ts=4:et:sw=4:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAutoPtr.h"
-#include "gtest/gtest.h"
+#include <stdio.h>
+#include "nscore.h"
+#include "mozilla/Attributes.h"
 
 class TestObjectBaseA {
-  public:
-    // Virtual dtor for deleting through base class pointer
-    virtual ~TestObjectBaseA() { }
-    void MemberFunction(int, int*, int&)
-    {
-    }
-    virtual void VirtualMemberFunction(int, int*, int&) { };
-    virtual void VirtualConstMemberFunction(int, int*, int&) const { };
-    int fooA;
+    public:
+        // Virtual dtor for deleting through base class pointer
+        virtual ~TestObjectBaseA() { }
+        void MemberFunction( int, int*, int& )
+        {
+          printf("member function is invoked.\n");
+        }
+        virtual void VirtualMemberFunction(int, int*, int&) { };
+        virtual void VirtualConstMemberFunction(int, int*, int&) const { };
+        int fooA;
 };
 
 class TestObjectBaseB {
-  public:
-    // Virtual dtor for deleting through base class pointer
-    virtual ~TestObjectBaseB() { }
-    int fooB;
+    public:
+        // Virtual dtor for deleting through base class pointer
+        virtual ~TestObjectBaseB() { }
+        int fooB;
 };
 
 class TestObject : public TestObjectBaseA, public TestObjectBaseB {
-  public:
-    TestObject()
-    {
-    }
+    public:
+        TestObject()
+        {
+            printf("  Creating TestObject %p.\n",
+                   static_cast<void*>(this));
+        }
+
+        // Virtual dtor for deleting through base class pointer
+        virtual ~TestObject()
+        {
+            printf("  Destroying TestObject %p.\n",
+                   static_cast<void*>(this));
+        }
 
-    // Virtual dtor for deleting through base class pointer
-    virtual ~TestObject()
-    {
-      destructed++;
-    }
+        virtual void VirtualMemberFunction(int, int*, int&) override
+        {
+          printf("override virtual member function is invoked.\n");
+        }
+        virtual void VirtualConstMemberFunction(int, int*, int&) const override
+        {
+          printf("override virtual const member function is invoked.\n");
+        }
+};
 
-    virtual void VirtualMemberFunction(int, int*, int&) override
-    {
-    }
-    virtual void VirtualConstMemberFunction(int, int*, int&) const override
-    {
-    }
+class TestRefObjectBaseA {
+    public:
+        int fooA;
+        // Must return |nsrefcnt| to keep |nsDerivedSafe| happy.
+        virtual nsrefcnt AddRef() = 0;
+        virtual nsrefcnt Release() = 0;
+};
 
-    static int destructed;
-    static const void* last_ptr;
+class TestRefObjectBaseB {
+    public:
+        int fooB;
+        virtual nsrefcnt AddRef() = 0;
+        virtual nsrefcnt Release() = 0;
 };
 
-int TestObject::destructed = 0;
-const void* TestObject::last_ptr = nullptr;
+class TestRefObject final : public TestRefObjectBaseA, public TestRefObjectBaseB {
+    public:
+        TestRefObject()
+            : mRefCount(0)
+        {
+            printf("  Creating TestRefObject %p.\n",
+                   static_cast<void*>(this));
+        }
+
+        ~TestRefObject()
+        {
+            printf("  Destroying TestRefObject %p.\n",
+                   static_cast<void*>(this));
+        }
+
+        nsrefcnt AddRef()
+        {
+            ++mRefCount;
+            printf("  AddRef to %d on TestRefObject %p.\n",
+                   mRefCount, static_cast<void*>(this));
+            return mRefCount;
+        }
+
+        nsrefcnt Release()
+        {
+            --mRefCount;
+            printf("  Release to %d on TestRefObject %p.\n",
+                   mRefCount, static_cast<void*>(this));
+            if (mRefCount == 0) {
+                delete const_cast<TestRefObject*>(this);
+                return 0;
+            }
+            return mRefCount;
+        }
+
+    protected:
+        uint32_t mRefCount;
+
+};
 
 static void CreateTestObject(TestObject **aResult)
 {
-  *aResult = new TestObject();
+    *aResult = new TestObject();
+}
+
+static void CreateTestRefObject(TestRefObject **aResult)
+{
+    (*aResult = new TestRefObject())->AddRef();
 }
 
 static void DoSomethingWithTestObject(TestObject *aIn)
 {
-  TestObject::last_ptr = static_cast<void*>(aIn);
+    printf("  Doing something with |TestObject| %p.\n",
+           static_cast<void*>(aIn));
 }
 
 static void DoSomethingWithConstTestObject(const TestObject *aIn)
 {
-  TestObject::last_ptr = static_cast<const void*>(aIn);
+    printf("  Doing something with |const TestObject| %p.\n",
+           static_cast<const void*>(aIn));
+}
+
+static void DoSomethingWithTestRefObject(TestRefObject *aIn)
+{
+    printf("  Doing something with |TestRefObject| %p.\n",
+           static_cast<void*>(aIn));
+}
+
+static void DoSomethingWithConstTestRefObject(const TestRefObject *aIn)
+{
+    printf("  Doing something with |const TestRefObject| %p.\n",
+           static_cast<const void*>(aIn));
 }
 
 static void DoSomethingWithTestObjectBaseB(TestObjectBaseB *aIn)
 {
-  TestObject::last_ptr = static_cast<void*>(aIn);
+    printf("  Doing something with |TestObjectBaseB| %p.\n",
+           static_cast<void*>(aIn));
 }
 
 static void DoSomethingWithConstTestObjectBaseB(const TestObjectBaseB *aIn)
 {
-  TestObject::last_ptr = static_cast<const void*>(aIn);
-}
-
-TEST(AutoPtr, Assignment)
-{
-  TestObject::destructed = 0;
-
-  {
-    nsAutoPtr<TestObject> pobj( new TestObject() );
-  }
-
-  ASSERT_EQ(1, TestObject::destructed);
-
-  {
-    nsAutoPtr<TestObject> pobj( new TestObject() );
-    pobj = new TestObject();
-    ASSERT_EQ(2, TestObject::destructed);
-  }
-
-  ASSERT_EQ(3, TestObject::destructed);
+    printf("  Doing something with |const TestObjectBaseB| %p.\n",
+           static_cast<const void*>(aIn));
 }
 
-TEST(AutoPtr, getter_Transfers)
+static void DoSomethingWithTestRefObjectBaseB(TestRefObjectBaseB *aIn)
 {
-  TestObject::destructed = 0;
-
-  {
-    nsAutoPtr<TestObject> ptr;
-    CreateTestObject(getter_Transfers(ptr));
-  }
-
-  ASSERT_EQ(1, TestObject::destructed);
+    printf("  Doing something with |TestRefObjectBaseB| %p.\n",
+           static_cast<void*>(aIn));
 }
 
-TEST(AutoPtr, Casting)
+static void DoSomethingWithConstTestRefObjectBaseB(const TestRefObjectBaseB *aIn)
 {
-  // This comparison is always false, as it should be. The extra parens
-  // suppress a -Wunreachable-code warning about printf being unreachable.
-  ASSERT_NE(((void*)(TestObject*)0x1000),
-             ((void*)(TestObjectBaseB*)(TestObject*)0x1000));
-
-  {
-    nsAutoPtr<TestObject> p1(new TestObject());
-    TestObjectBaseB *p2 = p1;
-    ASSERT_NE(static_cast<void*>(p1),
-               static_cast<void*>(p2));
-    ASSERT_EQ(p1, p2);
-    ASSERT_FALSE(p1 != p2);
-    ASSERT_EQ(p2, p1);
-    ASSERT_FALSE(p2 != p1);
-  }
-
-  {
-    TestObject *p1 = new TestObject();
-    nsAutoPtr<TestObjectBaseB> p2(p1);
-    ASSERT_EQ(p1, p2);
-    ASSERT_FALSE(p1 != p2);
-    ASSERT_EQ(p2, p1);
-    ASSERT_FALSE(p2 != p1);
-  }
+    printf("  Doing something with |const TestRefObjectBaseB| %p.\n",
+           static_cast<const void*>(aIn));
 }
 
-TEST(AutoPtr, Forget)
+int main()
 {
-  TestObject::destructed = 0;
+    {
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObject> pobj( new TestObject() );
+        printf("Should destroy one |TestObject|:\n");
+    }
+
+    {
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObject> pobj( new TestObject() );
+        printf("Should create one |TestObject| and then destroy one:\n");
+        pobj = new TestObject();
+        printf("Should destroy one |TestObject|:\n");
+    }
+
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> pobj( new TestRefObject() );
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
+
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> pobj( new TestRefObject() );
+        printf("Should create and AddRef one |TestRefObject| and then Release and destroy one:\n");
+        pobj = new TestRefObject();
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
 
-  {
-    nsAutoPtr<TestObject> pobj( new TestObject() );
-    nsAutoPtr<TestObject> pobj2( pobj.forget() );
-    ASSERT_EQ(0, TestObject::destructed);
-  }
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        printf("Should AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> p2( p1 );
+        printf("Should Release twice and destroy one |TestRefObject|:\n");
+    }
+
+    printf("\nTesting equality (with all const-ness combinations):\n");
+
+    {
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        RefPtr<TestRefObject> p2( p1 );
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+    }
 
-  ASSERT_EQ(1, TestObject::destructed);
-}
+    {
+        const RefPtr<TestRefObject> p1( new TestRefObject() );
+        RefPtr<TestRefObject> p2( p1 );
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+    }
+
+    {
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        const RefPtr<TestRefObject> p2( p1 );
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+    }
 
-TEST(AutoPtr, Construction)
-{
-  TestObject::destructed = 0;
+    {
+        const RefPtr<TestRefObject> p1( new TestRefObject() );
+        const RefPtr<TestRefObject> p2( p1 );
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+    }
+
+    {
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        TestRefObject * p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
 
-  {
-    nsAutoPtr<TestObject> pobj(new TestObject());
-  }
+    {
+        const RefPtr<TestRefObject> p1( new TestRefObject() );
+        TestRefObject * p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
+
+#if 0 /* MSVC++ 6.0 can't be coaxed to accept this */
+    {
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        TestRefObject * const p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
 
-  ASSERT_EQ(1, TestObject::destructed);
-}
+    {
+        const RefPtr<TestRefObject> p1( new TestRefObject() );
+        TestRefObject * const p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
+#endif /* Things that MSVC++ 6.0 can't be coaxed to accept */
+
+    {
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        const TestRefObject * p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
+
+    {
+        const RefPtr<TestRefObject> p1( new TestRefObject() );
+        const TestRefObject * p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
 
-TEST(AutoPtr, ImplicitConversion)
-{
-  // This test is basically successful if it builds. We add a few assertions
-  // to make gtest happy.
-  TestObject::destructed = 0;
+    {
+        RefPtr<TestRefObject> p1( new TestRefObject() );
+        const TestRefObject * const p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
+
+    {
+        const RefPtr<TestRefObject> p1( new TestRefObject() );
+        const TestRefObject * const p2 = p1;
+        printf("equality %s.\n",
+               ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+    }
+
+    printf("\nTesting getter_Transfers and getter_AddRefs.\n");
+
+    {
+        nsAutoPtr<TestObject> ptr;
+        printf("Should create one |TestObject|:\n");
+        CreateTestObject(getter_Transfers(ptr));
+        printf("Should destroy one |TestObject|:\n");
+    }
 
-  {
-    nsAutoPtr<TestObject> pobj(new TestObject());
-    DoSomethingWithTestObject(pobj);
-    DoSomethingWithConstTestObject(pobj);
-  }
+    {
+        RefPtr<TestRefObject> ptr;
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        CreateTestRefObject(getter_AddRefs(ptr));
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
+
+    printf("\nTesting casts and equality tests.\n");
 
-  ASSERT_EQ(1, TestObject::destructed);
+    // This comparison is always false, as it should be. The extra parens
+    // suppress a -Wunreachable-code warning about printf being unreachable.
+    if (((void*)(TestObject*)0x1000) ==
+        ((void*)(TestObjectBaseB*)(TestObject*)0x1000))
+        printf("\n\nAll these tests are meaningless!\n\n\n");
+
+    {
+        nsAutoPtr<TestObject> p1(new TestObject());
+        TestObjectBaseB *p2 = p1;
+        printf("equality %s.\n",
+               ((static_cast<void*>(p1) != static_cast<void*>(p2)) &&
+                (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+               ? "OK" : "broken");
+    }
 
-  {
-    nsAutoPtr<TestObject> pobj(new TestObject());
-    DoSomethingWithTestObjectBaseB(pobj);
-    DoSomethingWithConstTestObjectBaseB(pobj);
-  }
+    {
+        TestObject *p1 = new TestObject();
+        nsAutoPtr<TestObjectBaseB> p2(p1);
+        printf("equality %s.\n",
+               ((static_cast<void*>(p1) != static_cast<void*>(p2)) &&
+                (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+               ? "OK" : "broken");
+    }
+
+    {
+        RefPtr<TestRefObject> p1 = new TestRefObject();
+        // nsCOMPtr requires a |get| for something like this as well
+        RefPtr<TestRefObjectBaseB> p2 = p1.get();
+        printf("equality %s.\n",
+               ((static_cast<void*>(p1) != static_cast<void*>(p2)) &&
+                (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+               ? "OK" : "broken");
+    }
 
-  ASSERT_EQ(2, TestObject::destructed);
+    {
+        RefPtr<TestRefObject> p1 = new TestRefObject();
+        TestRefObjectBaseB *p2 = p1;
+        printf("equality %s.\n",
+               ((static_cast<void*>(p1) != static_cast<void*>(p2)) &&
+                (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+               ? "OK" : "broken");
+    }
+
+    {
+        TestRefObject *p1 = new TestRefObject();
+        RefPtr<TestRefObjectBaseB> p2 = p1;
+        printf("equality %s.\n",
+               ((static_cast<void*>(p1) != static_cast<void*>(p2)) &&
+                (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+               ? "OK" : "broken");
+    }
+
+    printf("\nTesting |forget()|.\n");
 
-  {
-    const nsAutoPtr<TestObject> pobj(new TestObject());
-    DoSomethingWithTestObject(pobj);
-    DoSomethingWithConstTestObject(pobj);
-  }
+    {
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObject> pobj( new TestObject() );
+        printf("Should do nothing:\n");
+        nsAutoPtr<TestObject> pobj2( pobj.forget() );
+        printf("Should destroy one |TestObject|:\n");
+    }
+
+    {
+        printf("Should create one |TestRefObject|:\n");
+        RefPtr<TestRefObject> pobj( new TestRefObject() );
+        printf("Should do nothing:\n");
+        RefPtr<TestRefObject> pobj2( pobj.forget() );
+        printf("Should destroy one |TestRefObject|:\n");
+    }
+
+    printf("\nTesting construction.\n");
 
-  ASSERT_EQ(3, TestObject::destructed);
+    {
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObject> pobj(new TestObject());
+        printf("Should destroy one |TestObject|:\n");
+    }
+
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> pobj = new TestRefObject();
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
 
-  {
-    const nsAutoPtr<TestObject> pobj(new TestObject());
-    DoSomethingWithTestObjectBaseB(pobj);
-    DoSomethingWithConstTestObjectBaseB(pobj);
-  }
+    printf("\nTesting calling of functions (including array access and casts).\n");
+
+    {
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObject> pobj(new TestObject());
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithTestObject(pobj);
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithConstTestObject(pobj);
+        printf("Should destroy one |TestObject|:\n");
+    }
 
-  ASSERT_EQ(4, TestObject::destructed);
-}
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> pobj = new TestRefObject();
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithTestRefObject(pobj);
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithConstTestRefObject(pobj);
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
+
+    {
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObject> pobj(new TestObject());
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithTestObjectBaseB(pobj);
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithConstTestObjectBaseB(pobj);
+        printf("Should destroy one |TestObject|:\n");
+    }
 
-TEST(AutoPtr, ArrowOperator)
-{
-  // This test is basically successful if it builds. We add a few assertions
-  // to make gtest happy.
-  TestObject::destructed = 0;
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        RefPtr<TestRefObject> pobj = new TestRefObject();
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithTestRefObjectBaseB(pobj);
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithConstTestRefObjectBaseB(pobj);
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
+
+    {
+        printf("Should create one |TestObject|:\n");
+        const nsAutoPtr<TestObject> pobj(new TestObject());
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithTestObject(pobj);
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithConstTestObject(pobj);
+        printf("Should destroy one |TestObject|:\n");
+    }
 
-  {
-    int test = 1;
-    void (TestObjectBaseA::*fPtr)( int, int*, int& ) = &TestObjectBaseA::MemberFunction;
-    void (TestObjectBaseA::*fVPtr)( int, int*, int& ) = &TestObjectBaseA::VirtualMemberFunction;
-    void (TestObjectBaseA::*fVCPtr)( int, int*, int& ) const = &TestObjectBaseA::VirtualConstMemberFunction;
-    nsAutoPtr<TestObjectBaseA> pobj(new TestObject());
-    (pobj->*fPtr)(test, &test, test);
-    (pobj->*fVPtr)(test, &test, test);
-    (pobj->*fVCPtr)(test, &test, test);
-  }
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        const RefPtr<TestRefObject> pobj = new TestRefObject();
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithTestRefObject(pobj);
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithConstTestRefObject(pobj);
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
+
+    {
+        printf("Should create one |TestObject|:\n");
+        const nsAutoPtr<TestObject> pobj(new TestObject());
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithTestObjectBaseB(pobj);
+        printf("Should do something with one |TestObject|:\n");
+        DoSomethingWithConstTestObjectBaseB(pobj);
+        printf("Should destroy one |TestObject|:\n");
+    }
 
-  ASSERT_EQ(1, TestObject::destructed);
+    {
+        printf("Should create and AddRef one |TestRefObject|:\n");
+        const RefPtr<TestRefObject> pobj = new TestRefObject();
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithTestRefObjectBaseB(pobj);
+        printf("Should do something with one |TestRefObject|:\n");
+        DoSomethingWithConstTestRefObjectBaseB(pobj);
+        printf("Should Release and destroy one |TestRefObject|:\n");
+    }
+
+    {
+        int test = 1;
+        void (TestObjectBaseA::*fPtr)( int, int*, int& ) = &TestObjectBaseA::MemberFunction;
+        void (TestObjectBaseA::*fVPtr)( int, int*, int& ) = &TestObjectBaseA::VirtualMemberFunction;
+        void (TestObjectBaseA::*fVCPtr)( int, int*, int& ) const = &TestObjectBaseA::VirtualConstMemberFunction;
+        printf("Should create one |TestObject|:\n");
+        nsAutoPtr<TestObjectBaseA> pobj(new TestObject());
+        printf("Should do something with operator->*:\n");
+        (pobj->*fPtr)(test, &test, test);
+        (pobj->*fVPtr)(test, &test, test);
+        (pobj->*fVCPtr)(test, &test, test);
+        printf("Should destroy one |TestObject|:\n");
+    }
+
+    return 0;
 }
rename from xpcom/tests/gtest/TestAutoRef.cpp
rename to xpcom/tests/TestAutoRef.cpp
--- a/xpcom/tests/gtest/TestAutoRef.cpp
+++ b/xpcom/tests/TestAutoRef.cpp
@@ -1,24 +1,27 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 // vim:cindent:ts=4:et:sw=4:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAutoRef.h"
-#include "gtest/gtest.h"
+#include "TestHarness.h"
+
+#define TEST(aCondition, aMsg) \
+  if (!(aCondition)) { fail("TestAutoRef: "#aMsg); exit(1); }
 
 struct TestObjectA {
 public:
   TestObjectA() : mRefCnt(0) {
   }
 
   ~TestObjectA() {
-    EXPECT_EQ(mRefCnt, 0);
+    TEST(mRefCnt == 0, "mRefCnt in destructor");
   }
 
 public:
   int mRefCnt;
 };
 
 template <>
 class nsAutoRefTraits<TestObjectA> : public nsPointerRefTraits<TestObjectA>
@@ -35,22 +38,25 @@ public:
 
   static void AddRef(TestObjectA *ptr) {
     ptr->mRefCnt++;
   }
 };
 
 int nsAutoRefTraits<TestObjectA>::mTotalRefsCnt = 0;
 
-TEST(AutoRef, Assignment)
+int main()
 {
   {
     nsCountedRef<TestObjectA> a(new TestObjectA());
-    ASSERT_EQ(a->mRefCnt, 1);
+    TEST(a->mRefCnt == 1, "nsCountedRef instantiation with valid RawRef");
 
     nsCountedRef<TestObjectA> b;
-    ASSERT_EQ(b.get(), nullptr);
+    TEST(b.get() == nullptr, "nsCountedRef instantiation with invalid RawRef");
 
     a.swap(b);
-    ASSERT_EQ(b->mRefCnt, 1);
-    ASSERT_EQ(a.get(), nullptr);
+    TEST(b->mRefCnt, "nsAutoRef::swap() t1");
+    TEST(a.get() == nullptr, "nsAutoRef::swap() t2");
   }
+
+  TEST(true, "All tests pass");
+  return 0;
 }
rename from xpcom/tests/gtest/TestCOMArray.cpp
rename to xpcom/tests/TestCOMArray.cpp
--- a/xpcom/tests/gtest/TestCOMArray.cpp
+++ b/xpcom/tests/TestCOMArray.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:cindent:ts=4:et:sw=4:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "TestHarness.h"
 #include "nsCOMArray.h"
-#include "gtest/gtest.h"
+#include "mozilla/Attributes.h"
 
 // {9e70a320-be02-11d1-8031-006008159b5a}
 #define NS_IFOO_IID \
   {0x9e70a320, 0xbe02, 0x11d1,    \
     {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
 
 class IFoo : public nsISupports {
 public:
@@ -53,16 +54,19 @@ Foo::Foo(int32_t aID)
 Foo::~Foo()
 {
   --gCount;
 }
 
 NS_IMPL_ISUPPORTS(Foo, IFoo)
 
 
+typedef nsCOMArray<IFoo> Array;
+
+
 // {0e70a320-be02-11d1-8031-006008159b5a}
 #define NS_IBAR_IID \
   {0x0e70a320, 0xbe02, 0x11d1,    \
     {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
 
 class IBar : public nsISupports {
 public:
 
@@ -93,74 +97,95 @@ typedef nsCOMArray<IBar> Array2;
 
 Bar::Bar(Array2& aArray)
   : mArray(aArray)
 {
 }
 
 Bar::~Bar()
 {
-  EXPECT_FALSE(mArray.RemoveObject(this));
+  if (mArray.RemoveObject(this)) {
+    fail("We should never manage to remove the object here");
+  }
 }
 
 NS_IMPL_ADDREF(Bar)
 NS_IMPL_QUERY_INTERFACE(Bar, IBar)
 
 NS_IMETHODIMP_(MozExternalRefCountType)
 Bar::Release(void)
 {
   ++Bar::sReleaseCalled;
-  EXPECT_GT(int(mRefCnt), 0);
+  MOZ_RELEASE_ASSERT(int32_t(mRefCnt) > 0, "dup release");
   NS_ASSERT_OWNINGTHREAD(_class);
   --mRefCnt;
   NS_LOG_RELEASE(this, mRefCnt, "Bar");
   if (mRefCnt == 0) {
     mRefCnt = 1; /* stabilize */
     delete this;
     return 0;
   }
   return mRefCnt;
 }
 
-TEST(COMArray, Sizing)
+
+int main(int argc, char **argv)
 {
-  nsCOMArray<IFoo> arr;
+  ScopedXPCOM xpcom("nsCOMArrayTests");
+  if (xpcom.failed()) {
+    return 1;
+  }
+
+  int rv = 0;
+
+  Array arr;
 
   for (int32_t i = 0; i < 20; ++i) {
     nsCOMPtr<IFoo> foo = new Foo(i);
     arr.AppendObject(foo);
   }
 
-  ASSERT_EQ(arr.Count(), int32_t(20));
-  ASSERT_EQ(Foo::gCount, int32_t(20));
+  if (arr.Count() != 20 || Foo::gCount != 20) {
+    fail("nsCOMArray::AppendObject failed");
+    rv = 1;
+  }
 
   arr.TruncateLength(10);
 
-  ASSERT_EQ(arr.Count(), int32_t(10));
-  ASSERT_EQ(Foo::gCount, int32_t(10));
+  if (arr.Count() != 10 || Foo::gCount != 10) {
+    fail("nsCOMArray::TruncateLength shortening of array failed");
+    rv = 1;
+  }
 
   arr.SetCount(30);
 
-  ASSERT_EQ(arr.Count(), int32_t(30));
-  ASSERT_EQ(Foo::gCount, int32_t(10));
+  if (arr.Count() != 30 || Foo::gCount != 10) {
+    fail("nsCOMArray::SetCount lengthening of array failed");
+    rv = 1;
+  }
 
   for (int32_t i = 0; i < 10; ++i) {
-	ASSERT_NE(arr[i], nullptr);
+	if (arr[i] == nullptr) {
+      fail("nsCOMArray elements should be non-null");
+      rv = 1;
+	  break;
+    }
   }
 
   for (int32_t i = 10; i < 30; ++i) {
-	ASSERT_EQ(arr[i], nullptr);
+	if (arr[i] != nullptr) {
+      fail("nsCOMArray elements should be null");
+      rv = 1;
+	  break;
+    }
   }
-}
 
-TEST(COMArray, ObjectFunctions)
-{
   int32_t base;
   {
-    nsCOMArray<IBar> arr2;
+    Array2 arr2;
 
     IBar *thirdObject = nullptr,
          *fourthObject = nullptr,
          *fifthObject = nullptr,
          *ninthObject = nullptr;
     for (int32_t i = 0; i < 20; ++i) {
       nsCOMPtr<IBar> bar = new Bar(arr2);
       switch (i) {
@@ -174,50 +199,74 @@ TEST(COMArray, ObjectFunctions)
         ninthObject = bar; break;
       }
       arr2.AppendObject(bar);
     }
 
     base = Bar::sReleaseCalled;
 
     arr2.SetCount(10);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 10);
-    ASSERT_EQ(arr2.Count(), int32_t(10));
+    if (Bar::sReleaseCalled != base + 10) {
+      fail("Release called multiple times for SetCount");
+    }
+    if (arr2.Count() != 10) {
+      fail("SetCount(10) should remove exactly ten objects");
+    }
 
     arr2.RemoveObjectAt(9);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 11);
-    ASSERT_EQ(arr2.Count(), int32_t(9));
+    if (Bar::sReleaseCalled != base + 11) {
+      fail("Release called multiple times for RemoveObjectAt");
+    }
+    if (arr2.Count() != 9) {
+      fail("RemoveObjectAt should remove exactly one object");
+    }
 
     arr2.RemoveObject(ninthObject);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 12);
-    ASSERT_EQ(arr2.Count(), int32_t(8));
+    if (Bar::sReleaseCalled != base + 12) {
+      fail("Release called multiple times for RemoveObject");
+    }
+    if (arr2.Count() != 8) {
+      fail("RemoveObject should remove exactly one object");
+    }
 
     arr2.RemoveObjectsAt(2, 3);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 15);
-    ASSERT_EQ(arr2.Count(), int32_t(5));
+    if (Bar::sReleaseCalled != base + 15) {
+      fail("Release called more or less than three times for RemoveObjectsAt");
+    }
+    if (arr2.Count() != 5) {
+      fail("RemoveObjectsAt should remove exactly three objects");
+    }
     for (int32_t j = 0; j < arr2.Count(); ++j) {
-      ASSERT_NE(arr2.ObjectAt(j), thirdObject);
-      ASSERT_NE(arr2.ObjectAt(j), fourthObject);
-      ASSERT_NE(arr2.ObjectAt(j), fifthObject);
+      if (arr2.ObjectAt(j) == thirdObject) {
+        fail("RemoveObjectsAt should have removed thirdObject");
+      }
+      if (arr2.ObjectAt(j) == fourthObject) {
+        fail("RemoveObjectsAt should have removed fourthObject");
+      }
+      if (arr2.ObjectAt(j) == fifthObject) {
+        fail("RemoveObjectsAt should have removed fifthObject");
+      }
     }
 
     arr2.RemoveObjectsAt(4, 1);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 16);
-    ASSERT_EQ(arr2.Count(), int32_t(4));
+    if (Bar::sReleaseCalled != base + 16) {
+      fail("Release called more or less than one time for RemoveObjectsAt");
+    }
+    if (arr2.Count() != 4) {
+      fail("RemoveObjectsAt should work for removing the last element");
+    }
 
     arr2.Clear();
-    ASSERT_EQ(Bar::sReleaseCalled, base + 20);
+    if (Bar::sReleaseCalled != base + 20) {
+      fail("Release called multiple times for Clear");
+    }
   }
-}
 
-TEST(COMArray, ElementFunctions)
-{
-  int32_t base;
   {
-    nsCOMArray<IBar> arr2;
+    Array2 arr2;
 
     IBar *thirdElement = nullptr,
          *fourthElement = nullptr,
          *fifthElement = nullptr,
          *ninthElement = nullptr;
     for (int32_t i = 0; i < 20; ++i) {
       nsCOMPtr<IBar> bar = new Bar(arr2);
       switch (i) {
@@ -231,56 +280,84 @@ TEST(COMArray, ElementFunctions)
         ninthElement = bar; break;
       }
       arr2.AppendElement(bar);
     }
 
     base = Bar::sReleaseCalled;
 
     arr2.TruncateLength(10);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 10);
-    ASSERT_EQ(arr2.Length(), uint32_t(10));
+    if (Bar::sReleaseCalled != base + 10) {
+      fail("Release called multiple times for TruncateLength");
+    }
+    if (arr2.Length() != 10) {
+      fail("TruncateLength(10) should remove exactly ten objects");
+    }
 
     arr2.RemoveElementAt(9);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 11);
-    ASSERT_EQ(arr2.Length(), uint32_t(9));
+    if (Bar::sReleaseCalled != base + 11) {
+      fail("Release called multiple times for RemoveElementAt");
+    }
+    if (arr2.Length() != 9) {
+      fail("RemoveElementAt should remove exactly one object");
+    }
 
     arr2.RemoveElement(ninthElement);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 12);
-    ASSERT_EQ(arr2.Length(), uint32_t(8));
+    if (Bar::sReleaseCalled != base + 12) {
+      fail("Release called multiple times for RemoveElement");
+    }
+    if (arr2.Length() != 8) {
+      fail("RemoveElement should remove exactly one object");
+    }
 
     arr2.RemoveElementsAt(2, 3);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 15);
-    ASSERT_EQ(arr2.Length(), uint32_t(5));
+    if (Bar::sReleaseCalled != base + 15) {
+      fail("Release called more or less than three times for RemoveElementsAt");
+    }
+    if (arr2.Length() != 5) {
+      fail("RemoveElementsAt should remove exactly three objects");
+    }
     for (uint32_t j = 0; j < arr2.Length(); ++j) {
-      ASSERT_NE(arr2.ElementAt(j), thirdElement);
-      ASSERT_NE(arr2.ElementAt(j), fourthElement);
-      ASSERT_NE(arr2.ElementAt(j), fifthElement);
+      if (arr2.ElementAt(j) == thirdElement) {
+        fail("RemoveElementsAt should have removed thirdElement");
+      }
+      if (arr2.ElementAt(j) == fourthElement) {
+        fail("RemoveElementsAt should have removed fourthElement");
+      }
+      if (arr2.ElementAt(j) == fifthElement) {
+        fail("RemoveElementsAt should have removed fifthElement");
+      }
     }
 
     arr2.RemoveElementsAt(4, 1);
-    ASSERT_EQ(Bar::sReleaseCalled, base + 16);
-    ASSERT_EQ(arr2.Length(), uint32_t(4));
+    if (Bar::sReleaseCalled != base + 16) {
+      fail("Release called more or less than one time for RemoveElementsAt");
+    }
+    if (arr2.Length() != 4) {
+      fail("RemoveElementsAt should work for removing the last element");
+    }
 
     arr2.Clear();
-    ASSERT_EQ(Bar::sReleaseCalled, base + 20);
+    if (Bar::sReleaseCalled != base + 20) {
+      fail("Release called multiple times for Clear");
+    }
   }
-}
 
-TEST(COMArray, Destructor)
-{
-  int32_t base;
   Bar::sReleaseCalled = 0;
 
   {
-    nsCOMArray<IBar> arr2;
+    Array2 arr2;
 
     for (int32_t i = 0; i < 20; ++i) {
       nsCOMPtr<IBar> bar  = new Bar(arr2);
       arr2.AppendObject(bar);
     }
 
     base = Bar::sReleaseCalled;
 
     // Let arr2 be destroyed
   }
-  ASSERT_EQ(Bar::sReleaseCalled, base + 20);
+  if (Bar::sReleaseCalled != base + 20) {
+    fail("Release called multiple times for nsCOMArray::~nsCOMArray");
+  }
+
+  return rv;
 }
rename from xpcom/tests/gtest/TestCOMPtr.cpp
rename to xpcom/tests/TestCOMPtr.cpp
--- a/xpcom/tests/gtest/TestCOMPtr.cpp
+++ b/xpcom/tests/TestCOMPtr.cpp
@@ -1,459 +1,549 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include <assert.h>
+#include <stdio.h>
 #include "nsCOMPtr.h"
-#include "gtest/gtest.h"
-
+#include "nsISupports.h"
 #include "mozilla/Unused.h"
 
 #define NS_IFOO_IID \
 { 0x6f7652e0,  0xee43, 0x11d1, \
-  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
+ { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
 
 class IFoo : public nsISupports
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
+  {
+		public:
+			NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
 
-public:
-  IFoo();
-  // virtual dtor because IBar uses our Release()
-  virtual ~IFoo();
+		public:
+      IFoo();
+      // virtual dtor because IBar uses our Release()
+      virtual ~IFoo();
 
-  NS_IMETHOD_(MozExternalRefCountType) AddRef();
-  NS_IMETHOD_(MozExternalRefCountType) Release();
-  NS_IMETHOD QueryInterface( const nsIID&, void** );
+      NS_IMETHOD_(MozExternalRefCountType) AddRef();
+      NS_IMETHOD_(MozExternalRefCountType) Release();
+      NS_IMETHOD QueryInterface( const nsIID&, void** );
+
+      static void print_totals();
 
-  unsigned int refcount_;
+    private:
+      unsigned int refcount_;
 
-  static int total_constructions_;
-  static int total_destructions_;
-  static int total_queries_;
-};
+      static unsigned int total_constructions_;
+      static unsigned int total_destructions_;
+  };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
 
-int IFoo::total_constructions_;
-int IFoo::total_destructions_;
-int IFoo::total_queries_;
+class IBar;
+
+  // some types I'll need
+typedef unsigned long NS_RESULT;
+
+  // some functions I'll need (and define below)
+          nsresult  CreateIFoo( void** );
+          nsresult  CreateIBar( void** result );
+              void  AnIFooPtrPtrContext( IFoo** );
+              void	AnISupportsPtrPtrContext( nsISupports** );
+              void  AVoidPtrPtrContext( void** );
+              void  set_a_IFoo( nsCOMPtr<IFoo>* result );
+nsCOMPtr<IFoo>  return_a_IFoo();
+
+
+
+
+unsigned int IFoo::total_constructions_;
+unsigned int IFoo::total_destructions_;
+
+class test_message
+  {
+    public:
+      test_message()
+        {
+          printf("BEGIN unit tests for |nsCOMPtr|, compiled " __DATE__ "\n");
+        }
+
+     ~test_message()
+        {
+          IFoo::print_totals();
+          printf("END unit tests for |nsCOMPtr|.\n");
+        }
+  };
+
+test_message gTestMessage;
+
+
+  /*
+    ...
+  */
+
+void
+IFoo::print_totals()
+  {
+    printf("total constructions/destructions --> %d/%d\n", 
+           total_constructions_, total_destructions_);
+  }
 
 IFoo::IFoo()
-  : refcount_(0)
-{
-  ++total_constructions_;
-}
+    : refcount_(0)
+  {
+    ++total_constructions_;
+    printf("  new IFoo@%p [#%d]\n",
+           static_cast<void*>(this), total_constructions_);
+  }
 
 IFoo::~IFoo()
-{
-  ++total_destructions_;
-}
+  {
+    ++total_destructions_;
+    printf("IFoo@%p::~IFoo() [#%d]\n",
+           static_cast<void*>(this), total_destructions_);
+  }
 
 MozExternalRefCountType
 IFoo::AddRef()
-{
-  ++refcount_;
-  return refcount_;
-}
+  {
+    ++refcount_;
+    printf("IFoo@%p::AddRef(), refcount --> %d\n", 
+           static_cast<void*>(this), refcount_);
+    return refcount_;
+  }
 
 MozExternalRefCountType
 IFoo::Release()
-{
-  int newcount = --refcount_;
+  {
+    int newcount = --refcount_;
+    if ( newcount == 0 )
+      printf(">>");
+
+    printf("IFoo@%p::Release(), refcount --> %d\n",
+           static_cast<void*>(this), refcount_);
 
-  if ( newcount == 0 )
-  {
-    delete this;
+    if ( newcount == 0 )
+      {
+        printf("  delete IFoo@%p\n", static_cast<void*>(this));
+        printf("<<IFoo@%p::Release()\n", static_cast<void*>(this));
+        delete this;
+      }
+
+    return newcount;
   }
 
-  return newcount;
-}
-
 nsresult
 IFoo::QueryInterface( const nsIID& aIID, void** aResult )
-{
-  total_queries_++;
-
-  nsISupports* rawPtr = 0;
-  nsresult status = NS_OK;
+	{
+    printf("IFoo@%p::QueryInterface()\n", static_cast<void*>(this));
+		nsISupports* rawPtr = 0;
+		nsresult status = NS_OK;
 
-  if ( aIID.Equals(NS_GET_IID(IFoo)) )
-    rawPtr = this;
-  else
-  {
-    nsID iid_of_ISupports = NS_ISUPPORTS_IID;
-    if ( aIID.Equals(iid_of_ISupports) )
-      rawPtr = static_cast<nsISupports*>(this);
-    else
-      status = NS_ERROR_NO_INTERFACE;
-  }
+		if ( aIID.Equals(NS_GET_IID(IFoo)) )
+			rawPtr = this;
+		else
+			{
+				nsID iid_of_ISupports = NS_ISUPPORTS_IID;
+				if ( aIID.Equals(iid_of_ISupports) )
+					rawPtr = static_cast<nsISupports*>(this);
+				else
+					status = NS_ERROR_NO_INTERFACE;
+			}
 
-  NS_IF_ADDREF(rawPtr);
-  *aResult = rawPtr;
+		NS_IF_ADDREF(rawPtr);
+		*aResult = rawPtr;
 
-  return status;
-}
+		return status;
+	}
 
 nsresult
 CreateIFoo( void** result )
-// a typical factory function (that calls AddRef)
-{
-  IFoo* foop = new IFoo;
+    // a typical factory function (that calls AddRef)
+  {
+    printf(">>CreateIFoo() --> ");
+    IFoo* foop = new IFoo;
+    printf("IFoo@%p\n", static_cast<void*>(foop));
 
-  foop->AddRef();
-  *result = foop;
+    foop->AddRef();
+    *result = foop;
 
-  return NS_OK;
-}
+    printf("<<CreateIFoo()\n");
+    return NS_OK;
+  }
 
 void
 set_a_IFoo( nsCOMPtr<IFoo>* result )
-{
-  nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
-  *result = foop;
-}
+  {
+    printf(">>set_a_IFoo()\n");
+    assert(result);
+
+    nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+    *result = foop;
+    printf("<<set_a_IFoo()\n");
+  }
 
 nsCOMPtr<IFoo>
 return_a_IFoo()
-{
-  nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
-  return foop;
-}
+  {
+    printf(">>return_a_IFoo()\n");
+    nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+    printf("<<return_a_IFoo()\n");
+    return foop;
+  }
+
+
+
 
 #define NS_IBAR_IID \
 { 0x6f7652e1,  0xee43, 0x11d1, \
-  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
+ { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
 
 class IBar : public IFoo
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IBAR_IID)
+  {
+  	public:
+  		NS_DECLARE_STATIC_IID_ACCESSOR(NS_IBAR_IID)
 
-public:
-  IBar();
-  virtual ~IBar();
+    public:
+      IBar();
+      virtual ~IBar();
 
-  NS_IMETHOD QueryInterface( const nsIID&, void** );
-
-  static int total_destructions_;
-  static int total_queries_;
-};
+      NS_IMETHOD QueryInterface( const nsIID&, void** );
+  };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IBar, NS_IBAR_IID)
 
-int IBar::total_destructions_;
-int IBar::total_queries_;
-
 IBar::IBar()
-{
-}
+  {
+    printf("  new IBar@%p\n", static_cast<void*>(this));
+  }
 
 IBar::~IBar()
-{
-  total_destructions_++;
-}
+  {
+    printf("IBar@%p::~IBar()\n", static_cast<void*>(this));
+  }
 
 nsresult
 IBar::QueryInterface( const nsID& aIID, void** aResult )
-{
-  total_queries_++;
-
-  nsISupports* rawPtr = 0;
-  nsresult status = NS_OK;
+	{
+    printf("IBar@%p::QueryInterface()\n", static_cast<void*>(this));
+		nsISupports* rawPtr = 0;
+		nsresult status = NS_OK;
 
-  if ( aIID.Equals(NS_GET_IID(IBar)) )
-    rawPtr = this;
-  else if ( aIID.Equals(NS_GET_IID(IFoo)) )
-    rawPtr = static_cast<IFoo*>(this);
-  else
-  {
-    nsID iid_of_ISupports = NS_ISUPPORTS_IID;
-    if ( aIID.Equals(iid_of_ISupports) )
-      rawPtr = static_cast<nsISupports*>(this);
-    else
-      status = NS_ERROR_NO_INTERFACE;
-  }
+		if ( aIID.Equals(NS_GET_IID(IBar)) )
+			rawPtr = this;
+		else if ( aIID.Equals(NS_GET_IID(IFoo)) )
+			rawPtr = static_cast<IFoo*>(this);
+		else
+			{
+				nsID iid_of_ISupports = NS_ISUPPORTS_IID;
+				if ( aIID.Equals(iid_of_ISupports) )
+					rawPtr = static_cast<nsISupports*>(this);
+				else
+					status = NS_ERROR_NO_INTERFACE;
+			}
 
-  NS_IF_ADDREF(rawPtr);
-  *aResult = rawPtr;
+		NS_IF_ADDREF(rawPtr);
+		*aResult = rawPtr;
 
-  return status;
-}
+		return status;
+	}
 
 
 
 nsresult
 CreateIBar( void** result )
-  // a typical factory function (that calls AddRef)
-{
-  IBar* barp = new IBar;
+    // a typical factory function (that calls AddRef)
+  {
+    printf(">>CreateIBar() --> ");
+    IBar* barp = new IBar;
+    printf("IBar@%p\n", static_cast<void*>(barp));
 
-  barp->AddRef();
-  *result = barp;
+    barp->AddRef();
+    *result = barp;
 
-  return NS_OK;
-}
+    printf("<<CreateIBar()\n");
+    return NS_OK;
+  }
 
 void
 AnIFooPtrPtrContext( IFoo** )
-{
-}
+  {
+  }
 
 void
 AVoidPtrPtrContext( void** )
-{
-}
+  {
+  }
 
 void
 AnISupportsPtrPtrContext( nsISupports** )
-{
-}
+	{
+	}
+
+static
+nsresult
+TestBloat_Raw_Unsafe()
+	{
+		IBar* barP = 0;
+		nsresult result = CreateIBar(reinterpret_cast<void**>(&barP));
+
+		if ( barP )
+			{
+				IFoo* fooP = 0;
+				if ( NS_SUCCEEDED( result = barP->QueryInterface(NS_GET_IID(IFoo), reinterpret_cast<void**>(&fooP)) ) )
+					{
+						fooP->print_totals();
+						NS_RELEASE(fooP);
+					}
+
+				NS_RELEASE(barP);
+			}
+
+		return result;
+	}
+
 
-TEST(COMPtr, Bloat_Raw_Unsafe)
-{
-  // ER: I'm not sure what this is testing...
-  IBar* barP = 0;
-  nsresult rv = CreateIBar(reinterpret_cast<void**>(&barP));
-  ASSERT_TRUE(NS_SUCCEEDED(rv));
-  ASSERT_TRUE(barP);
+static
+nsresult
+TestBloat_Smart()
+	{
+		nsCOMPtr<IBar> barP;
+		nsresult result = CreateIBar( getter_AddRefs(barP) );
+
+		nsCOMPtr<IFoo> fooP( do_QueryInterface(barP, &result) );
+
+		if ( fooP )
+			fooP->print_totals();
+
+		return result;
+	}
+
+
+
 
-  IFoo* fooP = 0;
-  rv = barP->QueryInterface(NS_GET_IID(IFoo), reinterpret_cast<void**>(&fooP));
-  ASSERT_TRUE(NS_SUCCEEDED(rv));
-  ASSERT_TRUE(fooP);
+nsCOMPtr<IFoo> gFoop;
+
+int
+main()
+  {
+    printf(">>main()\n");
+
+		printf("sizeof(nsCOMPtr<IFoo>) --> %u\n", unsigned(sizeof(nsCOMPtr<IFoo>)));
 
-  NS_RELEASE(fooP);
-  NS_RELEASE(barP);
-}
+		TestBloat_Raw_Unsafe();
+		TestBloat_Smart();
+
+
+    {
+      printf("\n### Test  1: will a |nsCOMPtr| call |AddRef| on a pointer assigned into it?\n");
+      nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+
+      printf("\n### Test  2: will a |nsCOMPtr| |Release| its old pointer when a new one is assigned in?\n");
+      foop = do_QueryInterface(new IFoo);
 
-TEST(COMPtr, Bloat_Smart)
-{
-  // ER: I'm not sure what this is testing...
-  nsCOMPtr<IBar> barP;
-  nsresult rv = CreateIBar( getter_AddRefs(barP) );
-  ASSERT_TRUE(NS_SUCCEEDED(rv));
-  ASSERT_TRUE(barP);
+        // [Shouldn't compile] Is it a compile time error to try to |AddRef| by hand?
+      //foop->AddRef();
+
+        // [Shouldn't compile] Is it a compile time error to try to |Release| be hand?
+      //foop->Release();
+
+				// [Shouldn't compile] Is it a compile time error to try to |delete| an |nsCOMPtr|?
+			//delete foop;
+
+      printf("\n### Test  3: can you |AddRef| if you must?\n");
+      static_cast<IFoo*>(foop)->AddRef();
+
+      printf("\n### Test  4: can you |Release| if you must?\n");
+      static_cast<IFoo*>(foop)->Release();
 
-  nsCOMPtr<IFoo> fooP( do_QueryInterface(barP, &rv) );
-  ASSERT_TRUE(NS_SUCCEEDED(rv));
-  ASSERT_TRUE(fooP);
-}
+      printf("\n### Test  5: will a |nsCOMPtr| |Release| when it goes out of scope?\n");
+    }
+
+    {
+      printf("\n### Test  6: will a |nsCOMPtr| call the correct destructor?\n");
+      nsCOMPtr<IFoo> foop( do_QueryInterface(new IBar) );
+      mozilla::Unused << foop;
+    }
+
+    {
+      printf("\n### Test  7: can you compare one |nsCOMPtr| with another [!=]?\n");
+
+      nsCOMPtr<IFoo> foo1p( do_QueryInterface(new IFoo) );
+
+        // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
+      //AnIFooPtrPtrContext(&foo1p);
 
-TEST(COMPtr, AddRefAndRelease)
-{
-  IFoo::total_constructions_ = 0;
-  IFoo::total_destructions_ = 0;
-  IBar::total_destructions_ = 0;
+        // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
+      //AVoidPtrPtrContext(&foo1p);
+
+      nsCOMPtr<IFoo> foo2p( do_QueryInterface(new IFoo) );
+
+      if ( foo1p != foo2p )
+        printf("foo1p != foo2p\n");
+      else
+        printf("foo1p == foo2p\n");
+
+
+      IFoo* raw_foo2p = foo2p.get();
 
-  {
-    nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
-    ASSERT_EQ(foop->refcount_, (unsigned int)1);
-    ASSERT_EQ(IFoo::total_constructions_, 1);
-    ASSERT_EQ(IFoo::total_destructions_, 0);
+      printf("\n### Test  8: can you compare a |nsCOMPtr| with a raw interface pointer [!=]?\n");
+      if ( foo1p.get() != raw_foo2p )
+        printf("foo1p != raw_foo2p\n");
+      else
+        printf("foo1p == raw_foo2p\n");
+
+
+      printf("\n### Test  9: can you assign one |nsCOMPtr| into another?\n");
+      foo1p = foo2p;
 
-    foop = do_QueryInterface(new IFoo);
-    ASSERT_EQ(foop->refcount_, (unsigned int)1);
-    ASSERT_EQ(IFoo::total_constructions_, 2);
-    ASSERT_EQ(IFoo::total_destructions_, 1);
+      printf("\n### Test 10: can you compare one |nsCOMPtr| with another [==]?\n");
+      if ( foo1p == foo2p )
+        printf("foo1p == foo2p\n");
+      else
+        printf("foo1p != foo2p\n");
 
-    // [Shouldn't compile] Is it a compile time error to try to |AddRef| by hand?
-    //foop->AddRef();
+      printf("\n### Test 11: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
+      if ( raw_foo2p == foo2p.get() )
+        printf("raw_foo2p == foo2p\n");
+      else
+        printf("raw_foo2p != foo2p\n");
 
-    // [Shouldn't compile] Is it a compile time error to try to |Release| be hand?
-    //foop->Release();
+#if 1
+      printf("\n### Test 11.5: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
+      if ( nsCOMPtr<IFoo>( raw_foo2p ) == foo2p )
+        printf("raw_foo2p == foo2p\n");
+      else
+        printf("raw_foo2p != foo2p\n");
+#endif
+
+      printf("\n### Test 12: bare pointer test?\n");
+      if ( foo1p )
+        printf("foo1p is not NULL\n");
+      else
+        printf("foo1p is NULL\n");
 
-    // [Shouldn't compile] Is it a compile time error to try to |delete| an |nsCOMPtr|?
-    //delete foop;
+#if 0
+			if ( foo1p == 1 )
+				printf("foo1p allowed compare with in\n");
+#endif
+
+      printf("\n### Test 13: how about when two |nsCOMPtr|s referring to the same object go out of scope?\n");
+    }
 
-    static_cast<IFoo*>(foop)->AddRef();
-    ASSERT_EQ(foop->refcount_, (unsigned int)2);
-    ASSERT_EQ(IFoo::total_constructions_, 2);
-    ASSERT_EQ(IFoo::total_destructions_, 1);
+    {
+      printf("\n### Test 14,15 ...setup...\n");
+      IFoo* raw_foo1p = new IFoo;
+      raw_foo1p->AddRef();
+
+      IFoo* raw_foo2p = new IFoo;
+      raw_foo2p->AddRef();
+
+      printf("\n### Test 14: what if I don't want to |AddRef| when I construct?\n");
+      nsCOMPtr<IFoo> foo1p( dont_AddRef(raw_foo1p) );
+      //nsCOMPtr<IFoo> foo1p = dont_AddRef(raw_foo1p);
 
-    static_cast<IFoo*>(foop)->Release();
-    ASSERT_EQ(foop->refcount_, (unsigned int)1);
-    ASSERT_EQ(IFoo::total_constructions_, 2);
-    ASSERT_EQ(IFoo::total_destructions_, 1);
-  }
+      printf("\n### Test 15: what if I don't want to |AddRef| when I assign in?\n");
+      nsCOMPtr<IFoo> foo2p;
+      foo2p = dont_AddRef(raw_foo2p);
+    }
+
+
+
+
+
+
 
-  ASSERT_EQ(IFoo::total_constructions_, 2);
-  ASSERT_EQ(IFoo::total_destructions_, 2);
+    {
+      printf("\n### setup for Test 16\n");
+      nsCOMPtr<IFoo> foop;
+      printf("### Test 16: basic parameter behavior?\n");
+      CreateIFoo( nsGetterAddRefs<IFoo>(foop) );
+    }
+    printf("### End Test 16\n");
+
 
-  {
-    nsCOMPtr<IFoo> foop( do_QueryInterface(new IBar) );
-    mozilla::Unused << foop;
-  }
+    {
+      printf("\n### setup for Test 17\n");
+      nsCOMPtr<IFoo> foop;
+      printf("### Test 17: basic parameter behavior, using the short form?\n");
+      CreateIFoo( getter_AddRefs(foop) );
+    }
+    printf("### End Test 17\n");
 
-  ASSERT_EQ(IBar::total_destructions_, 1);
-}
+
+    {
+      printf("\n### setup for Test 18, 19\n");
+      nsCOMPtr<IFoo> foop;
+      printf("### Test 18: reference parameter behavior?\n");
+      set_a_IFoo(address_of(foop));
 
-void Comparison()
-{
-  IFoo::total_constructions_ = 0;
-  IFoo::total_destructions_ = 0;
+      printf("### Test 19: return value behavior?\n");
+      foop = return_a_IFoo();
+    }
+    printf("### End Test 18, 19\n");
+
+		{
+      printf("\n### setup for Test 20\n");
+			nsCOMPtr<IFoo> fooP;
+
+			printf("### Test 20: is |QueryInterface| called on assigning in a raw pointer?\n");
+			fooP = do_QueryInterface(new IFoo);
+		}
+    printf("### End Test 20\n");
 
-  {
-    nsCOMPtr<IFoo> foo1p( do_QueryInterface(new IFoo) );
-    nsCOMPtr<IFoo> foo2p( do_QueryInterface(new IFoo) );
+		{
+      printf("\n### setup for Test 21\n");
+			nsCOMPtr<IFoo> fooP;
+			fooP = do_QueryInterface(new IFoo);
+
+			nsCOMPtr<IFoo> foo2P;
 
-    ASSERT_EQ(IFoo::total_constructions_, 2);
+			printf("### Test 21: is |QueryInterface| _not_ called when assigning in a smart-pointer of the same type?\n");
+			foo2P = fooP;
+		}
+    printf("### End Test 21\n");
 
-    // Test != operator
-    ASSERT_NE(foo1p, foo2p);
-    ASSERT_NE(foo1p, foo2p.get());
+		{
+      printf("\n### setup for Test 22\n");
+			nsCOMPtr<IBar> barP( do_QueryInterface(new IBar) );
+
+			printf("### Test 22: is |QueryInterface| called when assigning in a smart-pointer of a different type?\n");
 
-    // Test == operator
-    foo1p = foo2p;
+			nsCOMPtr<IFoo> fooP( do_QueryInterface(barP) );
+			if ( fooP )
+				printf("an IBar* is an IFoo*\n");
+		}
+    printf("### End Test 22\n");
+
 
-    ASSERT_EQ(IFoo::total_destructions_, 1);
+		{
+      printf("\n### setup for Test 23\n");
+			nsCOMPtr<IFoo> fooP( do_QueryInterface(new IFoo) );
+
+			printf("### Test 23: does |forget| avoid an AddRef/Release when assigning to another nsCOMPtr?\n");
+      nsCOMPtr<IFoo> fooP2( fooP.forget() );
+		}
+    printf("### End Test 23\n");
+
+		{
+			nsCOMPtr<IFoo> fooP;
 
-    ASSERT_EQ(foo1p, foo2p);
-    ASSERT_EQ(foo2p, foo2p.get());
-    ASSERT_EQ(foo2p.get(), foo2p);
+			AnIFooPtrPtrContext( getter_AddRefs(fooP) );
+			AVoidPtrPtrContext( getter_AddRefs(fooP) );
+		}
+
+
+		{
+			nsCOMPtr<nsISupports> supportsP;
 
-    // Test () operator
-    ASSERT_TRUE(foo1p);
+			AVoidPtrPtrContext( getter_AddRefs(supportsP) );
+			AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
+		}
+
 
-    ASSERT_EQ(foo1p->refcount_, (unsigned int)2);
-    ASSERT_EQ(foo2p->refcount_, (unsigned int)2);
+    printf("\n### Test 24: will a static |nsCOMPtr| |Release| before program termination?\n");
+    gFoop = do_QueryInterface(new IFoo);
+    
+    printf("<<main()\n");
+    return 0;
   }
 
-  ASSERT_EQ(IFoo::total_destructions_, 2);
-}
-
-void DontAddRef()
-{
-  {
-    IFoo* raw_foo1p = new IFoo;
-    raw_foo1p->AddRef();
-
-    IFoo* raw_foo2p = new IFoo;
-    raw_foo2p->AddRef();
-
-    nsCOMPtr<IFoo> foo1p( dont_AddRef(raw_foo1p) );
-    ASSERT_EQ(raw_foo1p, foo1p);
-    ASSERT_EQ(foo1p->refcount_, (unsigned int)1);
-
-    nsCOMPtr<IFoo> foo2p;
-    foo2p = dont_AddRef(raw_foo2p);
-    ASSERT_EQ(raw_foo2p, foo2p);
-    ASSERT_EQ(foo2p->refcount_, (unsigned int)1);
-  }
-}
-
-TEST(COMPtr, AssignmentHelpers)
-{
-  IFoo::total_constructions_ = 0;
-  IFoo::total_destructions_ = 0;
-
-  {
-    nsCOMPtr<IFoo> foop;
-    ASSERT_FALSE(foop);
-    CreateIFoo( nsGetterAddRefs<IFoo>(foop) );
-    ASSERT_TRUE(foop);
-  }
-
-  ASSERT_EQ(IFoo::total_constructions_, 1);
-  ASSERT_EQ(IFoo::total_destructions_, 1);
-
-  {
-    nsCOMPtr<IFoo> foop;
-    ASSERT_FALSE(foop);
-    CreateIFoo( getter_AddRefs(foop) );
-    ASSERT_TRUE(foop);
-  }
-
-  ASSERT_EQ(IFoo::total_constructions_, 2);
-  ASSERT_EQ(IFoo::total_destructions_, 2);
-
-  {
-    nsCOMPtr<IFoo> foop;
-    ASSERT_FALSE(foop);
-    set_a_IFoo(address_of(foop));
-    ASSERT_TRUE(foop);
-
-    ASSERT_EQ(IFoo::total_constructions_, 3);
-    ASSERT_EQ(IFoo::total_destructions_, 2);
-
-    foop = return_a_IFoo();
-    ASSERT_TRUE(foop);
-
-    ASSERT_EQ(IFoo::total_constructions_, 4);
-    ASSERT_EQ(IFoo::total_destructions_, 3);
-  }
-
-  ASSERT_EQ(IFoo::total_constructions_, 4);
-  ASSERT_EQ(IFoo::total_destructions_, 4);
-
-  {
-    nsCOMPtr<IFoo> fooP( do_QueryInterface(new IFoo) );
-    ASSERT_TRUE(fooP);
-
-    ASSERT_EQ(IFoo::total_constructions_, 5);
-    ASSERT_EQ(IFoo::total_destructions_, 4);
-
-    nsCOMPtr<IFoo> fooP2( fooP.forget() );
-    ASSERT_TRUE(fooP2);
-
-    ASSERT_EQ(IFoo::total_constructions_, 5);
-    ASSERT_EQ(IFoo::total_destructions_, 4);
-  }
-
-  ASSERT_EQ(IFoo::total_constructions_, 5);
-  ASSERT_EQ(IFoo::total_destructions_, 5);
-}
-
-TEST(COMPtr, QueryInterface)
-{
-  IFoo::total_queries_ = 0;
-  IBar::total_queries_ = 0;
-
-  {
-    nsCOMPtr<IFoo> fooP;
-    ASSERT_FALSE(fooP);
-    fooP = do_QueryInterface(new IFoo);
-    ASSERT_TRUE(fooP);
-    ASSERT_EQ(IFoo::total_queries_, 1);
-
-    nsCOMPtr<IFoo> foo2P;
-
-    // Test that |QueryInterface| _not_ called when assigning a smart-pointer
-    // of the same type.);
-    foo2P = fooP;
-    ASSERT_EQ(IFoo::total_queries_, 1);
-  }
-
-  {
-    nsCOMPtr<IBar> barP( do_QueryInterface(new IBar) );
-    ASSERT_EQ(IBar::total_queries_, 1);
-
-    // Test that |QueryInterface| is called when assigning a smart-pointer of
-    // a different type.
-    nsCOMPtr<IFoo> fooP( do_QueryInterface(barP) );
-    ASSERT_EQ(IBar::total_queries_, 2);
-    ASSERT_EQ(IFoo::total_queries_, 1);
-    ASSERT_TRUE(fooP);
-  }
-}
-
-TEST(COMPtr, GetterConversions)
-{
-  // This is just a compilation test. We add a few asserts to keep gtest happy.
-  {
-    nsCOMPtr<IFoo> fooP;
-    ASSERT_FALSE(fooP);
-
-    AnIFooPtrPtrContext( getter_AddRefs(fooP) );
-    AVoidPtrPtrContext( getter_AddRefs(fooP) );
-  }
-
-
-  {
-    nsCOMPtr<nsISupports> supportsP;
-    ASSERT_FALSE(supportsP);
-
-    AVoidPtrPtrContext( getter_AddRefs(supportsP) );
-    AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
-  }
-}
rename from xpcom/tests/gtest/TestCOMPtrEq.cpp
rename to xpcom/tests/TestCOMPtrEq.cpp
--- a/xpcom/tests/gtest/TestCOMPtrEq.cpp
+++ b/xpcom/tests/TestCOMPtrEq.cpp
@@ -1,79 +1,166 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/**
- * This attempts to test all the possible variations of |operator==|
- * used with |nsCOMPtr|s.
- */
+ /**
+  * This attempts to test all the possible variations of |operator==|
+  * used with |nsCOMPtr|s.  Currently only the tests where pointers
+  * are to the same class are enabled.  It's not clear whether we
+  * should be supporting other tests, and some of them won't work
+  * on at least some platforms.  If we add separate comparisons
+  * for nsCOMPtr<nsISupports> we'll need to add more tests for
+  * those cases.
+  */
 
 #include "nsCOMPtr.h"
-#include "gtest/gtest.h"
+
+  // Don't test these now, since some of them won't work and it's
+  // not clear whether they should (see above).
+#undef NSCAP_EQTEST_TEST_ACROSS_TYPES
 
 #define NS_ICOMPTREQTESTFOO_IID \
-{0x8eb5bbef, 0xd1a3, 0x4659, \
-  {0x9c, 0xf6, 0xfd, 0xf3, 0xe4, 0xd2, 0x00, 0x0e}}
+  {0x8eb5bbef, 0xd1a3, 0x4659, \
+    {0x9c, 0xf6, 0xfd, 0xf3, 0xe4, 0xd2, 0x00, 0x0e}}
 
 class nsICOMPtrEqTestFoo : public nsISupports {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICOMPTREQTESTFOO_IID)
+  public:
+    NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICOMPTREQTESTFOO_IID)
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICOMPtrEqTestFoo, NS_ICOMPTREQTESTFOO_IID)
 
-TEST(COMPtrEq, NullEquality)
-{
-  nsCOMPtr<nsICOMPtrEqTestFoo> s;
-  nsICOMPtrEqTestFoo* r = nullptr;
-  const nsCOMPtr<nsICOMPtrEqTestFoo> sc;
-  const nsICOMPtrEqTestFoo* rc = nullptr;
-  nsICOMPtrEqTestFoo* const rk = nullptr;
-  const nsICOMPtrEqTestFoo* const rkc = nullptr;
-  nsICOMPtrEqTestFoo* d = s;
+#ifdef NSCAP_EQTEST_TEST_ACROSS_TYPES
+
+#define NS_ICOMPTREQTESTFOO2_IID \
+  {0x6516387b, 0x36c5, 0x4036, \
+    {0x82, 0xc9, 0xa7, 0x4d, 0xd9, 0xe5, 0x92, 0x2f}}
+
+class nsICOMPtrEqTestFoo2 : public nsISupports {
+  public:
+    NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICOMPTREQTESTFOO2_IID)
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsICOMPtrEqTestFoo2, NS_ICOMPTREQTESTFOO2_IID)
+
+#endif
+
+int
+main()
+  {
+    nsCOMPtr<nsICOMPtrEqTestFoo> s;
+    nsICOMPtrEqTestFoo* r = 0;
+    const nsCOMPtr<nsICOMPtrEqTestFoo> sc;
+    const nsICOMPtrEqTestFoo* rc = 0;
+    nsICOMPtrEqTestFoo* const rk = 0;
+    const nsICOMPtrEqTestFoo* const rkc = 0;
+    nsICOMPtrEqTestFoo* d = s;
+    
+#ifdef NSCAP_EQTEST_TEST_ACROSS_TYPES
+    nsCOMPtr<nsICOMPtrEqTestFoo2> s2;
+    nsICOMPtrEqTestFoo2* r2 = 0;
+    const nsCOMPtr<nsICOMPtrEqTestFoo2> sc2;
+    const nsICOMPtrEqTestFoo2* rc2 = 0;
+    nsICOMPtrEqTestFoo2* const rk2 = 0;
+    const nsICOMPtrEqTestFoo2* const rkc2 = 0;
+    nsICOMPtrEqTestFoo2* d2 = s2;
+#endif
 
-  ASSERT_EQ(s, s);
-  ASSERT_EQ(s, r);
-  ASSERT_EQ(s, sc);
-  ASSERT_EQ(s, rc);
-  ASSERT_EQ(s, rk);
-  ASSERT_EQ(s, rkc);
-  ASSERT_EQ(s, d);
-  ASSERT_EQ(r, s);
-  ASSERT_EQ(r, sc);
-  ASSERT_EQ(r, rc);
-  ASSERT_EQ(r, rk);
-  ASSERT_EQ(r, rkc);
-  ASSERT_EQ(r, d);
-  ASSERT_EQ(sc, s);
-  ASSERT_EQ(sc, r);
-  ASSERT_EQ(sc, sc);
-  ASSERT_EQ(sc, rc);
-  ASSERT_EQ(sc, rk);
-  ASSERT_EQ(sc, rkc);
-  ASSERT_EQ(sc, d);
-  ASSERT_EQ(rc, s);
-  ASSERT_EQ(rc, r);
-  ASSERT_EQ(rc, sc);
-  ASSERT_EQ(rc, rk);
-  ASSERT_EQ(rc, rkc);
-  ASSERT_EQ(rc, d);
-  ASSERT_EQ(rk, s);
-  ASSERT_EQ(rk, r);
-  ASSERT_EQ(rk, sc);
-  ASSERT_EQ(rk, rc);
-  ASSERT_EQ(rk, rkc);
-  ASSERT_EQ(rk, d);
-  ASSERT_EQ(rkc, s);
-  ASSERT_EQ(rkc, r);
-  ASSERT_EQ(rkc, sc);
-  ASSERT_EQ(rkc, rc);
-  ASSERT_EQ(rkc, rk);
-  ASSERT_EQ(rkc, d);
-  ASSERT_EQ(d, s);
-  ASSERT_EQ(d, r);
-  ASSERT_EQ(d, sc);
-  ASSERT_EQ(d, rc);
-  ASSERT_EQ(d, rk);
-  ASSERT_EQ(d, rkc);
-}
+    return (!(true &&
+              (s == s) &&
+              (s == r) &&
+              (s == sc) &&
+              (s == rc) &&
+              (s == rk) &&
+              (s == rkc) &&
+              (s == d) &&
+              (r == s) &&
+              (r == sc) &&
+              (r == rc) &&
+              (r == rk) &&
+              (r == rkc) &&
+              (r == d) &&
+              (sc == s) &&
+              (sc == r) &&
+              (sc == sc) &&
+              (sc == rc) &&
+              (sc == rk) &&
+              (sc == rkc) &&
+              (sc == d) &&
+              (rc == s) &&
+              (rc == r) &&
+              (rc == sc) &&
+              (rc == rk) &&
+              (rc == rkc) &&
+              (rc == d) &&
+              (rk == s) &&
+              (rk == r) &&
+              (rk == sc) &&
+              (rk == rc) &&
+              (rk == rkc) &&
+              (rk == d) &&
+              (rkc == s) &&
+              (rkc == r) &&
+              (rkc == sc) &&
+              (rkc == rc) &&
+              (rkc == rk) &&
+              (rkc == d) &&
+              (d == s) &&
+              (d == r) &&
+              (d == sc) &&
+              (d == rc) &&
+              (d == rk) &&
+              (d == rkc) &&
+#ifdef NSCAP_EQTEST_TEST_ACROSS_TYPES
+              (s == s2) &&
+              (s == r2) &&
+              (s == sc2) &&
+              (s == rc2) &&
+              (s == rk2) &&
+              (s == rkc2) &&
+              (s == d2) &&
+              (r == s2) &&
+              (r == r2) &&
+              (r == sc2) &&
+              (r == rc2) &&
+              (r == rk2) &&
+              (r == rkc2) &&
+              (r == d2) &&
+              (sc == s2) &&
+              (sc == r2) &&
+              (sc == sc2) &&
+              (sc == rc2) &&
+              (sc == rk2) &&
+              (sc == rkc2) &&
+              (sc == d2) &&
+              (rc == s2) &&
+              (rc == r2) &&
+              (rc == sc2) &&
+              (rc == rc2) &&
+              (rc == rk2) &&
+              (rc == rkc2) &&
+              (rc == d2) &&
+              (rk == s2) &&
+              (rk == r2) &&
+              (rk == sc2) &&
+              (rk == rc2) &&
+              (rk == rk2) &&
+              (rk == rkc2) &&
+              (rk == d2) &&
+              (rkc == s2) &&
+              (rkc == r2) &&
+              (rkc == sc2) &&
+              (rkc == rc2) &&
+              (rkc == rk2) &&
+              (rkc == rkc2) &&
+              (rkc == d2) &&
+              (d == s2) &&
+              (d == r2) &&
+              (d == sc2) &&
+              (d == rc2) &&
+              (d == rk2) &&
+              (d == rkc2) &&
+              (d == d2) &&
+#endif
+              true));
+  }
rename from xpcom/tests/gtest/TestFile.cpp
rename to xpcom/tests/TestFile.cpp
--- a/xpcom/tests/gtest/TestFile.cpp
+++ b/xpcom/tests/TestFile.cpp
@@ -1,477 +1,524 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "prio.h"
 #include "prsystem.h"
 
+#include "TestHarness.h"
+
 #include "nsIFile.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 
-#include "gtest/gtest.h"
+static const char* gFunction = "main";
 
 static bool VerifyResult(nsresult aRV, const char* aMsg)
 {
-  bool failed = NS_FAILED(aRV);
-  EXPECT_FALSE(failed) << aMsg << " rv=" << std::hex << (unsigned int)aRV;
-  return !failed;
+    if (NS_FAILED(aRV)) {
+        fail("%s %s, rv=%x", gFunction, aMsg, aRV);
+        return false;
+    }
+    return true;
 }
 
 static already_AddRefed<nsIFile> NewFile(nsIFile* aBase)
 {
-  nsresult rv;
-  nsCOMPtr<nsIFile> file =
-    do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
-  VerifyResult(rv, "Creating nsIFile");
-  rv = file->InitWithFile(aBase);
-  VerifyResult(rv, "InitWithFile");
-  return file.forget();
+    nsresult rv;
+    nsCOMPtr<nsIFile> file =
+        do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+    VerifyResult(rv, "Creating nsIFile");
+    rv = file->InitWithFile(aBase);
+    VerifyResult(rv, "InitWithFile");
+    return file.forget();
 }
 
 static nsCString FixName(const char* aName)
 {
-  nsCString name;
-  for (uint32_t i = 0; aName[i]; ++i) {
-    char ch = aName[i];
-    // PR_GetPathSeparator returns the wrong value on Mac so don't use it
+    nsCString name;
+    for (uint32_t i = 0; aName[i]; ++i) {
+        char ch = aName[i];
+       // PR_GetPathSeparator returns the wrong value on Mac so don't use it
 #if defined(XP_WIN)
-    if (ch == '/') {
-      ch = '\\';
-    }
+        if (ch == '/') {
+            ch = '\\';
+        }
 #endif
-    name.Append(ch);
-  }
-  return name;
+        name.Append(ch);
+    }
+    return name;
 }
 
 // Test nsIFile::AppendNative, verifying that aName is not a valid file name
 static bool TestInvalidFileName(nsIFile* aBase, const char* aName)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
+    gFunction = "TestInvalidFileName";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (NS_SUCCEEDED(rv)) {
-    EXPECT_FALSE(NS_SUCCEEDED(rv)) << "AppendNative with invalid filename " << name.get();
-    return false;
-  }
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (NS_SUCCEEDED(rv)) {
+        fail("%s AppendNative with invalid filename %s", gFunction, name.get());
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::Create, verifying that the file exists and did not exist before,
 // and leaving it there for future tests
 static bool TestCreate(nsIFile* aBase, const char* aName, int32_t aType, int32_t aPerm)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
+    gFunction = "TestCreate";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
 
-  bool exists;
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (before)"))
-    return false;
-  EXPECT_FALSE(exists) << "File "<< name.get() << " already exists";
-  if (exists) {
-    return false;
-  }
+    bool exists;
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (before)"))
+        return false;
+    if (exists) {
+        fail("%s File %s already exists", gFunction, name.get());
+        return false;
+    }
 
-  rv = file->Create(aType, aPerm);
-  if (!VerifyResult(rv, "Create"))
-    return false;
+    rv = file->Create(aType, aPerm);  
+    if (!VerifyResult(rv, "Create"))
+        return false;
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (after)"))
-    return false;
-  EXPECT_TRUE(exists) << "File " << name.get() << " was not created";
-  if (!exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (after)"))
+        return false;
+    if (!exists) {
+        fail("%s File %s was not created", gFunction, name.get());
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::CreateUnique, verifying that the new file exists and if it existed before,
 // the new file has a different name.
 // The new file is left in place.
 static bool TestCreateUnique(nsIFile* aBase, const char* aName, int32_t aType, int32_t aPerm)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
-
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    gFunction = "TestCreateUnique";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  bool existsBefore;
-  rv = file->Exists(&existsBefore);
-  if (!VerifyResult(rv, "Exists (before)"))
-    return false;
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
 
-  rv = file->CreateUnique(aType, aPerm);
-  if (!VerifyResult(rv, "Create"))
-    return false;
+    bool existsBefore;
+    rv = file->Exists(&existsBefore);
+    if (!VerifyResult(rv, "Exists (before)"))
+        return false;
+
+    rv = file->CreateUnique(aType, aPerm);  
+    if (!VerifyResult(rv, "Create"))
+        return false;
 
-  bool existsAfter;
-  rv = file->Exists(&existsAfter);
-  if (!VerifyResult(rv, "Exists (after)"))
-    return false;
-  EXPECT_TRUE(existsAfter) << "File " << name.get() << " was not created";
-  if (!existsAfter) {
-    return false;
-  }
+    bool existsAfter;
+    rv = file->Exists(&existsAfter);
+    if (!VerifyResult(rv, "Exists (after)"))
+        return false;
+    if (!existsAfter) {
+        fail("%s File %s was not created", gFunction, name.get());
+        return false;
+    }
 
-  if (existsBefore) {
-    nsAutoCString leafName;
-    rv = file->GetNativeLeafName(leafName);
-    if (!VerifyResult(rv, "GetNativeLeafName"))
-      return false;
-    EXPECT_FALSE(leafName.Equals(name)) << "File " << name.get() << " was not given a new name by CreateUnique";
-    if (leafName.Equals(name)) {
-      return false;
+    if (existsBefore) {
+        nsAutoCString leafName;
+        rv = file->GetNativeLeafName(leafName);
+        if (!VerifyResult(rv, "GetNativeLeafName"))
+            return false;
+        if (leafName.Equals(name)) {
+            fail("%s File %s was not given a new name by CreateUnique", gFunction, name.get());
+            return false;
+        }
     }
-  }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::OpenNSPRFileDesc with DELETE_ON_CLOSE, verifying that the file exists
 // and did not exist before, and leaving it there for future tests
 static bool TestDeleteOnClose(nsIFile* aBase, const char* aName, int32_t aFlags, int32_t aPerm)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
-
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    gFunction = "TestDeleteOnClose";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  bool exists;
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (before)"))
-    return false;
-  EXPECT_FALSE(exists) << "File " << name.get() << " already exists";
-  if (exists) {
-    return false;
-  }
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
+
+    bool exists;
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (before)"))
+        return false;
+    if (exists) {
+        fail("%s File %s already exists", gFunction, name.get());
+        return false;
+    }
 
-  PRFileDesc* fileDesc;
-  rv = file->OpenNSPRFileDesc(aFlags | nsIFile::DELETE_ON_CLOSE, aPerm, &fileDesc);
-  if (!VerifyResult(rv, "OpenNSPRFileDesc"))
-    return false;
-  PRStatus status = PR_Close(fileDesc);
-  EXPECT_EQ(status, PR_SUCCESS) << "File " << name.get() << " could not be closed";
-  if (status != PR_SUCCESS) {
-    return false;
-  }
+    PRFileDesc* fileDesc;
+    rv = file->OpenNSPRFileDesc(aFlags | nsIFile::DELETE_ON_CLOSE, aPerm, &fileDesc);  
+    if (!VerifyResult(rv, "OpenNSPRFileDesc"))
+        return false;
+    PRStatus status = PR_Close(fileDesc);
+    if (status != PR_SUCCESS) {
+        fail("%s File %s could not be closed", gFunction, name.get());
+        return false;
+    }
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (after)"))
-    return false;
-  EXPECT_FALSE(exists) << "File " << name.get() << " was not removed on close";
-  if (exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (after)"))
+        return false;
+    if (exists) {
+        fail("%s File %s was not removed on close!", gFunction, name.get());
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::Remove, verifying that the file does not exist and did before
 static bool TestRemove(nsIFile* aBase, const char* aName, bool aRecursive)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
+    gFunction = "TestDelete";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
 
-  bool exists;
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (before)"))
-    return false;
-  EXPECT_TRUE(exists);
-  if (!exists) {
-    return false;
-  }
+    bool exists;
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (before)"))
+        return false;
+    if (!exists) {
+        fail("%s File %s does not exist", gFunction, name.get());
+        return false;
+    }
 
-  rv = file->Remove(aRecursive);
-  if (!VerifyResult(rv, "Remove"))
-    return false;
+    rv = file->Remove(aRecursive);  
+    if (!VerifyResult(rv, "Remove"))
+        return false;
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (after)"))
-    return false;
-  EXPECT_FALSE(exists) << "File " << name.get() << " was not removed";
-  if (exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (after)"))
+        return false;
+    if (exists) {
+        fail("%s File %s was not removed", gFunction, name.get());
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::MoveToNative, verifying that the file did not exist at the new location
 // before and does afterward, and that it does not exist at the old location anymore
 static bool TestMove(nsIFile* aBase, nsIFile* aDestDir, const char* aName, const char* aNewName)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
+    gFunction = "TestMove";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
 
-  bool exists;
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (before)"))
-    return false;
-  EXPECT_TRUE(exists);
-  if (!exists) {
-    return false;
-  }
+    bool exists;
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (before)"))
+        return false;
+    if (!exists) {
+        fail("%s File %s does not exist", gFunction, name.get());
+        return false;
+    }
 
-  nsCOMPtr<nsIFile> newFile = NewFile(file);
-  nsCString newName = FixName(aNewName);
-  rv = newFile->MoveToNative(aDestDir, newName);
-  if (!VerifyResult(rv, "MoveToNative"))
-    return false;
+    nsCOMPtr<nsIFile> newFile = NewFile(file);
+    nsCString newName = FixName(aNewName);
+    rv = newFile->MoveToNative(aDestDir, newName);
+    if (!VerifyResult(rv, "MoveToNative"))
+        return false;
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (after)"))
-    return false;
-  EXPECT_FALSE(exists) << "File " << name.get() << " was not moved";
-  if (exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (after)"))
+        return false;
+    if (exists) {
+        fail("%s File %s was not moved", gFunction, name.get());
+        return false;
+    }
 
-  file = NewFile(aDestDir);
-  if (!file)
-    return false;
-  rv = file->AppendNative(newName);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
-  bool equal;
-  rv = file->Equals(newFile, &equal);
-  if (!VerifyResult(rv, "Equals"))
-    return false;
-  EXPECT_TRUE(equal) << "File object was not updated to destination";
-  if (!equal) {
-    return false;
-  }
+    file = NewFile(aDestDir);
+    if (!file)
+        return false;
+    rv = file->AppendNative(newName);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
+    bool equal;
+    rv = file->Equals(newFile, &equal);
+    if (!VerifyResult(rv, "Equals"))
+        return false;
+    if (!equal) {
+        fail("%s file object was not updated to destination", gFunction);
+        return false;
+    }
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (new after)"))
-    return false;
-  EXPECT_TRUE(exists) << "Destination file " << newName.get() << " was not created";
-  if (!exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (new after)"))
+        return false;
+    if (!exists) {
+        fail("%s Destination file %s was not created", gFunction, newName.get());
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::CopyToNative, verifying that the file did not exist at the new location
 // before and does afterward, and that it does exist at the old location too
 static bool TestCopy(nsIFile* aBase, nsIFile* aDestDir, const char* aName, const char* aNewName)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aBase);
-  if (!file)
-    return false;
-
-  nsCString name = FixName(aName);
-  nsresult rv = file->AppendNative(name);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    gFunction = "TestCopy";
+    nsCOMPtr<nsIFile> file = NewFile(aBase);
+    if (!file)
+        return false;
 
-  bool exists;
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (before)"))
-    return false;
-  EXPECT_TRUE(exists);
-  if (!exists) {
-    return false;
-  }
+    nsCString name = FixName(aName);
+    nsresult rv = file->AppendNative(name);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
+
+    bool exists;
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (before)"))
+        return false;
+    if (!exists) {
+        fail("%s File %s does not exist", gFunction, name.get());
+        return false;
+    }
 
-  nsCOMPtr<nsIFile> newFile = NewFile(file);
-  nsCString newName = FixName(aNewName);
-  rv = newFile->CopyToNative(aDestDir, newName);
-  if (!VerifyResult(rv, "MoveToNative"))
-    return false;
-  bool equal;
-  rv = file->Equals(newFile, &equal);
-  if (!VerifyResult(rv, "Equals"))
-    return false;
-  EXPECT_TRUE(equal) << "File object updated unexpectedly";
-  if (!equal) {
-    return false;
-  }
+    nsCOMPtr<nsIFile> newFile = NewFile(file);
+    nsCString newName = FixName(aNewName);
+    rv = newFile->CopyToNative(aDestDir, newName);
+    if (!VerifyResult(rv, "MoveToNative"))
+        return false;
+    bool equal;
+    rv = file->Equals(newFile, &equal);
+    if (!VerifyResult(rv, "Equals"))
+        return false;
+    if (!equal) {
+        fail("%s file object updated unexpectedly", gFunction);
+        return false;
+    }
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (after)"))
-    return false;
-  EXPECT_TRUE(exists) << "File " << name.get() << " was removed";
-  if (!exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (after)"))
+        return false;
+    if (!exists) {
+        fail("%s File %s was removed", gFunction, name.get());
+        return false;
+    }
 
-  file = NewFile(aDestDir);
-  if (!file)
-    return false;
-  rv = file->AppendNative(newName);
-  if (!VerifyResult(rv, "AppendNative"))
-    return false;
+    file = NewFile(aDestDir);
+    if (!file)
+        return false;
+    rv = file->AppendNative(newName);
+    if (!VerifyResult(rv, "AppendNative"))
+        return false;
 
-  rv = file->Exists(&exists);
-  if (!VerifyResult(rv, "Exists (new after)"))
-    return false;
-  EXPECT_TRUE(exists) << "Destination file " << newName.get() << " was not created";
-  if (!exists) {
-    return false;
-  }
+    rv = file->Exists(&exists);
+    if (!VerifyResult(rv, "Exists (new after)"))
+        return false;
+    if (!exists) {
+        fail("%s Destination file %s was not created", gFunction, newName.get());
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::GetParent
 static bool TestParent(nsIFile* aBase, nsIFile* aStart)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aStart);
-  if (!file)
-    return false;
+    gFunction = "TestParent";
+    nsCOMPtr<nsIFile> file = NewFile(aStart);
+    if (!file)
+        return false;
 
-  nsCOMPtr<nsIFile> parent;
-  nsresult rv = file->GetParent(getter_AddRefs(parent));
-  VerifyResult(rv, "GetParent");
+    nsCOMPtr<nsIFile> parent;
+    nsresult rv = file->GetParent(getter_AddRefs(parent));
+    VerifyResult(rv, "GetParent");
 
-  bool equal;
-  rv = parent->Equals(aBase, &equal);
-  VerifyResult(rv, "Equals");
-  EXPECT_TRUE(equal) << "Incorrect parent";
-  if (!equal) {
-    return false;
-  }
+    bool equal;
+    rv = parent->Equals(aBase, &equal);
+    VerifyResult(rv, "Equals");
+    if (!equal) {
+        fail("%s Incorrect parent", gFunction);
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
 // Test nsIFile::Normalize and native path setting/getting
 static bool TestNormalizeNativePath(nsIFile* aBase, nsIFile* aStart)
 {
-  nsCOMPtr<nsIFile> file = NewFile(aStart);
-  if (!file)
-    return false;
+    gFunction = "TestNormalizeNativePath";
+    nsCOMPtr<nsIFile> file = NewFile(aStart);
+    if (!file)
+        return false;
 
-  nsAutoCString path;
-  nsresult rv = file->GetNativePath(path);
-  VerifyResult(rv, "GetNativePath");
-  path.Append(FixName("/./.."));
-  rv = file->InitWithNativePath(path);
-  VerifyResult(rv, "InitWithNativePath");
-  rv = file->Normalize();
-  VerifyResult(rv, "Normalize");
-  rv = file->GetNativePath(path);
-  VerifyResult(rv, "GetNativePath (after normalization)");
+    nsAutoCString path;
+    nsresult rv = file->GetNativePath(path);
+    VerifyResult(rv, "GetNativePath");
+    path.Append(FixName("/./.."));
+    rv = file->InitWithNativePath(path);
+    VerifyResult(rv, "InitWithNativePath");
+    rv = file->Normalize();
+    VerifyResult(rv, "Normalize");
+    rv = file->GetNativePath(path);
+    VerifyResult(rv, "GetNativePath (after normalization)");
 
-  nsAutoCString basePath;
-  rv = aBase->GetNativePath(basePath);
-  VerifyResult(rv, "GetNativePath (base)");
+    nsAutoCString basePath;
+    rv = aBase->GetNativePath(basePath);
+    VerifyResult(rv, "GetNativePath (base)");
 
-  EXPECT_TRUE(path.Equals(basePath)) << "Incorrect normalization: " << path.get() << " - " << basePath.get();
-  if (!path.Equals(basePath)) {
-    return false;
-  }
+    if (!path.Equals(basePath)) {
+        fail("%s Incorrect normalization");
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
-TEST(TestFile, Tests)
+int main(int argc, char** argv)
 {
-  nsCOMPtr<nsIFile> base;
-  nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(base));
-  ASSERT_TRUE(VerifyResult(rv, "Getting temp directory"));
+    ScopedXPCOM xpcom("nsLocalFile");
+    if (xpcom.failed())
+        return 1;
 
-  rv = base->AppendNative(nsDependentCString("mozfiletests"));
-  ASSERT_TRUE(VerifyResult(rv, "Appending mozfiletests to temp directory name"));
+    nsCOMPtr<nsIFile> base;
+    nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(base));
+    if (!VerifyResult(rv, "Getting temp directory"))
+        return 1;
+    rv = base->AppendNative(nsDependentCString("mozfiletests"));
+    if (!VerifyResult(rv, "Appending mozfiletests to temp directory name"))
+        return 1;
+    // Remove the directory in case tests failed and left it behind.
+    // don't check result since it might not be there
+    base->Remove(true);
 
-  // Remove the directory in case tests failed and left it behind.
-  // don't check result since it might not be there
-  base->Remove(true);
-
-  // Now create the working directory we're going to use
-  rv = base->Create(nsIFile::DIRECTORY_TYPE, 0700);
-  ASSERT_TRUE(VerifyResult(rv, "Creating temp directory"));
+    // Now create the working directory we're going to use
+    rv = base->Create(nsIFile::DIRECTORY_TYPE, 0700);
+    if (!VerifyResult(rv, "Creating temp directory"))
+        return 1;
+    // Now we can safely normalize the path
+    rv = base->Normalize();
+    if (!VerifyResult(rv, "Normalizing temp directory name"))
+        return 1;
 
-  // Now we can safely normalize the path
-  rv = base->Normalize();
-  ASSERT_TRUE(VerifyResult(rv, "Normalizing temp directory name"));
+    // Initialize subdir object for later use
+    nsCOMPtr<nsIFile> subdir = NewFile(base);
+    if (!subdir)
+        return 1;
+    rv = subdir->AppendNative(nsDependentCString("subdir"));
+    if (!VerifyResult(rv, "Appending 'subdir' to test dir name"))
+        return 1;
 
-  // Initialize subdir object for later use
-  nsCOMPtr<nsIFile> subdir = NewFile(base);
-  ASSERT_TRUE(subdir);
+    passed("Setup");
 
-  rv = subdir->AppendNative(nsDependentCString("subdir"));
-  ASSERT_TRUE(VerifyResult(rv, "Appending 'subdir' to test dir name"));
+    // Test path parsing
+    if (TestInvalidFileName(base, "a/b")) {
+        passed("AppendNative with invalid file name");
+    }
+    if (TestParent(base, subdir)) {
+        passed("GetParent");
+    }
 
-  // ---------------
-  // End setup code.
-  // ---------------
-
-  // Test path parsing
-  ASSERT_TRUE(TestInvalidFileName(base, "a/b"));
-  ASSERT_TRUE(TestParent(base, subdir));
+    // Test file creation
+    if (TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600)) {
+        passed("Create file");
+    }
+    if (TestRemove(base, "file.txt", false)) {
+        passed("Remove file");
+    }
 
-  // Test file creation
-  ASSERT_TRUE(TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600));
-  ASSERT_TRUE(TestRemove(base, "file.txt", false));
-
-  // Test directory creation
-  ASSERT_TRUE(TestCreate(base, "subdir", nsIFile::DIRECTORY_TYPE, 0700));
+    // Test directory creation
+    if (TestCreate(base, "subdir", nsIFile::DIRECTORY_TYPE, 0700)) {
+        passed("Create directory");
+    }
 
-  // Test move and copy in the base directory
-  ASSERT_TRUE(TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600));
-  ASSERT_TRUE(TestMove(base, base, "file.txt", "file2.txt"));
-  ASSERT_TRUE(TestCopy(base, base, "file2.txt", "file3.txt"));
-
-  // Test moving across directories
-  ASSERT_TRUE(TestMove(base, subdir, "file2.txt", "file2.txt"));
-
-  // Test moving across directories and renaming at the same time
-  ASSERT_TRUE(TestMove(subdir, base, "file2.txt", "file4.txt"));
+    // Test move and copy in the base directory
+    if (TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600) &&
+        TestMove(base, base, "file.txt", "file2.txt")) {
+        passed("MoveTo rename file");
+    }
+    if (TestCopy(base, base, "file2.txt", "file3.txt")) {
+        passed("CopyTo copy file");
+    }
+    // Test moving across directories
+    if (TestMove(base, subdir, "file2.txt", "file2.txt")) {
+        passed("MoveTo move file");
+    }
+    // Test moving across directories and renaming at the same time
+    if (TestMove(subdir, base, "file2.txt", "file4.txt")) {
+        passed("MoveTo move and rename file");
+    }
+    // Test copying across directoreis
+    if (TestCopy(base, subdir, "file4.txt", "file5.txt")) {
+        passed("CopyTo copy file across directories");
+    }
 
-  // Test copying across directoreis
-  ASSERT_TRUE(TestCopy(base, subdir, "file4.txt", "file5.txt"));
+    // Run normalization tests while the directory exists
+    if (TestNormalizeNativePath(base, subdir)) {
+        passed("Normalize with native paths");
+    }
 
-  // Run normalization tests while the directory exists
-  ASSERT_TRUE(TestNormalizeNativePath(base, subdir));
-
-  // Test recursive directory removal
-  ASSERT_TRUE(TestRemove(base, "subdir", true));
+    // Test recursive directory removal
+    if (TestRemove(base, "subdir", true)) {
+        passed("Remove directory");
+    }
 
-  ASSERT_TRUE(TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600));
-  ASSERT_TRUE(TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600));
-  ASSERT_TRUE(TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700));
-  ASSERT_TRUE(TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700));
+    if (TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600) &&
+        TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600)) {
+        passed("CreateUnique file");
+    }
+    if (TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700) &&
+        TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700)) {
+        passed("CreateUnique directory");
+    }
 
-  ASSERT_TRUE(TestDeleteOnClose(base, "file7.txt", PR_RDWR | PR_CREATE_FILE, 0600));
+    if (TestDeleteOnClose(base, "file7.txt", PR_RDWR | PR_CREATE_FILE, 0600)) {
+        passed("OpenNSPRFileDesc DELETE_ON_CLOSE");
+    }
 
-  // Clean up temporary stuff
-  rv = base->Remove(true);
-  VerifyResult(rv, "Cleaning up temp directory");
+    gFunction = "main";
+    // Clean up temporary stuff
+    rv = base->Remove(true);
+    VerifyResult(rv, "Cleaning up temp directory");
+
+    return gFailCount > 0;
 }
rename from xpcom/tests/gtest/TestHashtables.cpp
rename to xpcom/tests/TestHashtables.cpp
--- a/xpcom/tests/gtest/TestHashtables.cpp
+++ b/xpcom/tests/TestHashtables.cpp
@@ -10,30 +10,32 @@
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
 
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
 #include "nsCOMArray.h"
 #include "mozilla/Attributes.h"
 
-#include "gtest/gtest.h"
+#include <stdio.h>
 
 namespace TestHashtables {
 
 class TestUniChar // for nsClassHashtable
 {
 public:
   explicit TestUniChar(uint32_t aWord)
   {
+    printf("    TestUniChar::TestUniChar() %u\n", aWord);
     mWord = aWord;
   }
 
   ~TestUniChar()
   {
+    printf("    TestUniChar::~TestUniChar() %u\n", mWord);
   }
 
   uint32_t GetChar() const { return mWord; }
 
 private:
   uint32_t mWord;
 };
 
@@ -81,59 +83,96 @@ public:
   const EntityNode* mNode;
 };
 
 static uint32_t
 nsTIterPrint(nsTHashtable<EntityToUnicodeEntry>& hash)
 {
   uint32_t n = 0;
   for (auto iter = hash.Iter(); !iter.Done(); iter.Next()) {
+    EntityToUnicodeEntry* entry = iter.Get();
+    printf("  enumerated \"%s\" = %u\n",
+           entry->mNode->mStr, entry->mNode->mUnicode);
     n++;
   }
   return n;
 }
 
 static uint32_t
 nsTIterPrintRemove(nsTHashtable<EntityToUnicodeEntry>& hash)
 {
   uint32_t n = 0;
   for (auto iter = hash.Iter(); !iter.Done(); iter.Next()) {
+    EntityToUnicodeEntry* entry = iter.Get();
+    printf("  enumerated \"%s\" = %u\n",
+           entry->mNode->mStr, entry->mNode->mUnicode);
     iter.Remove();
     n++;
   }
   return n;
 }
 
 void
 testTHashtable(nsTHashtable<EntityToUnicodeEntry>& hash, uint32_t numEntries) {
+  printf("Filling hash with %d entries.\n", numEntries);
+
   uint32_t i;
   for (i = 0; i < numEntries; ++i) {
+    printf("  Putting entry \"%s\"...", gEntities[i].mStr);
     EntityToUnicodeEntry* entry =
       hash.PutEntry(gEntities[i].mStr);
 
-    EXPECT_TRUE(entry);
+    if (!entry) {
+      printf("FAILED\n");
+      exit (2);
+    }
+    printf("OK...");
 
-    EXPECT_FALSE(entry->mNode);
+    if (entry->mNode) {
+      printf("entry already exists!\n");
+      exit (3);
+    }
+    printf("\n");
+
     entry->mNode = &gEntities[i];
   }
 
+  printf("Testing Get:\n");
+
   for (i = 0; i < numEntries; ++i) {
+    printf("  Getting entry \"%s\"...", gEntities[i].mStr);
     EntityToUnicodeEntry* entry =
       hash.GetEntry(gEntities[i].mStr);
 
-    EXPECT_TRUE(entry);
+    if (!entry) {
+      printf("FAILED\n");
+      exit (4);
+    }
+
+    printf("Found %u\n", entry->mNode->mUnicode);
   }
 
+  printf("Testing nonexistent entries...");
+
   EntityToUnicodeEntry* entry =
     hash.GetEntry("xxxy");
 
-  EXPECT_FALSE(entry);
+  if (entry) {
+    printf("FOUND! BAD!\n");
+    exit (5);
+  }
+
+  printf("not found; good.\n");
 
+  printf("Enumerating:\n");
   uint32_t count = nsTIterPrint(hash);
-  EXPECT_EQ(count, numEntries);
+  if (count != numEntries) {
+    printf("  Bad count!\n");
+    exit (6);
+  }
 }
 
 //
 // all this nsIFoo stuff was copied wholesale from TestCOMPtr.cpp
 //
 
 #define NS_IFOO_IID \
 { 0x6f7652e0,  0xee43, 0x11d1, \
@@ -168,51 +207,68 @@ class IFoo final : public nsISupports
 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
 
 unsigned int IFoo::total_constructions_;
 unsigned int IFoo::total_destructions_;
 
 void
 IFoo::print_totals()
   {
+    printf("total constructions/destructions --> %d/%d\n",
+           total_constructions_, total_destructions_);
   }
 
 IFoo::IFoo()
     : refcount_(0)
   {
     ++total_constructions_;
+    printf("  new IFoo@%p [#%d]\n",
+           static_cast<void*>(this), total_constructions_);
   }
 
 IFoo::~IFoo()
   {
     ++total_destructions_;
+    printf("IFoo@%p::~IFoo() [#%d]\n",
+           static_cast<void*>(this), total_destructions_);
   }
 
 MozExternalRefCountType
 IFoo::AddRef()
   {
     ++refcount_;
+    printf("IFoo@%p::AddRef(), refcount --> %d\n", 
+           static_cast<void*>(this), refcount_);
     return refcount_;
   }
 
 MozExternalRefCountType
 IFoo::Release()
   {
     int newcount = --refcount_;
     if ( newcount == 0 )
+      printf(">>");
+
+    printf("IFoo@%p::Release(), refcount --> %d\n",
+           static_cast<void*>(this), refcount_);
+
+    if ( newcount == 0 )
       {
+        printf("  delete IFoo@%p\n", static_cast<void*>(this));
+        printf("<<IFoo@%p::Release()\n", static_cast<void*>(this));
         delete this;
       }
 
     return newcount;
   }
 
 nsresult
 IFoo::QueryInterface( const nsIID& aIID, void** aResult )
   {
+    printf("IFoo@%p::QueryInterface()\n", static_cast<void*>(this));
     nsISupports* rawPtr = 0;
     nsresult status = NS_OK;
 
     if ( aIID.Equals(NS_GET_IID(IFoo)) )
       rawPtr = this;
     else
       {
         nsID iid_of_ISupports = NS_ISUPPORTS_IID;
@@ -241,195 +297,362 @@ IFoo::GetString(nsACString& aString)
   aString = mString;
   return NS_OK;
 }
 
 nsresult
 CreateIFoo( IFoo** result )
     // a typical factory function (that calls AddRef)
   {
+    printf("    >>CreateIFoo() --> ");
     IFoo* foop = new IFoo();
+    printf("IFoo@%p\n", static_cast<void*>(foop));
 
     foop->AddRef();
     *result = foop;
 
+    printf("<<CreateIFoo()\n");
     return NS_OK;
   }
 
 } // namespace TestHashtables
 
 using namespace TestHashtables;
 
-TEST(Hashtable, THashtable)
-{
+int
+main(void) {
   // check an nsTHashtable
+  printf("Initializing nsTHashtable...");
   nsTHashtable<EntityToUnicodeEntry> EntityToUnicode(ENTITY_COUNT);
+  printf("OK\n");
 
+  printf("Partially filling nsTHashtable:\n");
   testTHashtable(EntityToUnicode, 5);
 
+  printf("Enumerate-removing...\n");
   uint32_t count = nsTIterPrintRemove(EntityToUnicode);
-  ASSERT_EQ(count, uint32_t(5));
+  if (count != 5) {
+    printf("wrong count\n");
+    exit (7);
+  }
+  printf("OK\n");
 
+  printf("Check enumeration...");
   count = nsTIterPrint(EntityToUnicode);
-  ASSERT_EQ(count, uint32_t(0));
+  if (count != 0) {
+    printf("entries remain in table!\n");
+    exit (8);
+  }
+  printf("OK\n");
 
+  printf("Filling nsTHashtable:\n");
   testTHashtable(EntityToUnicode, ENTITY_COUNT);
 
+  printf("Clearing...");
   EntityToUnicode.Clear();
+  printf("OK\n");
 
+  printf("Check enumeration...");
   count = nsTIterPrint(EntityToUnicode);
-  ASSERT_EQ(count, uint32_t(0));
-}
+  if (count != 0) {
+    printf("entries remain in table!\n");
+    exit (9);
+  }
+  printf("OK\n");
 
-TEST(Hashtables, DataHashtable)
-{
-  // check a data-hashtable
+  //
+  // now check a data-hashtable
+  //
+
+  printf("Initializing nsDataHashtable...");
   nsDataHashtable<nsUint32HashKey,const char*> UniToEntity(ENTITY_COUNT);
+  printf("OK\n");
 
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
+  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
+
+  uint32_t i;
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Putting entry %u...", gEntities[i].mUnicode);
     UniToEntity.Put(gEntities[i].mUnicode, gEntities[i].mStr);
+    printf("OK...\n");
   }
 
+  printf("Testing Get:\n");
   const char* str;
 
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    ASSERT_TRUE(UniToEntity.Get(gEntities[i].mUnicode, &str));
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Getting entry %u...", gEntities[i].mUnicode);
+    if (!UniToEntity.Get(gEntities[i].mUnicode, &str)) {
+      printf("FAILED\n");
+      exit (12);
+    }
+
+    printf("Found %s\n", str);
+  }
+
+  printf("Testing nonexistent entries...");
+  if (UniToEntity.Get(99446, &str)) {
+    printf("FOUND! BAD!\n");
+    exit (13);
   }
 
-  ASSERT_FALSE(UniToEntity.Get(99446, &str));
+  printf("not found; good.\n");
+
+  printf("Enumerating:\n");
 
-  uint32_t count = 0;
+  count = 0;
   for (auto iter = UniToEntity.Iter(); !iter.Done(); iter.Next()) {
+    printf("  enumerated %u = \"%s\"\n", iter.Key(), iter.UserData());
     count++;
   }
-  ASSERT_EQ(count, ENTITY_COUNT);
+  if (count != ENTITY_COUNT) {
+    printf("  Bad count!\n");
+    exit (14);
+  }
 
+  printf("Clearing...");
   UniToEntity.Clear();
+  printf("OK\n");
 
+  printf("Checking count...");
   count = 0;
   for (auto iter = UniToEntity.Iter(); !iter.Done(); iter.Next()) {
     printf("  enumerated %u = \"%s\"\n", iter.Key(), iter.Data());
     count++;
   }
-  ASSERT_EQ(count, uint32_t(0));
-}
-
-TEST(Hashtables, ClassHashtable)
-{
-  // check a class-hashtable
-  nsClassHashtable<nsCStringHashKey,TestUniChar> EntToUniClass(ENTITY_COUNT);
-
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
-    EntToUniClass.Put(nsDependentCString(gEntities[i].mStr), temp);
+  if (count != 0) {
+    printf("  Clear did not remove all entries.\n");
+    exit (15);
   }
 
-  TestUniChar* myChar;
+  printf("OK\n");
+
+  //
+  // now check a class-hashtable
+  //
 
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    ASSERT_TRUE(EntToUniClass.Get(nsDependentCString(gEntities[i].mStr), &myChar));
+  printf("Initializing nsClassHashtable...");
+  nsClassHashtable<nsCStringHashKey,TestUniChar> EntToUniClass(ENTITY_COUNT);
+  printf("OK\n");
+
+  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
+
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Putting entry %u...", gEntities[i].mUnicode);
+    TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
+
+    EntToUniClass.Put(nsDependentCString(gEntities[i].mStr), temp);
+    printf("OK...\n");
   }
 
-  ASSERT_FALSE(EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar));
+  printf("Testing Get:\n");
+  TestUniChar* myChar;
+
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Getting entry %s...", gEntities[i].mStr);
+    if (!EntToUniClass.Get(nsDependentCString(gEntities[i].mStr), &myChar)) {
+      printf("FAILED\n");
+      exit (18);
+    }
 
-  uint32_t count = 0;
-  for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
-    count++;
+    printf("Found %c\n", myChar->GetChar());
   }
-  ASSERT_EQ(count, ENTITY_COUNT);
 
-  EntToUniClass.Clear();
+  printf("Testing nonexistent entries...");
+  if (EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar)) {
+    printf("FOUND! BAD!\n");
+    exit (19);
+  }
+
+  printf("not found; good.\n");
+
+  printf("Enumerating:\n");
 
   count = 0;
   for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
+    printf("  enumerated \"%s\" = %c\n",
+           PromiseFlatCString(iter.Key()).get(), iter.UserData()->GetChar());
     count++;
   }
-  ASSERT_EQ(count, uint32_t(0));
-}
+  if (count != ENTITY_COUNT) {
+    printf("  Bad count!\n");
+    exit (20);
+  }
+
+  printf("Clearing...\n");
+  EntToUniClass.Clear();
+  printf("  Clearing OK\n");
 
-TEST(Hashtables, DataHashtableWithInterfaceKey)
-{
-  // check a data-hashtable with an interface key
+  printf("Checking count...");
+  count = 0;
+  for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
+    printf("  enumerated \"%s\" = %c\n",
+           PromiseFlatCString(iter.Key()).get(), iter.Data()->GetChar());
+    count++;
+  }
+  if (count != 0) {
+    printf("  Clear did not remove all entries.\n");
+    exit (21);
+  }
+
+  printf("OK\n");
+
+  //
+  // now check a data-hashtable with an interface key
+  //
+
+  printf("Initializing nsDataHashtable with interface key...");
   nsDataHashtable<nsISupportsHashKey,uint32_t> EntToUniClass2(ENTITY_COUNT);
+  printf("OK\n");
+
+  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
 
   nsCOMArray<IFoo> fooArray;
 
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Putting entry %u...", gEntities[i].mUnicode);
     nsCOMPtr<IFoo> foo;
     CreateIFoo(getter_AddRefs(foo));
     foo->SetString(nsDependentCString(gEntities[i].mStr));
 
     fooArray.InsertObjectAt(foo, i);
 
     EntToUniClass2.Put(foo, gEntities[i].mUnicode);
-  }
-
-  uint32_t myChar2;
-
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    ASSERT_TRUE(EntToUniClass2.Get(fooArray[i], &myChar2));
+    printf("OK...\n");
   }
 
-  ASSERT_FALSE(EntToUniClass2.Get((nsISupports*) 0x55443316, &myChar2));
+  printf("Testing Get:\n");
+  uint32_t myChar2;
+
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Getting entry %s...", gEntities[i].mStr);
+
+    if (!EntToUniClass2.Get(fooArray[i], &myChar2)) {
+      printf("FAILED\n");
+      exit (24);
+    }
 
-  uint32_t count = 0;
-  for (auto iter = EntToUniClass2.Iter(); !iter.Done(); iter.Next()) {
-    nsAutoCString s;
-    nsCOMPtr<IFoo> foo = do_QueryInterface(iter.Key());
-    foo->GetString(s);
-    count++;
+    printf("Found %c\n", myChar2);
   }
-  ASSERT_EQ(count, ENTITY_COUNT);
 
-  EntToUniClass2.Clear();
+  printf("Testing nonexistent entries...");
+  if (EntToUniClass2.Get((nsISupports*) 0x55443316, &myChar2)) {
+    printf("FOUND! BAD!\n");
+    exit (25);
+  }
+
+  printf("not found; good.\n");
+
+  printf("Enumerating:\n");
 
   count = 0;
   for (auto iter = EntToUniClass2.Iter(); !iter.Done(); iter.Next()) {
     nsAutoCString s;
     nsCOMPtr<IFoo> foo = do_QueryInterface(iter.Key());
     foo->GetString(s);
+    printf("  enumerated \"%s\" = %u\n", s.get(), iter.UserData());
     count++;
   }
-  ASSERT_EQ(count, uint32_t(0));
-}
+  if (count != ENTITY_COUNT) {
+    printf("  Bad count!\n");
+    exit (26);
+  }
+
+  printf("Clearing...\n");
+  EntToUniClass2.Clear();
+  printf("  Clearing OK\n");
 
-TEST(Hashtables, InterfaceHashtable)
-{
-  // check an interface-hashtable with an uint32_t key
+  printf("Checking count...");
+  count = 0;
+  for (auto iter = EntToUniClass2.Iter(); !iter.Done(); iter.Next()) {
+    nsAutoCString s;
+    nsCOMPtr<IFoo> foo = do_QueryInterface(iter.Key());
+    foo->GetString(s);
+    printf("  enumerated \"%s\" = %u\n", s.get(), iter.Data());
+    count++;
+  }
+  if (count != 0) {
+    printf("  Clear did not remove all entries.\n");
+    exit (27);
+  }
+
+  printf("OK\n");
+
+  //
+  // now check an interface-hashtable with an uint32_t key
+  //
+
+  printf("Initializing nsInterfaceHashtable...");
   nsInterfaceHashtable<nsUint32HashKey,IFoo> UniToEntClass2(ENTITY_COUNT);
+  printf("OK\n");
 
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
+  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
+
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Putting entry %u...", gEntities[i].mUnicode);
     nsCOMPtr<IFoo> foo;
     CreateIFoo(getter_AddRefs(foo));
     foo->SetString(nsDependentCString(gEntities[i].mStr));
 
     UniToEntClass2.Put(gEntities[i].mUnicode, foo);
+    printf("OK...\n");
   }
 
-  for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
+  printf("Testing Get:\n");
+
+  for (i = 0; i < ENTITY_COUNT; ++i) {
+    printf("  Getting entry %s...", gEntities[i].mStr);
+
     nsCOMPtr<IFoo> myEnt;
-    ASSERT_TRUE(UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt)));
+    if (!UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
+      printf("FAILED\n");
+      exit (30);
+    }
 
     nsAutoCString myEntStr;
     myEnt->GetString(myEntStr);
+    printf("Found %s\n", myEntStr.get());
   }
 
+  printf("Testing nonexistent entries...");
   nsCOMPtr<IFoo> myEnt;
-  ASSERT_FALSE(UniToEntClass2.Get(9462, getter_AddRefs(myEnt)));
+  if (UniToEntClass2.Get(9462, getter_AddRefs(myEnt))) {
+    printf("FOUND! BAD!\n");
+    exit (31);
+  }
 
-  uint32_t count = 0;
-  for (auto iter = UniToEntClass2.Iter(); !iter.Done(); iter.Next()) {
-    nsAutoCString s;
-    iter.UserData()->GetString(s);
-    count++;
-  }
-  ASSERT_EQ(count, ENTITY_COUNT);
+  printf("not found; good.\n");
 
-  UniToEntClass2.Clear();
+  printf("Enumerating:\n");
 
   count = 0;
   for (auto iter = UniToEntClass2.Iter(); !iter.Done(); iter.Next()) {
     nsAutoCString s;
-    iter.Data()->GetString(s);
+    iter.UserData()->GetString(s);
+    printf("  enumerated %u = \"%s\"\n", iter.Key(), s.get());
     count++;
   }
-  ASSERT_EQ(count, uint32_t(0));
+  if (count != ENTITY_COUNT) {
+    printf("  Bad count!\n");
+    exit (32);
+  }
+
+  printf("Clearing...\n");
+  UniToEntClass2.Clear();
+  printf("  Clearing OK\n");
+
+  printf("Checking count...");
+  count = 0;
+  for (auto iter = UniToEntClass2.Iter(); !iter.Done(); iter.Next()) {
+    nsAutoCString s;
+    iter.Data()->GetString(s);
+    printf("  enumerated %u = \"%s\"\n", iter.Key(), s.get());
+    count++;
+  }
+  if (count != 0) {
+    printf("  Clear did not remove all entries.\n");
+    exit (33);
+  }
+
+  printf("OK\n");
+
+  return 0;
 }
rename from xpcom/tests/gtest/TestID.cpp
rename to xpcom/tests/TestID.cpp
--- a/xpcom/tests/gtest/TestID.cpp
+++ b/xpcom/tests/TestID.cpp
@@ -1,36 +1,43 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+#include <stdio.h>
+#include "plstr.h"
 #include "nsID.h"
 
-#include "gtest/gtest.h"
-
 static const char* const ids[] = {
   "5C347B10-D55C-11D1-89B7-006008911B81",
   "{5C347B10-D55C-11D1-89B7-006008911B81}",
   "5c347b10-d55c-11d1-89b7-006008911b81",
   "{5c347b10-d55c-11d1-89b7-006008911b81}",
 
   "FC347B10-D55C-F1D1-F9B7-006008911B81",
   "{FC347B10-D55C-F1D1-F9B7-006008911B81}",
   "fc347b10-d55c-f1d1-f9b7-006008911b81",
   "{fc347b10-d55c-f1d1-f9b7-006008911b81}",
 };
 #define NUM_IDS ((int) (sizeof(ids) / sizeof(ids[0])))
 
-TEST(nsID, StringConversion)
+int main(int argc, char** argv)
 {
   nsID id;
   for (int i = 0; i < NUM_IDS; i++) {
     const char* idstr = ids[i];
-    ASSERT_TRUE(id.Parse(idstr));
-
+    if (!id.Parse(idstr)) {
+      fprintf(stderr, "TestID: Parse failed on test #%d\n", i);
+      return -1;
+    }
     char* cp = id.ToString();
-    ASSERT_NE(cp, nullptr);
-    ASSERT_STREQ(cp, ids[4*(i/4) + 3]);
+    if (nullptr == cp) {
+      fprintf(stderr, "TestID: ToString failed on test #%d\n", i);
+      return -1;
+    }
+    if (0 != PL_strcmp(cp, ids[4*(i/4) + 3])) {
+      fprintf(stderr, "TestID: compare of ToString failed on test #%d\n", i);
+      return -1;
+    }
+  }
 
-    free(cp);
-  }
+  return 0;
 }
--- a/xpcom/tests/gtest/TestStorageStream.cpp
+++ b/xpcom/tests/gtest/TestStorageStream.cpp
@@ -7,17 +7,16 @@
 #include <stdlib.h>
 #include "gtest/gtest.h"
 #include "Helpers.h"
 #include "nsCOMPtr.h"
 #include "nsICloneableInputStream.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsIStorageStream.h"
-#include "nsTArray.h"
 
 namespace {
 
 void
 WriteData(nsIOutputStream* aOut, nsTArray<char>& aData, uint32_t aNumBytes,
           nsACString& aDataWritten)
 {
   uint32_t n;
--- a/xpcom/tests/gtest/TestStringStream.cpp
+++ b/xpcom/tests/gtest/TestStringStream.cpp
@@ -3,19 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gtest/gtest.h"
 #include "Helpers.h"
 #include "nsICloneableInputStream.h"
 #include "nsStringStream.h"
-#include "nsTArray.h"
-#include "nsIInputStream.h"
-#include "nsCOMPtr.h"
 
 namespace {
 
 static void TestStringStream(uint32_t aNumBytes)
 {
   nsTArray<char> inputData;
   testing::CreateData(aNumBytes, inputData);
   nsDependentCSubstring inputString(inputData.Elements(), inputData.Length());
--- a/xpcom/tests/gtest/moz.build
+++ b/xpcom/tests/gtest/moz.build
@@ -2,27 +2,21 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 UNIFIED_SOURCES += [
     'Helpers.cpp',
     'TestAtoms.cpp',
-    'TestAutoPtr.cpp',
-    'TestAutoRef.cpp',
     'TestCloneInputStream.cpp',
-    'TestCOMArray.cpp',
-    'TestCOMPtrEq.cpp',
     'TestCRT.cpp',
     'TestEncoding.cpp',
     'TestEscapeURL.cpp',
     'TestExpirationTracker.cpp',
-    'TestFile.cpp',
-    'TestID.cpp',
     'TestNSPRLogModulesParser.cpp',
     'TestPipes.cpp',
     'TestPLDHash.cpp',
     'TestPriorityQueue.cpp',
     'TestSlicedInputStream.cpp',
     'TestSnappyStreams.cpp',
     'TestStateWatching.cpp',
     'TestStorageStream.cpp',
@@ -37,17 +31,15 @@ UNIFIED_SOURCES += [
     'TestUTF.cpp',
     'TestXPIDLString.cpp',
 ]
 
 # Compile TestAllocReplacement separately so Windows headers don't pollute
 # the global namespace for other files.
 SOURCES += [
     'TestAllocReplacement.cpp',
-    'TestCOMPtr.cpp', # Redefines IFoo and IBar
-    'TestHashtables.cpp', # Redefines IFoo
 ]
 
 LOCAL_INCLUDES += [
     '../../base',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
--- a/xpcom/tests/moz.build
+++ b/xpcom/tests/moz.build
@@ -41,16 +41,25 @@ if CONFIG['OS_TARGET'] == 'WINNT':
 if CONFIG['WRAP_STL_INCLUDES'] and not CONFIG['CLANG_CL']:
     GeckoSimplePrograms([
         'TestSTLWrappers',
     ])
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
 
 GeckoCppUnitTests([
+    'ShowAlignments',
+    'TestAutoPtr',
+    'TestAutoRef',
+    'TestCOMArray',
+    'TestCOMPtr',
+    'TestCOMPtrEq',
+    'TestFile',
+    'TestHashtables',
+    'TestID',
     'TestNsRefPtr',
     'TestObserverArray',
     'TestObserverService',
     'TestStringAPI',
     'TestTArray',
     'TestTextFormatter',
     'TestThreadUtils',
     'TestTimers'
--- a/xpcom/threads/StateWatching.h
+++ b/xpcom/threads/StateWatching.h
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #if !defined(StateWatching_h_)
 #define StateWatching_h_
 
 #include "mozilla/AbstractThread.h"
-#include "mozilla/Logging.h"
 #include "mozilla/TaskDispatcher.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 
 #include "nsISupportsImpl.h"
 
 /*
  * The state-watching machinery automates the process of responding to changes
--- a/xpcom/threads/TaskDispatcher.h
+++ b/xpcom/threads/TaskDispatcher.h
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #if !defined(TaskDispatcher_h_)
 #define TaskDispatcher_h_
 
 #include "mozilla/AbstractThread.h"
-#include "mozilla/Maybe.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 
 #include <queue>