Bug 886907 - Remove old synchronous contentPrefService from the tree. r=adw
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 11 Aug 2017 23:29:55 +0900
changeset 647766 832df1d6017e762fa677b76373ff32cc229f4c6e
parent 647765 22aad1598498156460162c9264cf80be344b0fe0
child 647767 c570f065e0ade1bae026d5cf059305350496acfd
push id74539
push userbmo:mkelly@mozilla.com
push dateWed, 16 Aug 2017 22:39:32 +0000
reviewersadw
bugs886907
milestone57.0a1
Bug 886907 - Remove old synchronous contentPrefService from the tree. r=adw MozReview-Commit-ID: BZsB3FR3jHC
browser/base/content/test/static/browser_all_files_referenced.js
browser/installer/package-manifest.in
dom/html/HTMLInputElement.cpp
dom/interfaces/base/moz.build
dom/interfaces/base/nsIContentPrefService.idl
dom/interfaces/base/nsIContentPrefService2.idl
editor/composer/nsEditorSpellCheck.cpp
mobile/android/installer/package-manifest.in
toolkit/components/contentprefs/ContentPrefInstance.jsm
toolkit/components/contentprefs/ContentPrefService2.js
toolkit/components/contentprefs/ContentPrefService2.jsm
toolkit/components/contentprefs/ContentPrefService2.manifest
toolkit/components/contentprefs/moz.build
toolkit/components/contentprefs/nsContentPrefService.js
toolkit/components/contentprefs/nsContentPrefService.manifest
toolkit/components/contentprefs/tests/unit/.eslintrc.js
toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
toolkit/components/contentprefs/tests/unit/test_bug248970.js
toolkit/components/contentprefs/tests/unit/test_bug503971.js
toolkit/components/contentprefs/tests/unit/test_bug679784.js
toolkit/components/contentprefs/tests/unit/test_contentPrefs.js
toolkit/components/contentprefs/tests/unit/test_contentPrefsCache.js
toolkit/components/contentprefs/tests/unit/test_getPrefAsync.js
toolkit/components/contentprefs/tests/unit/test_stringGroups.js
toolkit/components/contentprefs/tests/unit/test_unusedGroupsAndSettings.js
toolkit/components/contentprefs/tests/unit/xpcshell.ini
toolkit/components/contentprefs/tests/unit_cps2/test_service.js
toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini
toolkit/modules/Services.jsm
toolkit/modules/tests/xpcshell/test_Services.js
toolkit/mozapps/downloads/DownloadLastDir.jsm
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -159,18 +159,16 @@ var whitelist = [
   {file: "chrome://mozapps/skin/plugins/pluginBlocked.png"},
   // Bug 1348558
   {file: "chrome://mozapps/skin/update/downloadButtons.png",
    platforms: ["linux"]},
   // Bug 1348559
   {file: "chrome://pippki/content/resetpassword.xul"},
   // Bug 1351078
   {file: "resource://gre/modules/Battery.jsm"},
-  // Bug 1351070
-  {file: "resource://gre/modules/ContentPrefInstance.jsm"},
   // Bug 1351079
   {file: "resource://gre/modules/ISO8601DateUtils.jsm"},
   // Bug 1337345
   {file: "resource://gre/modules/Manifest.jsm"},
   // Bug 1351097
   {file: "resource://gre/modules/accessibility/AccessFu.jsm"},
   // Bug 1351637
   {file: "resource://gre/modules/sdk/bootstrap.js"},
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -459,18 +459,18 @@
 @RESPATH@/components/PageIconProtocolHandler.js
 @RESPATH@/components/PlacesCategoriesStarter.js
 @RESPATH@/components/ColorAnalyzer.js
 @RESPATH@/components/PageThumbsProtocol.js
 @RESPATH@/components/mozProtocolHandler.js
 @RESPATH@/components/mozProtocolHandler.manifest
 @RESPATH@/components/nsDefaultCLH.manifest
 @RESPATH@/components/nsDefaultCLH.js
-@RESPATH@/components/nsContentPrefService.manifest
-@RESPATH@/components/nsContentPrefService.js
+@RESPATH@/components/ContentPrefService2.manifest
+@RESPATH@/components/ContentPrefService2.js
 @RESPATH@/components/nsContentDispatchChooser.manifest
 @RESPATH@/components/nsContentDispatchChooser.js
 @RESPATH@/components/nsHandlerService-json.manifest
 @RESPATH@/components/nsHandlerService-json.js
 @RESPATH@/components/nsHandlerService.manifest
 @RESPATH@/components/nsHandlerService.js
 @RESPATH@/components/nsWebHandlerApp.manifest
 @RESPATH@/components/nsWebHandlerApp.js
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -81,17 +81,17 @@
 
 // input type=file
 #include "mozilla/dom/FileSystemEntry.h"
 #include "mozilla/dom/FileSystem.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FileList.h"
 #include "nsIFile.h"
 #include "nsDirectoryServiceDefs.h"
-#include "nsIContentPrefService.h"
+#include "nsIContentPrefService2.h"
 #include "nsIMIMEService.h"
 #include "nsIObserverService.h"
 #include "nsIPopupWindowManager.h"
 #include "nsGlobalWindow.h"
 
 // input type=image
 #include "nsImageLoadingContent.h"
 #include "imgRequestProxy.h"
--- a/dom/interfaces/base/moz.build
+++ b/dom/interfaces/base/moz.build
@@ -7,17 +7,16 @@
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM")
 
 XPIDL_SOURCES += [
     'domstubs.idl',
     'nsIBrowser.idl',
     'nsIBrowserDOMWindow.idl',
     'nsIContentPermissionPrompt.idl',
-    'nsIContentPrefService.idl',
     'nsIContentPrefService2.idl',
     'nsIContentProcess.idl',
     'nsIContentURIGrouper.idl',
     'nsIDOMChromeWindow.idl',
     'nsIDOMClientRect.idl',
     'nsIDOMClientRectList.idl',
     'nsIDOMConstructor.idl',
     'nsIDOMCrypto.idl',
deleted file mode 100644
--- a/dom/interfaces/base/nsIContentPrefService.idl
+++ /dev/null
@@ -1,263 +0,0 @@
-/* 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 "nsISupports.idl"
-
-interface nsIVariant;
-interface nsIPropertyBag2;
-interface nsIContentURIGrouper;
-interface nsILoadContext;
-interface mozIStorageConnection;
-
-[scriptable, uuid(43635c53-b445-4c4e-8cc5-562697299b55)]
-interface nsIContentPrefObserver : nsISupports
-{
-  /**
-   * Called when a content pref is set to a different value.
-   *
-   * @param    aGroup      the group to which the pref belongs, or null
-   *                       if it's a global pref (applies to all sites)
-   * @param    aName       the name of the pref that was set
-   * @param    aValue      the new value of the pref
-   * @param    aIsPrivate  an optional flag determining whether the
-   *                       original context is private or not
-   */
-  void onContentPrefSet(in AString aGroup,
-                        in AString aName,
-                        in nsIVariant aValue,
-                        [optional] in boolean aIsPrivate);
-
-  /**
-   * Called when a content pref is removed.
-   *
-   * @param    aGroup      the group to which the pref belongs, or null
-   *                       if it's a global pref (applies to all sites)
-   * @param    aName       the name of the pref that was removed
-   * @param    aIsPrivate  an optional flag determining whether the
-   *                       original context is private or not
-   */
-  void onContentPrefRemoved(in AString aGroup,
-                            in AString aName,
-                            [optional] in boolean aIsPrivate);
-};
-
-[scriptable, function, uuid(c1b3d6df-5373-4606-8494-8bcf14a7fc62)]
-interface nsIContentPrefCallback : nsISupports
-{
-  void onResult(in nsIVariant aResult);
-};
-
-/**
- * @deprecated Please use nsIContentPrefService2 instead.
- */
-[scriptable, uuid(e3f772f3-023f-4b32-b074-36cf0fd5d414)]
-interface nsIContentPrefService : nsISupports
-{
-  /**
-   * Get a pref.
-   *
-   * Besides the regular string, integer, boolean, etc. values, this method
-   * may return null (nsIDataType::VTYPE_EMPTY), which means the pref is set
-   * to NULL in the database, as well as undefined (nsIDataType::VTYPE_VOID),
-   * which means there is no record for this pref in the database.
-   *
-   * This method can be called from content processes in electrolysis builds.
-   * We have a whitelist of values that can be read in such a way.
-   *
-   * @param    aGroup      the group for which to get the pref, as an nsIURI
-   *                       from which the hostname will be used, a string
-   *                       (typically in the format of a hostname), or null
-   *                       to get the global pref (applies to all sites)
-   * @param    aName       the name of the pref to get
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to search in memory or in
-   *                       permanent storage for it), obtained from a relevant
-   *                       window or channel.
-   * @param    aCallback   an optional nsIContentPrefCallback to receive the
-   *                       result. If desired, JavaScript callers can instead
-   *                       provide a function to call upon completion
-   *
-   * @returns  the value of the pref
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  nsIVariant getPref(in nsIVariant aGroup, in AString aName,
-                     in nsILoadContext aPrivacyContext,
-                     [optional] in nsIContentPrefCallback aCallback);
-
-  /**
-   * Set a pref.
-   *
-   * This method can be called from content processes in electrolysis builds.
-   * We have a whitelist of values that can be set in such a way.
-   *
-   * @param    aGroup      the group for which to set the pref, as an nsIURI
-   *                       from which the hostname will be used, a string
-   *                       (typically in the format of a hostname), or null
-   *                       to set the global pref (applies to all sites)
-   * @param    aName       the name of the pref to set
-   * @param    aValue      the new value of the pref
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to store it in memory or in
-   *                       permanent storage), obtained from a relevant
-   *                       window or channel.
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  void setPref(in nsIVariant aGroup, in AString aName, in nsIVariant aValue, in nsILoadContext aPrivacyContext);
-
-  /**
-   * Check whether or not a pref exists.
-   *
-   * @param    aGroup      the group for which to check for the pref, as an nsIURI
-   *                       from which the hostname will be used, a string
-   *                       (typically in the format of a hostname), or null
-   *                       to check for the global pref (applies to all sites)
-   * @param    aName       the name of the pref to check for
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to search in memory or in
-   *                       permanent storage for it), obtained from a relevant
-   *                       window or channel.
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  boolean hasPref(in nsIVariant aGroup, in AString aName, in nsILoadContext aContext);
-
-  /**
-   * Check whether or not the value of a pref (or its non-existance) is cached.
-   *
-   * @param    aGroup      the group for which to check for the pref, as an nsIURI
-   *                       from which the hostname will be used, a string
-   *                       (typically in the format of a hostname), or null
-   *                       to check for the global pref (applies to all sites)
-   * @param    aName       the name of the pref to check for
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to search in memory or in
-   *                       permanent storage for it), obtained from a relevant
-   *                       window or channel.
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  boolean hasCachedPref(in nsIVariant aGroup, in AString aName, in nsILoadContext aContext);
-
-  /**
-   * Remove a pref.
-   *
-   * @param    aGroup      the group for which to remove the pref, as an nsIURI
-   *                       from which the hostname will be used, a string
-   *                       (typically in the format of a hostname), or null
-   *                       to remove the global pref (applies to all sites)
-   * @param    aName       the name of the pref to remove
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to search in memory or in
-   *                       permanent storage for it), obtained from a relevant
-   *                       window or channel.
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  void removePref(in nsIVariant aGroup, in AString aName, in nsILoadContext aContext);
-
-  /**
-   * Remove all grouped prefs.  Useful for removing references to the sites
-   * the user has visited when the user clears their private data.
-   *
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to remove prefs in memory or
-   *                       in permanent storage), obtained from a relevant
-   *                       window or channel.
-   */
-  void removeGroupedPrefs(in nsILoadContext aContext);
-
-  /**
-   * Remove all prefs with the given name.
-   *
-   * @param    aName        the setting name for which to remove prefs
-   * @param    aPrivacyContext
-   *                        a context from which to determine the privacy status
-   *                        of the prefs (ie. whether to remove prefs in memory or
-   *                        in permanent storage), obtained from a relevant
-   *                        window or channel.
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  void removePrefsByName(in AString aName, in nsILoadContext aContext);
-
-  /**
-   * Get the prefs that apply to the given site.
-   *
-   * @param    aGroup      the group for which to retrieve prefs, as an nsIURI
-   *                       from which the hostname will be used, a string
-   *                       (typically in the format of a hostname), or null
-   *                       to get the global prefs (apply to all sites)
-   * @param    aPrivacyContext
-   *                       a context from which to determine the privacy status
-   *                       of the pref (ie. whether to search for prefs in memory
-   *                       or in permanent storage), obtained from a relevant
-   *                       window or channel.
-   *
-   * @returns  a property bag of prefs
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aGroup is not a string, nsIURI, or null
-   */
-  nsIPropertyBag2 getPrefs(in nsIVariant aGroup, in nsILoadContext aContext);
-
-  /**
-   * Get the prefs with the given name.
-   *
-   * @param    aName        the setting name for which to retrieve prefs
-   * @param    aPrivacyContext
-   *                        a context from which to determine the privacy status
-   *                        of the pref (ie. whether to search for prefs in memory
-   *                        or in permanent storage), obtained from a relevant
-   *                        window or channel.
-   *
-   * @returns  a property bag of prefs
-   * @throws   NS_ERROR_ILLEGAL_VALUE if aName is null or an empty string
-   */
-  nsIPropertyBag2 getPrefsByName(in AString aName, in nsILoadContext aContext);
-
-  /**
-   * Add an observer.
-   *
-   * @param    aName       the setting to observe, or null to add
-   *                       a generic observer that observes all settings
-   * @param    aObserver   the observer to add
-   */
-  void addObserver(in AString aName, in nsIContentPrefObserver aObserver);
-
-  /**
-   * Remove an observer.
-   *
-   * @param    aName       the setting being observed, or null to remove
-   *                       a generic observer that observes all settings
-   * @param    aObserver   the observer to remove
-   */
-  void removeObserver(in AString aName, in nsIContentPrefObserver aObserver);
-
-  /**
-   * The component that the service uses to determine the groups to which
-   * URIs belong.  By default this is the "hostname grouper", which groups
-   * URIs by full hostname (a.k.a. site).
-   */
-  readonly attribute nsIContentURIGrouper grouper;
-
-  /**
-   * The database connection to the content preferences database.
-   * Useful for accessing and manipulating preferences in ways that are caller-
-   * specific or for which there is not yet a generic method, although generic
-   * functionality useful to multiple callers should generally be added to this
-   * unfrozen interface.  Also useful for testing the database creation
-   * and migration code.
-   */
-  readonly attribute mozIStorageConnection DBConnection;
-};
-
-%{C++
-// The contractID for the generic implementation built in to xpcom.
-#define NS_CONTENT_PREF_SERVICE_CONTRACTID "@mozilla.org/content-pref/service;1"
-%}
--- a/dom/interfaces/base/nsIContentPrefService2.idl
+++ b/dom/interfaces/base/nsIContentPrefService2.idl
@@ -1,20 +1,51 @@
 /* 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 "nsISupports.idl"
 
 interface nsIVariant;
-interface nsIContentPrefObserver;
 interface nsIContentPrefCallback2;
 interface nsILoadContext;
 interface nsIContentPref;
 
+[scriptable, uuid(43635c53-b445-4c4e-8cc5-562697299b55)]
+interface nsIContentPrefObserver : nsISupports
+{
+  /**
+   * Called when a content pref is set to a different value.
+   *
+   * @param    aGroup      the group to which the pref belongs, or null
+   *                       if it's a global pref (applies to all sites)
+   * @param    aName       the name of the pref that was set
+   * @param    aValue      the new value of the pref
+   * @param    aIsPrivate  an optional flag determining whether the
+   *                       original context is private or not
+   */
+  void onContentPrefSet(in AString aGroup,
+                        in AString aName,
+                        in nsIVariant aValue,
+                        [optional] in boolean aIsPrivate);
+
+  /**
+   * Called when a content pref is removed.
+   *
+   * @param    aGroup      the group to which the pref belongs, or null
+   *                       if it's a global pref (applies to all sites)
+   * @param    aName       the name of the pref that was removed
+   * @param    aIsPrivate  an optional flag determining whether the
+   *                       original context is private or not
+   */
+  void onContentPrefRemoved(in AString aGroup,
+                            in AString aName,
+                            [optional] in boolean aIsPrivate);
+};
+
 /**
  * Content Preferences
  *
  * Content preferences allow the application to associate arbitrary data, or
  * "preferences", with specific domains, or web "content".  Specifically, a
  * content preference is a structure with three values: a domain with which the
  * preference is associated, a name that identifies the preference within its
  * domain, and a value.  (See nsIContentPref below.)
@@ -398,8 +429,13 @@ interface nsIContentPrefCallback2 : nsIS
 
 [scriptable, function, uuid(9f24948d-24b5-4b1b-b554-7dbd58c1d792)]
 interface nsIContentPref : nsISupports
 {
   readonly attribute AString domain;
   readonly attribute AString name;
   readonly attribute nsIVariant value;
 };
+
+%{C++
+// The contractID for the generic implementation built in to xpcom.
+#define NS_CONTENT_PREF_SERVICE_CONTRACTID "@mozilla.org/content-pref/service;1"
+%}
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -14,17 +14,16 @@
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAString.h"                  // for nsAString::IsEmpty, etc
 #include "nsComponentManagerUtils.h"    // for do_CreateInstance
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsDependentSubstring.h"       // for Substring
 #include "nsEditorSpellCheck.h"
 #include "nsError.h"                    // for NS_ERROR_NOT_INITIALIZED, etc
 #include "nsIContent.h"                 // for nsIContent
-#include "nsIContentPrefService.h"      // for nsIContentPrefService, etc
 #include "nsIContentPrefService2.h"     // for nsIContentPrefService2, etc
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor
 #include "nsILoadContext.h"
 #include "nsISelection.h"               // for nsISelection
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -328,18 +328,18 @@
 @BINPATH@/components/pluginGlue.manifest
 @BINPATH@/components/ProcessSingleton.manifest
 @BINPATH@/components/MainProcessSingleton.js
 @BINPATH@/components/ContentProcessSingleton.js
 @BINPATH@/components/nsURLFormatter.manifest
 @BINPATH@/components/nsURLFormatter.js
 @BINPATH@/components/txEXSLTRegExFunctions.manifest
 @BINPATH@/components/txEXSLTRegExFunctions.js
-@BINPATH@/components/nsContentPrefService.manifest
-@BINPATH@/components/nsContentPrefService.js
+@BINPATH@/components/ContentPrefService2.manifest
+@BINPATH@/components/ContentPrefService2.js
 @BINPATH@/components/nsHandlerService-json.manifest
 @BINPATH@/components/nsHandlerService-json.js
 @BINPATH@/components/nsHandlerService.manifest
 @BINPATH@/components/nsHandlerService.js
 @BINPATH@/components/nsWebHandlerApp.manifest
 @BINPATH@/components/nsWebHandlerApp.js
 @BINPATH@/components/satchel.manifest
 @BINPATH@/components/nsFormAutoComplete.js
deleted file mode 100644
--- a/toolkit/components/contentprefs/ContentPrefInstance.jsm
+++ /dev/null
@@ -1,79 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-this.EXPORTED_SYMBOLS = ["ContentPrefInstance"];
-
-// This is a wrapper for nsIContentPrefService that alleviates the need to pass
-// an nsILoadContext argument to every method. Pass the context to the constructor
-// instead and continue on your way in blissful ignorance.
-
-this.ContentPrefInstance = function ContentPrefInstance(aContext) {
-  this._contentPrefSvc = Cc["@mozilla.org/content-pref/service;1"].
-                           getService(Ci.nsIContentPrefService);
-  this._context = aContext;
-};
-
-ContentPrefInstance.prototype = {
-  getPref: function ContentPrefInstance_init(aName, aGroup, aCallback) {
-    return this._contentPrefSvc.getPref(aName, aGroup, this._context, aCallback);
-  },
-
-  setPref: function ContentPrefInstance_setPref(aGroup, aName, aValue, aContext) {
-    return this._contentPrefSvc.setPref(aGroup, aName, aValue,
-                                        aContext ? aContext : this._context);
-  },
-
-  hasPref: function ContentPrefInstance_hasPref(aGroup, aName) {
-    return this._contentPrefSvc.hasPref(aGroup, aName, this._context);
-  },
-
-  hasCachedPref: function ContentPrefInstance_hasCachedPref(aGroup, aName) {
-    return this._contentPrefSvc.hasCachedPref(aGroup, aName, this._context);
-  },
-
-  removePref: function ContentPrefInstance_removePref(aGroup, aName) {
-    return this._contentPrefSvc.removePref(aGroup, aName, this._context);
-  },
-
-  removeGroupedPrefs: function ContentPrefInstance_removeGroupedPrefs() {
-    return this._contentPrefSvc.removeGroupedPrefs(this._context);
-  },
-
-  removePrefsByName: function ContentPrefInstance_removePrefsByName(aName) {
-    return this._contentPrefSvc.removePrefsByName(aName, this._context);
-  },
-
-  getPrefs: function ContentPrefInstance_getPrefs(aGroup) {
-    return this._contentPrefSvc.getPrefs(aGroup, this._context);
-  },
-
-  getPrefsByName: function ContentPrefInstance_getPrefsByName(aName) {
-    return this._contentPrefSvc.getPrefsByName(aName, this._context);
-  },
-
-  addObserver: function ContentPrefInstance_addObserver(aName, aObserver) {
-    return this._contentPrefSvc.addObserver(aName, aObserver);
-  },
-
-  removeObserver: function ContentPrefInstance_removeObserver(aName, aObserver) {
-    return this._contentPrefSvc.removeObserver(aName, aObserver);
-  },
-
-  get grouper() {
-    return this._contentPrefSvc.grouper;
-  },
-
-  get DBConnection() {
-    return this._contentPrefSvc.DBConnection;
-  },
-
-  set loadContext(aLoadContext) {
-    this._context = aLoadContext;
-  }
-};
rename from toolkit/components/contentprefs/ContentPrefService2.jsm
rename to toolkit/components/contentprefs/ContentPrefService2.js
--- a/toolkit/components/contentprefs/ContentPrefService2.jsm
+++ b/toolkit/components/contentprefs/ContentPrefService2.js
@@ -1,56 +1,119 @@
 /* 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 file is an XPCOM component that implements nsIContentPrefService2.
-// Although it's a JSM, it's not intended to be imported by consumers like JSMs
-// are usually imported.  It's only a JSM so that nsContentPrefService.js can
-// easily use it.  Consumers should access this component with the usual XPCOM
-// rigmarole:
-//
-//   Cc["@mozilla.org/content-pref/service;1"].
-//   getService(Ci.nsIContentPrefService2);
-//
-// That contract ID actually belongs to nsContentPrefService.js, which, when
-// QI'ed to nsIContentPrefService2, returns an instance of this component.
-//
-// The plan is to eventually remove nsIContentPrefService and its
-// implementation, nsContentPrefService.js.  At such time this file can stop
-// being a JSM, and the "_cps" parts that ContentPrefService2 relies on and
-// NSGetFactory and all the other XPCOM initialization goop in
-// nsContentPrefService.js can be moved here.
-//
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=699859
-
-var EXPORTED_SYMBOLS = [
-  "ContentPrefService2",
-];
-
 const { interfaces: Ci, classes: Cc, results: Cr, utils: Cu } = Components;
 
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ContentPrefUtils.jsm");
 Cu.import("resource://gre/modules/ContentPrefStore.jsm");
 
+const CACHE_MAX_GROUP_ENTRIES = 100;
+
 const GROUP_CLAUSE = `
   SELECT id
   FROM groups
   WHERE name = :group OR
         (:includeSubdomains AND name LIKE :pattern ESCAPE '/')
 `;
 
-function ContentPrefService2(cps) {
-  this._cps = cps;
-  this._cache = cps._cache;
-  this._pbStore = cps._privModeStorage;
+function ContentPrefService2() {
+  if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
+    return Cu.import("resource://gre/modules/ContentPrefServiceChild.jsm")
+             .ContentPrefServiceChild;
+  }
+
+  // If this throws an exception, it causes the getService call to fail,
+  // but the next time a consumer tries to retrieve the service, we'll try
+  // to initialize the database again, which might work if the failure
+  // was due to a temporary condition (like being out of disk space).
+  this._dbInit();
+
+  this._observerSvc.addObserver(this, "last-pb-context-exited");
+
+  // Observe shutdown so we can shut down the database connection.
+  this._observerSvc.addObserver(this, "xpcom-shutdown");
 }
 
+const cache = new ContentPrefStore();
+cache.set = function CPS_cache_set(group, name, val) {
+  Object.getPrototypeOf(this).set.apply(this, arguments);
+  let groupCount = this._groups.size;
+  if (groupCount >= CACHE_MAX_GROUP_ENTRIES) {
+    // Clean half of the entries
+    for (let [group, name, ] of this) {
+      this.remove(group, name);
+      groupCount--;
+      if (groupCount < CACHE_MAX_GROUP_ENTRIES / 2)
+        break;
+    }
+  }
+};
+
+const privModeStorage = new ContentPrefStore();
+
 ContentPrefService2.prototype = {
+  // XPCOM Plumbing
+
+  classID: Components.ID("{e3f772f3-023f-4b32-b074-36cf0fd5d414}"),
+
+  // Convenience Getters
+
+  // Observer Service
+  __observerSvc: null,
+  get _observerSvc() {
+    if (!this.__observerSvc)
+      this.__observerSvc = Cc["@mozilla.org/observer-service;1"].
+                           getService(Ci.nsIObserverService);
+    return this.__observerSvc;
+  },
+
+  // Preferences Service
+  __prefSvc: null,
+  get _prefSvc() {
+    if (!this.__prefSvc)
+      this.__prefSvc = Cc["@mozilla.org/preferences-service;1"].
+                       getService(Ci.nsIPrefBranch);
+    return this.__prefSvc;
+  },
+
+
+  // Destruction
+
+  _destroy: function ContentPrefService__destroy() {
+    this._observerSvc.removeObserver(this, "xpcom-shutdown");
+    this._observerSvc.removeObserver(this, "last-pb-context-exited");
+
+    this.destroy();
+
+    this._dbConnection.asyncClose(() => {
+      Services.obs.notifyObservers(null, "content-prefs-db-closed");
+    });
+
+    // Delete references to XPCOM components to make sure we don't leak them
+    // (although we haven't observed leakage in tests).  Also delete references
+    // in _observers and _genericObservers to avoid cycles with those that
+    // refer to us and don't remove themselves from those observer pools.
+    delete this._observers;
+    delete this._genericObservers;
+    delete this.__grouper;
+    delete this.__observerSvc;
+    delete this.__prefSvc;
+  },
+
+
+  // in-memory cache and private-browsing stores
+
+  _cache: cache,
+  _pbStore: privModeStorage,
+
+  // nsIContentPrefService
 
   getByName: function CPS2_getByName(name, context, callback) {
     checkNameArg(name);
     checkCallbackArg(callback, true);
 
     // Some prefs may be in both the database and the private browsing store.
     // Notify the caller of such prefs only once, using the values from private
     // browsing.
@@ -249,17 +312,17 @@ ContentPrefService2.prototype = {
     checkNameArg(name);
     checkValueArg(value);
     checkCallbackArg(callback, false);
 
     if (context && context.usePrivateBrowsing) {
       this._pbStore.set(group, name, value);
       this._schedule(function() {
         cbHandleCompletion(callback, Ci.nsIContentPrefCallback2.COMPLETE_OK);
-        this._cps._notifyPrefSet(group, name, value, context.usePrivateBrowsing);
+        this._notifyPrefSet(group, name, value, context.usePrivateBrowsing);
       });
       return;
     }
 
     // Invalidate the cached value so consumers accessing the cache between now
     // and when the operation finishes don't get old data.
     this._cache.remove(group, name);
 
@@ -321,17 +384,17 @@ ContentPrefService2.prototype = {
     stmts.push(stmt);
 
     this._execStmts(stmts, {
       onDone: function onDone(reason, ok) {
         if (ok)
           this._cache.setWithCast(group, name, value);
         cbHandleCompletion(callback, reason);
         if (ok)
-          this._cps._notifyPrefSet(group, name, value, context && context.usePrivateBrowsing);
+          this._notifyPrefSet(group, name, value, context && context.usePrivateBrowsing);
       },
       onError: function onError(nsresult) {
         cbHandleError(callback, nsresult);
       }
     });
   },
 
   removeByDomainAndName: function CPS2_removeByDomainAndName(group, name,
@@ -401,17 +464,17 @@ ContentPrefService2.prototype = {
               prefs.set(sgroup, name, undefined);
               this._pbStore.remove(sgroup, name);
             }
           }
         }
         cbHandleCompletion(callback, reason);
         if (ok) {
           for (let [sgroup, , ] of prefs) {
-            this._cps._notifyPrefRemoved(sgroup, name, isPrivate);
+            this._notifyPrefRemoved(sgroup, name, isPrivate);
           }
         }
       },
       onError: function onError(nsresult) {
         cbHandleError(callback, nsresult);
       }
     });
   },
@@ -514,17 +577,17 @@ ContentPrefService2.prototype = {
               prefs.set(sgroup, sname, undefined);
               this._pbStore.remove(sgroup, sname);
             }
           }
         }
         cbHandleCompletion(callback, reason);
         if (ok) {
           for (let [sgroup, sname, ] of prefs) {
-            this._cps._notifyPrefRemoved(sgroup, sname, isPrivate);
+            this._notifyPrefRemoved(sgroup, sname, isPrivate);
           }
         }
       },
       onError: function onError(nsresult) {
         cbHandleError(callback, nsresult);
       }
     });
   },
@@ -580,17 +643,17 @@ ContentPrefService2.prototype = {
               prefs.set(sgroup, sname, undefined);
             }
           }
           this._pbStore.removeAllGroups();
         }
         cbHandleCompletion(callback, reason);
         if (ok) {
           for (let [sgroup, sname, ] of prefs) {
-            this._cps._notifyPrefRemoved(sgroup, sname, isPrivate);
+            this._notifyPrefRemoved(sgroup, sname, isPrivate);
           }
         }
       },
       onError: function onError(nsresult) {
         cbHandleError(callback, nsresult);
       }
     });
   },
@@ -669,17 +732,17 @@ ContentPrefService2.prototype = {
               prefs.set(sgroup, name, undefined);
               this._pbStore.remove(sgroup, name);
             }
           }
         }
         cbHandleCompletion(callback, reason);
         if (ok) {
           for (let [sgroup, , ] of prefs) {
-            this._cps._notifyPrefRemoved(sgroup, name, isPrivate);
+            this._notifyPrefRemoved(sgroup, name, isPrivate);
           }
         }
       },
       onError: function onError(nsresult) {
         cbHandleError(callback, nsresult);
       }
     });
   },
@@ -699,17 +762,17 @@ ContentPrefService2.prototype = {
    *
    * @param sql  The SQL query string.
    * @return     The cached, possibly new, statement.
    */
   _stmt: function CPS2__stmt(sql) {
     if (!this._statements)
       this._statements = {};
     if (!this._statements[sql])
-      this._statements[sql] = this._cps._dbConnection.createAsyncStatement(sql);
+      this._statements[sql] = this._dbConnection.createAsyncStatement(sql);
     return this._statements[sql];
   },
 
   /**
    * Executes some async statements.
    *
    * @param stmts      An array of mozIStorageAsyncStatements.
    * @param callbacks  An object with the following methods:
@@ -723,17 +786,17 @@ ContentPrefService2.prototype = {
    *                     didGetRow: True if onRow was ever called.
    *                   onError(nsresult) (optional)
    *                     Called on error.
    *                     nsresult: The error code.
    */
   _execStmts: function CPS2__execStmts(stmts, callbacks) {
     let self = this;
     let gotRow = false;
-    this._cps._dbConnection.executeAsync(stmts, stmts.length, {
+    this._dbConnection.executeAsync(stmts, stmts.length, {
       handleResult: function handleResult(results) {
         try {
           let row = null;
           while ((row = results.getNextRow())) {
             gotRow = true;
             if (callbacks.onRow)
               callbacks.onRow.call(self, row);
           }
@@ -758,16 +821,24 @@ ContentPrefService2.prototype = {
             callbacks.onError.call(self, Cr.NS_ERROR_FAILURE);
         } catch (err) {
           Cu.reportError(err);
         }
       }
     });
   },
 
+  __grouper: null,
+  get _grouper() {
+    if (!this.__grouper)
+      this.__grouper = Cc["@mozilla.org/content-pref/hostname-grouper;1"].
+                       getService(Ci.nsIContentURIGrouper);
+    return this.__grouper;
+  },
+
   /**
    * Parses the domain (the "group", to use the database's term) from the given
    * string.
    *
    * @param groupStr  Assumed to be either a string or falsey.
    * @return          If groupStr is a valid URL string, returns the domain of
    *                  that URL.  If groupStr is some other nonempty string,
    *                  returns groupStr itself.  Otherwise returns null.
@@ -775,85 +846,378 @@ ContentPrefService2.prototype = {
   _parseGroup: function CPS2__parseGroup(groupStr) {
     if (!groupStr)
       return null;
     try {
       var groupURI = Services.io.newURI(groupStr);
     } catch (err) {
       return groupStr;
     }
-    return this._cps._grouper.group(groupURI);
+    return this._grouper.group(groupURI);
   },
 
   _schedule: function CPS2__schedule(fn) {
     Services.tm.dispatchToMainThread(fn.bind(this));
   },
 
-  addObserverForName: function CPS2_addObserverForName(name, observer) {
-    this._cps._addObserver(name, observer);
+  // A hash of arrays of observers, indexed by setting name.
+  _observers: {},
+
+  // An array of generic observers, which observe all settings.
+  _genericObservers: [],
+
+  addObserverForName: function CPS2_addObserverForName(aName, aObserver) {
+    var observers;
+    if (aName) {
+      if (!this._observers[aName])
+        this._observers[aName] = [];
+      observers = this._observers[aName];
+    } else
+      observers = this._genericObservers;
+
+    if (observers.indexOf(aObserver) == -1)
+      observers.push(aObserver);
+  },
+
+  removeObserverForName: function CPS2_removeObserverForName(aName, aObserver) {
+    var observers;
+    if (aName) {
+      if (!this._observers[aName])
+        return;
+      observers = this._observers[aName];
+    } else
+      observers = this._genericObservers;
+
+    if (observers.indexOf(aObserver) != -1)
+      observers.splice(observers.indexOf(aObserver), 1);
   },
 
-  removeObserverForName: function CPS2_removeObserverForName(name, observer) {
-    this._cps._removeObserver(name, observer);
+  /**
+   * Construct a list of observers to notify about a change to some setting,
+   * putting setting-specific observers before before generic ones, so observers
+   * that initialize individual settings (like the page style controller)
+   * execute before observers that display multiple settings and depend on them
+   * being initialized first (like the content prefs sidebar).
+   */
+  _getObservers: function ContentPrefService__getObservers(aName) {
+    var observers = [];
+
+    if (aName && this._observers[aName])
+      observers = observers.concat(this._observers[aName]);
+    observers = observers.concat(this._genericObservers);
+
+    return observers;
+  },
+
+  /**
+   * Notify all observers about the removal of a preference.
+   */
+  _notifyPrefRemoved: function ContentPrefService__notifyPrefRemoved(aGroup, aName, aIsPrivate) {
+    for (var observer of this._getObservers(aName)) {
+      try {
+        observer.onContentPrefRemoved(aGroup, aName, aIsPrivate);
+      } catch (ex) {
+        Cu.reportError(ex);
+      }
+    }
+  },
+
+  /**
+   * Notify all observers about a preference change.
+   */
+  _notifyPrefSet: function ContentPrefService__notifyPrefSet(aGroup, aName, aValue, aIsPrivate) {
+    for (var observer of this._getObservers(aName)) {
+      try {
+        observer.onContentPrefSet(aGroup, aName, aValue, aIsPrivate);
+      } catch (ex) {
+        Cu.reportError(ex);
+      }
+    }
   },
 
   extractDomain: function CPS2_extractDomain(str) {
     return this._parseGroup(str);
   },
 
   /**
    * Tests use this as a backchannel by calling it directly.
    *
    * @param subj   This value depends on topic.
    * @param topic  The backchannel "method" name.
    * @param data   This value depends on topic.
    */
   observe: function CPS2_observe(subj, topic, data) {
     switch (topic) {
+    case "xpcom-shutdown":
+      this._destroy();
+      break;
+    case "last-pb-context-exited":
+      this._pbStore.removeAll();
+      break;
     case "test:reset":
       let fn = subj.QueryInterface(Ci.xpcIJSWeakReference).get();
       this._reset(fn);
       break;
     case "test:db":
       let obj = subj.QueryInterface(Ci.xpcIJSWeakReference).get();
-      obj.value = this._cps._dbConnection;
+      obj.value = this._dbConnection;
       break;
     }
   },
 
   /**
    * Removes all state from the service.  Used by tests.
    *
    * @param callback  A function that will be called when done.
    */
   _reset: function CPS2__reset(callback) {
     this._pbStore.removeAll();
     this._cache.removeAll();
 
-    let cps = this._cps;
-    cps._observers = {};
-    cps._genericObservers = [];
+    this._observers = {};
+    this._genericObservers = [];
 
     let tables = ["prefs", "groups", "settings"];
     let stmts = tables.map(t => this._stmt(`DELETE FROM ${t}`));
     this._execStmts(stmts, { onDone: () => callback() });
   },
 
   QueryInterface: function CPS2_QueryInterface(iid) {
     let supportedIIDs = [
       Ci.nsIContentPrefService2,
       Ci.nsIObserver,
       Ci.nsISupports,
     ];
     if (supportedIIDs.some(i => iid.equals(i)))
       return this;
-    if (iid.equals(Ci.nsIContentPrefService))
-      return this._cps;
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
+
+
+  // Database Creation & Access
+
+  _dbVersion: 4,
+
+  _dbSchema: {
+    tables: {
+      groups:     "id           INTEGER PRIMARY KEY, \
+                   name         TEXT NOT NULL",
+
+      settings:   "id           INTEGER PRIMARY KEY, \
+                   name         TEXT NOT NULL",
+
+      prefs:      "id           INTEGER PRIMARY KEY, \
+                   groupID      INTEGER REFERENCES groups(id), \
+                   settingID    INTEGER NOT NULL REFERENCES settings(id), \
+                   value        BLOB, \
+                   timestamp    INTEGER NOT NULL DEFAULT 0" // Storage in seconds, API in ms. 0 for migrated values.
+    },
+    indices: {
+      groups_idx: {
+        table: "groups",
+        columns: ["name"]
+      },
+      settings_idx: {
+        table: "settings",
+        columns: ["name"]
+      },
+      prefs_idx: {
+        table: "prefs",
+        columns: ["timestamp", "groupID", "settingID"]
+      }
+    }
+  },
+
+  _dbConnection: null,
+
+  // _dbInit and the methods it calls (_dbCreate, _dbMigrate, and version-
+  // specific migration methods) must be careful not to call any method
+  // of the service that assumes the database connection has already been
+  // initialized, since it won't be initialized until at the end of _dbInit.
+
+  _dbInit: function ContentPrefService__dbInit() {
+    var dirService = Cc["@mozilla.org/file/directory_service;1"].
+                     getService(Ci.nsIProperties);
+    var dbFile = dirService.get("ProfD", Ci.nsIFile);
+    dbFile.append("content-prefs.sqlite");
+
+    var dbService = Cc["@mozilla.org/storage/service;1"].
+                    getService(Ci.mozIStorageService);
+
+    var dbConnection;
+
+    if (!dbFile.exists())
+      dbConnection = this._dbCreate(dbService, dbFile);
+    else {
+      try {
+        dbConnection = dbService.openDatabase(dbFile);
+      } catch (e) {
+        // If the connection isn't ready after we open the database, that means
+        // the database has been corrupted, so we back it up and then recreate it.
+        if (e.result != Cr.NS_ERROR_FILE_CORRUPTED)
+          throw e;
+        dbConnection = this._dbBackUpAndRecreate(dbService, dbFile,
+                                                 dbConnection);
+      }
+
+      // Get the version of the schema in the file.
+      var version = dbConnection.schemaVersion;
+
+      // Try to migrate the schema in the database to the current schema used by
+      // the service.  If migration fails, back up the database and recreate it.
+      if (version != this._dbVersion) {
+        try {
+          this._dbMigrate(dbConnection, version, this._dbVersion);
+        } catch (ex) {
+          Cu.reportError("error migrating DB: " + ex + "; backing up and recreating");
+          dbConnection = this._dbBackUpAndRecreate(dbService, dbFile, dbConnection);
+        }
+      }
+    }
+
+    // Turn off disk synchronization checking to reduce disk churn and speed up
+    // operations when prefs are changed rapidly (such as when a user repeatedly
+    // changes the value of the browser zoom setting for a site).
+    //
+    // Note: this could cause database corruption if the OS crashes or machine
+    // loses power before the data gets written to disk, but this is considered
+    // a reasonable risk for the not-so-critical data stored in this database.
+    //
+    // If you really don't want to take this risk, however, just set the
+    // toolkit.storage.synchronous pref to 1 (NORMAL synchronization) or 2
+    // (FULL synchronization), in which case mozStorageConnection::Initialize
+    // will use that value, and we won't override it here.
+    if (!this._prefSvc.prefHasUserValue("toolkit.storage.synchronous"))
+      dbConnection.executeSimpleSQL("PRAGMA synchronous = OFF");
+
+    this._dbConnection = dbConnection;
+  },
+
+  _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
+    var dbConnection = aDBService.openDatabase(aDBFile);
+
+    try {
+      this._dbCreateSchema(dbConnection);
+      dbConnection.schemaVersion = this._dbVersion;
+    } catch (ex) {
+      // If we failed to create the database (perhaps because the disk ran out
+      // of space), then remove the database file so we don't leave it in some
+      // half-created state from which we won't know how to recover.
+      dbConnection.close();
+      aDBFile.remove(false);
+      throw ex;
+    }
+
+    return dbConnection;
+  },
+
+  _dbCreateSchema: function ContentPrefService__dbCreateSchema(aDBConnection) {
+    this._dbCreateTables(aDBConnection);
+    this._dbCreateIndices(aDBConnection);
+  },
+
+  _dbCreateTables: function ContentPrefService__dbCreateTables(aDBConnection) {
+    for (let name in this._dbSchema.tables)
+      aDBConnection.createTable(name, this._dbSchema.tables[name]);
+  },
+
+  _dbCreateIndices: function ContentPrefService__dbCreateIndices(aDBConnection) {
+    for (let name in this._dbSchema.indices) {
+      let index = this._dbSchema.indices[name];
+      let statement = `
+        CREATE INDEX IF NOT EXISTS ${name} ON ${index.table}
+        (${index.columns.join(", ")})
+      `;
+      aDBConnection.executeSimpleSQL(statement);
+    }
+  },
+
+  _dbBackUpAndRecreate: function ContentPrefService__dbBackUpAndRecreate(aDBService,
+                                                                         aDBFile,
+                                                                         aDBConnection) {
+    aDBService.backupDatabaseFile(aDBFile, "content-prefs.sqlite.corrupt");
+
+    // Close the database, ignoring the "already closed" exception, if any.
+    // It'll be open if we're here because of a migration failure but closed
+    // if we're here because of database corruption.
+    try { aDBConnection.close() } catch (ex) {}
+
+    aDBFile.remove(false);
+
+    let dbConnection = this._dbCreate(aDBService, aDBFile);
+
+    return dbConnection;
+  },
+
+  _dbMigrate: function ContentPrefService__dbMigrate(aDBConnection, aOldVersion, aNewVersion) {
+    /**
+     * Migrations should follow the template rules in bug 1074817 comment 3 which are:
+     * 1. Migration should be incremental and non-breaking.
+     * 2. It should be idempotent because one can downgrade an upgrade again.
+     * On downgrade:
+     * 1. Decrement schema version so that upgrade runs the migrations again.
+     */
+    aDBConnection.beginTransaction();
+
+    try {
+       /**
+       * If the schema version is 0, that means it was never set, which means
+       * the database was somehow created without the schema being applied, perhaps
+       * because the system ran out of disk space (although we check for this
+       * in _createDB) or because some other code created the database file without
+       * applying the schema.  In any case, recover by simply reapplying the schema.
+       */
+      if (aOldVersion == 0) {
+        this._dbCreateSchema(aDBConnection);
+      } else {
+        for (let i = aOldVersion; i < aNewVersion; i++) {
+          let migrationName = "_dbMigrate" + i + "To" + (i + 1);
+          if (typeof this[migrationName] != "function") {
+            throw ("no migrator function from version " + aOldVersion + " to version " + aNewVersion);
+          }
+          this[migrationName](aDBConnection);
+        }
+      }
+      aDBConnection.schemaVersion = aNewVersion;
+      aDBConnection.commitTransaction();
+    } catch (ex) {
+      aDBConnection.rollbackTransaction();
+      throw ex;
+    }
+  },
+
+  _dbMigrate1To2: function ContentPrefService___dbMigrate1To2(aDBConnection) {
+    aDBConnection.executeSimpleSQL("ALTER TABLE groups RENAME TO groupsOld");
+    aDBConnection.createTable("groups", this._dbSchema.tables.groups);
+    aDBConnection.executeSimpleSQL(`
+      INSERT INTO groups (id, name)
+      SELECT id, name FROM groupsOld
+    `);
+
+    aDBConnection.executeSimpleSQL("DROP TABLE groupers");
+    aDBConnection.executeSimpleSQL("DROP TABLE groupsOld");
+  },
+
+  _dbMigrate2To3: function ContentPrefService__dbMigrate2To3(aDBConnection) {
+    this._dbCreateIndices(aDBConnection);
+  },
+
+  _dbMigrate3To4: function ContentPrefService__dbMigrate3To4(aDBConnection) {
+    // Add timestamp column if it does not exist yet. This operation is idempotent.
+    try {
+      let stmt = aDBConnection.createStatement("SELECT timestamp FROM prefs");
+      stmt.finalize();
+    } catch (e) {
+      aDBConnection.executeSimpleSQL("ALTER TABLE prefs ADD COLUMN timestamp INTEGER NOT NULL DEFAULT 0");
+    }
+
+    // To modify prefs_idx drop it and create again.
+    aDBConnection.executeSimpleSQL("DROP INDEX IF EXISTS prefs_idx");
+    this._dbCreateIndices(aDBConnection);
+  },
 };
 
 function checkGroupArg(group) {
   if (!group || typeof(group) != "string")
     throw invalidArg("domain must be nonempty string.");
 }
 
 function checkNameArg(name) {
@@ -871,8 +1235,61 @@ function checkCallbackArg(callback, requ
     throw invalidArg("callback must be an nsIContentPrefCallback2.");
   if (!callback && required)
     throw invalidArg("callback must be given.");
 }
 
 function invalidArg(msg) {
   return Components.Exception(msg, Cr.NS_ERROR_INVALID_ARG);
 }
+
+
+function HostnameGrouper() {}
+
+HostnameGrouper.prototype = {
+  // XPCOM Plumbing
+
+  classID:          Components.ID("{8df290ae-dcaa-4c11-98a5-2429a4dc97bb}"),
+  QueryInterface:   XPCOMUtils.generateQI([Ci.nsIContentURIGrouper]),
+
+  // nsIContentURIGrouper
+
+  group: function HostnameGrouper_group(aURI) {
+    var group;
+
+    try {
+      // Accessing the host property of the URI will throw an exception
+      // if the URI is of a type that doesn't have a host property.
+      // Otherwise, we manually throw an exception if the host is empty,
+      // since the effect is the same (we can't derive a group from it).
+
+      group = aURI.host;
+      if (!group)
+        throw ("can't derive group from host; no host in URI");
+    } catch (ex) {
+      // If we don't have a host, then use the entire URI (minus the query,
+      // reference, and hash, if possible) as the group.  This means that URIs
+      // like about:mozilla and about:blank will be considered separate groups,
+      // but at least they'll be grouped somehow.
+
+      // This also means that each individual file: URL will be considered
+      // its own group.  This seems suboptimal, but so does treating the entire
+      // file: URL space as a single group (especially if folks start setting
+      // group-specific capabilities prefs).
+
+      // XXX Is there something better we can do here?
+
+      try {
+        var url = aURI.QueryInterface(Ci.nsIURL);
+        group = aURI.prePath + url.filePath;
+      } catch (ex) {
+        group = aURI.spec;
+      }
+    }
+
+    return group;
+  }
+};
+
+// XPCOM Plumbing
+
+var components = [ContentPrefService2, HostnameGrouper];
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
rename from toolkit/components/contentprefs/nsContentPrefService.manifest
rename to toolkit/components/contentprefs/ContentPrefService2.manifest
--- a/toolkit/components/contentprefs/nsContentPrefService.manifest
+++ b/toolkit/components/contentprefs/ContentPrefService2.manifest
@@ -1,5 +1,5 @@
-component {e3f772f3-023f-4b32-b074-36cf0fd5d414} nsContentPrefService.js
+component {e3f772f3-023f-4b32-b074-36cf0fd5d414} ContentPrefService2.js
 contract @mozilla.org/content-pref/service;1 {e3f772f3-023f-4b32-b074-36cf0fd5d414}
-component {8df290ae-dcaa-4c11-98a5-2429a4dc97bb} nsContentPrefService.js
+component {8df290ae-dcaa-4c11-98a5-2429a4dc97bb} ContentPrefService2.js
 contract @mozilla.org/content-pref/hostname-grouper;1 {8df290ae-dcaa-4c11-98a5-2429a4dc97bb}
 
--- a/toolkit/components/contentprefs/moz.build
+++ b/toolkit/components/contentprefs/moz.build
@@ -1,31 +1,28 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # 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/.
 
 XPCSHELL_TESTS_MANIFESTS += [
-    'tests/unit/xpcshell.ini',
     'tests/unit_cps2/xpcshell.ini',
 ]
 
 MOCHITEST_MANIFESTS += [
     'tests/mochitest/mochitest.ini'
 ]
 
 EXTRA_COMPONENTS += [
-    'nsContentPrefService.js',
-    'nsContentPrefService.manifest',
+    'ContentPrefService2.js',
+    'ContentPrefService2.manifest',
 ]
 
 EXTRA_JS_MODULES += [
-    'ContentPrefInstance.jsm',
-    'ContentPrefService2.jsm',
     'ContentPrefServiceChild.jsm',
     'ContentPrefServiceParent.jsm',
     'ContentPrefStore.jsm',
     'ContentPrefUtils.jsm',
 ]
 
 with Files('**'):
     BUG_COMPONENT = ('Toolkit', 'Preferences')
deleted file mode 100644
--- a/toolkit/components/contentprefs/nsContentPrefService.js
+++ /dev/null
@@ -1,1309 +0,0 @@
-/* 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/. */
-
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-const CACHE_MAX_GROUP_ENTRIES = 100;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-function ContentPrefService() {
-  if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
-    return Cu.import("resource://gre/modules/ContentPrefServiceChild.jsm")
-             .ContentPrefServiceChild;
-  }
-
-  // If this throws an exception, it causes the getService call to fail,
-  // but the next time a consumer tries to retrieve the service, we'll try
-  // to initialize the database again, which might work if the failure
-  // was due to a temporary condition (like being out of disk space).
-  this._dbInit();
-
-  this._observerSvc.addObserver(this, "last-pb-context-exited");
-
-  // Observe shutdown so we can shut down the database connection.
-  this._observerSvc.addObserver(this, "xpcom-shutdown");
-}
-
-Cu.import("resource://gre/modules/ContentPrefStore.jsm");
-const cache = new ContentPrefStore();
-cache.set = function CPS_cache_set(group, name, val) {
-  Object.getPrototypeOf(this).set.apply(this, arguments);
-  let groupCount = this._groups.size;
-  if (groupCount >= CACHE_MAX_GROUP_ENTRIES) {
-    // Clean half of the entries
-    for (let [group, name, ] of this) {
-      this.remove(group, name);
-      groupCount--;
-      if (groupCount < CACHE_MAX_GROUP_ENTRIES / 2)
-        break;
-    }
-  }
-};
-
-const privModeStorage = new ContentPrefStore();
-
-ContentPrefService.prototype = {
-  // XPCOM Plumbing
-
-  classID: Components.ID("{e3f772f3-023f-4b32-b074-36cf0fd5d414}"),
-
-  QueryInterface: function CPS_QueryInterface(iid) {
-    let supportedIIDs = [
-      Ci.nsIContentPrefService,
-      Ci.nsISupports,
-    ];
-    if (supportedIIDs.some(i => iid.equals(i)))
-      return this;
-    if (iid.equals(Ci.nsIContentPrefService2)) {
-      if (!this._contentPrefService2) {
-        let s = {};
-        Cu.import("resource://gre/modules/ContentPrefService2.jsm", s);
-        this._contentPrefService2 = new s.ContentPrefService2(this);
-      }
-      return this._contentPrefService2;
-    }
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  },
-
-  // Convenience Getters
-
-  // Observer Service
-  __observerSvc: null,
-  get _observerSvc() {
-    if (!this.__observerSvc)
-      this.__observerSvc = Cc["@mozilla.org/observer-service;1"].
-                           getService(Ci.nsIObserverService);
-    return this.__observerSvc;
-  },
-
-  // Console Service
-  __consoleSvc: null,
-  get _consoleSvc() {
-    if (!this.__consoleSvc)
-      this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
-                          getService(Ci.nsIConsoleService);
-    return this.__consoleSvc;
-  },
-
-  // Preferences Service
-  __prefSvc: null,
-  get _prefSvc() {
-    if (!this.__prefSvc)
-      this.__prefSvc = Cc["@mozilla.org/preferences-service;1"].
-                       getService(Ci.nsIPrefBranch);
-    return this.__prefSvc;
-  },
-
-
-  // Destruction
-
-  _destroy: function ContentPrefService__destroy() {
-    this._observerSvc.removeObserver(this, "xpcom-shutdown");
-    this._observerSvc.removeObserver(this, "last-pb-context-exited");
-
-    // Finalize statements which may have been used asynchronously.
-    // FIXME(696499): put them in an object cache like other components.
-    if (this.__stmtSelectPrefID) {
-      this.__stmtSelectPrefID.finalize();
-      this.__stmtSelectPrefID = null;
-    }
-    if (this.__stmtSelectGlobalPrefID) {
-      this.__stmtSelectGlobalPrefID.finalize();
-      this.__stmtSelectGlobalPrefID = null;
-    }
-    if (this.__stmtInsertPref) {
-      this.__stmtInsertPref.finalize();
-      this.__stmtInsertPref = null;
-    }
-    if (this.__stmtInsertGroup) {
-      this.__stmtInsertGroup.finalize();
-      this.__stmtInsertGroup = null;
-    }
-    if (this.__stmtInsertSetting) {
-      this.__stmtInsertSetting.finalize();
-      this.__stmtInsertSetting = null;
-    }
-    if (this.__stmtSelectGroupID) {
-      this.__stmtSelectGroupID.finalize();
-      this.__stmtSelectGroupID = null;
-    }
-    if (this.__stmtSelectSettingID) {
-      this.__stmtSelectSettingID.finalize();
-      this.__stmtSelectSettingID = null;
-    }
-    if (this.__stmtSelectPref) {
-      this.__stmtSelectPref.finalize();
-      this.__stmtSelectPref = null;
-    }
-    if (this.__stmtSelectGlobalPref) {
-      this.__stmtSelectGlobalPref.finalize();
-      this.__stmtSelectGlobalPref = null;
-    }
-    if (this.__stmtSelectPrefsByName) {
-      this.__stmtSelectPrefsByName.finalize();
-      this.__stmtSelectPrefsByName = null;
-    }
-    if (this.__stmtDeleteSettingIfUnused) {
-      this.__stmtDeleteSettingIfUnused.finalize();
-      this.__stmtDeleteSettingIfUnused = null;
-    }
-    if (this.__stmtSelectPrefs) {
-      this.__stmtSelectPrefs.finalize();
-      this.__stmtSelectPrefs = null;
-    }
-    if (this.__stmtDeleteGroupIfUnused) {
-      this.__stmtDeleteGroupIfUnused.finalize();
-      this.__stmtDeleteGroupIfUnused = null;
-    }
-    if (this.__stmtDeletePref) {
-      this.__stmtDeletePref.finalize();
-      this.__stmtDeletePref = null;
-    }
-    if (this.__stmtUpdatePref) {
-      this.__stmtUpdatePref.finalize();
-      this.__stmtUpdatePref = null;
-    }
-
-    if (this._contentPrefService2)
-      this._contentPrefService2.destroy();
-
-    this._dbConnection.asyncClose(() => {
-      Services.obs.notifyObservers(null, "content-prefs-db-closed");
-    });
-
-    // Delete references to XPCOM components to make sure we don't leak them
-    // (although we haven't observed leakage in tests).  Also delete references
-    // in _observers and _genericObservers to avoid cycles with those that
-    // refer to us and don't remove themselves from those observer pools.
-    delete this._observers;
-    delete this._genericObservers;
-    delete this.__consoleSvc;
-    delete this.__grouper;
-    delete this.__observerSvc;
-    delete this.__prefSvc;
-  },
-
-
-  // nsIObserver
-
-  observe: function ContentPrefService_observe(subject, topic, data) {
-    switch (topic) {
-      case "xpcom-shutdown":
-        this._destroy();
-        break;
-      case "last-pb-context-exited":
-        this._privModeStorage.removeAll();
-        break;
-    }
-  },
-
-
-  // in-memory cache and private-browsing stores
-
-  _cache: cache,
-  _privModeStorage: privModeStorage,
-
-  // nsIContentPrefService
-
-  getPref: function ContentPrefService_getPref(aGroup, aName, aContext, aCallback) {
-    warnDeprecated();
-
-    if (!aName)
-      throw Components.Exception("aName cannot be null or an empty string",
-                                 Cr.NS_ERROR_ILLEGAL_VALUE);
-
-    var group = this._parseGroupParam(aGroup);
-
-    if (aContext && aContext.usePrivateBrowsing) {
-      if (this._privModeStorage.has(group, aName)) {
-        let value = this._privModeStorage.get(group, aName);
-        if (aCallback) {
-          this._scheduleCallback(function() { aCallback.onResult(value); });
-          return undefined;
-        }
-        return value;
-      }
-      // if we don't have a pref specific to this private mode browsing
-      // session, to try to get one from normal mode
-    }
-
-    if (group == null)
-      return this._selectGlobalPref(aName, aCallback);
-    return this._selectPref(group, aName, aCallback);
-  },
-
-  setPref: function ContentPrefService_setPref(aGroup, aName, aValue, aContext) {
-    warnDeprecated();
-
-    // If the pref is already set to the value, there's nothing more to do.
-    var currentValue = this.getPref(aGroup, aName, aContext);
-    if (typeof currentValue != "undefined") {
-      if (currentValue == aValue)
-        return;
-    }
-
-    var group = this._parseGroupParam(aGroup);
-
-    if (aContext && aContext.usePrivateBrowsing) {
-      this._privModeStorage.setWithCast(group, aName, aValue);
-      this._notifyPrefSet(group, aName, aValue, aContext.usePrivateBrowsing);
-      return;
-    }
-
-    var settingID = this._selectSettingID(aName) || this._insertSetting(aName);
-    var groupID, prefID;
-    if (group == null) {
-      groupID = null;
-      prefID = this._selectGlobalPrefID(settingID);
-    } else {
-      groupID = this._selectGroupID(group) || this._insertGroup(group);
-      prefID = this._selectPrefID(groupID, settingID);
-    }
-
-    // Update the existing record, if any, or create a new one.
-    if (prefID)
-      this._updatePref(prefID, aValue);
-    else
-      this._insertPref(groupID, settingID, aValue);
-
-    this._cache.setWithCast(group, aName, aValue);
-
-    this._notifyPrefSet(group, aName, aValue,
-                        aContext ? aContext.usePrivateBrowsing : false);
-  },
-
-  hasPref: function ContentPrefService_hasPref(aGroup, aName, aContext) {
-    warnDeprecated();
-
-    // XXX If consumers end up calling this method regularly, then we should
-    // optimize this to query the database directly.
-    return (typeof this.getPref(aGroup, aName, aContext) != "undefined");
-  },
-
-  hasCachedPref: function ContentPrefService_hasCachedPref(aGroup, aName, aContext) {
-    warnDeprecated();
-
-    if (!aName)
-      throw Components.Exception("aName cannot be null or an empty string",
-                                 Cr.NS_ERROR_ILLEGAL_VALUE);
-
-    let group = this._parseGroupParam(aGroup);
-    let storage = aContext && aContext.usePrivateBrowsing ? this._privModeStorage : this._cache;
-    return storage.has(group, aName);
-  },
-
-  removePref: function ContentPrefService_removePref(aGroup, aName, aContext) {
-    warnDeprecated();
-
-    // If there's no old value, then there's nothing to remove.
-    if (!this.hasPref(aGroup, aName, aContext))
-      return;
-
-    var group = this._parseGroupParam(aGroup);
-
-    if (aContext && aContext.usePrivateBrowsing) {
-      this._privModeStorage.remove(group, aName);
-      this._notifyPrefRemoved(group, aName, true);
-      return;
-    }
-
-    var settingID = this._selectSettingID(aName);
-    var groupID, prefID;
-    if (group == null) {
-      groupID = null;
-      prefID = this._selectGlobalPrefID(settingID);
-    } else {
-      groupID = this._selectGroupID(group);
-      prefID = this._selectPrefID(groupID, settingID);
-    }
-
-    this._deletePref(prefID);
-
-    // Get rid of extraneous records that are no longer being used.
-    this._deleteSettingIfUnused(settingID);
-    if (groupID)
-      this._deleteGroupIfUnused(groupID);
-
-    this._cache.remove(group, aName);
-    this._notifyPrefRemoved(group, aName, false);
-  },
-
-  removeGroupedPrefs: function ContentPrefService_removeGroupedPrefs(aContext) {
-    warnDeprecated();
-
-    // will not delete global preferences
-    if (aContext && aContext.usePrivateBrowsing) {
-        // keep only global prefs
-        this._privModeStorage.removeAllGroups();
-    }
-    this._cache.removeAllGroups();
-    this._dbConnection.beginTransaction();
-    try {
-      this._dbConnection.executeSimpleSQL("DELETE FROM prefs WHERE groupID IS NOT NULL");
-      this._dbConnection.executeSimpleSQL("DELETE FROM groups");
-      this._dbConnection.executeSimpleSQL(`
-        DELETE FROM settings
-        WHERE id NOT IN (SELECT DISTINCT settingID FROM prefs)
-      `);
-      this._dbConnection.commitTransaction();
-    } catch (ex) {
-      this._dbConnection.rollbackTransaction();
-      throw ex;
-    }
-  },
-
-  removePrefsByName: function ContentPrefService_removePrefsByName(aName, aContext) {
-    warnDeprecated();
-
-    if (!aName)
-      throw Components.Exception("aName cannot be null or an empty string",
-                                 Cr.NS_ERROR_ILLEGAL_VALUE);
-
-    if (aContext && aContext.usePrivateBrowsing) {
-      for (let [group, name, ] of this._privModeStorage) {
-        if (name === aName) {
-          this._privModeStorage.remove(group, aName);
-          this._notifyPrefRemoved(group, aName, true);
-        }
-      }
-    }
-
-    var settingID = this._selectSettingID(aName);
-    if (!settingID)
-      return;
-
-    var selectGroupsStmt = this._dbCreateStatement(`
-      SELECT groups.id AS groupID, groups.name AS groupName
-      FROM prefs
-      JOIN groups ON prefs.groupID = groups.id
-      WHERE prefs.settingID = :setting
-    `);
-
-    var groupNames = [];
-    var groupIDs = [];
-    try {
-      selectGroupsStmt.params.setting = settingID;
-
-      while (selectGroupsStmt.executeStep()) {
-        groupIDs.push(selectGroupsStmt.row.groupID);
-        groupNames.push(selectGroupsStmt.row.groupName);
-      }
-    } finally {
-      selectGroupsStmt.reset();
-    }
-
-    if (this.hasPref(null, aName)) {
-      groupNames.push(null);
-    }
-
-    this._dbConnection.executeSimpleSQL("DELETE FROM prefs WHERE settingID = " + settingID);
-    this._dbConnection.executeSimpleSQL("DELETE FROM settings WHERE id = " + settingID);
-
-    for (var i = 0; i < groupNames.length; i++) {
-      this._cache.remove(groupNames[i], aName);
-      if (groupNames[i]) // ie. not null, which will be last (and i == groupIDs.length)
-        this._deleteGroupIfUnused(groupIDs[i]);
-      if (!aContext || !aContext.usePrivateBrowsing) {
-        this._notifyPrefRemoved(groupNames[i], aName, false);
-      }
-    }
-  },
-
-  getPrefs: function ContentPrefService_getPrefs(aGroup, aContext) {
-    warnDeprecated();
-
-    var group = this._parseGroupParam(aGroup);
-    if (aContext && aContext.usePrivateBrowsing) {
-        let prefs = Cc["@mozilla.org/hash-property-bag;1"].
-                    createInstance(Ci.nsIWritablePropertyBag);
-        for (let [sgroup, sname, sval] of this._privModeStorage) {
-          if (sgroup === group)
-            prefs.setProperty(sname, sval);
-        }
-        return prefs;
-    }
-
-    if (group == null)
-      return this._selectGlobalPrefs();
-    return this._selectPrefs(group);
-  },
-
-  getPrefsByName: function ContentPrefService_getPrefsByName(aName, aContext) {
-    warnDeprecated();
-
-    if (!aName)
-      throw Components.Exception("aName cannot be null or an empty string",
-                                 Cr.NS_ERROR_ILLEGAL_VALUE);
-
-    if (aContext && aContext.usePrivateBrowsing) {
-      let prefs = Cc["@mozilla.org/hash-property-bag;1"].
-                  createInstance(Ci.nsIWritablePropertyBag);
-      for (let [sgroup, sname, sval] of this._privModeStorage) {
-        if (sname === aName)
-          prefs.setProperty(sgroup, sval);
-      }
-      return prefs;
-    }
-
-    return this._selectPrefsByName(aName);
-  },
-
-  // A hash of arrays of observers, indexed by setting name.
-  _observers: {},
-
-  // An array of generic observers, which observe all settings.
-  _genericObservers: [],
-
-  addObserver: function ContentPrefService_addObserver(aName, aObserver) {
-    warnDeprecated();
-    this._addObserver.apply(this, arguments);
-  },
-
-  _addObserver: function ContentPrefService__addObserver(aName, aObserver) {
-    var observers;
-    if (aName) {
-      if (!this._observers[aName])
-        this._observers[aName] = [];
-      observers = this._observers[aName];
-    } else
-      observers = this._genericObservers;
-
-    if (observers.indexOf(aObserver) == -1)
-      observers.push(aObserver);
-  },
-
-  removeObserver: function ContentPrefService_removeObserver(aName, aObserver) {
-    warnDeprecated();
-    this._removeObserver.apply(this, arguments);
-  },
-
-  _removeObserver: function ContentPrefService__removeObserver(aName, aObserver) {
-    var observers;
-    if (aName) {
-      if (!this._observers[aName])
-        return;
-      observers = this._observers[aName];
-    } else
-      observers = this._genericObservers;
-
-    if (observers.indexOf(aObserver) != -1)
-      observers.splice(observers.indexOf(aObserver), 1);
-  },
-
-  /**
-   * Construct a list of observers to notify about a change to some setting,
-   * putting setting-specific observers before before generic ones, so observers
-   * that initialize individual settings (like the page style controller)
-   * execute before observers that display multiple settings and depend on them
-   * being initialized first (like the content prefs sidebar).
-   */
-  _getObservers: function ContentPrefService__getObservers(aName) {
-    var observers = [];
-
-    if (aName && this._observers[aName])
-      observers = observers.concat(this._observers[aName]);
-    observers = observers.concat(this._genericObservers);
-
-    return observers;
-  },
-
-  /**
-   * Notify all observers about the removal of a preference.
-   */
-  _notifyPrefRemoved: function ContentPrefService__notifyPrefRemoved(aGroup, aName, aIsPrivate) {
-    for (var observer of this._getObservers(aName)) {
-      try {
-        observer.onContentPrefRemoved(aGroup, aName, aIsPrivate);
-      } catch (ex) {
-        Cu.reportError(ex);
-      }
-    }
-  },
-
-  /**
-   * Notify all observers about a preference change.
-   */
-  _notifyPrefSet: function ContentPrefService__notifyPrefSet(aGroup, aName, aValue, aIsPrivate) {
-    for (var observer of this._getObservers(aName)) {
-      try {
-        observer.onContentPrefSet(aGroup, aName, aValue, aIsPrivate);
-      } catch (ex) {
-        Cu.reportError(ex);
-      }
-    }
-  },
-
-  get grouper() {
-    warnDeprecated();
-    return this._grouper;
-  },
-  __grouper: null,
-  get _grouper() {
-    if (!this.__grouper)
-      this.__grouper = Cc["@mozilla.org/content-pref/hostname-grouper;1"].
-                       getService(Ci.nsIContentURIGrouper);
-    return this.__grouper;
-  },
-
-  get DBConnection() {
-    warnDeprecated();
-    return this._dbConnection;
-  },
-
-
-  // Data Retrieval & Modification
-
-  __stmtSelectPref: null,
-  get _stmtSelectPref() {
-    if (!this.__stmtSelectPref)
-      this.__stmtSelectPref = this._dbCreateStatement(`
-        SELECT prefs.value AS value
-        FROM prefs
-        JOIN groups ON prefs.groupID = groups.id
-        JOIN settings ON prefs.settingID = settings.id
-        WHERE groups.name = :group
-        AND settings.name = :setting
-      `);
-
-    return this.__stmtSelectPref;
-  },
-
-  _scheduleCallback(func) {
-    let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
-    tm.dispatchToMainThread(func);
-  },
-
-  _selectPref: function ContentPrefService__selectPref(aGroup, aSetting, aCallback) {
-    let value = undefined;
-    if (this._cache.has(aGroup, aSetting)) {
-      value = this._cache.get(aGroup, aSetting);
-      if (aCallback) {
-        this._scheduleCallback(function() { aCallback.onResult(value); });
-        return undefined;
-      }
-      return value;
-    }
-
-    try {
-      this._stmtSelectPref.params.group = aGroup;
-      this._stmtSelectPref.params.setting = aSetting;
-
-      if (aCallback) {
-        let cache = this._cache;
-        new AsyncStatement(this._stmtSelectPref).execute({onResult(aResult) {
-          cache.set(aGroup, aSetting, aResult);
-          aCallback.onResult(aResult);
-        }});
-      } else {
-        if (this._stmtSelectPref.executeStep()) {
-          value = this._stmtSelectPref.row.value;
-        }
-        this._cache.set(aGroup, aSetting, value);
-      }
-    } finally {
-      this._stmtSelectPref.reset();
-    }
-
-    return value;
-  },
-
-  __stmtSelectGlobalPref: null,
-  get _stmtSelectGlobalPref() {
-    if (!this.__stmtSelectGlobalPref)
-      this.__stmtSelectGlobalPref = this._dbCreateStatement(`
-        SELECT prefs.value AS value
-        FROM prefs
-        JOIN settings ON prefs.settingID = settings.id
-        WHERE prefs.groupID IS NULL
-        AND settings.name = :name
-      `);
-
-    return this.__stmtSelectGlobalPref;
-  },
-
-  _selectGlobalPref: function ContentPrefService__selectGlobalPref(aName, aCallback) {
-    let value = undefined;
-    if (this._cache.has(null, aName)) {
-      value = this._cache.get(null, aName);
-      if (aCallback) {
-        this._scheduleCallback(function() { aCallback.onResult(value); });
-        return undefined;
-      }
-      return value;
-    }
-
-    try {
-      this._stmtSelectGlobalPref.params.name = aName;
-
-      if (aCallback) {
-        let cache = this._cache;
-        new AsyncStatement(this._stmtSelectGlobalPref).execute({onResult(aResult) {
-          cache.set(null, aName, aResult);
-          aCallback.onResult(aResult);
-        }});
-      } else {
-        if (this._stmtSelectGlobalPref.executeStep()) {
-          value = this._stmtSelectGlobalPref.row.value;
-        }
-        this._cache.set(null, aName, value);
-      }
-    } finally {
-      this._stmtSelectGlobalPref.reset();
-    }
-
-    return value;
-  },
-
-  __stmtSelectGroupID: null,
-  get _stmtSelectGroupID() {
-    if (!this.__stmtSelectGroupID)
-      this.__stmtSelectGroupID = this._dbCreateStatement(`
-        SELECT groups.id AS id
-        FROM groups
-        WHERE groups.name = :name
-      `);
-
-    return this.__stmtSelectGroupID;
-  },
-
-  _selectGroupID: function ContentPrefService__selectGroupID(aName) {
-    var id;
-
-    try {
-      this._stmtSelectGroupID.params.name = aName;
-
-      if (this._stmtSelectGroupID.executeStep())
-        id = this._stmtSelectGroupID.row.id;
-    } finally {
-      this._stmtSelectGroupID.reset();
-    }
-
-    return id;
-  },
-
-  __stmtInsertGroup: null,
-  get _stmtInsertGroup() {
-    if (!this.__stmtInsertGroup)
-      this.__stmtInsertGroup = this._dbCreateStatement(
-        "INSERT INTO groups (name) VALUES (:name)"
-      );
-
-    return this.__stmtInsertGroup;
-  },
-
-  _insertGroup: function ContentPrefService__insertGroup(aName) {
-    this._stmtInsertGroup.params.name = aName;
-    this._stmtInsertGroup.execute();
-    return this._dbConnection.lastInsertRowID;
-  },
-
-  __stmtSelectSettingID: null,
-  get _stmtSelectSettingID() {
-    if (!this.__stmtSelectSettingID)
-      this.__stmtSelectSettingID = this._dbCreateStatement(
-        "SELECT id FROM settings WHERE name = :name"
-      );
-
-    return this.__stmtSelectSettingID;
-  },
-
-  _selectSettingID: function ContentPrefService__selectSettingID(aName) {
-    var id;
-
-    try {
-      this._stmtSelectSettingID.params.name = aName;
-
-      if (this._stmtSelectSettingID.executeStep())
-        id = this._stmtSelectSettingID.row.id;
-    } finally {
-      this._stmtSelectSettingID.reset();
-    }
-
-    return id;
-  },
-
-  __stmtInsertSetting: null,
-  get _stmtInsertSetting() {
-    if (!this.__stmtInsertSetting)
-      this.__stmtInsertSetting = this._dbCreateStatement(
-        "INSERT INTO settings (name) VALUES (:name)"
-      );
-
-    return this.__stmtInsertSetting;
-  },
-
-  _insertSetting: function ContentPrefService__insertSetting(aName) {
-    this._stmtInsertSetting.params.name = aName;
-    this._stmtInsertSetting.execute();
-    return this._dbConnection.lastInsertRowID;
-  },
-
-  __stmtSelectPrefID: null,
-  get _stmtSelectPrefID() {
-    if (!this.__stmtSelectPrefID)
-      this.__stmtSelectPrefID = this._dbCreateStatement(
-        "SELECT id FROM prefs WHERE groupID = :groupID AND settingID = :settingID"
-      );
-
-    return this.__stmtSelectPrefID;
-  },
-
-  _selectPrefID: function ContentPrefService__selectPrefID(aGroupID, aSettingID) {
-    var id;
-
-    try {
-      this._stmtSelectPrefID.params.groupID = aGroupID;
-      this._stmtSelectPrefID.params.settingID = aSettingID;
-
-      if (this._stmtSelectPrefID.executeStep())
-        id = this._stmtSelectPrefID.row.id;
-    } finally {
-      this._stmtSelectPrefID.reset();
-    }
-
-    return id;
-  },
-
-  __stmtSelectGlobalPrefID: null,
-  get _stmtSelectGlobalPrefID() {
-    if (!this.__stmtSelectGlobalPrefID)
-      this.__stmtSelectGlobalPrefID = this._dbCreateStatement(
-        "SELECT id FROM prefs WHERE groupID IS NULL AND settingID = :settingID"
-      );
-
-    return this.__stmtSelectGlobalPrefID;
-  },
-
-  _selectGlobalPrefID: function ContentPrefService__selectGlobalPrefID(aSettingID) {
-    var id;
-
-    try {
-      this._stmtSelectGlobalPrefID.params.settingID = aSettingID;
-
-      if (this._stmtSelectGlobalPrefID.executeStep())
-        id = this._stmtSelectGlobalPrefID.row.id;
-    } finally {
-      this._stmtSelectGlobalPrefID.reset();
-    }
-
-    return id;
-  },
-
-  __stmtInsertPref: null,
-  get _stmtInsertPref() {
-    if (!this.__stmtInsertPref)
-      this.__stmtInsertPref = this._dbCreateStatement(`
-        INSERT INTO prefs (groupID, settingID, value)
-        VALUES (:groupID, :settingID, :value)
-      `);
-
-    return this.__stmtInsertPref;
-  },
-
-  _insertPref: function ContentPrefService__insertPref(aGroupID, aSettingID, aValue) {
-    this._stmtInsertPref.params.groupID = aGroupID;
-    this._stmtInsertPref.params.settingID = aSettingID;
-    this._stmtInsertPref.params.value = aValue;
-    this._stmtInsertPref.execute();
-    return this._dbConnection.lastInsertRowID;
-  },
-
-  __stmtUpdatePref: null,
-  get _stmtUpdatePref() {
-    if (!this.__stmtUpdatePref)
-      this.__stmtUpdatePref = this._dbCreateStatement(
-        "UPDATE prefs SET value = :value WHERE id = :id"
-      );
-
-    return this.__stmtUpdatePref;
-  },
-
-  _updatePref: function ContentPrefService__updatePref(aPrefID, aValue) {
-    this._stmtUpdatePref.params.id = aPrefID;
-    this._stmtUpdatePref.params.value = aValue;
-    this._stmtUpdatePref.execute();
-  },
-
-  __stmtDeletePref: null,
-  get _stmtDeletePref() {
-    if (!this.__stmtDeletePref)
-      this.__stmtDeletePref = this._dbCreateStatement(
-        "DELETE FROM prefs WHERE id = :id"
-      );
-
-    return this.__stmtDeletePref;
-  },
-
-  _deletePref: function ContentPrefService__deletePref(aPrefID) {
-    this._stmtDeletePref.params.id = aPrefID;
-    this._stmtDeletePref.execute();
-  },
-
-  __stmtDeleteSettingIfUnused: null,
-  get _stmtDeleteSettingIfUnused() {
-    if (!this.__stmtDeleteSettingIfUnused)
-      this.__stmtDeleteSettingIfUnused = this._dbCreateStatement(`
-        DELETE FROM settings WHERE id = :id
-        AND id NOT IN (SELECT DISTINCT settingID FROM prefs)
-      `);
-
-    return this.__stmtDeleteSettingIfUnused;
-  },
-
-  _deleteSettingIfUnused: function ContentPrefService__deleteSettingIfUnused(aSettingID) {
-    this._stmtDeleteSettingIfUnused.params.id = aSettingID;
-    this._stmtDeleteSettingIfUnused.execute();
-  },
-
-  __stmtDeleteGroupIfUnused: null,
-  get _stmtDeleteGroupIfUnused() {
-    if (!this.__stmtDeleteGroupIfUnused)
-      this.__stmtDeleteGroupIfUnused = this._dbCreateStatement(`
-        DELETE FROM groups WHERE id = :id
-        AND id NOT IN (SELECT DISTINCT groupID FROM prefs)
-      `);
-
-    return this.__stmtDeleteGroupIfUnused;
-  },
-
-  _deleteGroupIfUnused: function ContentPrefService__deleteGroupIfUnused(aGroupID) {
-    this._stmtDeleteGroupIfUnused.params.id = aGroupID;
-    this._stmtDeleteGroupIfUnused.execute();
-  },
-
-  __stmtSelectPrefs: null,
-  get _stmtSelectPrefs() {
-    if (!this.__stmtSelectPrefs)
-      this.__stmtSelectPrefs = this._dbCreateStatement(`
-        SELECT settings.name AS name, prefs.value AS value
-        FROM prefs
-        JOIN groups ON prefs.groupID = groups.id
-        JOIN settings ON prefs.settingID = settings.id
-        WHERE groups.name = :group
-      `);
-
-    return this.__stmtSelectPrefs;
-  },
-
-  _selectPrefs: function ContentPrefService__selectPrefs(aGroup) {
-    var prefs = Cc["@mozilla.org/hash-property-bag;1"].
-                createInstance(Ci.nsIWritablePropertyBag);
-
-    try {
-      this._stmtSelectPrefs.params.group = aGroup;
-
-      while (this._stmtSelectPrefs.executeStep())
-        prefs.setProperty(this._stmtSelectPrefs.row.name,
-                          this._stmtSelectPrefs.row.value);
-    } finally {
-      this._stmtSelectPrefs.reset();
-    }
-
-    return prefs;
-  },
-
-  __stmtSelectGlobalPrefs: null,
-  get _stmtSelectGlobalPrefs() {
-    if (!this.__stmtSelectGlobalPrefs)
-      this.__stmtSelectGlobalPrefs = this._dbCreateStatement(`
-        SELECT settings.name AS name, prefs.value AS value
-        FROM prefs
-        JOIN settings ON prefs.settingID = settings.id
-        WHERE prefs.groupID IS NULL
-      `);
-
-    return this.__stmtSelectGlobalPrefs;
-  },
-
-  _selectGlobalPrefs: function ContentPrefService__selectGlobalPrefs() {
-    var prefs = Cc["@mozilla.org/hash-property-bag;1"].
-                createInstance(Ci.nsIWritablePropertyBag);
-
-    try {
-      while (this._stmtSelectGlobalPrefs.executeStep())
-        prefs.setProperty(this._stmtSelectGlobalPrefs.row.name,
-                          this._stmtSelectGlobalPrefs.row.value);
-    } finally {
-      this._stmtSelectGlobalPrefs.reset();
-    }
-
-    return prefs;
-  },
-
-  __stmtSelectPrefsByName: null,
-  get _stmtSelectPrefsByName() {
-    if (!this.__stmtSelectPrefsByName)
-      this.__stmtSelectPrefsByName = this._dbCreateStatement(`
-        SELECT groups.name AS groupName, prefs.value AS value
-        FROM prefs
-        JOIN groups ON prefs.groupID = groups.id
-        JOIN settings ON prefs.settingID = settings.id
-        WHERE settings.name = :setting
-      `);
-
-    return this.__stmtSelectPrefsByName;
-  },
-
-  _selectPrefsByName: function ContentPrefService__selectPrefsByName(aName) {
-    var prefs = Cc["@mozilla.org/hash-property-bag;1"].
-                createInstance(Ci.nsIWritablePropertyBag);
-
-    try {
-      this._stmtSelectPrefsByName.params.setting = aName;
-
-      while (this._stmtSelectPrefsByName.executeStep())
-        prefs.setProperty(this._stmtSelectPrefsByName.row.groupName,
-                          this._stmtSelectPrefsByName.row.value);
-    } finally {
-      this._stmtSelectPrefsByName.reset();
-    }
-
-    var global = this._selectGlobalPref(aName);
-    if (typeof global != "undefined") {
-      prefs.setProperty(null, global);
-    }
-
-    return prefs;
-  },
-
-
-  // Database Creation & Access
-
-  _dbVersion: 4,
-
-  _dbSchema: {
-    tables: {
-      groups:     "id           INTEGER PRIMARY KEY, \
-                   name         TEXT NOT NULL",
-
-      settings:   "id           INTEGER PRIMARY KEY, \
-                   name         TEXT NOT NULL",
-
-      prefs:      "id           INTEGER PRIMARY KEY, \
-                   groupID      INTEGER REFERENCES groups(id), \
-                   settingID    INTEGER NOT NULL REFERENCES settings(id), \
-                   value        BLOB, \
-                   timestamp    INTEGER NOT NULL DEFAULT 0" // Storage in seconds, API in ms. 0 for migrated values.
-    },
-    indices: {
-      groups_idx: {
-        table: "groups",
-        columns: ["name"]
-      },
-      settings_idx: {
-        table: "settings",
-        columns: ["name"]
-      },
-      prefs_idx: {
-        table: "prefs",
-        columns: ["timestamp", "groupID", "settingID"]
-      }
-    }
-  },
-
-  _dbConnection: null,
-
-  _dbCreateStatement: function ContentPrefService__dbCreateStatement(aSQLString) {
-    try {
-      var statement = this._dbConnection.createStatement(aSQLString);
-    } catch (ex) {
-      Cu.reportError("error creating statement " + aSQLString + ": " +
-                     this._dbConnection.lastError + " - " +
-                     this._dbConnection.lastErrorString);
-      throw ex;
-    }
-
-    return statement;
-  },
-
-  // _dbInit and the methods it calls (_dbCreate, _dbMigrate, and version-
-  // specific migration methods) must be careful not to call any method
-  // of the service that assumes the database connection has already been
-  // initialized, since it won't be initialized until at the end of _dbInit.
-
-  _dbInit: function ContentPrefService__dbInit() {
-    var dirService = Cc["@mozilla.org/file/directory_service;1"].
-                     getService(Ci.nsIProperties);
-    var dbFile = dirService.get("ProfD", Ci.nsIFile);
-    dbFile.append("content-prefs.sqlite");
-
-    var dbService = Cc["@mozilla.org/storage/service;1"].
-                    getService(Ci.mozIStorageService);
-
-    var dbConnection;
-
-    if (!dbFile.exists())
-      dbConnection = this._dbCreate(dbService, dbFile);
-    else {
-      try {
-        dbConnection = dbService.openDatabase(dbFile);
-      } catch (e) {
-        // If the connection isn't ready after we open the database, that means
-        // the database has been corrupted, so we back it up and then recreate it.
-        if (e.result != Cr.NS_ERROR_FILE_CORRUPTED)
-          throw e;
-        dbConnection = this._dbBackUpAndRecreate(dbService, dbFile,
-                                                 dbConnection);
-      }
-
-      // Get the version of the schema in the file.
-      var version = dbConnection.schemaVersion;
-
-      // Try to migrate the schema in the database to the current schema used by
-      // the service.  If migration fails, back up the database and recreate it.
-      if (version != this._dbVersion) {
-        try {
-          this._dbMigrate(dbConnection, version, this._dbVersion);
-        } catch (ex) {
-          Cu.reportError("error migrating DB: " + ex + "; backing up and recreating");
-          dbConnection = this._dbBackUpAndRecreate(dbService, dbFile, dbConnection);
-        }
-      }
-    }
-
-    // Turn off disk synchronization checking to reduce disk churn and speed up
-    // operations when prefs are changed rapidly (such as when a user repeatedly
-    // changes the value of the browser zoom setting for a site).
-    //
-    // Note: this could cause database corruption if the OS crashes or machine
-    // loses power before the data gets written to disk, but this is considered
-    // a reasonable risk for the not-so-critical data stored in this database.
-    //
-    // If you really don't want to take this risk, however, just set the
-    // toolkit.storage.synchronous pref to 1 (NORMAL synchronization) or 2
-    // (FULL synchronization), in which case mozStorageConnection::Initialize
-    // will use that value, and we won't override it here.
-    if (!this._prefSvc.prefHasUserValue("toolkit.storage.synchronous"))
-      dbConnection.executeSimpleSQL("PRAGMA synchronous = OFF");
-
-    this._dbConnection = dbConnection;
-  },
-
-  _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
-    var dbConnection = aDBService.openDatabase(aDBFile);
-
-    try {
-      this._dbCreateSchema(dbConnection);
-      dbConnection.schemaVersion = this._dbVersion;
-    } catch (ex) {
-      // If we failed to create the database (perhaps because the disk ran out
-      // of space), then remove the database file so we don't leave it in some
-      // half-created state from which we won't know how to recover.
-      dbConnection.close();
-      aDBFile.remove(false);
-      throw ex;
-    }
-
-    return dbConnection;
-  },
-
-  _dbCreateSchema: function ContentPrefService__dbCreateSchema(aDBConnection) {
-    this._dbCreateTables(aDBConnection);
-    this._dbCreateIndices(aDBConnection);
-  },
-
-  _dbCreateTables: function ContentPrefService__dbCreateTables(aDBConnection) {
-    for (let name in this._dbSchema.tables)
-      aDBConnection.createTable(name, this._dbSchema.tables[name]);
-  },
-
-  _dbCreateIndices: function ContentPrefService__dbCreateIndices(aDBConnection) {
-    for (let name in this._dbSchema.indices) {
-      let index = this._dbSchema.indices[name];
-      let statement = `
-        CREATE INDEX IF NOT EXISTS ${name} ON ${index.table}
-        (${index.columns.join(", ")})
-      `;
-      aDBConnection.executeSimpleSQL(statement);
-    }
-  },
-
-  _dbBackUpAndRecreate: function ContentPrefService__dbBackUpAndRecreate(aDBService,
-                                                                         aDBFile,
-                                                                         aDBConnection) {
-    aDBService.backupDatabaseFile(aDBFile, "content-prefs.sqlite.corrupt");
-
-    // Close the database, ignoring the "already closed" exception, if any.
-    // It'll be open if we're here because of a migration failure but closed
-    // if we're here because of database corruption.
-    try { aDBConnection.close() } catch (ex) {}
-
-    aDBFile.remove(false);
-
-    let dbConnection = this._dbCreate(aDBService, aDBFile);
-
-    return dbConnection;
-  },
-
-  _dbMigrate: function ContentPrefService__dbMigrate(aDBConnection, aOldVersion, aNewVersion) {
-    /**
-     * Migrations should follow the template rules in bug 1074817 comment 3 which are:
-     * 1. Migration should be incremental and non-breaking.
-     * 2. It should be idempotent because one can downgrade an upgrade again.
-     * On downgrade:
-     * 1. Decrement schema version so that upgrade runs the migrations again.
-     */
-    aDBConnection.beginTransaction();
-
-    try {
-       /**
-       * If the schema version is 0, that means it was never set, which means
-       * the database was somehow created without the schema being applied, perhaps
-       * because the system ran out of disk space (although we check for this
-       * in _createDB) or because some other code created the database file without
-       * applying the schema.  In any case, recover by simply reapplying the schema.
-       */
-      if (aOldVersion == 0) {
-        this._dbCreateSchema(aDBConnection);
-      } else {
-        for (let i = aOldVersion; i < aNewVersion; i++) {
-          let migrationName = "_dbMigrate" + i + "To" + (i + 1);
-          if (typeof this[migrationName] != "function") {
-            throw ("no migrator function from version " + aOldVersion + " to version " + aNewVersion);
-          }
-          this[migrationName](aDBConnection);
-        }
-      }
-      aDBConnection.schemaVersion = aNewVersion;
-      aDBConnection.commitTransaction();
-    } catch (ex) {
-      aDBConnection.rollbackTransaction();
-      throw ex;
-    }
-  },
-
-  _dbMigrate1To2: function ContentPrefService___dbMigrate1To2(aDBConnection) {
-    aDBConnection.executeSimpleSQL("ALTER TABLE groups RENAME TO groupsOld");
-    aDBConnection.createTable("groups", this._dbSchema.tables.groups);
-    aDBConnection.executeSimpleSQL(`
-      INSERT INTO groups (id, name)
-      SELECT id, name FROM groupsOld
-    `);
-
-    aDBConnection.executeSimpleSQL("DROP TABLE groupers");
-    aDBConnection.executeSimpleSQL("DROP TABLE groupsOld");
-  },
-
-  _dbMigrate2To3: function ContentPrefService__dbMigrate2To3(aDBConnection) {
-    this._dbCreateIndices(aDBConnection);
-  },
-
-  _dbMigrate3To4: function ContentPrefService__dbMigrate3To4(aDBConnection) {
-    // Add timestamp column if it does not exist yet. This operation is idempotent.
-    try {
-      let stmt = aDBConnection.createStatement("SELECT timestamp FROM prefs");
-      stmt.finalize();
-    } catch (e) {
-      aDBConnection.executeSimpleSQL("ALTER TABLE prefs ADD COLUMN timestamp INTEGER NOT NULL DEFAULT 0");
-    }
-
-    // To modify prefs_idx drop it and create again.
-    aDBConnection.executeSimpleSQL("DROP INDEX IF EXISTS prefs_idx");
-    this._dbCreateIndices(aDBConnection);
-  },
-
-  _parseGroupParam: function ContentPrefService__parseGroupParam(aGroup) {
-    if (aGroup == null)
-      return null;
-    if (aGroup.constructor.name == "String")
-      return aGroup.toString();
-    if (aGroup instanceof Ci.nsIURI)
-      return this.grouper.group(aGroup);
-
-    throw Components.Exception("aGroup is not a string, nsIURI or null",
-                               Cr.NS_ERROR_ILLEGAL_VALUE);
-  },
-};
-
-function warnDeprecated() {
-  let Deprecated = Cu.import("resource://gre/modules/Deprecated.jsm", {}).Deprecated;
-  Deprecated.warning("nsIContentPrefService is deprecated. Please use nsIContentPrefService2 instead.",
-                     "https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIContentPrefService2",
-                     Components.stack.caller);
-}
-
-
-function HostnameGrouper() {}
-
-HostnameGrouper.prototype = {
-  // XPCOM Plumbing
-
-  classID:          Components.ID("{8df290ae-dcaa-4c11-98a5-2429a4dc97bb}"),
-  QueryInterface:   XPCOMUtils.generateQI([Ci.nsIContentURIGrouper]),
-
-  // nsIContentURIGrouper
-
-  group: function HostnameGrouper_group(aURI) {
-    var group;
-
-    try {
-      // Accessing the host property of the URI will throw an exception
-      // if the URI is of a type that doesn't have a host property.
-      // Otherwise, we manually throw an exception if the host is empty,
-      // since the effect is the same (we can't derive a group from it).
-
-      group = aURI.host;
-      if (!group)
-        throw ("can't derive group from host; no host in URI");
-    } catch (ex) {
-      // If we don't have a host, then use the entire URI (minus the query,
-      // reference, and hash, if possible) as the group.  This means that URIs
-      // like about:mozilla and about:blank will be considered separate groups,
-      // but at least they'll be grouped somehow.
-
-      // This also means that each individual file: URL will be considered
-      // its own group.  This seems suboptimal, but so does treating the entire
-      // file: URL space as a single group (especially if folks start setting
-      // group-specific capabilities prefs).
-
-      // XXX Is there something better we can do here?
-
-      try {
-        var url = aURI.QueryInterface(Ci.nsIURL);
-        group = aURI.prePath + url.filePath;
-      } catch (ex) {
-        group = aURI.spec;
-      }
-    }
-
-    return group;
-  }
-};
-
-function AsyncStatement(aStatement) {
-  this.stmt = aStatement;
-}
-
-AsyncStatement.prototype = {
-  execute: function AsyncStmt_execute(aCallback) {
-    let stmt = this.stmt;
-    stmt.executeAsync({
-      _callback: aCallback,
-      _hadResult: false,
-      handleResult(aResult) {
-        this._hadResult = true;
-        if (this._callback) {
-          let row = aResult.getNextRow();
-          this._callback.onResult(row.getResultByName("value"));
-        }
-      },
-      handleCompletion(aReason) {
-        if (!this._hadResult && this._callback &&
-            aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED)
-          this._callback.onResult(undefined);
-      },
-      handleError(aError) {}
-    });
-  }
-};
-
-// XPCOM Plumbing
-
-var components = [ContentPrefService, HostnameGrouper];
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
-  "extends": [
-    "plugin:mozilla/xpcshell-test"
-  ]
-};
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/head_contentPrefs.js
+++ /dev/null
@@ -1,170 +0,0 @@
-/* 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/. */
-
-// Inspired by the Places infrastructure in head_bookmarks.js
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cr = Components.results;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/ContentPrefInstance.jsm");
-Cu.import("resource://testing-common/TestUtils.jsm");
-
-const CONTENT_PREFS_DB_FILENAME = "content-prefs.sqlite";
-const CONTENT_PREFS_BACKUP_DB_FILENAME = "content-prefs.sqlite.corrupt";
-
-var ContentPrefTest = {
-  // Convenience Getters
-
-  __dirSvc: null,
-  get _dirSvc() {
-    if (!this.__dirSvc)
-      this.__dirSvc = Cc["@mozilla.org/file/directory_service;1"].
-                      getService(Ci.nsIProperties);
-    return this.__dirSvc;
-  },
-
-  __consoleSvc: null,
-  get _consoleSvc() {
-    if (!this.__consoleSvc)
-      this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
-                          getService(Ci.nsIConsoleService);
-    return this.__consoleSvc;
-  },
-
-  __ioSvc: null,
-  get _ioSvc() {
-    if (!this.__ioSvc)
-      this.__ioSvc = Cc["@mozilla.org/network/io-service;1"].
-                     getService(Ci.nsIIOService);
-    return this.__ioSvc;
-  },
-
-
-  // nsISupports
-
-  interfaces: [Ci.nsIDirectoryServiceProvider, Ci.nsISupports],
-
-  QueryInterface: function ContentPrefTest_QueryInterface(iid) {
-    if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
-      throw Cr.NS_ERROR_NO_INTERFACE;
-    return this;
-  },
-
-
-  // nsIDirectoryServiceProvider
-
-  getFile: function ContentPrefTest_getFile(property, persistent) {
-    persistent.value = true;
-
-    if (property == "ProfD")
-      return this._dirSvc.get("CurProcD", Ci.nsIFile);
-
-    // This causes extraneous errors to show up in the log when the directory
-    // service asks us first for CurProcD and MozBinD.  I wish there was a way
-    // to suppress those errors.
-    throw Cr.NS_ERROR_FAILURE;
-  },
-
-
-  // Utilities
-
-  getURI: function ContentPrefTest_getURI(spec) {
-    return this._ioSvc.newURI(spec);
-  },
-
-  /**
-   * Get the profile directory.
-   */
-  getProfileDir: function ContentPrefTest_getProfileDir() {
-    // do_get_profile can be only called from a parent process
-    if (runningInParent) {
-      return do_get_profile();
-    }
-    // if running in a content process, this just returns the path
-    // profile was initialized in the ipc head file
-    let env = Components.classes["@mozilla.org/process/environment;1"]
-                        .getService(Components.interfaces.nsIEnvironment);
-    // the python harness sets this in the environment for us
-    let profd = env.get("XPCSHELL_TEST_PROFILE_DIR");
-    let file = Components.classes["@mozilla.org/file/local;1"]
-                         .createInstance(Components.interfaces.nsIFile);
-    file.initWithPath(profd);
-    return file;
-  },
-
-  /**
-   * Delete the content pref service's persistent datastore.  We do this before
-   * and after running tests to make sure we start from scratch each time. We
-   * also do it during the database creation, schema migration, and backup tests.
-   */
-  deleteDatabase: function ContentPrefTest_deleteDatabase() {
-    var file = this.getProfileDir();
-    file.append(CONTENT_PREFS_DB_FILENAME);
-    if (file.exists())
-      try { file.remove(false); } catch (e) { /* stupid windows box */ }
-    return file;
-  },
-
-  /**
-   * Delete the backup of the content pref service's persistent datastore.
-   * We do this during the database creation, schema migration, and backup tests.
-   */
-  deleteBackupDatabase: function ContentPrefTest_deleteBackupDatabase() {
-    var file = this.getProfileDir();
-    file.append(CONTENT_PREFS_BACKUP_DB_FILENAME);
-    if (file.exists())
-      file.remove(false);
-    return file;
-  },
-
-  /**
-   * Log a message to the console and the test log.
-   */
-  log: function ContentPrefTest_log(message) {
-    message = "*** ContentPrefTest: " + message;
-    this._consoleSvc.logStringMessage(message);
-    print(message);
-  }
-
-};
-
-let loadContext = Cc["@mozilla.org/loadcontext;1"].
-                    createInstance(Ci.nsILoadContext);
-let privateLoadContext = Cc["@mozilla.org/privateloadcontext;1"].
-                           createInstance(Ci.nsILoadContext);
-function enterPBMode(cps) {
-  cps.loadContext = privateLoadContext;
-}
-function exitPBMode(cps) {
-  cps.loadContext = loadContext;
-  Services.obs.notifyObservers(null, "last-pb-context-exited");
-}
-
-ContentPrefTest.deleteDatabase();
-
-do_register_cleanup(function() {
-  ContentPrefTest.deleteDatabase();
-  ContentPrefTest.__dirSvc = null;
-});
-
-function inChildProcess() {
-  var appInfo = Cc["@mozilla.org/xre/app-info;1"];
-  if (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType ==
-      Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
-    return false;
-  }
-  return true;
-}
-
-// Turn on logging for the content preferences service so we can troubleshoot
-// problems with the tests. Note that we cannot do this in a child process
-// without crashing (but we don't need it anyhow)
-if (!inChildProcess()) {
-  var prefBranch = Cc["@mozilla.org/preferences-service;1"].
-                   getService(Ci.nsIPrefBranch);
-  prefBranch.setBoolPref("browser.preferences.content.log", true);
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_bug248970.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* 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/. */
-
-function run_test() {
-    ContentPrefTest.deleteDatabase();
-    var cp = new ContentPrefInstance(loadContext);
-    do_check_neq(cp, null, "Retrieving the content prefs service failed");
-
-    try {
-      const uri1 = ContentPrefTest.getURI("http://www.example.com/");
-      const uri2 = ContentPrefTest.getURI("http://www.anotherexample.com/");
-      const pref_name = "browser.content.full-zoom";
-      const zoomA = 1.5, zoomA_new = 0.8, zoomB = 1.3;
-      // save Zoom-A
-      cp.setPref(uri1, pref_name, zoomA);
-      // make sure Zoom-A is retrievable
-      do_check_eq(cp.getPref(uri1, pref_name), zoomA);
-      // enter private browsing mode
-      enterPBMode(cp);
-      // make sure Zoom-A is retrievable
-      do_check_eq(cp.getPref(uri1, pref_name), zoomA);
-      // save Zoom-B
-      cp.setPref(uri2, pref_name, zoomB);
-      // make sure Zoom-B is retrievable
-      do_check_eq(cp.getPref(uri2, pref_name), zoomB);
-      // update Zoom-A
-      cp.setPref(uri1, pref_name, zoomA_new);
-      // make sure Zoom-A has changed
-      do_check_eq(cp.getPref(uri1, pref_name), zoomA_new);
-      // exit private browsing mode
-      exitPBMode(cp);
-      // make sure Zoom-A change has not persisted
-      do_check_eq(cp.getPref(uri1, pref_name), zoomA);
-      // make sure Zoom-B change has not persisted
-      do_check_eq(cp.hasPref(uri2, pref_name), false);
-    } catch (e) {
-      do_throw("Unexpected exception: " + e);
-    }
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_bug503971.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 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/. */
-
-function run_test() {
-  var cps = new ContentPrefInstance(null);
-
-  var uri = ContentPrefTest.getURI("http://www.example.com/");
-
-  do_check_thrown(function() { cps.setPref(uri, null, 8); });
-  do_check_thrown(function() { cps.hasPref(uri, null); });
-  do_check_thrown(function() { cps.getPref(uri, null); });
-  do_check_thrown(function() { cps.removePref(uri, null); });
-  do_check_thrown(function() { cps.getPrefsByName(null); });
-  do_check_thrown(function() { cps.removePrefsByName(null); });
-
-  do_check_thrown(function() { cps.setPref(uri, "", 21); });
-  do_check_thrown(function() { cps.hasPref(uri, ""); });
-  do_check_thrown(function() { cps.getPref(uri, ""); });
-  do_check_thrown(function() { cps.removePref(uri, ""); });
-  do_check_thrown(function() { cps.getPrefsByName(""); });
-  do_check_thrown(function() { cps.removePrefsByName(""); });
-}
-
-function do_check_thrown(aCallback) {
-  var exThrown = false;
-  try {
-    aCallback();
-    do_throw("NS_ERROR_ILLEGAL_VALUE should have been thrown here");
-  } catch (e) {
-    do_check_eq(e.result, Cr.NS_ERROR_ILLEGAL_VALUE);
-    exThrown = true;
-  }
-  do_check_true(exThrown);
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_bug679784.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* 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/. */
-
-
-var prefObserver = {
-    setCalledNum: 0,
-    onContentPrefSet(aGroup, aName, aValue) {
-        this.setCalledNum++;
-    },
-    removedCalledNum: 0,
-    onContentPrefRemoved(aGroup, aName) {
-        this.removedCalledNum++;
-    }
-};
-
-function run_test() {
-  var cps = new ContentPrefInstance(loadContext);
-  cps.removeGroupedPrefs();
-
-  var uri = ContentPrefTest.getURI("http://www.example.com/");
-  var group = cps.grouper.group(uri);
-
-  // first, set a pref in normal mode
-  cps.setPref(uri, "value", "foo");
-  cps.setPref(null, "value-global", "foo-global");
-
-  var num;
-  cps.addObserver("value", prefObserver);
-  cps.addObserver("value-global", prefObserver);
-
-  enterPBMode(cps);
-
-  // test setPref
-  num = prefObserver.setCalledNum;
-  cps.setPref(uri, "value", "foo-private-browsing");
-  do_check_eq(cps.hasPref(uri, "value"), true);
-  do_check_eq(cps.getPref(uri, "value"), "foo-private-browsing");
-  do_check_eq(prefObserver.setCalledNum, num + 1);
-
-  num = prefObserver.setCalledNum;
-  cps.setPref(null, "value-global", "foo-private-browsing-global");
-  do_check_eq(cps.hasPref(null, "value-global"), true);
-  do_check_eq(cps.getPref(null, "value-global"), "foo-private-browsing-global");
-  do_check_eq(prefObserver.setCalledNum, num + 1);
-
-  // test removePref
-  num = prefObserver.removedCalledNum;
-  cps.removePref(uri, "value");
-  do_check_eq(cps.hasPref(uri, "value"), true);
-  // fallback to non private mode value
-  do_check_eq(cps.getPref(uri, "value"), "foo");
-  do_check_eq(prefObserver.removedCalledNum, num + 1);
-
-  num = prefObserver.removedCalledNum;
-  cps.removePref(null, "value-global");
-  do_check_eq(cps.hasPref(null, "value-global"), true);
-  // fallback to non private mode value
-  do_check_eq(cps.getPref(null, "value-global"), "foo-global") ;
-  do_check_eq(prefObserver.removedCalledNum, num + 1);
-
-  // test removeGroupedPrefs
-  cps.setPref(uri, "value", "foo-private-browsing");
-  cps.removeGroupedPrefs();
-  do_check_eq(cps.hasPref(uri, "value"), false);
-  do_check_eq(cps.getPref(uri, "value"), undefined);
-
-  cps.setPref(null, "value-global", "foo-private-browsing-global");
-  cps.removeGroupedPrefs();
-  do_check_eq(cps.hasPref(null, "value-global"), true);
-  do_check_eq(cps.getPref(null, "value-global"), "foo-private-browsing-global");
-
-  // test removePrefsByName
-  num = prefObserver.removedCalledNum;
-  cps.setPref(uri, "value", "foo-private-browsing");
-  cps.removePrefsByName("value");
-  do_check_eq(cps.hasPref(uri, "value"), false);
-  do_check_eq(cps.getPref(uri, "value"), undefined);
-  do_check_true(prefObserver.removedCalledNum > num);
-
-  num = prefObserver.removedCalledNum;
-  cps.setPref(null, "value-global", "foo-private-browsing");
-  cps.removePrefsByName("value-global");
-  do_check_eq(cps.hasPref(null, "value-global"), false);
-  do_check_eq(cps.getPref(null, "value-global"), undefined);
-  do_check_true(prefObserver.removedCalledNum > num);
-
-  // test getPrefs
-  cps.setPref(uri, "value", "foo-private-browsing");
-  do_check_eq(cps.getPrefs(uri).getProperty("value"), "foo-private-browsing");
-
-  cps.setPref(null, "value-global", "foo-private-browsing-global");
-  do_check_eq(cps.getPrefs(null).getProperty("value-global"), "foo-private-browsing-global");
-
-  // test getPrefsByName
-  do_check_eq(cps.getPrefsByName("value").getProperty(group), "foo-private-browsing");
-  do_check_eq(cps.getPrefsByName("value-global").getProperty(null), "foo-private-browsing-global");
-
-  cps.removeObserver("value", prefObserver);
-  cps.removeObserver("value-global", prefObserver);
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_contentPrefs.js
+++ /dev/null
@@ -1,462 +0,0 @@
-/* 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/. */
-
-
-add_task(async function() {
-  // Database Creation, Schema Migration, and Backup
-
-  // Note: in these tests we use createInstance instead of getService
-  // so we can instantiate the service multiple times and make it run
-  // its database initialization code each time.
-
-  function with_cps_instance(testFn) {
-    let cps = Cc["@mozilla.org/content-pref/service;1"]
-                .createInstance(Ci.nsIContentPrefService)
-                .QueryInterface(Ci.nsIObserver);
-    testFn(cps);
-    let promiseClosed = TestUtils.topicObserved("content-prefs-db-closed");
-    cps.observe(null, "xpcom-shutdown", "");
-    return promiseClosed;
-  }
-
-  // Create a new database.
-  ContentPrefTest.deleteDatabase();
-  await with_cps_instance(cps => {
-    do_check_true(cps.DBConnection.connectionReady);
-  });
-
-  // Open an existing database.
-
-  ContentPrefTest.deleteDatabase();
-  await with_cps_instance(cps => {});
-
-  // Get the service and make sure it has a ready database connection.
-  await with_cps_instance(cps => {
-    do_check_true(cps.DBConnection.connectionReady);
-  });
-
-  // Open an empty database.
-  {
-    let dbFile = ContentPrefTest.deleteDatabase();
-
-    // Create an empty database.
-    let dbService = Cc["@mozilla.org/storage/service;1"].
-                    getService(Ci.mozIStorageService);
-    let dbConnection = dbService.openDatabase(dbFile);
-    do_check_eq(dbConnection.schemaVersion, 0);
-    dbConnection.close();
-    do_check_true(dbFile.exists());
-
-    // Get the service and make sure it has created the schema.
-    await with_cps_instance(cps => {
-      do_check_neq(cps.DBConnection.schemaVersion, 0);
-    });
-  }
-
-  // Open a corrupted database.
-  {
-    let dbFile = ContentPrefTest.deleteDatabase();
-    let backupDBFile = ContentPrefTest.deleteBackupDatabase();
-
-    // Create a corrupted database.
-    let foStream = Cc["@mozilla.org/network/file-output-stream;1"].
-                   createInstance(Ci.nsIFileOutputStream);
-    foStream.init(dbFile, 0x02 | 0x08 | 0x20, 0o666, 0);
-    let garbageData = "garbage that makes SQLite think the file is corrupted";
-    foStream.write(garbageData, garbageData.length);
-    foStream.close();
-
-    // Get the service and make sure it backs up and recreates the database.
-    await with_cps_instance(cps => {
-      do_check_true(backupDBFile.exists());
-      do_check_true(cps.DBConnection.connectionReady);
-    });
-  }
-
-  // Open a database with a corrupted schema.
-  {
-    let dbFile = ContentPrefTest.deleteDatabase();
-    let backupDBFile = ContentPrefTest.deleteBackupDatabase();
-
-    // Create an empty database and set the schema version to a number
-    // that will trigger a schema migration that will fail.
-    let dbService = Cc["@mozilla.org/storage/service;1"].
-                    getService(Ci.mozIStorageService);
-    let dbConnection = dbService.openDatabase(dbFile);
-    dbConnection.schemaVersion = -1;
-    dbConnection.close();
-    do_check_true(dbFile.exists());
-
-    // Get the service and make sure it backs up and recreates the database.
-    await with_cps_instance(cps => {
-      do_check_true(backupDBFile.exists());
-      do_check_true(cps.DBConnection.connectionReady);
-    });
-  }
-
-
-  // Now get the content pref service for real for use by the rest of the tests.
-  let cps = new ContentPrefInstance(null);
-
-  var uri = ContentPrefTest.getURI("http://www.example.com/");
-
-  // Make sure disk synchronization checking is turned off by default.
-  var statement = cps.DBConnection.createStatement("PRAGMA synchronous");
-  try {
-    statement.executeStep();
-    do_check_eq(0, statement.getInt32(0));
-  } finally {
-    statement.finalize();
-  }
-
-  // Nonexistent Pref
-
-  do_check_eq(cps.getPref(uri, "test.nonexistent.getPref"), undefined);
-  do_check_eq(cps.setPref(uri, "test.nonexistent.setPref", 5), undefined);
-  do_check_false(cps.hasPref(uri, "test.nonexistent.hasPref"));
-  do_check_eq(cps.removePref(uri, "test.nonexistent.removePref"), undefined);
-
-
-  // Existing Pref
-
-  cps.setPref(uri, "test.existing", 5);
-
-  // getPref should return the pref value
-  do_check_eq(cps.getPref(uri, "test.existing"), 5);
-
-  // setPref should return undefined and change the value of the pref
-  do_check_eq(cps.setPref(uri, "test.existing", 6), undefined);
-  do_check_eq(cps.getPref(uri, "test.existing"), 6);
-
-  // hasPref should return true
-  do_check_true(cps.hasPref(uri, "test.existing"));
-
-  // removePref should return undefined and remove the pref
-  do_check_eq(cps.removePref(uri, "test.existing"), undefined);
-  do_check_false(cps.hasPref(uri, "test.existing"));
-
-
-  // Round-Trip Data Integrity
-
-  // Make sure pref values remain the same from setPref to getPref.
-
-  cps.setPref(uri, "test.data-integrity.integer", 5);
-  do_check_eq(cps.getPref(uri, "test.data-integrity.integer"), 5);
-
-  cps.setPref(uri, "test.data-integrity.float", 5.5);
-  do_check_eq(cps.getPref(uri, "test.data-integrity.float"), 5.5);
-
-  cps.setPref(uri, "test.data-integrity.boolean", true);
-  do_check_eq(cps.getPref(uri, "test.data-integrity.boolean"), true);
-
-  cps.setPref(uri, "test.data-integrity.string", "test");
-  do_check_eq(cps.getPref(uri, "test.data-integrity.string"), "test");
-
-  cps.setPref(uri, "test.data-integrity.null", null);
-  do_check_eq(cps.getPref(uri, "test.data-integrity.null"), null);
-
-  // XXX Test arbitrary binary data.
-
-  // Make sure hasPref and removePref work on all data types.
-
-  do_check_true(cps.hasPref(uri, "test.data-integrity.integer"));
-  do_check_true(cps.hasPref(uri, "test.data-integrity.float"));
-  do_check_true(cps.hasPref(uri, "test.data-integrity.boolean"));
-  do_check_true(cps.hasPref(uri, "test.data-integrity.string"));
-  do_check_true(cps.hasPref(uri, "test.data-integrity.null"));
-
-  do_check_eq(cps.removePref(uri, "test.data-integrity.integer"), undefined);
-  do_check_eq(cps.removePref(uri, "test.data-integrity.float"), undefined);
-  do_check_eq(cps.removePref(uri, "test.data-integrity.boolean"), undefined);
-  do_check_eq(cps.removePref(uri, "test.data-integrity.string"), undefined);
-  do_check_eq(cps.removePref(uri, "test.data-integrity.null"), undefined);
-
-  do_check_false(cps.hasPref(uri, "test.data-integrity.integer"));
-  do_check_false(cps.hasPref(uri, "test.data-integrity.float"));
-  do_check_false(cps.hasPref(uri, "test.data-integrity.boolean"));
-  do_check_false(cps.hasPref(uri, "test.data-integrity.string"));
-  do_check_false(cps.hasPref(uri, "test.data-integrity.null"));
-
-
-  // getPrefs
-
-  cps.setPref(uri, "test.getPrefs.a", 1);
-  cps.setPref(uri, "test.getPrefs.b", 2);
-  cps.setPref(uri, "test.getPrefs.c", 3);
-
-  var prefs = cps.getPrefs(uri);
-  do_check_true(prefs.hasKey("test.getPrefs.a"));
-  do_check_eq(prefs.get("test.getPrefs.a"), 1);
-  do_check_true(prefs.hasKey("test.getPrefs.b"));
-  do_check_eq(prefs.get("test.getPrefs.b"), 2);
-  do_check_true(prefs.hasKey("test.getPrefs.c"));
-  do_check_eq(prefs.get("test.getPrefs.c"), 3);
-
-
-  // Site-Specificity
-
-  {
-    // These are all different sites, and setting a pref for one of them
-    // shouldn't set it for the others.
-    let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
-    let uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
-    let uri3 = ContentPrefTest.getURI("http://domain1.com/");
-    let uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
-
-    cps.setPref(uri1, "test.site-specificity.uri1", 5);
-    do_check_false(cps.hasPref(uri2, "test.site-specificity.uri1"));
-    do_check_false(cps.hasPref(uri3, "test.site-specificity.uri1"));
-    do_check_false(cps.hasPref(uri4, "test.site-specificity.uri1"));
-
-    cps.setPref(uri2, "test.site-specificity.uri2", 5);
-    do_check_false(cps.hasPref(uri1, "test.site-specificity.uri2"));
-    do_check_false(cps.hasPref(uri3, "test.site-specificity.uri2"));
-    do_check_false(cps.hasPref(uri4, "test.site-specificity.uri2"));
-
-    cps.setPref(uri3, "test.site-specificity.uri3", 5);
-    do_check_false(cps.hasPref(uri1, "test.site-specificity.uri3"));
-    do_check_false(cps.hasPref(uri2, "test.site-specificity.uri3"));
-    do_check_false(cps.hasPref(uri4, "test.site-specificity.uri3"));
-
-    cps.setPref(uri4, "test.site-specificity.uri4", 5);
-    do_check_false(cps.hasPref(uri1, "test.site-specificity.uri4"));
-    do_check_false(cps.hasPref(uri2, "test.site-specificity.uri4"));
-    do_check_false(cps.hasPref(uri3, "test.site-specificity.uri4"));
-  }
-
-  // Observers
-
-  var specificObserver = {
-    interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
-
-    QueryInterface: function ContentPrefTest_QueryInterface(iid) {
-      if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
-        throw Cr.NS_ERROR_NO_INTERFACE;
-      return this;
-    },
-
-    numTimesSetCalled: 0,
-    onContentPrefSet: function specificObserver_onContentPrefSet(group, name, value) {
-      ++this.numTimesSetCalled;
-      do_check_eq(group, "www.example.com");
-      do_check_eq(name, "test.observer.1");
-      do_check_eq(value, "test value");
-    },
-
-    numTimesRemovedCalled: 0,
-    onContentPrefRemoved: function specificObserver_onContentPrefRemoved(group, name) {
-      ++this.numTimesRemovedCalled;
-      do_check_eq(group, "www.example.com");
-      do_check_eq(name, "test.observer.1");
-    }
-
-  };
-
-  var genericObserver = {
-    interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
-
-    QueryInterface: function ContentPrefTest_QueryInterface(iid) {
-      if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
-        throw Cr.NS_ERROR_NO_INTERFACE;
-      return this;
-    },
-
-    numTimesSetCalled: 0,
-    onContentPrefSet: function genericObserver_onContentPrefSet(group, name, value, isPrivate) {
-      ++this.numTimesSetCalled;
-      do_check_eq(group, "www.example.com");
-      if (name == "test.observer.private")
-        do_check_true(isPrivate);
-      else if (name == "test.observer.normal")
-        do_check_false(isPrivate);
-      else if (name != "test.observer.1" && name != "test.observer.2")
-        do_throw("genericObserver.onContentPrefSet: " +
-                 "name not in (test.observer.(1|2|normal|private))");
-      do_check_eq(value, "test value");
-    },
-
-    numTimesRemovedCalled: 0,
-    onContentPrefRemoved: function genericObserver_onContentPrefRemoved(group, name, isPrivate) {
-      ++this.numTimesRemovedCalled;
-      do_check_eq(group, "www.example.com");
-      if (name == "test.observer.private")
-        do_check_true(isPrivate);
-      else if (name == "test.observer.normal")
-        do_check_false(isPrivate);
-      if (name != "test.observer.1" && name != "test.observer.2" &&
-          name != "test.observer.normal" && name != "test.observer.private") {
-        do_throw("genericObserver.onContentPrefSet: " +
-                 "name not in (test.observer.(1|2|normal|private))");
-      }
-    }
-
-  };
-
-  // Make sure we can add observers, observers get notified about changes,
-  // specific observers only get notified about changes to the specific setting,
-  // and generic observers get notified about changes to all settings.
-  cps.addObserver("test.observer.1", specificObserver);
-  cps.addObserver(null, genericObserver);
-  cps.setPref(uri, "test.observer.1", "test value");
-  cps.setPref(uri, "test.observer.2", "test value");
-  cps.removePref(uri, "test.observer.1");
-  cps.removePref(uri, "test.observer.2");
-  do_check_eq(specificObserver.numTimesSetCalled, 1);
-  do_check_eq(genericObserver.numTimesSetCalled, 2);
-  do_check_eq(specificObserver.numTimesRemovedCalled, 1);
-  do_check_eq(genericObserver.numTimesRemovedCalled, 2);
-
-  // Make sure information about private context is properly
-  // retrieved by the observer.
-  cps.setPref(uri, "test.observer.private", "test value", privateLoadContext);
-  cps.setPref(uri, "test.observer.normal", "test value", loadContext);
-  cps.removePref(uri, "test.observer.private");
-  cps.removePref(uri, "test.observer.normal");
-
-  // Make sure we can remove observers and they don't get notified
-  // about changes anymore.
-  cps.removeObserver("test.observer.1", specificObserver);
-  cps.removeObserver(null, genericObserver);
-  cps.setPref(uri, "test.observer.1", "test value");
-  cps.removePref(uri, "test.observer.1", "test value");
-  do_check_eq(specificObserver.numTimesSetCalled, 1);
-  do_check_eq(genericObserver.numTimesSetCalled, 4);
-  do_check_eq(specificObserver.numTimesRemovedCalled, 1);
-  do_check_eq(genericObserver.numTimesRemovedCalled, 3);
-
-
-  // Get/Remove Prefs By Name
-
-  {
-    var anObserver = {
-      interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
-
-      QueryInterface: function ContentPrefTest_QueryInterface(iid) {
-        if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
-          throw Cr.NS_ERROR_NO_INTERFACE;
-        return this;
-      },
-
-      onContentPrefSet: function anObserver_onContentPrefSet(group, name, value) {
-      },
-
-      expectedDomains: [],
-      numTimesRemovedCalled: 0,
-      onContentPrefRemoved: function anObserver_onContentPrefRemoved(group, name) {
-        ++this.numTimesRemovedCalled;
-
-        // remove the domain from the list of expected domains
-        var index = this.expectedDomains.indexOf(group);
-        do_check_true(index >= 0);
-        this.expectedDomains.splice(index, 1);
-      }
-    };
-
-    let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
-    let uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
-    let uri3 = ContentPrefTest.getURI("http://domain1.com/");
-    let uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
-
-    cps.setPref(uri1, "test.byname.1", 1);
-    cps.setPref(uri1, "test.byname.2", 2);
-    cps.setPref(uri2, "test.byname.1", 4);
-    cps.setPref(uri3, "test.byname.3", 8);
-    cps.setPref(uri4, "test.byname.1", 16);
-    cps.setPref(null, "test.byname.1", 32);
-    cps.setPref(null, "test.byname.2", false);
-
-    function enumerateAndCheck(testName, expectedSum, expectedDomains) {
-      var prefsByName = cps.getPrefsByName(testName);
-      var enumerator = prefsByName.enumerator;
-      var sum = 0;
-      while (enumerator.hasMoreElements()) {
-        var property = enumerator.getNext().QueryInterface(Components.interfaces.nsIProperty);
-        sum += parseInt(property.value);
-
-        // remove the domain from the list of expected domains
-        var index = expectedDomains.indexOf(property.name);
-        do_check_true(index >= 0);
-        expectedDomains.splice(index, 1);
-      }
-      do_check_eq(sum, expectedSum);
-      // check all domains have been removed from the array
-      do_check_eq(expectedDomains.length, 0);
-    }
-
-    enumerateAndCheck("test.byname.1", 53,
-      ["foo.domain1.com", null, "www.domain1.com", "www.domain2.com"]);
-    enumerateAndCheck("test.byname.2", 2, ["www.domain1.com", null]);
-    enumerateAndCheck("test.byname.3", 8, ["domain1.com"]);
-
-    cps.addObserver("test.byname.1", anObserver);
-    anObserver.expectedDomains = ["foo.domain1.com", null, "www.domain1.com", "www.domain2.com"];
-
-    cps.removePrefsByName("test.byname.1");
-    do_check_false(cps.hasPref(uri1, "test.byname.1"));
-    do_check_false(cps.hasPref(uri2, "test.byname.1"));
-    do_check_false(cps.hasPref(uri3, "test.byname.1"));
-    do_check_false(cps.hasPref(uri4, "test.byname.1"));
-    do_check_false(cps.hasPref(null, "test.byname.1"));
-    do_check_true(cps.hasPref(uri1, "test.byname.2"));
-    do_check_true(cps.hasPref(uri3, "test.byname.3"));
-
-    do_check_eq(anObserver.numTimesRemovedCalled, 4);
-    do_check_eq(anObserver.expectedDomains.length, 0);
-
-    cps.removeObserver("test.byname.1", anObserver);
-
-    // Clean up after ourselves
-    cps.removePref(uri1, "test.byname.2");
-    cps.removePref(uri3, "test.byname.3");
-    cps.removePref(null, "test.byname.2");
-  }
-
-
-  // Clear Private Data Pref Removal
-
-  {
-    let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
-    let uri2 = ContentPrefTest.getURI("http://www.domain2.com/");
-    let uri3 = ContentPrefTest.getURI("http://www.domain3.com/");
-
-    let dbConnection = cps.DBConnection;
-
-    let prefCount = dbConnection.createStatement("SELECT COUNT(*) AS count FROM prefs");
-
-    let groupCount = dbConnection.createStatement("SELECT COUNT(*) AS count FROM groups");
-
-    // Add some prefs for multiple domains.
-    cps.setPref(uri1, "test.removeAllGroups", 1);
-    cps.setPref(uri2, "test.removeAllGroups", 2);
-    cps.setPref(uri3, "test.removeAllGroups", 3);
-
-    // Add a global pref.
-    cps.setPref(null, "test.removeAllGroups", 1);
-
-    // Make sure there are some prefs and groups in the database.
-    prefCount.executeStep();
-    do_check_true(prefCount.row.count > 0);
-    prefCount.reset();
-    groupCount.executeStep();
-    do_check_true(groupCount.row.count > 0);
-    groupCount.reset();
-
-    // Remove all prefs and groups from the database using the same routine
-    // the Clear Private Data dialog uses.
-    cps.removeGroupedPrefs();
-
-    // Make sure there are no longer any groups in the database and the only pref
-    // is the global one.
-    prefCount.executeStep();
-    do_check_true(prefCount.row.count == 1);
-    prefCount.reset();
-    groupCount.executeStep();
-    do_check_true(groupCount.row.count == 0);
-    groupCount.reset();
-    let globalPref = dbConnection.createStatement("SELECT groupID FROM prefs");
-    globalPref.executeStep();
-    do_check_true(globalPref.row.groupID == null);
-    globalPref.reset();
-  }
-});
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_contentPrefsCache.js
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var cps = new ContentPrefInstance(null);
-
-function run_test() {
-  testCacheWorks("test1.example.com", "test-pref1");
-  testHasCachedPrefFunction("test2.example.com", "test-pref2");
-  testSetCaches("test3.example.com", "test-pref3");
-  testGetCaches("test4.example.com", "test-pref4");
-  testRemovePrefs("test5.example.com", "test-pref5");
-  testTypeConversions("test6.example.com", "test-pref6");
-  testNonExistingPrefCachesAsUndefined("test7.example.com", "test-pref7");
-  testCacheEviction("test8.example.com", "test-pref8");
-}
-
-function testCacheWorks(uri, prefName) {
-  const CACHED_VALUE = 3;
-  const NEW_VALUE = 5;
-
-  cps.setPref(uri, prefName, CACHED_VALUE);
-  do_check_eq(cps.getPref(uri, prefName), CACHED_VALUE);
-
-  // Now change the value directly through the DB and check
-  // that the cached value is different
-
-  let groupId = selectValue("SELECT id FROM groups WHERE name = :param1", "id", uri);
-  let settingId = selectValue("SELECT id FROM settings WHERE name = :param1", "id", prefName);
-  let prefId = selectValue("SELECT id FROM prefs WHERE groupID = :param1 AND settingID = :param2",
-                           "id", groupId, settingId);
-
-  let stmt = cps.DBConnection.createStatement("UPDATE prefs SET value = :value WHERE id = :id");
-  stmt.params.value = NEW_VALUE;
-  stmt.params.id = prefId;
-  stmt.execute();
-
-  let dbValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
-  let cacheValue = cps.getPref(uri, prefName);
-
-  do_check_eq(dbValue, NEW_VALUE);
-  do_check_eq(cacheValue, CACHED_VALUE);
-  do_check_neq(cacheValue, dbValue);
-
-  do_test_pending();
-  cps.getPref(uri, prefName, function(value) {
-    do_check_eq(dbValue, NEW_VALUE);
-    do_check_eq(value, CACHED_VALUE);
-    do_check_neq(value, dbValue);
-    do_test_finished();
-  });
-}
-
-function testHasCachedPrefFunction(uri, prefName) {
-  const STARTING_VALUE = 3;
-  const NEW_VALUE = 5;
-
-  do_check_false(isCached(uri, prefName));
-
-  cps.setPref(uri, prefName, STARTING_VALUE);
-
-  let groupId = selectValue("SELECT id FROM groups WHERE name = :param1", "id", uri);
-  let settingId = selectValue("SELECT id FROM settings WHERE name = :param1", "id", prefName);
-  let prefId = selectValue("SELECT id FROM prefs WHERE groupID = :param1 AND settingID = :param2",
-                       "id", groupId, settingId);
-
-  do_check_neq(prefId, undefined);
-
-  let originalValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
-  do_check_eq(originalValue, STARTING_VALUE);
-
-  let stmt = cps.DBConnection.createStatement("UPDATE prefs SET value = :value WHERE id = :id");
-  stmt.params.value = NEW_VALUE;
-  stmt.params.id = prefId;
-  stmt.execute();
-
-  let newValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
-  do_check_eq(newValue, NEW_VALUE);
-
-  let cachedValue = cps.getPref(uri, prefName);
-  do_check_eq(cachedValue, STARTING_VALUE);
-  do_check_true(isCached(uri, prefName));
-}
-
-function testSetCaches(uri, prefName) {
-  cps.setPref(uri, prefName, 0);
-  do_check_true(isCached(uri, prefName));
-}
-
-function testRemovePrefs(uri, prefName) {
-
-  /* removePref */
-  cps.setPref("www1." + uri, prefName, 1);
-
-  do_check_eq(cps.getPref("www1." + uri, prefName), 1);
-
-  cps.removePref("www1." + uri, prefName);
-
-  do_check_false(isCached("www1." + uri, prefName));
-  do_check_false(cps.hasPref("www1." + uri, prefName));
-  do_check_neq(cps.getPref("www1." + uri, prefName), 1);
-
-  /* removeGroupedPrefs */
-  cps.setPref("www2." + uri, prefName, 2);
-  cps.setPref("www3." + uri, prefName, 3);
-
-  do_check_eq(cps.getPref("www2." + uri, prefName), 2);
-  do_check_eq(cps.getPref("www3." + uri, prefName), 3);
-
-  cps.removeGroupedPrefs();
-
-  do_check_false(isCached("www2." + uri, prefName));
-  do_check_false(isCached("www3." + uri, prefName));
-  do_check_false(cps.hasPref("www2." + uri, prefName));
-  do_check_false(cps.hasPref("www3." + uri, prefName));
-  do_check_neq(cps.getPref("www2." + uri, prefName), 2);
-  do_check_neq(cps.getPref("www3." + uri, prefName), 3);
-
-  /* removePrefsByName */
-  cps.setPref("www4." + uri, prefName, 4);
-  cps.setPref("www5." + uri, prefName, 5);
-
-  do_check_eq(cps.getPref("www4." + uri, prefName), 4);
-  do_check_eq(cps.getPref("www5." + uri, prefName), 5);
-
-  cps.removePrefsByName(prefName);
-
-  do_check_false(isCached("www4." + uri, prefName));
-  do_check_false(isCached("www5." + uri, prefName));
-  do_check_false(cps.hasPref("www4." + uri, prefName));
-  do_check_false(cps.hasPref("www5." + uri, prefName));
-  do_check_neq(cps.getPref("www4." + uri, prefName), 4);
-  do_check_neq(cps.getPref("www5." + uri, prefName), 5);
-}
-
-function testGetCaches(uri, prefName) {
-  const VALUE = 4;
-
-  let insertGroup = cps.DBConnection.createStatement("INSERT INTO groups (name) VALUES (:name)");
-  insertGroup.params.name = uri;
-  insertGroup.execute();
-  let groupId = cps.DBConnection.lastInsertRowID;
-
-  let insertSetting = cps.DBConnection.createStatement("INSERT INTO settings (name) VALUES (:name)");
-  insertSetting.params.name = prefName;
-  insertSetting.execute();
-  let settingId = cps.DBConnection.lastInsertRowID;
-
-  let insertPref = cps.DBConnection.createStatement(`
-    INSERT INTO prefs (groupID, settingID, value)
-    VALUES (:groupId, :settingId, :value)
-  `);
-  insertPref.params.groupId = groupId;
-  insertPref.params.settingId = settingId;
-  insertPref.params.value = VALUE;
-  insertPref.execute();
-  let prefId = cps.DBConnection.lastInsertRowID;
-
-  let dbValue = selectValue("SELECT value FROM prefs WHERE id = :param1", "value", prefId);
-
-  // First access from service should hit the DB
-  let svcValue = cps.getPref(uri, prefName);
-
-  // Second time should get the value from cache
-  let cacheValue = cps.getPref(uri, prefName);
-
-  do_check_eq(VALUE, dbValue);
-  do_check_eq(VALUE, svcValue);
-  do_check_eq(VALUE, cacheValue);
-
-  do_check_true(isCached(uri, prefName));
-}
-
-function testTypeConversions(uri, prefName) {
-  let value;
-
-  cps.setPref(uri, prefName, true);
-  value = cps.getPref(uri, prefName);
-  do_check_true(value === 1);
-
-  cps.setPref(uri, prefName, false);
-  value = cps.getPref(uri, prefName);
-  do_check_true(value === 0);
-
-  cps.setPref(uri, prefName, null);
-  value = cps.getPref(uri, prefName);
-  do_check_true(value === null);
-
-  cps.setPref(uri, prefName, undefined);
-  value = cps.getPref(uri, prefName);
-  do_check_true(value === null);
-}
-
-function testNonExistingPrefCachesAsUndefined(uri, prefName) {
-
-  do_check_false(isCached(uri, prefName));
-
-  // Cache the pref
-  let value = cps.getPref(uri, prefName);
-  do_check_true(value === undefined);
-
-  do_check_true(isCached(uri, prefName));
-
-  // Cached pref
-  value = cps.getPref(uri, prefName);
-  do_check_true(value === undefined);
-}
-
-function testCacheEviction(uri, prefName) {
-
-  cps.setPref(uri, prefName, 5);
-  do_check_eq(cps.getPref(uri, prefName), 5);
-  do_check_true(isCached(uri, prefName));
-
-  // try to evict value from cache by adding various other entries
-  const ENTRIES_TO_ADD = 200;
-  for (let i = 0; i < ENTRIES_TO_ADD; i++) {
-    let uriToAdd = "www" + i + uri;
-    cps.setPref(uriToAdd, prefName, 0);
-  }
-
-  do_check_false(isCached(uri, prefName));
-
-}
-
-function selectValue(stmt, columnName, param1, param2) {
-  stmt = cps.DBConnection.createStatement(stmt);
-  if (param1)
-    stmt.params.param1 = param1;
-
-  if (param2)
-    stmt.params.param2 = param2;
-
-  stmt.executeStep();
-  let val = stmt.row[columnName];
-  stmt.reset();
-  stmt.finalize();
-  return val;
-}
-
-function isCached(uri, prefName) {
-  return cps.hasCachedPref(uri, prefName);
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_getPrefAsync.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* 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/. */
-var cps = new ContentPrefInstance(null);
-var uri = ContentPrefTest.getURI("http://www.example.com/");
-
-function run_test() {
-  do_test_pending();
-
-  cps.setPref(uri, "asynctest", "pie");
-  do_check_eq(cps.getPref(uri, "asynctest"), "pie");
-
-  cps.getPref(uri, "asynctest", function(aValue) {
-    do_check_eq(aValue, "pie");
-    testCallbackObj();
-  });
-}
-
-function testCallbackObj() {
-  cps.getPref(uri, "asynctest", {
-    onResult(aValue) {
-      do_check_eq(aValue, "pie");
-      cps.removePref(uri, "asynctest");
-      testNoResult();
-    }
-  });
-}
-
-function testNoResult() {
-  cps.getPref(uri, "asynctest", function(aValue) {
-    do_check_eq(aValue, undefined);
-    do_test_finished();
-  });
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_stringGroups.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/* 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/. */
-
-function run_test() {
-
-  var cps = new ContentPrefInstance(null);
-
-  // Make sure disk synchronization checking is turned off by default.
-  var statement = cps.DBConnection.createStatement("PRAGMA synchronous");
-  statement.executeStep();
-  do_check_eq(0, statement.getInt32(0));
-
-  // These are the different types of aGroup arguments we'll test.
-  var anObject = {"foo": "bar"};                               // a simple object
-  var uri = ContentPrefTest.getURI("http://www.example.com/"); // nsIURI
-  var stringURI = "www.example.com";                           // typeof = "string"
-
-  // Test wants to check for a String object
-  // eslint-disable-next-line no-new-wrappers
-  var stringObjectURI = new String("www.example.com");         // typeof = "object"
-
-  // First check that all the methods work or don't work.
-  function simple_test_methods(aGroup, shouldThrow) {
-    var prefName = "test.pref.0";
-    var prefValue = Math.floor(Math.random() * 100);
-
-    if (shouldThrow) {
-      do_check_thrown(function() { cps.getPref(aGroup, prefName); });
-      do_check_thrown(function() { cps.setPref(aGroup, prefName, prefValue); });
-      do_check_thrown(function() { cps.hasPref(aGroup, prefName); });
-      do_check_thrown(function() { cps.removePref(aGroup, prefName); });
-      do_check_thrown(function() { cps.getPrefs(aGroup); });
-    } else {
-      do_check_eq(cps.setPref(aGroup, prefName, prefValue), undefined);
-      do_check_true(cps.hasPref(aGroup, prefName));
-      do_check_eq(cps.getPref(aGroup, prefName), prefValue);
-      do_check_eq(cps.removePref(aGroup, prefName), undefined);
-      do_check_false(cps.hasPref(aGroup, prefName));
-    }
-  }
-
-  simple_test_methods(cps, true); // arbitrary nsISupports object, should throw too
-  simple_test_methods(anObject, true);
-  simple_test_methods(uri, false);
-  simple_test_methods(stringURI, false);
-  simple_test_methods(stringObjectURI, false);
-
-  // Now we'll check that each argument produces the same result.
-  function complex_test_methods(aGroup) {
-    var prefName = "test.pref.1";
-    var prefValue = Math.floor(Math.random() * 100);
-
-    do_check_eq(cps.setPref(aGroup, prefName, prefValue), undefined);
-
-    do_check_true(cps.hasPref(uri, prefName));
-    do_check_true(cps.hasPref(stringURI, prefName));
-    do_check_true(cps.hasPref(stringObjectURI, prefName));
-
-    do_check_eq(cps.getPref(uri, prefName), prefValue);
-    do_check_eq(cps.getPref(stringURI, prefName), prefValue);
-    do_check_eq(cps.getPref(stringObjectURI, prefName), prefValue);
-
-    do_check_eq(cps.removePref(aGroup, prefName), undefined);
-
-    do_check_false(cps.hasPref(uri, prefName));
-    do_check_false(cps.hasPref(stringURI, prefName));
-    do_check_false(cps.hasPref(stringObjectURI, prefName));
-  }
-
-  complex_test_methods(uri);
-  complex_test_methods(stringURI);
-  complex_test_methods(stringObjectURI);
-
-  // test getPrefs returns the same prefs
-  do_check_eq(cps.setPref(stringObjectURI, "test.5", 5), undefined);
-  do_check_eq(cps.setPref(stringURI, "test.2", 2), undefined);
-  do_check_eq(cps.setPref(uri, "test.1", 1), undefined);
-
-  enumerateAndCheck(cps.getPrefs(uri), 8, ["test.1", "test.2", "test.5"]);
-  enumerateAndCheck(cps.getPrefs(stringURI), 8, ["test.1", "test.2", "test.5"]);
-  enumerateAndCheck(cps.getPrefs(stringObjectURI), 8, ["test.1", "test.2", "test.5"]);
-
-  do_check_eq(cps.setPref(uri, "test.4", 4), undefined);
-  do_check_eq(cps.setPref(stringObjectURI, "test.0", 0), undefined);
-
-  enumerateAndCheck(cps.getPrefs(uri), 12, ["test.0", "test.1", "test.2", "test.4", "test.5"]);
-  enumerateAndCheck(cps.getPrefs(stringURI), 12, ["test.0", "test.1", "test.2", "test.4", "test.5"]);
-  enumerateAndCheck(cps.getPrefs(stringObjectURI), 12, ["test.0", "test.1", "test.2", "test.4", "test.5"]);
-
-  do_check_eq(cps.setPref(stringURI, "test.3", 3), undefined);
-
-  enumerateAndCheck(cps.getPrefs(uri), 15, ["test.0", "test.1", "test.2", "test.3", "test.4", "test.5"]);
-  enumerateAndCheck(cps.getPrefs(stringURI), 15, ["test.0", "test.1", "test.2", "test.3", "test.4", "test.5"]);
-  enumerateAndCheck(cps.getPrefs(stringObjectURI), 15, ["test.0", "test.1", "test.2", "test.3", "test.4", "test.5"]);
-}
-
-function do_check_thrown(aCallback) {
-  var exThrown = false;
-  try {
-    aCallback();
-    do_throw("NS_ERROR_ILLEGAL_VALUE should have been thrown here");
-  } catch (e) {
-    do_check_eq(e.result, Cr.NS_ERROR_ILLEGAL_VALUE);
-    exThrown = true;
-  }
-  do_check_true(exThrown);
-}
-
-function enumerateAndCheck(prefs, expectedSum, expectedNames) {
-  var enumerator = prefs.enumerator;
-  var sum = 0;
-  while (enumerator.hasMoreElements()) {
-    var property = enumerator.getNext().QueryInterface(Components.interfaces.nsIProperty);
-    sum += parseInt(property.value);
-
-    // remove the pref name from the list of expected names
-    var index = expectedNames.indexOf(property.name);
-    do_check_true(index >= 0);
-    expectedNames.splice(index, 1);
-  }
-  do_check_eq(sum, expectedSum);
-  // check all pref names have been removed from the array
-  do_check_eq(expectedNames.length, 0);
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/test_unusedGroupsAndSettings.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 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/. */
-
-var cps = new ContentPrefInstance(null);
-
-function run_test() {
-  var uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
-  var uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
-  var uri3 = ContentPrefTest.getURI("http://domain1.com/");
-  var uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
-
-  cps.setPref(uri1, "one", 1);
-  cps.setPref(uri1, "two", 2);
-  cps.setPref(uri2, "one", 4);
-  cps.setPref(uri3, "three", 8);
-  cps.setPref(uri4, "two", 16);
-
-  cps.removePref(uri3, "three"); // uri3 should be removed now
-  checkForUnusedGroups();
-  checkForUnusedSettings();
-
-  cps.removePrefsByName("two"); // uri4 should be removed now
-  checkForUnusedGroups();
-  checkForUnusedSettings();
-
-  cps.removeGroupedPrefs();
-  checkForUnusedGroups();
-  checkForUnusedSettings();
-}
-
-function checkForUnusedGroups() {
-  var stmt = cps.DBConnection.createStatement(`
-               SELECT COUNT(*) AS count FROM groups
-               WHERE id NOT IN (SELECT DISTINCT groupID FROM prefs)
-             `);
-  stmt.executeStep();
-  do_check_eq(0, stmt.row.count);
-  stmt.reset();
-  stmt.finalize();
-}
-
-function checkForUnusedSettings() {
-  var stmt = cps.DBConnection.createStatement(`
-               SELECT COUNT(*) AS count FROM settings
-               WHERE id NOT IN (SELECT DISTINCT settingID FROM prefs)
-             `);
-  stmt.executeStep();
-  do_check_eq(0, stmt.row.count);
-  stmt.reset();
-  stmt.finalize();
-}
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-head = head_contentPrefs.js
-
-[test_bug248970.js]
-[test_bug503971.js]
-[test_bug679784.js]
-[test_contentPrefs.js]
-[test_contentPrefsCache.js]
-[test_getPrefAsync.js]
-[test_stringGroups.js]
-[test_unusedGroupsAndSettings.js]
deleted file mode 100644
--- a/toolkit/components/contentprefs/tests/unit_cps2/test_service.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* 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/. */
-
-function run_test() {
-  let serv = Cc["@mozilla.org/content-pref/service;1"].
-             getService(Ci.nsIContentPrefService2);
-  do_check_eq(serv.QueryInterface(Ci.nsIContentPrefService2), serv);
-  do_check_eq(serv.QueryInterface(Ci.nsISupports), serv);
-  let val = serv.QueryInterface(Ci.nsIContentPrefService);
-  do_check_true(val instanceof Ci.nsIContentPrefService);
-}
--- a/toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini
+++ b/toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini
@@ -1,14 +1,13 @@
 [DEFAULT]
 head = head.js
 skip-if = toolkit == 'android'
 support-files = AsyncRunner.jsm
 
-[test_service.js]
 [test_setGet.js]
 [test_getSubdomains.js]
 [test_remove.js]
 [test_removeByDomain.js]
 [test_removeAllDomains.js]
 [test_removeByName.js]
 [test_getCached.js]
 [test_getCachedSubdomains.js]
--- a/toolkit/modules/Services.jsm
+++ b/toolkit/modules/Services.jsm
@@ -67,17 +67,16 @@ XPCOMUtils.defineLazyGetter(Services, "i
 });
 
 var initTable = {
   appShell: ["@mozilla.org/appshell/appShellService;1", "nsIAppShellService"],
   cache: ["@mozilla.org/network/cache-service;1", "nsICacheService"],
   cache2: ["@mozilla.org/netwerk/cache-storage-service;1", "nsICacheStorageService"],
   cpmm: ["@mozilla.org/childprocessmessagemanager;1", "nsIMessageSender"],
   console: ["@mozilla.org/consoleservice;1", "nsIConsoleService"],
-  contentPrefs: ["@mozilla.org/content-pref/service;1", "nsIContentPrefService"],
   cookies: ["@mozilla.org/cookiemanager;1", "nsICookieManager2"],
   downloads: ["@mozilla.org/download-manager;1", "nsIDownloadManager"],
   droppedLinkHandler: ["@mozilla.org/content/dropped-link-handler;1", "nsIDroppedLinkHandler"],
   els: ["@mozilla.org/eventlistenerservice;1", "nsIEventListenerService"],
   eTLD: ["@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"],
   intl: ["@mozilla.org/mozintl;1", "mozIMozIntl"],
   locale: ["@mozilla.org/intl/localeservice;1", "mozILocaleService"],
   logins: ["@mozilla.org/login-manager;1", "nsILoginManager"],
--- a/toolkit/modules/tests/xpcshell/test_Services.js
+++ b/toolkit/modules/tests/xpcshell/test_Services.js
@@ -28,17 +28,16 @@ function run_test() {
 
   checkService("appShell", Ci.nsIAppShellService);
   checkService("appinfo", Ci.nsIXULRuntime);
   checkService("blocklist", Ci.nsIBlocklistService);
   checkService("cache", Ci.nsICacheService);
   checkService("cache2", Ci.nsICacheStorageService);
   checkService("clipboard", Ci.nsIClipboard);
   checkService("console", Ci.nsIConsoleService);
-  checkService("contentPrefs", Ci.nsIContentPrefService);
   checkService("cookies", Ci.nsICookieManager2);
   checkService("dirsvc", Ci.nsIDirectoryService);
   checkService("dirsvc", Ci.nsIProperties);
   checkService("DOMRequest", Ci.nsIDOMRequestService);
   checkService("domStorageManager", Ci.nsIDOMStorageManager);
   checkService("downloads", Ci.nsIDownloadManager);
   checkService("droppedLinkHandler", Ci.nsIDroppedLinkHandler);
   checkService("eTLD", Ci.nsIEffectiveTLDService);
--- a/toolkit/mozapps/downloads/DownloadLastDir.jsm
+++ b/toolkit/mozapps/downloads/DownloadLastDir.jsm
@@ -108,35 +108,16 @@ DownloadLastDir.prototype = {
     return this.fakeContext.usePrivateBrowsing;
   },
   // compat shims
   get file() { return this._getLastFile(); },
   set file(val) { this.setFile(null, val); },
   cleanupPrivateFile() {
     gDownloadLastDirFile = null;
   },
-  // This function is now deprecated as it uses the sync nsIContentPrefService
-  // interface. New consumers should use the getFileAsync function.
-  getFile(aURI) {
-    let Deprecated = Components.utils.import("resource://gre/modules/Deprecated.jsm", {}).Deprecated;
-    Deprecated.warning("DownloadLastDir.getFile is deprecated. Please use getFileAsync instead.",
-                       "https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/DownloadLastDir.jsm",
-                       Components.stack.caller);
-
-    if (aURI && isContentPrefEnabled()) {
-      let lastDir = Services.contentPrefs.getPref(aURI, LAST_DIR_PREF, this.fakeContext);
-      if (lastDir) {
-        var lastDirFile = Components.classes["@mozilla.org/file/local;1"]
-                                    .createInstance(Components.interfaces.nsIFile);
-        lastDirFile.initWithPath(lastDir);
-        return lastDirFile;
-      }
-    }
-    return this._getLastFile();
-  },
 
   _getLastFile() {
     if (gDownloadLastDirFile && !gDownloadLastDirFile.exists())
       gDownloadLastDirFile = null;
 
     if (this.isPrivate()) {
       if (!gDownloadLastDirFile)
         gDownloadLastDirFile = readLastDirPref();