Bug 475141 - Create a C++ wrapper for the private browsing service for Firefox 3.1; r+sr=mconnor
☠☠ backed out by 0127329dbe21 ☠ ☠
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Thu, 19 Feb 2009 09:22:08 +0330
changeset 25171 dcb3aa2fd0ab7b1e0a3ce7d89c20509c98631014
parent 25170 1b6278ecd0d77fd2952bbc66a728e835d8300f87
child 25172 9059416d26cf9e80f206027b612f70ab3664ea31
child 25200 0127329dbe2148700371f96d20325c31d6cbe62a
push id5439
push userehsan.akhgari@gmail.com
push dateThu, 19 Feb 2009 06:14:37 +0000
treeherdermozilla-central@59e2945cce3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs475141
milestone1.9.2a1pre
Bug 475141 - Create a C++ wrapper for the private browsing service for Firefox 3.1; r+sr=mconnor
browser/components/build/Makefile.in
browser/components/build/nsBrowserCompsCID.h
browser/components/build/nsModule.cpp
browser/components/privatebrowsing/src/Makefile.in
browser/components/privatebrowsing/src/nsPrivateBrowsingServiceWrapper.cpp
browser/components/privatebrowsing/src/nsPrivateBrowsingServiceWrapper.h
browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_autostart.js
browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_exit.js
browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain.js
browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain_activeDownloads.js
browser/components/privatebrowsing/test/unit/head_privatebrowsing.js
browser/components/privatebrowsing/test/unit/test_0-privatebrowsing.js
browser/components/privatebrowsing/test/unit/test_aboutprivatebrowsing.js
browser/components/privatebrowsing/test/unit/test_httpauth.js
browser/components/privatebrowsing/test/unit/test_privatebrowsing_autostart.js
browser/components/privatebrowsing/test/unit/test_privatebrowsing_exit.js
browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_autostart.js
browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_exit.js
browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_removeDataFromDomain.js
browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_removeDataFromDomain_activeDownloads.js
browser/components/privatebrowsing/test/unit/test_removeDataFromDomain.js
browser/components/privatebrowsing/test/unit/test_removeDataFromDomain_activeDownloads.js
netwerk/build/nsNetCID.h
toolkit/components/satchel/src/Makefile.in
toolkit/components/satchel/src/nsStorageFormHistory.cpp
--- a/browser/components/build/Makefile.in
+++ b/browser/components/build/Makefile.in
@@ -25,16 +25,17 @@ REQUIRES = \
 	uriloader \
 	intl \
 	necko \
 	shellservice \
 	xulapp \
 	places \
 	browserplaces \
 	microsummaries \
+	privatebrowsing \
 	$(NULL)
 
 EXPORTS = nsBrowserCompsCID.h
 
 CPPSRCS = nsModule.cpp \
           $(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
@@ -42,25 +43,27 @@ DEFINES += -DPSTOREC_DLL=\"$(subst \,\\,
 
 OS_LIBS	+= $(call EXPAND_LIBNAME,ole32 shell32)
 endif
 
 LOCAL_INCLUDES = \
 	-I$(srcdir)/../shell/src \
 	-I$(srcdir)/../feeds/src \
 	-I$(srcdir)/../places/src \
+	-I$(srcdir)/../privatebrowsing/src \
 	$(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS += $(call EXPAND_LIBNAME,version)
 endif
 
 SHARED_LIBRARY_LIBS = \
 	../feeds/src/$(LIB_PREFIX)browser_feeds_s.$(LIB_SUFFIX) \
 	../places/src/$(LIB_PREFIX)browserplaces_s.$(LIB_SUFFIX) \
+	../privatebrowsing/src/$(LIB_PREFIX)privatebrowsing_s.$(LIB_SUFFIX) \
 	$(NULL)
 
 ifneq (,$(filter windows mac cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
 SHARED_LIBRARY_LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX)
 endif
 
 EXTRA_DSO_LDOPTS += \
 	$(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib) \
--- a/browser/components/build/nsBrowserCompsCID.h
+++ b/browser/components/build/nsBrowserCompsCID.h
@@ -92,8 +92,12 @@
 { 0x12ff56ec, 0x58be, 0x402c, { 0xb0, 0x57, 0x1, 0xf9, 0x61, 0xde, 0x96, 0x9b } }
 
 // 6fb0c970-e1b1-11db-8314-0800200c9a66
 #define NS_PLACESIMPORTEXPORTSERVICE_CID \
 { 0x6fb0c970, 0xe1b1, 0x11db, { 0x83, 0x14, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
 
 #define NS_PLACESIMPORTEXPORTSERVICE_CONTRACTID \
   "@mozilla.org/browser/places/import-export-service;1"
+
+// 136e2c4d-c5a4-477c-b131-d93d7d704f64
+#define NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID \
+{ 0x136e2c4d, 0xc5a4, 0x477c, { 0xb1, 0x31, 0xd9, 0x3d, 0x7d, 0x70, 0x4f, 0x64 } }
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -72,16 +72,19 @@
 
 #endif // WINCE
 
 #include "rdf.h"
 #include "nsFeedSniffer.h"
 #include "nsAboutFeeds.h"
 #include "nsIAboutModule.h"
 
+#include "nsPrivateBrowsingServiceWrapper.h"
+#include "nsNetCID.h"
+
 /////////////////////////////////////////////////////////////////////////////
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPlacesImportExportService)
 #if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsShellService)
 #elif defined(XP_MACOSX)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
 #elif defined(MOZ_WIDGET_GTK2)
@@ -108,16 +111,18 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacIEPr
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCaminoProfileMigrator)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsICabProfileMigrator)
 #endif
 
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
 
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrivateBrowsingServiceWrapper, Init)
+
 /////////////////////////////////////////////////////////////////////////////
 
 static const nsModuleComponentInfo components[] =
 {
 #if defined(XP_WIN)
   { "Browser Shell Service",
     NS_SHELLSERVICE_CID,
     NS_SHELLSERVICE_CONTRACTID,
@@ -212,15 +217,20 @@ static const nsModuleComponentInfo compo
   { "Phoenix Profile Migrator",
     NS_PHOENIXPROFILEMIGRATOR_CID,
     NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "phoenix",
     nsPhoenixProfileMigratorConstructor },
 
   { "Seamonkey Profile Migrator",
     NS_SEAMONKEYPROFILEMIGRATOR_CID,
     NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "seamonkey",
-    nsSeamonkeyProfileMigratorConstructor }
+    nsSeamonkeyProfileMigratorConstructor },
 
 #endif /* WINCE */
+
+  { "PrivateBrowsing Service C++ Wrapper",
+    NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID,
+    NS_PRIVATE_BROWSING_SERVICE_CONTRACTID,
+    nsPrivateBrowsingServiceWrapperConstructor }
 };
 
 NS_IMPL_NSGETMODULE(nsBrowserCompsModule, components)
 
--- a/browser/components/privatebrowsing/src/Makefile.in
+++ b/browser/components/privatebrowsing/src/Makefile.in
@@ -37,14 +37,36 @@
 
 DEPTH   = ../../../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
+MODULE = privatebrowsing
+LIBRARY_NAME = privatebrowsing_s
+FORCE_STATIC_LIB = 1
+FORCE_USE_PIC = 1
+ifndef MOZ_MEMORY
+USE_STATIC_LIBS = 1
+endif
+
+REQUIRES = \
+	xpcom \
+	string \
+	necko \
+	js \
+	xpconnect \
+	$(NULL)
+
+CPPSRCS = \
+	nsPrivateBrowsingServiceWrapper.cpp \
+	$(NULL)
+
+LOCAL_INCLUDES = -I$(srcdir)/../../build
+
 EXTRA_PP_COMPONENTS = \
 	nsPrivateBrowsingService.js \
 	aboutPrivateBrowsing.js \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingServiceWrapper.cpp
@@ -0,0 +1,135 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsPrivateBrowsingServiceWrapper.h"
+#include "nsServiceManagerUtils.h"
+#include "jsapi.h"
+#include "nsIJSContextStack.h"
+
+NS_IMPL_ISUPPORTS2(nsPrivateBrowsingServiceWrapper, nsIPrivateBrowsingService, nsIObserver)
+
+nsresult
+nsPrivateBrowsingServiceWrapper::Init()
+{
+  nsresult rv;
+  mPBService = do_GetService("@mozilla.org/privatebrowsing;1", &rv);
+  return rv;
+}
+
+nsresult
+nsPrivateBrowsingServiceWrapper::PrepareCall(nsIJSContextStack ** aJSStack)
+{
+  nsresult rv = CallGetService("@mozilla.org/js/xpc/ContextStack;1", aJSStack);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (*aJSStack) {
+    rv = (*aJSStack)->Push(nsnull);
+    if (NS_FAILED(rv))
+      *aJSStack = nsnull;
+  }
+  return rv;
+}
+
+void
+nsPrivateBrowsingServiceWrapper::FinishCall(nsIJSContextStack * aJSStack)
+{
+  if (aJSStack) {
+    JSContext *cx;
+    aJSStack->Pop(&cx);
+    NS_ASSERTION(cx == nsnull, "JSContextStack mismatch");
+  }
+}
+
+NS_IMETHODIMP
+nsPrivateBrowsingServiceWrapper::GetPrivateBrowsingEnabled(PRBool *aPrivateBrowsingEnabled)
+{
+  if (!aPrivateBrowsingEnabled)
+    return NS_ERROR_NULL_POINTER;
+  nsCOMPtr<nsIJSContextStack> jsStack;
+  nsresult rv = PrepareCall(getter_AddRefs(jsStack));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = mPBService->GetPrivateBrowsingEnabled(aPrivateBrowsingEnabled);
+  FinishCall(jsStack);
+  return rv;
+}
+
+NS_IMETHODIMP
+nsPrivateBrowsingServiceWrapper::SetPrivateBrowsingEnabled(PRBool aPrivateBrowsingEnabled)
+{
+  nsCOMPtr<nsIJSContextStack> jsStack;
+  nsresult rv = PrepareCall(getter_AddRefs(jsStack));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = mPBService->SetPrivateBrowsingEnabled(aPrivateBrowsingEnabled);
+  FinishCall(jsStack);
+  return rv;
+}
+
+NS_IMETHODIMP
+nsPrivateBrowsingServiceWrapper::GetAutoStarted(PRBool *aAutoStarted)
+{
+  if (!aAutoStarted)
+    return NS_ERROR_NULL_POINTER;
+  nsCOMPtr<nsIJSContextStack> jsStack;
+  nsresult rv = PrepareCall(getter_AddRefs(jsStack));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = mPBService->GetAutoStarted(aAutoStarted);
+  FinishCall(jsStack);
+  return rv;
+}
+
+NS_IMETHODIMP
+nsPrivateBrowsingServiceWrapper::RemoveDataFromDomain(const nsACString & aDomain)
+{
+  nsCOMPtr<nsIJSContextStack> jsStack;
+  nsresult rv = PrepareCall(getter_AddRefs(jsStack));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = mPBService->RemoveDataFromDomain(aDomain);
+  FinishCall(jsStack);
+  return rv;
+}
+
+NS_IMETHODIMP
+nsPrivateBrowsingServiceWrapper::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
+{
+  nsCOMPtr<nsIJSContextStack> jsStack;
+  nsresult rv = PrepareCall(getter_AddRefs(jsStack));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIObserver> observer(do_QueryInterface(mPBService));
+  NS_ENSURE_TRUE(observer, NS_ERROR_FAILURE);
+  rv = observer->Observe(aSubject, aTopic, aData);
+  FinishCall(jsStack);
+  return rv;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingServiceWrapper.h
@@ -0,0 +1,58 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsCOMPtr.h"
+#include "nsIPrivateBrowsingService.h"
+#include "nsIObserver.h"
+
+class nsIJSContextStack;
+
+class nsPrivateBrowsingServiceWrapper : public nsIPrivateBrowsingService,
+                                        public nsIObserver
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIPRIVATEBROWSINGSERVICE
+  NS_DECL_NSIOBSERVER
+
+  nsresult Init();
+
+private:
+  nsresult PrepareCall(nsIJSContextStack ** aJSStack);
+  void FinishCall(nsIJSContextStack * aJSStack);
+
+  nsCOMPtr<nsIPrivateBrowsingService> mPBService;
+};
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_autostart.js
@@ -0,0 +1,68 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test checks the browser.privatebrowsing.autostart preference.
+
+function do_test() {
+  // initialization
+  var prefsService = Cc["@mozilla.org/preferences-service;1"].
+                     getService(Ci.nsIPrefBranch);
+  prefsService.setBoolPref("browser.privatebrowsing.autostart", true);
+  do_check_true(prefsService.getBoolPref("browser.privatebrowsing.autostart"));
+
+  var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
+           getService(Ci.nsIPrivateBrowsingService).
+           QueryInterface(Ci.nsIObserver);
+
+  // private browsing not auto-started yet
+  do_check_false(pb.autoStarted);
+
+  // simulate startup to make the PB service read the prefs
+  pb.observe(null, "profile-after-change", "");
+
+  // the private mode should be entered automatically
+  do_check_true(pb.privateBrowsingEnabled);
+
+  // private browsing is auto-started
+  do_check_true(pb.autoStarted);
+
+  // leave private browsing mode
+  pb.privateBrowsingEnabled = false;
+
+  // private browsing not auto-started
+  do_check_false(pb.autoStarted);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_exit.js
@@ -0,0 +1,97 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the private browsing mode is left at application
+// shutdown.
+
+function do_test() {
+  // initialization
+  var os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
+           getService(Ci.nsIPrivateBrowsingService);
+  var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+                   getService(Ci.nsIPrefBranch);
+  prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+
+  var expectedQuitting;
+  var called = 0;
+  var observer = {
+    observe: function(aSubject, aTopic, aData) {
+      if (aTopic == kPrivateBrowsingNotification &&
+          aData == kExit) {
+        // increment the call counter
+        ++ called;
+
+        do_check_neq(aSubject, null);
+        try {
+          aSubject.QueryInterface(Ci.nsISupportsPRBool);
+        } catch (ex) {
+          do_throw("aSubject was not null, but wasn't an nsISupportsPRBool");
+        }
+        // check the "quitting" argument
+        do_check_eq(aSubject.data, expectedQuitting);
+
+        // finish up the test
+        if (expectedQuitting) {
+          os.removeObserver(this, kPrivateBrowsingNotification);
+          prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
+          do_test_finished();
+        }
+      }
+    }
+  };
+
+  // set the observer
+  os.addObserver(observer, kPrivateBrowsingNotification, false);
+
+  // enter the private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  // exit the private browsing mode
+  expectedQuitting = false;
+  pb.privateBrowsingEnabled = false;
+  do_check_eq(called, 1);
+
+  // enter the private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  // Simulate an exit
+  expectedQuitting = true;
+  do_test_pending();
+  os.notifyObservers(null, "quit-application-granted", null);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain.js
@@ -0,0 +1,618 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Test added with bug 460086 to test the behavior of the new API that was added
+ * to remove all traces of visiting a site.
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
+         getService(Ci.nsIPrivateBrowsingService);
+
+const COOKIE_EXPIRY = Math.round(Date.now() / 1000) + 60;
+const COOKIE_NAME = "testcookie";
+const COOKIE_PATH = "/";
+
+const LOGIN_USERNAME = "username";
+const LOGIN_PASSWORD = "password";
+const LOGIN_USERNAME_FIELD = "username_field";
+const LOGIN_PASSWORD_FIELD = "password_field";
+
+const PERMISSION_TYPE = "test-perm";
+const PERMISSION_VALUE = Ci.nsIPermissionManager.ALLOW_ACTION;
+
+const PREFERENCE_NAME = "test-pref";
+
+////////////////////////////////////////////////////////////////////////////////
+//// Utility Functions
+
+/**
+ * Creates an nsIURI object for the given string representation of a URI.
+ *
+ * @param aURIString
+ *        The spec of the URI to create.
+ * @returns an nsIURI representing aURIString.
+ */
+function uri(aURIString)
+{
+  return Cc["@mozilla.org/network/io-service;1"].
+         getService(Ci.nsIIOService).
+         newURI(aURIString, null, null);
+}
+
+/**
+ * Adds a visit to history.
+ *
+ * @param aURI
+ *        The URI to add.
+ */
+function add_visit(aURI)
+{
+  check_visited(aURI, false);
+  let bh = Cc["@mozilla.org/browser/global-history;2"].
+           getService(Ci.nsIBrowserHistory);
+  bh.addPageWithDetails(aURI, aURI.spec, Date.now() * 1000);
+  check_visited(aURI, true);
+}
+
+/**
+ * Checks to ensure a URI string is visited or not.
+ *
+ * @param aURI
+ *        The URI to check.
+ * @param aIsVisited
+ *        True if the URI should be visited, false otherwise.
+ */
+function check_visited(aURI, aIsVisited)
+{
+  let gh = Cc["@mozilla.org/browser/global-history;2"].
+           getService(Ci.nsIGlobalHistory2);
+  let checker = aIsVisited ? do_check_true : do_check_false;
+  checker(gh.isVisited(aURI));
+}
+
+/**
+ * Add a cookie to the cookie service.
+ *
+ * @param aDomain
+ */
+function add_cookie(aDomain)
+{
+  check_cookie_exists(aDomain, false);
+  let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
+  cm.add(aDomain, COOKIE_PATH, COOKIE_NAME, "", false, false, false,
+         COOKIE_EXPIRY);
+  check_cookie_exists(aDomain, true);
+}
+
+/**
+ * Checks to ensure that a cookie exists or not for a domain.
+ *
+ * @param aDomain
+ *        The domain to check for the cookie.
+ * @param aExists
+ *        True if the cookie should exist, false otherwise.
+ */
+function check_cookie_exists(aDomain, aExists)
+{
+  let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
+  let cookie = {
+    host: aDomain,
+    name: COOKIE_NAME,
+    path: COOKIE_PATH
+  }
+  let checker = aExists ? do_check_true : do_check_false;
+  checker(cm.cookieExists(cookie));
+}
+
+/**
+ * Adds a download to download history.
+ *
+ * @param aURIString
+ *        The string of the URI to add.
+ * @param aIsActive
+ *        If it should be set to an active state in the database.  This does not
+ *        make it show up in the list of active downloads however!
+ */
+function add_download(aURIString, aIsActive)
+{
+  check_downloaded(aURIString, false);
+  let db = Cc["@mozilla.org/download-manager;1"].
+           getService(Ci.nsIDownloadManager).
+           DBConnection;
+  let stmt = db.createStatement(
+    "INSERT INTO moz_downloads (source, state) " +
+    "VALUES (:source, :state)"
+  );
+  stmt.params.source = aURIString;
+  stmt.params.state = aIsActive ? Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING :
+                                  Ci.nsIDownloadManager.DOWNLOAD_FINISHED;
+  try {
+    stmt.execute();
+  }
+  finally {
+    stmt.finalize();
+  }
+  check_downloaded(aURIString, true);
+}
+
+/**
+ * Checks to ensure a URI string is in download history or not.
+ *
+ * @param aURIString
+ *        The string of the URI to check.
+ * @param aIsDownloaded
+ *        True if the URI should be downloaded, false otherwise.
+ */
+function check_downloaded(aURIString, aIsDownloaded)
+{
+  let db = Cc["@mozilla.org/download-manager;1"].
+           getService(Ci.nsIDownloadManager).
+           DBConnection;
+  let stmt = db.createStatement(
+    "SELECT * " +
+    "FROM moz_downloads " +
+    "WHERE source = :source"
+  );
+  stmt.params.source = aURIString;
+
+  let checker = aIsDownloaded ? do_check_true : do_check_false;
+  try {
+    checker(stmt.step());
+  }
+  finally {
+    stmt.finalize();
+  }
+}
+
+/**
+ * Adds a disabled host to the login manager.
+ *
+ * @param aHost
+ *        The host to add to the list of disabled hosts.
+ */
+function add_disabled_host(aHost)
+{
+  check_disabled_host(aHost, false);
+  let lm = Cc["@mozilla.org/login-manager;1"].
+           getService(Ci.nsILoginManager);
+  lm.setLoginSavingEnabled(aHost, false);
+  check_disabled_host(aHost, true);
+}
+
+/**
+ * Checks to see if a host is disabled for storing logins or not.
+ *
+ * @param aHost
+ *        The host to check if it is disabled.
+ * @param aIsDisabled
+ *        True if the host should be disabled, false otherwise.
+ */
+function check_disabled_host(aHost, aIsDisabled)
+{
+  let lm = Cc["@mozilla.org/login-manager;1"].
+           getService(Ci.nsILoginManager);
+  let checker = aIsDisabled ? do_check_false : do_check_true;
+  checker(lm.getLoginSavingEnabled(aHost));
+}
+
+/**
+ * Adds a login for the specified host to the login manager.
+ *
+ * @param aHost
+ *        The host to add the login for.
+ */
+function add_login(aHost)
+{
+  check_login_exists(aHost, false);
+  let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
+              createInstance(Ci.nsILoginInfo);
+  login.init(aHost, "", null, LOGIN_USERNAME, LOGIN_PASSWORD,
+             LOGIN_USERNAME_FIELD, LOGIN_PASSWORD_FIELD);
+  let lm = Cc["@mozilla.org/login-manager;1"].
+           getService(Ci.nsILoginManager);
+  lm.addLogin(login);
+  check_login_exists(aHost, true);
+}
+
+/**
+ * Checks to see if a login exists for a host.
+ *
+ * @param aHost
+ *        The host to check for the test login.
+ * @param aExists
+ *        True if the login should exist, false otherwise.
+ */
+function check_login_exists(aHost, aExists)
+{
+  let lm = Cc["@mozilla.org/login-manager;1"].
+           getService(Ci.nsILoginManager);
+  let count = { value: 0 };
+  lm.findLogins(count, aHost, "", null);
+  do_check_eq(count.value, aExists ? 1 : 0);
+}
+
+/**
+ * Adds a permission for the specified URI to the permission manager.
+ *
+ * @param aURI
+ *        The URI to add the test permission for.
+ */
+function add_permission(aURI)
+{
+  check_permission_exists(aURI, false);
+  let pm = Cc["@mozilla.org/permissionmanager;1"].
+           getService(Ci.nsIPermissionManager);
+  pm.add(aURI, PERMISSION_TYPE, PERMISSION_VALUE);
+  check_permission_exists(aURI, true);
+}
+
+/**
+ * Checks to see if a permission exists for the given URI.
+ *
+ * @param aURI
+ *        The URI to check if a permission exists.
+ * @param aExists
+ *        True if the permission should exist, false otherwise.
+ */
+function check_permission_exists(aURI, aExists)
+{
+  let pm = Cc["@mozilla.org/permissionmanager;1"].
+           getService(Ci.nsIPermissionManager);
+  let perm = pm.testExactPermission(aURI, PERMISSION_TYPE);
+  let checker = aExists ? do_check_eq : do_check_neq;
+  checker(perm, PERMISSION_VALUE);
+}
+
+/**
+ * Adds a content preference for the specified URI.
+ *
+ * @param aURI
+ *        The URI to add a preference for.
+ */
+function add_preference(aURI)
+{
+  check_preference_exists(aURI, false);
+  let cp = Cc["@mozilla.org/content-pref/service;1"].
+           getService(Ci.nsIContentPrefService);
+  cp.setPref(aURI, PREFERENCE_NAME, "foo");
+  check_preference_exists(aURI, true);
+}
+
+/**
+ * Checks to see if a preference exists for the given URI.
+ *
+ * @param aURI
+ *        The URI to check if a preference exists.
+ * @param aExists
+ *        True if the permission should exist, false otherwise.
+ */
+function check_preference_exists(aURI, aExists)
+{
+  let cp = Cc["@mozilla.org/content-pref/service;1"].
+           getService(Ci.nsIContentPrefService);
+  let checker = aExists ? do_check_true : do_check_false;
+  checker(cp.hasPref(aURI, PREFERENCE_NAME));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// Test Functions
+
+// History
+function test_history_cleared_with_direct_match()
+{
+  const TEST_URI = uri("http://mozilla.org/foo");
+  add_visit(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_visited(TEST_URI, false);
+}
+
+function test_history_cleared_with_subdomain()
+{
+  const TEST_URI = uri("http://www.mozilla.org/foo");
+  add_visit(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_visited(TEST_URI, false);
+}
+
+function test_history_not_cleared_with_uri_contains_domain()
+{
+  const TEST_URI = uri("http://ilovemozilla.org/foo");
+  add_visit(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_visited(TEST_URI, true);
+
+  // Clear history since we left something there from this test.
+  let bh = Cc["@mozilla.org/browser/global-history;2"].
+           getService(Ci.nsIBrowserHistory);
+  bh.removeAllPages();
+}
+
+// Cookie Service
+function test_cookie_cleared_with_direct_match()
+{
+  const TEST_DOMAIN = "mozilla.org";
+  add_cookie(TEST_DOMAIN);
+  pb.removeDataFromDomain("mozilla.org");
+  check_cookie_exists(TEST_DOMAIN, false);
+}
+
+function test_cookie_cleared_with_subdomain()
+{
+  const TEST_DOMAIN = "www.mozilla.org";
+  add_cookie(TEST_DOMAIN);
+  pb.removeDataFromDomain("mozilla.org");
+  check_cookie_exists(TEST_DOMAIN, false);
+}
+
+function test_cookie_not_cleared_with_uri_contains_domain()
+{
+  const TEST_DOMAIN = "ilovemozilla.org";
+  add_cookie(TEST_DOMAIN);
+  pb.removeDataFromDomain("mozilla.org");
+  check_cookie_exists(TEST_DOMAIN, true);
+}
+
+// Download Manager
+function test_download_history_cleared_with_direct_match()
+{
+  const TEST_URI = "http://mozilla.org/foo";
+  add_download(TEST_URI, false);
+  pb.removeDataFromDomain("mozilla.org");
+  check_downloaded(TEST_URI, false);
+}
+
+function test_download_history_cleared_with_subdomain()
+{
+  const TEST_URI = "http://www.mozilla.org/foo";
+  add_download(TEST_URI, false);
+  pb.removeDataFromDomain("mozilla.org");
+  check_downloaded(TEST_URI, false);
+}
+
+function test_download_history_not_cleared_with_active_direct_match()
+{
+  // Tests that downloads marked as active in the db are not deleted from the db
+  const TEST_URI = "http://mozilla.org/foo";
+  add_download(TEST_URI, true);
+  pb.removeDataFromDomain("mozilla.org");
+  check_downloaded(TEST_URI, true);
+
+  // Reset state
+  let db = Cc["@mozilla.org/download-manager;1"].
+           getService(Ci.nsIDownloadManager).
+           DBConnection;
+  db.executeSimpleSQL("DELETE FROM moz_downloads");
+  check_downloaded(TEST_URI, false);
+}
+
+// Login Manager
+function test_login_manager_disabled_hosts_cleared_with_direct_match()
+{
+  const TEST_HOST = "http://mozilla.org";
+  add_disabled_host(TEST_HOST);
+  pb.removeDataFromDomain("mozilla.org");
+  check_disabled_host(TEST_HOST, false);
+}
+
+function test_login_manager_disabled_hosts_cleared_with_subdomain()
+{
+  const TEST_HOST = "http://www.mozilla.org";
+  add_disabled_host(TEST_HOST);
+  pb.removeDataFromDomain("mozilla.org");
+  check_disabled_host(TEST_HOST, false);
+}
+
+function test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain()
+{
+  const TEST_HOST = "http://ilovemozilla.org";
+  add_disabled_host(TEST_HOST);
+  pb.removeDataFromDomain("mozilla.org");
+  check_disabled_host(TEST_HOST, true);
+
+  // Reset state
+  let lm = Cc["@mozilla.org/login-manager;1"].
+           getService(Ci.nsILoginManager);
+  lm.setLoginSavingEnabled(TEST_HOST, true);
+  check_disabled_host(TEST_HOST, false);
+}
+
+function test_login_manager_logins_cleared_with_direct_match()
+{
+  const TEST_HOST = "http://mozilla.org";
+  add_login(TEST_HOST);
+  pb.removeDataFromDomain("mozilla.org");
+  check_login_exists(TEST_HOST, false);
+}
+
+function test_login_manager_logins_cleared_with_subdomain()
+{
+  const TEST_HOST = "http://www.mozilla.org";
+  add_login(TEST_HOST);
+  pb.removeDataFromDomain("mozilla.org");
+  check_login_exists(TEST_HOST, false);
+}
+
+function tets_login_manager_logins_not_cleared_with_uri_contains_domain()
+{
+  const TEST_HOST = "http://ilovemozilla.org";
+  add_login(TEST_HOST);
+  pb.removeDataFromDomain("mozilla.org");
+  check_login_exists(TEST_HOST, true);
+
+  let lm = Cc["@mozilla.org/login-manager;1"].
+           getService(Ci.nsILoginManager);
+  lm.removeAllLogins();
+  check_login_exists(TEST_HOST, false);
+}
+
+// Permission Manager
+function test_permission_manager_cleared_with_direct_match()
+{
+  const TEST_URI = uri("http://mozilla.org");
+  add_permission(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_permission_exists(TEST_URI, false);
+}
+
+function test_permission_manager_cleared_with_subdomain()
+{
+  const TEST_URI = uri("http://www.mozilla.org");
+  add_permission(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_permission_exists(TEST_URI, false);
+}
+
+function test_permission_manager_not_cleared_with_uri_contains_domain()
+{
+  const TEST_URI = uri("http://ilovemozilla.org");
+  add_permission(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_permission_exists(TEST_URI, true);
+
+  // Reset state
+  let pm = Cc["@mozilla.org/permissionmanager;1"].
+           getService(Ci.nsIPermissionManager);
+  pm.removeAll();
+  check_permission_exists(TEST_URI, false);
+}
+
+// Content Preferences
+function test_content_preferences_cleared_with_direct_match()
+{
+  const TEST_URI = uri("http://mozilla.org");
+  add_preference(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_preference_exists(TEST_URI, false);
+}
+
+function test_content_preferences_cleared_with_subdomain()
+{
+  const TEST_URI = uri("http://www.mozilla.org");
+  add_preference(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_preference_exists(TEST_URI, false);
+}
+
+function test_content_preferecnes_not_cleared_with_uri_contains_domain()
+{
+  const TEST_URI = uri("http://ilovemozilla.org");
+  add_preference(TEST_URI);
+  pb.removeDataFromDomain("mozilla.org");
+  check_preference_exists(TEST_URI, true);
+
+  // Reset state
+  let cp = Cc["@mozilla.org/content-pref/service;1"].
+           getService(Ci.nsIContentPrefService);
+  cp.removePref(TEST_URI, PREFERENCE_NAME);
+  check_preference_exists(TEST_URI, false);
+}
+
+// Cache
+function test_cache_cleared()
+{
+  // Because this test is asynchronous, it should be the last test
+  do_check_eq(tests[tests.length - 1], arguments.callee);
+
+  // NOTE: We could be more extensive with this test and actually add an entry
+  //       to the cache, and then make sure it is gone.  However, we trust that
+  //       the API is well tested, and that when we get the observer
+  //       notification, we have actually cleared the cache.
+  // This seems to happen asynchronously...
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let observer = {
+    observe: function(aSubject, aTopic, aData)
+    {
+      os.removeObserver(observer, "cacheservice:empty-cache");
+      do_test_finished();
+    }
+  };
+  os.addObserver(observer, "cacheservice:empty-cache", false);
+  pb.removeDataFromDomain("mozilla.org");
+  do_test_pending();
+}
+
+let tests = [
+  // History
+  test_history_cleared_with_direct_match,
+  test_history_cleared_with_subdomain,
+  test_history_not_cleared_with_uri_contains_domain,
+
+  // Cookie Service
+  test_cookie_cleared_with_direct_match,
+  test_cookie_cleared_with_subdomain,
+  test_cookie_not_cleared_with_uri_contains_domain,
+
+  // Download Manager
+  // Note: active downloads tested in test_removeDataFromDomain_activeDownloads.js
+  test_download_history_cleared_with_direct_match,
+  test_download_history_cleared_with_subdomain,
+  test_download_history_not_cleared_with_active_direct_match,
+
+  // Login Manager
+  test_login_manager_disabled_hosts_cleared_with_direct_match,
+  test_login_manager_disabled_hosts_cleared_with_subdomain,
+  test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain,
+  test_login_manager_logins_cleared_with_direct_match,
+  test_login_manager_logins_cleared_with_subdomain,
+  tets_login_manager_logins_not_cleared_with_uri_contains_domain,
+
+  // Permission Manager
+  test_permission_manager_cleared_with_direct_match,
+  test_permission_manager_cleared_with_subdomain,
+  test_permission_manager_not_cleared_with_uri_contains_domain,
+
+  // Content Preferences
+  test_content_preferences_cleared_with_direct_match,
+  test_content_preferences_cleared_with_subdomain,
+  test_content_preferecnes_not_cleared_with_uri_contains_domain,
+
+  // Cache
+  test_cache_cleared,
+];
+
+function do_test()
+{
+  for (let i = 0; i < tests.length; i++)
+    tests[i]();
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain_activeDownloads.js
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Test added with bug 460086 to test the behavior of the new API that was added
+ * to remove all traces of visiting a site.
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
+         getService(Ci.nsIPrivateBrowsingService);
+
+////////////////////////////////////////////////////////////////////////////////
+//// Utility Functions
+
+/**
+ * Creates an nsIURI object for the given file.
+ *
+ * @param aFile
+ *        The nsIFile of the URI to create.
+ * @returns an nsIURI representing aFile.
+ */
+function uri(aFile)
+{
+  return Cc["@mozilla.org/network/io-service;1"].
+         getService(Ci.nsIIOService).
+         newFileURI(aFile);
+}
+
+/**
+ * Checks to ensure a URI string is in download history or not.
+ *
+ * @param aURIString
+ *        The string of the URI to check.
+ * @param aIsActive
+ *        True if the URI should be actively downloaded, false otherwise.
+ */
+function check_active_download(aURIString, aIsActive)
+{
+  let dm = Cc["@mozilla.org/download-manager;1"].
+           getService(Ci.nsIDownloadManager);
+  let enumerator = dm.activeDownloads;
+  let found = false;
+  while (enumerator.hasMoreElements()) {
+    let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
+    if (dl.source.spec == aURIString)
+      found = true;
+  }
+  let checker = aIsActive ? do_check_true : do_check_false;
+  checker(found);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// Test Functions
+
+let destFile = dirSvc.get("TmpD", Ci.nsIFile);
+destFile.append("dm-test-file");
+destFile = uri(destFile);
+let data = [
+  { source: "http://mozilla.org/direct_match",
+    target: destFile.spec,
+    removed: true
+  },
+  { source: "http://www.mozilla.org/subdomain",
+    target: destFile.spec,
+    removed: true
+  },
+  { source: "http://ilovemozilla.org/contains_domain",
+    target: destFile.spec,
+    removed: false
+  },
+];
+
+function do_test()
+{
+  // We add this data to the database first, but we cannot instantiate the
+  // download manager service, otherwise these downloads will not be placed in
+  // the active downloads array.
+
+  // Copy the empty downloads database to our profile directory
+  let downloads = do_get_file("toolkit/components/downloads/test/downloads.empty.sqlite");
+  downloads.copyTo(dirSvc.get("ProfD", Ci.nsIFile), "downloads.sqlite");
+
+  // Open the database
+  let ss = Cc["@mozilla.org/storage/service;1"].
+           getService(Ci.mozIStorageService);
+  let file = dirSvc.get("ProfD", Ci.nsIFile);
+  file.append("downloads.sqlite");
+  let db = ss.openDatabase(file);
+
+  // Insert the data
+  let stmt = db.createStatement(
+    "INSERT INTO moz_downloads (source, target, state, autoResume, entityID) " +
+    "VALUES (:source, :target, :state, :autoResume, :entityID)"
+  );
+  for (let i = 0; i < data.length; i++) {
+    stmt.params.source = data[i].source;
+    stmt.params.target = data[i].target;
+    stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_PAUSED;
+    stmt.params.autoResume = 0; // DONT_RESUME is 0
+    stmt.params.entityID = "foo" // just has to be non-null for our test
+    stmt.execute();
+    stmt.reset();
+  }
+  stmt.finalize();
+  stmt = null;
+  db.close();
+  db = null;
+
+  // Check to make sure it's all there
+  for (let i = 0; i < data.length; i++)
+    check_active_download(data[i].source, true);
+
+  // Dispatch the remove call
+  pb.removeDataFromDomain("mozilla.org");
+
+  // And check our data
+  for (let i = 0; i < data.length; i++)
+    check_active_download(data[i].source, !data[i].removed);
+}
--- a/browser/components/privatebrowsing/test/unit/head_privatebrowsing.js
+++ b/browser/components/privatebrowsing/test/unit/head_privatebrowsing.js
@@ -104,8 +104,21 @@ function cleanUp()
   for (let i = 0; i < files.length; i++) {
     let file = dirSvc.get("ProfD", Ci.nsIFile);
     file.append(files[i]);
     if (file.exists())
       file.remove(false);
   }
 }
 cleanUp();
+
+var PRIVATEBROWSING_CONTRACT_ID;
+function run_test_on_all_services() {
+  var contractIDs = [
+    "@mozilla.org/privatebrowsing;1",
+    "@mozilla.org/privatebrowsing-wrapper;1"
+  ];
+  for (var i = 0; i < contractIDs.length; ++i) {
+    PRIVATEBROWSING_CONTRACT_ID = contractIDs[i];
+    run_test_on_service();
+    cleanUp();
+  }
+}
--- a/browser/components/privatebrowsing/test/unit/test_0-privatebrowsing.js
+++ b/browser/components/privatebrowsing/test/unit/test_0-privatebrowsing.js
@@ -36,33 +36,33 @@
  * ***** END LICENSE BLOCK ***** */
 
 // This tests the private browsing service to make sure it implements its
 // documented interface correctly.
 
 // This test should run before the rest of private browsing service unit tests,
 // hence the naming used for this file.
 
-function run_test() {
+function run_test_on_service() {
   // initialization
   var os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
   var prefBranch = Cc["@mozilla.org/preferences-service;1"].
                    getService(Ci.nsIPrefBranch);
   prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
 
   // the contract ID should be available
-  do_check_true("@mozilla.org/privatebrowsing;1" in Cc);
+  do_check_true(PRIVATEBROWSING_CONTRACT_ID in Cc);
 
   // the interface should be available
   do_check_true("nsIPrivateBrowsingService" in Ci);
 
   // it should be possible to initialize the component
   try {
-    var pb = Cc["@mozilla.org/privatebrowsing;1"].
+    var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
              getService(Ci.nsIPrivateBrowsingService);
   } catch (ex) {
     LOG("exception thrown when trying to get the service: " + ex);
     do_throw("private browsing service could not be initialized");
   }
 
   // private browsing should be turned off initially
   do_check_false(pb.privateBrowsingEnabled);
@@ -217,8 +217,13 @@ function run_test() {
       kPrivateBrowsingCancelVoteNotification + " " + kExit,
       "enter phase 2",
       kPrivateBrowsingNotification + " " + kExit,
     ];
   do_check_eq(observer.notifications.join(","), reference_order.join(","));
 
   prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
 }
+
+// Support running tests on both the service itself and its wrapper
+function run_test() {
+  run_test_on_all_services();
+}
--- a/browser/components/privatebrowsing/test/unit/test_aboutprivatebrowsing.js
+++ b/browser/components/privatebrowsing/test/unit/test_aboutprivatebrowsing.js
@@ -54,19 +54,19 @@ function is_about_privatebrowsing_availa
     input.close();
     return true;
   } catch (ex if ("result" in ex && ex.result == Cr.NS_ERROR_MALFORMED_URI)) { // expected
   }
 
   return false;
 }
 
-function run_test() {
+function run_test_on_service() {
   // initialization
-  var pb = Cc["@mozilla.org/privatebrowsing;1"].
+  var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
            getService(Ci.nsIPrivateBrowsingService);
   var prefBranch = Cc["@mozilla.org/preferences-service;1"].
                    getService(Ci.nsIPrefBranch);
   prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
 
   try {
     // about:privatebrowsing should be available before entering the private mode
     do_check_true(is_about_privatebrowsing_available());
@@ -81,8 +81,13 @@ function run_test() {
     pb.privateBrowsingEnabled = false;
 
     // about:privatebrowsing should be available after leaving the private mode
     do_check_true(is_about_privatebrowsing_available());
   } finally {
     prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
   }
 }
+
+// Support running tests on both the service itself and its wrapper
+function run_test() {
+  run_test_on_all_services();
+}
--- a/browser/components/privatebrowsing/test/unit/test_httpauth.js
+++ b/browser/components/privatebrowsing/test/unit/test_httpauth.js
@@ -33,22 +33,22 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // This test makes sure the HTTP authenticated sessions are correctly cleared
 // when entering and leaving the private browsing mode.
 
-function run_test() {
+function run_test_on_service() {
   var prefBranch = Cc["@mozilla.org/preferences-service;1"].
                    getService(Ci.nsIPrefBranch);
   prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
 
-  var pb = Cc["@mozilla.org/privatebrowsing;1"].
+  var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
            getService(Ci.nsIPrivateBrowsingService);
 
   var am = Cc["@mozilla.org/network/http-auth-manager;1"].
            getService(Ci.nsIHttpAuthManager);
 
   const kHost1 = "pbtest3.example.com";
   const kHost2 = "pbtest4.example.com";
   const kPort = 80;
@@ -107,8 +107,13 @@ function run_test() {
       do_check_eq(pass.value, kEmpty);
     }
   } catch (e) {
     do_throw("Unexpected exception while testing HTTP auth manager: " + e);
   } finally {
     prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
   }
 }
+
+// Support running tests on both the service itself and its wrapper
+function run_test() {
+  run_test_on_all_services();
+}
--- a/browser/components/privatebrowsing/test/unit/test_privatebrowsing_autostart.js
+++ b/browser/components/privatebrowsing/test/unit/test_privatebrowsing_autostart.js
@@ -33,36 +33,12 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // This test checks the browser.privatebrowsing.autostart preference.
 
 function run_test() {
-  // initialization
-  var prefsService = Cc["@mozilla.org/preferences-service;1"].
-                     getService(Ci.nsIPrefBranch);
-  prefsService.setBoolPref("browser.privatebrowsing.autostart", true);
-  do_check_true(prefsService.getBoolPref("browser.privatebrowsing.autostart"));
-
-  var pb = Cc["@mozilla.org/privatebrowsing;1"].
-           getService(Ci.nsIPrivateBrowsingService).
-           QueryInterface(Ci.nsIObserver);
-
-  // private browsing not auto-started yet
-  do_check_false(pb.autoStarted);
-
-  // simulate startup to make the PB service read the prefs
-  pb.observe(null, "profile-after-change", "");
-
-  // the private mode should be entered automatically
-  do_check_true(pb.privateBrowsingEnabled);
-
-  // private browsing is auto-started
-  do_check_true(pb.autoStarted);
-
-  // leave private browsing mode
-  pb.privateBrowsingEnabled = false;
-
-  // private browsing not auto-started
-  do_check_false(pb.autoStarted);
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_autostart.js");
+  do_test();
 }
--- a/browser/components/privatebrowsing/test/unit/test_privatebrowsing_exit.js
+++ b/browser/components/privatebrowsing/test/unit/test_privatebrowsing_exit.js
@@ -34,64 +34,12 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // This test makes sure that the private browsing mode is left at application
 // shutdown.
 
 function run_test() {
-  // initialization
-  var os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  var pb = Cc["@mozilla.org/privatebrowsing;1"].
-           getService(Ci.nsIPrivateBrowsingService);
-  var prefBranch = Cc["@mozilla.org/preferences-service;1"].
-                   getService(Ci.nsIPrefBranch);
-  prefBranch.setBoolPref("browser.privatebrowsing.keep_current_session", true);
-
-  var expectedQuitting;
-  var called = 0;
-  var observer = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic == kPrivateBrowsingNotification &&
-          aData == kExit) {
-        // increment the call counter
-        ++ called;
-
-        do_check_neq(aSubject, null);
-        try {
-          aSubject.QueryInterface(Ci.nsISupportsPRBool);
-        } catch (ex) {
-          do_throw("aSubject was not null, but wasn't an nsISupportsPRBool");
-        }
-        // check the "quitting" argument
-        do_check_eq(aSubject.data, expectedQuitting);
-
-        // finish up the test
-        if (expectedQuitting) {
-          os.removeObserver(this, kPrivateBrowsingNotification);
-          prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
-          do_test_finished();
-        }
-      }
-    }
-  };
-
-  // set the observer
-  os.addObserver(observer, kPrivateBrowsingNotification, false);
-
-  // enter the private browsing mode
-  pb.privateBrowsingEnabled = true;
-
-  // exit the private browsing mode
-  expectedQuitting = false;
-  pb.privateBrowsingEnabled = false;
-  do_check_eq(called, 1);
-
-  // enter the private browsing mode
-  pb.privateBrowsingEnabled = true;
-
-  // Simulate an exit
-  expectedQuitting = true;
-  do_test_pending();
-  os.notifyObservers(null, "quit-application-granted", null);
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_exit.js");
+  do_test();
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_autostart.js
@@ -0,0 +1,44 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test checks the browser.privatebrowsing.autostart preference.
+
+function run_test() {
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing-wrapper;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_autostart.js");
+  do_test();
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_exit.js
@@ -0,0 +1,45 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the private browsing mode is left at application
+// shutdown.
+
+function run_test() {
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing-wrapper;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_privatebrowsing_exit.js");
+  do_test();
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_removeDataFromDomain.js
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Test added with bug 460086 to test the behavior of the new API that was added
+ * to remove all traces of visiting a site.
+ */
+
+function run_test() {
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing-wrapper;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain.js");
+  do_test();
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/test_privatebrowsingwrapper_removeDataFromDomain_activeDownloads.js
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Test added with bug 460086 to test the behavior of the new API that was added
+ * to remove all traces of visiting a site.
+ */
+
+function run_test() {
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain_activeDownloads.js");
+  do_test();
+}
--- a/browser/components/privatebrowsing/test/unit/test_removeDataFromDomain.js
+++ b/browser/components/privatebrowsing/test/unit/test_removeDataFromDomain.js
@@ -37,582 +37,13 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Test added with bug 460086 to test the behavior of the new API that was added
  * to remove all traces of visiting a site.
  */
 
-////////////////////////////////////////////////////////////////////////////////
-//// Constants
-
-let pb = Cc["@mozilla.org/privatebrowsing;1"].
-         getService(Ci.nsIPrivateBrowsingService);
-
-const COOKIE_EXPIRY = Math.round(Date.now() / 1000) + 60;
-const COOKIE_NAME = "testcookie";
-const COOKIE_PATH = "/";
-
-const LOGIN_USERNAME = "username";
-const LOGIN_PASSWORD = "password";
-const LOGIN_USERNAME_FIELD = "username_field";
-const LOGIN_PASSWORD_FIELD = "password_field";
-
-const PERMISSION_TYPE = "test-perm";
-const PERMISSION_VALUE = Ci.nsIPermissionManager.ALLOW_ACTION;
-
-const PREFERENCE_NAME = "test-pref";
-
-////////////////////////////////////////////////////////////////////////////////
-//// Utility Functions
-
-/**
- * Creates an nsIURI object for the given string representation of a URI.
- *
- * @param aURIString
- *        The spec of the URI to create.
- * @returns an nsIURI representing aURIString.
- */
-function uri(aURIString)
-{
-  return Cc["@mozilla.org/network/io-service;1"].
-         getService(Ci.nsIIOService).
-         newURI(aURIString, null, null);
-}
-
-/**
- * Adds a visit to history.
- *
- * @param aURI
- *        The URI to add.
- */
-function add_visit(aURI)
-{
-  check_visited(aURI, false);
-  let bh = Cc["@mozilla.org/browser/global-history;2"].
-           getService(Ci.nsIBrowserHistory);
-  bh.addPageWithDetails(aURI, aURI.spec, Date.now() * 1000);
-  check_visited(aURI, true);
-}
-
-/**
- * Checks to ensure a URI string is visited or not.
- *
- * @param aURI
- *        The URI to check.
- * @param aIsVisited
- *        True if the URI should be visited, false otherwise.
- */
-function check_visited(aURI, aIsVisited)
-{
-  let gh = Cc["@mozilla.org/browser/global-history;2"].
-           getService(Ci.nsIGlobalHistory2);
-  let checker = aIsVisited ? do_check_true : do_check_false;
-  checker(gh.isVisited(aURI));
-}
-
-/**
- * Add a cookie to the cookie service.
- *
- * @param aDomain
- */
-function add_cookie(aDomain)
-{
-  check_cookie_exists(aDomain, false);
-  let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
-  cm.add(aDomain, COOKIE_PATH, COOKIE_NAME, "", false, false, false,
-         COOKIE_EXPIRY);
-  check_cookie_exists(aDomain, true);
-}
-
-/**
- * Checks to ensure that a cookie exists or not for a domain.
- *
- * @param aDomain
- *        The domain to check for the cookie.
- * @param aExists
- *        True if the cookie should exist, false otherwise.
- */
-function check_cookie_exists(aDomain, aExists)
-{
-  let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
-  let cookie = {
-    host: aDomain,
-    name: COOKIE_NAME,
-    path: COOKIE_PATH
-  }
-  let checker = aExists ? do_check_true : do_check_false;
-  checker(cm.cookieExists(cookie));
-}
-
-/**
- * Adds a download to download history.
- *
- * @param aURIString
- *        The string of the URI to add.
- * @param aIsActive
- *        If it should be set to an active state in the database.  This does not
- *        make it show up in the list of active downloads however!
- */
-function add_download(aURIString, aIsActive)
-{
-  check_downloaded(aURIString, false);
-  let db = Cc["@mozilla.org/download-manager;1"].
-           getService(Ci.nsIDownloadManager).
-           DBConnection;
-  let stmt = db.createStatement(
-    "INSERT INTO moz_downloads (source, state) " +
-    "VALUES (:source, :state)"
-  );
-  stmt.params.source = aURIString;
-  stmt.params.state = aIsActive ? Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING :
-                                  Ci.nsIDownloadManager.DOWNLOAD_FINISHED;
-  try {
-    stmt.execute();
-  }
-  finally {
-    stmt.finalize();
-  }
-  check_downloaded(aURIString, true);
-}
-
-/**
- * Checks to ensure a URI string is in download history or not.
- *
- * @param aURIString
- *        The string of the URI to check.
- * @param aIsDownloaded
- *        True if the URI should be downloaded, false otherwise.
- */
-function check_downloaded(aURIString, aIsDownloaded)
-{
-  let db = Cc["@mozilla.org/download-manager;1"].
-           getService(Ci.nsIDownloadManager).
-           DBConnection;
-  let stmt = db.createStatement(
-    "SELECT * " +
-    "FROM moz_downloads " +
-    "WHERE source = :source"
-  );
-  stmt.params.source = aURIString;
-
-  let checker = aIsDownloaded ? do_check_true : do_check_false;
-  try {
-    checker(stmt.step());
-  }
-  finally {
-    stmt.finalize();
-  }
-}
-
-/**
- * Adds a disabled host to the login manager.
- *
- * @param aHost
- *        The host to add to the list of disabled hosts.
- */
-function add_disabled_host(aHost)
-{
-  check_disabled_host(aHost, false);
-  let lm = Cc["@mozilla.org/login-manager;1"].
-           getService(Ci.nsILoginManager);
-  lm.setLoginSavingEnabled(aHost, false);
-  check_disabled_host(aHost, true);
-}
-
-/**
- * Checks to see if a host is disabled for storing logins or not.
- *
- * @param aHost
- *        The host to check if it is disabled.
- * @param aIsDisabled
- *        True if the host should be disabled, false otherwise.
- */
-function check_disabled_host(aHost, aIsDisabled)
-{
-  let lm = Cc["@mozilla.org/login-manager;1"].
-           getService(Ci.nsILoginManager);
-  let checker = aIsDisabled ? do_check_false : do_check_true;
-  checker(lm.getLoginSavingEnabled(aHost));
-}
-
-/**
- * Adds a login for the specified host to the login manager.
- *
- * @param aHost
- *        The host to add the login for.
- */
-function add_login(aHost)
-{
-  check_login_exists(aHost, false);
-  let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
-              createInstance(Ci.nsILoginInfo);
-  login.init(aHost, "", null, LOGIN_USERNAME, LOGIN_PASSWORD,
-             LOGIN_USERNAME_FIELD, LOGIN_PASSWORD_FIELD);
-  let lm = Cc["@mozilla.org/login-manager;1"].
-           getService(Ci.nsILoginManager);
-  lm.addLogin(login);
-  check_login_exists(aHost, true);
-}
-
-/**
- * Checks to see if a login exists for a host.
- *
- * @param aHost
- *        The host to check for the test login.
- * @param aExists
- *        True if the login should exist, false otherwise.
- */
-function check_login_exists(aHost, aExists)
-{
-  let lm = Cc["@mozilla.org/login-manager;1"].
-           getService(Ci.nsILoginManager);
-  let count = { value: 0 };
-  lm.findLogins(count, aHost, "", null);
-  do_check_eq(count.value, aExists ? 1 : 0);
-}
-
-/**
- * Adds a permission for the specified URI to the permission manager.
- *
- * @param aURI
- *        The URI to add the test permission for.
- */
-function add_permission(aURI)
-{
-  check_permission_exists(aURI, false);
-  let pm = Cc["@mozilla.org/permissionmanager;1"].
-           getService(Ci.nsIPermissionManager);
-  pm.add(aURI, PERMISSION_TYPE, PERMISSION_VALUE);
-  check_permission_exists(aURI, true);
-}
-
-/**
- * Checks to see if a permission exists for the given URI.
- *
- * @param aURI
- *        The URI to check if a permission exists.
- * @param aExists
- *        True if the permission should exist, false otherwise.
- */
-function check_permission_exists(aURI, aExists)
-{
-  let pm = Cc["@mozilla.org/permissionmanager;1"].
-           getService(Ci.nsIPermissionManager);
-  let perm = pm.testExactPermission(aURI, PERMISSION_TYPE);
-  let checker = aExists ? do_check_eq : do_check_neq;
-  checker(perm, PERMISSION_VALUE);
-}
-
-/**
- * Adds a content preference for the specified URI.
- *
- * @param aURI
- *        The URI to add a preference for.
- */
-function add_preference(aURI)
-{
-  check_preference_exists(aURI, false);
-  let cp = Cc["@mozilla.org/content-pref/service;1"].
-           getService(Ci.nsIContentPrefService);
-  cp.setPref(aURI, PREFERENCE_NAME, "foo");
-  check_preference_exists(aURI, true);
+function run_test() {
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain.js");
+  do_test();
 }
-
-/**
- * Checks to see if a preference exists for the given URI.
- *
- * @param aURI
- *        The URI to check if a preference exists.
- * @param aExists
- *        True if the permission should exist, false otherwise.
- */
-function check_preference_exists(aURI, aExists)
-{
-  let cp = Cc["@mozilla.org/content-pref/service;1"].
-           getService(Ci.nsIContentPrefService);
-  let checker = aExists ? do_check_true : do_check_false;
-  checker(cp.hasPref(aURI, PREFERENCE_NAME));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Functions
-
-// History
-function test_history_cleared_with_direct_match()
-{
-  const TEST_URI = uri("http://mozilla.org/foo");
-  add_visit(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_visited(TEST_URI, false);
-}
-
-function test_history_cleared_with_subdomain()
-{
-  const TEST_URI = uri("http://www.mozilla.org/foo");
-  add_visit(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_visited(TEST_URI, false);
-}
-
-function test_history_not_cleared_with_uri_contains_domain()
-{
-  const TEST_URI = uri("http://ilovemozilla.org/foo");
-  add_visit(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_visited(TEST_URI, true);
-
-  // Clear history since we left something there from this test.
-  let bh = Cc["@mozilla.org/browser/global-history;2"].
-           getService(Ci.nsIBrowserHistory);
-  bh.removeAllPages();
-}
-
-// Cookie Service
-function test_cookie_cleared_with_direct_match()
-{
-  const TEST_DOMAIN = "mozilla.org";
-  add_cookie(TEST_DOMAIN);
-  pb.removeDataFromDomain("mozilla.org");
-  check_cookie_exists(TEST_DOMAIN, false);
-}
-
-function test_cookie_cleared_with_subdomain()
-{
-  const TEST_DOMAIN = "www.mozilla.org";
-  add_cookie(TEST_DOMAIN);
-  pb.removeDataFromDomain("mozilla.org");
-  check_cookie_exists(TEST_DOMAIN, false);
-}
-
-function test_cookie_not_cleared_with_uri_contains_domain()
-{
-  const TEST_DOMAIN = "ilovemozilla.org";
-  add_cookie(TEST_DOMAIN);
-  pb.removeDataFromDomain("mozilla.org");
-  check_cookie_exists(TEST_DOMAIN, true);
-}
-
-// Download Manager
-function test_download_history_cleared_with_direct_match()
-{
-  const TEST_URI = "http://mozilla.org/foo";
-  add_download(TEST_URI, false);
-  pb.removeDataFromDomain("mozilla.org");
-  check_downloaded(TEST_URI, false);
-}
-
-function test_download_history_cleared_with_subdomain()
-{
-  const TEST_URI = "http://www.mozilla.org/foo";
-  add_download(TEST_URI, false);
-  pb.removeDataFromDomain("mozilla.org");
-  check_downloaded(TEST_URI, false);
-}
-
-function test_download_history_not_cleared_with_active_direct_match()
-{
-  // Tests that downloads marked as active in the db are not deleted from the db
-  const TEST_URI = "http://mozilla.org/foo";
-  add_download(TEST_URI, true);
-  pb.removeDataFromDomain("mozilla.org");
-  check_downloaded(TEST_URI, true);
-
-  // Reset state
-  let db = Cc["@mozilla.org/download-manager;1"].
-           getService(Ci.nsIDownloadManager).
-           DBConnection;
-  db.executeSimpleSQL("DELETE FROM moz_downloads");
-  check_downloaded(TEST_URI, false);
-}
-
-// Login Manager
-function test_login_manager_disabled_hosts_cleared_with_direct_match()
-{
-  const TEST_HOST = "http://mozilla.org";
-  add_disabled_host(TEST_HOST);
-  pb.removeDataFromDomain("mozilla.org");
-  check_disabled_host(TEST_HOST, false);
-}
-
-function test_login_manager_disabled_hosts_cleared_with_subdomain()
-{
-  const TEST_HOST = "http://www.mozilla.org";
-  add_disabled_host(TEST_HOST);
-  pb.removeDataFromDomain("mozilla.org");
-  check_disabled_host(TEST_HOST, false);
-}
-
-function test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain()
-{
-  const TEST_HOST = "http://ilovemozilla.org";
-  add_disabled_host(TEST_HOST);
-  pb.removeDataFromDomain("mozilla.org");
-  check_disabled_host(TEST_HOST, true);
-
-  // Reset state
-  let lm = Cc["@mozilla.org/login-manager;1"].
-           getService(Ci.nsILoginManager);
-  lm.setLoginSavingEnabled(TEST_HOST, true);
-  check_disabled_host(TEST_HOST, false);
-}
-
-function test_login_manager_logins_cleared_with_direct_match()
-{
-  const TEST_HOST = "http://mozilla.org";
-  add_login(TEST_HOST);
-  pb.removeDataFromDomain("mozilla.org");
-  check_login_exists(TEST_HOST, false);
-}
-
-function test_login_manager_logins_cleared_with_subdomain()
-{
-  const TEST_HOST = "http://www.mozilla.org";
-  add_login(TEST_HOST);
-  pb.removeDataFromDomain("mozilla.org");
-  check_login_exists(TEST_HOST, false);
-}
-
-function tets_login_manager_logins_not_cleared_with_uri_contains_domain()
-{
-  const TEST_HOST = "http://ilovemozilla.org";
-  add_login(TEST_HOST);
-  pb.removeDataFromDomain("mozilla.org");
-  check_login_exists(TEST_HOST, true);
-
-  let lm = Cc["@mozilla.org/login-manager;1"].
-           getService(Ci.nsILoginManager);
-  lm.removeAllLogins();
-  check_login_exists(TEST_HOST, false);
-}
-
-// Permission Manager
-function test_permission_manager_cleared_with_direct_match()
-{
-  const TEST_URI = uri("http://mozilla.org");
-  add_permission(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_permission_exists(TEST_URI, false);
-}
-
-function test_permission_manager_cleared_with_subdomain()
-{
-  const TEST_URI = uri("http://www.mozilla.org");
-  add_permission(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_permission_exists(TEST_URI, false);
-}
-
-function test_permission_manager_not_cleared_with_uri_contains_domain()
-{
-  const TEST_URI = uri("http://ilovemozilla.org");
-  add_permission(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_permission_exists(TEST_URI, true);
-
-  // Reset state
-  let pm = Cc["@mozilla.org/permissionmanager;1"].
-           getService(Ci.nsIPermissionManager);
-  pm.removeAll();
-  check_permission_exists(TEST_URI, false);
-}
-
-// Content Preferences
-function test_content_preferences_cleared_with_direct_match()
-{
-  const TEST_URI = uri("http://mozilla.org");
-  add_preference(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_preference_exists(TEST_URI, false);
-}
-
-function test_content_preferences_cleared_with_subdomain()
-{
-  const TEST_URI = uri("http://www.mozilla.org");
-  add_preference(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_preference_exists(TEST_URI, false);
-}
-
-function test_content_preferecnes_not_cleared_with_uri_contains_domain()
-{
-  const TEST_URI = uri("http://ilovemozilla.org");
-  add_preference(TEST_URI);
-  pb.removeDataFromDomain("mozilla.org");
-  check_preference_exists(TEST_URI, true);
-
-  // Reset state
-  let cp = Cc["@mozilla.org/content-pref/service;1"].
-           getService(Ci.nsIContentPrefService);
-  cp.removePref(TEST_URI, PREFERENCE_NAME);
-  check_preference_exists(TEST_URI, false);
-}
-
-// Cache
-function test_cache_cleared()
-{
-  // Because this test is asynchronous, it should be the last test
-  do_check_eq(tests[tests.length - 1], arguments.callee);
-
-  // NOTE: We could be more extensive with this test and actually add an entry
-  //       to the cache, and then make sure it is gone.  However, we trust that
-  //       the API is well tested, and that when we get the observer
-  //       notification, we have actually cleared the cache.
-  // This seems to happen asynchronously...
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  let observer = {
-    observe: function(aSubject, aTopic, aData)
-    {
-      os.removeObserver(observer, "cacheservice:empty-cache");
-      do_test_finished();
-    }
-  };
-  os.addObserver(observer, "cacheservice:empty-cache", false);
-  pb.removeDataFromDomain("mozilla.org");
-  do_test_pending();
-}
-
-let tests = [
-  // History
-  test_history_cleared_with_direct_match,
-  test_history_cleared_with_subdomain,
-  test_history_not_cleared_with_uri_contains_domain,
-
-  // Cookie Service
-  test_cookie_cleared_with_direct_match,
-  test_cookie_cleared_with_subdomain,
-  test_cookie_not_cleared_with_uri_contains_domain,
-
-  // Download Manager
-  // Note: active downloads tested in test_removeDataFromDomain_activeDownloads.js
-  test_download_history_cleared_with_direct_match,
-  test_download_history_cleared_with_subdomain,
-  test_download_history_not_cleared_with_active_direct_match,
-
-  // Login Manager
-  test_login_manager_disabled_hosts_cleared_with_direct_match,
-  test_login_manager_disabled_hosts_cleared_with_subdomain,
-  test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain,
-  test_login_manager_logins_cleared_with_direct_match,
-  test_login_manager_logins_cleared_with_subdomain,
-  tets_login_manager_logins_not_cleared_with_uri_contains_domain,
-
-  // Permission Manager
-  test_permission_manager_cleared_with_direct_match,
-  test_permission_manager_cleared_with_subdomain,
-  test_permission_manager_not_cleared_with_uri_contains_domain,
-
-  // Content Preferences
-  test_content_preferences_cleared_with_direct_match,
-  test_content_preferences_cleared_with_subdomain,
-  test_content_preferecnes_not_cleared_with_uri_contains_domain,
-
-  // Cache
-  test_cache_cleared,
-];
-
-function run_test()
-{
-  for (let i = 0; i < tests.length; i++)
-    tests[i]();
-}
--- a/browser/components/privatebrowsing/test/unit/test_removeDataFromDomain_activeDownloads.js
+++ b/browser/components/privatebrowsing/test/unit/test_removeDataFromDomain_activeDownloads.js
@@ -37,122 +37,13 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Test added with bug 460086 to test the behavior of the new API that was added
  * to remove all traces of visiting a site.
  */
 
-////////////////////////////////////////////////////////////////////////////////
-//// Constants
-
-let pb = Cc["@mozilla.org/privatebrowsing;1"].
-         getService(Ci.nsIPrivateBrowsingService);
-
-////////////////////////////////////////////////////////////////////////////////
-//// Utility Functions
-
-/**
- * Creates an nsIURI object for the given file.
- *
- * @param aFile
- *        The nsIFile of the URI to create.
- * @returns an nsIURI representing aFile.
- */
-function uri(aFile)
-{
-  return Cc["@mozilla.org/network/io-service;1"].
-         getService(Ci.nsIIOService).
-         newFileURI(aFile);
-}
-
-/**
- * Checks to ensure a URI string is in download history or not.
- *
- * @param aURIString
- *        The string of the URI to check.
- * @param aIsActive
- *        True if the URI should be actively downloaded, false otherwise.
- */
-function check_active_download(aURIString, aIsActive)
-{
-  let dm = Cc["@mozilla.org/download-manager;1"].
-           getService(Ci.nsIDownloadManager);
-  let enumerator = dm.activeDownloads;
-  let found = false;
-  while (enumerator.hasMoreElements()) {
-    let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
-    if (dl.source.spec == aURIString)
-      found = true;
-  }
-  let checker = aIsActive ? do_check_true : do_check_false;
-  checker(found);
+function run_test() {
+  PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
+  do_import_script("browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain_activeDownloads.js");
+  do_test();
 }
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Functions
-
-let destFile = dirSvc.get("TmpD", Ci.nsIFile);
-destFile.append("dm-test-file");
-destFile = uri(destFile);
-let data = [
-  { source: "http://mozilla.org/direct_match",
-    target: destFile.spec,
-    removed: true
-  },
-  { source: "http://www.mozilla.org/subdomain",
-    target: destFile.spec,
-    removed: true
-  },
-  { source: "http://ilovemozilla.org/contains_domain",
-    target: destFile.spec,
-    removed: false
-  },
-];
-
-function run_test()
-{
-  // We add this data to the database first, but we cannot instantiate the
-  // download manager service, otherwise these downloads will not be placed in
-  // the active downloads array.
-
-  // Copy the empty downloads database to our profile directory
-  let downloads = do_get_file("toolkit/components/downloads/test/downloads.empty.sqlite");
-  downloads.copyTo(dirSvc.get("ProfD", Ci.nsIFile), "downloads.sqlite");
-
-  // Open the database
-  let ss = Cc["@mozilla.org/storage/service;1"].
-           getService(Ci.mozIStorageService);
-  let file = dirSvc.get("ProfD", Ci.nsIFile);
-  file.append("downloads.sqlite");
-  let db = ss.openDatabase(file);
-
-  // Insert the data
-  let stmt = db.createStatement(
-    "INSERT INTO moz_downloads (source, target, state, autoResume, entityID) " +
-    "VALUES (:source, :target, :state, :autoResume, :entityID)"
-  );
-  for (let i = 0; i < data.length; i++) {
-    stmt.params.source = data[i].source;
-    stmt.params.target = data[i].target;
-    stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_PAUSED;
-    stmt.params.autoResume = 0; // DONT_RESUME is 0
-    stmt.params.entityID = "foo" // just has to be non-null for our test
-    stmt.execute();
-    stmt.reset();
-  }
-  stmt.finalize();
-  stmt = null;
-  db.close();
-  db = null;
-
-  // Check to make sure it's all there
-  for (let i = 0; i < data.length; i++)
-    check_active_download(data[i].source, true);
-
-  // Dispatch the remove call
-  pb.removeDataFromDomain("mozilla.org");
-
-  // And check our data
-  for (let i = 0; i < data.length; i++)
-    check_active_download(data[i].source, !data[i].removed);
-}
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -427,17 +427,17 @@
     0xa181af0d,                                      \
     0x68b8,                                          \
     0x4308,                                          \
     {0x94, 0xdb, 0xd4, 0xf8, 0x59, 0x05, 0x82, 0x15} \
 }
 
 // component implementing nsIPrivateBrowsingService
 #define NS_PRIVATE_BROWSING_SERVICE_CONTRACTID \
-    "@mozilla.org/privatebrowsing;1"
+    "@mozilla.org/privatebrowsing-wrapper;1"
 #define NS_PRIVATE_BROWSING_SERVICE_CID              \
 { /* c31f4883-839b-45f6-82ad-a6a9bc5ad599 */         \
     0xc31f4883,                                      \
     0x839b,                                          \
     0x45f6,                                          \
     {0x82, 0xad, 0xa6, 0xa9, 0xbc, 0x5a, 0xd5, 0x99} \
 }
 
--- a/toolkit/components/satchel/src/Makefile.in
+++ b/toolkit/components/satchel/src/Makefile.in
@@ -63,18 +63,16 @@ REQUIRES =	\
 		necko \
 		widget \
 		content \
 		locale \
 		unicharutil \
 		pref \
 		storage \
 		loginmgr \
-		js \
-		xpconnect \
 		$(NULL)
 
 CPPSRCS = nsFormFillController.cpp \
           nsStorageFormHistory.cpp \
           $(NULL)
 
 LOCAL_INCLUDES = \
 	-I$(srcdir)/../../build \
--- a/toolkit/components/satchel/src/nsStorageFormHistory.cpp
+++ b/toolkit/components/satchel/src/nsStorageFormHistory.cpp
@@ -61,18 +61,16 @@
 #include "nsVoidArray.h"
 #include "nsCOMArray.h"
 #include "mozStorageHelper.h"
 #include "mozStorageCID.h"
 #include "nsIAutoCompleteSimpleResult.h"
 #include "nsTArray.h"
 #include "nsIPrivateBrowsingService.h"
 #include "nsNetCID.h"
-#include "jsapi.h"
-#include "nsIJSContextStack.h"
 
 // The size of the database cache. This is the number of database PAGES that
 // can be cached in memory. Normally, pages are 1K unless the size has been
 // explicitly changed.
 //
 // 4MB should be much larger than normal form histories. Normal form histories
 // will be several hundered KB at most. If the form history is smaller, the
 // extra memory will never be allocated, so there is no penalty for larger
@@ -263,28 +261,19 @@ NS_IMETHODIMP
 nsFormHistory::AddEntry(const nsAString &aName, const nsAString &aValue)
 {
   // If the user is in private browsing mode, don't add any entry.
   nsresult rv;
   nsCOMPtr<nsIPrivateBrowsingService> pbs =
     do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
   if (pbs) {
     PRBool inPrivateBrowsing = PR_TRUE;
-    // Temporary fix for bug 472396: push a null js context on the context stack
-    // so that calls made through web page scripts succeed.
-    nsCOMPtr<nsIJSContextStack> stack =
-      do_GetService("@mozilla.org/js/xpc/ContextStack;1");
-    if (stack && NS_SUCCEEDED(stack->Push(nsnull))) {
-      rv = pbs->GetPrivateBrowsingEnabled(&inPrivateBrowsing);
-      if (NS_FAILED(rv))
-        inPrivateBrowsing = PR_TRUE; // err on the safe side if we fail
-      JSContext *cx;
-      stack->Pop(&cx);
-      NS_ASSERTION(cx == nsnull, "JSContextStack mismatch");
-    }
+    rv = pbs->GetPrivateBrowsingEnabled(&inPrivateBrowsing);
+    if (NS_FAILED(rv))
+      inPrivateBrowsing = PR_TRUE; // err on the safe side if we fail
     if (inPrivateBrowsing)
       return NS_OK;
   }
 
   if (!FormHistoryEnabled())
     return NS_OK;
 
   PRInt64 existingID = GetExistingEntryID(aName, aValue);