Merge autoland to mozilla-central. a=merge
authorGurzau Raul <rgurzau@mozilla.com>
Mon, 29 Oct 2018 23:59:38 +0200
changeset 443417 b851d42e26209d66cf854f4464d637fa943e98a6
parent 443290 f7a97b344fa59bd3b01ea81ebd5b150aa63bfb12 (current diff)
parent 443416 a799f209a66e93f584093a4f6d141266a2df6f7c (diff)
child 443418 4c7772c170a1848c4e57fea0087c351fd2288859
push id109362
push userrgurzau@mozilla.com
push dateMon, 29 Oct 2018 22:12:05 +0000
treeherdermozilla-inbound@1c7d0042fc4a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
browser/components/pocket/content/panels/tmpl/ho2/ho2_sharebutton_v1.handlebars
browser/components/pocket/content/panels/tmpl/ho2/ho2_sharebutton_v2.handlebars
browser/components/pocket/content/panels/tmpl/ho2/ho2_sharebutton_v3.handlebars
editor/libeditor/TextEditorTest.cpp
editor/libeditor/TextEditorTest.h
extensions/auth/nsAuthFactory.cpp
testing/web-platform/meta/css/css-grid/parsing/grid-area-invalid.html.ini
testing/web-platform/tests/webdriver/tests/conftest.py
toolkit/themes/linux/global/icons/blacklist_favicon.png
toolkit/themes/linux/global/icons/blacklist_large.png
toolkit/themes/osx/global/icons/blacklist_64.png
toolkit/themes/osx/global/icons/blacklist_favicon.png
toolkit/themes/windows/global/icons/blacklist_favicon.png
toolkit/themes/windows/global/icons/blacklist_large.png
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -274,21 +274,19 @@ pref("browser.urlbar.doubleClickSelectsA
 // browser.fixup.alternate.suffix to the URL bar value prior to
 // navigating.
 pref("browser.urlbar.ctrlCanonizesURLs", true);
 
 // Control autoFill behavior
 pref("browser.urlbar.autoFill", true);
 pref("browser.urlbar.speculativeConnect.enabled", true);
 
-// 0: Match anywhere (e.g., middle of words)
-// 1: Match on word boundaries and then try matching anywhere
-// 2: Match only on word boundaries (e.g., after / or .)
-// 3: Match at the beginning of the url or title
-pref("browser.urlbar.matchBehavior", 1);
+// Whether bookmarklets should be filtered out of Address Bar matches.
+// This is enabled for security reasons, when true it is still possible to
+// search for bookmarklets typing "javascript: " followed by the actual query.
 pref("browser.urlbar.filter.javascript", true);
 
 // the maximum number of results to show in autocomplete when doing richResults
 pref("browser.urlbar.maxRichResults", 10);
 // The amount of time (ms) to wait after the user has stopped typing
 // before starting to perform autocomplete.  50 is the default set in
 // autocomplete.xml.
 pref("browser.urlbar.delay", 50);
@@ -1139,17 +1137,16 @@ pref("services.sync.prefs.sync.accessibi
 pref("services.sync.prefs.sync.accessibility.typeaheadfind", true);
 pref("services.sync.prefs.sync.accessibility.typeaheadfind.linksonly", true);
 pref("services.sync.prefs.sync.addons.ignoreUserEnabledChanges", true);
 // The addons prefs related to repository verification are intentionally
 // not synced for security reasons. If a system is compromised, a user
 // could weaken the pref locally, install an add-on from an untrusted
 // source, and this would propagate automatically to other,
 // uncompromised Sync-connected devices.
-pref("services.sync.prefs.sync.browser.contentblocking.enabled", true);
 pref("services.sync.prefs.sync.browser.ctrlTab.recentlyUsedOrder", true);
 pref("services.sync.prefs.sync.browser.download.useDownloadDir", true);
 pref("services.sync.prefs.sync.browser.formfill.enable", true);
 pref("services.sync.prefs.sync.browser.link.open_newwindow", true);
 pref("services.sync.prefs.sync.browser.newtabpage.enabled", true);
 pref("services.sync.prefs.sync.browser.newtabpage.pinned", true);
 pref("services.sync.prefs.sync.browser.offline-apps.notify", true);
 pref("services.sync.prefs.sync.browser.safebrowsing.phishing.enabled", true);
--- a/browser/base/content/blockedSite.xhtml
+++ b/browser/base/content/blockedSite.xhtml
@@ -10,21 +10,21 @@
   <!ENTITY % blockedSiteDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
   %blockedSiteDTD;
 ]>
 
 <!-- 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/. -->
 
-<html xmlns="http://www.w3.org/1999/xhtml" class="blacklist">
+<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Security-Policy" content="default-src chrome:" />
     <link rel="stylesheet" href="chrome://browser/skin/blockedSite.css" type="text/css" media="all" />
-    <link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/blacklist_favicon.png"/>
+    <link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/blocklist_favicon.png"/>
   </head>
   <body dir="&locale.dir;">
     <div id="errorPageContainer" class="container">
 
       <!-- Error Title -->
       <div id="errorTitle" class="title">
         <h1 class="title-text" id="errorTitleText_phishing">&safeb.blocked.phishingPage.title3;</h1>
         <h1 class="title-text" id="errorTitleText_malware">&safeb.blocked.malwarePage.title2;</h1>
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -124,17 +124,16 @@ var ThirdPartyCookies = {
            (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_FOREIGN) != 0;
   },
 };
 
 
 var ContentBlocking = {
   // If the user ignores the doorhanger, we stop showing it after some time.
   MAX_INTROS: 20,
-  PREF_ENABLED: "browser.contentblocking.enabled",
   PREF_ANIMATIONS_ENABLED: "toolkit.cosmeticAnimations.enabled",
   PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.reportBreakage.enabled",
   PREF_REPORT_BREAKAGE_URL: "browser.contentblocking.reportBreakage.url",
   PREF_INTRO_COUNT_CB: "browser.contentblocking.introCount",
   content: null,
   icon: null,
   activeTooltipText: null,
   disabledTooltipText: null,
@@ -211,23 +210,19 @@ var ContentBlocking = {
         blocker.init();
       }
     }
 
     this.updateAnimationsEnabled();
 
     Services.prefs.addObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
 
-    XPCOMUtils.defineLazyPreferenceGetter(this, "contentBlockingEnabled", this.PREF_ENABLED, false,
-      this.updateEnabled.bind(this));
     XPCOMUtils.defineLazyPreferenceGetter(this, "reportBreakageEnabled",
       this.PREF_REPORT_BREAKAGE_ENABLED, false);
 
-    this.updateEnabled();
-
     this.appMenuLabel.setAttribute("label", this.strings.appMenuTitle);
     this.appMenuLabel.setAttribute("tooltiptext", this.strings.appMenuTooltip);
 
     this.activeTooltipText =
       gNavigatorBundle.getString("trackingProtection.icon.activeTooltip");
     this.disabledTooltipText =
       gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip");
   },
@@ -237,29 +232,16 @@ var ContentBlocking = {
       if (blocker.uninit) {
         blocker.uninit();
       }
     }
 
     Services.prefs.removeObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
   },
 
-  get enabled() {
-    return this.contentBlockingEnabled;
-  },
-
-  updateEnabled() {
-    this.content.toggleAttribute("enabled", this.enabled);
-
-    // The enabled state of blockers may also change since it depends on this.enabled.
-    for (let blocker of this.blockers) {
-      blocker.categoryItem.classList.toggle("blocked", this.enabled && blocker.enabled);
-    }
-  },
-
   hideIdentityPopupAndReload() {
     document.getElementById("identity-popup").hidePopup();
     BrowserReload();
   },
 
   openPreferences(origin) {
     openPreferences("privacy-trackingprotection", { origin });
   },
@@ -361,42 +343,42 @@ var ContentBlocking = {
     let anyBlockerActivated = false;
 
     for (let blocker of this.blockers) {
       // Store data on whether the blocker is activated in the current document for
       // reporting it using the "report breakage" dialog. Under normal circumstances this
       // dialog should only be able to open in the currently selected tab and onSecurityChange
       // runs on tab switch, so we can avoid associating the data with the document directly.
       blocker.activated = blocker.isBlockerActivated(state);
-      blocker.categoryItem.classList.toggle("blocked", this.enabled && blocker.enabled);
+      blocker.categoryItem.classList.toggle("blocked", blocker.enabled);
       blocker.categoryItem.hidden = !blocker.visible;
       anyBlockerActivated = anyBlockerActivated || blocker.activated;
     }
 
     // We consider the shield state "active" when some kind of blocking activity
     // occurs on the page.  Note that merely allowing the loading of content that
     // we could have blocked does not trigger the appearance of the shield.
     // This state will be overriden later if there's an exception set for this site.
-    let active = this.enabled && anyBlockerActivated;
+    let active = anyBlockerActivated;
     let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
     let detected = anyBlockerActivated || isAllowing;
 
     let isBrowserPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);
 
     // Check whether the user has added an exception for this site.
     let type =  isBrowserPrivate ? "trackingprotection-pb" : "trackingprotection";
     let hasException = Services.perms.testExactPermission(baseURI, type) ==
       Services.perms.ALLOW_ACTION;
 
     this.content.toggleAttribute("detected", detected);
     this.content.toggleAttribute("hasException", hasException);
     this.content.toggleAttribute("active", active);
 
     this.iconBox.toggleAttribute("active", active);
-    this.iconBox.toggleAttribute("hasException", this.enabled && hasException);
+    this.iconBox.toggleAttribute("hasException", hasException);
 
     // For release (due to the large volume) we only want to receive reports
     // for breakage that is directly related to third party cookie blocking.
     if (this.reportBreakageEnabled ||
         (ThirdPartyCookies.reportBreakageEnabled &&
          ThirdPartyCookies.activated &&
          !TrackingProtection.activated)) {
       this.reportBreakageButton.removeAttribute("hidden");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3775,17 +3775,17 @@ const BrowserSearch = {
 
   delayedStartupInit() {
     // Asynchronously initialize the search service if necessary, to get the
     // current engine for working out the placeholder.
     Services.search.init(rv => {
       if (Components.isSuccessCode(rv)) {
         // Delay the update for this until so that we don't change it while
         // the user is looking at it / isn't expecting it.
-        this._updateURLBarPlaceholder(Services.search.currentEngine, true);
+        this._updateURLBarPlaceholder(Services.search.defaultEngine, true);
         this._searchInitComplete = true;
       }
     });
   },
 
   uninit() {
     Services.obs.removeObserver(this, "browser-search-engine-modified");
   },
@@ -4067,27 +4067,21 @@ const BrowserSearch = {
    *        A string meant to indicate the context of the search request. This
    *        allows the search service to provide a different nsISearchSubmission
    *        depending on e.g. where the search is triggered in the UI.
    *
    * @return engine The search engine used to perform a search, or null if no
    *                search was performed.
    */
   _loadSearch(searchText, useNewTab, purpose, triggeringPrincipal) {
-    let engine;
     if (!triggeringPrincipal) {
       throw new Error("Required argument triggeringPrincipal missing within _loadSearch");
     }
 
-    // If the search bar is visible, use the current engine, otherwise, fall
-    // back to the default engine.
-    if (isElementVisible(this.searchBar))
-      engine = Services.search.currentEngine;
-    else
-      engine = Services.search.defaultEngine;
+    let engine = Services.search.defaultEngine;
 
     let submission = engine.getSubmission(searchText, null, purpose); // HTML response
 
     // getSubmission can return null if the engine doesn't have a URL
     // with a text/html response type.  This is unlikely (since
     // SearchService._addEngineToStore() should fail for such an engine),
     // but let's be on the safe side.
     if (!submission) {
@@ -8060,17 +8054,17 @@ const SafeBrowsingNotificationBox = {
     let previousNotification = notificationBox.getNotificationWithValue(value);
     if (previousNotification) {
       notificationBox.removeNotification(previousNotification);
     }
 
     let notification = notificationBox.appendNotification(
       title,
       value,
-      "chrome://global/skin/icons/blacklist_favicon.png",
+      "chrome://global/skin/icons/blocklist_favicon.png",
       notificationBox.PRIORITY_CRITICAL_HIGH,
       buttons
     );
     // Persist the notification until the user removes so it
     // doesn't get removed on redirects.
     notification.persistence = -1;
   },
   onLocationChange(aLocationURI) {
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1501,17 +1501,17 @@ nsContextMenu.prototype = {
       let truncLength = 15;
       let truncChar = selectedText[15].charCodeAt(0);
       if (truncChar >= 0xDC00 && truncChar <= 0xDFFF)
         truncLength++;
       selectedText = selectedText.substr(0, truncLength) + this.ellipsis;
     }
 
     // format "Search <engine> for <selection>" string to show in menu
-    let engineName = Services.search.currentEngine.name;
+    let engineName = Services.search.defaultEngine.name;
     var menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch",
                                                         [engineName,
                                                          selectedText]);
     menuItem.label = menuLabel;
     menuItem.accessKey = gNavigatorBundle.getString("contextMenuSearch.accesskey");
   },
 
   createContainerMenu(aEvent) {
--- a/browser/base/content/test/general/browser_tabfocus.js
+++ b/browser/base/content/test/general/browser_tabfocus.js
@@ -445,17 +445,20 @@ function compareFocusResults() {
     is(fm.focusedWindow, matchWindow, currentTestName + " focusedWindow");
     var focusedWindow = {};
     is(getId(fm.getFocusedElementForWindow(matchWindow, false, focusedWindow)),
        _expectedElement, currentTestName + " getFocusedElementForWindow");
     is(focusedWindow.value, matchWindow, currentTestName + " getFocusedElementForWindow frame");
     is(matchWindow.document.hasFocus(), true, currentTestName + " hasFocus");
     var expectedActive = _expectedElement;
     if (!expectedActive) {
-      expectedActive = matchWindow.document instanceof XULDocument ?
+      // Documents that have a XUL document element currently have a different
+      // active element behavior than regular HTML documents. This test will
+      // need to be updated when bug 1492582 is fixed.
+      expectedActive = matchWindow.document.documentElement instanceof XULElement ?
                        "main-window" : getId(matchWindow.document.body);
     }
     is(getId(matchWindow.document.activeElement), expectedActive, currentTestName + " activeElement");
 
     currentPromiseResolver();
     currentPromiseResolver = null;
   });
 }
--- a/browser/base/content/test/performance/browser_urlbar_keyed_search.js
+++ b/browser/base/content/test/performance/browser_urlbar_keyed_search.js
@@ -18,17 +18,18 @@ requestLongerTimeout(5);
 const EXPECTED_REFLOWS_FIRST_OPEN = [];
 if (AppConstants.DEBUG ||
     AppConstants.platform == "win" ||
     AppConstants.platform == "macosx") {
   EXPECTED_REFLOWS_FIRST_OPEN.push({
     stack: [
       "_rebuild@chrome://browser/content/search/search-one-offs.js",
       "set popup@chrome://browser/content/search/search-one-offs.js",
-      "set_oneOffSearchesEnabled@chrome://browser/content/urlbarBindings.xml",
+      "_syncOneOffSearchesEnabled@chrome://browser/content/urlbarBindings.xml",
+      "toggleOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "_enableOrDisableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "@chrome://browser/content/urlbarBindings.xml",
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/autocomplete.xml",
       "set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
     ],
   });
--- a/browser/base/content/test/performance/browser_urlbar_search.js
+++ b/browser/base/content/test/performance/browser_urlbar_search.js
@@ -19,17 +19,18 @@ const EXPECTED_REFLOWS_FIRST_OPEN = [];
 if (AppConstants.DEBUG ||
     AppConstants.platform == "linux" ||
     AppConstants.platform == "macosx" ||
     AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
   EXPECTED_REFLOWS_FIRST_OPEN.push({
     stack: [
       "_rebuild@chrome://browser/content/search/search-one-offs.js",
       "set popup@chrome://browser/content/search/search-one-offs.js",
-      "set_oneOffSearchesEnabled@chrome://browser/content/urlbarBindings.xml",
+      "_syncOneOffSearchesEnabled@chrome://browser/content/urlbarBindings.xml",
+      "toggleOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "_enableOrDisableOneOffSearches@chrome://browser/content/urlbarBindings.xml",
       "@chrome://browser/content/urlbarBindings.xml",
       "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml",
       "openPopup@chrome://global/content/bindings/autocomplete.xml",
       "set_popupOpen@chrome://global/content/bindings/autocomplete.xml",
     ],
   });
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -1,15 +1,16 @@
 [DEFAULT]
 tags = trackingprotection
 support-files =
   head.js
   benignPage.html
   cookiePage.html
   cookieServer.sjs
+  trackingAPI.js
   trackingPage.html
 
 [browser_trackingUI_3.js]
 [browser_trackingUI_animation.js]
 [browser_trackingUI_animation_2.js]
 [browser_trackingUI_appMenu.js]
 [browser_trackingUI_fetch.js]
 support-files =
--- a/browser/base/content/test/trackingUI/browser_trackingUI_animation_2.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_animation_2.js
@@ -1,25 +1,27 @@
 /*
  * Test that the Content Blocking icon is properly animated in the identity
  * block when loading tabs and switching between tabs.
  * See also Bug 1175858.
  */
 
-const CB_PREF = "browser.contentblocking.enabled";
 const TP_PREF = "privacy.trackingprotection.enabled";
 const TP_PB_PREF = "privacy.trackingprotection.enabled";
+const NCB_PREF = "network.cookie.cookieBehavior";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
+const COOKIE_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/cookiePage.html";
 
 registerCleanupFunction(function() {
   UrlClassifierTestUtils.cleanupTestTrackers();
   Services.prefs.clearUserPref(TP_PREF);
   Services.prefs.clearUserPref(TP_PB_PREF);
-  Services.prefs.clearUserPref(CB_PREF);
+  Services.prefs.clearUserPref(NCB_PREF);
+  Services.prefs.clearUserPref(ContentBlocking.prefIntroCount);
 });
 
 function waitForSecurityChange(tabbrowser, numChanges = 1) {
   return new Promise(resolve => {
     let n = 0;
     let listener = {
       onSecurityChange() {
         n = n + 1;
@@ -42,72 +44,151 @@ async function testTrackingProtectionAni
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "iconBox not active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   info("Load a test page containing tracking elements");
   let trackingTab = await BrowserTestUtils.openNewForegroundTab(tabbrowser, TRACKING_PAGE);
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(ContentBlocking.iconBox.hasAttribute("animate"), "iconBox animating");
+  await BrowserTestUtils.waitForEvent(ContentBlocking.animatedIcon, "animationend");
 
-  info("Switch from tracking -> benign tab");
+  info("Load a test page containing tracking cookies");
+  let trackingCookiesTab = await BrowserTestUtils.openNewForegroundTab(tabbrowser, COOKIE_PAGE);
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(ContentBlocking.iconBox.hasAttribute("animate"), "iconBox animating");
+  await BrowserTestUtils.waitForEvent(ContentBlocking.animatedIcon, "animationend");
+
+  info("Switch from tracking cookie -> benign tab");
   let securityChanged = waitForSecurityChange(tabbrowser);
   tabbrowser.selectedTab = benignTab;
   await securityChanged;
 
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "iconBox not active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   info("Switch from benign -> tracking tab");
   securityChanged = waitForSecurityChange(tabbrowser);
   tabbrowser.selectedTab = trackingTab;
   await securityChanged;
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
-  info("Reload tracking tab");
+  info("Switch from tracking -> tracking cookies tab");
+  securityChanged = waitForSecurityChange(tabbrowser);
+  tabbrowser.selectedTab = trackingCookiesTab;
+  await securityChanged;
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
+
+  info("Reload tracking cookies tab");
   securityChanged = waitForSecurityChange(tabbrowser, 2);
   tabbrowser.reload();
   await securityChanged;
 
   ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
   ok(ContentBlocking.iconBox.hasAttribute("animate"), "iconBox animating");
+  await BrowserTestUtils.waitForEvent(ContentBlocking.animatedIcon, "animationend");
+
+  info("Reload tracking tab");
+  securityChanged = waitForSecurityChange(tabbrowser, 3);
+  tabbrowser.selectedTab = trackingTab;
+  tabbrowser.reload();
+  await securityChanged;
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(ContentBlocking.iconBox.hasAttribute("animate"), "iconBox animating");
+  await BrowserTestUtils.waitForEvent(ContentBlocking.animatedIcon, "animationend");
+
+  info("Inject tracking cookie inside tracking tab");
+  securityChanged = waitForSecurityChange(tabbrowser);
+  await ContentTask.spawn(tabbrowser.selectedBrowser, {},
+                          function() {
+    content.postMessage("cookie", "*");
+  });
+  await securityChanged;
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
+
+  info("Inject tracking element inside tracking tab");
+  securityChanged = waitForSecurityChange(tabbrowser);
+  await ContentTask.spawn(tabbrowser.selectedBrowser, {},
+                          function() {
+    content.postMessage("tracking", "*");
+  });
+  await securityChanged;
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
+
+  tabbrowser.selectedTab = trackingCookiesTab;
+
+  info("Inject tracking cookie inside tracking cookies tab");
+  securityChanged = waitForSecurityChange(tabbrowser);
+  await ContentTask.spawn(tabbrowser.selectedBrowser, {},
+                          function() {
+    content.postMessage("cookie", "*");
+  });
+  await securityChanged;
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
+
+  info("Inject tracking element inside tracking cookies tab");
+  securityChanged = waitForSecurityChange(tabbrowser);
+  await ContentTask.spawn(tabbrowser.selectedBrowser, {},
+                          function() {
+    content.postMessage("tracking", "*");
+  });
+  await securityChanged;
+
+  ok(ContentBlocking.iconBox.hasAttribute("active"), "iconBox active");
+  ok(!ContentBlocking.iconBox.hasAttribute("animate"), "iconBox not animating");
 
   while (tabbrowser.tabs.length > 1) {
     tabbrowser.removeCurrentTab();
   }
 }
 
 add_task(async function testNormalBrowsing() {
   await UrlClassifierTestUtils.addTestTrackers();
 
   let ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the browser window");
   let TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
   ok(TrackingProtection, "TP is attached to the browser window");
+  let ThirdPartyCookies = gBrowser.ownerGlobal.ThirdPartyCookies;
+  ok(ThirdPartyCookies, "TPC is attached to the browser window");
 
   Services.prefs.setBoolPref(TP_PREF, true);
   ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
+  Services.prefs.setIntPref(NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER);
+  ok(ThirdPartyCookies.enabled, "ThirdPartyCookies is enabled after setting the pref");
+  Services.prefs.setIntPref(ContentBlocking.prefIntroCount, ContentBlocking.MAX_INTROS);
 
   await testTrackingProtectionAnimation(gBrowser);
 });
 
 add_task(async function testPrivateBrowsing() {
   let privateWin = await BrowserTestUtils.openNewBrowserWindow({private: true});
   let tabbrowser = privateWin.gBrowser;
 
   let ContentBlocking = tabbrowser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the private window");
   let TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
   ok(TrackingProtection, "TP is attached to the private window");
+  let ThirdPartyCookies = tabbrowser.ownerGlobal.ThirdPartyCookies;
+  ok(ThirdPartyCookies, "TPC is attached to the browser window");
 
   Services.prefs.setBoolPref(TP_PB_PREF, true);
   ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(TrackingProtection.enabled, "CB is enabled after setting the pref");
+  Services.prefs.setIntPref(NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER);
+  ok(ThirdPartyCookies.enabled, "ThirdPartyCookies is enabled after setting the pref");
+  Services.prefs.setIntPref(ContentBlocking.prefIntroCount, ContentBlocking.MAX_INTROS);
 
   await testTrackingProtectionAnimation(tabbrowser);
 
   privateWin.close();
 });
--- a/browser/base/content/test/trackingUI/browser_trackingUI_fetch.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_fetch.js
@@ -15,30 +15,28 @@ function waitForSecurityChange(numChange
     };
     gBrowser.addProgressListener(listener);
   });
 }
 
 add_task(async function test_fetch() {
   await SpecialPowers.pushPrefEnv({ set: [
     ["privacy.trackingprotection.enabled", true],
-    ["browser.contentblocking.enabled", true],
   ]});
 
   await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(newTabBrowser) {
     let securityChange = waitForSecurityChange();
     await ContentTask.spawn(newTabBrowser, null, async function() {
       await content.wrappedJSObject.test_fetch()
                    .then(response => Assert.ok(false, "should have denied the request"))
                    .catch(e => Assert.ok(true, `Caught exception: ${e}`));
     });
     await securityChange;
 
     let ContentBlocking = newTabBrowser.ownerGlobal.ContentBlocking;
     ok(ContentBlocking, "got CB object");
-    ok(ContentBlocking.enabled, "CB is enabled");
 
     ok(ContentBlocking.content.hasAttribute("detected"), "has detected content blocking");
     ok(ContentBlocking.iconBox.hasAttribute("active"), "icon box is active");
     is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
        gNavigatorBundle.getString("trackingProtection.icon.activeTooltip"), "correct tooltip");
   });
 });
--- a/browser/base/content/test/trackingUI/browser_trackingUI_open_preferences.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_open_preferences.js
@@ -1,14 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const CB_PREF = "browser.contentblocking.enabled";
 const TP_PREF = "privacy.trackingprotection.enabled";
 const FB_PREF = "browser.fastblock.enabled";
 const TPC_PREF = "network.cookie.cookieBehavior";
 const FB_UI_PREF = "browser.contentblocking.fastblock.control-center.ui.enabled";
 const TP_UI_PREF = "browser.contentblocking.trackingprotection.control-center.ui.enabled";
 const RT_UI_PREF = "browser.contentblocking.rejecttrackers.control-center.ui.enabled";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 
@@ -62,17 +61,16 @@ add_task(async function testOpenPreferen
     is(clickEvents.length, 1, "recorded telemetry for the click");
   });
 });
 
 // Tests that clicking the contentblocking category items "add blocking" labels
 // links to about:preferences
 add_task(async function testOpenPreferencesFromAddBlockingButtons() {
   SpecialPowers.pushPrefEnv({set: [
-    [CB_PREF, true],
     [FB_PREF, false],
     [TP_PREF, false],
     [TPC_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT],
     [FB_UI_PREF, true],
     [TP_UI_PREF, true],
     [RT_UI_PREF, true],
   ]});
 
--- a/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
@@ -1,24 +1,22 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that sites added to the Tracking Protection whitelist in private
 // browsing mode don't persist once the private browsing window closes.
 
-const CB_PREF = "browser.contentblocking.enabled";
 const TP_PB_PREF = "privacy.trackingprotection.enabled";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 var TrackingProtection = null;
 var ContentBlocking = null;
 var browser = null;
 
 registerCleanupFunction(function() {
   Services.prefs.clearUserPref(TP_PB_PREF);
-  Services.prefs.clearUserPref(CB_PREF);
   ContentBlocking = TrackingProtection = browser = null;
   UrlClassifierTestUtils.cleanupTestTrackers();
 });
 
 function hidden(sel) {
   let win = browser.ownerGlobal;
   let el = win.document.querySelector(sel);
   let display = win.getComputedStyle(el).getPropertyValue("display", null);
@@ -100,18 +98,16 @@ add_task(async function testExceptionAdd
 
   ContentBlocking = browser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the private window");
   TrackingProtection = browser.ownerGlobal.TrackingProtection;
   ok(TrackingProtection, "TP is attached to the private window");
 
   Services.prefs.setBoolPref(TP_PB_PREF, true);
   ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(TrackingProtection.enabled, "CB is enabled after setting the pref");
 
   info("Load a test page containing tracking elements");
   await promiseTabLoadEvent(tab, TRACKING_PAGE);
 
   testTrackingPage(tab.ownerGlobal);
 
   info("Disable TP for the page (which reloads the page)");
   let tabReloadPromise = promiseTabLoadEvent(tab);
@@ -137,17 +133,16 @@ add_task(async function testExceptionPer
   browser = privateWin.gBrowser;
   let tab = await BrowserTestUtils.openNewForegroundTab({ gBrowser: browser, waitForLoad: true, waitForStateStop: true });
 
   ContentBlocking = browser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the private window");
   TrackingProtection = browser.ownerGlobal.TrackingProtection;
   ok(TrackingProtection, "TP is attached to the private window");
 
-  ok(ContentBlocking.enabled, "CB is still enabled");
   ok(TrackingProtection.enabled, "TP is still enabled");
 
   info("Load a test page containing tracking elements");
   await promiseTabLoadEvent(tab, TRACKING_PAGE);
 
   testTrackingPage(tab.ownerGlobal);
 
   info("Disable TP for the page (which reloads the page)");
--- a/browser/base/content/test/trackingUI/browser_trackingUI_report_breakage.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_report_breakage.js
@@ -2,17 +2,16 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
 const COOKIE_PAGE = "http://not-tracking.example.com/browser/browser/base/content/test/trackingUI/cookiePage.html";
 
-const CB_PREF = "browser.contentblocking.enabled";
 const TP_PREF = "privacy.trackingprotection.enabled";
 const PREF_REPORT_BREAKAGE_ENABLED = "browser.contentblocking.reportBreakage.enabled";
 const PREF_REPORT_BREAKAGE_URL = "browser.contentblocking.reportBreakage.url";
 
 let {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js", {});
 let {CommonUtils} = ChromeUtils.import("resource://services-common/utils.js", {});
 let {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm", {});
 
@@ -34,63 +33,49 @@ function openIdentityPopup() {
   return viewShown;
 }
 
 add_task(async function testReportBreakageVisibility() {
   let scenarios = [
     {
       url: TRACKING_PAGE,
       prefs: {
-        "browser.contentblocking.enabled": true,
         "privacy.trackingprotection.enabled": true,
         "browser.contentblocking.reportBreakage.enabled": true,
       },
       buttonVisible: true,
     },
     {
       url: TRACKING_PAGE,
       hasException: true,
       prefs: {
-        "browser.contentblocking.enabled": true,
         "privacy.trackingprotection.enabled": true,
         "browser.contentblocking.reportBreakage.enabled": true,
       },
       buttonVisible: true,
     },
     {
       url: TRACKING_PAGE,
       prefs: {
-        "browser.contentblocking.enabled": false,
-        "privacy.trackingprotection.enabled": true,
-        "browser.contentblocking.reportBreakage.enabled": true,
-      },
-      buttonVisible: false,
-    },
-    {
-      url: TRACKING_PAGE,
-      prefs: {
-        "browser.contentblocking.enabled": true,
         "privacy.trackingprotection.enabled": true,
         "browser.contentblocking.reportBreakage.enabled": false,
       },
       buttonVisible: false,
     },
     {
       url: BENIGN_PAGE,
       prefs: {
-        "browser.contentblocking.enabled": true,
         "privacy.trackingprotection.enabled": true,
         "browser.contentblocking.reportBreakage.enabled": true,
       },
       buttonVisible: false,
     },
     {
       url: COOKIE_PAGE,
       prefs: {
-        "browser.contentblocking.enabled": true,
         "privacy.trackingprotection.enabled": false,
         "network.cookie.cookieBehavior": Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
         "browser.contentblocking.reportBreakage.enabled": false,
         "browser.contentblocking.rejecttrackers.reportBreakage.enabled": true,
       },
       buttonVisible: true,
     },
   ];
@@ -117,17 +102,16 @@ add_task(async function testReportBreaka
     for (let pref in scenario.prefs) {
       Services.prefs.clearUserPref(pref);
     }
   }
 });
 
 add_task(async function testReportBreakageCancel() {
   Services.prefs.setBoolPref(TP_PREF, true);
-  Services.prefs.setBoolPref(CB_PREF, true);
   Services.prefs.setBoolPref(PREF_REPORT_BREAKAGE_ENABLED, true);
 
   await BrowserTestUtils.withNewTab(TRACKING_PAGE, async function() {
     await openIdentityPopup();
 
     Services.telemetry.clearEvents();
 
     let reportBreakageButton = document.getElementById("identity-popup-content-blocking-report-breakage");
@@ -148,30 +132,28 @@ add_task(async function testReportBreaka
     viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
     let cancelButton = document.getElementById("identity-popup-breakageReportView-cancel");
     cancelButton.click();
     await viewShown;
 
     ok(true, "Main view was shown");
   });
 
-  Services.prefs.clearUserPref(CB_PREF);
   Services.prefs.clearUserPref(TP_PREF);
   Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_ENABLED);
 });
 
 add_task(async function testReportBreakage() {
   // Setup a mock server for receiving breakage reports.
   let server = new HttpServer();
   server.start(-1);
   let i = server.identity;
   let path = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort + "/";
 
   Services.prefs.setBoolPref(TP_PREF, true);
-  Services.prefs.setBoolPref(CB_PREF, true);
   Services.prefs.setBoolPref(PREF_REPORT_BREAKAGE_ENABLED, true);
   Services.prefs.setStringPref(PREF_REPORT_BREAKAGE_URL, path);
 
   // Make sure that we correctly strip the query.
   let url = TRACKING_PAGE + "?a=b&1=abc&unicode=šŸ¦Š";
   await BrowserTestUtils.withNewTab(url, async function() {
     await openIdentityPopup();
 
@@ -243,23 +225,21 @@ add_task(async function testReportBreaka
     });
 
     await popuphidden;
   });
 
   // Stop the server.
   await new Promise(r => server.stop(r));
 
-  Services.prefs.clearUserPref(CB_PREF);
   Services.prefs.clearUserPref(TP_PREF);
   Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_ENABLED);
   Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_URL);
 });
 
 add_task(async function cleanup() {
   // Clear prefs that are touched in this test again for sanity.
-  Services.prefs.clearUserPref(CB_PREF);
   Services.prefs.clearUserPref(TP_PREF);
   Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_ENABLED);
   Services.prefs.clearUserPref(PREF_REPORT_BREAKAGE_URL);
 
   UrlClassifierTestUtils.cleanupTestTrackers();
 });
--- a/browser/base/content/test/trackingUI/browser_trackingUI_state.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_state.js
@@ -9,17 +9,16 @@
  *     3) A page with tracking elements is loaded and they are not blocked.
  *   With TP disabled
  *     1) A page with no tracking elements is loaded.
  *     2) A page with tracking elements is loaded.
  *
  * See also Bugs 1175327, 1043801, 1178985
  */
 
-const CB_PREF = "browser.contentblocking.enabled";
 const TP_PREF = "privacy.trackingprotection.enabled";
 const TP_PB_PREF = "privacy.trackingprotection.pbmode.enabled";
 const TPC_PREF = "network.cookie.cookieBehavior";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 const COOKIE_PAGE = "http://not-tracking.example.com/browser/browser/base/content/test/trackingUI/cookiePage.html";
 var ContentBlocking = null;
 var TrackingProtection = null;
@@ -28,17 +27,16 @@ var tabbrowser = null;
 var gTrackingPageURL = TRACKING_PAGE;
 
 registerCleanupFunction(function() {
   TrackingProtection = ContentBlocking =
     ThirdPartyCookies = tabbrowser = null;
   UrlClassifierTestUtils.cleanupTestTrackers();
   Services.prefs.clearUserPref(TP_PREF);
   Services.prefs.clearUserPref(TP_PB_PREF);
-  Services.prefs.clearUserPref(CB_PREF);
   Services.prefs.clearUserPref(TPC_PREF);
 });
 
 // This is a special version of "hidden" that doesn't check for item
 // visibility and just asserts the display and opacity attributes.
 // That way we can test elements even when their panel is hidden...
 function hidden(sel) {
   let win = tabbrowser.ownerGlobal;
@@ -62,54 +60,47 @@ function testBenignPage() {
 
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
   ok(!ContentBlocking.iconBox.hasAttribute("hasException"), "icon box shows no exception");
   ok(!ContentBlocking.iconBox.hasAttribute("tooltiptext"), "icon box has no tooltip");
 
   ok(BrowserTestUtils.is_hidden(ContentBlocking.iconBox), "icon box is hidden");
   ok(hidden("#tracking-action-block"), "blockButton is hidden");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-  is(!hidden("#identity-popup-content-blocking-disabled-label"), !ContentBlocking.enabled,
-    "disabled label is visible if CB is off");
+  ok(hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is not visible");
 
   ok(!hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is visible");
   ok(hidden("#identity-popup-content-blocking-detected"), "blocking detected label is hidden");
   ok(hidden("#identity-popup-content-blocking-category-list"), "category list is hidden");
 }
 
 function testBenignPageWithException() {
   info("Non-tracking content must not be blocked");
   ok(!ContentBlocking.content.hasAttribute("detected"), "no trackers are detected");
   ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
   ok(!ContentBlocking.content.hasAttribute("active"), "content is not active");
 
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
-  is(ContentBlocking.iconBox.hasAttribute("hasException"), ContentBlocking.enabled,
-    "shield shows exception if CB is on");
+  ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
   is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
      gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
 
-  is(!BrowserTestUtils.is_hidden(ContentBlocking.iconBox), ContentBlocking.enabled,
-    "icon box is not hidden if CB is on");
-  is(!hidden("#tracking-action-block"), ContentBlocking.enabled,
-     "blockButton is visible if CB is on");
+  ok(!BrowserTestUtils.is_hidden(ContentBlocking.iconBox), "icon box is not hidden");
+  ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
   ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is visible");
   ok(hidden("#identity-popup-content-blocking-detected"), "blocking detected label is hidden");
   ok(hidden("#identity-popup-content-blocking-category-list"), "category list is hidden");
 }
 
 function areTrackersBlocked(isPrivateBrowsing) {
-  let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
-  let blockedByTP = cbEnabled &&
-                    Services.prefs.getBoolPref(isPrivateBrowsing ? TP_PB_PREF : TP_PREF);
-  let blockedByTPC = cbEnabled &&
-                     Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
+  let blockedByTP = Services.prefs.getBoolPref(isPrivateBrowsing ? TP_PB_PREF : TP_PREF);
+  let blockedByTPC = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
   return blockedByTP || blockedByTPC;
 }
 
 function testTrackingPage(window) {
   info("Tracking content must be blocked");
   ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
   ok(!ContentBlocking.content.hasAttribute("hasException"), "content shows no exception");
 
@@ -164,28 +155,24 @@ function testTrackingPage(window) {
   }
 }
 
 function testTrackingPageUnblocked(blockedByTP, window) {
   info("Tracking content must be white-listed and not blocked");
   ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
   ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
 
-  let blockingEnabled = Services.prefs.getBoolPref(CB_PREF);
   ok(!ContentBlocking.content.hasAttribute("active"), "content is not active");
   ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
-  is(ContentBlocking.iconBox.hasAttribute("hasException"), blockingEnabled,
-     "shield" + (blockingEnabled ? " shows" : " doesn't show") + " exception");
+  ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
   is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
      gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
 
-  is(BrowserTestUtils.is_visible(ContentBlocking.iconBox), blockingEnabled,
-     "icon box is" + (blockingEnabled ? "" : " not") + " visible");
-  is(hidden("#tracking-action-block"), !blockingEnabled,
-     "blockButton is" + (blockingEnabled ? " not" : "") + " visible");
+  ok(BrowserTestUtils.is_visible(ContentBlocking.iconBox), "icon box is visible");
+  ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
   ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
   let category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
@@ -193,42 +180,17 @@ function testTrackingPageUnblocked(block
                "#identity-popup-content-blocking-category-tracking-protection";
   is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
     "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
   // Always hidden no matter if blockedByTP or not, since we have an exception.
   ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
     "TP category item is not set to blocked");
 }
 
-function testTrackingPageWithCBDisabled() {
-  info("Tracking content must be white-listed and not blocked");
-  ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
-  ok(!ContentBlocking.content.hasAttribute("hasException"), "content shows no exception");
-  ok(!ContentBlocking.content.hasAttribute("active"), "content is not active");
-
-  ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is not active");
-  ok(!ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows no exception");
-  ok(!ContentBlocking.iconBox.getAttribute("tooltiptext"), "icon box has no tooltip");
-
-  ok(BrowserTestUtils.is_hidden(ContentBlocking.iconBox), "icon box is hidden");
-  ok(hidden("#tracking-action-block"), "blockButton is hidden");
-  ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
-  ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
-
-  ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
-  ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
-
-  ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
-  ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-add-blocking"),
-    "TP category item is showing add blocking");
-  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
-    "TP category item is not set to blocked");
-}
-
-async function testContentBlockingEnabled(tab) {
+async function testContentBlocking(tab) {
   info("Testing with Tracking Protection ENABLED.");
 
   info("Load a test page not containing tracking elements");
   await promiseTabLoadEvent(tab, BENIGN_PAGE);
   testBenignPage();
 
   info("Load a test page not containing tracking elements which has an exception.");
   let isPrivateBrowsing = PrivateBrowsingUtils.isWindowPrivate(tab.ownerGlobal);
@@ -261,79 +223,37 @@ async function testContentBlockingEnable
 
   info("Re-enable TP for the page (which reloads the page)");
   tabReloadPromise = promiseTabLoadEvent(tab);
   clickButton("#tracking-action-block");
   await tabReloadPromise;
   testTrackingPage(tab.ownerGlobal);
 }
 
-async function testContentBlockingDisabled(tab) {
-  info("Testing with Tracking Protection DISABLED.");
-
-  info("Load a test page not containing tracking elements");
-  await promiseTabLoadEvent(tab, BENIGN_PAGE);
-  testBenignPage();
-
-  info("Load a test page not containing tracking elements which has an exception.");
-  let isPrivateBrowsing = PrivateBrowsingUtils.isWindowPrivate(tab.ownerGlobal);
-  let uri = Services.io.newURI("https://example.org/");
-  if (isPrivateBrowsing) {
-    PrivateBrowsingUtils.addToTrackingAllowlist(uri);
-  } else {
-    Services.perms.add(uri, "trackingprotection", Services.perms.ALLOW_ACTION);
-  }
-
-  await promiseTabLoadEvent(tab, uri.spec);
-  testBenignPageWithException();
-
-  if (isPrivateBrowsing) {
-    PrivateBrowsingUtils.removeFromTrackingAllowlist(uri);
-  } else {
-    Services.perms.remove(uri, "trackingprotection");
-  }
-
-  info("Load a test page containing tracking elements");
-  await promiseTabLoadEvent(tab, gTrackingPageURL);
-  testTrackingPageWithCBDisabled();
-}
-
 add_task(async function testNormalBrowsing() {
   await UrlClassifierTestUtils.addTestTrackers();
 
   tabbrowser = gBrowser;
   let tab = tabbrowser.selectedTab = BrowserTestUtils.addTab(tabbrowser);
 
   ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the browser window");
   TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
   ok(TrackingProtection, "TP is attached to the browser window");
   is(TrackingProtection.enabled, Services.prefs.getBoolPref(TP_PREF),
      "TP.enabled is based on the original pref value");
 
   Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT);
 
-  await testContentBlockingEnabled(tab);
-
-  Services.prefs.setBoolPref(CB_PREF, false);
-  ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
-
-  await testContentBlockingDisabled(tab);
+  await testContentBlocking(tab);
 
   Services.prefs.setBoolPref(TP_PREF, true);
   ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
 
-  await testContentBlockingEnabled(tab);
-
-  Services.prefs.setBoolPref(CB_PREF, false);
-  ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
-
-  await testContentBlockingDisabled(tab);
+  await testContentBlocking(tab);
 
   gBrowser.removeCurrentTab();
 
   Services.prefs.clearUserPref(TPC_PREF);
 });
 
 add_task(async function testPrivateBrowsing() {
   let privateWin = await BrowserTestUtils.openNewBrowserWindow({private: true});
@@ -347,34 +267,22 @@ add_task(async function testPrivateBrows
 
   ContentBlocking = tabbrowser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the private window");
   TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
   ok(TrackingProtection, "TP is attached to the private window");
   is(TrackingProtection.enabled, Services.prefs.getBoolPref(TP_PB_PREF),
      "TP.enabled is based on the pb pref value");
 
-  await testContentBlockingEnabled(tab);
-
-  Services.prefs.setBoolPref(CB_PREF, false);
-  ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
-
-  await testContentBlockingDisabled(tab);
+  await testContentBlocking(tab);
 
   Services.prefs.setBoolPref(TP_PB_PREF, true);
   ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(TrackingProtection.enabled, "CB is enabled after setting the pref");
 
-  await testContentBlockingEnabled(tab);
-
-  Services.prefs.setBoolPref(CB_PREF, false);
-  ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
-
-  await testContentBlockingDisabled(tab);
+  await testContentBlocking(tab);
 
   privateWin.close();
 
   Services.prefs.clearUserPref(TPC_PREF);
 });
 
 add_task(async function testThirdPartyCookies() {
   await UrlClassifierTestUtils.addTestTrackers();
@@ -385,33 +293,19 @@ add_task(async function testThirdPartyCo
 
   ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
   ok(ContentBlocking, "CB is attached to the browser window");
   ThirdPartyCookies = gBrowser.ownerGlobal.ThirdPartyCookies;
   ok(ThirdPartyCookies, "TP is attached to the browser window");
   is(ThirdPartyCookies.enabled,
      Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
      "TPC.enabled is based on the original pref value");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
 
-  await testContentBlockingEnabled(tab);
-
-  Services.prefs.setBoolPref(CB_PREF, false);
-  ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
-
-  await testContentBlockingDisabled(tab);
+  await testContentBlocking(tab);
 
   Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER);
   ok(ThirdPartyCookies.enabled, "TPC is enabled after setting the pref");
-  Services.prefs.setBoolPref(CB_PREF, true);
-  ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
 
-  await testContentBlockingEnabled(tab);
-
-  Services.prefs.setBoolPref(CB_PREF, false);
-  ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
-
-  await testContentBlockingDisabled(tab);
+  await testContentBlocking(tab);
 
   Services.prefs.clearUserPref(TPC_PREF);
   gBrowser.removeCurrentTab();
 });
--- a/browser/base/content/test/trackingUI/browser_trackingUI_state_all_disabled.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_state_all_disabled.js
@@ -1,26 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
-const CB_PREF = "browser.contentblocking.enabled";
 const TP_PREF = "privacy.trackingprotection.enabled";
 const FB_PREF = "browser.fastblock.enabled";
 const COOKIE_PREF = "network.cookie.cookieBehavior";
 const ANIMATIONS_PREF = "toolkit.cosmeticAnimations.enabled";
 
 // Check that the shield icon is always hidden when all content blocking
 // categories are turned off, even when content blocking is on.
 add_task(async function testContentBlockingAllDisabled() {
   await SpecialPowers.pushPrefEnv({set: [
-    [CB_PREF, true],
     [TP_PREF, false],
     [FB_PREF, false],
     [COOKIE_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT],
   ]});
   await UrlClassifierTestUtils.addTestTrackers();
 
   let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
   Services.prefs.setBoolPref(ANIMATIONS_PREF, true);
--- a/browser/base/content/test/trackingUI/browser_trackingUI_telemetry.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_telemetry.js
@@ -34,18 +34,16 @@ add_task(async function setup() {
 
   let enabledCounts =
     Services.telemetry.getHistogramById("TRACKING_PROTECTION_ENABLED").snapshot().counts;
   is(enabledCounts[0], 1, "TP was not enabled on start up");
 
   let scalars = Services.telemetry.snapshotScalars(
     Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT, false).parent;
 
-  is(scalars["contentblocking.enabled"], Services.prefs.getBoolPref("browser.contentblocking.enabled"),
-    "CB enabled status was recorded at startup");
   is(scalars["contentblocking.exceptions"], 0, "no CB exceptions at startup");
 });
 
 
 add_task(async function testShieldHistogram() {
   Services.prefs.setBoolPref(PREF, true);
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
 
--- a/browser/base/content/test/trackingUI/cookiePage.html
+++ b/browser/base/content/test/trackingUI/cookiePage.html
@@ -1,12 +1,13 @@
 <!DOCTYPE HTML>
 <!-- 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/. -->
 <html dir="ltr" xml:lang="en-US" lang="en-US">
   <head>
     <meta charset="utf8">
+    <script src="trackingAPI.js" type="text/javascript"></script>
   </head>
   <body>
     <iframe src="http://trackertest.org/browser/browser/base/content/test/trackingUI/cookieServer.sjs"></iframe>
   </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/trackingUI/trackingAPI.js
@@ -0,0 +1,16 @@
+onmessage = event => {
+  switch (event.data) {
+  case "tracking": {
+      let ifr = document.createElement("iframe");
+      ifr.src = "https://trackertest.org/";
+      document.body.appendChild(ifr);
+    }
+    break;
+  case "cookie": {
+      let ifr = document.createElement("iframe");
+      ifr.src = "https://trackertest.org/browser/browser/base/content/test/trackingUI/cookieServer.sjs";
+      document.body.appendChild(ifr);
+    }
+    break;
+  }
+};
--- a/browser/base/content/test/trackingUI/trackingPage.html
+++ b/browser/base/content/test/trackingUI/trackingPage.html
@@ -1,12 +1,13 @@
 <!DOCTYPE HTML>
 <!-- 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/. -->
 <html dir="ltr" xml:lang="en-US" lang="en-US">
   <head>
     <meta charset="utf8">
+    <script src="trackingAPI.js" type="text/javascript"></script>
   </head>
   <body>
     <iframe src="http://trackertest.org/"></iframe>
   </body>
 </html>
--- a/browser/base/content/test/urlbar/browser_urlbarOneOffs.js
+++ b/browser/base/content/test/urlbar/browser_urlbarOneOffs.js
@@ -29,16 +29,18 @@ add_task(async function init() {
     });
   }
   await PlacesTestUtils.addVisits(visits);
 });
 
 // Keys up and down through the history panel, i.e., the panel that's shown when
 // there's no text in the textbox.
 add_task(async function history() {
+  gURLBar.popup.toggleOneOffSearches(true);
+
   gURLBar.focus();
   EventUtils.synthesizeKey("KEY_ArrowDown");
   await promisePopupShown(gURLBar.popup);
   await waitForAutocompleteResultAt(gMaxResults - 1);
 
   assertState(-1, -1, "");
 
   // Key down through each result.
@@ -244,16 +246,42 @@ add_task(async function collapsedOneOffs
   assertState(0, -1);
   Assert.ok(gURLBar.popup.oneOffSearchButtons.buttons.collapsed,
     "The one-off buttons should be collapsed");
   EventUtils.synthesizeKey("KEY_ArrowUp");
   assertState(1, -1);
   await hidePopup();
 });
 
+
+// The one-offs should be hidden when searching with an "@engine" search engine
+// alias.
+add_task(async function hiddenWhenUsingSearchAlias() {
+  let typedValue = "@example";
+  await promiseAutocompleteResultPopup(typedValue, window, true);
+  await waitForAutocompleteResultAt(0);
+  Assert.equal(gURLBar.popup.oneOffSearchesEnabled, false);
+  Assert.equal(
+    window.getComputedStyle(gURLBar.popup.oneOffSearchButtons).display,
+    "none"
+  );
+  await hidePopup();
+
+  typedValue = "not an engine alias";
+  await promiseAutocompleteResultPopup(typedValue, window, true);
+  await waitForAutocompleteResultAt(0);
+  Assert.equal(gURLBar.popup.oneOffSearchesEnabled, true);
+  Assert.equal(
+    window.getComputedStyle(gURLBar.popup.oneOffSearchButtons).display,
+    "-moz-box"
+  );
+  await hidePopup();
+});
+
+
 function assertState(result, oneOff, textValue = undefined) {
   Assert.equal(gURLBar.popup.selectedIndex, result,
                "Expected result should be selected");
   Assert.equal(gURLBar.popup.oneOffSearchButtons.selectedButtonIndex, oneOff,
                "Expected one-off should be selected");
   if (textValue !== undefined) {
     Assert.equal(gURLBar.textValue, textValue, "Expected textValue");
   }
--- a/browser/base/content/test/urlbar/browser_urlbarSearchFunction.js
+++ b/browser/base/content/test/urlbar/browser_urlbarSearchFunction.js
@@ -23,17 +23,17 @@ add_task(async function init() {
     // Make sure the popup is closed for the next test.
     gURLBar.handleRevert();
     gURLBar.blur();
     Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
   });
 });
 
 
-// Calls search() with only a search-string argument.
+// Calls search() with a normal, non-"@engine" search-string argument.
 add_task(async function basic() {
   let resetNotification = enableSearchSuggestionsNotification();
 
   gURLBar.search("basic");
   await promiseSearchComplete();
   await waitForAutocompleteResultAt(0);
   assertUrlbarValue("basic");
 
@@ -42,109 +42,39 @@ add_task(async function basic() {
 
   EventUtils.synthesizeKey("KEY_Escape");
   await promisePopupHidden(gURLBar.popup);
 
   resetNotification();
 });
 
 
-// Calls search() with the search-suggestions notification disabled.
-add_task(async function disableSearchSuggestionsNotification() {
-  let resetNotification = enableSearchSuggestionsNotification();
-
-  gURLBar.search("disableSearchSuggestionsNotification", {
-    disableSearchSuggestionsNotification: true,
-  });
-  await promiseSearchComplete();
-  await waitForAutocompleteResultAt(0);
-  assertUrlbarValue("disableSearchSuggestionsNotification");
-
-  assertSearchSuggestionsNotificationVisible(false);
-  assertOneOffButtonsVisible(true);
-
-  EventUtils.synthesizeKey("KEY_Escape");
-  await promisePopupHidden(gURLBar.popup);
-
-  // Open the popup again (by doing another search) to make sure the
-  // notification is shown -- i.e., that we didn't accidentally break it if
-  // it should continue being shown.
-  gURLBar.search("disableSearchSuggestionsNotification again");
-  await promiseSearchComplete();
-  await waitForAutocompleteResultAt(0);
-  assertUrlbarValue("disableSearchSuggestionsNotification again");
-  assertSearchSuggestionsNotificationVisible(true);
-  assertOneOffButtonsVisible(true);
-
-  EventUtils.synthesizeKey("KEY_Escape");
-  await promisePopupHidden(gURLBar.popup);
-
-  resetNotification();
-});
-
-
-// Calls search() with the one-off search buttons disabled.
-add_task(async function disableOneOffButtons() {
+// Calls search() with an "@engine" search engine alias so that the one-off
+// search buttons and search-suggestions notification are disabled.
+add_task(async function searchEngineAlias() {
   let resetNotification = enableSearchSuggestionsNotification();
 
-  gURLBar.search("disableOneOffButtons", {
-    disableOneOffButtons: true,
-  });
-  await promiseSearchComplete();
-  await waitForAutocompleteResultAt(0);
-  assertUrlbarValue("disableOneOffButtons");
-
-  assertSearchSuggestionsNotificationVisible(true);
-  assertOneOffButtonsVisible(false);
-
-  EventUtils.synthesizeKey("KEY_Escape");
-  await promisePopupHidden(gURLBar.popup);
-
-  // Open the popup again (by doing another search) to make sure the one-off
-  // buttons are shown -- i.e., that we didn't accidentally break them.
-  gURLBar.search("disableOneOffButtons again");
+  gURLBar.search("@example");
   await promiseSearchComplete();
   await waitForAutocompleteResultAt(0);
-  assertUrlbarValue("disableOneOffButtons again");
-  assertSearchSuggestionsNotificationVisible(true);
-  assertOneOffButtonsVisible(true);
-
-  EventUtils.synthesizeKey("KEY_Escape");
-  await promisePopupHidden(gURLBar.popup);
-
-  resetNotification();
-});
-
-
-// Calls search() with both the search-suggestions notification and the one-off
-// search buttons disabled.
-add_task(async function disableSearchSuggestionsNotificationAndOneOffButtons() {
-  let resetNotification = enableSearchSuggestionsNotification();
-
-  gURLBar.search("disableSearchSuggestionsNotificationAndOneOffButtons", {
-    disableSearchSuggestionsNotification: true,
-    disableOneOffButtons: true,
-  });
-  await promiseSearchComplete();
-  await waitForAutocompleteResultAt(0);
-  assertUrlbarValue("disableSearchSuggestionsNotificationAndOneOffButtons");
+  assertUrlbarValue("@example");
 
   assertSearchSuggestionsNotificationVisible(false);
   assertOneOffButtonsVisible(false);
 
   EventUtils.synthesizeKey("KEY_Escape");
   await promisePopupHidden(gURLBar.popup);
 
   // Open the popup again (by doing another search) to make sure the
   // notification and one-off buttons are shown -- i.e., that we didn't
   // accidentally break them.
-  gURLBar.search("disableSearchSuggestionsNotificationAndOneOffButtons again");
+  gURLBar.search("not an engine alias");
   await promiseSearchComplete();
   await waitForAutocompleteResultAt(0);
-  assertUrlbarValue("disableSearchSuggestionsNotificationAndOneOffButtons again");
+  assertUrlbarValue("not an engine alias");
   assertSearchSuggestionsNotificationVisible(true);
   assertOneOffButtonsVisible(true);
 
   EventUtils.synthesizeKey("KEY_Escape");
   await promisePopupHidden(gURLBar.popup);
 
   resetNotification();
 });
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1237,18 +1237,20 @@ file, You can obtain one at http://mozil
                 break;
             }
           }
         ]]></body>
       </method>
 
       <method name="_enableOrDisableOneOffSearches">
         <body><![CDATA[
-          this.popup.oneOffSearchesEnabled =
-            this._prefs.getBoolPref("oneOffSearches");
+          this.popup.toggleOneOffSearches(
+            this._prefs.getBoolPref("oneOffSearches"),
+            "pref"
+          );
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
             case "paste":
@@ -1637,42 +1639,23 @@ file, You can obtain one at http://mozil
       </method>
 
       <!--
         Sets the input's value, starts a search, and opens the popup.
 
         @param  value
                 The input's value will be set to this value, and the search will
                 use it as its query.
-        @param  options
-                An optional object with the following optional properties:
-                * disableOneOffButtons: Set to true to hide the one-off search
-                  buttons.
-                * disableSearchSuggestionsNotification: Set to true to hide the
-                  onboarding opt-out search suggestions notification.
       -->
       <method name="search">
         <parameter name="value"/>
-        <parameter name="options"/>
         <body><![CDATA[
-          options = options || {};
-
-          if (options.disableOneOffButtons) {
-            this.popup.addEventListener("popupshowing", () => {
-              if (this.popup.oneOffSearchesEnabled) {
-                this.popup.oneOffSearchesEnabled = false;
-                this.popup.addEventListener("popuphidden", () => {
-                  this.popup.oneOffSearchesEnabled = true;
-                }, {once: true});
-              }
-            }, {once: true});
-          }
-
-          if (options.disableSearchSuggestionsNotification &&
-              this.whichSearchSuggestionsNotification != "none") {
+          // Hide the suggestions notification if the search uses an "@engine"
+          // search engine alias.
+          if (value.trim()[0] == "@") {
             let which = this.whichSearchSuggestionsNotification;
             this._whichSearchSuggestionsNotification = "none";
             this.popup.addEventListener("popuphidden", () => {
               this._whichSearchSuggestionsNotification = which;
             }, {once: true});
           }
 
           // We want the value to be treated as text that the user typed.  It
@@ -1914,18 +1897,16 @@ file, You can obtain one at http://mozil
         250
       </field>
 
       <field name="oneOffSearchButtons" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid",
                                                 "one-off-search-buttons");
       </field>
 
-      <field name="_oneOffSearchesEnabled">false</field>
-
       <field name="_overrideValue">null</field>
       <property name="overrideValue"
                 onget="return this._overrideValue;"
                 onset="this._overrideValue = val; return val;"/>
 
       <method name="onPopupClick">
         <parameter name="aEvent"/>
         <body><![CDATA[
@@ -1933,37 +1914,60 @@ file, You can obtain one at http://mozil
             // Ignore right-clicks.
             return;
           }
           // Otherwise "call super" -- do what autocomplete-base-popup does.
           this.input.controller.handleEnter(true, aEvent);
         ]]></body>
       </method>
 
-      <property name="oneOffSearchesEnabled">
-        <getter><![CDATA[
-          return this._oneOffSearchesEnabled;
-        ]]></getter>
-        <setter><![CDATA[
-          this._oneOffSearchesEnabled = !!val;
-          if (val) {
+      <field name="_oneOffSearchesEnabledByReason">new Map()</field>
+
+      <method name="toggleOneOffSearches">
+        <parameter name="enable"/>
+        <parameter name="reason"/>
+        <body><![CDATA[
+          this._oneOffSearchesEnabledByReason.set(reason || "runtime", enable);
+          this._syncOneOffSearchesEnabled();
+        ]]></body>
+      </method>
+
+      <method name="_syncOneOffSearchesEnabled">
+        <body><![CDATA[
+          // If the popup hasn't ever been opened yet, then don't actually do
+          // anything.  (The popup will still be hidden in that case.)  The
+          // input adds a popupshowing listener that will call this method back
+          // and lazily initialize the one-off buttons the first time the popup
+          // opens.  There are performance tests that fail if we don't do this.
+          if (this.hidden) {
+            return;
+          }
+
+          let enable = Array.from(this._oneOffSearchesEnabledByReason.values())
+                            .every(v => v);
+          if (enable) {
             this.oneOffSearchButtons.telemetryOrigin = "urlbar";
             this.oneOffSearchButtons.style.display = "-moz-box";
             // Set .textbox first, since the popup setter will cause
             // a _rebuild call that uses it.
             this.oneOffSearchButtons.textbox = this.input;
             this.oneOffSearchButtons.popup = this;
           } else {
             this.oneOffSearchButtons.telemetryOrigin = null;
             this.oneOffSearchButtons.style.display = "none";
             this.oneOffSearchButtons.textbox = null;
             this.oneOffSearchButtons.popup = null;
           }
-          return this._oneOffSearchesEnabled;
-        ]]></setter>
+        ]]></body>
+      </method>
+
+      <property name="oneOffSearchesEnabled" readonly="true">
+        <getter><![CDATA[
+          return this.oneOffSearchButtons.style.display != "none";
+        ]]></getter>
       </property>
 
       <!-- Override this so that navigating between items results in an item
            always being selected. -->
       <method name="getNextIndex">
         <parameter name="reverse"/>
         <parameter name="amount"/>
         <parameter name="index"/>
@@ -2456,16 +2460,20 @@ file, You can obtain one at http://mozil
             // search alias in the input or remove the formatting of the
             // previous alias, as necessary.  We need to check selectHeuristic
             // because the result may have already been added but only now is
             // being selected, and we need to check gotResultForCurrentQuery
             // because the result may be from the previous search and already
             // selected and is now being reused.
             if (selectHeuristic || !this.input.gotResultForCurrentQuery) {
               this.input.formatValue();
+
+              // Also, hide the one-off search buttons if the user is using, or
+              // starting to use, an "@engine" search engine alias.
+              this.toggleOneOffSearches(this.input.value.trim()[0] != "@");
             }
 
             // If this is the first time we get the result from the current
             // search and we are not in the private context, we can speculatively
             // connect to the intended site as a performance optimization.
             if (!this.input.gotResultForCurrentQuery &&
                 this.input.speculativeConnectEnabled &&
                 !this.input.inPrivateContext &&
@@ -2474,17 +2482,17 @@ file, You can obtain one at http://mozil
               if (firstStyle.includes("autofill")) {
                 let uri = this.input.mController.getFinalCompleteValueAt(0);
                 this.maybeSetupSpeculativeConnect(uri);
               } else if (firstStyle.includes("searchengine") &&
                          this.input.browserSearchSuggestEnabled &&
                          this.input.urlbarSearchSuggestEnabled) {
                 // Preconnect to the current search engine only if the search
                 // suggestions are enabled.
-                let engine = Services.search.currentEngine;
+                let engine = Services.search.defaultEngine;
                 engine.speculativeConnect({window,
                                            originAttributes: gBrowser.contentPrincipal.originAttributes});
               }
             }
 
             // When a result is present the footer should always be visible.
             this.footer.collapsed = false;
             this.input.tabScrolling = true;
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -837,17 +837,17 @@ var Policies = {
               }
             } catch (ex) {
               log.error(`Search engine lookup failed when attempting to set ` +
                         `the default engine. Requested engine was ` +
                         `"${param.Default}".`, ex);
             }
             if (defaultEngine) {
               try {
-                Services.search.currentEngine = defaultEngine;
+                Services.search.defaultEngine = defaultEngine;
               } catch (ex) {
                 log.error("Unable to set the default search engine", ex);
               }
             }
           });
         }
       });
     },
--- a/browser/components/extensions/parent/ext-chrome-settings-overrides.js
+++ b/browser/components/extensions/parent/ext-chrome-settings-overrides.js
@@ -81,30 +81,30 @@ async function handleInitialHomepagePopu
 
 this.chrome_settings_overrides = class extends ExtensionAPI {
   static async processDefaultSearchSetting(action, id) {
     await ExtensionSettingsStore.initialize();
     let item = ExtensionSettingsStore.getSetting(DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
     if (!item) {
       return;
     }
-    if (Services.search.currentEngine.name != item.value &&
-        Services.search.currentEngine.name != item.initialValue) {
+    if (Services.search.defaultEngine.name != item.value &&
+        Services.search.defaultEngine.name != item.initialValue) {
       // The current engine is not the same as the value that the ExtensionSettingsStore has.
       // This means that the user changed the engine, so we shouldn't control it anymore.
       // Do nothing and remove our entry from the ExtensionSettingsStore.
       ExtensionSettingsStore.removeSetting(id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
       return;
     }
     item = ExtensionSettingsStore[action](id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
     if (item) {
       try {
         let engine = Services.search.getEngineByName(item.value || item.initialValue);
         if (engine) {
-          Services.search.currentEngine = engine;
+          Services.search.defaultEngine = engine;
         }
       } catch (e) {
         Cu.reportError(e);
       }
     }
   }
 
   static async removeEngine(id) {
@@ -212,27 +212,27 @@ this.chrome_settings_overrides = class e
           return;
         }
       }
       await this.addSearchEngine();
       if (searchProvider.is_default) {
         if (extension.startupReason === "ADDON_INSTALL") {
           // Don't ask if it already the current engine
           let engine = Services.search.getEngineByName(engineName);
-          if (Services.search.currentEngine != engine) {
+          if (Services.search.defaultEngine != engine) {
             let allow = await new Promise(resolve => {
               let subject = {
                 wrappedJSObject: {
                   // This is a hack because we don't have the browser of
                   // the actual install. This means the popup might show
                   // in a different window. Will be addressed in a followup bug.
                   browser: windowTracker.topWindow.gBrowser.selectedBrowser,
                   name: this.extension.name,
                   icon: this.extension.iconURL,
-                  currentEngine: Services.search.currentEngine.name,
+                  currentEngine: Services.search.defaultEngine.name,
                   newEngine: engineName,
                   resolve,
                 },
               };
               Services.obs.notifyObservers(subject, "webextension-defaultsearch-prompt");
             });
             if (!allow) {
               return;
@@ -251,50 +251,50 @@ this.chrome_settings_overrides = class e
     }
   }
 
   async setDefault(engineName) {
     let {extension} = this;
     if (extension.startupReason === "ADDON_INSTALL") {
       let item = await ExtensionSettingsStore.addSetting(
         extension.id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME, engineName, () => {
-          return Services.search.currentEngine.name;
+          return Services.search.defaultEngine.name;
         });
-      Services.search.currentEngine = Services.search.getEngineByName(item.value);
+      Services.search.defaultEngine = Services.search.getEngineByName(item.value);
     } else if (extension.startupReason === "ADDON_ENABLE") {
       chrome_settings_overrides.processDefaultSearchSetting("enable", extension.id);
     }
   }
 
   async addSearchEngine() {
     let {extension} = this;
     let isCurrent = false;
     let index = -1;
     if (extension.startupReason === "ADDON_UPGRADE") {
       let engines = Services.search.getEnginesByExtensionID(extension.id);
       if (engines.length > 0) {
         // There can be only one engine right now
-        isCurrent = Services.search.currentEngine == engines[0];
+        isCurrent = Services.search.defaultEngine == engines[0];
         // Get position of engine and store it
         index = Services.search.getEngines().indexOf(engines[0]);
         Services.search.removeEngine(engines[0]);
       }
     }
     try {
       Services.search.addEnginesFromExtension(extension);
       // Bug 1488516.  Preparing to support multiple engines per extension so
       // multiple locales can be loaded.
       let engines = Services.search.getEnginesByExtensionID(extension.id);
       await ExtensionSettingsStore.addSetting(
         extension.id, DEFAULT_SEARCH_STORE_TYPE, ENGINE_ADDED_SETTING_NAME,
         engines[0].name);
       if (extension.startupReason === "ADDON_UPGRADE") {
         let engine = Services.search.getEngineByName(engines[0].name);
         if (isCurrent) {
-          Services.search.currentEngine = engine;
+          Services.search.defaultEngine = engine;
         }
         if (index != -1) {
           Services.search.moveEngine(engine, index);
         }
       }
     } catch (e) {
       Cu.reportError(e);
       return false;
--- a/browser/components/extensions/parent/ext-search.js
+++ b/browser/components/extensions/parent/ext-search.js
@@ -48,33 +48,33 @@ this.search = class extends ExtensionAPI
                 favIconUrl = await getDataURI(engine.iconURI.spec);
               } else {
                 favIconUrl = engine.iconURI.spec;
               }
             }
 
             return {
               name: engine.name,
-              isDefault: engine === Services.search.currentEngine,
+              isDefault: engine === Services.search.defaultEngine,
               alias: engine.alias || undefined,
               favIconUrl,
             };
           }));
         },
 
         async search(searchProperties) {
           await searchInitialized;
           let engine;
           if (searchProperties.engine) {
             engine = Services.search.getEngineByName(searchProperties.engine);
             if (!engine) {
               throw new ExtensionError(`${searchProperties.engine} was not found`);
             }
           } else {
-            engine = Services.search.currentEngine;
+            engine = Services.search.defaultEngine;
           }
           let submission = engine.getSubmission(searchProperties.query, null, "webextension");
           let options = {
             postData: submission.postData,
             triggeringPrincipal: context.principal,
           };
           if (searchProperties.tabId === null) {
             let {gBrowser} = windowTracker.topWindow;
--- a/browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_cookieStoreId.js
@@ -150,8 +150,58 @@ add_task(async function() {
   }
 
   info("Waiting for shutting down...");
   extension.sendMessage("finish");
   await extension.awaitMessage("gone");
 
   await extension.unload();
 });
+
+add_task(async function perma_private_browsing_mode() {
+  await SpecialPowers.pushPrefEnv({set: [["browser.privatebrowsing.autostart", true]]});
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs", "cookies"],
+    },
+    async background() {
+      await browser.test.assertRejects(
+        browser.tabs.create({cookieStoreId: "firefox-container-1"}),
+        /Contextual identities are unavailable in permanent private browsing mode/,
+        "should refuse to open container tab in existing non-private window");
+
+      let win = await browser.windows.create({});
+      browser.test.assertTrue(win.incognito, "New window should be private when perma-PBM is enabled.");
+      await browser.test.assertRejects(
+        browser.tabs.create({cookieStoreId: "firefox-container-1", windowId: win.id}),
+        /Illegal to set non-private cookieStoreId in a private window/,
+        "should refuse to open container tab in private browsing window");
+      await browser.windows.remove(win.id);
+
+      browser.test.sendMessage("done");
+    },
+  });
+  await extension.startup();
+  await extension.awaitMessage("done");
+  await extension.unload();
+  await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function userContext_disabled() {
+  await SpecialPowers.pushPrefEnv({"set": [["privacy.userContext.enabled", false]]});
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs", "cookies"],
+    },
+    async background() {
+      await browser.test.assertRejects(
+        browser.tabs.create({cookieStoreId: "firefox-container-1"}),
+        /Contextual identities are currently disabled/,
+        "should refuse to open container tab when contextual identities are disabled");
+      browser.test.sendMessage("done");
+    },
+  });
+  await extension.startup();
+  await extension.awaitMessage("done");
+  await extension.unload();
+  await SpecialPowers.popPrefEnv();
+});
--- a/browser/components/extensions/test/browser/browser_ext_windows_create_cookieStoreId.js
+++ b/browser/components/extensions/test/browser/browser_ext_windows_create_cookieStoreId.js
@@ -55,16 +55,58 @@ add_task(async function invalid_cookieSt
     },
   });
 
   await extension.startup();
   await extension.awaitMessage("done");
   await extension.unload();
 });
 
+add_task(async function perma_private_browsing_mode() {
+  await SpecialPowers.pushPrefEnv({set: [["browser.privatebrowsing.autostart", true]]});
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs", "cookies"],
+    },
+    async background() {
+      await browser.test.assertRejects(
+        browser.windows.create({cookieStoreId: "firefox-container-1"}),
+        /Contextual identities are unavailable in permanent private browsing mode/,
+        "cookieStoreId cannot be a container tab ID in perma-private browsing mode");
+
+      browser.test.sendMessage("done");
+    },
+  });
+  await extension.startup();
+  await extension.awaitMessage("done");
+  await extension.unload();
+  await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function userContext_disabled() {
+  await SpecialPowers.pushPrefEnv({"set": [["privacy.userContext.enabled", false]]});
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      "permissions": ["tabs", "cookies"],
+    },
+    async background() {
+      await browser.test.assertRejects(
+        browser.windows.create({cookieStoreId: "firefox-container-1"}),
+        /Contextual identities are currently disabled/,
+        "cookieStoreId cannot be a container tab ID when contextual identities are disabled");
+      browser.test.sendMessage("done");
+    },
+  });
+  await extension.startup();
+  await extension.awaitMessage("done");
+  await extension.unload();
+  await SpecialPowers.popPrefEnv();
+});
+
 add_task(async function valid_cookieStoreId() {
   await SpecialPowers.pushPrefEnv({"set": [
     ["privacy.userContext.enabled", true],
   ]});
 
   const testCases = [{
     description: "no explicit URL",
     createParams: {
--- a/browser/components/newtab/lib/PlacesFeed.jsm
+++ b/browser/components/newtab/lib/PlacesFeed.jsm
@@ -275,17 +275,17 @@ class PlacesFeed {
         }));
       }
     } catch (err) {
       Cu.reportError(err);
     }
   }
 
   fillSearchTopSiteTerm({_target, data}) {
-    _target.browser.ownerGlobal.gURLBar.search(`${data.label} `, {disableOneOffButtons: true, disableSearchSuggestionsNotification: true});
+    _target.browser.ownerGlobal.gURLBar.search(`${data.label} `);
   }
 
   onAction(action) {
     switch (action.type) {
       case at.INIT:
         // Briefly avoid loading services for observing for better startup timing
         Services.tm.dispatchToMainThread(() => this.addObservers());
         break;
--- a/browser/components/newtab/lib/TopSitesFeed.jsm
+++ b/browser/components/newtab/lib/TopSitesFeed.jsm
@@ -48,17 +48,17 @@ const SEARCH_FILTERS = [
   "search.yahoo",
   "yahoo",
   "bing",
   "ask",
   "duckduckgo",
 ];
 
 function getShortURLForCurrentSearch() {
-  const url = shortURL({url: Services.search.currentEngine.searchForm});
+  const url = shortURL({url: Services.search.defaultEngine.searchForm});
   return url;
 }
 
 this.TopSitesFeed = class TopSitesFeed {
   constructor() {
     this._tippyTopProvider = new TippyTopProvider();
     XPCOMUtils.defineLazyGetter(this, "_currentSearchHostname", getShortURLForCurrentSearch);
     this.dedupe = new Dedupe(this._dedupeKey);
--- a/browser/components/newtab/test/unit/lib/PlacesFeed.test.js
+++ b/browser/components/newtab/test/unit/lib/PlacesFeed.test.js
@@ -245,17 +245,17 @@ describe("PlacesFeed", () => {
         type: at.FILL_SEARCH_TERM,
         data: {label: "@Foo"},
         _target: {browser: {ownerGlobal: {gURLBar: locationBar}}},
       };
 
       feed.fillSearchTopSiteTerm(action);
 
       assert.calledOnce(locationBar.search);
-      assert.calledWithExactly(locationBar.search, "@Foo ", {disableOneOffButtons: true, disableSearchSuggestionsNotification: true});
+      assert.calledWithExactly(locationBar.search, "@Foo ");
     });
     it("should call saveToPocket on SAVE_TO_POCKET", () => {
       const action = {
         type: at.SAVE_TO_POCKET,
         data: {site: {url: "raspberry.com", title: "raspberry"}},
         _target: {browser: {}},
       };
       sinon.stub(feed, "saveToPocket");
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1027,30 +1027,38 @@ BrowserGlue.prototype = {
       name: gBrowserBundle.GetStringFromName("lightTheme.name"),
       description: gBrowserBundle.GetStringFromName("lightTheme.description"),
       iconURL: "resource:///chrome/browser/content/browser/defaultthemes/light.icon.svg",
       textcolor: "black",
       accentcolor: "white",
       popup: "#fff",
       popup_text: "#0c0c0d",
       popup_border: "#ccc",
+      toolbarColor: "#f5f6f7",
+      toolbar_bottom_separator: "#ccc",
+      toolbar_field: "#fff",
+      toolbar_field_border: "#ccc",
       author: vendorShortName,
     });
     LightweightThemeManager.addBuiltInTheme({
       id: "firefox-compact-dark@mozilla.org",
       name: gBrowserBundle.GetStringFromName("darkTheme.name"),
       description: gBrowserBundle.GetStringFromName("darkTheme.description"),
       iconURL: "resource:///chrome/browser/content/browser/defaultthemes/dark.icon.svg",
       textcolor: "white",
       accentcolor: "black",
       popup: "#4a4a4f",
       popup_text: "rgb(249, 249, 250)",
       popup_border: "#27272b",
+      toolbarColor: "hsl(240, 1%, 20%)",
+      toolbar_bottom_separator: "hsl(240, 5%, 5%)",
+      toolbar_field: "rgb(71, 71, 73)",
+      toolbar_field_border: "rgba(249, 249, 250, 0.2)",
+      toolbar_field_separator: "#5F6670",
       toolbar_field_text: "rgb(249, 249, 250)",
-      toolbar_field_border: "rgba(249, 249, 250, 0.2)",
       ntp_background: "#2A2A2E",
       ntp_text: "rgb(249, 249, 250)",
       sidebar: "#38383D",
       sidebar_text: "rgb(249, 249, 250)",
       sidebar_border: "rgba(255, 255, 255, 0.1)",
       author: vendorShortName,
     }, {
       useInDarkMode: true,
@@ -1359,19 +1367,16 @@ BrowserGlue.prototype = {
     Services.telemetry.getHistogramById("TRACKING_PROTECTION_ENABLED").add(tpEnabled);
 
     let tpPBDisabled = Services.prefs.getBoolPref("privacy.trackingprotection.pbmode.enabled");
     Services.telemetry.getHistogramById("TRACKING_PROTECTION_PBM_DISABLED").add(!tpPBDisabled);
 
     let cookieBehavior = Services.prefs.getIntPref("network.cookie.cookieBehavior");
     Services.telemetry.getHistogramById("COOKIE_BEHAVIOR").add(cookieBehavior);
 
-    let contentBlockingEnabled = Services.prefs.getBoolPref("browser.contentblocking.enabled");
-    Services.telemetry.scalarSet("contentblocking.enabled", contentBlockingEnabled);
-
     let exceptions = 0;
     for (let permission of Services.perms.enumerator) {
       if (permission.type == "trackingprotection") {
         exceptions++;
       }
     }
     Services.telemetry.scalarSet("contentblocking.exceptions", exceptions);
   },
@@ -2361,17 +2366,17 @@ BrowserGlue.prototype = {
           if (data != "init-complete") {
             return;
           }
           Services.obs.removeObserver(observer, SEARCH_SERVICE_TOPIC);
           resolve();
         }, SEARCH_SERVICE_TOPIC);
       });
       searchInitializedPromise.then(() => {
-        let currentEngine = Services.search.currentEngine.wrappedJSObject;
+        let currentEngine = Services.search.defaultEngine.wrappedJSObject;
         // Only reset the current engine if it wasn't set by a WebExtension
         // and it is not one of the default engines.
         // If the original default is not a default, the user has a weird
         // configuration probably involving langpacks, it's not worth
         // attempting to reset their settings.
         if (currentEngine._extensionID || currentEngine._isDefault ||
             !Services.search.originalDefaultEngine.wrappedJSObject._isDefault)
           return;
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -537,29 +537,21 @@ var PlacesUIUtils = {
           return false;
         }
       } else if (PlacesUtils.isVirtualLeftPaneItem(aNode.bookmarkGuid)) {
         // If the item is a left-pane top-level item, it can't be removed.
         return false;
       }
     }
 
-    // If it's not a bookmark, we can remove it unless it's a child of a
-    // livemark.
-    if (aNode.itemId == -1) {
-      // Rather than executing a db query, checking the existence of the feedURI
-      // annotation, detect livemark children by the fact that they are the only
-      // direct non-bookmark children of bookmark folders.
-      return !PlacesUtils.nodeIsFolder(parentNode);
+    // If it's not a bookmark, or it's child of a query, we can remove it.
+    if (aNode.itemId == -1 || PlacesUtils.nodeIsQuery(parentNode)) {
+      return true;
     }
 
-    // Generally it's always possible to remove children of a query.
-    if (PlacesUtils.nodeIsQuery(parentNode))
-      return true;
-
     // Otherwise it has to be a child of an editable folder.
     return !this.isFolderReadOnly(parentNode);
   },
 
   /**
    * DO NOT USE THIS API IN ADDONS. IT IS VERY LIKELY TO CHANGE WHEN THE SWITCH
    * TO GUIDS IS COMPLETE (BUG 1071511).
    *
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -68,18 +68,16 @@ PlacesInsertionPoint.prototype = {
 function PlacesController(aView) {
   this._view = aView;
   XPCOMUtils.defineLazyServiceGetter(this, "clipboard",
                                      "@mozilla.org/widget/clipboard;1",
                                      "nsIClipboard");
   XPCOMUtils.defineLazyGetter(this, "profileName", function() {
     return Services.dirsvc.get("ProfD", Ci.nsIFile).leafName;
   });
-
-  this._cachedLivemarkInfoObjects = new Map();
 }
 
 PlacesController.prototype = {
   /**
    * The places view.
    */
   _view: null,
 
@@ -175,21 +173,16 @@ PlacesController.prototype = {
                  Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
     case "placesCmd_show:info": {
       let selectedNode = this._view.selectedNode;
       return selectedNode && (PlacesUtils.nodeIsTagQuery(selectedNode) ||
                               PlacesUtils.nodeIsBookmark(selectedNode) ||
                               (PlacesUtils.nodeIsFolder(selectedNode) &&
                                !PlacesUtils.isQueryGeneratedFolder(selectedNode)));
     }
-    case "placesCmd_reload": {
-      // Livemark containers
-      let selectedNode = this._view.selectedNode;
-      return selectedNode && this.hasCachedLivemarkInfo(selectedNode);
-    }
     case "placesCmd_sortBy:name": {
       let selectedNode = this._view.selectedNode;
       return selectedNode &&
              PlacesUtils.nodeIsFolder(selectedNode) &&
              !PlacesUIUtils.isFolderReadOnly(selectedNode) &&
              this._view.result.sortingMode ==
                  Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
     }
@@ -258,19 +251,16 @@ PlacesController.prototype = {
       this.newItem("bookmark").catch(Cu.reportError);
       break;
     case "placesCmd_new:separator":
       this.newSeparator().catch(Cu.reportError);
       break;
     case "placesCmd_show:info":
       this.showBookmarkPropertiesForSelection();
       break;
-    case "placesCmd_reload":
-      this.reloadSelectedLivemark();
-      break;
     case "placesCmd_sortBy:name":
       this.sortFolderByName().catch(Cu.reportError);
       break;
     case "placesCmd_createBookmark":
       let node = this._view.selectedNode;
       PlacesUIUtils.showBookmarkDialog({ action: "add",
                                          type: "bookmark",
                                          hiddenRows: [ "keyword", "location" ],
@@ -372,17 +362,16 @@ PlacesController.prototype = {
     }
   },
 
   /**
    * Gathers information about the selected nodes according to the following
    * rules:
    *    "link"              node is a URI
    *    "bookmark"          node is a bookmark
-   *    "livemarkChild"     node is a child of a livemark
    *    "tagChild"          node is a child of a tag
    *    "folder"            node is a folder
    *    "query"             node is a query
    *    "separator"         node is a separator line
    *    "host"              node is a host
    *
    * @return an array of objects corresponding the selected nodes. Each
    *         object has each of the properties above set if its corresponding
@@ -415,33 +404,27 @@ PlacesController.prototype = {
                 nodeData.day = true;
                 break;
             }
           }
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER:
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT:
           nodeData.folder = true;
-          if (this.hasCachedLivemarkInfo(node)) {
-            nodeData.livemark = true;
-          }
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR:
           nodeData.separator = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
           nodeData.link = true;
           if (PlacesUtils.nodeIsBookmark(node)) {
             nodeData.bookmark = true;
             var parentNode = node.parent;
-            if (parentNode) {
-              if (PlacesUtils.nodeIsTagQuery(parentNode))
-                nodeData.tagChild = true;
-              else if (this.hasCachedLivemarkInfo(parentNode))
-                nodeData.livemarkChild = true;
+            if (parentNode && PlacesUtils.nodeIsTagQuery(parentNode)) {
+              nodeData.tagChild = true;
             }
           }
           break;
       }
 
       metadata.push(nodeData);
     }
 
@@ -649,30 +632,16 @@ PlacesController.prototype = {
 
     PlacesUIUtils.showBookmarkDialog({ action: "edit",
                                        node,
                                        hiddenRows: [ "folderPicker" ],
                                      }, window.top);
   },
 
   /**
-   * Reloads the selected livemark if any.
-   */
-  reloadSelectedLivemark: function PC_reloadSelectedLivemark() {
-    var selectedNode = this._view.selectedNode;
-    if (selectedNode) {
-      let itemId = selectedNode.itemId;
-      PlacesUtils.livemarks.getLivemark({ id: itemId })
-        .then(aLivemark => {
-          aLivemark.reload(true);
-        }, Cu.reportError);
-    }
-  },
-
-  /**
    * Opens the links in the selected folder, or the selected links in new tabs.
    */
   openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
     var node = this._view.selectedNode;
     var nodes = this._view.selectedNodes;
     // In the case of no selection, open the root node:
     if (!node && !nodes.length) {
       node = this._view.result.root;
@@ -972,22 +941,17 @@ PlacesController.prototype = {
     try {
       let nodes = this._view.draggableSelection;
       for (let i = 0; i < nodes.length; ++i) {
         var node = nodes[i];
 
         // This order is _important_! It controls how this and other
         // applications select data to be inserted based on type.
         addData(PlacesUtils.TYPE_X_MOZ_PLACE, i);
-
-        // Drop the feed uri for livemark containers
-        let livemarkInfo = this.getCachedLivemarkInfo(node);
-        if (livemarkInfo) {
-          addURIData(i, livemarkInfo.feedURI.spec);
-        } else if (node.uri) {
+        if (node.uri) {
           addURIData(i);
         }
       }
     } finally {
       if (!didSuppressNotifications)
         result.suppressNotifications = false;
     }
   },
@@ -1050,23 +1014,18 @@ PlacesController.prototype = {
     // of them automatically.
     let copiedFolders = [];
     aNodes.forEach(function(node) {
       if (this._shouldSkipNode(node, copiedFolders))
         return;
       if (PlacesUtils.nodeIsFolder(node))
         copiedFolders.push(node);
 
-      let livemarkInfo = this.getCachedLivemarkInfo(node);
-      let feedURI = livemarkInfo && livemarkInfo.feedURI.spec;
-
       contents.forEach(function(content) {
-        content.entries.push(
-          PlacesUtils.wrapNode(node, content.type, feedURI)
-        );
+        content.entries.push(PlacesUtils.wrapNode(node, content.type));
       });
     }, this);
 
     function addData(type, data) {
       xferable.addDataFlavor(type);
       xferable.setTransferData(type, PlacesUtils.toISupportsString(data),
                                data.length * 2);
     }
@@ -1193,50 +1152,16 @@ PlacesController.prototype = {
       this._clearClipboard();
     }
 
     if (itemsToSelect.length > 0)
       this._view.selectItems(itemsToSelect, false);
   },
 
   /**
-   * Cache the livemark info for a node.  This allows the controller and the
-   * views to treat the given node as a livemark.
-   * @param aNode
-   *        a places result node.
-   * @param aLivemarkInfo
-   *        a mozILivemarkInfo object.
-   */
-  cacheLivemarkInfo: function PC_cacheLivemarkInfo(aNode, aLivemarkInfo) {
-    this._cachedLivemarkInfoObjects.set(aNode, aLivemarkInfo);
-  },
-
-  /**
-   * Returns whether or not there's cached mozILivemarkInfo object for a node.
-   * @param aNode
-   *        a places result node.
-   * @return true if there's a cached mozILivemarkInfo object for
-   *         aNode, false otherwise.
-   */
-  hasCachedLivemarkInfo: function PC_hasCachedLivemarkInfo(aNode) {
-    return this._cachedLivemarkInfoObjects.has(aNode);
-  },
-
-  /**
-   * Returns the cached livemark info for a node, if set by cacheLivemarkInfo,
-   * null otherwise.
-   * @param aNode
-   *        a places result node.
-   * @return the mozILivemarkInfo object for aNode, if set, null otherwise.
-   */
-  getCachedLivemarkInfo: function PC_getCachedLivemarkInfo(aNode) {
-    return this._cachedLivemarkInfoObjects.get(aNode, null);
-  },
-
-  /**
    * Checks if we can insert into a container.
    * @param   container
    *          The container were we are want to drop
    */
   disallowInsertion(container) {
     if (!container)
       throw new Error("empty container");
     // Allow dropping into Tag containers and editable folders.
--- a/browser/components/places/content/editBookmark.js
+++ b/browser/components/places/content/editBookmark.js
@@ -168,17 +168,17 @@ var gEditItemOverlay = {
    *          item to be edited. A node-like object must have the following
    *          properties (with values that match exactly those a result node
    *          would have): itemId, bookmarkGuid, uri, title, type.
    *        - uris: an array of uris for bulk tagging.
    *
    *        2. any of the following optional properties:
    *          - hiddenRows (Strings array): list of rows to be hidden regardless
    *            of the item edited. Possible values: "title", "location",
-   *            "keyword", "feedLocation", "siteLocation", folderPicker"
+   *            "keyword", "folderPicker".
    */
   initPanel(aInfo) {
     if (typeof(aInfo) != "object" || aInfo === null)
       throw new Error("aInfo must be an object.");
     if ("node" in aInfo) {
       try {
         aInfo.node.type;
       } catch (e) {
--- a/browser/components/places/content/placesCommands.inc.xul
+++ b/browser/components/places/content/placesCommands.inc.xul
@@ -22,18 +22,16 @@
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:folder');"/>
   <command id="placesCmd_new:separator"
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:separator');"/>
   <command id="placesCmd_show:info"
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_show:info');"/>
   <command id="placesCmd_rename"
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_show:info');"
            observes="placesCmd_show:info"/>
-  <command id="placesCmd_reload"
-           oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_reload');"/>
   <command id="placesCmd_sortBy:name"
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_sortBy:name');"/>
   <command id="placesCmd_deleteDataHost"
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_deleteDataHost');"/>
   <command id="placesCmd_createBookmark"
            oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_createBookmark');"/>
 
   <!-- Special versions of cut/copy/paste/delete which check for an open context menu. -->
--- a/browser/components/places/content/placesContextMenu.inc.xul
+++ b/browser/components/places/content/placesContextMenu.inc.xul
@@ -74,17 +74,17 @@
             selection="link"
             forcehideselection="bookmark|tagChild"/>
   <menuitem id="placesContext_cut"
             command="placesCmd_cut"
             label="&cutCmd.label;"
             accesskey="&cutCmd.accesskey;"
             closemenu="single"
             selection="bookmark|folder|separator|query"
-            forcehideselection="tagChild|livemarkChild"/>
+            forcehideselection="tagChild"/>
   <menuitem id="placesContext_copy"
             command="placesCmd_copy"
             label="&copyCmd.label;"
             closemenu="single"
             accesskey="&copyCmd.accesskey;"
             selection="any"/>
   <menuitem id="placesContext_paste"
             command="placesCmd_paste"
@@ -115,22 +115,15 @@
             forcehideselection="bookmark"/>
   <menuseparator id="placesContext_deleteSeparator"/>
   <menuitem id="placesContext_sortBy:name"
             command="placesCmd_sortBy:name"
             label="&cmd.sortby_name.label;"
             accesskey="&cmd.context_sortby_name.accesskey;"
             closemenu="single"
             selection="folder"/>
-  <menuitem id="placesContext_reload"
-            command="placesCmd_reload"
-            label="&cmd.reloadLivebookmark.label;"
-            accesskey="&cmd.reloadLivebookmark.accesskey;"
-            closemenu="single"
-            selection="livemark"/>
   <menuseparator id="placesContext_sortSeparator"/>
   <menuitem id="placesContext_show:info"
             command="placesCmd_show:info"
             label="&cmd.properties.label;"
             accesskey="&cmd.properties.accesskey;"
-            selection="bookmark|folder|query"
-            forcehideselection="livemarkChild"/>
+            selection="bookmark|folder|query"/>
 </menupopup>
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -736,18 +736,18 @@
 
           // Disallow dragging the root node of a tree.
           if (!node.parent) {
             event.preventDefault();
             event.stopPropagation();
             return;
           }
 
-          // If this node is child of a readonly container (e.g. a livemark)
-          // or cannot be moved, we must force a copy.
+          // If this node is child of a readonly container or cannot be moved,
+          // we must force a copy.
           if (!this.controller.canMoveNode(node)) {
             event.dataTransfer.effectAllowed = "copyLink";
             break;
           }
         }
 
         this._controller.setDataTransfer(event);
         event.stopPropagation();
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -469,17 +469,16 @@ var gPrivacyPane = {
    */
   async restoreContentBlockingPrefs() {
     function clearIfNotLocked(pref) {
       if (!Services.prefs.prefIsLocked(pref)) {
         Services.prefs.clearUserPref(pref);
       }
     }
 
-    clearIfNotLocked("browser.contentblocking.enabled");
     clearIfNotLocked("urlclassifier.trackingTable");
     clearIfNotLocked("network.cookie.cookieBehavior");
     clearIfNotLocked("network.cookie.lifetimePolicy");
 
     let controllingExtension = await getControllingExtension(
       PREF_SETTING_TYPE, TRACKING_PROTECTION_KEY);
     if (!controllingExtension) {
       for (let preference of TRACKING_PROTECTION_PREFS) {
--- a/browser/components/preferences/in-content/search.js
+++ b/browser/components/preferences/in-content/search.js
@@ -144,17 +144,17 @@ var gSearchPane = {
       document.getElementById("urlBarSuggestionPermanentPBLabel");
     permanentPBLabel.hidden = urlbarSuggests.hidden || !permanentPB;
   },
 
   buildDefaultEngineDropDown() {
     // This is called each time something affects the list of engines.
     let list = document.getElementById("defaultEngine");
     // Set selection to the current default engine.
-    let currentEngine = Services.search.currentEngine.name;
+    let currentEngine = Services.search.defaultEngine.name;
 
     // If the current engine isn't in the list any more, select the first item.
     let engines = gEngineView._engineStore._engines;
     if (!engines.some(e => e.name == currentEngine))
       currentEngine = engines[0].name;
 
     // Now clean-up and rebuild the list.
     list.removeAllItems();
@@ -386,17 +386,17 @@ var gSearchPane = {
       if (!engine.shown)
         hiddenList.push(engine.name);
     }
     Preferences.get("browser.search.hiddenOneOffs").value =
       hiddenList.join(",");
   },
 
   setDefaultEngine() {
-    Services.search.currentEngine =
+    Services.search.defaultEngine =
       document.getElementById("defaultEngine").selectedItem.engine;
     ExtensionSettingsStore.setByUser(SEARCH_TYPE, SEARCH_KEY);
   },
 };
 
 function onDragEngineStart(event) {
   var selectedIndex = gEngineView.selectedIndex;
   var tree = document.getElementById("engineList");
--- a/browser/components/preferences/in-content/tests/browser_spotlight.js
+++ b/browser/components/preferences/in-content/tests/browser_spotlight.js
@@ -47,17 +47,16 @@ add_task(async function test_form_autofi
     "Wait for the form-autofill section is spotlighted.");
   is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "form-autofill",
     "The form-autofill section is spotlighted.");
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
 
 add_task(async function test_change_cookie_settings() {
   await SpecialPowers.pushPrefEnv({set: [
-    ["browser.contentblocking.enabled", true],
     ["browser.contentblocking.trackingprotection.ui.enabled", true],
     ["browser.contentblocking.rejecttrackers.ui.enabled", true],
   ]});
   let prefs = await openPreferencesViaOpenPreferencesAPI("privacy-trackingprotection", {leaveOpen: true});
   is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected by default");
   let doc = gBrowser.contentDocument;
   is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
   await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"),
--- a/browser/components/search/content/search-one-offs.js
+++ b/browser/components/search/content/search-one-offs.js
@@ -138,47 +138,47 @@ class MozSearchOneOffs extends MozXULEle
       }
       if (target.classList.contains("search-one-offs-context-open-in-new-tab")) {
         // Select the context-clicked button so that consumers can easily
         // tell which button was acted on.
         this.selectedButton = this._buttonForEngine(this._contextEngine);
         this.handleSearchCommand(event, this._contextEngine, true);
       }
       if (target.classList.contains("search-one-offs-context-set-default")) {
-        let currentEngine = Services.search.currentEngine;
+        let currentEngine = Services.search.defaultEngine;
 
         if (!this.getAttribute("includecurrentengine")) {
           // Make the target button of the context menu reflect the current
           // search engine first. Doing this as opposed to rebuilding all the
           // one-off buttons avoids flicker.
           let button = this._buttonForEngine(this._contextEngine);
           button.id = this._buttonIDForEngine(currentEngine);
           let uri = "chrome://browser/skin/search-engine-placeholder.png";
           if (currentEngine.iconURI) {
             uri = currentEngine.iconURI.spec;
           }
           button.setAttribute("image", uri);
           button.setAttribute("tooltiptext", currentEngine.name);
           button.engine = currentEngine;
         }
 
-        Services.search.currentEngine = this._contextEngine;
+        Services.search.defaultEngine = this._contextEngine;
       }
     });
 
     this.addEventListener("contextmenu", event => {
       let target = event.originalTarget;
       // Prevent the context menu from appearing except on the one off buttons.
       if (!target.classList.contains("searchbar-engine-one-off-item") ||
           target.classList.contains("dummy")) {
         event.preventDefault();
         return;
       }
       this.querySelector(".search-one-offs-context-set-default")
-          .setAttribute("disabled", target.engine == Services.search.currentEngine);
+          .setAttribute("disabled", target.engine == Services.search.defaultEngine);
 
       this.contextMenuPopup.openPopupAtScreen(event.screenX, event.screenY, true);
       event.preventDefault();
 
       this._contextEngine = target.engine;
     });
   }
 
@@ -435,17 +435,17 @@ class MozSearchOneOffs extends MozXULEle
   }
 
   get engines() {
     if (this._engines) {
       return this._engines;
     }
     let currentEngineNameToIgnore;
     if (!this.getAttribute("includecurrentengine"))
-      currentEngineNameToIgnore = Services.search.currentEngine.name;
+      currentEngineNameToIgnore = Services.search.defaultEngine.name;
 
     let pref = Services.prefs.getStringPref("browser.search.hiddenOneOffs");
     let hiddenList = pref ? pref.split(",") : [];
 
     this._engines = Services.search.getVisibleEngines().filter(e => {
       let name = e.name;
       return (!currentEngineNameToIgnore ||
               name != currentEngineNameToIgnore) &&
@@ -563,17 +563,17 @@ class MozSearchOneOffs extends MozXULEle
     // content markup above.
     if (this.settingsButtonCompact.nextElementSibling) {
       this.settingsButtonCompact.nextElementSibling.remove();
     }
 
     let engines = this.engines;
     let oneOffCount = engines.length;
     let collapsed = !oneOffCount ||
-                    (oneOffCount == 1 && engines[0].name == Services.search.currentEngine.name);
+                    (oneOffCount == 1 && engines[0].name == Services.search.defaultEngine.name);
 
     // header is a xul:deck so collapsed doesn't work on it, see bug 589569.
     this.header.hidden = this.buttons.collapsed = collapsed;
 
     if (collapsed) {
       return;
     }
 
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -474,17 +474,17 @@
 
       <field name="oneOffButtons" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid",
                                                 "search-one-off-buttons");
       </field>
 
       <method name="updateHeader">
         <body><![CDATA[
-          let currentEngine = Services.search.currentEngine;
+          let currentEngine = Services.search.defaultEngine;
           let uri = currentEngine.iconURI;
           if (uri) {
             this.setAttribute("src", uri.spec);
           } else {
             // If the default has just been changed to a provider without icon,
             // avoid showing the icon of the previous default provider.
             this.removeAttribute("src");
           }
--- a/browser/components/search/content/searchReset.js
+++ b/browser/components/search/content/searchReset.js
@@ -36,17 +36,17 @@ function doSearch() {
     for (let param of params) {
       if (param.startsWith("data="))
         queryString = decodeURIComponent(param.slice(5));
       else if (param.startsWith("purpose="))
         purpose = param.slice(8);
     }
   }
 
-  let engine = Services.search.currentEngine;
+  let engine = Services.search.defaultEngine;
   let submission = engine.getSubmission(queryString, null, purpose);
 
   window.removeEventListener("unload", recordPageClosed);
 
   let win = window.docShell.rootTreeItem.domWindow;
   win.openTrustedLinkIn(submission.uri.spec, "current", {
     allowThirdPartyFixup: false,
     postData: submission.postData,
@@ -65,30 +65,30 @@ function savePref(value) {
     Services.prefs.setCharPref(statusPref, value);
 }
 
 function record(result) {
   Services.telemetry.getHistogramById("SEARCH_RESET_RESULT").add(result);
 }
 
 function keepCurrentEngine() {
-  // Calling the currentEngine setter will force a correct loadPathHash to be
+  // Calling the defaultEngine setter will force a correct loadPathHash to be
   // written for this engine, so that we don't prompt the user again.
   // eslint-disable-next-line no-self-assign
-  Services.search.currentEngine = Services.search.currentEngine;
+  Services.search.defaultEngine = Services.search.defaultEngine;
   record(TELEMETRY_RESULT_ENUM.KEPT_CURRENT);
   savePref("declined");
   doSearch();
 }
 
 function changeSearchEngine() {
   let engine = Services.search.originalDefaultEngine;
   if (engine.hidden)
     engine.hidden = false;
-  Services.search.currentEngine = engine;
+  Services.search.defaultEngine = engine;
 
   record(TELEMETRY_RESULT_ENUM.RESTORED_DEFAULT);
   savePref("accepted");
 
   doSearch();
 }
 
 function recordPageClosed() {
--- a/browser/components/search/content/searchbar.js
+++ b/browser/components/search/content/searchbar.js
@@ -153,22 +153,22 @@ class MozSearchbar extends MozXULElement
 
   get engines() {
     if (!this._engines)
       this._engines = Services.search.getVisibleEngines();
     return this._engines;
   }
 
   set currentEngine(val) {
-    Services.search.currentEngine = val;
+    Services.search.defaultEngine = val;
     return val;
   }
 
   get currentEngine() {
-    var currentEngine = Services.search.currentEngine;
+    var currentEngine = Services.search.defaultEngine;
     // Return a dummy engine if there is no currentEngine
     return currentEngine || { name: "", uri: null };
   }
   /**
    * textbox is used by sanitize.js to clear the undo history when
    * clearing form information.
    */
   get textbox() {
--- a/browser/components/uitour/test/browser_contentBlocking.js
+++ b/browser/components/uitour/test/browser_contentBlocking.js
@@ -1,33 +1,30 @@
 "use strict";
 
 const PREF_INTRO_COUNT = "browser.contentblocking.introCount";
-const PREF_CB_ENABLED = "browser.contentblocking.enabled";
 const PREF_TP_ENABLED = "privacy.trackingprotection.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 const TOOLTIP_PANEL = document.getElementById("UITourTooltip");
 const TOOLTIP_ANCHOR = document.getElementById("tracking-protection-icon-animatable-box");
 
 var {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
 
 registerCleanupFunction(function() {
   UrlClassifierTestUtils.cleanupTestTrackers();
-  Services.prefs.clearUserPref(PREF_CB_ENABLED);
   Services.prefs.clearUserPref(PREF_TP_ENABLED);
   Services.prefs.clearUserPref(PREF_INTRO_COUNT);
 });
 
 function allowOneIntro() {
   Services.prefs.setIntPref(PREF_INTRO_COUNT, window.ContentBlocking.MAX_INTROS - 1);
 }
 
 add_task(async function setup_test() {
-  Services.prefs.setBoolPref(PREF_CB_ENABLED, true);
   Services.prefs.setBoolPref(PREF_TP_ENABLED, true);
   await UrlClassifierTestUtils.addTestTrackers();
 });
 
 add_task(async function test_benignPage() {
   info("Load a test page not containing tracking elements");
   allowOneIntro();
   await BrowserTestUtils.withNewTab(BENIGN_PAGE, async function() {
--- a/browser/components/uitour/test/browser_trackingProtection.js
+++ b/browser/components/uitour/test/browser_trackingProtection.js
@@ -1,32 +1,29 @@
 "use strict";
 
 const PREF_INTRO_COUNT = "browser.contentblocking.introCount";
-const PREF_CB_ENABLED = "browser.contentblocking.enabled";
 const PREF_TP_ENABLED = "privacy.trackingprotection.enabled";
 const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 const TOOLTIP_PANEL = document.getElementById("UITourTooltip");
 const TOOLTIP_ANCHOR = document.getElementById("tracking-protection-icon-animatable-box");
 
 var {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
 
 registerCleanupFunction(function() {
   UrlClassifierTestUtils.cleanupTestTrackers();
-  Services.prefs.clearUserPref(PREF_CB_ENABLED);
   Services.prefs.clearUserPref(PREF_TP_ENABLED);
 });
 
 function allowOneIntro() {
   Services.prefs.setIntPref(PREF_INTRO_COUNT, window.ContentBlocking.MAX_INTROS - 1);
 }
 
 add_task(async function setup_test() {
-  Services.prefs.setBoolPref(PREF_CB_ENABLED, true);
   Services.prefs.setBoolPref(PREF_TP_ENABLED, true);
   await UrlClassifierTestUtils.addTestTrackers();
 });
 
 add_task(async function test_benignPage() {
   info("Load a test page not containing tracking elements");
   allowOneIntro();
   await BrowserTestUtils.withNewTab({gBrowser, url: BENIGN_PAGE}, async function() {
--- a/browser/components/urlbar/UrlbarController.jsm
+++ b/browser/components/urlbar/UrlbarController.jsm
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["QueryContext", "UrlbarController"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetters(this, {
+  AppConstants: "resource://gre/modules/AppConstants.jsm",
   // BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
   Services: "resource://gre/modules/Services.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
@@ -81,29 +82,33 @@ class QueryContext {
  */
 class UrlbarController {
   /**
    * Initialises the class. The manager may be overridden here, this is for
    * test purposes.
    *
    * @param {object} options
    *   The initial options for UrlbarController.
-   * @param {object} options.window
-   *   The window this controller is operating within.
+   * @param {object} options.browserWindow
+   *   The browser window this controller is operating within.
    * @param {object} [options.manager]
    *   Optional fake providers manager to override the built-in providers manager.
    *   Intended for use in unit tests only.
    */
   constructor(options = {}) {
-    if (!options.window) {
-      throw new Error("Missing options: window");
+    if (!options.browserWindow) {
+      throw new Error("Missing options: browserWindow");
+    }
+    if (!options.browserWindow.location ||
+        options.browserWindow.location.href != AppConstants.BROWSER_CHROME_URL) {
+      throw new Error("browserWindow should be an actual browser window.");
     }
 
     this.manager = options.manager || UrlbarProvidersManager;
-    this.window = options.window;
+    this.browserWindow = options.browserWindow;
 
     this._listeners = new Set();
   }
 
   /**
    * Takes a query context and starts the query based on the user input.
    *
    * @param {QueryContext} queryContext The query details.
@@ -145,17 +150,16 @@ class UrlbarController {
    * @param {Event} event The event that triggered this.
    * @param {string} text The text that was entered into the urlbar.
    * @param {string} [openWhere] Where we expect the result to be opened.
    * @param {object} [openParams]
    *   The parameters related to how and where the result will be opened.
    *   For possible properties @see {_loadURL}
    */
   handleEnteredText(event, text, openWhere, openParams = {}) {
-    let browser = this.window.gBrowser.selectedBrowser;
     let where = openWhere || this._whereToOpen(event);
 
     openParams.postData = null;
     openParams.allowInheritPrincipal = false;
 
     // TODO: Work out how we get the user selection behavior, probably via passing
     // it in, since we don't have the old autocomplete controller to work with.
     // BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
@@ -175,17 +179,17 @@ class UrlbarController {
       //     params.allowInheritPrincipal = data.mayInheritPrincipal;
       //     this._loadURL(data.url, browser, where,
       //                   openUILinkParams);
       //   }
       // });
       return;
     }
 
-    this._loadURL(text, browser, where, openParams);
+    this._loadURL(text, where, openParams);
   }
 
   /**
    * Opens a specific result that has been selected.
    *
    * @param {Event} event The event that triggered this.
    * @param {UrlbarMatch} result The result that was selected.
    * @param {string} [openWhere] Where we expect the result to be opened.
@@ -197,45 +201,44 @@ class UrlbarController {
     // TODO: Work out how we get the user selection behavior, probably via passing
     // it in, since we don't have the old autocomplete controller to work with.
     // BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
     //   event, this.userSelectionBehavior);
 
     let where = openWhere || this._whereToOpen(event);
     openParams.postData = null;
     openParams.allowInheritPrincipal = false;
-    let browser = this.window.gBrowser.selectedBrowser;
     let url = result.url;
 
     switch (result.type) {
       case UrlbarUtils.MATCH_TYPE.TAB_SWITCH: {
         // TODO: Implement handleRevert or equivalent on the input.
         // this.input.handleRevert();
-        let prevTab = this.window.gBrowser.selectedTab;
+        let prevTab = this.browserWindow.gBrowser.selectedTab;
         let loadOpts = {
           adoptIntoActiveWindow: UrlbarPrefs.get("switchTabs.adoptIntoActiveWindow"),
         };
 
-        if (this.window.switchToTabHavingURI(url, false, loadOpts) &&
+        if (this.browserWindow.switchToTabHavingURI(url, false, loadOpts) &&
             prevTab.isEmpty) {
-          this.window.gBrowser.removeTab(prevTab);
+          this.browserWindow.gBrowser.removeTab(prevTab);
         }
         return;
 
         // TODO: How to handle meta chars?
         // Once we get here, we got a TAB_SWITCH match but the user
         // bypassed it by pressing shift/meta/ctrl. Those modifiers
         // might otherwise affect where we open - we always want to
         // open in the current tab.
         // where = "current";
 
       }
     }
 
-    this._loadURL(url, browser, where, openParams);
+    this._loadURL(url, where, openParams);
   }
 
   /**
    * Adds a listener for query actions and results.
    *
    * @param {object} listener The listener to add.
    * @throws {TypeError} Throws if the listener is not an object.
    */
@@ -279,35 +282,35 @@ class UrlbarController {
     }
   }
 
   /**
    * Loads the url in the appropriate place.
    *
    * @param {string} url
    *   The URL to open.
-   * @param {object} browser
-   *   The browser to open it in.
    * @param {string} openUILinkWhere
    *   Where we expect the result to be opened.
    * @param {object} params
    *   The parameters related to how and where the result will be opened.
    *   Further supported paramters are listed in utilityOverlay.js#openUILinkIn.
    * @param {object} params.triggeringPrincipal
    *   The principal that the action was triggered from.
    * @param {nsIInputStream} [params.postData]
    *   The POST data associated with a search submission.
    * @param {boolean} [params.allowInheritPrincipal]
    *   If the principal may be inherited
    */
-  _loadURL(url, browser, openUILinkWhere, params) {
+  _loadURL(url, openUILinkWhere, params) {
+    let browser = this.browserWindow.gBrowser.selectedBrowser;
+
     // TODO: These should probably be set by the input field.
     // this.value = url;
     // browser.userTypedValue = url;
-    if (this.window.gInitialPages.includes(url)) {
+    if (this.browserWindow.gInitialPages.includes(url)) {
       browser.initialPageLoadedFromURLBar = url;
     }
     try {
       UrlbarUtils.addToUrlbarHistory(url);
     } catch (ex) {
       // Things may go wrong when adding url to session history,
       // but don't let that interfere with the loading of the url.
       Cu.reportError(ex);
@@ -316,31 +319,31 @@ class UrlbarController {
     params.allowThirdPartyFixup = true;
 
     if (openUILinkWhere == "current") {
       params.targetBrowser = browser;
       params.indicateErrorPageLoad = true;
       params.allowPinnedTabHostChange = true;
       params.allowPopups = url.startsWith("javascript:");
     } else {
-      params.initiatingDoc = this.window.document;
+      params.initiatingDoc = this.browserWindow.document;
     }
 
     // Focus the content area before triggering loads, since if the load
     // occurs in a new tab, we want focus to be restored to the content
     // area when the current tab is re-selected.
     browser.focus();
 
     if (openUILinkWhere != "current") {
       // TODO: Implement handleRevert or equivalent on the input.
       // this.input.handleRevert();
     }
 
     try {
-      this.window.openTrustedLinkIn(url, openUILinkWhere, params);
+      this.browserWindow.openTrustedLinkIn(url, openUILinkWhere, params);
     } catch (ex) {
       // This load can throw an exception in certain cases, which means
       // we'll want to replace the URL with the loaded URL:
       if (ex.result != Cr.NS_ERROR_LOAD_SHOWED_ERRORPAGE) {
         // TODO: Implement handleRevert or equivalent on the input.
         // this.input.handleRevert();
       }
     }
@@ -352,38 +355,38 @@ class UrlbarController {
 
   /**
    * Determines where a URL/page should be opened.
    *
    * @param {Event} event the event triggering the opening.
    * @returns {"current" | "tabshifted" | "tab" | "save" | "window"}
    */
   _whereToOpen(event) {
-    let isMouseEvent = event instanceof this.window.MouseEvent;
+    let isMouseEvent = event instanceof MouseEvent;
     let reuseEmpty = !isMouseEvent;
     let where = undefined;
     if (!isMouseEvent && event && event.altKey) {
       // We support using 'alt' to open in a tab, because ctrl/shift
       // might be used for canonizing URLs:
       where = event.shiftKey ? "tabshifted" : "tab";
     } else if (!isMouseEvent && this._ctrlCanonizesURLs && event && event.ctrlKey) {
       // If we're allowing canonization, and this is a key event with ctrl
       // pressed, open in current tab to allow ctrl-enter to canonize URL.
       where = "current";
     } else {
-      where = this.window.whereToOpenLink(event, false, false);
+      where = this.browserWindow.whereToOpenLink(event, false, false);
     }
     if (this.openInTab) {
       if (where == "current") {
         where = "tab";
       } else if (where == "tab") {
         where = "current";
       }
       reuseEmpty = true;
     }
     if (where == "tab" &&
         reuseEmpty &&
-        this.window.gBrowser.selectedTab.isEmpty) {
+        this.browserWindow.gBrowser.selectedTab.isEmpty) {
       where = "current";
     }
     return where;
   }
 }
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -41,17 +41,17 @@ class UrlbarInput {
   constructor(options = {}) {
     this.textbox = options.textbox;
     this.textbox.clickSelectsAll = UrlbarPrefs.get("clickSelectsAll");
 
     this.panel = options.panel;
     this.window = this.textbox.ownerGlobal;
     this.document = this.window.document;
     this.controller = options.controller || new UrlbarController({
-      window: this.window,
+      browserWindow: this.window,
     });
     this.view = new UrlbarView(this);
     this.valueIsTyped = false;
     this.userInitiatedFocus = false;
     this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.window);
     this._untrimmedValue = "";
 
     // Forward textbox methods and properties.
--- a/browser/components/urlbar/tests/browser/browser_UrlbarController_resultOpening.js
+++ b/browser/components/urlbar/tests/browser/browser_UrlbarController_resultOpening.js
@@ -8,17 +8,17 @@
 "use strict";
 
 let controller;
 
 add_task(async function setup() {
   sandbox = sinon.sandbox.create();
 
   controller = new UrlbarController({
-    window,
+    browserWindow: window,
   });
 
   registerCleanupFunction(async () => {
     sandbox.restore();
   });
 });
 
 add_task(function test_handleEnteredText_url() {
--- a/browser/components/urlbar/tests/browser/browser_UrlbarInput_unit.js
+++ b/browser/components/urlbar/tests/browser/browser_UrlbarInput_unit.js
@@ -55,17 +55,17 @@ function checkStartQueryCall(stub, expec
      value, `Should have the correct value for queryContext.${name}`);
   }
 }
 
 add_task(async function setup() {
   sandbox = sinon.sandbox.create();
 
   fakeController = new UrlbarController({
-    window,
+    browserWindow: window,
   });
 
   sandbox.stub(fakeController, "startQuery");
   sandbox.stub(PrivateBrowsingUtils, "isWindowPrivate").returns(false);
 
   // Open a new window, so we don't affect other tests by adding extra
   // UrbarInput wrappers around the urlbar.
   let gTestRoot = getRootDirectory(gTestPath);
--- a/browser/components/urlbar/tests/unit/test_UrlbarController_integration.js
+++ b/browser/components/urlbar/tests/unit/test_UrlbarController_integration.js
@@ -26,17 +26,21 @@ function assertContextMatches(context, e
   for (let [key, value] of Object.entries(expectedValues)) {
     Assert.equal(context[key], value,
       `Should have the expected value for ${key} in the QueryContext`);
   }
 }
 
 add_task(async function setup() {
   controller = new UrlbarController({
-    window: {},
+    browserWindow: {
+      location: {
+        href: AppConstants.BROWSER_CHROME_URL,
+      },
+    },
   });
 });
 
 add_task(async function test_basic_search() {
   const context = createContext(TEST_URL);
 
   registerBasicTestProvider([match]);
 
--- a/browser/components/urlbar/tests/unit/test_UrlbarController_unit.js
+++ b/browser/components/urlbar/tests/unit/test_UrlbarController_unit.js
@@ -41,21 +41,39 @@ add_task(function setup() {
   generalListener = {
     onQueryStarted: sandbox.stub(),
     onQueryResults: sandbox.stub(),
     onQueryCancelled: sandbox.stub(),
   };
 
   controller = new UrlbarController({
     manager: fPM,
-    window: {},
+    browserWindow: {
+      location: {
+        href: AppConstants.BROWSER_CHROME_URL,
+      },
+    },
   });
   controller.addQueryListener(generalListener);
 });
 
+add_task(function test_constructor_throws() {
+  Assert.throws(() => new UrlbarController(),
+    /Missing options: browserWindow/,
+    "Should throw if the browserWindow was not supplied");
+  Assert.throws(() => new UrlbarController({browserWindow: {}}),
+    /browserWindow should be an actual browser window/,
+    "Should throw if the browserWindow is not a window");
+  Assert.throws(() => new UrlbarController({browserWindow: {
+    location: "about:fake",
+  }}),
+    /browserWindow should be an actual browser window/,
+    "Should throw if the browserWindow does not have the correct location");
+});
+
 add_task(function test_add_and_remove_listeners() {
   Assert.throws(() => controller.addQueryListener(null),
     /Expected listener to be an object/,
     "Should throw for a null listener");
   Assert.throws(() => controller.addQueryListener(123),
     /Expected listener to be an object/,
     "Should throw for a non-object listener");
 
--- a/browser/components/urlbar/tests/unit/test_providersManager.js
+++ b/browser/components/urlbar/tests/unit/test_providersManager.js
@@ -4,17 +4,21 @@
 "use strict";
 
 add_task(async function test_providers() {
   let match = new UrlbarMatch(UrlbarUtils.MATCH_TYPE.TAB_SWITCH, { url: "http://mozilla.org/foo/" });
   registerBasicTestProvider([match]);
 
   let context = createContext();
   let controller = new UrlbarController({
-    window: {},
+    browserWindow: {
+      location: {
+        href: AppConstants.BROWSER_CHROME_URL,
+      },
+    },
   });
   let resultsPromise = promiseControllerNotification(controller, "onQueryResults");
 
   await UrlbarProvidersManager.startQuery(context, controller);
   // Sanity check that this doesn't throw. It should be a no-op since we await
   // for startQuery.
   UrlbarProvidersManager.cancelQuery(context);
 
--- a/browser/extensions/screenshots/experiments/screenshots/api.js
+++ b/browser/extensions/screenshots/experiments/screenshots/api.js
@@ -50,17 +50,17 @@ const LibraryButton = {
     const libraryViewInsertionPoint = win.document.getElementById("appMenu-library-remotetabs-button");
     // If the library view doesn't exist (on non-photon builds, for instance),
     // this will be null, and we bail out early.
     if (!libraryViewInsertionPoint) {
       return;
     }
     const parent = libraryViewInsertionPoint.parentNode;
     const {nextSibling} = libraryViewInsertionPoint;
-    const item = win.document.createElement("toolbarbutton");
+    const item = win.document.createXULElement("toolbarbutton");
     item.className = "subviewbutton subviewbutton-iconic";
     item.addEventListener("command", () => win.openWebLinkIn(this.PAGE_TO_OPEN, "tab"));
     item.id = this.ITEM_ID;
     const iconURL = this.ICON_URL;
     item.setAttribute("image", iconURL);
     item.setAttribute("label", this.LABEL);
 
     parent.insertBefore(item, nextSibling);
--- a/browser/extensions/screenshots/test/browser/browser_screenshots_ui_check.js
+++ b/browser/extensions/screenshots/test/browser/browser_screenshots_ui_check.js
@@ -52,18 +52,18 @@ function promisePageActionPanelEvent(eve
       executeSoon(resolve);
     }, { once: true });
   });
 }
 
 function promisePageActionViewChildrenVisible(panelViewNode) {
   info("promisePageActionViewChildrenVisible waiting for a child node to be visible");
   return BrowserTestUtils.waitForCondition(() => {
-    const bodyNode = panelViewNode.firstChild;
-    for (const childNode of bodyNode.childNodes) {
+    const bodyNode = panelViewNode.firstElementChild;
+    for (const childNode of bodyNode.children) {
       const bounds = window.windowUtils.getBoundsWithoutFlushing(childNode);
       if (bounds.width > 0 && bounds.height > 0) {
         return true;
       }
     }
     return false;
   });
 }
--- a/browser/locales/en-US/chrome/browser/places/editBookmarkOverlay.dtd
+++ b/browser/locales/en-US/chrome/browser/places/editBookmarkOverlay.dtd
@@ -1,20 +1,16 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!ENTITY editBookmarkOverlay.name.label                      "Name:">
 <!ENTITY editBookmarkOverlay.name.accesskey                  "N">
 <!ENTITY editBookmarkOverlay.location.label                  "Location:">
 <!ENTITY editBookmarkOverlay.location.accesskey              "L">
-<!ENTITY editBookmarkOverlay.feedLocation.label              "Feed Location:">
-<!ENTITY editBookmarkOverlay.feedLocation.accesskey          "F">
-<!ENTITY editBookmarkOverlay.siteLocation.label              "Site Location:">
-<!ENTITY editBookmarkOverlay.siteLocation.accesskey          "S">
 <!ENTITY editBookmarkOverlay.folder.label                    "Folder:">
 <!ENTITY editBookmarkOverlay.foldersExpanderDown.tooltip     "Show all the bookmarks folders">
 <!ENTITY editBookmarkOverlay.expanderUp.tooltip              "Hide">
 <!ENTITY editBookmarkOverlay.tags.label                      "Tags:">
 <!ENTITY editBookmarkOverlay.tags.accesskey                  "T">
 <!ENTITY editBookmarkOverlay.tagsEmptyDesc.label             "Separate tags with commas">
 <!ENTITY editBookmarkOverlay.keyword.label                   "Keyword:">
 <!ENTITY editBookmarkOverlay.keyword.accesskey               "K">
--- a/browser/locales/en-US/chrome/browser/places/places.dtd
+++ b/browser/locales/en-US/chrome/browser/places/places.dtd
@@ -65,19 +65,16 @@
 <!ENTITY cmd.new_bookmark.label            "New Bookmarkā€¦">
 <!ENTITY cmd.new_bookmark.accesskey        "B">
 <!ENTITY cmd.new_folder.label              "New Folderā€¦">
 <!ENTITY cmd.new_folder.accesskey          "o">
 <!ENTITY cmd.context_new_folder.accesskey  "F">
 <!ENTITY cmd.new_separator.label           "New Separator">
 <!ENTITY cmd.new_separator.accesskey       "S">
 
-<!ENTITY cmd.reloadLivebookmark.label      "Reload Live Bookmark">
-<!ENTITY cmd.reloadLivebookmark.accesskey  "R">
-
 <!ENTITY col.name.label          "Name">
 <!ENTITY col.tags.label          "Tags">
 <!ENTITY col.url.label           "Location">
 <!ENTITY col.mostrecentvisit.label "Most Recent Visit">
 <!ENTITY col.visitcount.label    "Visit Count">
 <!ENTITY col.dateadded.label     "Added">
 <!ENTITY col.lastmodified.label  "Last Modified">
 
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -329,17 +329,17 @@ var ContentSearch = {
   },
 
   async currentStateObj(uriFlag = false) {
     let state = {
       engines: [],
       currentEngine: await this._currentEngineObj(),
     };
     if (uriFlag) {
-      state.currentEngine.iconBuffer = Services.search.currentEngine.getIconURLBySize(16, 16);
+      state.currentEngine.iconBuffer = Services.search.defaultEngine.getIconURLBySize(16, 16);
     }
     let pref = Services.prefs.getCharPref("browser.search.hiddenOneOffs");
     let hiddenList = pref ? pref.split(",") : [];
     for (let engine of Services.search.getVisibleEngines()) {
       let uri = engine.getIconURLBySize(16, 16);
       let iconBuffer = uri;
       if (!uriFlag) {
         iconBuffer = await this._arrayBufferFromDataURI(uri);
@@ -415,17 +415,17 @@ var ContentSearch = {
     this._reply(msg, "Strings", this.searchSuggestionUIStrings);
   },
 
   _onMessageSearch(msg, data) {
     this.performSearch(msg, data);
   },
 
   _onMessageSetCurrentEngine(msg, data) {
-    Services.search.currentEngine = Services.search.getEngineByName(data);
+    Services.search.defaultEngine = Services.search.getEngineByName(data);
   },
 
   _onMessageManageEngines(msg) {
     msg.target.ownerGlobal.openPreferences("paneSearch", { origin: "contentSearch" });
   },
 
   async _onMessageGetSuggestions(msg, data) {
     this._ensureDataHasProperties(data, [
@@ -505,17 +505,17 @@ var ContentSearch = {
   _msgArgs(type, data) {
     return [OUTBOUND_MESSAGE, {
       type,
       data,
     }];
   },
 
   async _currentEngineObj() {
-    let engine = Services.search.currentEngine;
+    let engine = Services.search.defaultEngine;
     let favicon = engine.getIconURLBySize(16, 16);
     let placeholder = this._stringBundle.formatStringFromName(
       "searchWithEngine", [engine.name], 1);
     let obj = {
       name: engine.name,
       placeholder,
       iconBuffer: await this._arrayBufferFromDataURI(favicon),
     };
--- a/browser/themes/shared/compacttheme.inc.css
+++ b/browser/themes/shared/compacttheme.inc.css
@@ -3,76 +3,43 @@
 % file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 /* compacttheme.css is loaded in browser.xul after browser.css when it is
    preffed on.  The bulk of the styling is here in the shared file, but
    there are overrides for each platform in their compacttheme.css files. */
 
 :root:-moz-lwtheme {
   --toolbar-color: var(--chrome-color);
-  --toolbar-bgcolor: var(--chrome-secondary-background-color);
   --toolbar-non-lwt-bgcolor: var(--toolbar-bgcolor);
   --toolbar-non-lwt-textcolor: var(--chrome-color);
   --toolbar-non-lwt-bgimage: none;
 
   --toolbarbutton-icon-fill-opacity: .7;
 }
 
 :root:-moz-lwtheme-brighttext {
   /* Chrome */
   --chrome-background-color: hsl(240, 5%, 5%);
   --chrome-color: rgb(249, 249, 250);
-  --chrome-secondary-background-color: hsl(240, 1%, 20%);
-  --toolbox-border-bottom-color: hsl(240, 5%, 5%);
-  --chrome-nav-bar-controls-border-color: hsla(240, 5%, 5%, .3);
-
-  /* Url and search bars */
-  --lwt-toolbar-field-background-color: rgb(71, 71, 73);
-  --lwt-toolbar-field-color: var(--chrome-color);
-  --urlbar-separator-color: #5F6670;
 
   /* !important to override LightweightThemeManager.addBuiltInTheme in
      nsBrowserGlue.js */
   --autocomplete-popup-background: #2A2A2E !important;
   --autocomplete-popup-highlight-background: #0060DF;
 }
 
 :root:-moz-lwtheme-darktext {
-  --lwt-toolbar-field-background-color: #fff;
-
   --chrome-background-color: #E3E4E6;
   --chrome-color: #18191a;
-  --chrome-secondary-background-color: #f5f6f7;
-  --toolbox-border-bottom-color: #cccccc;
-  --chrome-nav-bar-controls-border-color: #ccc;
 }
 
 #tabbrowser-tabs:-moz-lwtheme {
   --tab-line-color: #0a84ff;
 }
 
-.toolbarbutton-animatable-box[brighttext],
-toolbar[brighttext] .toolbarbutton-animatable-box,
-toolbar[brighttext] .toolbarbutton-1 {
-  fill: rgb(249, 249, 250);
-}
-
 /* Change the base colors for the browser chrome */
 
 #TabsToolbar,
 #navigator-toolbox {
   background-color: var(--chrome-background-color);
   color: var(--chrome-color);
 }
 
-.browser-toolbar:not(.titlebar-color),
-.browserContainer > findbar,
-#browser-bottombox {
-  background-color: var(--chrome-secondary-background-color) !important;
-  background-image: none !important;
-  color: var(--chrome-color);
-}
-
-/* URL bar and search bar*/
-#urlbar:not([focused="true"]),
-.searchbar-textbox:not([focused="true"]) {
-  border-color: var(--chrome-nav-bar-controls-border-color);
-}
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -395,27 +395,17 @@ description#identity-popup-content-verif
 }
 
 #identity-popup-content-blocking-content[hasException] #identity-popup-content-blocking-disabled-label {
   display: -moz-box;
   background-color: #d7b600;
   stroke: #d7b600;
 }
 
-#identity-popup-content-blocking-content[enabled][hasException] #identity-popup-content-blocking-disabled-label-global {
-  display: none;
-}
-
-#identity-popup-content-blocking-content:not([enabled]) #identity-popup-content-blocking-disabled-label {
-  display: -moz-box;
-  background-color: #d70022;
-  stroke: #d70022;
-}
-
-#identity-popup-content-blocking-content:not([enabled]) #identity-popup-content-blocking-disabled-label-exception {
+#identity-popup-content-blocking-content[hasException] #identity-popup-content-blocking-disabled-label-global {
   display: none;
 }
 
 #identity-popup-content-blocking-disabled-label > label {
   margin: 0;
 }
 
 #identity-popup-content-blocking-disabled-label > image {
@@ -439,17 +429,17 @@ description#identity-popup-content-verif
 }
 
 /* Show the "detected"/"not detected" message depending on the content state. */
 #identity-popup-content-blocking-content:not([detected]) > #identity-popup-content-blocking-detected,
 #identity-popup-content-blocking-content[detected] > #identity-popup-content-blocking-not-detected {
   display: none;
 }
 
-#identity-popup-content-blocking-content[enabled][hasException] .identity-popup-content-blocking-category-state-label,
+#identity-popup-content-blocking-content[hasException] .identity-popup-content-blocking-category-state-label,
 .identity-popup-content-blocking-category:not(.blocked) .identity-popup-content-blocking-category-state-label {
   display: none;
 }
 
 .identity-popup-content-blocking-category.blocked .identity-popup-content-blocking-category-add-blocking {
   display: none;
 }
 
@@ -475,31 +465,30 @@ description#identity-popup-content-verif
   margin: 1em 0 0;
   display: none;
 }
 
 #identity-popup-content-blocking-report-breakage {
   margin-top: 6px;
 }
 
-/* Hide the "report breakage" button if TP is off or we have not detected any
- * trackers (except if the user added an exception, in which case they might
- * still (especially!) want to report the breakage). */
-#identity-popup-content-blocking-content:not([enabled]) #identity-popup-content-blocking-report-breakage,
+/* Hide the "report breakage" button if we have not detected any trackers
+ * (except if the user added an exception, in which case they might still
+ * (especially!) want to report the breakage). */
 #identity-popup-content-blocking-content:not([active]):not([hasException]) #identity-popup-content-blocking-report-breakage {
   display: none;
 }
 
 /* Show the right action buttons depending on content state */
 /* Offer to temporarily add an exception in private mode. */
 #main-window:not([privatebrowsingmode]) #identity-popup-content-blocking-content[active]:not([hasException]) > #tracking-action-unblock,
 /* Offer to permanently add an exception in normal mode. */
 #main-window[privatebrowsingmode] #identity-popup-content-blocking-content[active]:not([hasException]) > #tracking-action-unblock-private,
 /* If there's an exception just offer to remove the exception again. */
-#identity-popup-content-blocking-content[enabled][hasException] > #tracking-action-block {
+#identity-popup-content-blocking-content[hasException] > #tracking-action-block {
   display: -moz-box;
 }
 
 /* PERMISSIONS */
 
 #identity-popup-permissions-content {
   background-image: url(chrome://browser/skin/controlcenter/permissions.svg);
   padding-bottom: 1.5em;
--- a/devtools/client/aboutdebugging-new/aboutdebugging.js
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.js
@@ -135,8 +135,11 @@ const AboutDebugging = {
 
 window.addEventListener("DOMContentLoaded", () => {
   AboutDebugging.init();
 }, { once: true });
 
 window.addEventListener("unload", () => {
   AboutDebugging.destroy();
 }, {once: true});
+
+// Expose AboutDebugging to tests so that they can access to the store.
+window.AboutDebugging = AboutDebugging;
--- a/devtools/client/aboutdebugging-new/test/browser/head.js
+++ b/devtools/client/aboutdebugging-new/test/browser/head.js
@@ -8,16 +8,21 @@
 
 "use strict";
 
 // Load the shared-head file first.
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
   this);
 
+// Load the shared Redux helpers into this compartment.
+Services.scriptloader.loadSubScript(
+  "chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js",
+  this);
+
 // Load collapsibilities helpers
 Services.scriptloader.loadSubScript(
   CHROME_URL_ROOT + "debug-target-pane_collapsibilities_head.js", this);
 
 // Make sure the ADB addon is removed and ADB is stopped when the test ends.
 registerCleanupFunction(async function() {
   try {
     const { adbAddon } = require("devtools/shared/adb/adb-addon");
@@ -40,28 +45,42 @@ async function enableNewAboutDebugging()
 async function openAboutDebugging(page, win) {
   await enableNewAboutDebugging();
 
   info("opening about:debugging");
   const tab = await addTab("about:debugging", { window: win });
   const browser = tab.linkedBrowser;
   const document = browser.contentDocument;
   const window = browser.contentWindow;
+  const { AboutDebugging } = window;
 
   info("Wait until the main about debugging container is available");
   await waitUntil(() => document.querySelector(".app"));
 
   info("Wait until the client connection was established");
   await waitUntil(() => document.querySelector(".js-runtime-page"));
 
   // Wait until the about:debugging target is visible in the tab list
   // Otherwise, we might have a race condition where TAB1 is discovered by the initial
   // listTabs from the watchRuntime action, instead of being discovered after the
   // TAB_UPDATED event. See analysis in Bug 1493968.
-  await waitUntil(() => findDebugTargetByText("about:debugging", document));
+  info("Wait until tabs are displayed");
+  await waitUntilState(AboutDebugging.store, state => {
+    return state.debugTargets.tabs.length > 0;
+  });
+
+  info("Wait until pre-installed add-ons are displayed");
+  await waitUntilState(AboutDebugging.store, state => {
+    return state.debugTargets.installedExtensions.length > 0;
+  });
+
+  info("Wait until internal 'other workers' are displayed");
+  await waitUntilState(AboutDebugging.store, state => {
+    return state.debugTargets.otherWorkers.length > 0;
+  });
 
   return { tab, document, window };
 }
 
 /**
  * Navigate to the Connect page. Resolves when the Connect page is rendered.
  */
 async function selectConnectPage(doc) {
--- a/devtools/client/inspector/flexbox/components/FlexItemSizingOutline.js
+++ b/devtools/client/inspector/flexbox/components/FlexItemSizingOutline.js
@@ -56,50 +56,43 @@ class FlexItemSizingOutline extends Pure
 
   renderPoint(name) {
     return dom.div({ className: `flex-outline-point ${name}`, "data-label": name });
   }
 
   render() {
     const {
       flexItemSizing,
-      properties,
     } = this.props.flexItem;
     const {
       mainBaseSize,
       mainDeltaSize,
       mainMaxSize,
       mainMinSize,
+      clampState,
     } = flexItemSizing;
 
     const isRow = this.props.flexDirection.startsWith("row");
-    const dimension = isRow ? "width" : "height";
 
     // Calculate the final size. This is base + delta, then clamped by min or max.
     let mainFinalSize = mainBaseSize + mainDeltaSize;
     mainFinalSize = Math.max(mainFinalSize, mainMinSize);
     mainFinalSize = Math.min(mainFinalSize, mainMaxSize);
 
     // Just don't display anything if there isn't anything useful.
     if (!mainFinalSize && !mainBaseSize && !mainDeltaSize) {
       return null;
     }
 
-    // The max size is only interesting to show if it did clamp the item
-    // TODO: replace this with the new clamping state that the API will return once bug
-    // 1498273 is fixed.
-    const showMax = mainMaxSize === mainFinalSize;
+    // The max size is only interesting to show if it did clamp the item.
+    const showMax = clampState === "clamped_to_max";
 
     // The min size is only really interesting if it actually clamped the item.
-    // Just checking that the main size = final size isn't enough because this may be true
-    // if the max content size is the final size. So also check that min-width/height is
-    // set.
-    // TODO: replace this with the new clamping state that the API will return once bug
-    // 1498273 is fixed.
-    const showMin = mainMinSize === mainFinalSize && properties[`min-${dimension}`];
+    // TODO: We might also want to check if the min-size property is defined.
+    const showMin = clampState === "clamped_to_min";
 
     // Sort all of the dimensions in order to come up with a grid track template.
     // Make mainDeltaSize start from the same point as the other ones so we can compare.
     let sizes = [
       { name: "basis-end", size: mainBaseSize },
       { name: "final-end", size: mainFinalSize },
     ];
 
@@ -148,16 +141,16 @@ class FlexItemSizingOutline extends Pure
           },
           this.renderPoint("basis"),
           this.renderPoint("final"),
           showMin ? this.renderPoint("min") : null,
           showMax ? this.renderPoint("max") : null,
           this.renderBasisOutline(mainBaseSize),
           this.renderDeltaOutline(mainDeltaSize),
           this.renderFinalOutline(mainFinalSize, mainMaxSize, mainMinSize,
-                                  showMin || showMax)
+                                  clampState !== "unclamped")
         )
       )
     );
   }
 }
 
 module.exports = FlexItemSizingOutline;
--- a/devtools/client/inspector/flexbox/components/FlexItemSizingProperties.js
+++ b/devtools/client/inspector/flexbox/components/FlexItemSizingProperties.js
@@ -92,30 +92,24 @@ class FlexItemSizingProperties extends P
   renderReasons(sentences) {
     return (
       dom.ul({ className: "reasons" },
         sentences.map(sentence => dom.li({}, sentence))
       )
     );
   }
 
-  renderBaseSizeSection({ mainBaseSize, mainMinSize }, properties, dimension) {
+  renderBaseSizeSection({ mainBaseSize, clampState }, properties, dimension) {
     const flexBasisValue = properties["flex-basis"];
     const dimensionValue = properties[dimension];
-    const minDimensionValue = properties[`min-${dimension}`];
-    const hasMinClamping = mainMinSize && mainMinSize === mainBaseSize;
 
     let property = null;
     let reason = null;
 
-    if (hasMinClamping && minDimensionValue) {
-      // If min clamping happened, then the base size is going to be that value.
-      // TODO: this isn't going to be necessarily true after bug 1498273 is fixed.
-      property = this.renderCssProperty(`min-${dimension}`, minDimensionValue);
-    } else if (flexBasisValue && !hasMinClamping) {
+    if (flexBasisValue) {
       // If flex-basis is defined, then that's what is used for the base size.
       property = this.renderCssProperty("flex-basis", flexBasisValue);
     } else if (dimensionValue) {
       // If not and width/height is defined, then that's what defines the base size.
       property = this.renderCssProperty(dimension, dimensionValue);
     } else {
       // Finally, if nothing is set, then the base size is the max-content size.
       reason = this.renderReasons(
@@ -138,32 +132,31 @@ class FlexItemSizingProperties extends P
   }
 
   renderFlexibilitySection(flexItemSizing, properties) {
     const {
       mainDeltaSize,
       mainBaseSize,
       mainFinalSize,
       lineGrowthState,
+      clampState,
     } = flexItemSizing;
 
     // Don't attempt to display anything useful if everything is 0.
     if (!mainFinalSize && !mainBaseSize && !mainDeltaSize) {
       return null;
     }
 
     const flexGrow = properties["flex-grow"];
     const nonZeroFlexGrowDefined = flexGrow && parseFloat(flexGrow) !== 0;
     const flexShrink = properties["flex-shrink"];
     const flexShrink0 = parseFloat(flexShrink) === 0;
     const grew = mainDeltaSize > 0;
     const shrank = mainDeltaSize < 0;
-    // TODO: replace this with the new clamping state that the API will return once bug
-    // 1498273 is fixed.
-    const wasClamped = mainDeltaSize + mainBaseSize !== mainFinalSize;
+    const wasClamped = clampState !== "unclamped";
 
     const reasons = [];
 
     // First output a sentence for telling users about whether there was enough room or
     // not on the line.
     if (lineGrowthState === "growing") {
       reasons.push(getStr("flexbox.itemSizing.extraRoomOnLine"));
     } else if (lineGrowthState === "shrinking") {
@@ -257,45 +250,40 @@ class FlexItemSizingProperties extends P
           this.getFlexibilityValueString(grew, mainDeltaSize)
         ),
         property,
         this.renderReasons(reasons)
       )
     );
   }
 
-  renderMinimumSizeSection({ mainMinSize, mainFinalSize }, properties, dimension) {
+  renderMinimumSizeSection({ clampState, mainMinSize }, properties, dimension) {
     // We only display the minimum size when the item actually violates that size during
     // layout & is clamped.
-    // For now, we detect this by checking that the min-size is the same as the final size
-    // and that a min-size is actually defined in CSS.
-    // TODO: replace this with the new clamping state that the API will return once bug
-    // 1498273 is fixed.
-    const minDimensionValue = properties[`min-${dimension}`];
-    if (mainMinSize !== mainFinalSize || !minDimensionValue) {
+    if (clampState !== "clamped_to_min") {
       return null;
     }
 
+    const minDimensionValue = properties[`min-${dimension}`];
+
     return (
       dom.li({ className: "section min" },
         dom.span({ className: "name" },
           getStr("flexbox.itemSizing.minSizeSectionHeader")
         ),
         dom.span({ className: "value theme-fg-color1" },
           this.getRoundedDimension(mainMinSize)
         ),
         this.renderCssProperty(`min-${dimension}`, minDimensionValue)
       )
     );
   }
 
-  renderMaximumSizeSection({ mainMaxSize, mainFinalSize }, properties, dimension) {
-    // TODO: replace this with the new clamping state that the API will return once bug
-    // 1498273 is fixed.
-    if (mainMaxSize !== mainFinalSize) {
+  renderMaximumSizeSection({ clampState, mainMaxSize }, properties, dimension) {
+    if (clampState !== "clamped_to_max") {
       return null;
     }
 
     const maxDimensionValue = properties[`max-${dimension}`];
 
     return (
       dom.li({ className: "section max" },
         dom.span({ className: "name" },
--- a/devtools/client/inspector/flexbox/test/browser.ini
+++ b/devtools/client/inspector/flexbox/test/browser.ini
@@ -22,9 +22,10 @@ support-files =
 [browser_flexbox_item_outline_rotates_for_column.js]
 [browser_flexbox_pseudo_elements_are_listed.js]
 [browser_flexbox_sizing_grow_and_not_grow.js]
 [browser_flexbox_sizing_info_exists.js]
 [browser_flexbox_sizing_info_for_pseudos.js]
 [browser_flexbox_sizing_info_for_text_nodes.js]
 [browser_flexbox_sizing_info_has_correct_sections.js]
 [browser_flexbox_sizing_unrelated_to_siblings_when_clamped.js]
+[browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js]
 [browser_flexbox_text_nodes_are_listed.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/flexbox/test/browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js
@@ -0,0 +1,35 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
+
+// Test the specific max-clamping scenario where an item wants to grow a certain amount
+// but its max-size prevents it from growing that much.
+
+const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html";
+
+add_task(async function() {
+  await addTab(TEST_URI);
+  const { inspector, flexboxInspector } = await openLayoutView();
+  const { document: doc } = flexboxInspector;
+
+  info("Select the test item in the document and wait for the sizing info to render");
+  const onRendered = waitForDOM(doc, ".flex-outline, .flex-item-sizing", 2);
+  await selectNode("#want-to-grow-more-than-max div", inspector);
+  const [outlineContainer, sizingContainer] = await onRendered;
+
+  info("Check that the outline contains the max point and that it's equal to final");
+  const maxPoint = outlineContainer.querySelector(".flex-outline-point.max");
+  ok(maxPoint, "The max point is displayed");
+  ok(outlineContainer.style.gridTemplateColumns.includes("[final-end max]"),
+     "The final and max points are at the same position");
+
+  info("Check that the flexibility sizing section displays the right info");
+  const reasons = [...sizingContainer.querySelectorAll(".reasons li")];
+  const expectedReason = getStr("flexbox.itemSizing.growthAttemptWhenClamped");
+  ok(reasons.some(r => r.textContent === expectedReason),
+     "The 'wanted to grow but was clamped' reason was found");
+});
--- a/devtools/client/inspector/flexbox/test/doc_flexbox_specific_cases.html
+++ b/devtools/client/inspector/flexbox/test/doc_flexbox_specific_cases.html
@@ -9,13 +9,25 @@
 #grow-not-grow div:first-child {
   flex-grow:1;
   flex-basis:100px;
   max-width:50px;
 }
 #grow-not-grow div:last-child {
   flex-grow: 1;
 }
+
+#want-to-grow-more-than-max {
+  width: 500px;
+  display: flex;
+}
+#want-to-grow-more-than-max div {
+  flex: 1;
+  max-width: 200px;
+}
 </style>
 <div id="grow-not-grow">
   <div>item 1</div>
   <div>item 2</div>
 </div>
+<div id="want-to-grow-more-than-max">
+  <div>item wants to grow more</div>
+</div>
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -898,20 +898,16 @@ Inspector.prototype = {
     // Inject a lazy loaded react tab by exposing a fake React object
     // with a lazy defined Tab thanks to `panel` being a function
     const layoutId = "layoutview";
     const layoutTitle = INSPECTOR_L10N.getStr("inspector.sidebar.layoutViewTitle2");
     this.sidebar.queueTab(
       layoutId,
       layoutTitle,
       {
-        props: {
-          id: layoutId,
-          title: layoutTitle,
-        },
         panel: () => {
           if (!this.layoutview) {
             const LayoutView =
               this.browserRequire("devtools/client/inspector/layout/layout");
             this.layoutview = new LayoutView(this, this.panelWin);
           }
 
           return this.layoutview.provider;
@@ -926,20 +922,16 @@ Inspector.prototype = {
 
     const animationId = "animationinspector";
     const animationTitle =
       INSPECTOR_L10N.getStr("inspector.sidebar.animationInspectorTitle");
     this.sidebar.queueTab(
       animationId,
       animationTitle,
       {
-        props: {
-          id: animationId,
-          title: animationTitle,
-        },
         panel: () => {
           const AnimationInspector =
             this.browserRequire("devtools/client/inspector/animation/animation");
           this.animationinspector = new AnimationInspector(this, this.panelWin);
           return this.animationinspector.provider;
         },
       },
       defaultTab == animationId);
@@ -947,20 +939,16 @@ Inspector.prototype = {
     // Inject a lazy loaded react tab by exposing a fake React object
     // with a lazy defined Tab thanks to `panel` being a function
     const fontId = "fontinspector";
     const fontTitle = INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle");
     this.sidebar.queueTab(
       fontId,
       fontTitle,
       {
-        props: {
-          id: fontId,
-          title: fontTitle,
-        },
         panel: () => {
           if (!this.fontinspector) {
             const FontInspector =
               this.browserRequire("devtools/client/inspector/fonts/fonts");
             this.fontinspector = new FontInspector(this, this.panelWin);
           }
 
           return this.fontinspector.provider;
@@ -972,20 +960,16 @@ Inspector.prototype = {
       // Inject a lazy loaded react tab by exposing a fake React object
       // with a lazy defined Tab thanks to `panel` being a function
       const changesId = "changesview";
       const changesTitle = INSPECTOR_L10N.getStr("inspector.sidebar.changesViewTitle");
       this.sidebar.queueTab(
         changesId,
         changesTitle,
         {
-          props: {
-            id: changesId,
-            title: changesTitle,
-          },
           panel: () => {
             if (!this.changesView) {
               const ChangesView =
                 this.browserRequire("devtools/client/inspector/changes/ChangesView");
               this.changesView = new ChangesView(this, this.panelWin);
             }
 
             return this.changesView.provider;
--- a/devtools/client/shared/components/tabs/TabBar.js
+++ b/devtools/client/shared/components/tabs/TabBar.js
@@ -312,16 +312,19 @@ class Tabbar extends Component {
       return tab.panel({
         key: tab.id,
         title: tab.title,
         id: tab.id,
         url: tab.url,
       });
     }
 
+    // Ensure tab id and title are used as fallbacks if not defined as panel props.
+    tab.panel.props = Object.assign({ id: tab.id, title: tab.title }, tab.panel.props);
+
     return tab.panel;
   }
 
   render() {
     const tabs = this.state.tabs.map((tab) => this.renderTab(tab));
 
     return (
       div({className: "devtools-sidebar-tabs"},
--- a/devtools/server/actors/layout.js
+++ b/devtools/server/actors/layout.js
@@ -106,16 +106,17 @@ const FlexboxActor = ActorClassWithSpec(
         flexItemActors.push(new FlexItemActor(this, item.node, {
           crossMaxSize: item.crossMaxSize,
           crossMinSize: item.crossMinSize,
           mainBaseSize: item.mainBaseSize,
           mainDeltaSize: item.mainDeltaSize,
           mainMaxSize: item.mainMaxSize,
           mainMinSize: item.mainMinSize,
           lineGrowthState: line.growthState,
+          clampState: item.clampState,
         }));
       }
     }
 
     return flexItemActors;
   },
 });
 
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -5292,16 +5292,18 @@ nsGlobalWindowOuter::FirePopupBlockedEve
 }
 
 void
 nsGlobalWindowOuter::NotifyContentBlockingState(unsigned aState,
                                                 nsIChannel* aChannel,
                                                 bool aBlocked,
                                                 nsIURI* aURIHint)
 {
+  MOZ_ASSERT(aURIHint);
+
   nsCOMPtr<nsIDocShell> docShell = GetDocShell();
   if (!docShell) {
     return;
   }
   nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
   NS_ENSURE_TRUE_VOID(doc);
 
   // This event might come after the user has navigated to another page.
@@ -5321,20 +5323,18 @@ nsGlobalWindowOuter::NotifyContentBlocki
   uint32_t state = 0;
   nsCOMPtr<nsISecureBrowserUI> securityUI;
   docShell->GetSecurityUI(getter_AddRefs(securityUI));
   if (!securityUI) {
     return;
   }
   securityUI->GetState(&state);
   nsAutoString origin;
-  origin.SetIsVoid(true);
-  if (aURIHint) {
-    nsContentUtils::GetUTFOrigin(aURIHint, origin);
-  }
+  nsContentUtils::GetUTFOrigin(aURIHint, origin);
+
   bool unblocked = false;
   if (aState == nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT) {
     doc->SetHasTrackingContentBlocked(aBlocked, origin);
     if (!aBlocked) {
       unblocked = !doc->GetHasTrackingContentBlocked();
     }
   } else if (aState == nsIWebProgressListener::STATE_BLOCKED_SLOW_TRACKING_CONTENT) {
     doc->SetHasSlowTrackingContentBlocked(aBlocked, origin);
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -1089,18 +1089,18 @@ public:
   FirePopupBlockedEvent(nsIDocument* aDoc,
                         nsIURI* aPopupURI,
                         const nsAString& aPopupWindowName,
                         const nsAString& aPopupWindowFeatures) = 0;
 
   virtual void
   NotifyContentBlockingState(unsigned aState,
                              nsIChannel* aChannel,
-                             bool aBlocked = true,
-                             nsIURI* aURIHint = nullptr) = 0;
+                             bool aBlocked,
+                             nsIURI* aURIHint) = 0;
 
   // WebIDL-ish APIs
   void MarkUncollectableForCCGeneration(uint32_t aGeneration)
   {
     mMarkedCCGeneration = aGeneration;
   }
 
   uint32_t GetMarkedCCGeneration()
--- a/dom/media/encoder/MediaEncoder.cpp
+++ b/dom/media/encoder/MediaEncoder.cpp
@@ -105,40 +105,52 @@ public:
           NewRunnableMethod<StreamTime>(
             "mozilla::AudioTrackEncoder::SetStartOffset",
             mEncoder, &AudioTrackEncoder::SetStartOffset, aTrackOffset));
       MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
       Unused << rv;
       mInitialized = true;
     }
 
-    if (mDirectConnected) {
-      if (aQueuedMedia.IsNull()) {
-        nsresult rv =
-          mEncoderThread->Dispatch(
-            NewRunnableMethod<StreamTime>(
-              "mozilla::AudioTrackEncoder::AdvanceBlockedInput",
-              mEncoder, &AudioTrackEncoder::AdvanceBlockedInput,
-              aQueuedMedia.GetDuration()));
-        MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-        Unused << rv;
-        return;
-      }
-    } else {
+    if (!mDirectConnected) {
       NotifyRealtimeTrackData(aGraph, aTrackOffset, aQueuedMedia);
     }
 
-    nsresult rv =
-      mEncoderThread->Dispatch(
-        NewRunnableMethod<StreamTime>(
+    AutoTArray<Pair<bool, StreamTime>, 2> nulledSequence;
+    for (AudioSegment::ConstChunkIterator
+         iter(static_cast<const AudioSegment&>(aQueuedMedia));
+         !iter.IsEnded(); iter.Next()) {
+      if (!nulledSequence.IsEmpty()) {
+        Pair<bool, StreamTime>& last = nulledSequence.LastElement();
+        if (last.first() == iter->IsNull()) {
+          last.second() += iter->GetDuration();
+          continue;
+        }
+      }
+      nulledSequence.AppendElement(
+        MakePair(iter->IsNull(), iter->GetDuration()));
+    }
+
+    for (const Pair<bool, StreamTime>& nulledRange : nulledSequence) {
+      if (nulledRange.first()) {
+        nsresult rv = mEncoderThread->Dispatch(NewRunnableMethod<StreamTime>(
+          "mozilla::AudioTrackEncoder::AdvanceBlockedInput",
+          mEncoder, &AudioTrackEncoder::AdvanceBlockedInput,
+          nulledRange.second()));
+        MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+        Unused << rv;
+      } else {
+        nsresult rv = mEncoderThread->Dispatch(NewRunnableMethod<StreamTime>(
           "mozilla::AudioTrackEncoder::AdvanceCurrentTime",
           mEncoder, &AudioTrackEncoder::AdvanceCurrentTime,
-          aQueuedMedia.GetDuration()));
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-    Unused << rv;
+          nulledRange.second()));
+        MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+        Unused << rv;
+      }
+    }
   }
 
   void NotifyRealtimeTrackData(MediaStreamGraph* aGraph,
                                StreamTime aTrackOffset,
                                const MediaSegment& aMedia) override
   {
     TRACE_COMMENT("Encoder %p", mEncoder.get());
     MOZ_ASSERT(mEncoder);
@@ -257,46 +269,56 @@ public:
     MOZ_ASSERT(mEncoder);
     MOZ_ASSERT(mEncoderThread);
 
     if (mShutdown) {
       return;
     }
 
     if (!mInitialized) {
-      nsresult rv =
-        mEncoderThread->Dispatch(
-          NewRunnableMethod<StreamTime>(
-            "mozilla::VideoTrackEncoder::SetStartOffset",
-            mEncoder, &VideoTrackEncoder::SetStartOffset, aTrackOffset));
+      nsresult rv =mEncoderThread->Dispatch(NewRunnableMethod<StreamTime>(
+        "mozilla::VideoTrackEncoder::SetStartOffset",
+        mEncoder, &VideoTrackEncoder::SetStartOffset, aTrackOffset));
       MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
       Unused << rv;
       mInitialized = true;
     }
 
-    if (aQueuedMedia.IsNull()) {
-      nsresult rv =
-        mEncoderThread->Dispatch(
-          NewRunnableMethod<StreamTime>(
-            "mozilla::VideoTrackEncoder::AdvanceBlockedInput",
-            mEncoder, &VideoTrackEncoder::AdvanceBlockedInput,
-            aQueuedMedia.GetDuration()));
-      MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-      Unused << rv;
-      return;
+    AutoTArray<Pair<bool, StreamTime>, 2> nulledSequence;
+    for (VideoSegment::ConstChunkIterator
+         iter(static_cast<const VideoSegment&>(aQueuedMedia));
+         !iter.IsEnded(); iter.Next()) {
+      if (!nulledSequence.IsEmpty()) {
+        Pair<bool, StreamTime>& last = nulledSequence.LastElement();
+        if (last.first() == iter->IsNull()) {
+          last.second() += iter->GetDuration();
+          continue;
+        }
+      }
+      nulledSequence.AppendElement(
+        MakePair(iter->IsNull(), iter->GetDuration()));
     }
 
-    nsresult rv =
-      mEncoderThread->Dispatch(
-        NewRunnableMethod<StreamTime>(
+    for (const Pair<bool, StreamTime>& nulledRange : nulledSequence) {
+      if (nulledRange.first()) {
+        nsresult rv = mEncoderThread->Dispatch(NewRunnableMethod<StreamTime>(
+          "mozilla::VideoTrackEncoder::AdvanceBlockedInput",
+          mEncoder, &VideoTrackEncoder::AdvanceBlockedInput,
+          nulledRange.second()));
+        MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+        Unused << rv;
+      } else {
+        nsresult rv = mEncoderThread->Dispatch(NewRunnableMethod<StreamTime>(
           "mozilla::VideoTrackEncoder::AdvanceCurrentTime",
           mEncoder, &VideoTrackEncoder::AdvanceCurrentTime,
-          aQueuedMedia.GetDuration()));
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-    Unused << rv;
+          nulledRange.second()));
+        MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+        Unused << rv;
+      }
+    }
   }
 
   void SetCurrentFrames(const VideoSegment& aMedia) override
   {
     TRACE_COMMENT("Encoder %p", mEncoder.get());
     MOZ_ASSERT(mEncoder);
     MOZ_ASSERT(mEncoderThread);
 
new file mode 100644
--- /dev/null
+++ b/dom/media/gtest/TestOpusParser.cpp
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+#include "OpusParser.h"
+#include <algorithm>
+
+TEST(OpusParser, Mapping2)
+{
+  uint8_t validChannels[] = {
+    1,  3,  4,  6,   9,   11,  16,  18,  25,  27,  36,  38,  49,  51,  64,
+    66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171, 196, 198, 225, 227
+  };
+  for (uint8_t channels = 0; channels < 255; channels++) {
+    bool found = OpusParser::IsValidMapping2ChannelsCount(channels);
+    bool foundTable =
+      std::find(std::begin(validChannels), std::end(validChannels), channels) !=
+      std::end(validChannels);
+    EXPECT_EQ(found, foundTable);
+  }
+}
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -28,16 +28,17 @@ UNIFIED_SOURCES += [
     'TestGMPRemoveAndDelete.cpp',
     'TestGMPUtils.cpp',
     'TestIntervalSet.cpp',
     'TestMediaDataDecoder.cpp',
     'TestMediaEventSource.cpp',
     'TestMediaMIMETypes.cpp',
     'TestMP3Demuxer.cpp',
     'TestMP4Demuxer.cpp',
+    'TestOpusParser.cpp',
     'TestRust.cpp',
     'TestVideoSegment.cpp',
     'TestVideoUtils.cpp',
     'TestVPXDecoding.cpp',
     'TestWebMBuffered.cpp',
 ]
 
 if CONFIG['MOZ_WEBM_ENCODER']:
--- a/dom/media/ogg/OpusParser.cpp
+++ b/dom/media/ogg/OpusParser.cpp
@@ -88,37 +88,19 @@ bool OpusParser::DecodeHeader(unsigned c
       if (mChannelMapping == 1 && mChannels > 8) {
         OPUS_LOG(LogLevel::Debug,
                  ("Invalid Opus file: too many channels (%d) for"
                   " mapping family 1.",
                   mChannels));
         return false;
       }
       if (mChannelMapping == 2) {
-        // https://tools.ietf.org/html/draft-ietf-codec-ambisonics-08#page-3
-        // For both channel mapping family 2 and family 3, the allowed numbers
-        // of channels: (1 + n)^2 + 2j for n = 0, 1, ..., 14 and j = 0 or 1,
-        // where n denotes the (highest) ambisonic order and j denotes whether
-        // or not there is a separate non-diegetic stereo stream Explicitly the
-        // allowed number of channels are 1, 3, 4, 6, 9, 11, 16, 18, 25, 27, 36,
-        // 38, 49, 51, 64, 66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171,
-        // 196, 198, 225, and 227.
-
-        // We use the property that int(sqrt(n)) == int(sqrt(n+2)) for n != 3
-        // which is handled by the test n^2 + 2 != channel
-        double val = sqrt(mChannels);
-        if (val == 0 || val > 15) {
+        if (!IsValidMapping2ChannelsCount(mChannels)) {
           return false;
         }
-        if (val != int32_t(val)) {
-          if (val * val + 2 != mChannels) {
-            // Not a valid channel count.
-            return false;
-          }
-        }
       }
       if (aLength > static_cast<unsigned>(20 + mChannels)) {
         mStreams = aData[19];
         mCoupledStreams = aData[20];
         int i;
         for (i = 0; i < mChannels; i++) {
           mMappingTable[i] = aData[21 + i];
         }
@@ -210,9 +192,31 @@ bool OpusParser::DecodeTags(unsigned cha
   OPUS_LOG(LogLevel::Debug, ("  vendor: %s", mVendorString.get()));
   for (uint32_t i = 0; i < mTags.Length(); i++) {
     OPUS_LOG(LogLevel::Debug, (" %s", mTags[i].get()));
   }
 #endif
   return true;
 }
 
+/* static */ bool
+OpusParser::IsValidMapping2ChannelsCount(uint8_t aChannels)
+{
+  // https://tools.ietf.org/html/draft-ietf-codec-ambisonics-08#page-4
+  // For both channel mapping family 2 and family 3, the allowed numbers
+  // of channels: (1 + n)^2 + 2j for n = 0, 1, ..., 14 and j = 0 or 1,
+  // where n denotes the (highest) ambisonic order and j denotes whether
+  // or not there is a separate non-diegetic stereo stream Explicitly the
+  // allowed number of channels are 1, 3, 4, 6, 9, 11, 16, 18, 25, 27, 36,
+  // 38, 49, 51, 64, 66, 81, 83, 100, 102, 121, 123, 144, 146, 169, 171,
+  // 196, 198, 225, and 227.
+
+  // We use the property that int(sqrt(n)) == int(sqrt(n+2)) for n != 3
+  // which is handled by the test n^2 + 2 != channel
+  if (aChannels < 1 || aChannels > 227) {
+    return false;
+  }
+  double val = sqrt(aChannels);
+  int32_t valInt = int32_t(val);
+  return val == valInt || valInt * valInt + 2 == aChannels;
+}
+
 } // namespace mozilla
--- a/dom/media/ogg/OpusParser.h
+++ b/dom/media/ogg/OpusParser.h
@@ -13,16 +13,17 @@ namespace mozilla {
 
 class OpusParser
 {
 public:
   OpusParser();
 
   bool DecodeHeader(unsigned char* aData, size_t aLength);
   bool DecodeTags(unsigned char* aData, size_t aLength);
+  static bool IsValidMapping2ChannelsCount(uint8_t aChannels);
 
   // Various fields from the Ogg Opus header.
   int mRate;        // Sample rate the decoder uses (always 48 kHz).
   uint32_t mNominalRate; // Original sample rate of the data (informational).
   int mChannels;    // Number of channels the stream encodes.
   uint16_t mPreSkip; // Number of samples to strip after decoder reset.
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
   float mGain;      // Gain to apply to decoder output.
--- a/dom/prio/PrioEncoder.cpp
+++ b/dom/prio/PrioEncoder.cpp
@@ -101,16 +101,21 @@ PrioEncoder::Encode(GlobalObject& aGloba
       return;
     }
 
     sSingleton = new PrioEncoder();
     ClearOnShutdown(&sSingleton);
   }
 
   nsTArray<bool> dataItems = aPrioParams.mBooleans;
+  if (dataItems.Length() > gNumBooleans) {
+    aRv.ThrowRangeError<MSG_VALUE_OUT_OF_RANGE>(
+      NS_LITERAL_STRING("Maximum boolean value exceeded"));
+    return;
+  }
 
   PrioConfig prioConfig = PrioConfig_new(dataItems.Length(),
                                          sPublicKeyA,
                                          sPublicKeyB,
                                          reinterpret_cast<const unsigned char*>(aBatchID.BeginReading()),
                                          aBatchID.Length());
 
   if (!prioConfig) {
--- a/dom/prio/PrioEncoder.h
+++ b/dom/prio/PrioEncoder.h
@@ -24,16 +24,19 @@ public:
 
   static
   void Encode(GlobalObject& aGlobal,
               const nsCString& aBatchID,
               const PrioParams& aPrioParams,
               RootedDictionary<PrioEncodedData>& aData,
               ErrorResult& aRv);
 
+  // maximum number of booleans that can be prio-encoded in a single batch.
+  const static uint32_t gNumBooleans = 2046;
+
 private:
   PrioEncoder();
   ~PrioEncoder();
 
   static PublicKey
   sPublicKeyA;
 
   static PublicKey
--- a/dom/prio/test/gtest/TestPrioEncoder.cpp
+++ b/dom/prio/test/gtest/TestPrioEncoder.cpp
@@ -37,16 +37,50 @@ TEST(PrioEncoder, BadPublicKeys)
   // Call again to ensure that the singleton state is consistent.
   mozilla::dom::PrioEncoder::Encode(global, batchID, prioParams, prioEncodedData, rv);
   ASSERT_TRUE(rv.Failed());
 
   // Reset error result so test runner does not fail.
   rv = mozilla::ErrorResult();
 }
 
+TEST(PrioEncoder, BooleanLimitExceeded)
+{
+  mozilla::dom::AutoJSAPI jsAPI;
+  ASSERT_TRUE(jsAPI.Init(xpc::PrivilegedJunkScope()));
+  JSContext* cx = jsAPI.cx();
+
+  mozilla::dom::GlobalObject global(cx, xpc::PrivilegedJunkScope());
+
+  nsCString batchID = NS_LITERAL_CSTRING("abc123");
+
+  mozilla::dom::PrioParams prioParams;
+  FallibleTArray<bool> sequence;
+
+  const int ndata = mozilla::dom::PrioEncoder::gNumBooleans + 1;
+  const int seed = time(nullptr);
+  srand(seed);
+
+  for (int i = 0; i < ndata; i++) {
+    // Arbitrary data)
+    *(sequence.AppendElement(mozilla::fallible)) = rand() % 2;
+  }
+
+  prioParams.mBooleans.Assign(sequence);
+
+  mozilla::dom::RootedDictionary<mozilla::dom::PrioEncodedData> prioEncodedData(cx);
+  mozilla::ErrorResult rv;
+
+  mozilla::dom::PrioEncoder::Encode(global, batchID, prioParams, prioEncodedData, rv);
+  ASSERT_TRUE(rv.Failed());
+
+  // Reset error result so test runner does not fail.
+  rv = mozilla::ErrorResult();
+}
+
 TEST(PrioEncoder, VerifyFull)
 {
   SECStatus prioRv = SECSuccess;
 
   PublicKey pkA = nullptr;
   PublicKey pkB = nullptr;
   PrivateKey skA = nullptr;
   PrivateKey skB = nullptr;
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -2302,52 +2302,16 @@ NS_IMETHODIMP
 EditorBase::OutputToString(const nsAString& aFormatType,
                            uint32_t aFlags,
                            nsAString& aOutputString)
 {
   // these should be implemented by derived classes.
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
-EditorBase::DumpContentTree()
-{
-#ifdef DEBUG
-  if (mRootElement) {
-    mRootElement->List(stdout);
-  }
-#endif
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-EditorBase::DebugDumpContent()
-{
-#ifdef DEBUG
-  nsCOMPtr<nsIDocument> document = GetDocument();
-  if (NS_WARN_IF(!document)) {
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-  Element* body = document->GetBody();
-  if (body) {
-    body->List();
-  }
-#endif
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-EditorBase::DebugUnitTests(int32_t* outNumTests,
-                           int32_t* outNumTestsFailed)
-{
-  MOZ_ASSERT_UNREACHABLE("This should never get called. Overridden by "
-                         "subclasses");
-  return NS_OK;
-}
-
 bool
 EditorBase::ArePreservingSelection()
 {
   return !(mSavedSel.IsEmpty());
 }
 
 void
 EditorBase::PreserveSelectionAcrossActions(Selection* aSel)
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -46,17 +46,16 @@
 
 // netwerk
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 
 // Misc
 #include "mozilla/EditorUtils.h"
 #include "HTMLEditorObjectResizerUtils.h"
-#include "TextEditorTest.h"
 #include "WSRunObject.h"
 #include "nsGkAtoms.h"
 #include "nsIWidget.h"
 
 #include "nsIFrame.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/Element.h"
@@ -3568,34 +3567,16 @@ HTMLEditor::ContentRemoved(nsIContent* a
 
     RefPtr<HTMLEditRules> htmlRules = mRules->AsHTMLEditRules();
     if (htmlRules) {
       htmlRules->DocumentModified();
     }
   }
 }
 
-NS_IMETHODIMP
-HTMLEditor::DebugUnitTests(int32_t* outNumTests,
-                           int32_t* outNumTestsFailed)
-{
-#ifdef DEBUG
-  NS_ENSURE_TRUE(outNumTests && outNumTestsFailed, NS_ERROR_NULL_POINTER);
-
-  TextEditorTest *tester = new TextEditorTest();
-  NS_ENSURE_TRUE(tester, NS_ERROR_OUT_OF_MEMORY);
-
-  tester->Run(this, outNumTests, outNumTestsFailed);
-  delete tester;
-  return NS_OK;
-#else
-  return NS_ERROR_NOT_IMPLEMENTED;
-#endif
-}
-
 void
 HTMLEditor::OnStartToHandleTopLevelEditSubAction(
               EditSubAction aEditSubAction,
               nsIEditor::EDirection aDirection)
 {
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
 
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -134,19 +134,16 @@ public:
   NS_IMETHOD SetFlags(uint32_t aFlags) override;
 
   NS_IMETHOD CanPaste(int32_t aSelectionType, bool* aCanPaste) override;
 
   NS_IMETHOD PasteTransferable(nsITransferable* aTransferable) override;
 
   NS_IMETHOD DeleteNode(nsINode* aNode) override;
 
-  NS_IMETHOD DebugUnitTests(int32_t* outNumTests,
-                            int32_t* outNumTestsFailed) override;
-
   virtual nsresult HandleKeyPressEvent(
                      WidgetKeyboardEvent* aKeyboardEvent) override;
   virtual nsIContent* GetFocusedContent() override;
   virtual already_AddRefed<nsIContent> GetFocusedContentForIME() override;
   virtual bool IsActiveInDOMWindow() override;
   virtual dom::EventTarget* GetDOMEventTarget() override;
   virtual Element* FindSelectionRoot(nsINode *aNode) const override;
   virtual bool IsAcceptableInputEvent(WidgetGUIEvent* aGUIEvent) override;
deleted file mode 100644
--- a/editor/libeditor/TextEditorTest.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: C++ tab-width: 2 indent-tabs-mode: nil c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-
-#include "TextEditorTest.h"
-
-#include <stdio.h>
-
-#include "nsDebug.h"
-#include "nsError.h"
-#include "nsGkAtoms.h"
-#include "nsIDocument.h"
-#include "nsIEditor.h"
-#include "nsIHTMLEditor.h"
-#include "nsINodeList.h"
-#include "nsIPlaintextEditor.h"
-#include "nsLiteralString.h"
-#include "nsReadableUtils.h"
-#include "nsString.h"
-#include "nsStringFwd.h"
-#include "mozilla/dom/Selection.h"
-
-using mozilla::dom::Selection;
-
-#define TEST_RESULT(r) { if (NS_FAILED(r)) {printf("FAILURE result=%X\n", static_cast<uint32_t>(r)); return r; } }
-#define TEST_POINTER(p) { if (!p) {printf("FAILURE null pointer\n"); return NS_ERROR_NULL_POINTER; } }
-
-TextEditorTest::TextEditorTest()
-{
-  printf("constructed a TextEditorTest\n");
-}
-
-TextEditorTest::~TextEditorTest()
-{
-  printf("destroyed a TextEditorTest\n");
-}
-
-void TextEditorTest::Run(nsIEditor *aEditor, int32_t *outNumTests, int32_t *outNumTestsFailed)
-{
-  if (!aEditor) return;
-  mTextEditor = do_QueryInterface(aEditor);
-  mEditor = aEditor;
-  RunUnitTest(outNumTests, outNumTestsFailed);
-}
-
-nsresult TextEditorTest::RunUnitTest(int32_t *outNumTests, int32_t *outNumTestsFailed)
-{
-  NS_ENSURE_TRUE(outNumTests && outNumTestsFailed, NS_ERROR_NULL_POINTER);
-
-  *outNumTests = 0;
-  *outNumTestsFailed = 0;
-
-  nsresult rv = InitDoc();
-  TEST_RESULT(rv);
-  // shouldn't we just bail on error here?
-
-  // insert some simple text
-  rv = mTextEditor->InsertText(NS_LITERAL_STRING("1234567890abcdefghij1234567890"));
-  TEST_RESULT(rv);
-  (*outNumTests)++;
-  if (NS_FAILED(rv)) {
-    ++(*outNumTestsFailed);
-  }
-
-  // insert some more text
-  rv = mTextEditor->InsertText(NS_LITERAL_STRING("Moreover, I am cognizant of the interrelatedness of all communities and states.  I cannot sit idly by in Atlanta and not be concerned about what happens in Birmingham.  Injustice anywhere is a threat to justice everywhere"));
-  TEST_RESULT(rv);
-  (*outNumTests)++;
-  if (NS_FAILED(rv)) {
-    ++(*outNumTestsFailed);
-  }
-
-  rv = TestInsertBreak();
-  TEST_RESULT(rv);
-  (*outNumTests)++;
-  if (NS_FAILED(rv)) {
-    ++(*outNumTestsFailed);
-  }
-
-  rv = TestTextProperties();
-  TEST_RESULT(rv);
-  (*outNumTests)++;
-  if (NS_FAILED(rv)) {
-    ++(*outNumTestsFailed);
-  }
-
-  // get us back to the original document
-  rv = mEditor->Undo(12);
-  TEST_RESULT(rv);
-
-  return rv;
-}
-
-nsresult TextEditorTest::InitDoc()
-{
-  nsresult rv = mEditor->SelectAll();
-  TEST_RESULT(rv);
-  rv = mEditor->DeleteSelection(nsIEditor::eNext, nsIEditor::eStrip);
-  TEST_RESULT(rv);
-  return rv;
-}
-
-nsresult TextEditorTest::TestInsertBreak()
-{
-  RefPtr<Selection>selection;
-  nsresult rv = mEditor->GetSelection(getter_AddRefs(selection));
-  TEST_RESULT(rv);
-  TEST_POINTER(selection.get());
-  nsCOMPtr<nsINode> anchor = selection->GetAnchorNode();
-  TEST_RESULT(rv);
-  TEST_POINTER(anchor.get());
-  selection->Collapse(anchor, 0);
-  // insert one break
-  printf("inserting a break\n");
-  rv = mTextEditor->InsertLineBreak();
-  TEST_RESULT(rv);
-  mEditor->DebugDumpContent();
-
-  // insert a second break adjacent to the first
-  printf("inserting a second break\n");
-  rv = mTextEditor->InsertLineBreak();
-  TEST_RESULT(rv);
-  mEditor->DebugDumpContent();
-
-  return rv;
-}
-
-nsresult TextEditorTest::TestTextProperties()
-{
-  nsCOMPtr<nsIDocument> doc = mEditor->AsEditorBase()->GetDocument();
-  TEST_POINTER(doc.get());
-  // XXX This is broken, text nodes are not elements.
-  nsAutoString textTag(NS_LITERAL_STRING("#text"));
-  nsCOMPtr<nsINodeList>nodeList = doc->GetElementsByTagName(textTag);
-  TEST_POINTER(nodeList.get());
-  uint32_t count = nodeList->Length();
-  NS_ASSERTION(0 != count, "there are no text nodes in the document!");
-  nsCOMPtr<nsINode>textNode = nodeList->Item(count - 1);
-  TEST_POINTER(textNode.get());
-
-  // set the whole text node to bold
-  printf("set the whole first text node to bold\n");
-  RefPtr<Selection>selection;
-  nsresult rv = mEditor->GetSelection(getter_AddRefs(selection));
-  TEST_RESULT(rv);
-  TEST_POINTER(selection.get());
-  uint32_t length = textNode->Length();
-  selection->Collapse(textNode, 0);
-  selection->Extend(textNode, length);
-
-  nsCOMPtr<nsIHTMLEditor> htmlEditor (do_QueryInterface(mTextEditor));
-  NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
-
-  bool any = false;
-  bool all = false;
-  bool first=false;
-
-  const nsString& empty = EmptyString();
-
-  NS_NAMED_LITERAL_STRING(b, "b");
-  NS_NAMED_LITERAL_STRING(i, "i");
-  NS_NAMED_LITERAL_STRING(u, "u");
-
-  rv = htmlEditor->GetInlineProperty(b, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(false==first, "first should be false");
-  NS_ASSERTION(false==any, "any should be false");
-  NS_ASSERTION(false==all, "all should be false");
-  rv = htmlEditor->SetInlineProperty(b, empty, empty);
-  TEST_RESULT(rv);
-  rv = htmlEditor->GetInlineProperty(b, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(true==first, "first should be true");
-  NS_ASSERTION(true==any, "any should be true");
-  NS_ASSERTION(true==all, "all should be true");
-  mEditor->DebugDumpContent();
-
-  // remove the bold we just set
-  printf("set the whole first text node to not bold\n");
-  rv = htmlEditor->RemoveInlineProperty(b, empty);
-  TEST_RESULT(rv);
-  rv = htmlEditor->GetInlineProperty(b, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(false==first, "first should be false");
-  NS_ASSERTION(false==any, "any should be false");
-  NS_ASSERTION(false==all, "all should be false");
-  mEditor->DebugDumpContent();
-
-  // set all but the first and last character to bold
-  printf("set the first text node (1, length-1) to bold and italic, and (2, length-1) to underline.\n");
-  selection->Collapse(textNode, 1);
-  selection->Extend(textNode, length-1);
-  rv = htmlEditor->SetInlineProperty(b, empty, empty);
-  TEST_RESULT(rv);
-  rv = htmlEditor->GetInlineProperty(b, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(true==first, "first should be true");
-  NS_ASSERTION(true==any, "any should be true");
-  NS_ASSERTION(true==all, "all should be true");
-  mEditor->DebugDumpContent();
-  // make all that same text italic
-  rv = htmlEditor->SetInlineProperty(i, empty, empty);
-  TEST_RESULT(rv);
-  rv = htmlEditor->GetInlineProperty(i, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(true==first, "first should be true");
-  NS_ASSERTION(true==any, "any should be true");
-  NS_ASSERTION(true==all, "all should be true");
-  rv = htmlEditor->GetInlineProperty(b, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(true==first, "first should be true");
-  NS_ASSERTION(true==any, "any should be true");
-  NS_ASSERTION(true==all, "all should be true");
-  mEditor->DebugDumpContent();
-
-  // make all the text underlined, except for the first 2 and last 2 characters
-  nodeList = doc->GetElementsByTagName(textTag);
-  TEST_POINTER(nodeList.get());
-  count = nodeList->Length();
-  NS_ASSERTION(0!=count, "there are no text nodes in the document!");
-  textNode = nodeList->Item(count-2);
-  TEST_POINTER(textNode.get());
-  length = textNode->Length();
-  NS_ASSERTION(length==915, "wrong text node");
-  selection->Collapse(textNode, 1);
-  selection->Extend(textNode, length-2);
-  rv = htmlEditor->SetInlineProperty(u, empty, empty);
-  TEST_RESULT(rv);
-  rv = htmlEditor->GetInlineProperty(u, empty, empty, &first, &any, &all);
-  TEST_RESULT(rv);
-  NS_ASSERTION(true==first, "first should be true");
-  NS_ASSERTION(true==any, "any should be true");
-  NS_ASSERTION(true==all, "all should be true");
-  mEditor->DebugDumpContent();
-
-  return rv;
-}
-
-#endif
deleted file mode 100644
--- a/editor/libeditor/TextEditorTest.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __TextEditorTest_h__
-#define __TextEditorTest_h__
-
-#include "nscore.h"
-
-class nsIEditor;
-class nsIPlaintextEditor;
-#ifdef DEBUG
-
-#include "nsCOMPtr.h"
-
-class TextEditorTest
-{
-public:
-
-  void Run(nsIEditor *aEditor, int32_t *outNumTests, int32_t *outNumTestsFailed);
-  TextEditorTest();
-  ~TextEditorTest();
-
-protected:
-
-  /** create an empty document */
-  nsresult InitDoc();
-
-  nsresult RunUnitTest(int32_t *outNumTests, int32_t *outNumTestsFailed);
-
-  nsresult TestInsertBreak();
-
-  nsresult TestTextProperties();
-
-  nsCOMPtr<nsIPlaintextEditor> mTextEditor;
-  nsCOMPtr<nsIEditor> mEditor;
-};
-
-#endif /* DEBUG */
-
-#endif
--- a/editor/libeditor/moz.build
+++ b/editor/libeditor/moz.build
@@ -66,17 +66,16 @@ UNIFIED_SOURCES += [
     'InsertTextTransaction.cpp',
     'InternetCiter.cpp',
     'JoinNodeTransaction.cpp',
     'PlaceholderTransaction.cpp',
     'SelectionState.cpp',
     'SplitNodeTransaction.cpp',
     'TextEditor.cpp',
     'TextEditorDataTransfer.cpp',
-    'TextEditorTest.cpp',
     'TextEditRules.cpp',
     'TextEditRulesBidi.cpp',
     'TextEditUtils.cpp',
     'TypeInState.cpp',
     'WSRunObject.cpp',
 ]
 
 LOCAL_INCLUDES += [
--- a/editor/nsIEditor.idl
+++ b/editor/nsIEditor.idl
@@ -466,30 +466,16 @@ interface nsIEditor  : nsISupports
   void removeEditActionListener(in nsIEditActionListener listener);
 
   /** Add a DocumentStateListener to the editors list of doc state listeners. */
   void addDocumentStateListener(in nsIDocumentStateListener listener);
 
   /** Remove a DocumentStateListener to the editors list of doc state listeners. */
   void removeDocumentStateListener(in nsIDocumentStateListener listener);
 
-
-  /* ------------ Debug methods -------------- */
-
-  /**
-   * And a debug method -- show us what the tree looks like right now
-   */
-  void dumpContentTree();
-
-  /** Dumps a text representation of the content tree to standard out */
-  void debugDumpContent() ;
-
-  /* Run unit tests. Noop in optimized builds */
-  void debugUnitTests(out long outNumTests, out long  outNumTestsFailed);
-
   /**
    * forceCompositionEnd() force the composition end
    */
   void forceCompositionEnd();
 
   /**
    * whether this editor has active IME transaction
    */
--- a/extensions/auth/moz.build
+++ b/extensions/auth/moz.build
@@ -1,35 +1,36 @@
 # -*- 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/.
 
 UNIFIED_SOURCES += [
-    'nsAuthFactory.cpp',
     'nsAuthGSSAPI.cpp',
 ]
 
 SOURCES += [
     'nsAuthSASL.cpp',
     'nsHttpNegotiateAuth.cpp', # contains constants whose names conflict with constants in other files
+    'nsIAuthModule.cpp',       # includes windows.h recursively which conflicts with TimeStamp.h
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     SOURCES += [
         'nsAuthSSPI.cpp',
     ]
     DEFINES['USE_SSPI'] = True
 else:
     UNIFIED_SOURCES += [
         'nsAuthSambaNTLM.cpp',
     ]
 
 LOCAL_INCLUDES += [
     '/netwerk/dns', # For nsDNSService2.h
+    '/security/manager/ssl',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'Networking')
 
--- a/extensions/auth/nsAuthSASL.cpp
+++ b/extensions/auth/nsAuthSASL.cpp
@@ -38,29 +38,27 @@ nsAuthSASL::Init(const char *serviceName
     NS_ASSERTION(!domain && !password, "unexpected credentials");
 
     mUsername = username;
 
     // If we're doing SASL, we should do mutual auth
     serviceFlags |= REQ_MUTUAL_AUTH;
 
     // Find out whether we should be trying SSPI or not
-    const char *contractID = NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-gss";
+    const char *authType = "kerb-gss";
 
     nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (prefs) {
         bool val;
         rv = prefs->GetBoolPref(kNegotiateAuthSSPI, &val);
         if (NS_SUCCEEDED(rv) && val)
-            contractID = NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-sspi";
+            authType = "kerb-sspi";
     }
 
-    mInnerModule = do_CreateInstance(contractID, &rv);
-    // if we can't create the GSSAPI module, then bail
-    NS_ENSURE_SUCCESS(rv, rv);
+    MOZ_ALWAYS_TRUE(mInnerModule = nsIAuthModule::CreateInstance(authType));
 
     mInnerModule->Init(serviceName, serviceFlags, nullptr, nullptr, nullptr);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAuthSASL::GetNextToken(const void *inToken,
--- a/extensions/auth/nsAuthSSPI.h
+++ b/extensions/auth/nsAuthSSPI.h
@@ -34,17 +34,17 @@ public:
 
     explicit nsAuthSSPI(pType package = PACKAGE_TYPE_NEGOTIATE);
 
 private:
     ~nsAuthSSPI();
 
     void Reset();
 
-    typedef TimeStamp MS_TimeStamp;
+    typedef ::TimeStamp MS_TimeStamp;
 
 private:
     nsresult MakeSN(const char *principal, nsCString &result);
 
     CredHandle   mCred;
     CtxtHandle   mCtxt;
     nsCString    mServiceName;
     uint32_t     mServiceFlags;
--- a/extensions/auth/nsHttpNegotiateAuth.cpp
+++ b/extensions/auth/nsHttpNegotiateAuth.cpp
@@ -44,29 +44,32 @@
 #include "nsIChannel.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 #include "nsIHttpAuthenticatorCallback.h"
 #include "mozilla/Mutex.h"
 #include "nsICancelable.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/net/HttpAuthUtils.h"
+#include "mozilla/ClearOnShutdown.h"
 
 using mozilla::Base64Decode;
 
 //-----------------------------------------------------------------------------
 
 static const char kNegotiate[] = "Negotiate";
 static const char kNegotiateAuthTrustedURIs[] = "network.negotiate-auth.trusted-uris";
 static const char kNegotiateAuthDelegationURIs[] = "network.negotiate-auth.delegation-uris";
 static const char kNegotiateAuthAllowProxies[] = "network.negotiate-auth.allow-proxies";
 static const char kNegotiateAuthAllowNonFqdn[] = "network.negotiate-auth.allow-non-fqdn";
 static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
 static const char kSSOinPBmode[] = "network.auth.private-browsing-sso";
 
+mozilla::StaticRefPtr<nsHttpNegotiateAuth> nsHttpNegotiateAuth::gSingleton;
+
 #define kNegotiateLen  (sizeof(kNegotiate)-1)
 #define DEFAULT_THREAD_TIMEOUT_MS 30000
 
 //-----------------------------------------------------------------------------
 
 // Return false when the channel comes from a Private browsing window.
 static bool
 TestNotInPBMode(nsIHttpAuthenticableChannel *authChannel, bool proxyAuth)
@@ -100,16 +103,31 @@ TestNotInPBMode(nsIHttpAuthenticableChan
             dontRememberHistory) {
             return true;
         }
     }
 
     return false;
 }
 
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpNegotiateAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpNegotiateAuth();
+      mozilla::ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 NS_IMETHODIMP
 nsHttpNegotiateAuth::GetAuthFlags(uint32_t *flags)
 {
     //
     // Negotiate Auth creds should not be reused across multiple requests.
     // Only perform the negotiation when it is explicitly requested by the
     // server.  Thus, do *NOT* use the "REUSABLE_CREDENTIALS" flag here.
     //
@@ -131,23 +149,24 @@ nsHttpNegotiateAuth::GetAuthFlags(uint32
 NS_IMETHODIMP
 nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel *authChannel,
                                        const char *challenge,
                                        bool isProxyAuth,
                                        nsISupports **sessionState,
                                        nsISupports **continuationState,
                                        bool *identityInvalid)
 {
-    nsIAuthModule *module = (nsIAuthModule *) *continuationState;
+    nsIAuthModule *rawModule = (nsIAuthModule *) *continuationState;
 
     *identityInvalid = false;
-    if (module)
+    if (rawModule)
         return NS_OK;
 
     nsresult rv;
+    nsCOMPtr<nsIAuthModule> module;
 
     nsCOMPtr<nsIURI> uri;
     rv = authChannel->GetURI(getter_AddRefs(uri));
     if (NS_FAILED(rv))
         return rv;
 
     uint32_t req_flags = nsIAuthModule::REQ_DEFAULT;
     nsAutoCString service;
@@ -192,41 +211,35 @@ nsHttpNegotiateAuth::ChallengeReceived(n
     // construct the proper service name for passing to "gss_import_name".
     //
     // TODO: Possibly make this a configurable service name for use
     // with non-standard servers that use stuff like "khttp/f.q.d.n"
     // instead.
     //
     service.InsertLiteral("HTTP@", 0);
 
-    const char *contractID;
+    const char *authType;
     if (TestBoolPref(kNegotiateAuthSSPI)) {
 	   LOG(("  using negotiate-sspi\n"));
-	   contractID = NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate-sspi";
+	   authType = "negotiate-sspi";
     }
     else {
 	   LOG(("  using negotiate-gss\n"));
-	   contractID = NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate-gss";
+	   authType = "negotiate-gss";
     }
 
-    rv = CallCreateInstance(contractID, &module);
-
-    if (NS_FAILED(rv)) {
-        LOG(("  Failed to load Negotiate Module \n"));
-        return rv;
-    }
+    MOZ_ALWAYS_TRUE(module = nsIAuthModule::CreateInstance(authType));
 
     rv = module->Init(service.get(), req_flags, nullptr, nullptr, nullptr);
 
     if (NS_FAILED(rv)) {
-        NS_RELEASE(module);
         return rv;
     }
 
-    *continuationState = module;
+    module.forget(continuationState);
     return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(nsHttpNegotiateAuth, nsIHttpAuthenticator)
 
 namespace {
 
 //
@@ -377,22 +390,18 @@ class GetNextTokenRunnable final : publi
                                                    mContinuationState.forget());
         }
 
         NS_IMETHODIMP ObtainCredentialsAndFlags(char **aCreds, uint32_t *aFlags)
         {
             nsresult rv;
 
             // Use negotiate service to call GenerateCredentials outside of main thread
-            nsAutoCString contractId;
-            contractId.AssignLiteral(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
-            contractId.AppendLiteral("negotiate");
             nsCOMPtr<nsIHttpAuthenticator> authenticator =
-              do_GetService(contractId.get(), &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
+              new nsHttpNegotiateAuth();
 
             nsISupports *sessionState = mSessionState;
             nsISupports *continuationState = mContinuationState;
             // The continuationState is for the sake of completeness propagated
             // to the caller (despite it is not changed in any GenerateCredentials
             // implementation).
             //
             // The only implementation that use sessionState is the
--- a/extensions/auth/nsHttpNegotiateAuth.h
+++ b/extensions/auth/nsHttpNegotiateAuth.h
@@ -5,31 +5,37 @@
 
 #ifndef nsHttpNegotiateAuth_h__
 #define nsHttpNegotiateAuth_h__
 
 #include "nsIHttpAuthenticator.h"
 #include "nsIURI.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/LazyIdleThread.h"
+#include "mozilla/StaticPtr.h"
 
 // The nsHttpNegotiateAuth class provides responses for the GSS-API Negotiate method
 // as specified by Microsoft in draft-brezak-spnego-http-04.txt
 
 class nsHttpNegotiateAuth final : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
 private:
     ~nsHttpNegotiateAuth() {}
 
     // returns the value of the given boolean pref
     bool TestBoolPref(const char *pref);
 
     // tests if the host part of an uri is fully qualified
     bool TestNonFqdn(nsIURI *uri);
 
     // Thread for GenerateCredentialsAsync
     RefPtr<mozilla::LazyIdleThread> mNegotiateThread;
+
+    // Singleton pointer
+    static mozilla::StaticRefPtr<nsHttpNegotiateAuth> gSingleton;
 };
 #endif /* nsHttpNegotiateAuth_h__ */
rename from extensions/auth/nsAuthFactory.cpp
rename to extensions/auth/nsIAuthModule.cpp
--- a/extensions/auth/nsAuthFactory.cpp
+++ b/extensions/auth/nsIAuthModule.cpp
@@ -1,247 +1,65 @@
 /* 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 "mozilla/ModuleUtils.h"
-#include "nsAuth.h"
-
-//-----------------------------------------------------------------------------
-
-#define NS_HTTPNEGOTIATEAUTH_CID                   \
-{ /* 75c80fd0-accb-432c-af59-ec60668c3990 */       \
-  0x75c80fd0,                                      \
-  0xaccb,                                          \
-  0x432c,                                          \
-  {0xaf, 0x59, 0xec, 0x60, 0x66, 0x8c, 0x39, 0x90} \
-}
-
-#include "nsHttpNegotiateAuth.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNegotiateAuth)
-//-----------------------------------------------------------------------------
-
-#define NS_NEGOTIATEAUTH_CID                       \
-{ /* 96ec4163-efc8-407a-8735-007fb26be4e8 */       \
-  0x96ec4163,                                      \
-  0xefc8,                                          \
-  0x407a,                                          \
-  {0x87, 0x35, 0x00, 0x7f, 0xb2, 0x6b, 0xe4, 0xe8} \
-}
-#define NS_GSSAUTH_CID                             \
-{ /* dc8e21a0-03e4-11da-8cd6-0800200c9a66 */       \
-  0xdc8e21a0,                                      \
-  0x03e4,                                          \
-  0x11da,                                          \
-  {0x8c, 0xd6, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66} \
-}
-
-#include "nsAuthGSSAPI.h"
-
+#include "nsIAuthModule.h"
 #if defined( USE_SSPI )
 #include "nsAuthSSPI.h"
-
-static nsresult
-nsSysNTLMAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
-{
-  if (outer)
-    return NS_ERROR_NO_AGGREGATION;
-
-  nsAuthSSPI *auth = new nsAuthSSPI(PACKAGE_TYPE_NTLM);
-  if (!auth)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(auth);
-  nsresult rv = auth->QueryInterface(iid, result);
-  NS_RELEASE(auth);
-  return rv;
-}
-
-static nsresult
-nsKerbSSPIAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
-{
-  if (outer)
-    return NS_ERROR_NO_AGGREGATION;
-
-  nsAuthSSPI *auth = new nsAuthSSPI(PACKAGE_TYPE_KERBEROS);
-  if (!auth)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(auth);
-  nsresult rv = auth->QueryInterface(iid, result);
-  NS_RELEASE(auth);
-  return rv;
-}
-
-#define NS_SYSNTLMAUTH_CID                         \
-{ /* dc195987-6e9a-47bc-b1fd-ab895d398833 */       \
-  0xdc195987,                                      \
-  0x6e9a,                                          \
-  0x47bc,                                          \
-  {0xb1, 0xfd, 0xab, 0x89, 0x5d, 0x39, 0x88, 0x33} \
-}
+#else
+#include "nsAuthSambaNTLM.h"
+#endif
+#include "nsCRT.h"
+#include "nsAuthGSSAPI.h"
+#include "nsAuthSASL.h"
+#include "nsNTLMAuthModule.h"
+#include "nsNSSComponent.h"
 
-#define NS_NEGOTIATEAUTHSSPI_CID                   \
-{ /* 78d3b0c0-0241-11da-8cd6-0800200c9a66 */       \
-  0x78d3b0c0,                                      \
-  0x0241,                                          \
-  0x11da,                                          \
-  {0x8c, 0xd6, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66} \
-}
-
-#define NS_KERBAUTHSSPI_CID                        \
-{ /* 8c3a0e20-03e5-11da-8cd6-0800200c9a66 */       \
-  0x8c3a0e20,                                      \
-  0x03e5,                                          \
-  0x11da,                                          \
-  {0x8c, 0xd6, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66} \
-}
-
-#else
+// static
+already_AddRefed<nsIAuthModule>
+nsIAuthModule::CreateInstance(const char* aType)
+{
+  nsCOMPtr<nsIAuthModule> auth;
+  if (!nsCRT::strcmp(aType, "kerb-gss")) {
+    auth = new nsAuthGSSAPI(PACKAGE_TYPE_KERBEROS);
+  } else if (!nsCRT::strcmp(aType, "negotiate-gss")) {
+    auth = new nsAuthGSSAPI(PACKAGE_TYPE_NEGOTIATE);
+#if defined( USE_SSPI )
+  } else if (!nsCRT::strcmp(aType, "negotiate-sspi")) {
+    auth = new nsAuthSSPI();
+  } else if (!nsCRT::strcmp(aType, "kerb-sspi")) {
+    auth = new nsAuthSSPI(PACKAGE_TYPE_KERBEROS);
+  } else if (!nsCRT::strcmp(aType, "sys-ntlm")) {
+    auth = new nsAuthSSPI(PACKAGE_TYPE_NTLM);
+#elif !defined(XP_MACOSX)
+  } else if (!nsCRT::strcmp(aType, "sys-ntlm")) {
+    RefPtr<nsAuthSambaNTLM> sambaAuth = new nsAuthSambaNTLM();
 
-#define NS_SAMBANTLMAUTH_CID                       \
-{ /* bc54f001-6eb0-4e32-9f49-7e064d8e70ef */       \
-  0xbc54f001,                                      \
-  0x6eb0,                                          \
-  0x4e32,                                          \
-  {0x9f, 0x49, 0x7e, 0x06, 0x4d, 0x8e, 0x70, 0xef} \
-}
+    nsresult rv = sambaAuth->SpawnNTLMAuthHelper();
+    if (NS_FAILED(rv)) {
+      // Failure here probably means that cached credentials were not available
+      return nullptr;
+    }
 
-#include "nsAuthSambaNTLM.h"
-static nsresult
-nsSambaNTLMAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
-{
-  if (outer)
-    return NS_ERROR_NO_AGGREGATION;
+    auth = sambaAuth.forget();
+#endif
+  } else if (!nsCRT::strcmp(aType, "sasl-gssapi")) {
+    auth = new nsAuthSASL();
+  } else if (!nsCRT::strcmp(aType, "ntlm") &&
+    XRE_IsParentProcess() &&
+    EnsureNSSInitializedChromeOrContent()) {
+    RefPtr<nsNTLMAuthModule> ntlmAuth = new nsNTLMAuthModule();
 
-  RefPtr<nsAuthSambaNTLM> auth = new nsAuthSambaNTLM();
-  if (!auth)
-    return NS_ERROR_OUT_OF_MEMORY;
+    nsresult rv = ntlmAuth->InitTest();
+    if (NS_FAILED(rv)) {
+      return nullptr;
+    }
 
-  nsresult rv = auth->SpawnNTLMAuthHelper();
-  if (NS_FAILED(rv)) {
-    // Failure here probably means that cached credentials were not available
-    return rv;
+    auth = ntlmAuth.forget();
+  } else {
+    return nullptr;
   }
 
-  return auth->QueryInterface(iid, result);
-}
-
-#endif
-
-static nsresult
-nsKerbGSSAPIAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
-{
-  if (outer)
-    return NS_ERROR_NO_AGGREGATION;
-
-  nsAuthGSSAPI *auth = new nsAuthGSSAPI(PACKAGE_TYPE_KERBEROS);
-  if (!auth)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(auth);
-  nsresult rv = auth->QueryInterface(iid, result);
-  NS_RELEASE(auth);
-  return rv;
-}
-
-static nsresult
-nsGSSAPIAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
-{
-  if (outer)
-    return NS_ERROR_NO_AGGREGATION;
-
-  nsAuthGSSAPI *auth = new nsAuthGSSAPI(PACKAGE_TYPE_NEGOTIATE);
-  if (!auth)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(auth);
-  nsresult rv = auth->QueryInterface(iid, result);
-  NS_RELEASE(auth);
-  return rv;
-}
-
-
-#if defined( USE_SSPI )
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsAuthSSPI)
-#endif
-
-#define NS_AUTHSASL_CID                            \
-{ /* 815e42e0-72cc-480f-934b-148e33c228a6 */       \
-  0x815e42e0,                                      \
-  0x72cc,                                          \
-  0x480f,                                          \
-  {0x93, 0x4b, 0x14, 0x8e, 0x33, 0xc2, 0x28, 0xa6} \
+  return auth.forget();
 }
 
-#include "nsAuthSASL.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsAuthSASL)
-
-NS_DEFINE_NAMED_CID(NS_GSSAUTH_CID);
-NS_DEFINE_NAMED_CID(NS_NEGOTIATEAUTH_CID);
-#if defined( USE_SSPI )
-NS_DEFINE_NAMED_CID(NS_NEGOTIATEAUTHSSPI_CID);
-NS_DEFINE_NAMED_CID(NS_KERBAUTHSSPI_CID);
-NS_DEFINE_NAMED_CID(NS_SYSNTLMAUTH_CID);
-#else
-NS_DEFINE_NAMED_CID(NS_SAMBANTLMAUTH_CID);
-#endif
-NS_DEFINE_NAMED_CID(NS_HTTPNEGOTIATEAUTH_CID);
-NS_DEFINE_NAMED_CID(NS_AUTHSASL_CID);
-
-
-static const mozilla::Module::CIDEntry kAuthCIDs[] = {
-  { &kNS_GSSAUTH_CID, false, nullptr, nsKerbGSSAPIAuthConstructor },
-  { &kNS_NEGOTIATEAUTH_CID, false, nullptr, nsGSSAPIAuthConstructor },
-#if defined( USE_SSPI )
-  { &kNS_NEGOTIATEAUTHSSPI_CID, false, nullptr, nsAuthSSPIConstructor },
-  { &kNS_KERBAUTHSSPI_CID, false, nullptr, nsKerbSSPIAuthConstructor },
-  { &kNS_SYSNTLMAUTH_CID, false, nullptr, nsSysNTLMAuthConstructor },
-#else
-  { &kNS_SAMBANTLMAUTH_CID, false, nullptr, nsSambaNTLMAuthConstructor },
-#endif
-  { &kNS_HTTPNEGOTIATEAUTH_CID, false, nullptr, nsHttpNegotiateAuthConstructor },
-  { &kNS_AUTHSASL_CID, false, nullptr, nsAuthSASLConstructor },
-  { nullptr }
-};
-
-static const mozilla::Module::ContractIDEntry kAuthContracts[] = {
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-gss", &kNS_GSSAUTH_CID },
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate-gss", &kNS_NEGOTIATEAUTH_CID },
-#if defined( USE_SSPI )
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate-sspi", &kNS_NEGOTIATEAUTHSSPI_CID },
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-sspi", &kNS_KERBAUTHSSPI_CID },
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm", &kNS_SYSNTLMAUTH_CID },
-#elif !defined(XP_MACOSX)
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm", &kNS_SAMBANTLMAUTH_CID },
-#endif
-  { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "negotiate", &kNS_HTTPNEGOTIATEAUTH_CID },
-  { NS_AUTH_MODULE_CONTRACTID_PREFIX "sasl-gssapi", &kNS_AUTHSASL_CID },
-  { nullptr }
-};
-
-//-----------------------------------------------------------------------------
 mozilla::LazyLogModule gNegotiateLog("negotiateauth");
-
-// setup nspr logging ...
-static nsresult
-InitNegotiateAuth()
-{
-  return NS_OK;
-}
-
-static void
-DestroyNegotiateAuth()
-{
-  nsAuthGSSAPI::Shutdown();
-}
-
-static const mozilla::Module kAuthModule = {
-  mozilla::Module::kVersion,
-  kAuthCIDs,
-  kAuthContracts,
-  nullptr,
-  nullptr,
-  InitNegotiateAuth,
-  DestroyNegotiateAuth
-};
-
-NSMODULE_DEFN(nsAuthModule) = &kAuthModule;
--- a/gfx/webrender/src/image.rs
+++ b/gfx/webrender/src/image.rs
@@ -151,20 +151,20 @@ pub fn repetitions(
 #[derive(Debug)]
 pub struct Tile {
     pub rect: LayoutRect,
     pub offset: TileOffset,
     pub edge_flags: EdgeAaSegmentMask,
 }
 
 pub struct TileIterator {
-    current_x: u16,
-    x_count: u16,
-    current_y: u16,
-    y_count: u16,
+    current_x: u32,
+    x_count: u32,
+    current_y: u32,
+    y_count: u32,
     origin: TileOffset,
     tile_size: LayoutSize,
     leftover_offset: TileOffset,
     leftover_size: LayoutSize,
     local_origin: LayoutPoint,
     row_flags: EdgeAaSegmentMask,
 }
 
@@ -297,36 +297,53 @@ pub fn tiles(
     // The size in layer space of the tiles on the right and bottom edges.
     let leftover_layer_size = LayoutSize::new(
         layer_tile_size.width * leftover_device_size.width as f32 / device_tile_size_f32,
         layer_tile_size.height * leftover_device_size.height as f32 / device_tile_size_f32,
     );
 
     // Offset of the row and column of tiles with leftover size.
     let leftover_offset = TileOffset::new(
-        (device_image_size.width / device_tile_size) as u16,
-        (device_image_size.height / device_tile_size) as u16,
+        (device_image_size.width / device_tile_size) as u32,
+        (device_image_size.height / device_tile_size) as u32,
     );
 
     // Number of culled out tiles to skip before the first visible tile.
     let t0 = TileOffset::new(
         if visible_rect.origin.x > prim_rect.origin.x {
-            f32::floor((visible_rect.origin.x - prim_rect.origin.x) / layer_tile_size.width) as u16
+            f32::floor((visible_rect.origin.x - prim_rect.origin.x) / layer_tile_size.width) as u32
         } else {
             0
         },
         if visible_rect.origin.y > prim_rect.origin.y {
-            f32::floor((visible_rect.origin.y - prim_rect.origin.y) / layer_tile_size.height) as u16
+            f32::floor((visible_rect.origin.y - prim_rect.origin.y) / layer_tile_size.height) as u32
         } else {
             0
         },
     );
 
-    let x_count = f32::ceil((visible_rect.max_x() - prim_rect.origin.x) / layer_tile_size.width) as u16 - t0.x;
-    let y_count = f32::ceil((visible_rect.max_y() - prim_rect.origin.y) / layer_tile_size.height) as u16 - t0.y;
+    // Since we're working in layer space, we can end up computing leftover tiles with an empty
+    // size due to floating point precision issues. Detect this case so that we don't return
+    // tiles with an empty size.
+    let x_count = {
+        let result = f32::ceil((visible_rect.max_x() - prim_rect.origin.x) / layer_tile_size.width) as u32 - t0.x;
+        if result == leftover_offset.x + 1 && leftover_layer_size.width == 0.0f32 {
+            leftover_offset.x
+        } else {
+            result
+        }
+    };
+    let y_count = {
+        let result = f32::ceil((visible_rect.max_y() - prim_rect.origin.y) / layer_tile_size.height) as u32 - t0.y;
+        if result == leftover_offset.y + 1 && leftover_layer_size.height == 0.0f32 {
+            leftover_offset.y
+        } else {
+            result
+        }
+    };
 
     let mut row_flags = EdgeAaSegmentMask::TOP;
     if y_count == 1 {
         row_flags |= EdgeAaSegmentMask::BOTTOM;
     }
     TileIterator {
         current_x: 0,
         current_y: 0,
@@ -347,22 +364,22 @@ pub fn compute_tile_range(
 ) -> TileRange {
     // Tile dimensions in normalized coordinates.
     let tw = 1. / (tile_size as f32);
     let th = 1. / (tile_size as f32);
 
     let t0 = point2(
         f32::floor(visible_area.origin.x as f32 * tw),
         f32::floor(visible_area.origin.y as f32 * th),
-    ).try_cast::<u16>().unwrap_or_else(|| panic!("compute_tile_range bad values {:?} {:?}", visible_area, tile_size));
+    ).try_cast::<u32>().unwrap_or_else(|| panic!("compute_tile_range bad values {:?} {:?}", visible_area, tile_size));
 
     let t1 = point2(
         f32::ceil(visible_area.max_x() as f32 * tw),
         f32::ceil(visible_area.max_y() as f32 * th),
-    ).try_cast::<u16>().unwrap_or_else(|| panic!("compute_tile_range bad values {:?} {:?}", visible_area, tile_size));
+    ).try_cast::<u32>().unwrap_or_else(|| panic!("compute_tile_range bad values {:?} {:?}", visible_area, tile_size));
 
     TileRange {
         origin: t0,
         size: (t1 - t0).to_size(),
     }
 }
 
 pub fn for_each_tile_in_range(
--- a/gfx/webrender_api/src/units.rs
+++ b/gfx/webrender_api/src/units.rs
@@ -88,18 +88,18 @@ pub type WorldPoint = TypedPoint2D<f32, 
 pub type WorldSize = TypedSize2D<f32, WorldPixel>;
 pub type WorldPoint3D = TypedPoint3D<f32, WorldPixel>;
 pub type WorldVector2D = TypedVector2D<f32, WorldPixel>;
 pub type WorldVector3D = TypedVector3D<f32, WorldPixel>;
 
 /// Offset in number of tiles.
 #[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
 pub struct Tiles;
-pub type TileOffset = TypedPoint2D<u16, Tiles>;
-pub type TileRange = TypedRect<u16, Tiles>;
+pub type TileOffset = TypedPoint2D<u32, Tiles>;
+pub type TileRange = TypedRect<u32, Tiles>;
 
 /// Scaling ratio from world pixels to device pixels.
 pub type DevicePixelScale = TypedScale<f32, WorldPixel, DevicePixel>;
 /// Scaling ratio from layout to world. Used for cases where we know the layout
 /// is in world space, or specifically want to treat it this way.
 pub type LayoutToWorldScale = TypedScale<f32, LayoutPixel, WorldPixel>;
 /// A complete scaling ratio from layout space to device pixel space.
 pub type LayoutToDeviceScale = TypedScale<f32, LayoutPixel, DevicePixel>;
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-855eac28847f289575210357418a3d0f9881e285
+154844d79c840dcc15b28d824498bf0713d4e7d1
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -967,17 +967,17 @@ struct ByteSlice {
   uintptr_t len;
 
   bool operator==(const ByteSlice& aOther) const {
     return buffer == aOther.buffer &&
            len == aOther.len;
   }
 };
 
-using TileOffset = TypedPoint2D<uint16_t, Tiles>;
+using TileOffset = TypedPoint2D<uint32_t, Tiles>;
 
 using DeviceUintRect = TypedRect<uint32_t, DevicePixel>;
 
 struct MutByteSlice {
   uint8_t *buffer;
   uintptr_t len;
 
   bool operator==(const MutByteSlice& aOther) const {
--- a/js/src/NamespaceImports.h
+++ b/js/src/NamespaceImports.h
@@ -42,19 +42,16 @@ class SourceBufferHolder;
 
 class HandleValueArray;
 
 class ObjectOpResult;
 class PropertyResult;
 
 enum class SymbolCode: uint32_t;
 
-#ifdef ENABLE_BIGINT
-class BigInt;
-#endif
 } // namespace JS
 
 // Do the importing.
 namespace js {
 
 using JS::Value;
 using JS::BooleanValue;
 using JS::DoubleValue;
@@ -166,11 +163,12 @@ using JS::Realm;
 using JS::Zone;
 
 using JS::Symbol;
 using JS::SymbolCode;
 
 #ifdef ENABLE_BIGINT
 using JS::BigInt;
 #endif
+
 } /* namespace js */
 
 #endif /* NamespaceImports_h */
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -8083,16 +8083,19 @@ GeneralParser<ParseHandler, Unit>::class
                 return null();
             }
             if (!tokenStream.getToken(&tt)) {
                 return null();
             }
             Node initializer = null();
             if (tt == TokenKind::Assign) {
                 initializer = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
+                if (!initializer) {
+                    return null();
+                }
                 if (!tokenStream.getToken(&tt)) {
                     return null();
                 }
             }
 
             // TODO(khyperia): Implement ASI
             if (tt != TokenKind::Semi) {
                 error(JSMSG_MISSING_SEMI_FIELD);
--- a/js/src/gc/DeletePolicy.h
+++ b/js/src/gc/DeletePolicy.h
@@ -4,22 +4,16 @@
  * 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/. */
 
 #ifndef gc_DeletePolicy_h
 #define gc_DeletePolicy_h
 
 #include "js/TracingAPI.h"
 
-#ifdef ENABLE_BIGINT
-namespace JS {
-class BigInt;
-} // namespace JS
-#endif
-
 namespace js {
 namespace gc {
 
 struct ClearEdgesTracer : public JS::CallbackTracer
 {
     ClearEdgesTracer();
 
 #ifdef DEBUG
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/xdr/bug1427860.js
@@ -0,0 +1,12 @@
+// |jit-test| skip-if: !('oomAtAllocation' in this)
+
+let x = cacheEntry("function inner() { return 3; }; inner()");
+evaluate(x, { saveIncrementalBytecode: true });
+
+try {
+    // Fail XDR decode with partial script
+    oomAtAllocation(20);
+    evaluate(x, { loadBytecode: true });
+} catch { }
+
+getLcovInfo();
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -696,16 +696,20 @@ js::XDRScript(XDRState<mode>* xdr, Handl
     }
 
     if (mode == XDR_DECODE) {
         if (!script->createScriptData(cx, length, nsrcnotes, natoms)) {
             return xdr->fail(JS::TranscodeResult_Throw);
         }
     }
 
+    // If XDR operation fails, we must call JSScript::freeScriptData in order
+    // to neuter the script. Various things that iterate raw scripts in a GC
+    // arena use the presense of this data to detect if initialization is
+    // complete.
     auto scriptDataGuard = mozilla::MakeScopeExit([&] {
         if (mode == XDR_DECODE) {
             script->freeScriptData();
         }
     });
 
     jsbytecode* code = script->code();
     MOZ_TRY(xdr->codeBytes(code, length));
@@ -717,17 +721,16 @@ js::XDRScript(XDRState<mode>* xdr, Handl
             MOZ_TRY(XDRAtom(xdr, &tmp));
             script->atoms()[i].init(tmp);
         } else {
             RootedAtom tmp(cx, script->atoms()[i]);
             MOZ_TRY(XDRAtom(xdr, &tmp));
         }
     }
 
-    scriptDataGuard.release();
     if (mode == XDR_DECODE) {
         if (!script->shareScriptData(cx)) {
             return xdr->fail(JS::TranscodeResult_Throw);
         }
     }
 
     if (nconsts) {
         RootedValue val(cx);
@@ -976,16 +979,17 @@ js::XDRScript(XDRState<mode>* xdr, Handl
         scriptp.set(script);
 
         /* see BytecodeEmitter::tellDebuggerAboutCompiledScript */
         if (!fun && !cx->helperThread()) {
             Debugger::onNewScript(cx, script);
         }
     }
 
+    scriptDataGuard.release();
     return Ok();
 }
 
 template XDRResult
 js::XDRScript(XDRState<XDR_ENCODE>*, HandleScope, HandleScriptSourceObject, HandleFunction,
               MutableHandleScript);
 
 template XDRResult
--- a/layout/reftests/w3c-css/submitted/values3/calc-background-position-1-ref.html
+++ b/layout/reftests/w3c-css/submitted/values3/calc-background-position-1-ref.html
@@ -4,17 +4,17 @@
   <title>CSS Reference: Test for calc() on background-position</title>
   <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
   <meta name="flags" content="">
 <style type="text/css">
 
 p {
     height: 50px; width: 200px;
     border: thin solid;
-    background-image: url(../backgrounds/blue-32x32.png);
+    background-image: url(support/blue-32x32.png);
     background-repeat: no-repeat;
 }
 
 #one { background-position: 134px -12px }
 #two { background-position: -18px -19px }
 
 </style>
 </head>
--- a/layout/reftests/w3c-css/submitted/values3/calc-background-position-1.html
+++ b/layout/reftests/w3c-css/submitted/values3/calc-background-position-1.html
@@ -6,17 +6,17 @@
   <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
   <link rel="match" href="calc-background-position-1-ref.html">
   <meta name="flags" content="">
 <style type="text/css">
 
 p {
     height: 50px; width: 200px;
     border: thin solid;
-    background-image: url(../backgrounds/blue-32x32.png);
+    background-image: url(support/blue-32x32.png);
     background-repeat: no-repeat;
 }
 
 #one { background-position: calc(50px + 50%) calc(100% - 30px) }
 #two { background-position: calc(-12.5% + 3px) calc(-10px - 50%) }
 
 </style>
 </head>
--- a/layout/reftests/w3c-css/submitted/values3/calc-background-size-1-ref.html
+++ b/layout/reftests/w3c-css/submitted/values3/calc-background-size-1-ref.html
@@ -4,17 +4,17 @@
   <title>CSS Reference: Test for calc() on background-size</title>
   <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
   <meta name="flags" content="">
 <style type="text/css">
 
 p {
     height: 50px; width: 200px;
     border: thin solid;
-    background-image: url(../backgrounds/blue-32x32.png);
+    background-image: url(support/blue-32x32.png);
     background-repeat: no-repeat;
 }
 
 #one { background-size: 150px 20px; }
 #two { background-image: none }
 
 </style>
 </head>
--- a/layout/reftests/w3c-css/submitted/values3/calc-background-size-1.html
+++ b/layout/reftests/w3c-css/submitted/values3/calc-background-size-1.html
@@ -6,17 +6,17 @@
   <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
   <link rel="match" href="calc-background-size-1-ref.html">
   <meta name="flags" content="">
 <style type="text/css">
 
 p {
     height: 50px; width: 200px;
     border: thin solid;
-    background-image: url(../backgrounds/blue-32x32.png);
+    background-image: url(support/blue-32x32.png);
     background-repeat: no-repeat;
 }
 
 #one { background-size: calc(50px + 50%) calc(100% - 30px) }
 #two { background-size: calc(50px + 50%) calc(10px - 50%) }
 
 </style>
 </head>
copy from layout/reftests/backgrounds/blue-32x32.png
copy to layout/reftests/w3c-css/submitted/values3/support/blue-32x32.png
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -6682,17 +6682,17 @@ gCSSProperties["grid-template-columns"] 
   ],
   unbalanced_values: [
     "(foo] 40px",
   ]
 };
 if (isGridTemplateSubgridValueEnabled) {
   gCSSProperties["grid-template-columns"].other_values.push(
     // See https://bugzilla.mozilla.org/show_bug.cgi?id=981300
-    "[none auto subgrid min-content max-content foo] 40px",
+    "[none subgrid min-content max-content foo] 40px",
 
     "subgrid",
     "subgrid [] [foo bar]",
     "subgrid repeat(1, [])",
     "subgrid Repeat(4, [a] [b c] [] [d])",
     "subgrid repeat(auto-fill, [])",
     "subgrid [x] repeat( Auto-fill, [a b c]) []",
     "subgrid [x] repeat(auto-fill, []) [y z]"
--- a/layout/style/test/test_dont_use_document_colors.html
+++ b/layout/style/test/test_dont_use_document_colors.html
@@ -9,48 +9,61 @@
   <style type="text/css">
 
   #one, #three { background: blue; color: yellow; border: thin solid red; -moz-column-rule: 2px solid green; text-shadow: 2px 2px green; box-shadow: 3px 7px blue; }
   #two { background: transparent; border: thin solid; }
   #five, #six {border: thick solid red; border-inline-start-color:green; border-inline-end-color:blue}
   #seven {
     border: 3px solid;
   }
+  #eight {
+    border: 10px solid transparent;
+    border-image: repeating-linear-gradient(45deg, blue, blue 1%, red 1%, red 8%) 10;
+  }
+  #nine {
+    border: 10px solid blue;
+    border-image: none;
+  }
 
   /* XXX also test rgba() */
 
   </style>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=58048">Mozilla Bug 58048</a>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=255411">Mozilla Bug 255411</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430969">Mozilla Bug 1430969</a>
 <div id="display">
 
 <div id="one">Hello</div>
 <div id="two">Hello</div>
 <input id="three" type="button" value="Hello">
 <input id="four" type="button" value="Hello">
 <div id="five" dir="ltr">Hello</div>
 <div id="six" dir="rtl">Hello</div>
 <div id="seven">Hello</div>
+<div id="eight">I have a border-image</div>
+<div id="nine">I do not have a border-image</div>
 
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestFlakyTimeout('nsPresContext internally delays applying prefs using an nsITimer');
 
 var cs1 = getComputedStyle(document.getElementById("one"), "");
 var cs2 = getComputedStyle(document.getElementById("two"), "");
 var cs3 = getComputedStyle(document.getElementById("three"), "");
 var cs4 = getComputedStyle(document.getElementById("four"), "");
 var cs5 = getComputedStyle(document.getElementById("five"), "");
 var cs6 = getComputedStyle(document.getElementById("six"), "");
 var cs7 = getComputedStyle(document.getElementById("seven"), "");
+var cs8 = getComputedStyle(document.getElementById("eight"), "");
+var cs9 = getComputedStyle(document.getElementById("nine"), "");
 
 function pushPrefEnvAndWait(args, cb) {
   SpecialPowers.pushPrefEnv(args, _ => {
     // The nsPresContext delays applying a preference change until after a 0ms
     // nsITimer fires.  The SpecialPowers.pushPrefEnv() uses setTimeout(f, 0)
     // which may execute as a simple runnable dispatch and fire before the
     // 0ms nsITimer.  Therefore wait an additional 1ms to allow the nsPresContext
     // to apply the preferences.
@@ -61,17 +74,16 @@ function pushPrefEnvAndWait(args, cb) {
 pushPrefEnvAndWait({'set': [['browser.display.document_color_use', 1]]}, part1);
 
 var transparentBackgroundColor;
 var inputBackgroundColor, inputColor, inputBorderTopColor;
 var inputBorderRightColor, inputBorderLeftColor, inputBorderBottomColor;
 
 function part1()
 {
-
     isnot(cs1.backgroundColor, cs2.backgroundColor, "background-color applies");
     isnot(cs1.color, cs2.color, "color applies");
     isnot(cs1.borderTopColor, cs2.borderTopColor, "border-top-color applies");
     isnot(cs1.borderRightColor, cs2.borderRightColor,
           "border-right-color applies");
     isnot(cs1.borderLeftColor, cs2.borderLeftColor,
           "border-left-color applies");
     isnot(cs1.borderBottomColor, cs2.borderBottomColor,
@@ -109,16 +121,17 @@ function part1()
     isnot(cs3.color, cs4.color, "color applies");
     isnot(cs3.borderTopColor, cs4.borderTopColor, "border-top-color applies");
     isnot(cs3.borderRightColor, cs4.borderRightColor,
           "border-right-color applies");
     isnot(cs3.borderLeftColor, cs4.borderLeftColor,
           "border-left-color applies");
     isnot(cs3.borderBottomColor, cs4.borderBottomColor,
           "border-bottom-color applies");
+    isnot(cs8.borderImageSource, cs9.borderImageSource, "border-image-source applies");
     transparentBackgroundColor = cs2.backgroundColor;
     inputBackgroundColor = cs4.backgroundColor;
     inputColor = cs4.color;
     inputBorderTopColor = cs4.borderTopColor;
     inputBorderRightColor = cs4.borderRightColor;
     inputBorderLeftColor = cs4.borderLeftColor;
     inputBorderBottomColor = cs4.borderBottomColor;
     pushPrefEnvAndWait({'set': [['browser.display.document_color_use', 2]]}, part2);
@@ -163,16 +176,17 @@ function part2()
     is(cs4.color, inputColor, "color not broken on inputs");
     is(cs4.borderTopColor, inputBorderTopColor, "border-top-color not broken on inputs");
     is(cs4.borderRightColor, inputBorderRightColor,
        "border-right-color not broken on inputs");
     is(cs4.borderLeftColor, inputBorderLeftColor,
        "border-left-color not broken on inputs");
     is(cs4.borderBottomColor, inputBorderBottomColor,
        "border-bottom-color not broken on inputs");
+    is(cs8.borderImageSource, cs9.borderImageSource, "border-image-source is blocked");
 
     SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoJavaSampler.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoJavaSampler.java
@@ -135,17 +135,16 @@ public class GeckoJavaSampler {
     @WrapForJNI
     public synchronized static double getSampleTime(int aThreadId, int aSampleId) {
         Sample sample = getSample(aThreadId, aSampleId);
         if (sample != null) {
             if (sample.mJavaTime != 0) {
                 return (sample.mJavaTime -
                     SystemClock.elapsedRealtime()) + getProfilerTime();
             }
-            System.out.println("Sample: " + sample.mTime);
             return sample.mTime;
         }
         return 0;
     }
 
     @WrapForJNI
     public synchronized static String getFrameName(int aThreadId, int aSampleId, int aFrameId) {
         Sample sample = getSample(aThreadId, aSampleId);
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
@@ -856,33 +856,39 @@ public class GeckoPreferences
 
                     // Mma can only work if Health Report is enabled
                     boolean isHealthReportEnabled = isHealthReportEnabled(this);
                     if (!isHealthReportEnabled) {
                         ((SwitchPreference) pref).setChecked(isHealthReportEnabled);
                         pref.setEnabled(isHealthReportEnabled);
 
                         // Instruct the user on how to enable Health Report
-                        final String RIGHT_CHEVRON_SPACE_PADDED = " > ";
-                        StringBuilder healthReportSettingPath = new StringBuilder()
-                                .append(getString(R.string.pref_category_privacy_short))
-                                .append(RIGHT_CHEVRON_SPACE_PADDED)
-                                .append(getString(R.string.pref_category_datareporting))
-                                .append(RIGHT_CHEVRON_SPACE_PADDED)
-                                .append(getString(R.string.datareporting_fhr_title));
-                        SpannableString boldSettingsLocation = new SpannableString(healthReportSettingPath);
-                        boldSettingsLocation.setSpan(new StyleSpan(Typeface.BOLD),
-                                0, healthReportSettingPath.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+                        final String healthReportSettingPath =
+                                getString(R.string.pref_feature_tips_notification_enabling_path);
+                        final String enableHealthReportHint =
+                                getString(R.string.pref_feature_tips_notification_enabling_hint);
+
+                        final int healthReportPathFirstCharIndex =
+                                enableHealthReportHint.indexOf(healthReportSettingPath);
+                        if (healthReportPathFirstCharIndex < 0) {
+                            return;
+                        }
+                        final int healthReportPathLastCharIndex =
+                                healthReportPathFirstCharIndex + healthReportSettingPath.length();
+
+                        final SpannableString enableHealthReportBoldedHint =
+                                new SpannableString(enableHealthReportHint);
+                        enableHealthReportBoldedHint.setSpan(new StyleSpan(Typeface.BOLD),
+                                healthReportPathFirstCharIndex, healthReportPathLastCharIndex,
+                                Spannable.SPAN_INCLUSIVE_INCLUSIVE);
 
                         SpannableStringBuilder summaryTextBuilder = new SpannableStringBuilder()
                                 .append(getString(R.string.pref_feature_tips_notification_summary))
                                 .append("\n\n")
-                                .append(getString(R.string.pref_feature_tips_notification_enabling_hint))
-                                .append(" ")
-                                .append(boldSettingsLocation);
+                                .append(enableHealthReportBoldedHint);
 
                         pref.setSummary(summaryTextBuilder);
                     }
                 }
 
                 // Some Preference UI elements are not actually preferences,
                 // but they require a key to work correctly. For example,
                 // "Clear private data" requires a key for its state to be
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -285,20 +285,22 @@
 <!ENTITY pref_whats_new_notification_summary "Learn about new features after an update">
 
 <!-- Localization note (pref_feature_tips_notification): Title of a new toggleable setting in Settings-Notifications screen.
      Similar to the already existing "pref_whats_new_notification"-->
 <!ENTITY pref_feature_tips_notification "Product and feature tips">
 <!-- Localization note (pref_feature_tips_notification_summary): Description of a new toggleable setting in Settings-Notifications screen.
      Similar to the already existing "pref_whats_new_notification_summary"-->
 <!ENTITY pref_feature_tips_notification_summary "Learn more about using &brandShortName; and other &vendorShortName; products">
+<!-- Localization note (pref_feature_tips_notification_enabling_path):
+     Nothing to translate. Simple concatenation of already localized strings. Result is used below. -->
+<!ENTITY pref_feature_tips_notification_enabling_path "&pref_category_privacy_short; > &pref_category_datareporting; > &datareporting_fhr_title;">
 <!-- Localization note (pref_feature_tips_notification_enabling_hint):
-     Describe the action the user should do to enable this preference
-     Will be used in the context "<Turn on> ... to enable this feature" -->
-<!ENTITY pref_feature_tips_notification_enabling_hint "Turn on">
+     Describe the action the user should do to enable this preference. -->
+<!ENTITY pref_feature_tips_notification_enabling_hint2 "Turn on &pref_feature_tips_notification_enabling_path;">
 
 <!-- Localization note (pref_category_experimental): Title of a sub category in the 'advanced' category
      for experimental features. -->
 <!ENTITY pref_category_experimental "Experimental features">
 
 <!-- Custom Tabs is an Android API for allowing third-party apps to open URLs in a customized UI.
      Instead of switching to the browser it appears as if the user stays in the third-party app.
      For more see: https://developer.chrome.com/multidevice/android/customtabs -->
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -219,17 +219,18 @@
   <string name="pref_tracking_protection_enabled_pb">&pref_tracking_protection_enabled_pb;</string>
   <string name="pref_tracking_protection_disabled">&pref_tracking_protection_disabled;</string>
 
   <string name="pref_whats_new_notification">&pref_whats_new_notification;</string>
   <string name="pref_whats_new_notification_summary">&pref_whats_new_notification_summary;</string>
 
   <string name="pref_feature_tips_notification">&pref_feature_tips_notification;</string>
   <string name="pref_feature_tips_notification_summary">&pref_feature_tips_notification_summary;</string>
-  <string name="pref_feature_tips_notification_enabling_hint">&pref_feature_tips_notification_enabling_hint;</string>
+  <string name="pref_feature_tips_notification_enabling_path">&pref_feature_tips_notification_enabling_path;</string>
+  <string name="pref_feature_tips_notification_enabling_hint">&pref_feature_tips_notification_enabling_hint2;</string>
 
   <string name="pref_category_experimental">&pref_category_experimental;</string>
 
   <string name="pref_custom_tabs">&pref_custom_tabs2;</string>
   <string name="pref_custom_tabs_summary">&pref_custom_tabs_summary4;</string>
 
   <string name="custom_tabs_menu_item_open_in">&custom_tabs_menu_item_open_in;</string>
   <string name="custom_tabs_menu_footer">&custom_tabs_menu_footer;</string>
--- a/mobile/android/chrome/content/blockedSite.xhtml
+++ b/mobile/android/chrome/content/blockedSite.xhtml
@@ -10,17 +10,17 @@
   <!ENTITY % blockedSiteDTD SYSTEM "chrome://browser/locale/phishing.dtd">
   %blockedSiteDTD;
 ]>
 
 <!-- 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/. -->
 
-<html xmlns="http://www.w3.org/1999/xhtml" class="blacklist">
+<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta name="viewport" content="width=device-width; user-scalable=false" />
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
     <link rel="icon" type="image/png" id="favicon" sizes="64x64" href="chrome://browser/skin/images/blocked-warning.png"/>
 
     <script type="application/javascript"><![CDATA[
       // Error url MUST be formatted like this:
       //   about:blocked?e=error_code&u=url(&o=1)?
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/FennecNativeDriver.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/FennecNativeDriver.java
@@ -21,16 +21,17 @@ import java.lang.StringBuffer;
 import java.lang.Math;
 
 import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.gfx.CompositorController;
 import org.mozilla.gecko.gfx.PanningPerfAPI;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.util.StrictModeContext;
 import org.mozilla.geckoview.GeckoView;
 
 import android.app.Activity;
 import android.util.Log;
 import android.view.View;
 
 import com.robotium.solo.Solo;
 
@@ -442,38 +443,41 @@ public class FennecNativeDriver implemen
     public static void log(LogLevel level, String message) {
         log(level, message, null);
     }
 
     public static void log(LogLevel level, Throwable t) {
         log(level, null, t);
     }
 
+    @SuppressWarnings("try")
     public static void log(LogLevel level, String message, Throwable t) {
         if (mLogFile == null) {
             throw new RuntimeException(
                     "No log file specified!\n" +
                     "(If you are running this test from an IDE don't forget to before run \"robocop --serve\")");
         }
 
         if (level.isEnabled(mLogLevel)) {
             PrintWriter pw = null;
-            try {
-                pw = new PrintWriter(new FileWriter(mLogFile, true));
-                if (message != null) {
-                    pw.println(message);
-                }
-                if (t != null) {
-                    t.printStackTrace(pw);
-                }
-            } catch (IOException ioe) {
-                Log.e("Robocop", "exception with file writer on: " + mLogFile);
-            } finally {
-                if (pw != null) {
-                    pw.close();
+            try (StrictModeContext unused = StrictModeContext.allowDiskWrites()) {
+                try {
+                    pw = new PrintWriter(new FileWriter(mLogFile, true));
+                    if (message != null) {
+                        pw.println(message);
+                    }
+                    if (t != null) {
+                        t.printStackTrace(pw);
+                    }
+                } catch (IOException ioe) {
+                    Log.e("Robocop", "exception with file writer on: " + mLogFile);
+                } finally {
+                    if (pw != null) {
+                        pw.close();
+                    }
                 }
             }
 
             // PrintWriter doesn't throw IOE but sets an error flag instead,
             // so check for that
             if (pw != null && pw.checkError()) {
                 Log.e("Robocop", "exception with file writer on: " + mLogFile);
             }
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5428,16 +5428,20 @@ pref("memory_info_dumper.watch_fifo.enab
 // If minInterval is 0, the check will only happen
 // when the service has a strong suspicion we are in a captive portal
 pref("network.captive-portal-service.minInterval", 60000); // 60 seconds
 pref("network.captive-portal-service.maxInterval", 1500000); // 25 minutes
 // Every 10 checks, the delay is increased by a factor of 5
 pref("network.captive-portal-service.backoffFactor", "5.0");
 pref("network.captive-portal-service.enabled", false);
 
+pref("network.connectivity-service.enabled", true);
+pref("network.connectivity-service.DNSv4.domain", "mozilla.org");
+pref("network.connectivity-service.DNSv6.domain", "mozilla.org");
+
 // DNS Trusted Recursive Resolver
 // 0 - default off, 1 - race, 2 TRR first, 3 TRR only, 4 shadow, 5 off by choice
 pref("network.trr.mode", 0);
 // DNS-over-HTTP service to use, must be HTTPS://
 pref("network.trr.uri", "https://mozilla.cloudflare-dns.com/dns-query");
 // credentials to pass to DOH end-point
 pref("network.trr.credentials", "");
 // Wait for captive portal confirmation before enabling TRR
new file mode 100644
--- /dev/null
+++ b/netwerk/base/NetworkConnectivityService.cpp
@@ -0,0 +1,179 @@
+/* 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 "NetworkConnectivityService.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
+#include "xpcpublic.h"
+#include "nsSocketTransport2.h"
+
+namespace mozilla {
+namespace net {
+
+NS_IMPL_ISUPPORTS(NetworkConnectivityService, nsINetworkConnectivityService, nsIObserver, nsIDNSListener)
+
+static StaticRefPtr<NetworkConnectivityService> gConnService;
+
+// static
+already_AddRefed<NetworkConnectivityService>
+NetworkConnectivityService::GetSingleton()
+{
+  if (gConnService) {
+    return do_AddRef(gConnService);
+  }
+
+  RefPtr<NetworkConnectivityService> service = new NetworkConnectivityService();
+  service->Init();
+
+  gConnService = service.forget();
+  ClearOnShutdown(&gConnService);
+  return do_AddRef(gConnService);
+}
+
+nsresult
+NetworkConnectivityService::Init()
+{
+  nsCOMPtr<nsIObserverService> observerService =
+    mozilla::services::GetObserverService();
+  observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
+  observerService->AddObserver(this, "network:captive-portal-connectivity", false);
+
+  // We need to schedule this for a bit later, to avoid a recursive service
+  // initialization.
+  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
+    NewRunnableMethod("NetworkConnectivityService::PerformChecks",
+                      this,
+                      &NetworkConnectivityService::PerformChecks)));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+NetworkConnectivityService::GetDNSv4(int32_t *aState)
+{
+  NS_ENSURE_ARG(aState);
+  *aState = mDNSv4;
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP
+NetworkConnectivityService::GetDNSv6(int32_t *aState)
+{
+  NS_ENSURE_ARG(aState);
+  *aState = mDNSv6;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+NetworkConnectivityService::GetIPv4(int32_t *aState)
+{
+  NS_ENSURE_ARG(aState);
+  *aState = nsSocketTransport::HasIPv4Connectivity()
+              ? nsINetworkConnectivityService::OK
+              : nsINetworkConnectivityService::NOT_AVAILABLE;
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP
+NetworkConnectivityService::GetIPv6(int32_t *aState)
+{
+  NS_ENSURE_ARG(aState);
+  *aState = nsSocketTransport::HasIPv6Connectivity()
+              ? nsINetworkConnectivityService::OK
+              : nsINetworkConnectivityService::NOT_AVAILABLE;
+  return NS_OK;
+}
+
+void
+NetworkConnectivityService::PerformChecks()
+{
+  RecheckDNS();
+}
+
+NS_IMETHODIMP
+NetworkConnectivityService::OnLookupComplete(nsICancelable *aRequest,
+                                             nsIDNSRecord *aRecord,
+                                             nsresult aStatus)
+{
+  int32_t state = aRecord ? nsINetworkConnectivityService::OK
+                          : nsINetworkConnectivityService::NOT_AVAILABLE;
+
+  if (aRequest == mDNSv4Request) {
+    mDNSv4 = state;
+    mDNSv4Request = nullptr;
+  } else if (aRequest == mDNSv6Request) {
+    mDNSv6 = state;
+    mDNSv6Request = nullptr;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+NetworkConnectivityService::OnLookupByTypeComplete(nsICancelable *aRequest,
+                                                   nsIDNSByTypeRecord *aRes,
+                                                   nsresult aStatus)
+{
+    return NS_OK;
+}
+
+
+NS_IMETHODIMP
+NetworkConnectivityService::RecheckDNS()
+{
+  bool enabled = Preferences::GetBool("network.connectivity-service.enabled", false);
+  if (!enabled) {
+    return NS_OK;
+  }
+
+  nsresult rv;
+  nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
+  OriginAttributes attrs;
+  nsAutoCString host;
+  Preferences::GetCString("network.connectivity-service.DNSv4.domain", host);
+
+  rv = dns->AsyncResolveNative(host, nsIDNSService::RESOLVE_DISABLE_IPV6,
+                               this, NS_GetCurrentThread(),
+                               attrs, getter_AddRefs(mDNSv4Request));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Preferences::GetCString("network.connectivity-service.DNSv6.domain", host);
+  rv = dns->AsyncResolveNative(host, nsIDNSService::RESOLVE_DISABLE_IPV4,
+                               this, NS_GetCurrentThread(),
+                               attrs, getter_AddRefs(mDNSv6Request));
+  return rv;
+}
+
+NS_IMETHODIMP
+NetworkConnectivityService::Observe(nsISupports *aSubject,
+                                    const char * aTopic,
+                                    const char16_t * aData)
+{
+  if (!strcmp(aTopic, "network:captive-portal-connectivity")) {
+    // Captive portal is cleared, so we redo the checks.
+    mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
+    mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
+
+    PerformChecks();
+  } else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
+    if (mDNSv4Request) {
+      mDNSv4Request->Cancel(NS_ERROR_ABORT);
+      mDNSv4Request = nullptr;
+    }
+    if (mDNSv6Request) {
+      mDNSv6Request->Cancel(NS_ERROR_ABORT);
+      mDNSv6Request = nullptr;
+    }
+
+    nsCOMPtr<nsIObserverService> observerService =
+      mozilla::services::GetObserverService();
+    observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
+    observerService->RemoveObserver(this, "network:captive-portal-connectivity");
+  }
+
+  return NS_OK;
+}
+
+} // namespace net
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/base/NetworkConnectivityService.h
@@ -0,0 +1,47 @@
+/* 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/. */
+
+#ifndef NetworkConnectivityService_h_
+#define NetworkConnectivityService_h_
+
+#include "nsINetworkConnectivityService.h"
+
+namespace mozilla {
+namespace net {
+
+class NetworkConnectivityService
+  : public nsINetworkConnectivityService
+  , public nsIObserver
+  , public nsIDNSListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSINETWORKCONNECTIVITYSERVICE
+  NS_DECL_NSIOBSERVER
+  NS_DECL_NSIDNSLISTENER
+
+  nsresult Init();
+  static already_AddRefed<NetworkConnectivityService> GetSingleton();
+
+private:
+  NetworkConnectivityService() = default;
+  virtual ~NetworkConnectivityService() = default;
+
+  // Calls all the check methods
+  void PerformChecks();
+
+  // Will be set to OK if the DNS request returned in IP of this type,
+  //                NOT_AVAILABLE if that type of resolution is not available
+  //                UNKNOWN if the check wasn't performed
+  int32_t mDNSv4 = nsINetworkConnectivityService::UNKNOWN;
+  int32_t mDNSv6 = nsINetworkConnectivityService::UNKNOWN;
+
+  nsCOMPtr<nsICancelable> mDNSv4Request;
+  nsCOMPtr<nsICancelable> mDNSv6Request;
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif // NetworkConnectivityService_h_
--- a/netwerk/base/RedirectChannelRegistrar.cpp
+++ b/netwerk/base/RedirectChannelRegistrar.cpp
@@ -1,21 +1,20 @@
 /* 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 "RedirectChannelRegistrar.h"
 #include "mozilla/StaticPtr.h"
+#include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace net {
 
-namespace {
-StaticRefPtr<RedirectChannelRegistrar> gSingleton;
-}
+StaticRefPtr<RedirectChannelRegistrar> RedirectChannelRegistrar::gSingleton;
 
 NS_IMPL_ISUPPORTS(RedirectChannelRegistrar, nsIRedirectChannelRegistrar)
 
 RedirectChannelRegistrar::RedirectChannelRegistrar()
   : mRealChannels(32)
   , mParentChannels(32)
   , mId(1)
   , mLock("RedirectChannelRegistrar")
--- a/netwerk/base/RedirectChannelRegistrar.h
+++ b/netwerk/base/RedirectChannelRegistrar.h
@@ -38,14 +38,16 @@ protected:
           ChannelHashtable;
   typedef nsInterfaceHashtable<nsUint32HashKey, nsIParentChannel>
           ParentChannelHashtable;
 
   ChannelHashtable mRealChannels;
   ParentChannelHashtable mParentChannels;
   uint32_t mId;
   Mutex mLock;
+
+  static StaticRefPtr<RedirectChannelRegistrar> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -58,16 +58,17 @@ XPIDL_SOURCES += [
     'nsILoadGroup.idl',
     'nsILoadGroupChild.idl',
     'nsILoadInfo.idl',
     'nsIMIMEInputStream.idl',
     'nsIMultiPartChannel.idl',
     'nsINestedURI.idl',
     'nsINetAddr.idl',
     'nsINetUtil.idl',
+    'nsINetworkConnectivityService.idl',
     'nsINetworkInfoService.idl',
     'nsINetworkInterceptController.idl',
     'nsINetworkLinkService.idl',
     'nsINetworkPredictor.idl',
     'nsINetworkPredictorVerifier.idl',
     'nsINetworkProperties.idl',
     'nsINullChannel.idl',
     'nsIParentChannel.idl',
@@ -168,16 +169,17 @@ EXPORTS.mozilla += [
 EXPORTS.mozilla.net += [
     'CaptivePortalService.h',
     'ChannelDiverterChild.h',
     'ChannelDiverterParent.h',
     'Dashboard.h',
     'DashboardTypes.h',
     'IOActivityMonitor.h',
     'MemoryDownloader.h',
+    'NetworkConnectivityService.h',
     'PartiallySeekableInputStream.h',
     'Predictor.h',
     'RedirectChannelRegistrar.h',
     'ReferrerPolicy.h',
     'RequestContextService.h',
     'SimpleChannelParent.h',
     'TCPFastOpen.h',
 ]
@@ -189,16 +191,17 @@ UNIFIED_SOURCES += [
     'ChannelDiverterChild.cpp',
     'ChannelDiverterParent.cpp',
     'Dashboard.cpp',
     'EventTokenBucket.cpp',
     'IOActivityMonitor.cpp',
     'LoadContextInfo.cpp',
     'LoadInfo.cpp',
     'MemoryDownloader.cpp',
+    'NetworkConnectivityService.cpp',
     'nsAsyncRedirectVerifyHelper.cpp',
     'nsAsyncStreamCopier.cpp',
     'nsAuthInformationHolder.cpp',
     'nsBase64Encoder.cpp',
     'nsBaseChannel.cpp',
     'nsBaseContentStream.cpp',
     'nsBufferedStreams.cpp',
     'nsChannelClassifier.cpp',
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -918,27 +918,27 @@ nsChannelClassifier::SetBlockedContent(n
   auto* pwin = nsPIDOMWindowOuter::From(win);
   nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
   if (!docShell) {
     return NS_OK;
   }
   nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
   NS_ENSURE_TRUE(doc, NS_OK);
 
+  nsCOMPtr<nsIURI> uri;
+  channel->GetURI(getter_AddRefs(uri));
   unsigned state;
   if (aErrorCode == NS_ERROR_TRACKING_URI) {
     state = nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
   } else {
     state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
   }
-  pwin->NotifyContentBlockingState(state, channel);
+  pwin->NotifyContentBlockingState(state, channel, true, uri);
 
   // Log a warning to the web console.
-  nsCOMPtr<nsIURI> uri;
-  channel->GetURI(getter_AddRefs(uri));
   NS_ConvertUTF8toUTF16 spec(uri->GetSpecOrDefault());
   const char16_t* params[] = { spec.get() };
   const char* message = (aErrorCode == NS_ERROR_TRACKING_URI) ?
     "TrackerUriBlocked" : "UnsafeUriBlocked";
   nsCString category = (aErrorCode == NS_ERROR_TRACKING_URI) ?
     NS_LITERAL_CSTRING("Tracking Protection") :
     NS_LITERAL_CSTRING("Safe Browsing");
 
--- a/netwerk/base/nsIAuthModule.idl
+++ b/netwerk/base/nsIAuthModule.idl
@@ -128,18 +128,19 @@ interface nsIAuthModule : nsISupports
      *
      * Unwrap() may return NS_ERROR_NOT_IMPLEMENTED, if the underlying  
      * authentication mechanism does not support security layers.
      */
     void unwrap([const] in voidPtr aInToken,
                 in unsigned long   aInTokenLength,
                 out voidPtr        aOutToken,
                 out unsigned long  aOutTokenLength);
-};
 
 %{C++
-/**
- * nsIAuthModule implementations are registered under the following contract
- * ID prefix:
- */
-#define NS_AUTH_MODULE_CONTRACTID_PREFIX \
-    "@mozilla.org/network/auth-module;1?name="
+    /**
+     * Create a new instance of an auth module.
+     *
+     * @param aType
+     *        The type of the auth module to be constructed.
+     */
+    static already_AddRefed<nsIAuthModule> CreateInstance(const char* aType);
 %}
+};
new file mode 100644
--- /dev/null
+++ b/netwerk/base/nsINetworkConnectivityService.idl
@@ -0,0 +1,31 @@
+/* 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"
+
+[scriptable, builtinclass, uuid(2693457e-3ba5-4455-991f-5350946adb12)]
+interface nsINetworkConnectivityService : nsISupports
+{
+  /**
+   * Each tested feature may be in one of 3 states:
+   *   UNKNOWN, if a check hasn't been performed.
+   *   OK, if the feature was successfully tested
+   *   NOT_AVAILABLE, if the feature is blocked by the network.
+   *                  Note that the endpoints are guaranteed to support the features.
+   */
+  const long UNKNOWN             = 0;
+  const long OK                  = 1;
+  const long NOT_AVAILABLE       = 2;
+
+  /* If DNS v4/v6 queries actually work on the current network */
+  readonly attribute long DNSv4;
+  readonly attribute long DNSv6;
+
+  /* If connecting to IPv4/v6 works on the current network */
+  readonly attribute long IPv4;
+  readonly attribute long IPv6;
+
+  /* Starts the DNS request to check for DNS v4/v6 availability */
+  void recheckDNS();
+};
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -48,16 +48,17 @@
 #include "mozilla/net/DNS.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/dom/ClientInfo.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/net/CaptivePortalService.h"
+#include "mozilla/net/NetworkConnectivityService.h"
 #include "mozilla/Unused.h"
 #include "ReferrerPolicy.h"
 #include "nsContentSecurityManager.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace net {
 
@@ -257,16 +258,20 @@ nsIOService::Init()
 
     gIOService = this;
 
     InitializeNetworkLinkService();
     InitializeProtocolProxyService();
 
     SetOffline(false);
 
+    RefPtr<NetworkConnectivityService> ncs =
+      NetworkConnectivityService::GetSingleton();
+    ncs->Init();
+
     return NS_OK;
 }
 
 
 nsIOService::~nsIOService()
 {
     if (gIOService) {
         MOZ_ASSERT(gIOService == this);
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -750,16 +750,25 @@ nsSocketOutputStream::AsyncWait(nsIOutpu
     mTransport->OnOutputPending();
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // socket transport impl
 //-----------------------------------------------------------------------------
 
+// We assume we have connectivity at first.
+bool nsSocketTransport::sHasIPv4Connectivity = true;
+bool nsSocketTransport::sHasIPv6Connectivity = true;
+
+uint32_t nsSocketTransport::sIPv4FailedCounter = 0;
+uint32_t nsSocketTransport::sIPv6FailedCounter = 0;
+
+const uint32_t kFailureThreshold = 50;
+
 nsSocketTransport::nsSocketTransport()
     : mTypes(nullptr)
     , mTypeCount(0)
     , mPort(0)
     , mProxyPort(0)
     , mOriginPort(0)
     , mProxyTransparent(false)
     , mProxyTransparentResolvesHost(false)
@@ -1852,24 +1861,35 @@ nsSocketTransport::RecoverFromError()
         mFastOpenCallback = nullptr;
 
     } else {
 
         // This is only needed for telemetry.
         if (NS_SUCCEEDED(mFirstRetryError)) {
             mFirstRetryError = mCondition;
         }
-        if ((mState == STATE_CONNECTING) && mDNSRecord &&
-            mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
+        if ((mState == STATE_CONNECTING) && mDNSRecord) {
             if (mNetAddr.raw.family == AF_INET) {
-                Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
-                                      UNSUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
+                sIPv4FailedCounter++;
+                if (sIPv4FailedCounter > kFailureThreshold) {
+                    sHasIPv4Connectivity = false;
+                }
+                if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
+                    Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
+                                          UNSUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
+                }
             } else if (mNetAddr.raw.family == AF_INET6) {
-                Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
-                                      UNSUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
+                sIPv6FailedCounter++;
+                if (sIPv6FailedCounter > kFailureThreshold) {
+                    sHasIPv6Connectivity = false;
+                }
+                if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
+                    Telemetry::Accumulate(Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
+                                          UNSUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
+                }
             }
         }
 
         if (mConnectionFlags & RETRY_WITH_DIFFERENT_IP_FAMILY &&
             mCondition == NS_ERROR_UNKNOWN_HOST &&
             mState == STATE_RESOLVING &&
             !mProxyTransparentResolvesHost) {
             SOCKET_LOG(("  trying lookup again with opposite ip family\n"));
@@ -2341,22 +2361,28 @@ nsSocketTransport::OnSocketReady(PRFileD
         }
 
         if (status == PR_SUCCESS) {
             //
             // we are connected!
             //
             OnSocketConnected();
 
-            if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
-                if (mNetAddr.raw.family == AF_INET) {
+            if (mNetAddr.raw.family == AF_INET) {
+                sIPv4FailedCounter = 0;
+                sHasIPv4Connectivity = true;
+                if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
                     Telemetry::Accumulate(
                         Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
                         SUCCESSFUL_CONNECTING_TO_IPV4_ADDRESS);
-                } else if (mNetAddr.raw.family == AF_INET6) {
+                }
+            } else if (mNetAddr.raw.family == AF_INET6) {
+                sIPv6FailedCounter = 0;
+                sHasIPv6Connectivity = true;
+                if (mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase()) {
                     Telemetry::Accumulate(
                         Telemetry::IPV4_AND_IPV6_ADDRESS_CONNECTIVITY,
                         SUCCESSFUL_CONNECTING_TO_IPV6_ADDRESS);
                 }
             }
         }
         else {
             PRErrorCode code = PR_GetError();
--- a/netwerk/base/nsSocketTransport2.h
+++ b/netwerk/base/nsSocketTransport2.h
@@ -172,16 +172,20 @@ public:
     uint64_t ByteCountSent() override { return mOutput.ByteCount(); }
     static void CloseSocket(PRFileDesc *aFd, bool aTelemetryEnabled);
     static void SendPRBlockingTelemetry(PRIntervalTime aStart,
         Telemetry::HistogramID aIDNormal,
         Telemetry::HistogramID aIDShutdown,
         Telemetry::HistogramID aIDConnectivityChange,
         Telemetry::HistogramID aIDLinkChange,
         Telemetry::HistogramID aIDOffline);
+
+
+    static bool HasIPv4Connectivity() { return sHasIPv4Connectivity; }
+    static bool HasIPv6Connectivity() { return sHasIPv6Connectivity; }
 protected:
 
     virtual ~nsSocketTransport();
     void     CleanupTypes();
 
 private:
 
     // event types
@@ -482,14 +486,19 @@ private:
 
     // A Fast Open callback.
     TCPFastOpen *mFastOpenCallback;
     bool mFastOpenLayerHasBufferedData;
     uint8_t mFastOpenStatus;
     nsresult mFirstRetryError;
 
     bool mDoNotRetryToConnect;
+
+    static bool sHasIPv4Connectivity;
+    static bool sHasIPv6Connectivity;
+    static uint32_t sIPv4FailedCounter;
+    static uint32_t sIPv6FailedCounter;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // !nsSocketTransport_h__
--- a/netwerk/build/moz.build
+++ b/netwerk/build/moz.build
@@ -12,16 +12,17 @@ SOURCES += [
     'nsNetModule.cpp',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
+    '/extensions/auth',
     '/netwerk/base',
     '/netwerk/cache',
     '/netwerk/dns',
     '/netwerk/mime',
     '/netwerk/protocol/about',
     '/netwerk/protocol/data',
     '/netwerk/protocol/file',
     '/netwerk/protocol/ftp',
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -447,16 +447,26 @@
 #define NS_CAPTIVEPORTAL_CID \
 { /* bdbe0555-fc3d-4f7b-9205-c309ceb2d641 */ \
     0xbdbe0555, \
     0xfc3d, \
     0x4f7b, \
   { 0x92, 0x05, 0xc3, 0x09, 0xce, 0xb2, 0xd6, 0x41 } \
 }
 
+#define NS_NETWORKCONNECTIVITYSERVICE_CONTRACTID \
+    "@mozilla.org/network/network-connectivity-service;1"
+#define NS_NETWORKCONNECTIVITYSERVICE_CID \
+{ /* 2693457e-3ba5-4455-991f-5350946adb12 */ \
+    0x2693457e, \
+    0x3ba5, \
+    0x4455, \
+  { 0x99, 0x1f, 0x53, 0x50, 0x94, 0x6a, 0xdb, 0x12 } \
+}
+
 /******************************************************************************
  * netwerk/cache/ classes
  */
 
 // service implementing nsICacheService.
 #define NS_CACHESERVICE_CONTRACTID \
     "@mozilla.org/network/cache-service;1"
 #define NS_CACHESERVICE_CID                          \
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -34,16 +34,17 @@
 #include "nsXULAppAPI.h"
 #include "nsCategoryCache.h"
 #include "nsIContentSniffer.h"
 #include "Predictor.h"
 #include "nsIThreadPool.h"
 #include "mozilla/net/BackgroundChannelRegistrar.h"
 #include "mozilla/net/NeckoChild.h"
 #include "RedirectChannelRegistrar.h"
+#include "nsAuthGSSAPI.h"
 
 #include "nsNetCID.h"
 
 #if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_LINUX)
 #define BUILD_NETWORK_INFO_SERVICE 1
 #endif
 
 typedef nsCategoryCache<nsIContentSniffer> ContentSnifferCache;
@@ -136,16 +137,24 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(LoadConte
 #include "mozilla/net/CaptivePortalService.h"
 namespace mozilla {
 namespace net {
   NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsICaptivePortalService,
     CaptivePortalService::GetSingleton)
 } // namespace net
 } // namespace mozilla
 
+#include "mozilla/net/NetworkConnectivityService.h"
+namespace mozilla {
+namespace net {
+  NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsINetworkConnectivityService,
+    NetworkConnectivityService::GetSingleton)
+} // namespace net
+} // namespace mozilla
+
 ///////////////////////////////////////////////////////////////////////////////
 
 extern nsresult
 net_NewIncrementalDownload(nsISupports *, const nsIID &, void **);
 
 #define NS_INCREMENTALDOWNLOAD_CID \
 { /* a62af1ba-79b3-4896-8aaf-b148bfce4280 */         \
     0xa62af1ba,                                      \
@@ -220,32 +229,26 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFi
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFtpProtocolHandler, Init)
 
 // http/https
 #include "nsHttpHandler.h"
 #include "Http2Compression.h"
 #undef LOG
 #undef LOG_ENABLED
 #include "nsHttpAuthManager.h"
-#include "nsHttpBasicAuth.h"
-#include "nsHttpDigestAuth.h"
-#include "nsHttpNTLMAuth.h"
 #include "nsHttpActivityDistributor.h"
 #include "ThrottleQueue.h"
 #undef LOG
 #undef LOG_ENABLED
 namespace mozilla {
 namespace net {
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNTLMAuth)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsHttpHandler, nsHttpHandler::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpsHandler, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHttpAuthManager, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpActivityDistributor)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
 NS_GENERIC_FACTORY_CONSTRUCTOR(ThrottleQueue)
 } // namespace net
 } // namespace mozilla
 
 #include "mozilla/net/Dashboard.h"
 namespace mozilla {
 namespace net {
   NS_GENERIC_FACTORY_CONSTRUCTOR(Dashboard)
@@ -613,16 +616,18 @@ static void nsNetShutdown()
     mozilla::net::WebSocketChannel::Shutdown();
 
     mozilla::net::Http2CompressionCleanup();
 
     mozilla::net::RedirectChannelRegistrar::Shutdown();
 
     mozilla::net::BackgroundChannelRegistrar::Shutdown();
 
+    nsAuthGSSAPI::Shutdown();
+
     delete gNetSniffers;
     gNetSniffers = nullptr;
     delete gDataSniffers;
     gDataSniffers = nullptr;
 }
 
 NS_DEFINE_NAMED_CID(NS_IOSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_STREAMTRANSPORTSERVICE_CID);
@@ -671,19 +676,16 @@ NS_DEFINE_NAMED_CID(NS_MULTIMIXEDCONVERT
 NS_DEFINE_NAMED_CID(NS_UNKNOWNDECODER_CID);
 NS_DEFINE_NAMED_CID(NS_BINARYDETECTOR_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPCOMPRESSCONVERTER_CID);
 NS_DEFINE_NAMED_CID(MOZITXTTOHTMLCONV_CID);
 NS_DEFINE_NAMED_CID(NS_MIMEHEADERPARAM_CID);
 NS_DEFINE_NAMED_CID(NS_FILEPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPSPROTOCOLHANDLER_CID);
-NS_DEFINE_NAMED_CID(NS_HTTPBASICAUTH_CID);
-NS_DEFINE_NAMED_CID(NS_HTTPDIGESTAUTH_CID);
-NS_DEFINE_NAMED_CID(NS_HTTPNTLMAUTH_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPAUTHMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_HTTPACTIVITYDISTRIBUTOR_CID);
 NS_DEFINE_NAMED_CID(NS_THROTTLEQUEUE_CID);
 NS_DEFINE_NAMED_CID(NS_FTPPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_RESPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_EXTENSIONPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_SUBSTITUTINGURL_CID);
 NS_DEFINE_NAMED_CID(NS_SUBSTITUTINGURLMUTATOR_CID);
@@ -717,16 +719,17 @@ NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERV
 #elif defined(XP_LINUX)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
 NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NSILOADCONTEXTINFOFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
 NS_DEFINE_NAMED_CID(NS_CAPTIVEPORTAL_CID);
+NS_DEFINE_NAMED_CID(NS_NETWORKCONNECTIVITYSERVICE_CID);
 #ifdef BUILD_NETWORK_INFO_SERVICE
 NS_DEFINE_NAMED_CID(NETWORKINFOSERVICE_CID);
 #endif // BUILD_NETWORK_INFO_SERVICE
 
 static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
     // clang-format off
     { &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
     { &kNS_STREAMTRANSPORTSERVICE_CID, false, nullptr, nsStreamTransportServiceConstructor },
@@ -777,19 +780,16 @@ static const mozilla::Module::CIDEntry k
     { &kNS_UNKNOWNDECODER_CID, false, nullptr, CreateNewUnknownDecoderFactory },
     { &kNS_BINARYDETECTOR_CID, false, nullptr, CreateNewBinaryDetectorFactory },
     { &kNS_HTTPCOMPRESSCONVERTER_CID, false, nullptr, CreateNewHTTPCompressConvFactory },
     { &kMOZITXTTOHTMLCONV_CID, false, nullptr, CreateNewTXTToHTMLConvFactory },
     { &kNS_MIMEHEADERPARAM_CID, false, nullptr, nsMIMEHeaderParamImplConstructor },
     { &kNS_FILEPROTOCOLHANDLER_CID, false, nullptr, nsFileProtocolHandlerConstructor },
     { &kNS_HTTPPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::nsHttpHandlerConstructor },
     { &kNS_HTTPSPROTOCOLHANDLER_CID, false, nullptr, mozilla::net::nsHttpsHandlerConstructor },
-    { &kNS_HTTPBASICAUTH_CID, false, nullptr, mozilla::net::nsHttpBasicAuthConstructor },
-    { &kNS_HTTPDIGESTAUTH_CID, false, nullptr, mozilla::net::nsHttpDigestAuthConstructor },
-    { &kNS_HTTPNTLMAUTH_CID, false, nullptr, mozilla::net::nsHttpNTLMAuthConstructor },
     { &kNS_HTTPAUTHMANAGER_CID, false, nullptr, mozilla::net::nsHttpAuthManagerConstructor },
     { &kNS_HTTPACTIVITYDISTRIBUTOR_CID, false, nullptr, mozilla::net::nsHttpActivityDistributorConstructor },
     { &kNS_THROTTLEQUEUE_CID, false, nullptr, mozilla::net::ThrottleQueueConstructor },
     { &kNS_FTPPROTOCOLHANDLER_CID, false, nullptr, nsFtpProtocolHandlerConstructor },
     { &kNS_RESPROTOCOLHANDLER_CID, false, nullptr, nsResProtocolHandlerConstructor },
     { &kNS_EXTENSIONPROTOCOLHANDLER_CID, false, nullptr, mozilla::ExtensionProtocolHandlerConstructor },
     { &kNS_SUBSTITUTINGURL_CID, false, nullptr, mozilla::SubstitutingURLMutatorConstructor }, // do_CreateInstance returns mutator
     { &kNS_SUBSTITUTINGURLMUTATOR_CID, false, nullptr, mozilla::SubstitutingURLMutatorConstructor },
@@ -825,16 +825,17 @@ static const mozilla::Module::CIDEntry k
 #elif defined(XP_LINUX)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNotifyAddrListenerConstructor },
 #endif
     { &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
     { &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
     { &kNS_NSILOADCONTEXTINFOFACTORY_CID, false, nullptr, LoadContextInfoFactoryConstructor },
     { &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
     { &kNS_CAPTIVEPORTAL_CID, false, nullptr, mozilla::net::nsICaptivePortalServiceConstructor },
+    { &kNS_NETWORKCONNECTIVITYSERVICE_CID, false, nullptr, mozilla::net::nsINetworkConnectivityServiceConstructor },
 #ifdef BUILD_NETWORK_INFO_SERVICE
     { &kNETWORKINFOSERVICE_CID, false, nullptr, nsNetworkInfoServiceConstructor },
 #endif
     { nullptr }
     // clang-format on
 };
 
 static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
@@ -890,19 +891,16 @@ static const mozilla::Module::ContractID
     { NS_ISTREAMCONVERTER_KEY COMPRESS_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
     { NS_ISTREAMCONVERTER_KEY XCOMPRESS_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
     { NS_ISTREAMCONVERTER_KEY DEFLATE_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
     { MOZ_TXTTOHTMLCONV_CONTRACTID, &kMOZITXTTOHTMLCONV_CID },
     { NS_MIMEHEADERPARAM_CONTRACTID, &kNS_MIMEHEADERPARAM_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "file", &kNS_FILEPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &kNS_HTTPPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "https", &kNS_HTTPSPROTOCOLHANDLER_CID },
-    { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "basic", &kNS_HTTPBASICAUTH_CID },
-    { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "digest", &kNS_HTTPDIGESTAUTH_CID },
-    { NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "ntlm", &kNS_HTTPNTLMAUTH_CID },
     { NS_HTTPAUTHMANAGER_CONTRACTID, &kNS_HTTPAUTHMANAGER_CID },
     { NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &kNS_HTTPACTIVITYDISTRIBUTOR_CID },
     { NS_THROTTLEQUEUE_CONTRACTID, &kNS_THROTTLEQUEUE_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &kNS_FTPPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource", &kNS_RESPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-extension", &kNS_EXTENSIONPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about", &kNS_ABOUTPROTOCOLHANDLER_CID },
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-safe-about", &kNS_SAFEABOUTPROTOCOLHANDLER_CID },
@@ -933,16 +931,17 @@ static const mozilla::Module::ContractID
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #endif
     { NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID, &kNS_CACHE_STORAGE_SERVICE_CID },
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID2, &kNS_CACHE_STORAGE_SERVICE_CID },
     { NS_NSILOADCONTEXTINFOFACTORY_CONTRACTID, &kNS_NSILOADCONTEXTINFOFACTORY_CID },
     { NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
     { NS_CAPTIVEPORTAL_CONTRACTID, &kNS_CAPTIVEPORTAL_CID },
+    { NS_NETWORKCONNECTIVITYSERVICE_CONTRACTID, &kNS_NETWORKCONNECTIVITYSERVICE_CID },
 #ifdef BUILD_NETWORK_INFO_SERVICE
     { NETWORKINFOSERVICE_CONTRACT_ID, &kNETWORKINFOSERVICE_CID },
 #endif
     { nullptr }
     // clang-format on
 };
 
 static const mozilla::Module kNeckoModule = {
--- a/netwerk/dns/effective_tld_names.dat
+++ b/netwerk/dns/effective_tld_names.dat
@@ -10830,16 +10830,21 @@ pimienta.org
 poivron.org
 potager.org
 sweetpepper.org
 
 // ASUSTOR Inc. : http://www.asustor.com
 // Submitted by Vincent Tseng <vincenttseng@asustor.com>
 myasustor.com
 
+// Automattic Inc. : https://automattic.com/
+// Submitted by Alex Concha <alex.concha@automattic.com>
+go-vip.co
+wpcomstaging.com
+
 // AVM : https://avm.de
 // Submitted by Andreas Weise <a.weise@avm.de>
 myfritz.net
 
 // AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com
 // Submitted by James Kennedy <domains@advisorwebsites.com>
 *.awdev.ca
 *.advisor.ws
@@ -11080,16 +11085,21 @@ debian.net
 // deSEC : https://desec.io/
 // Submitted by Peter Thomassen <peter@desec.io>
 dedyn.io
 
 // DNShome : https://www.dnshome.de/
 // Submitted by Norbert Auler <mail@dnshome.de>
 dnshome.de
 
+// DotArai : https://www.dotarai.com/
+// Submitted by Atsadawat Netcharadsang <atsadawat@dotarai.co.th>
+online.th
+shop.th
+
 // DrayTek Corp. : https://www.draytek.com/
 // Submitted by Paul Fang <mis@draytek.com>
 drayddns.com
 
 // DreamHost : http://www.dreamhost.com/
 // Submitted by Andrew Farmer <andrew.farmer@dreamhost.com>
 dreamhosters.com
 
@@ -11636,16 +11646,20 @@ fhapp.xyz
 // Fedora : https://fedoraproject.org/
 // submitted by Patrick Uiterwijk <puiterwijk@fedoraproject.org>
 fedorainfracloud.org
 fedorapeople.org
 cloud.fedoraproject.org
 app.os.fedoraproject.org
 app.os.stg.fedoraproject.org
 
+// Fermax : https://fermax.com/
+// submitted by Koen Van Isterdael <k.vanisterdael@fermax.be>
+mydobiss.com
+
 // Filegear Inc. : https://www.filegear.com
 // Submitted by Jason Zhu <jason@owtware.com>
 filegear.me
 
 // Firebase, Inc.
 // Submitted by Chris Raynor <chris@firebase.com>
 firebaseapp.com
 
@@ -11923,16 +11937,25 @@ linkitools.space
 // Submitted by Mario Siegenthaler <mario.siegenthaler@linkyard.ch>
 linkyard.cloud
 linkyard-cloud.ch
 
 // LiquidNet Ltd : http://www.liquidnetlimited.com/
 // Submitted by Victor Velchev <admin@liquidnetlimited.com>
 we.bs
 
+// LubMAN UMCS Sp. z o.o : https://lubman.pl/
+// Submitted by Ireneusz Maliszewski <ireneusz.maliszewski@lubman.pl>
+krasnik.pl
+leczna.pl
+lubartow.pl
+lublin.pl
+poniatowa.pl
+swidnik.pl
+
 // Lug.org.uk : https://lug.org.uk
 // Submitted by Jon Spriggs <admin@lug.org.uk>
 uklugs.org
 glug.org.uk
 lug.org.uk
 lugs.org.uk
 
 // Lukanet Ltd : https://lukanet.com
@@ -12310,16 +12333,20 @@ priv.at
 // Submitted by Martin Meier <admin@protonet.io>
 protonet.io
 
 // Publication Presse Communication SARL : https://ppcom.fr
 // Submitted by Yaacov Akiba Slama <admin@chirurgiens-dentistes-en-france.fr>
 chirurgiens-dentistes-en-france.fr
 byen.site
 
+// Redstar Consultants : https://www.redstarconsultants.com/
+// Submitted by Jons Slemmer <jons@redstarconsultants.com>
+instantcloud.cn
+
 // Russian Academy of Sciences
 // Submitted by Tech Support <support@rasnet.ru>
 ras.ru
 
 // QA2
 // Submitted by Daniel Dent (https://www.danieldent.com/)
 qa2.com
 
@@ -12414,16 +12441,20 @@ myshopblocks.com
 // SinaAppEngine : http://sae.sina.com.cn/
 // Submitted by SinaAppEngine <saesupport@sinacloud.com>
 1kapp.com
 appchizi.com
 applinzi.com
 sinaapp.com
 vipsinaapp.com
 
+// Siteleaf : https://www.siteleaf.com/
+// Submitted by Skylar Challand <support@siteleaf.com>
+siteleaf.net
+
 // Skyhat : http://www.skyhat.io
 // Submitted by Shante Adam <shante@skyhat.io>
 bounty-full.com
 alpha.bounty-full.com
 beta.bounty-full.com
 
 // staticland : https://static.land
 // Submitted by Seth Vincent <sethvincent@gmail.com>
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -128,16 +128,17 @@ EXTRA_JS_MODULES += [
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
+    '/extensions/auth',
     '/netwerk/base',
     '/netwerk/cookie',
 ]
 
 EXTRA_COMPONENTS += [
     'UAOverridesBootstrapper.js',
     'UAOverridesBootstrapper.manifest',
     'WellKnownOpportunisticUtils.js',
--- a/netwerk/protocol/http/nsHttpBasicAuth.cpp
+++ b/netwerk/protocol/http/nsHttpBasicAuth.cpp
@@ -5,20 +5,38 @@
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpBasicAuth.h"
 #include "plstr.h"
 #include "nsString.h"
 #include "mozilla/Base64.h"
+#include "mozilla/ClearOnShutdown.h"
 
 namespace mozilla {
 namespace net {
 
+StaticRefPtr<nsHttpBasicAuth> nsHttpBasicAuth::gSingleton;
+
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpBasicAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpBasicAuth();
+      ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpBasicAuth::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(nsHttpBasicAuth, nsIHttpAuthenticator)
 
 //-----------------------------------------------------------------------------
 // nsHttpBasicAuth::nsIHttpAuthenticator
--- a/netwerk/protocol/http/nsHttpBasicAuth.h
+++ b/netwerk/protocol/http/nsHttpBasicAuth.h
@@ -2,31 +2,38 @@
 /* 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/. */
 
 #ifndef nsBasicAuth_h__
 #define nsBasicAuth_h__
 
 #include "nsIHttpAuthenticator.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPtr.h"
 
 namespace mozilla { namespace net {
 
 //-----------------------------------------------------------------------------
 // The nsHttpBasicAuth class produces HTTP Basic-auth responses for a username/
 // (optional)password pair, BASE64("user:pass").
 //-----------------------------------------------------------------------------
 
 class nsHttpBasicAuth : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpBasicAuth() = default;
+
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
 private:
     virtual ~nsHttpBasicAuth() = default;
+
+    static StaticRefPtr<nsHttpBasicAuth> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // !nsHttpBasicAuth_h__
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -20,16 +20,20 @@
 #include "nsEscape.h"
 #include "nsAuthInformationHolder.h"
 #include "nsIStringBundle.h"
 #include "nsIPrompt.h"
 #include "netCore.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsIURI.h"
 #include "nsContentUtils.h"
+#include "nsHttpBasicAuth.h"
+#include "nsHttpDigestAuth.h"
+#include "nsHttpNegotiateAuth.h"
+#include "nsHttpNTLMAuth.h"
 #include "nsServiceManagerUtils.h"
 #include "nsILoadContext.h"
 #include "nsIURL.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "nsIProxiedChannel.h"
 #include "nsIProxyInfo.h"
 
@@ -1090,21 +1094,33 @@ nsHttpChannelAuthProvider::GetAuthentica
     LOG(("nsHttpChannelAuthProvider::GetAuthenticator [this=%p channel=%p]\n",
         this, mAuthChannel));
 
     GetAuthType(challenge, authType);
 
     // normalize to lowercase
     ToLowerCase(authType);
 
-    nsAutoCString contractid;
-    contractid.AssignLiteral(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
-    contractid.Append(authType);
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (authType.EqualsLiteral("negotiate")) {
+      authenticator = nsHttpNegotiateAuth::GetOrCreate();
+    } else if (authType.EqualsLiteral("basic")) {
+      authenticator = nsHttpBasicAuth::GetOrCreate();
+    } else if (authType.EqualsLiteral("digest")) {
+      authenticator = nsHttpDigestAuth::GetOrCreate();
+    } else if (authType.EqualsLiteral("ntlm")) {
+      authenticator = nsHttpNTLMAuth::GetOrCreate();
+    } else {
+      return NS_ERROR_SERVICE_NOT_FOUND;
+    }
 
-    return CallGetService(contractid.get(), auth);
+    MOZ_ASSERT(authenticator);
+    authenticator.forget(auth);
+
+    return NS_OK;
 }
 
 void
 nsHttpChannelAuthProvider::GetIdentityFromURI(uint32_t            authFlags,
                                               nsHttpAuthIdentity &ident)
 {
     LOG(("nsHttpChannelAuthProvider::GetIdentityFromURI [this=%p channel=%p]\n",
         this, mAuthChannel));
--- a/netwerk/protocol/http/nsHttpDigestAuth.cpp
+++ b/netwerk/protocol/http/nsHttpDigestAuth.cpp
@@ -2,16 +2,17 @@
  *
  * 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/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
+#include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Unused.h"
 
 #include "nsHttp.h"
 #include "nsHttpDigestAuth.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIURI.h"
@@ -20,16 +21,33 @@
 #include "nsNetCID.h"
 #include "nsCRT.h"
 #include "nsICryptoHash.h"
 #include "nsComponentManagerUtils.h"
 
 namespace mozilla {
 namespace net {
 
+StaticRefPtr<nsHttpDigestAuth> nsHttpDigestAuth::gSingleton;
+
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpDigestAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpDigestAuth();
+      ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpDigestAuth::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(nsHttpDigestAuth, nsIHttpAuthenticator)
 
 //-----------------------------------------------------------------------------
 // nsHttpDigestAuth <protected>
--- a/netwerk/protocol/http/nsHttpDigestAuth.h
+++ b/netwerk/protocol/http/nsHttpDigestAuth.h
@@ -6,16 +6,17 @@
 
 #ifndef nsDigestAuth_h__
 #define nsDigestAuth_h__
 
 #include "nsIHttpAuthenticator.h"
 #include "nsStringFwd.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/StaticPtr.h"
 
 class nsICryptoHash;
 
 namespace mozilla { namespace net {
 
 #define ALGO_SPECIFIED 0x01
 #define ALGO_MD5 0x02
 #define ALGO_MD5_SESS 0x04
@@ -33,16 +34,18 @@ namespace mozilla { namespace net {
 class nsHttpDigestAuth final : public nsIHttpAuthenticator
 {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpDigestAuth() = default;
 
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
   protected:
     ~nsHttpDigestAuth() = default;
 
     MOZ_MUST_USE nsresult ExpandToHex(const char * digest, char * result);
 
     MOZ_MUST_USE nsresult CalculateResponse(const char * ha1_digest,
                                             const char * ha2_digest,
                                             const nsCString&  nonce,
@@ -82,14 +85,16 @@ class nsHttpDigestAuth final : public ns
 
     // append the quoted version of value to aHeaderLine
     MOZ_MUST_USE nsresult AppendQuotedString(const nsACString & value,
                                              nsACString & aHeaderLine);
 
   protected:
     nsCOMPtr<nsICryptoHash>        mVerifier;
     char                           mHashBuf[DIGEST_LENGTH];
+
+    static StaticRefPtr<nsHttpDigestAuth> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // nsHttpDigestAuth_h__
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -30,26 +30,29 @@
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Tokenizer.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "nsNetUtil.h"
 #include "nsIChannel.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/net/HttpAuthUtils.h"
+#include "mozilla/ClearOnShutdown.h"
 
 namespace mozilla {
 namespace net {
 
 static const char kAllowProxies[] = "network.automatic-ntlm-auth.allow-proxies";
 static const char kAllowNonFqdn[] = "network.automatic-ntlm-auth.allow-non-fqdn";
 static const char kTrustedURIs[]  = "network.automatic-ntlm-auth.trusted-uris";
 static const char kForceGeneric[] = "network.auth.force-generic-ntlm";
 static const char kSSOinPBmode[] = "network.auth.private-browsing-sso";
 
+StaticRefPtr<nsHttpNTLMAuth> nsHttpNTLMAuth::gSingleton;
+
 static bool
 IsNonFqdn(nsIURI *uri)
 {
     nsAutoCString host;
     PRNetAddr addr;
 
     if (NS_FAILED(uri->GetAsciiHost(host)))
         return false;
@@ -139,16 +142,31 @@ class nsNTLMSessionState final : public 
     ~nsNTLMSessionState() = default;
 public:
     NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS0(nsNTLMSessionState)
 
 //-----------------------------------------------------------------------------
 
+already_AddRefed<nsIHttpAuthenticator>
+nsHttpNTLMAuth::GetOrCreate()
+{
+    nsCOMPtr<nsIHttpAuthenticator> authenticator;
+    if (gSingleton) {
+      authenticator = gSingleton;
+    } else {
+      gSingleton = new nsHttpNTLMAuth();
+      ClearOnShutdown(&gSingleton);
+      authenticator = gSingleton;
+    }
+
+    return authenticator.forget();
+}
+
 NS_IMPL_ISUPPORTS(nsHttpNTLMAuth, nsIHttpAuthenticator)
 
 NS_IMETHODIMP
 nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel *channel,
                                   const char     *challenge,
                                   bool            isProxyAuth,
                                   nsISupports   **sessionState,
                                   nsISupports   **continuationState,
@@ -163,41 +181,41 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHtt
     // NOTE: we don't define any session state, but we do use the pointer.
 
     *identityInvalid = false;
 
     // Start a new auth sequence if the challenge is exactly "NTLM".
     // If native NTLM auth apis are available and enabled through prefs,
     // try to use them.
     if (PL_strcasecmp(challenge, "NTLM") == 0) {
-        nsCOMPtr<nsISupports> module;
+        nsCOMPtr<nsIAuthModule> module;
 
         // Check to see if we should default to our generic NTLM auth module
         // through UseGenericNTLM. (We use native auth by default if the
         // system provides it.) If *sessionState is non-null, we failed to
         // instantiate a native NTLM module the last time, so skip trying again.
         bool forceGeneric = ForceGenericNTLM();
         if (!forceGeneric && !*sessionState) {
             // Check for approved default credentials hosts and proxies. If
             // *continuationState is non-null, the last authentication attempt
             // failed so skip default credential use.
             if (!*continuationState && CanUseDefaultCredentials(channel, isProxyAuth)) {
                 // Try logging in with the user's default credentials. If
                 // successful, |identityInvalid| is false, which will trigger
                 // a default credentials attempt once we return.
-                module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
+                module = nsIAuthModule::CreateInstance("sys-ntlm");
             }
 #ifdef XP_WIN
             else {
                 // Try to use native NTLM and prompt the user for their domain,
                 // username, and password. (only supported by windows nsAuthSSPI module.)
                 // Note, for servers that use LMv1 a weak hash of the user's password
                 // will be sent. We rely on windows internal apis to decide whether
                 // we should support this older, less secure version of the protocol.
-                module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
+                module = nsIAuthModule::CreateInstance("sys-ntlm");
                 *identityInvalid = true;
             }
 #endif // XP_WIN
             if (!module)
                 LOG(("Native sys-ntlm auth module not found.\n"));
         }
 
 #ifdef XP_WIN
@@ -215,33 +233,33 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHtt
                 if (!*sessionState)
                     return NS_ERROR_OUT_OF_MEMORY;
                 NS_ADDREF(*sessionState);
             }
 
             // Use our internal NTLM implementation. Note, this is less secure,
             // see bug 520607 for details.
             LOG(("Trying to fall back on internal ntlm auth.\n"));
-            module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
+            module = nsIAuthModule::CreateInstance("ntlm");
 
             mUseNative = false;
 
             // Prompt user for domain, username, and password.
             *identityInvalid = true;
         }
 
         // If this fails, then it means that we cannot do NTLM auth.
         if (!module) {
             LOG(("No ntlm auth modules available.\n"));
             return NS_ERROR_UNEXPECTED;
         }
 
         // A non-null continuation state implies that we failed to authenticate.
         // Blow away the old authentication state, and use the new one.
-        module.swap(*continuationState);
+        module.forget(continuationState);
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpNTLMAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
                                          nsIHttpAuthenticatorCallback* aCallback,
                                          const char *challenge,
--- a/netwerk/protocol/http/nsHttpNTLMAuth.h
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.h
@@ -1,31 +1,36 @@
 /* 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/. */
 
 #ifndef nsHttpNTLMAuth_h__
 #define nsHttpNTLMAuth_h__
 
 #include "nsIHttpAuthenticator.h"
+#include "mozilla/StaticPtr.h"
 
 namespace mozilla { namespace net {
 
 class nsHttpNTLMAuth : public nsIHttpAuthenticator
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPAUTHENTICATOR
 
     nsHttpNTLMAuth() : mUseNative(false) {}
 
+    static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
 private:
     virtual ~nsHttpNTLMAuth() = default;
 
     // This flag indicates whether we are using the native NTLM implementation
     // or the internal one.
     bool  mUseNative;
+
+    static StaticRefPtr<nsHttpNTLMAuth> gSingleton;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // !nsHttpNTLMAuth_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -4,21 +4,25 @@
  * 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/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "base/basictypes.h"
 
+#include "nsHttpBasicAuth.h"
+#include "nsHttpChunkedDecoder.h"
+#include "nsHttpDigestAuth.h"
 #include "nsHttpHandler.h"
-#include "nsHttpTransaction.h"
+#include "nsHttpNegotiateAuth.h"
+#include "nsHttpNTLMAuth.h"
 #include "nsHttpRequestHead.h"
 #include "nsHttpResponseHead.h"
-#include "nsHttpChunkedDecoder.h"
+#include "nsHttpTransaction.h"
 #include "nsTransportUtils.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIChannel.h"
 #include "nsIPipe.h"
 #include "nsCRT.h"
 #include "mozilla/Tokenizer.h"
 #include "TCPFastOpenLayer.h"
@@ -2017,22 +2021,27 @@ nsHttpTransaction::CheckForStickyAuthSch
       return;
   }
 
   Tokenizer p(auth);
   nsAutoCString schema;
   while (p.ReadWord(schema)) {
       ToLowerCase(schema);
 
-      nsAutoCString contractid;
-      contractid.AssignLiteral(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
-      contractid.Append(schema);
-
       // using a new instance because of thread safety of auth modules refcnt
-      nsCOMPtr<nsIHttpAuthenticator> authenticator(do_CreateInstance(contractid.get()));
+      nsCOMPtr<nsIHttpAuthenticator> authenticator;
+      if (schema.EqualsLiteral("negotiate")) {
+        authenticator = new nsHttpNegotiateAuth();
+      } else if (schema.EqualsLiteral("basic")) {
+        authenticator = new nsHttpBasicAuth();
+      } else if (schema.EqualsLiteral("digest")) {
+        authenticator = new nsHttpDigestAuth();
+      } else if (schema.EqualsLiteral("ntlm")) {
+        authenticator = new nsHttpNTLMAuth();
+      }
       if (authenticator) {
           uint32_t flags;
           nsresult rv = authenticator->GetAuthFlags(&flags);
           if (NS_SUCCEEDED(rv) && (flags & nsIHttpAuthenticator::CONNECTION_BASED)) {
               LOG(("  connection made sticky, found %s auth shema", schema.get()));
               // This is enough to make this transaction keep it's current connection,
               // prevents the connection from being released back to the pool.
               mCaps |= NS_HTTP_STICKY_CONNECTION;
--- a/netwerk/protocol/http/nsIHttpAuthenticator.idl
+++ b/netwerk/protocol/http/nsIHttpAuthenticator.idl
@@ -214,13 +214,8 @@ interface nsIHttpAuthenticator : nsISupp
     const unsigned long IDENTITY_INCLUDES_DOMAIN = (1<<11);
 
     /**
      * This flag indicates that the identity will be sent encrypted. It does
      * not make sense to combine this flag with IDENTITY_IGNORED.
      */
     const unsigned long IDENTITY_ENCRYPTED = (1<<12);
 };
-
-%{C++
-#define NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX \
-    "@mozilla.org/network/http-authenticator;1?scheme="
-%}
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_network_connectivity_service.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+"use strict";
+
+ChromeUtils.import("resource://testing-common/httpd.js");
+ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+registerCleanupFunction(() => {
+  Services.prefs.clearUserPref("network.connectivity-service.DNSv4.domain");
+  Services.prefs.clearUserPref("network.connectivity-service.DNSv6.domain");
+});
+
+const DEFAULT_WAIT_TIME = 200; // ms
+
+const kDNSv6Domain = (mozinfo.os == "linux")
+                       ? "ip6-localhost"
+                       : "localhost";
+
+add_task(async function testDNS() {
+  let ncs = Cc["@mozilla.org/network/network-connectivity-service;1"]
+              .getService(Ci.nsINetworkConnectivityService);
+
+  // Set the endpoints, trigger a DNS recheck, and wait for it to complete.
+  Services.prefs.setCharPref("network.connectivity-service.DNSv4.domain", "example.org");
+  Services.prefs.setCharPref("network.connectivity-service.DNSv6.domain", kDNSv6Domain);
+  ncs.recheckDNS();
+  await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
+
+  equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.OK, "Check DNSv4 support (expect OK)");
+  equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.OK, "Check DNSv6 support (expect OK)");
+
+  // Set the endpoints to non-exitant domains, trigger a DNS recheck, and wait for it to complete.
+  Services.prefs.setCharPref("network.connectivity-service.DNSv4.domain", "does-not-exist.example");
+  Services.prefs.setCharPref("network.connectivity-service.DNSv6.domain", "does-not-exist.example");
+  ncs.recheckDNS();
+  await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
+
+  equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.NOT_AVAILABLE, "Check DNSv4 support (expect N/A)");
+  equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.NOT_AVAILABLE, "Check DNSv6 support (expect N/A)");
+
+  // Set the endpoints back to the proper domains, and simulate a captive portal
+  // event.
+  Services.prefs.setCharPref("network.connectivity-service.DNSv4.domain", "example.org");
+  Services.prefs.setCharPref("network.connectivity-service.DNSv6.domain", kDNSv6Domain);
+  Services.obs.notifyObservers(null, "network:captive-portal-connectivity", null);
+  // This will cause the state to go to UNKNOWN for a bit, until the check is completed.
+  equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.UNKNOWN, "Check DNSv4 support (expect UNKNOWN)");
+  equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.UNKNOWN, "Check DNSv6 support (expect UNKNOWN)");
+
+  await new Promise(resolve => do_timeout(DEFAULT_WAIT_TIME, resolve));
+
+  equal(ncs.DNSv4, Ci.nsINetworkConnectivityService.OK, "Check DNSv4 support (expect OK)");
+  equal(ncs.DNSv6, Ci.nsINetworkConnectivityService.OK, "Check DNSv6 support (expect OK)");
+
+  // It's difficult to check when there's no connectivity in automation,
+  equal(ncs.IPv4, Ci.nsINetworkConnectivityService.OK, "Check IPv4 support (expect OK)");
+  equal(ncs.IPv6, Ci.nsINetworkConnectivityService.OK, "Check IPv6 support (expect OK)");
+});
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -417,8 +417,10 @@ skip-if = os == "android"
 [test_ioservice.js]
 [test_substituting_protocol_handler.js]
 [test_captive_portal_service.js]
 skip-if = os == "android" # CP service is disabled on Android
 run-sequentially = node server exceptions dont replay well
 [test_esni_dns_fetch.js]
 # http2-using tests require node available
 skip-if = os == "android"
+[test_network_connectivity_service.js]
+skip-if = os == "android" # DNSv6 issues on android
--- a/python/mozbuild/mozbuild/action/test_archive.py
+++ b/python/mozbuild/mozbuild/action/test_archive.py
@@ -160,16 +160,22 @@ ARCHIVE_FILES = {
         {
             'source': buildconfig.topsrcdir,
             'base': '',
             'pattern': 'testing/firefox-ui/tests',
             'dest': 'firefox-ui/tests',
         },
         {
             'source': buildconfig.topsrcdir,
+            'base': 'toolkit/components/telemetry/tests/marionette',
+            'pattern': '/**',
+            'dest': 'telemetry/marionette',
+        },
+        {
+            'source': buildconfig.topsrcdir,
             'base': 'js/src',
             'pattern': 'jit-test/**',
             'dest': 'jit-test',
         },
         {
             'source': buildconfig.topsrcdir,
             'base': 'js/src/tests',
             'pattern': 'non262/shell.js',
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1166,9 +1166,9 @@ static const TransportSecurityPreload kP
   { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
   { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
 };
 
 // Pinning Preload List Length = 488;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1548936380438000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1549281958944000);
--- a/security/manager/ssl/nsNSSModule.cpp
+++ b/security/manager/ssl/nsNSSModule.cpp
@@ -18,17 +18,16 @@
 #include "nsCryptoHash.h"
 #include "nsICategoryManager.h"
 #include "nsKeyModule.h"
 #include "nsKeygenHandler.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSCertificateDB.h"
 #include "nsNSSComponent.h"
 #include "nsNSSVersion.h"
-#include "nsNTLMAuthModule.h"
 #include "nsNetCID.h"
 #include "nsPK11TokenDB.h"
 #include "nsPKCS11Slot.h"
 #include "nsRandomGenerator.h"
 #include "nsSecureBrowserUIImpl.h"
 #include "nsSiteSecurityService.h"
 #include "nsXULAppAPI.h"
 #include "OSKeyStore.h"
@@ -139,17 +138,16 @@ NS_DEFINE_NAMED_CID(NS_X509CERT_CID);
 NS_DEFINE_NAMED_CID(NS_X509CERTDB_CID);
 NS_DEFINE_NAMED_CID(NS_X509CERTLIST_CID);
 NS_DEFINE_NAMED_CID(NS_FORMPROCESSOR_CID);
 #ifdef MOZ_XUL
 NS_DEFINE_NAMED_CID(NS_CERTTREE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_CRYPTO_HASH_CID);
 NS_DEFINE_NAMED_CID(NS_CRYPTO_HMAC_CID);
-NS_DEFINE_NAMED_CID(NS_NTLMAUTHMODULE_CID);
 NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECT_CID);
 NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_CONTENTSIGNATUREVERIFIER_CID);
 NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID);
 NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID);
 NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
 NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NSSVERSION_CID);
@@ -178,18 +176,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_FORMPROCESSOR_CID, false, nullptr, nsKeygenFormProcessor::Create },
 #ifdef MOZ_XUL
   { &kNS_CERTTREE_CID, false, nullptr, Constructor<nsCertTree> },
 #endif
   { &kNS_CRYPTO_HASH_CID, false, nullptr,
     Constructor<nsCryptoHash, nullptr, ProcessRestriction::AnyProcess> },
   { &kNS_CRYPTO_HMAC_CID, false, nullptr,
     Constructor<nsCryptoHMAC, nullptr, ProcessRestriction::AnyProcess> },
-  { &kNS_NTLMAUTHMODULE_CID, false, nullptr,
-    Constructor<nsNTLMAuthModule, &nsNTLMAuthModule::InitTest> },
   { &kNS_KEYMODULEOBJECT_CID, false, nullptr,
     Constructor<nsKeyObject, nullptr, ProcessRestriction::AnyProcess> },
   { &kNS_KEYMODULEOBJECTFACTORY_CID, false, nullptr,
     Constructor<nsKeyObjectFactory, nullptr, ProcessRestriction::AnyProcess> },
   { &kNS_CONTENTSIGNATUREVERIFIER_CID, false, nullptr,
     Constructor<ContentSignatureVerifier> },
   { &kNS_CERTOVERRIDE_CID, false, nullptr,
     Constructor<nsCertOverrideService, &nsCertOverrideService::Init,
@@ -234,17 +230,16 @@ static const mozilla::Module::ContractID
   { NS_X509CERTLIST_CONTRACTID, &kNS_X509CERTLIST_CID },
   { NS_FORMPROCESSOR_CONTRACTID, &kNS_FORMPROCESSOR_CID },
 #ifdef MOZ_XUL
   { NS_CERTTREE_CONTRACTID, &kNS_CERTTREE_CID },
 #endif
   { NS_CRYPTO_HASH_CONTRACTID, &kNS_CRYPTO_HASH_CID },
   { NS_CRYPTO_HMAC_CONTRACTID, &kNS_CRYPTO_HMAC_CID },
   { "@mozilla.org/uriloader/psm-external-content-listener;1", &kNS_PSMCONTENTLISTEN_CID },
-  { NS_NTLMAUTHMODULE_CONTRACTID, &kNS_NTLMAUTHMODULE_CID },
   { NS_KEYMODULEOBJECT_CONTRACTID, &kNS_KEYMODULEOBJECT_CID },
   { NS_KEYMODULEOBJECTFACTORY_CONTRACTID, &kNS_KEYMODULEOBJECTFACTORY_CID },
   { NS_CONTENTSIGNATUREVERIFIER_CONTRACTID, &kNS_CONTENTSIGNATUREVERIFIER_CID },
   { NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID },
   { NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID },
   { NS_SECURE_BROWSER_UI_CONTRACTID, &kNS_SECURE_BROWSER_UI_CID },
   { NS_SSSERVICE_CONTRACTID, &kNS_SITE_SECURITY_SERVICE_CID },
   { NS_CERTBLOCKLIST_CONTRACTID, &kNS_CERT_BLOCKLIST_CID },
--- a/security/manager/ssl/nsNTLMAuthModule.h
+++ b/security/manager/ssl/nsNTLMAuthModule.h
@@ -26,19 +26,9 @@ protected:
 
 private:
   nsString mDomain;
   nsString mUsername;
   nsString mPassword;
   bool mNTLMNegotiateSent;
 };
 
-#define NS_NTLMAUTHMODULE_CONTRACTID \
-  NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm"
-#define NS_NTLMAUTHMODULE_CID \
-{ /* a4e5888f-4fe4-4632-8e7e-745196ea7c70 */       \
-  0xa4e5888f,                                      \
-  0x4fe4,                                          \
-  0x4632,                                          \
-  {0x8e, 0x7e, 0x74, 0x51, 0x96, 0xea, 0x7c, 0x70} \
-}
-
 #endif // nsNTLMAuthModule_h__
--- a/security/manager/ssl/nsSTSPreloadList.inc
+++ b/security/manager/ssl/nsSTSPreloadList.inc
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*****************************************************************************/
 /* This is an automatically generated file. If you're not                    */
 /* nsSiteSecurityService.cpp, you shouldn't be #including it.                */
 /*****************************************************************************/
 
 #include <stdint.h>
-const PRTime gPreloadListExpirationTime = INT64_C(1551355575263000);
+const PRTime gPreloadListExpirationTime = INT64_C(1551701153978000);
 %%
 0-1.party, 1
 00100010.net, 1
 0010100.net, 1
 00120012.net, 1
 00130013.net, 1
 00140014.net, 1
 00150015.net, 1
@@ -372,16 +372,17 @@ 1volcano.ru, 1
 1whw.co.uk, 1
 1wirelog.de, 1
 1wl.uk, 1
 2.wtf, 1
 200.network, 1
 200fcw.com, 1
 2012.ovh, 1
 2018.wales, 1
+20188088.com, 1
 2048-spiel.de, 1
 2048game.co.uk, 1
 20at.com, 1
 20denier.com, 1
 20zq.com, 1
 215dy.net, 1
 21sthammersmith.org.uk, 1
 21stnc.com, 1
@@ -584,17 +585,16 @@ 354933.com, 1
 356433.com, 1
 357maelai.co, 1
 360ds.co.in, 1
 360live.fr, 1
 360rail.nl, 1
 360vrs.com, 1
 360woodworking.com, 1
 364553.com, 1
-365365.com, 1
 365beautyworld.com, 1
 365daysreview.com, 1
 365healthworld.com, 1
 365propertybuyer.co.uk, 1
 365skulls.com, 1
 370422.com, 1
 371422.com, 1
 371cloud.com, 1
@@ -727,16 +727,17 @@ 4d2.xyz, 1
 4dbygg.se, 1
 4decor.org, 1
 4everproxy.com, 1
 4eyes.ch, 1
 4fit.ro, 1
 4flex.info, 1
 4freepress.com, 1
 4g-server.eu, 0
+4garage.com.br, 1
 4host.ch, 1
 4kprojektory.cz, 1
 4loc.us, 1
 4mm.org, 1
 4plebs.moe, 1
 4project.co.il, 1
 4share.tv, 1
 4sics.se, 1
@@ -940,17 +941,16 @@ 646.io, 0
 646022.com, 1
 646322.com, 1
 646722.com, 1
 649022.com, 1
 649622.com, 1
 649722.com, 1
 649822.com, 1
 64bitgaming.de, 1
-64bitservers.net, 0
 651422.com, 1
 652422.com, 1
 6541166.com, 1
 6542277.com, 1
 6543399.com, 1
 65477.com, 1
 6547700.com, 1
 6547711.com, 1
@@ -1035,25 +1035,23 @@ 738433.com, 1
 739433.com, 1
 73info.com, 0
 740833.com, 1
 741833.com, 1
 742833.com, 1
 743833.com, 1
 74th.jp, 1
 755k3.com, 1
-7570.com, 1
 762.ch, 1
 7733445.com, 1
 7777yh.com, 1
 777coin.com, 1
 783lab.com, 1
 787k3.com, 1
 7885765.com, 1
-788da.com, 1
 7891553.com, 1
 7891997.com, 1
 7careconnect.com, 1
 7delights.com, 1
 7delights.in, 1
 7geese.com, 1
 7graus.pt, 1
 7kicks.com, 1
@@ -1337,20 +1335,20 @@ a3.pm, 1
 a4sound.com, 1
 a632079.me, 1
 a7m2.me, 1
 a8q.org, 1
 aa-tour.ru, 1
 aa43d.cn, 1
 aa6688.net, 1
 aaapl.com, 1
+aabanet.com.br, 1
 aaben-bank.dk, 1
 aabenbank.dk, 1
 aacfree.com, 1
-aaex.cloud, 1
 aagetransport.no, 1
 aalalbayt.com, 1
 aalalbayt.net, 1
 aalstmotors-usedcars.be, 1
 aaltocapital.com, 1
 aamwa.com, 1
 aanbieders.ga, 1
 aandeautobody.com, 1
@@ -1476,16 +1474,17 @@ aboutyou.at, 1
 aboutyou.be, 1
 aboutyou.ch, 1
 aboutyou.de, 1
 aboutyou.nl, 1
 aboveaverageplumbing.com, 1
 abox-kb.com, 1
 abpis.hr, 1
 abracadabra.co.jp, 0
+abrakidabra.com.br, 1
 abraxan.pro, 1
 abrilect.com, 1
 abristolgeek.co.uk, 1
 abseits.org, 1
 absolem.cc, 1
 absoluteautobody.com, 1
 absolutedouble.co.uk, 1
 absolutehaitian.com, 1
@@ -1511,18 +1510,18 @@ ac-admin.pl, 1
 ac-epmservices.com, 1
 ac-town.com, 1
 ac0g.dyndns.org, 1
 aca-creative.co.uk, 1
 academicexperts.us, 1
 academie-de-police.ch, 1
 academkin.com, 1
 academytv.com.au, 1
-acadianapatios.com, 1
 acaeum.com, 1
+acampar.com.br, 1
 acaonegocios.com.br, 1
 acaptureservices.com, 1
 acara-yoga.de, 1
 acareer.in, 1
 acat.io, 1
 acbrussels-used.be, 1
 accbay.com, 1
 accelaway.com, 1
@@ -1563,27 +1562,29 @@ acecolleges.edu.au, 1
 acedog.co, 1
 aceinflatables.com, 1
 aceinstituteonline.com, 1
 acelpb.com, 1
 acem.org.au, 1
 acemobileforce.com, 1
 acemypaper.com, 1
 acen.eu, 1
+acendealuz.com.br, 1
 acerentalandsales.com, 1
 acerislaw.com, 1
 acessoeducacao.com, 1
 acevik.de, 1
 acfo.org, 1
 acg.mn, 1
 acg.sb, 0
 acg.social, 1
 acg18.us, 0
 acgaudio.com, 1
 acgpiano.club, 1
+acgtalktw.com, 1
 achalay.org, 1
 acheconcursos.com.br, 1
 achenar.net, 1
 acheter-ethylotest.fr, 1
 achmadfamily.com, 1
 achromatisch.de, 1
 achterblog.de, 1
 achterhoekseveiligheidsbeurs.nl, 1
@@ -1595,17 +1596,17 @@ achwo.de, 1
 acid.ninja, 1
 acidbin.co, 1
 aciety.com, 1
 aciksite.com, 1
 ackermann.ch, 1
 ackis.duckdns.org, 0
 acklandstainless.com.au, 1
 acksoftdemo.fr, 1
-acl.gov, 1
+acl.gov, 0
 aclu.org, 0
 acluva.org, 0
 acme.beer, 1
 acmexyz123.info, 1
 acnpacific.com, 1
 acodess.com, 1
 aconnor.xyz, 1
 acordes.online, 1
@@ -1695,16 +1696,17 @@ ad-notam.asia, 1
 ad-notam.ch, 1
 ad-notam.co.uk, 1
 ad-notam.com, 1
 ad-notam.de, 1
 ad-notam.fr, 1
 ad-notam.it, 1
 ad-notam.pt, 1
 ad-notam.us, 1
+ad13.in, 1
 ada.gov, 1
 adalis.org, 1
 adam-ant.co.uk, 1
 adam-kostecki.de, 1
 adam-wilson.me, 1
 adamas-magicus.ru, 1
 adambalogh.net, 1
 adambyers.com, 1
@@ -1927,16 +1929,17 @@ aerobasegroup.com, 1
 aerobotz.com, 1
 aeronautix.com, 1
 aeropole.de, 1
 aeropole.eu, 1
 aerosimexperience.com, 1
 aerospace-schools.com, 1
 aerotechcoatings.com, 1
 aertel.ie, 1
+aessencia.com.br, 1
 aestheticdr.org, 1
 aesthetx.com, 1
 aestore.by, 1
 aesym.de, 1
 aeternus.tech, 1
 aetherc0r3.eu, 1
 aethonan.pro, 1
 aetoscg.com, 1
@@ -2161,32 +2164,32 @@ aiki.tk, 1
 aikido-club-limburg.de, 1
 aikido-kiel.de, 1
 aikido-linz.at, 1
 aikido-wels.at, 1
 ailitonia.com, 1
 ailitonia.xyz, 1
 aimax.com, 1
 aimeeandalec.com, 1
+aimerworld.com, 1
 aimgroup.co.tz, 1
 aimi-salon.com, 1
 aimotive.com, 1
 aimrom.org, 1
 aimstoreglobal.com, 1
 aintevenmad.ch, 1
 ainutrition.co.uk, 1
 ainvest.de, 1
 aioboot.com, 1
 aiois.com, 1
 aipbarcelona.com, 1
 aiphyron.com, 1
 air-craftglass.com, 1
 air-shots.ch, 1
 air-we-go.co.uk, 1
-airbly.com, 1
 airbnb.ae, 1
 airbnb.at, 1
 airbnb.be, 1
 airbnb.biz, 1
 airbnb.ca, 1
 airbnb.cat, 1
 airbnb.ch, 1
 airbnb.cl, 1
@@ -2250,17 +2253,16 @@ airbnb.ru, 1
 airbnb.se, 1
 airbnb.tools, 1
 airbnbchina.cn, 1
 airbnbopen.com, 1
 airborne-inflatables.co.uk, 1
 airbossofamerica.com, 1
 airclass.com, 1
 aircomms.com, 1
-airconssandton.co.za, 1
 airductclean.com, 0
 airductcleaning-fresno.com, 1
 airductcleaninggrandprairie.com, 1
 airductcleaningirving.com, 1
 airdur.eu, 1
 aireaseleaks.org, 1
 airedaleterrier.com.br, 1
 airetvie.com, 1
@@ -2347,17 +2349,17 @@ akita-boutique.com, 1
 akita-stream.com, 1
 akiym.com, 1
 akj.io, 1
 akkbouncycastles.co.uk, 1
 akkeylab.com, 1
 akoch.net, 1
 akostecki.de, 1
 akovana.com, 1
-akoww.de, 1
+akoww.de, 0
 akoya.fi, 1
 akplates.org, 1
 akpwebdesign.com, 1
 akr.io, 1
 akr.services, 1
 akracing.se, 1
 akritikos.info, 1
 akronet.cz, 0
@@ -2433,16 +2435,17 @@ alcatelonetouch.us, 1
 alcatraz.online, 1
 alchimic.ch, 1
 alcnutrition.com, 1
 alco-united.com, 1
 alcoholapi.com, 1
 alcolecapital.com, 1
 alcorao.org, 1
 aldiabcs.com, 1
+aldien.com.br, 1
 aldo-vandini.de, 1
 aldomedia.com, 1
 aldorr.net, 0
 aldous-huxley.com, 1
 aleax.me, 1
 alecpap.com, 1
 alecpapierniak.com, 1
 alecrust.com, 1
@@ -2454,16 +2457,17 @@ alela.fr, 1
 aleph.land, 1
 alerbon.net, 1
 alertboxx.com, 1
 alertonline.nl, 1
 alerts.sg, 1
 alertwire.com, 1
 alesia-formation.fr, 1
 alessandro.pw, 1
+alessandroonline.com.br, 1
 alessandroz.ddns.net, 1
 aletm.it, 1
 alex-ross.co.uk, 1
 alex97000.de, 1
 alexander-beck.eu, 1
 alexanderb.info, 1
 alexandermuetzel.de, 1
 alexanderneng.de, 1
@@ -2515,16 +2519,17 @@ alextaffe.com, 1
 alexthayne.co.uk, 1
 alextjam.es, 1
 alextsang.net, 1
 alexvdveen.nl, 1
 alexvetter.de, 1
 alexwardweb.com, 1
 alexyang.me, 1
 alfa-tech.su, 1
+alfaperfumes.com.br, 1
 alfaponny.se, 1
 alfirous.com, 1
 alftrain.com, 1
 algarmatic-automatismos.pt, 1
 algeriepart.com, 1
 alghanimcatering.com, 1
 algoaware.eu, 1
 algoentremanos.com, 1
@@ -2705,16 +2710,17 @@ alphaetomega3d.fr, 1
 alphafiduciaryservices.ch, 1
 alphafitnesslibya.com, 1
 alphagateanddoor.com, 1
 alphahunks.com, 0
 alphainflatablehire.com, 1
 alphaman.ooo, 1
 alphapengu.in, 1
 alpharotary.com, 1
+alphasall.com, 0
 alphassl.de, 1
 alphatrash.de, 1
 alphavote-avex.com, 1
 alphavote.com, 1
 alphera.nl, 1
 alphie.me, 1
 alphipneux.fr, 1
 alpinechaletrental.com, 1
@@ -2737,16 +2743,17 @@ alt.org, 1
 altahrim.net, 1
 altapina.com, 1
 altaplana.be, 1
 altbinaries.com, 1
 altedirect.com, 1
 alter-news.fr, 1
 alterbaum.net, 1
 altered.network, 1
+alternador.com.br, 1
 alternative.bike, 1
 alternativebit.fr, 1
 alternativedev.ca, 1
 alternativet.party, 1
 alterspalter.de, 1
 altes-sportamt.de, 1
 altesses.eu, 1
 altestore.com, 1
@@ -2764,23 +2771,23 @@ altstipendiaten.de, 1
 alttrackr.com, 1
 altunbas.info, 1
 alumni-kusa.jp, 1
 alupferd.de, 1
 aluroof.eu, 1
 alvcs.com, 1
 alviano.com, 1
 alvicom.hu, 1
-alvis-audio.com, 1
 alvn.ga, 1
 alvosec.com, 1
 alwaysdry.com.au, 1
 alwayslookingyourbest.com, 1
 alwaysmine.fi, 1
 alwaysonssl.com, 1
+alxpresentes.com.br, 1
 alyoung.com, 1
 alza.at, 1
 alza.co.uk, 1
 alza.cz, 1
 alza.de, 1
 alza.hu, 1
 alza.sk, 1
 alzashop.com, 1
@@ -2935,16 +2942,17 @@ anabolic.co, 1
 anacreon.de, 1
 anadiyogacentre.com, 1
 anaethelion.fr, 1
 anajianu.ro, 1
 anakros.me, 0
 analangelsteen.com, 1
 analbleachingguide.com, 1
 analgesia.net, 1
+analisilaica.it, 1
 analogist.net, 1
 analpantyhose.org, 1
 analteengirls.net, 1
 analytics-shop.com, 1
 analyticsinmotion.com, 1
 analyticum.at, 1
 analyticum.com, 1
 analyticum.de, 1
@@ -3075,17 +3083,17 @@ anecuni-club.com, 1
 anecuni-rec.com, 1
 anedot-sandbox.com, 1
 anedot.com, 1
 anedot.space, 1
 anedot.xyz, 1
 aneebahmed.com, 1
 anegabawa.com, 1
 anekdotes.com, 0
-aneslix.com, 1
+aneslix.com, 0
 anetaben.nl, 1
 anextraordinaryday.net, 1
 ange-de-bonheur444.com, 1
 angehardy.com, 1
 angel-body.com, 1
 angelesydemonios.es, 1
 angelic47.com, 1
 angelicare.co.uk, 1
@@ -3104,18 +3112,17 @@ anglingactive.co.uk, 1
 anglirl.eu.org, 1
 angrapa.ru, 1
 angristan.fr, 1
 angristan.xyz, 1
 angry-monk.com, 1
 angry.im, 1
 angrydragonproductions.com, 1
 angrysnarl.com, 1
-angryteeth.net, 0
-anguiao.com, 1
+angryteeth.net, 1
 angularjs.org, 0
 angusmak.com, 1
 anhaffen.lu, 1
 ani-man.de, 1
 aniaimichal.eu, 1
 aniforprez.net, 1
 anim.ee, 1
 animacurse.moe, 1
@@ -3286,16 +3293,17 @@ antoinemary.com, 1
 antonchen.com, 1
 antonellabb.eu, 1
 antonin.one, 1
 antonio-gartenbau.de, 1
 antonjuulnaber.dk, 1
 antota.lt, 1
 antragsgruen.de, 1
 antraxx.ee, 1
+antroposofica.com.br, 1
 anttitenhunen.com, 1
 antvklik.com, 1
 antyblokada.pl, 1
 anulowano.pl, 1
 anvartay.com, 0
 anwalt.us, 1
 anwaltsindex.com, 1
 anxietyspace.com, 1
@@ -3470,16 +3478,17 @@ apptomics.com, 1
 apptoutou.com, 1
 appuals.com, 1
 appui-de-fenetre.fr, 1
 appveyor.com, 1
 appzoojoo.be, 1
 apratimsaha.com, 1
 aprefix.com, 1
 apretatuercas.es, 1
+aprogend.com.br, 1
 aproposcomputing.com, 1
 aprovpn.com, 1
 aprr.org, 1
 aprsdroid.org, 1
 aprz.de, 1
 apsa.paris, 1
 apstudynotes.org, 1
 aptitude9.com, 1
@@ -3517,20 +3526,22 @@ ar-informatique.ch, 1
 arab.dating, 1
 arabicxz.com, 1
 arabsexi.info, 1
 arachina.com, 1
 arackiralama.name.tr, 1
 arados.de, 1
 arai21.net, 1
 araleeniken.com, 1
+aramado.com, 1
 aramido.de, 1
 aranchhomes.com, 1
 aranel.me, 1
 aranycsillag.net, 1
+araraexpress.com.br, 1
 araratour.com, 1
 araro.ch, 1
 araseifudousan.com, 1
 arawaza.biz, 1
 arawaza.com, 0
 arawaza.info, 1
 araxis.com, 1
 arbeitsch.eu, 1
@@ -3638,17 +3649,19 @@ arletalibrary.com, 1
 arlingtonelectric.com, 1
 arlingtonwine.net, 1
 arm.gov, 1
 armadaquadrat.com, 1
 armandsdiscount.com, 1
 armanozak.com, 1
 armansfinejewellery.com, 1
 armansfinejewellery.com.au, 1
+armarinhovirtual.com.br, 1
 armazemdaminiatura.com.br, 1
+armazemgourmetbrasil.com.br, 1
 armbrust.me, 1
 armedpoet.com, 1
 armenians.online, 1
 armeo.top, 1
 armil.it, 1
 armin-cme.de, 1
 armin-cpe.de, 1
 arminc.tk, 1
@@ -3675,16 +3688,17 @@ arnor.org, 1
 arnoudraeven.nl, 1
 arnoudvandalen.nl, 1
 arnsmedia.nl, 1
 arocloud.de, 1
 arod.tk, 1
 arogov.com, 1
 arokha.com, 1
 aromacos.ch, 1
+aromatlas.com, 1
 aron.host, 1
 aroonchande.com, 1
 aros.pl, 1
 arose.io, 1
 arox.eu, 1
 arpamip.org, 1
 arpnet.co.jp, 1
 arqueo-ecuatoriana.ec, 1
@@ -3720,16 +3734,17 @@ arteaga.me, 1
 arteaga.tech, 1
 arteaga.uk, 1
 arteaga.xyz, 1
 artecat.ch, 1
 artedellavetrina.it, 1
 artedona.com, 1
 arteequipamientos.com.uy, 1
 artefakt.es, 1
+artefeita.com.br, 1
 arteinstudio.it, 1
 artelt.com, 1
 artemis.re, 1
 arterienundvenen.ch, 1
 arteshow.ch, 1
 artetrama.com, 0
 artfabrics.com, 1
 artforum.sk, 1
@@ -3943,16 +3958,18 @@ asustreiber.de, 1
 asvsa.ch, 1
 asws.nl, 1
 asystent-dzierzawy.pl, 1
 at-one.ca, 1
 at.search.yahoo.com, 0
 at1.co, 1
 ataber.pw, 1
 atac.no, 1
+atacadocervejeiro.com.br, 1
+atacadodesandalias.com.br, 1
 atacadooptico.com.br, 1
 ataton.ch, 1
 atc.io, 1
 atchleyjazz.com, 1
 atchleyjazz.org, 1
 atchleylab.org, 1
 atcom.cl, 1
 atcreform.gov, 1
@@ -4031,16 +4048,17 @@ atolm.net, 1
 atom-china.org, 1
 atom.solutions, 1
 atom86.net, 1
 atombase.org, 1
 atomic-bounce.com, 1
 atomic.red, 1
 atomicbounce.co.uk, 1
 atomism.com, 1
+atorcidabrasileira.com.br, 1
 atplonline.co, 1
 atpnutrition.com, 1
 atracaosexshop.com.br, 1
 atraining.ru, 1
 atraverscugy.ch, 1
 atrevillot.com, 1
 atrinik.org, 1
 atsoftware.de, 1
@@ -4213,17 +4231,16 @@ automationpro.me, 1
 automotivegroup-usedcars.be, 1
 automotivemechanic.org, 1
 automoto-tom.net, 1
 autonewssite.com, 1
 autoosijek.com, 1
 autopapo.com.br, 1
 autoparts.im, 1
 autoparts.sh, 1
-autoparts.wf, 1
 autoprice.info, 0
 autoprogconsortium.ga, 1
 autoproshouston.com, 1
 autorando.com, 1
 autoschadeschreuder.nl, 1
 autoscuola.roma.it, 1
 autosecurityfinance.com, 1
 autoshinka72.ru, 1
@@ -4330,17 +4347,16 @@ avxo.pw, 1
 awan.tech, 1
 awardplatform.com, 1
 awardsplatform.com, 1
 awaremi-tai.com, 1
 awaresec.com, 1
 awaresec.no, 1
 awaro.net, 1
 awbouncycastlehire.com, 1
-awccanadianpharmacy.com, 1
 awecademy.org, 1
 awei.pub, 1
 awen.me, 1
 awesomebouncycastles.co.uk, 1
 awesomesit.es, 1
 awf0.xyz, 1
 awk.tw, 1
 awksolutions.com, 1
@@ -4414,17 +4430,16 @@ aztraslochi.it, 1
 aztrix.me, 1
 azu-l.com, 1
 azu-l.jp, 1
 azuki.cloud, 1
 azurecrimson.com, 1
 azuriasky.com, 1
 azuriasky.net, 1
 azuxul.fr, 1
-azzag.co.uk, 1
 azzorti.com, 1
 azzurrapelletterie.it, 1
 b-b-law.com, 1
 b-boom.nl, 1
 b-cyclesshop.ch, 1
 b-entropy.com, 1
 b-freerobux.ga, 1
 b-landia.net, 1
@@ -4651,16 +4666,17 @@ bahnbonus-praemienwelt.de, 1
 bahnenimbild.de, 1
 bahnenimbild.eu, 1
 bahnhelden.de, 1
 bahninrotweissrot.at, 1
 bahnmagazine.de, 1
 baiduo.com, 1
 baifubao.com, 1
 baiker.info, 1
+bailakomigo.com.br, 1
 baildonbouncycastles.co.uk, 1
 baildonhottubs.co.uk, 1
 baileebee.com, 1
 bailonga.com, 1
 bairdzhang.com, 1
 baitulongbaycruises.com, 1
 baiyangliu.com, 1
 bajajfinserv.in, 1
@@ -4676,25 +4692,27 @@ bakersafari.co, 1
 bakeup.be, 1
 bakibal.com, 1
 bakim.li, 1
 bakingstone.com, 1
 bakkerinjebuurt.be, 1
 bakongcondo.com, 1
 balade-commune.ch, 1
 baladecommune.ch, 1
+balancascia.com.br, 1
 balance7.jp, 1
 balancedbrawl.net, 1
 balancenaturalhealthclinic.ca, 1
 balboa.io, 1
 balcaonet.com.br, 1
 balconnr.com, 1
 balconsverdun.com, 1
 balia.de, 1
 balicekzdravi.cz, 1
+balidesignshop.com.br, 1
 balikonos.cz, 1
 balinese.dating, 1
 balist.es, 1
 balivillassanur.com, 1
 baliyano.com, 1
 balkonien.org, 1
 ball-bizarr.de, 1
 ball.holdings, 1
@@ -4715,28 +4733,31 @@ balmofgilead.org.uk, 1
 balonmano.co, 1
 balslev.io, 1
 balticer.de, 1
 balticnetworks.com, 1
 bamahammer.com, 1
 bambambaby.com.br, 1
 bambooforest.nl, 1
 bamboorelay.com, 1
+bambumania.com.br, 1
 bamily.rocks, 1
 bamtoki.com, 1
 bananavapes.com, 1
 bananium.fr, 1
 banburybid.com, 1
 bancacrs.it, 1
+bancaolhares.com.br, 1
 bancobai.ao, 1
 bancoctt.pt, 1
 bancor.network, 1
 bandagastrica.es, 1
 bandally.net, 1
 bandarifamily.com, 1
+bandeira1.com.br, 1
 bandgap.io, 1
 bandiga.it, 1
 bandito.re, 1
 banes.ch, 1
 bangdream.ga, 1
 bangkok-dark-night.com, 1
 bangkok.dating, 1
 bangkokcity.de, 1
@@ -4750,16 +4771,17 @@ bank, 1
 bank.simple.com, 0
 bankbranchlocator.com, 1
 bankcardoffer.com, 1
 bankcircle.co.in, 1
 bankee.us, 1
 bankerbuch.de, 1
 bankersonline.com, 1
 banketbesteld.nl, 1
+bankfreeoffers.com, 1
 bankgradesecurity.com, 1
 bankin.com, 1
 bankinter.pt, 1
 bankio.se, 1
 bankitt.network, 1
 banknet.gov, 1
 bankofdenton.com, 1
 bankofrealty.review, 1
@@ -4802,17 +4824,16 @@ barcamp.koeln, 1
 barcel.com.mx, 1
 barclays.net, 1
 barcodeberlin.com, 1
 barcoderealty.com, 1
 bardes.org, 1
 bardiharborow.com, 1
 bardiharborow.tk, 1
 baresquare.com, 1
-barf-alarm.de, 1
 baripedia.org, 1
 baris-sagdic.com, 1
 bariseau-mottrie.be, 1
 barisi.me, 1
 bariskaragoz.nl, 1
 baristador.com, 1
 barkerjr.xyz, 1
 barlotta.net, 1
@@ -4824,16 +4845,17 @@ barprive.com, 1
 barqo.co, 1
 barracuda.blog, 1
 barracuda.com.tr, 1
 barrera.io, 1
 barriofut.com, 1
 barrydenicola.com, 1
 barryswebdesign.co.uk, 1
 bars.kh.ua, 1
+barsashop.com.br, 1
 barsil.de, 1
 barslecht.com, 1
 barslecht.nl, 1
 barss.io, 1
 bart-f.com, 1
 barta.me, 1
 bartel.ws, 1
 bartelt.name, 1
@@ -4891,27 +4913,27 @@ bat909.net, 1
 bat9vip.com, 1
 bat9vip.net, 1
 batcave.tech, 1
 batch.com, 1
 batfoundry.com, 1
 bati-alu.fr, 1
 batiburrillo.net, 1
 batipresta.ch, 1
+batistareisfloresonline.com.br, 1
 batlab.ch, 1
 batolis.com, 1
 batook.org, 1
 batschu.de, 1
 batten.eu.org, 1
 batterystaple.pw, 1
 battle-game.com, 1
 battleboxx.com, 0
 battleofthegridiron.com, 1
 batvip9.net, 1
-bauen-mit-ziegel.de, 1
 bauer.network, 1
 bauernmarkt-fernitz.at, 1
 baugeldspezi.de, 1
 baugemeinschaftbernstein.de, 1
 baumannfabrice.com, 1
 baur.de, 1
 bausep.de, 1
 baustils.com, 1
@@ -5039,16 +5061,17 @@ bealpha.pl, 1
 beamer-discount.de, 1
 beamitapp.com, 1
 beamstat.com, 1
 beanbagaa.com, 1
 beanbot.party, 1
 beanilla.com, 1
 beanjuice.me, 1
 beans-one.com, 0
+bearcosports.com.br, 1
 bearded.sexy, 1
 beardic.cn, 1
 bearingworks.com, 1
 beasel.biz, 1
 beastiejob.com, 1
 beastowner.li, 1
 beatfeld.de, 1
 beatnikbreaks.com, 1
@@ -5058,16 +5081,17 @@ beauty-hippie-schmuck.de, 1
 beauty-italy.ru, 1
 beauty24.de, 1
 beautybear.dk, 1
 beautyby.tv, 1
 beautyevent.fr, 1
 beautykat.ru, 1
 beaverdamautos.com, 1
 bebef.de, 1
+bebefofuxo.com.br, 1
 bebes.uno, 1
 bebest.gov, 1
 bebetrotteur.com, 1
 bebout.domains, 1
 bebout.pw, 1
 beccajoshwedding.com, 1
 beckenhamcastles.co.uk, 1
 beckerantiques.com, 1
@@ -5134,16 +5158,17 @@ beeswax-orgone.com, 1
 beetgroup.id, 1
 beethoveninlove.com, 1
 beetman.net, 1
 beeutifulparties.co.uk, 1
 beexfit.com, 1
 beezkneezcastles.co.uk, 1
 beeznest.com, 1
 befoodsafe.gov, 1
+beforesunrise.de, 1
 beforeyoueatoc.com, 1
 beframed.ch, 1
 befundonline.de, 1
 begabungsfoerderung.info, 1
 begbie.com, 1
 beginatzero.com, 1
 beginner.nl, 1
 beginwp.top, 1
@@ -5225,16 +5250,17 @@ benchstoolo.com, 1
 bencorby.com, 1
 bendemaree.com, 1
 bendigoland.com.au, 1
 bendingtheending.com, 1
 bendix.co, 1
 bendyworks.com, 1
 beneathvt.com, 1
 benedict-balzer.de, 1
+benepiscinas.com.br, 1
 beneri.se, 1
 benevisim.com, 1
 benevita.bio, 1
 benevita.life, 1
 benevita.live, 1
 benevita.organic, 1
 benfairclough.com, 1
 bengalurugifts.com, 1
@@ -5399,16 +5425,17 @@ best66.me, 1
 bestattungen-kammerer.de, 1
 bestattungshaus-kammerer.de, 1
 bestautoinsurance.com, 1
 bestbatteriesonline.com, 1
 bestbefore.com, 1
 bestbestbitcoin.com, 1
 bestbrakes.com, 1
 bestbridal.top, 1
+bestbyte.com.br, 1
 bestcellular.com, 0
 bestdating.today, 1
 bestelectricnd.com, 1
 bestellipticalmachinereview.info, 1
 bestemailmarketingsoftware.org, 1
 bestesb.com, 1
 bestesb.net, 1
 bestessaycheap.com, 1
@@ -5493,17 +5520,16 @@ betterweb.fr, 1
 betterworldinternational.org, 1
 bettflaschen.ch, 1
 bettingbusiness.ru, 1
 bettingsider.dk, 1
 bettolinokitchen.com, 1
 bettrlifeapp.com, 1
 betulashop.ch, 1
 betwalker.com, 1
-between.be, 1
 betwin9.com, 1
 betwin9.net, 1
 beulen.email, 1
 beulen.link, 1
 beulen.pro, 1
 beuteugeu.com, 1
 bevedo.cz, 1
 beveiligingscamerawestland.nl, 1
@@ -5536,16 +5562,18 @@ beyondtrust.com, 1
 beyondweb.net, 1
 beyonic.com, 1
 beyours.be, 1
 bez-energie.de, 1
 bezemkast.nl, 1
 bezoomnyville.com, 1
 bezpecnostsiti.cf, 1
 bezr.co.uk, 1
+bf7088.com, 1
+bf7877.com, 1
 bfam.tv, 1
 bfem.gov, 1
 bfgcdn.com, 1
 bfi.wien, 0
 bflix.tv, 1
 bforb.sk, 1
 bfpg.org, 1
 bfrailwayclub.cf, 1
@@ -5635,16 +5663,17 @@ bigbouncetheory.co.uk, 1
 bigbounceuk.com, 1
 bigcakes.dk, 1
 bigclassaction.com, 1
 bigdinosaur.org, 1
 bigerbio.com, 1
 biggreenexchange.com, 1
 bight.ca, 1
 bigideasnetwork.com, 1
+bigio.com.br, 1
 biglou.com, 0
 bignumworks.com, 1
 bigorbitgallery.org, 1
 bigserp.com, 1
 bigshort.org, 1
 bigsisterchannel.com, 1
 bigskylifestylerealestate.com, 1
 bigskymontanalandforsale.com, 1
@@ -5919,16 +5948,17 @@ bitsburg.ru, 1
 bitskins.co, 1
 bitskrieg.net, 1
 bitsoffreedom.nl, 1
 bitstep.ca, 1
 bitstorm.nl, 1
 bitstorm.org, 1
 bitsum.com, 1
 bitsync.nl, 1
+bitten.pw, 1
 bittersweetcandybowl.com, 1
 bittervault.xyz, 1
 bittylicious.com, 1
 bitvest.io, 1
 bitwolk.nl, 1
 bitwrought.net, 1
 bitxel.com.co, 1
 bityes.org, 1
@@ -6154,17 +6184,16 @@ bloginbeeld.nl, 1
 bloglines.co.za, 1
 bloglogistics.com, 1
 blogom.at, 1
 blogpentrusuflet.ro, 1
 blogreen.org, 1
 blogsdna.com, 1
 blogthedayaway.com, 1
 blogtroterzy.pl, 1
-blok56.nl, 1
 blokmy.com, 1
 blood4pets.tk, 1
 bloodsports.org, 1
 bloom-avenue.com, 1
 bltc.co.uk, 1
 bltc.com, 1
 bltc.net, 1
 bltc.org, 1
@@ -6297,16 +6326,17 @@ bodsch.com, 1
 bodybuilding.events, 1
 bodybuildingworld.com, 1
 bodyconshop.com, 1
 bodygearguide.com, 1
 bodymusclejournal.com, 1
 bodypainter.pl, 1
 bodypainting.waw.pl, 1
 bodyshopnews.net, 1
+bodyweb.com.br, 1
 bodyworkbymichael.com, 1
 boeddhashop.nl, 1
 boekenlegger.nl, 1
 boem.gov, 1
 boernecancerfonden.dk, 1
 bogdancornianu.com, 1
 bogdanepureanu.ro, 1
 bogner.sh, 1
@@ -6356,16 +6386,17 @@ bondoer.fr, 1
 bondpro.gov, 1
 bondskampeerder.nl, 1
 bonebunny.de, 1
 bonesserver.com, 1
 bonfi.net, 1
 bongo.cat, 1
 bonibuty.com, 1
 bonifacius.be, 1
+bonita.com.br, 1
 bonito.pl, 1
 bonnant-associes.ch, 1
 bonnant-partners.ch, 1
 bonnebouffe.fr, 1
 bonniecoloring.com, 1
 bonniedraw.com, 1
 bonnieradvocaten.nl, 1
 bonnsustainabilityportal.de, 1
@@ -6395,27 +6426,25 @@ bookingready.com, 1
 bookingslog.com, 1
 bookingworldspeakers.com, 1
 bookluk.com, 1
 bookmakersfreebets.com.au, 1
 bookmein.in, 1
 bookourdjs.com, 1
 bookreport.ga, 1
 booksearch.jp, 1
-bookshopofindia.com, 1
 booksinthefridge.at, 1
 booktracker-org.appspot.com, 1
 bookwitty.social, 1
 bool.be, 1
 boombv.com, 1
 boomersurf.com, 1
 boomshelf.com, 1
 boomshelf.org, 1
 boonbox.com, 1
-boonehenry.co.uk, 1
 booox.biz, 1
 booox.cc, 1
 booox.info, 1
 booox.net, 1
 booox.org, 1
 booox.pw, 1
 boop.gq, 1
 boop.pro, 1
@@ -6457,17 +6486,16 @@ bosabosa.org, 1
 boschee.net, 1
 boscoyacht.ch, 1
 boskeopolis-stories.com, 1
 boss.az, 1
 bostadsportal.se, 1
 bostonadvisors.com, 1
 bosufitness.cz, 1
 bosun.io, 1
-bosworthdental.co.uk, 1
 bot-manager.pl, 1
 botezdepoveste.ro, 1
 botguard.net, 1
 bothellwaygarage.net, 1
 botlab.ch, 1
 botmanager.pl, 1
 bots.cat, 1
 botserver.de, 1
@@ -6584,33 +6612,34 @@ bouncyfeet.co.uk, 1
 bouncygiggles.com.au, 1
 bouncyhigher.co.uk, 1
 bouncyhousecastlehire.co.uk, 1
 bouncyhouses.co.uk, 1
 bouncykingdom.co.uk, 1
 bouncykings.co.uk, 1
 bouncykingsnortheast.co.uk, 1
 bouncymacs.co.uk, 1
-bouncymadness.com, 1
 bouncyrainbows.co.uk, 1
 bouncytime.co.uk, 1
 bouncytown.co.uk, 1
 bouncywouncy.co.uk, 1
 bound2bounce.co.uk, 1
 boundarybrighton.com, 1
 bountyfactory.io, 1
 bourasse.fr, 1
 bourdon.fr.eu.org, 1
 bourgdepabos.com, 1
 bourhis.info, 1
 bournefun.co.uk, 1
 bourqu.in, 1
 bourse-aux-jouets.org, 0
 bourse-aux-vetements.org, 0
 bourse-puericulture.org, 0
+boutiquedecanetas.com.br, 1
+boutiquefutebol.com.br, 1
 boutiqueguenaelleverdin.com, 1
 bouw.live, 1
 bouzouada.com, 1
 bouzouks.net, 1
 bovenwebdesign.nl, 1
 bowdens.me, 1
 bowedwallcrackrepair.com, 1
 boweryandvine.com, 1
@@ -6719,16 +6748,17 @@ brandtrapselfie.nl, 1
 brandweerfraneker.nl, 1
 brandweertrainingen.nl, 1
 brandweeruitgeest.nl, 1
 brank.as, 1
 branw.xyz, 1
 brasal.ma, 1
 brasalcosmetics.com, 1
 brashear.me, 1
+brasilbombas.com.br, 1
 brasildxn.com.br, 1
 brasileiro.ca, 1
 brasserie-mino.fr, 1
 brasspipedreams.org, 1
 bratislava-airport-taxi.com, 1
 bratteng.me, 1
 bratteng.xyz, 1
 bratvanov.com, 1
@@ -6742,16 +6772,17 @@ brave-foods.ch, 1
 brave-foods.com, 1
 brave.com, 1
 bravebaby.com.au, 1
 bravehearts.org.au, 1
 braviskindenjeugd.nl, 1
 bravisziekenhuis.nl, 1
 brazenfol.io, 1
 brazilian.dating, 1
+brazillens.com, 1
 brck.nl, 1
 brd.ro, 1
 breadandlife.org, 1
 breadofgod.org, 1
 breakingtech.it, 1
 breakpoint.at, 1
 breaky.de, 1
 breathedreamgo.com, 1
@@ -6881,16 +6912,17 @@ brody.digital, 1
 brody.ninja, 1
 broersma.com, 1
 broerweb.nl, 1
 broeselei.at, 1
 brokenhands.io, 1
 brokenjoysticks.net, 1
 brokervalues.com, 1
 brompton-cocktail.com, 1
+bronetb2b.com.br, 1
 bronevichok.ru, 1
 bronwynlewis.com, 1
 broodbesteld.nl, 1
 brooke-fan.com, 1
 brookehatton.com, 0
 brookframework.org, 1
 brooklynrealestateblog.com, 1
 brookworth.com, 1
@@ -6980,16 +7012,17 @@ btc2secure.com, 1
 btcarmory.com, 1
 btcbolsa.com, 1
 btcontract.com, 1
 btcp.space, 1
 btcpop.co, 1
 btcycle.org, 1
 btio.pw, 1
 btku.org, 1
+btmstore.com.br, 1
 btnissanparts.com, 1
 btorrent.xyz, 1
 btrb.ml, 1
 btsapem.com, 1
 btsoft.eu, 1
 btsow.com, 1
 bttc.co.uk, 1
 btth.live, 1
@@ -7105,17 +7138,16 @@ bupropion.com, 1
 bupu.ml, 1
 buradangonder.com, 1
 burcevo.info, 1
 burfordbedandbreakfast.co.uk, 1
 burg-hohnstein.com, 1
 burgernet.nl, 1
 burgers.io, 1
 burghardt.pl, 1
-buri.be, 0
 burialinsurancenetwork.com, 1
 buricloud.fr, 1
 burke.services, 1
 burlapsac.ca, 1
 burncorp.org, 1
 burnerfitness.com, 1
 burnhamonseabouncycastles.co.uk, 1
 burningbird.net, 1
@@ -7179,30 +7211,34 @@ butteramotors.com, 1
 buttermilk.cf, 1
 buttonline.ch, 1
 buttonrun.com, 1
 buturyu.net, 1
 buurtgenotencollectief.nl, 1
 buurtpreventiefraneker.nl, 1
 buxum-communication.ch, 1
 buy-out.jp, 1
+buybike.shop, 1
 buycarpet.shop, 1
 buycbd.store, 1
+buycook.shop, 1
 buydissertations.com, 1
 buyebook.xyz, 1
 buyerdocs.com, 1
 buyessay.org, 1
 buyessays.net, 1
 buyharpoon.com, 1
 buyhealth.shop, 1
 buyinginvestmentproperty.com, 1
 buyingsellingflorida.com, 1
+buyjewel.shop, 1
 buymindhack.com, 1
 buypapercheap.net, 1
 buyplussize.shop, 1
+buyprofessional.shop, 1
 buyritefairview.com, 1
 buysellinvestproperties.com, 1
 buyseo.store, 1
 buyshoe.org, 1
 buytermpaper.com, 1
 buytheway.co.za, 1
 buywine.shop, 1
 buywood.shop, 1
@@ -7335,16 +7371,17 @@ cabinet-bedin.com, 1
 cabinetfurnituree.com, 1
 cablehighspeed.net, 1
 cablemod.com, 1
 cablesandkits.com, 1
 cabotfinancial.co.uk, 1
 cacao-chocolate.com, 1
 cacao.supply, 1
 cacaolalina.com, 1
+cacaumidade.com.br, 1
 caceis.bank, 1
 cachacacha.com, 1
 cachetagalong.com, 1
 cachethome.com, 1
 cachetur.no, 1
 cackette.com, 1
 cad-noerdlingen.de, 1
 cadacoon.com, 1
@@ -7472,16 +7509,17 @@ cambridge-security.com, 1
 cambridgebouncers.co.uk, 1
 cambridgesecuritygroup.org, 1
 camcapital.com, 1
 camconn.cc, 1
 camdesign.pl, 1
 camel2243.com, 1
 camelservers.com, 1
 cameo-membership.uk, 1
+cameraviva.com.br, 1
 camerweb.es, 1
 camilomodzz.net, 1
 camjobs.net, 1
 camolist.com, 1
 camomile.desi, 1
 camp-pleinsoleil.ch, 1
 camp.co.uk, 1
 campaign-ad.com, 1
@@ -7521,17 +7559,17 @@ canada-tourisme.ch, 1
 canadabread.com, 0
 canadalife.de, 1
 canadasmotorcycle.ca, 1
 canadian-nurse.com, 1
 canadian.dating, 1
 canadianchristianity.com, 0
 canadianoutdoorequipment.com, 1
 canadiantouristboard.com, 1
-canal-onanismo.org, 1
+canal-onanismo.org, 0
 canalsidehouse.be, 1
 canalsidehouse.com, 1
 canarymod.net, 1
 cancelmyprofile.com, 1
 cancerdata.nhs.uk, 1
 candaceplayforth.com, 1
 candeo-books.nl, 1
 candex.com, 1
@@ -7590,17 +7628,16 @@ capitalcollections.org.uk, 1
 capitalfps.com, 1
 capitalibre.com, 1
 capitalism.party, 1
 capitalmediaventures.co.uk, 1
 capitalp.jp, 1
 capitalquadatv.org.nz, 1
 capitolpathways.org, 1
 caplinbouncycastles.co.uk, 1
-capogna.com, 0
 capper.de, 1
 capriccio.to, 1
 caprichosdevicky.com, 1
 caps.is, 1
 capsogusto.com, 1
 capstansecurity.co.uk, 1
 capstansecurity.com, 1
 capstoneinsights.com, 1
@@ -7709,16 +7746,17 @@ carlot-j.com, 1
 carlovanwyk.com, 1
 carnaticalifornia.com, 1
 carnet-du-voyageur.com, 1
 carnildo.com, 1
 caroes.be, 1
 caroffer.ch, 1
 carol-lambert.com, 1
 carolcappelletti.com, 1
+carolcestas.com, 1
 caroli.biz, 1
 caroli.com, 1
 caroli.info, 1
 caroli.name, 1
 caroli.net, 1
 carolina.cz, 1
 carolinaclimatecontrolsc.com, 1
 carolynjoyce.com.au, 1
@@ -7731,32 +7769,32 @@ carredejardin.com, 1
 carrentalsathens.com, 1
 carriedin.com, 1
 carrierplatform.com, 1
 carringtonrealtygroup.com, 1
 carroattrezzimilanodaluiso.it, 1
 carrollservicecompany.com, 1
 carrosserie-dubois.com, 1
 carseatchecks.ca, 1
-carson-aviation-adventures.com, 1
 carson-matthews.co.uk, 1
 carsoug.com, 1
 carspneu.cz, 1
 cartadeviajes.cl, 1
 cartadeviajes.co, 1
 cartadeviajes.com, 1
 cartadeviajes.com.ar, 1
 cartadeviajes.com.ve, 1
 cartadeviajes.de, 1
 cartadeviajes.ec, 1
 cartadeviajes.es, 1
 cartadeviajes.fr, 1
 cartadeviajes.mx, 1
 cartadeviajes.pe, 1
 cartadeviajes.uk, 1
+carteirasedistintivos.com.br, 1
 cartelcircuit.com, 1
 carterorland.com, 1
 carterstad.se, 1
 cartertonscouts.org.nz, 1
 cartesentreprises-unicef.fr, 1
 carthedral.com, 1
 cartierplan.ga, 1
 carto.la, 1
@@ -7778,19 +7816,22 @@ casa-lunch-break.de, 1
 casa-lunchbreak.de, 1
 casa-mea-inteligenta.ro, 1
 casa-su.casa, 1
 casaanastasia.ro, 1
 casabouquet.com, 1
 casacameo.com, 0
 casacochecurro.com, 1
 casadasportasejanelas.com, 1
+casadoarbitro.com.br, 1
+casadowifi.com.br, 1
 casalindamex.com, 1
 casalunchbreak.de, 1
 casamariposaspi.com, 1
+casapalla.com.br, 1
 casasuara.com, 1
 casasuleletrodomesticos.com.br, 1
 casbia.info, 1
 casbuijs.nl, 1
 casburggraaf.com, 1
 casc.cz, 1
 cascadesjobcorpscca.com, 1
 cascavelle.fr, 1
@@ -8054,16 +8095,17 @@ centralmissourifoundationrepair.com, 1
 centralpoint.be, 0
 centralpoint.nl, 0
 centralstatecu.org, 1
 centralvoice.org, 1
 centrationgame.com, 1
 centredaccueil.fr, 1
 centreoeil.ch, 1
 centrobill.com, 1
+centrodoinstalador.com.br, 1
 centrojovencuenca.es, 1
 centromasterin.com, 1
 centroperugia.gr, 1
 centrosocialferrel.pt, 1
 centrumhodinek.cz, 1
 centruvechisv.ro, 1
 centrym.top, 1
 centum.no, 1
@@ -8115,16 +8157,17 @@ cervejista.com, 1
 cesantias.co, 1
 cesboard.com, 1
 cesdb.com, 1
 cesipagano.com, 1
 ceskepivnesety.sk, 1
 ceskepivnisety.cz, 1
 ceso-saco.com, 1
 cesobaly.cz, 1
+cestasedelicias.com.br, 1
 cestlav.it, 1
 cestunmetier.ch, 1
 cetamol.com, 1
 cetangarana.com, 1
 ceu.edu, 0
 cevo.com.hr, 1
 ceyizlikelisleri.com, 1
 cf-ide.de, 1
@@ -8213,17 +8256,16 @@ chanissue.com, 0
 channeladam.com, 1
 chanoyu-gakkai.jp, 1
 chanshiyu.com, 0
 chantalguggenbuhl.ch, 1
 chanz.com, 1
 chaos-games.org, 1
 chaos-inc.de, 1
 chaos.run, 1
-chaoscastles.co.uk, 1
 chaoschemnitz.de, 1
 chaosdorf.de, 1
 chaosfield.at, 1
 chaoslab.org, 1
 chaosriftgames.com, 1
 chaoswars.ddns.net, 1
 chaotichive.com, 1
 chaoticlaw.com, 1
@@ -8412,17 +8454,16 @@ chenzhipeng.com.cn, 1
 cheolguso.com, 1
 cherevoiture.com, 1
 cherie-belle.com, 1
 cherrett.digital, 1
 cherry-green.ch, 1
 cherryonit.com, 1
 cherrywoodtech.com, 1
 chertseybouncycastles.co.uk, 1
-cherysunzhang.com, 0
 chesapeakebaychristmas.com, 1
 chess.com, 1
 chessboardao.com, 1
 chesscoders.com, 1
 chesspoint.ch, 1
 chesterlestreetasc.co.uk, 1
 chestnut.cf, 1
 chevy37.com, 1
@@ -8510,18 +8551,20 @@ chloehorler.com, 1
 chloescastles.co.uk, 1
 chlth.com, 1
 chmielarz.it, 1
 chmsoft.com.ua, 1
 chmsoft.ru, 1
 chmurakotori.ml, 1
 choc-o-lush.co.uk, 1
 chocgu.com, 1
+chocodecor.com.br, 1
 chocolah.com.au, 0
 chocolat-suisse.ch, 1
+chocolate13tilias.com.br, 1
 chocolatesandhealth.com, 1
 chocolatier-tristan.ch, 1
 chocotough.nl, 1
 chocoweb.net, 1
 choe.fi, 1
 choiceautoloan.com, 1
 choisirmonerp.com, 1
 chokladfantasi.net, 1
@@ -8735,17 +8778,20 @@ circu.ml, 1
 circulatedigital.com, 1
 circule.cc, 1
 cirfi.com, 1
 ciri.com.co, 1
 cirope.com, 1
 cirrus0.de, 1
 cirugiasplasticas.com.mx, 1
 cirujanooral.com, 1
-ciscodude.net, 0
+cirurgicagervasio.com.br, 1
+cirurgicalucena.com.br, 1
+cirurgicasalutar.com.br, 1
+ciscodude.net, 1
 cisoaid.com, 1
 cisofy.com, 1
 cispeo.org, 1
 ciss.ltd, 1
 cisum-cycling.com, 1
 cisy.me, 1
 citationgurus.com, 1
 citcuit.in, 1
@@ -8754,16 +8800,17 @@ citimarinestore.com, 1
 citizensbankal.com, 1
 citizenscience.gov, 0
 citizenslasvegas.com, 1
 citizensleague.org, 1
 citizenspact.eu, 1
 citizing.org, 1
 citrusui.me, 1
 cittadesign.com, 0
+citton.com.br, 1
 city-adm.lviv.ua, 1
 city-walks.info, 1
 citya.com, 1
 citybeat.de, 1
 citylights.eu, 1
 citymoobel.ee, 1
 cityofeastpointemi.gov, 1
 cityoftitans.com, 1
@@ -8886,16 +8933,17 @@ cles.jp, 1
 clevelandokla.com, 1
 clevergod.net, 1
 clevertarget.ru, 1
 clevisto.com, 1
 cleysense.com, 1
 clic-et-site.com, 1
 clic-music.com, 1
 clicandfioul.com, 1
+clicecompre.com.br, 1
 clicheshishalounge.co.uk, 1
 click-licht.de, 1
 click4web.com, 1
 clickclock.cc, 1
 clickenergy.com.au, 1
 clickphish.com, 1
 clicksaveandprint.com, 1
 clien.net, 1
@@ -8915,17 +8963,16 @@ clinicaltrials.gov, 1
 clinicasmedicas.com.br, 1
 clinicminds.com, 1
 cliniquecomplementaire.com, 1
 cliniquevethuy.be, 1
 clintonbloodworth.com, 1
 clintonlibrary.gov, 1
 clintonplasticsurgery.com, 1
 clip.mx, 0
-clip.ovh, 0
 clipclip.com, 1
 clippings.com, 1
 clive.io, 1
 clmde.de, 1
 clnc.to, 1
 clnnet.ch, 1
 cloaked.ch, 1
 clochix.net, 1
@@ -9018,16 +9065,17 @@ club-is.ru, 1
 club-premiere.com, 1
 club-reduc.com, 1
 club-slow.jp, 1
 club-yy.com, 1
 club103.ch, 1
 clubcorsavenezuela.com, 1
 clubdelzapato.com, 1
 clubdeslecteurs.net, 1
+clubedalutashop.com, 1
 clubefiel.com.br, 1
 clubempleos.com, 1
 clubeohara.com, 1
 clubfamily.de, 1
 clubgalaxy.futbol, 1
 clubiconkenosha.com, 1
 clubmate.rocks, 1
 clubmini.jp, 1
@@ -9210,16 +9258,17 @@ codeversetech.com, 1
 codewild.de, 1
 codewiz.xyz, 1
 codexpo.net, 1
 codeyellow.nl, 1
 codific.com, 1
 codific.eu, 1
 codigo-bonus-bet.es, 1
 codigodelbonusbet365.com, 1
+codigosddd.com.br, 1
 codimaker.com, 1
 coding-minds.com, 1
 coding.lv, 1
 coding.net, 1
 codingforspeed.com, 1
 codingfromhell.net, 1
 codinginfinity.me, 1
 codingrobots.com, 1
@@ -9251,16 +9300,17 @@ coigach-assynt.org, 1
 coimmvest.com, 1
 coin-quest.net, 1
 coin.dance, 1
 coinapult.com, 1
 coinbase.com, 1
 coinbit.trade, 1
 coincealed.com, 1
 coinchat.im, 1
+coincoele.com.br, 1
 coincoin.eu.org, 1
 coincolors.co, 1
 coindatabase.net, 1
 coindeal.com, 1
 coinessa.com, 1
 coinf.it, 1
 coinflux.com, 1
 coingate.com, 1
@@ -9378,16 +9428,17 @@ comestoarra.com, 1
 cometbot.cf, 1
 cometcache.com, 1
 cometonovascotia.ca, 1
 comevius.com, 1
 comevius.org, 1
 comevius.xyz, 1
 comff.net, 1
 comfintouch.com, 1
+comflores.com.br, 1
 comfortmastersinsulation.com, 1
 comfypc.com, 1
 comhack.com, 1
 comicspornos.com, 1
 comicspornoxxx.com, 1
 comicwiki.dk, 1
 comidasperuanas.net, 1
 comiq.io, 1
@@ -9462,16 +9513,18 @@ complexsystems.fail, 1
 compliance-management.ch, 1
 compliance-systeme.de, 1
 compliancedictionary.com, 1
 compliancerisksoftware.co.uk, 1
 complt.xyz, 1
 compostatebien.com.ar, 1
 compoundingrxusa.com, 1
 compraneta.com, 0
+comprasoffie.com.br, 1
+compreautomacao.com.br, 1
 compree.com, 1
 comprefitasadere.com.br, 1
 comprehensiveihc.com, 1
 compromised.com, 1
 compservice.in.ua, 1
 comptrollerofthecurrency.gov, 1
 comptu.com, 1
 compubench.com, 1
@@ -9504,24 +9557,26 @@ concept-web.ch, 1
 conceptatelier.de, 1
 conception.sk, 1
 concertengine.com, 1
 concerto.amsterdam, 1
 concertsenboite.fr, 1
 concertsto.com, 1
 conciliumnotaire.ca, 1
 conclave.global, 1
+conclinica.com.br, 1
 concordsoftwareleasing.com, 1
 concretehermit.com, 0
 concretelevelingsystems.com, 1
 concreterepairatlanta.com, 1
 concursopublico.com.br, 1
 concursos.com.br, 1
 concursosabertos.com.br, 1
 concursuri.biz, 1
+condecom.com.br, 1
 condepenalba.com, 0
 condesaelectronics.com, 1
 condolencemessages.net, 1
 condominioweb.com, 1
 condosforcash.com, 1
 condroz-motors.be, 1
 conectadev.com, 1
 conectar.ru, 1
@@ -9532,16 +9587,17 @@ conejovalleyexteriorlighting.com, 1
 conejovalleylandscapelighting.com, 1
 conejovalleylighting.com, 1
 conejovalleyoutdoorlighting.com, 1
 conexiontransporte.com, 1
 confiancefoundation.org, 1
 confidential.network, 1
 config.schokokeks.org, 0
 confiwall.de, 1
+conformax.com.br, 1
 conformist.jp, 1
 confucio.cl, 1
 congineer.com, 1
 congobunkering.com, 1
 conju.cat, 1
 conjugacao.com.br, 1
 conkret.ch, 1
 conkret.co.uk, 1
@@ -9637,16 +9693,17 @@ continuum.memorial, 1
 contrabass.net, 1
 contractdigital.co.uk, 1
 contractormountain.com, 1
 contractwriters.com, 1
 contraspin.co.nz, 1
 contratatupoliza.com, 1
 contributor.google.com, 1
 controlarlaansiedad.com, 1
+controlautocom.com.br, 1
 controlbooth.com, 1
 controle.net, 1
 controleer-maar-een-ander.nl, 1
 controltickets.com.br, 1
 conv2pdf.com, 1
 convergence.fi, 1
 convergencela.com, 1
 convergnce.com, 1
@@ -9799,16 +9856,17 @@ cosasque.com, 1
 cosciamoos.com, 1
 cosirex.com, 1
 coslinker.com, 1
 cosmechic.fr, 1
 cosmekaitori.jp, 1
 cosmeticappraisal.com, 1
 cosmeticasimple.com, 1
 cosmeticos-naturales.com, 1
+cosmeticosdelivery.com.br, 1
 cosmiatria.pe, 1
 cosmic-os.org, 1
 cosmicnavigator.com, 1
 cosmodacollection.com, 1
 cosmofunnel.com, 1
 cosmundi.de, 1
 cosni.co, 1
 cosplayer.com, 1
@@ -9848,16 +9906,17 @@ countryfrog.uk, 1
 countryhouseresort.com, 1
 countybankdel.com, 1
 countyjailinmatesearch.com, 1
 coup-dun-soir.ch, 1
 coupe-bordure.com, 1
 couponcodesme.com, 1
 cour4g3.me, 1
 couragefound.org, 1
+coursables.com, 1
 course.rs, 1
 coursera.org, 1
 courses.nl, 1
 courseworkbank.info, 1
 courtlistener.com, 1
 couscous.recipes, 1
 cousincouples.com, 0
 coussinsky.net, 1
@@ -10010,16 +10069,17 @@ creato.top, 1
 creators-design.com, 1
 creators.co, 1
 creators.direct, 1
 creatujoya.com, 1
 credential.eu, 1
 credex.bg, 1
 credigo.se, 1
 crediteo.pl, 1
+creditkarma.com, 1
 creditos-rapidos.com, 1
 creditproautos.com, 0
 creditscoretalk.com, 1
 creditta.com, 1
 credittoken.io, 1
 creeks-coworking.com, 1
 creep.im, 1
 creepycraft.nl, 1
@@ -10036,16 +10096,17 @@ crescent.gr.jp, 1
 crestasantos.com, 1
 cretdupuy.com, 1
 creteangle.com, 1
 cretica.no, 1
 creusalp.ch, 1
 crew505.org, 1
 crgalvin.com, 1
 crgm.net, 1
+criadorespet.com.br, 1
 cribcore.com, 1
 crickey.eu, 1
 criena.com, 1
 criena.net, 1
 crimefreeliving.com, 1
 crimesolutions.gov, 1
 crimevictims.gov, 1
 criminal-attorney.ru, 1
@@ -10061,16 +10122,17 @@ crisp.email, 1
 crisp.help, 1
 crisp.im, 1
 crisp.watch, 1
 crispinusphotography.com, 1
 cristarta.com, 1
 cristau.org, 1
 cristiandeluxe.com, 0
 cristianhares.com, 1
+critcola.com, 1
 critical.today, 0
 criticalaim.com, 1
 criticalsurveys.co.uk, 1
 crizin.io, 1
 crl-autos.com, 1
 crm.onlime.ch, 0
 crm114d.com, 1
 crochetnerd.com, 1
@@ -10116,16 +10178,17 @@ crownmarqueehire.co.uk, 1
 crownpoint.com, 1
 crows.io, 1
 crox.co, 1
 croydonapartments.com.au, 1
 croydonbouncycastles.co.uk, 1
 crrev.com, 1
 crsmsodry.cz, 1
 crstat.ru, 1
+crt.cloud, 1
 crt.sh, 1
 crt2014-2024review.gov, 1
 crumbcontrol.com, 1
 crunchrapps.com, 1
 crunchy.rocks, 1
 crustytoothpaste.net, 1
 crute.me, 1
 cruzadobalcazarabogados.com, 1
@@ -10272,16 +10335,18 @@ cubing.net, 1
 cublick.com, 1
 cubos.io, 0
 cubostecnologia.com, 0
 cubostecnologia.com.br, 0
 cubua.com, 1
 cuckoopalace.cn, 1
 cuddlecomfort.com, 1
 cuddlingyaks.com, 1
+cueca.com.br, 1
+cuecasonline.com.br, 1
 cuentasmutualamr.org.ar, 1
 cuetoems.com, 1
 cuibonobo.com, 1
 cuisinezest.com, 1
 cultiv.nl, 1
 cultivo.bio, 1
 cultofd50.org, 1
 cultofperf.org.uk, 1
@@ -10380,17 +10445,16 @@ cvcoders.com, 1
 cve-le-carrousel.ch, 1
 cviip.ca, 1
 cviip.com, 1
 cvjd.me, 1
 cvl.ch, 1
 cvlibrary.co.uk, 1
 cvmu.jp, 1
 cvninja.pl, 1
-cvps.top, 1
 cvr.dk, 1
 cvursache.com, 1
 cvv.cn, 1
 cw-bw.de, 0
 cw.center, 1
 cwagner.me, 1
 cwbrtrust.ca, 1
 cwgaming.co.uk, 1
@@ -10610,16 +10674,17 @@ daiyuu.jp, 1
 dajiadu.net, 1
 dak.org, 1
 daknob.net, 1
 daktarisys.com, 1
 daladubbeln.se, 1
 dalaran.city, 1
 dalb.in, 1
 dale-electric.com, 1
+dalek.co.nz, 1
 dalepresencia.com, 1
 dalfsennet.nl, 1
 dalingk.com, 1
 dallaslu.com, 1
 dallinbryce.com, 1
 dallmeier.net, 1
 dalmatiersheusden.be, 1
 daltonedwards.me, 1
@@ -10755,16 +10820,17 @@ dapps.earth, 1
 dappworld.com, 1
 daracokorilo.com, 1
 daravk.ch, 1
 darbi.org, 1
 darbtech.net, 1
 darc-mak.de, 1
 darchoods.net, 0
 darcymarshall.com, 1
+daren.com.br, 1
 dareyou.be, 1
 dariaburger.de, 1
 darinjohnson.ca, 0
 darinkotter.com, 1
 darioackermann.ch, 1
 darioclip.com, 1
 dariosirangelo.me, 1
 darioturchetti.me, 1
@@ -10854,17 +10920,16 @@ dataharvest.at, 1
 datahoarder.xyz, 1
 datahove.no, 0
 datajobs.ai, 1
 datakick.org, 1
 datalife.gr, 1
 datalysis.ch, 1
 datamatic.ru, 1
 dataprotectionadvisors.com, 1
-datapun.ch, 1
 datapure.net, 1
 datascience.cafe, 1
 datascience.ch, 1
 datascomemorativas.com.br, 1
 datasharesystem.com, 1
 dataskydd.net, 1
 dataspace.pl, 1
 datastream.re, 0
@@ -11007,16 +11072,17 @@ dc-elektro.de, 1
 dc-elektro.eu, 1
 dc-occasies.be, 1
 dc-solution.de, 0
 dc1.com.br, 1
 dc562.org, 1
 dc585.info, 1
 dcain.me, 1
 dcards.in.th, 1
+dcautomacao.com.br, 1
 dcbouncycastles.co.uk, 1
 dcc.cat, 1
 dcc.moe, 1
 dccommunity.de, 1
 dcepler.net, 1
 dchatelain.ch, 1
 dchest.org, 1
 dckd.nl, 1
@@ -11125,16 +11191,17 @@ decodeanddestroy.com, 1
 decoder.link, 1
 decompiled.de, 1
 decoora.com, 1
 decor-d.com, 1
 decoratingadvice.co.uk, 1
 decoratore.roma.it, 1
 decoratrix.com, 1
 decorauvent.ca, 1
+decorestilo.com.br, 1
 decorincasa.com.br, 1
 decormiernissanparts.com, 1
 decosoftware.com, 1
 decoyrouting.com, 1
 decrousaz-ceramique.ch, 1
 decs.es, 1
 decstasy.de, 1
 dede.ml, 1
@@ -11159,17 +11226,16 @@ deepbluecrafting.co.uk, 1
 deepblueemail.com, 1
 deepcode.io, 1
 deepcreampie.com, 1
 deeperxh.com, 1
 deephill.com, 1
 deepinsight.io, 1
 deeps.cat, 1
 deepserve.info, 1
-deepsouthsounds.com, 1
 deepspace.dedyn.io, 1
 deepvalley.tech, 1
 deepwealth.institute, 1
 deepz.pt, 1
 deer.team, 1
 deezeno.com, 1
 def-pos.ru, 1
 defcon.org, 1
@@ -11201,17 +11267,16 @@ degeberg.dk, 1
 degen-elektrotechnik.de, 1
 degestamptepot.nl, 1
 degosoft.nl, 1
 degoulet.net, 1
 degraafschapdierenartsen.nl, 1
 degracetechnologie.com, 1
 degressif.com, 1
 dehopre.com, 1
-dehydrated.de, 1
 deidee.nl, 1
 deinballon.de, 1
 deinewebsite.de, 1
 deinfoto.ch, 1
 deinserverhost.de, 1
 deitti.net, 1
 dejandayoff.com, 1
 dejure.org, 1
@@ -11221,17 +11286,16 @@ dekeurslagers.nl, 1
 dekka.cz, 1
 dekkercreativedesign.nl, 1
 dekko.io, 1
 dekoh-shouyu.com, 1
 dekonix.ru, 1
 dekulk.nl, 1
 delahrzolder.nl, 1
 delbecqvo.be, 1
-delbrouck.ch, 1
 delcopa.gov, 1
 deleidscheflesch.nl, 1
 delfic.org, 1
 delfino.cr, 1
 delhionlinegifts.com, 1
 deliacreates.com, 1
 deliandiver.org, 1
 deliberatedigital.com, 1
@@ -11316,17 +11380,16 @@ dentrassi.de, 1
 dentystabirmingham.co.uk, 1
 denwauranailab.com, 1
 deontology.com, 1
 depaddestoeltjes.be, 1
 depannage-traceur.fr, 1
 deparis.me, 1
 depechemode-live.com, 1
 depedshs.com, 1
-depedtayo.com, 1
 depedtayo.ph, 1
 depicus.com, 1
 depone.net, 1
 depot-leipzig.de, 1
 depotsquarekerrville.com, 1
 depotter-usedcars.be, 1
 deprecate.de, 1
 deprobe.pro, 1
@@ -11670,17 +11733,16 @@ diegelernten.de, 1
 diegerbers.de, 1
 diegobarrosmaia.com.br, 1
 diegogelin.com, 1
 diegorbaquero.com, 1
 diehl.io, 1
 diekperaiwseis.gr, 1
 diem-project.org, 1
 diemattels.at, 1
-diemogebhardt.com, 1
 dienchaninstitute.com, 1
 dienstplan.cc, 1
 dienstplan.one, 1
 dierenartsdeconinck.be, 1
 dieselanimals.lt, 1
 dieselgalleri.com, 1
 dieser.me, 1
 diesteppenreiter.de, 1
@@ -11700,16 +11762,17 @@ different.cz, 0
 differenta.ro, 0
 diffnow.com, 1
 difoosion.com, 1
 digcit.org, 1
 digdata.de, 1
 dighans.com, 1
 digiarc.net, 1
 digibild.ch, 1
+digibull.email, 1
 digibull.link, 1
 digicert-support.com, 1
 digicert.nl, 1
 digicy.cloud, 1
 digideli.ee, 1
 digidroom.be, 1
 digikol.net, 1
 digilicious.com, 1
@@ -11782,18 +11845,20 @@ diju.ch, 1
 dildoexperten.se, 1
 diletec.com.br, 1
 dilichen.fr, 1
 diligo.ch, 1
 dillewijnzwapak.nl, 1
 dillonkorman.com, 1
 diluv.com, 1
 dimanss47.net, 1
+dimdom.com.br, 1
 dime-staging.com, 1
 dime.io, 1
+dimeponline.com.br, 1
 dimeshop.nl, 1
 dimez.ru, 1
 dimiskovska.de, 1
 dimitrihomes.com, 1
 dimmersagourahills.com, 1
 dimmerscalabasas.com, 1
 dimmersdosvientos.com, 1
 dimmershiddenhills.com, 1
@@ -11847,16 +11912,17 @@ directorioz.com, 1
 directreal.sk, 1
 directspa.fr, 1
 directtwo.solutions, 1
 directtwosolutions.org, 0
 direktvermarktung-schmitzberger.at, 1
 direwolfsoftware.ca, 1
 dirips.com, 1
 dirk-scheele.de, 1
+dirk-weise.de, 0
 dirkdoering.de, 1
 dirkjonker.nl, 1
 dirko.net, 1
 dirkwolf.de, 1
 dirtcraft.ca, 1
 dirtycat.ru, 1
 dirtygeek.ovh, 1
 dirtyincest.com, 1
@@ -11944,16 +12010,17 @@ dissertationhelp.com, 1
 dissidence.ovh, 1
 dissident.host, 1
 dist.torproject.org, 0
 disti.com, 1
 distiduffer.org, 1
 distillery.com, 1
 distinctivephotography.com.au, 1
 distinguishedprisoner.com, 1
+distribuidoracristal.com.br, 1
 distribuidoraplus.com, 1
 distribuidorveterinario.es, 1
 distrilogservices.com, 1
 distro.re, 1
 ditch.ch, 1
 ditelbat.com, 1
 diti.me, 1
 ditisabc.nl, 1
@@ -11964,16 +12031,17 @@ dive-japan.com, 1
 divedowntown.com, 1
 divegearexpress.com, 1
 diveidc.com, 1
 diveplan.org, 1
 divergenz.org, 1
 diversityflags.com, 1
 diversityflags.com.au, 1
 diversityflags.nz, 1
+divertiagua.com.br, 1
 divi-experte.de, 1
 divinasaiamodas.com.br, 1
 divinegames.studio, 1
 divinemercyparishvld.com, 1
 divinemercyparishvlds.com, 1
 diving.photo, 1
 divingwithnic.com, 1
 divorcelawyersformen.com, 1
@@ -12071,28 +12139,30 @@ dnacloud.pl, 1
 dnakids.co.uk, 1
 dnc.org.nz, 1
 dndesign.be, 1
 dndtools.net, 1
 dne.lu, 1
 dnfc.rocks, 1
 dnlr.tech, 1
 dnmaze.com, 1
+dnmlab.it, 1
 dnplegal.com, 1
 dns-control.eu, 1
 dns-swiss.ch, 1
 dns.google.com, 1
 dns8.online, 1
 dnsbird.org, 1
 dnscrawler.com, 1
 dnscrypt.info, 1
 dnscrypt.nl, 1
 dnscurve.io, 1
 dnshallinta.fi, 1
 dnsinfo.ml, 1
+dnsipv6.srv.br, 1
 dnslog.com, 1
 dnsman.se, 1
 dnspod.ml, 1
 dnsql.io, 1
 dnstwister.report, 1
 dnzz123.com, 1
 do-it.cz, 1
 do-prod.com, 1
@@ -12157,16 +12227,17 @@ dogfi.sh, 1
 dogft.com, 1
 doggedbyirs.com, 1
 doggroomingcourse.com, 1
 dogmap.jp, 1
 dogoo.com, 1
 dogpawstudio.com, 1
 dogprograms.net, 1
 dogrescuegreece.nl, 1
+dogworld.com.br, 1
 dohanews.co, 1
 doihavetoputonpants.com, 1
 doitauto.de, 1
 dojifish.space, 1
 dojin.nagoya, 1
 dojozendebourges.fr, 1
 dokan-e.com, 0
 dokelio-idf.fr, 1
@@ -12207,17 +12278,17 @@ domains.motorcycles, 1
 domains.yachts, 1
 domainsilk.com, 1
 domainspeicher.one, 1
 domainstaff.com, 1
 domainwatch.me, 1
 domakidis.com, 1
 domaxpoker.com, 1
 domeconseil.fr, 1
-domein-direct.nl, 1
+domein-direct.nl, 0
 domen-reg.ru, 1
 domenic.me, 1
 domenicam.com, 1
 domesticcleaners.co.uk, 1
 domfee.com, 1
 domhaase.me, 1
 domian.cz, 1
 dominationgame.co.uk, 1
@@ -12226,25 +12297,26 @@ dominik-schlueter.de, 1
 dominikaner-vechta.de, 1
 dominikkulaga.pl, 1
 dominioanimal.com.br, 1
 dominionregistries.domains, 1
 dominique-haas.fr, 1
 dominoknihy.cz, 1
 dominomatrix.com, 1
 domix.fun, 1
+dommascate.com.br, 1
 domob.eu, 1
 domodeco.fr, 1
 domodedovo.travel, 1
 domprojects.com, 1
+domquixoteepi.com.br, 1
 domscripting.com, 1
 domster.com, 1
 domus-global.com, 1
 domus-global.cz, 1
-domwkwiatach.pl, 1
 domyassignments.com, 1
 domycasestudy.com, 1
 domycoursework.com, 1
 domycreativewritings.com, 1
 domydissertations.com, 1
 domyessay.net, 1
 domyessays.com, 1
 domyhomeworks.net, 1
@@ -12322,16 +12394,17 @@ dormiu.com, 1
 dormiu.com.br, 1
 dornhecker.me, 1
 dorpshuis-dwarsgracht.nl, 1
 dorpshuiskesteren.nl, 1
 dorquelle.com, 1
 dorsetentertainments.co.uk, 1
 dorth.nl, 1
 dosdediez.com, 1
+dosenbierrepublik.com, 1
 dosenkiwi.at, 1
 dosipe.com, 1
 doska.by, 1
 doska.kz, 1
 doska.ru, 1
 dosomeworks.biz, 1
 dossplumbing.co.za, 1
 dostalsecurity.com, 1
@@ -12582,17 +12655,17 @@ driverscollection.com, 1
 driving-lessons.co.uk, 1
 drivinghorror.com, 1
 drivingtestpro.com, 1
 drivinhors.com, 1
 drivya.com, 1
 drixn.cn, 1
 drixn.info, 1
 drixn.net, 1
-drizz.com.br, 1
+drizz.com.br, 0
 drjacquesmalan.com, 1
 drjenafernandez.com, 1
 drjoe.ca, 1
 drjuanitacollier.com, 0
 drjulianneil.com, 1
 drkhsh.at, 0
 drkmtrx.xyz, 1
 drlandis.com, 1
@@ -12681,31 +12754,31 @@ dsebastien.net, 1
 dsektionen.se, 0
 dsgarms.com, 1
 dsgholsters.com, 1
 dsgnet.hu, 1
 dsgvo.name, 1
 dshield.org, 1
 dsm5.com, 1
 dsmjs.com, 1
-dsne.com.mx, 1
 dso-imaging.co.uk, 1
 dso-izlake.si, 1
 dsol.hu, 1
 dsouzamusic.com, 1
 dsrw.org, 1
 dssale.com, 1
 dstamou.de, 1
 dsteiner.at, 1
 dstvinstallalberton.co.za, 1
 dstvinstallrandburg.co.za, 1
 dt27.org, 1
 dtbouncycastles.co.uk, 1
 dtdsh.com, 1
 dte.co.uk, 1
+dtechstore.com.br, 1
 dtg-fonds.com, 1
 dtg-fonds.de, 1
 dtg-fonds.net, 1
 dtk-vom-chausseehaus.de, 1
 dtnx.net, 1
 dtoweb.be, 1
 dtp-mstdn.jp, 0
 dtpak.cz, 1
@@ -12814,17 +12887,16 @@ dusnan.com, 1
 dustplanet.de, 1
 dustri.org, 1
 dustycloth.com, 1
 dustygroove.com, 1
 dustyspokesbnb.ca, 1
 dutch.desi, 1
 dutch1.nl, 1
 dutchdare.nl, 1
-dutchessuganda.com, 1
 dutchforkrunners.com, 1
 dutchrank.nl, 1
 dutchwanderers.nl, 1
 dutchweballiance.nl, 1
 duval.paris, 1
 dv189.com, 1
 dvbris.co.uk, 1
 dvbris.com, 1
@@ -12863,17 +12935,16 @@ dyeager.org, 1
 dyktig.as, 1
 dyktig.no, 1
 dylanboudro.com, 1
 dylancl.cf, 1
 dylankatz.com, 1
 dylanknoll.ca, 1
 dylanspcrepairs.com, 1
 dylanwise.net, 1
-dylmye.me, 1
 dym.asia, 1
 dym.bz, 1
 dym2012.com, 1
 dym2013.com, 1
 dym2014.com, 1
 dym2017.com, 1
 dymersion.com, 1
 dymfbbs.com, 1
@@ -12918,22 +12989,24 @@ dzndk.com, 1
 dzndk.net, 1
 dzndk.org, 1
 dznn.nl, 1
 dzomo.org, 1
 dzsibi.com, 1
 dzsula.hu, 1
 dzyabchenko.com, 1
 dzyszla.pl, 1
+e-apack.com.br, 1
 e-baraxolka.ru, 1
 e-bikesdirect.co.uk, 1
 e-biografias.net, 1
 e-borneoshop.com, 1
 e-briancon.com, 1
 e-colle.info, 1
+e-cottage.com.br, 1
 e-enterprise.gov, 1
 e-hon.link, 1
 e-id.ee, 1
 e-kontakti.fi, 1
 e-lambre.com, 1
 e-learningbs.com, 1
 e-lifetechnology.com, 1
 e-mak.eu, 1
@@ -13081,17 +13154,16 @@ ebenvloedaanleggen.nl, 1
 ebermannstadt.de, 0
 eberwe.in, 1
 ebest.co.jp, 1
 ebiebievidence.com, 1
 ebiografia.com, 1
 ebisi.be, 1
 ebizarts.com, 1
 eboek.info, 1
-ebonyporn.tv, 1
 ebonyriddle.com, 1
 ebooki.eu.org, 1
 ebooklaunchers.com, 1
 ebop.ch, 1
 eboutic.ch, 1
 eboyer.com, 1
 ebpglobal.com, 0
 ebrnd.de, 1
@@ -13107,16 +13179,17 @@ ecardoo.net, 1
 ecardoo.org, 1
 ecchidreams.com, 1
 ecclesia-koeln.de, 1
 ecco-verde.com, 0
 eccoviasolutions.com, 1
 eccux.com, 1
 ecdn.cz, 1
 ecelembrou.ovh, 1
+ecfnorte.com.br, 1
 echatta.net, 1
 echatta.org, 1
 echidna-rocktools.eu, 1
 echo-security.co, 1
 echo.cc, 1
 echoanalytics.com, 1
 echobridgepartners.com, 1
 echodio.com, 1
@@ -13160,16 +13233,17 @@ ecogen.net.au, 1
 ecoheatcool.co.uk, 1
 ecohostingservices.uk, 1
 ecolala.my, 1
 ecole-attalens.ch, 1
 ecole-iaf.fr, 1
 ecoledusabbat.org, 1
 ecolemathurincordier.com, 1
 ecombustibil.ro, 1
+ecommercestore.net.br, 1
 ecompen.co.za, 1
 ecomycie.com, 1
 econativa.pt, 1
 economias.pt, 1
 economic-sanctions.com, 1
 economicinclusion.gov, 1
 economics-colleges.com, 1
 economiefidu.ch, 1
@@ -13251,16 +13325,17 @@ edsm.net, 1
 edstep.com, 1
 edtech-hub.com, 1
 edtechwebb.com, 1
 edu-kingdom.com, 1
 edu6.cloud, 1
 eduard-dopler.de, 1
 eduardnikolenko.com, 1
 eduardnikolenko.ru, 1
+edubras.com.br, 1
 educationevolving.org, 1
 educationfutures.com, 1
 educationunlimited.com, 1
 educator-one.com, 1
 educatoys.com.br, 1
 eductf.org, 1
 eduid.se, 0
 eduif.nl, 0
@@ -13656,17 +13731,16 @@ elinvention.ovh, 1
 eliolita.com, 1
 eliott.be, 0
 elisa.ee, 0
 elisabeth-kostecki.de, 1
 elisabeth-strunz.de, 1
 elisabethkostecki.de, 1
 elisabethrene.com, 1
 elisechristie.com, 1
-elistor6100.xyz, 1
 elite-porno.ru, 1
 elite12.de, 1
 elitebouncingfun.com, 1
 elitegameservers.net, 1
 elitehosting.de, 0
 elitenutritionoficial.com, 1
 elixi.re, 1
 elixir.bzh, 1
@@ -13720,16 +13794,17 @@ elternbeiratswahl.online, 1
 elternforum-birmensdorf.ch, 1
 elternverein-utzenstorf.ch, 1
 eltip.click, 1
 eltlaw.com, 1
 eltransportquevolem.org, 1
 elucron.com, 1
 eluft.de, 1
 eluhome.de, 1
+eluvio.com, 1
 elvcino.com, 1
 elvidence.com.au, 1
 elviraszabo.com, 1
 elvispresley.net, 1
 elvisripley.com, 1
 elvn.tokyo, 1
 elwave.org, 1
 elwix.com, 1
@@ -13823,16 +13898,20 @@ empese.com, 1
 empherino.net, 1
 empire24.co, 1
 empireauto-2000.com, 1
 emploi-collectivites.fr, 1
 employeeexpress.gov, 1
 employer.gov, 1
 employer.guru, 1
 employer411.com, 1
+emporiodascalcinhas.com.br, 1
+emporiodosperfumes.com.br, 1
+emporioonline.com.br, 1
+emporiopatanegra.com.br, 1
 emporioviverbem.com.br, 0
 empower.net, 1
 empowerdb.com, 1
 emprego.pt, 1
 empyrean-advisors.com, 1
 emrenovation.com, 1
 emresaglam.com, 1
 emtradingacademy.com, 1
@@ -14091,21 +14170,22 @@ epublibre.org, 1
 epyonsuniverse.net, 1
 eq-serve.com, 1
 eqorg.com, 1
 equalcloud.com, 1
 equallyy.com, 1
 equalparts.eu, 1
 equeim.ru, 1
 equidam.com, 1
-equilime.com, 1
 equinecoaching.ca, 1
 equinetherapy.ca, 1
 equinox.io, 1
+equipandoloja.net.br, 1
 equipedefrance.tv, 1
+equipeferramentas.com.br, 1
 equk.co.uk, 1
 er-mgmt.com, 1
 er-music.com, 1
 er.tl, 1
 er1s.xyz, 1
 erad.fr, 1
 erasmusplusrooms.com, 1
 erate.fi, 1
@@ -14116,16 +14196,18 @@ ereader.uno, 1
 erecciontotalal100.com, 1
 erectiepillenwinkel.nl, 1
 erethon.com, 1
 erf-neuilly.com, 1
 ergo-open.de, 1
 ergobyte.eu, 1
 ergobyte.gr, 1
 ergodark.com, 1
+ergovita.com.br, 1
+ergovitanet.com.br, 1
 eriador.io, 1
 ericabrahamsen.net, 1
 ericairwin.com, 1
 ericdiao.com, 1
 erichogue.ca, 1
 erichorstmanshof.nl, 1
 ericisaweso.me, 1
 ericjohnltd.com, 1
@@ -14426,19 +14508,21 @@ estaleiro.org, 1
 estan.cn, 1
 estate360.co.tz, 1
 estateczech-eu.ru, 1
 estcequejailaflemme.fr, 1
 estcequonmetenprodaujourdhui.info, 1
 esteam.se, 1
 estedafah.com, 1
 esterilizacion-perros.es, 1
+esteticanorte.com.br, 1
 estetista.net, 1
 estherlew.is, 1
 esthesoleil.jp, 1
+estilopack-loja.com.br, 1
 estoic.net, 1
 estoniantrade.ee, 1
 estonoentraenelexamen.com, 1
 estoqueinformatica.com.br, 1
 estrietoit.com, 0
 estudiarparaser.com, 1
 estudio21pattern.com, 0
 estudiserradal.com, 1
@@ -14664,16 +14748,17 @@ everythingstech.com, 1
 everytrycounts.gov, 1
 everywhere.cloud, 1
 eveshaiwu.com, 1
 eveshamglass.co.uk, 1
 eveswell.com, 1
 evexia.xyz, 1
 evidence-based.review, 1
 evidencebased.net, 1
+evidenceusa.com.br, 1
 evidencija.ba, 1
 evidentiasoftware.com, 1
 evilarmy.com, 1
 evilbeasts.ru, 1
 evilbunnyfufu.com, 1
 evilcult.me, 1
 evileden.com, 1
 evilized.de, 1
@@ -14743,16 +14828,17 @@ excentos.com, 1
 exceptionalbits.com, 1
 exceptionalservers.com, 1
 exceptionalservices.us, 1
 excessamerica.com, 1
 excesssecurity.com, 1
 exchangecoordinator.com, 1
 exchaser.com, 1
 exclusivebouncycastles.co.uk, 1
+exclusivecarcare.co.uk, 1
 exclusivedesignz.com, 1
 exdamo.de, 0
 exe-boss.tech, 1
 execution.biz.tr, 1
 exehack.net, 1
 exeintel.com, 1
 exekutori.com, 1
 exemples-de-stands.com, 1
@@ -14794,16 +14880,17 @@ expert.cz, 1
 experteasy.com.au, 1
 expertofficefitouts.com.au, 1
 expertohomestaging.com, 1
 expertsverts.com, 1
 expertvagabond.com, 1
 expertviolinteacher.com, 1
 expiscor.solutions, 1
 explodie.org, 1
+exploflex.com.br, 1
 exploit-db.com, 1
 exploit.cz, 1
 exploit.party, 1
 exploit.ph, 1
 exploited.cz, 1
 exploitit.com.au, 1
 exploodo.rocks, 1
 exploravacations.in, 1
@@ -14952,16 +15039,18 @@ fabrica360.com, 1
 fabriceleroux.com, 1
 fabriziocavaliere.it, 1
 fabriziorocca.com, 1
 fabriziorocca.it, 1
 fabrysociety.org, 1
 fabse.net, 1
 fabulouslyyouthfulskin.com, 1
 fabulouslyyouthfulskineyeserum.com, 1
+facanabota.com, 1
+facanabota.com.br, 1
 faccess.it, 1
 facciadastile.it, 1
 face-mania.com, 1
 facealacrise.fr, 1
 facebattle.com, 1
 facebook-atom.appspot.com, 1
 facebook.ax, 1
 facebook.com, 0
@@ -14974,16 +15063,17 @@ facepunch.org, 1
 facerepo.com, 1
 faceresources.org, 1
 facesnf.com, 1
 fach-journalist.de, 1
 fachschaftslisten.at, 1
 fachschaftslisten.org, 1
 facialexercising.com, 1
 facil.services, 0
+faciledireto.com.br, 1
 facilities.fr, 1
 facilitiessurvey.org, 1
 facilitrak.com, 1
 facility-service-muenchen.de, 1
 fackovcova.cz, 1
 fackovcova.eu, 1
 fackovcova.sk, 1
 fackovec.cz, 1
@@ -15036,24 +15126,24 @@ fairssl.se, 1
 fairviewmotel-simcoe.com, 1
 fairydust.space, 1
 faithcentercogop.net, 1
 faithgrowth.com, 1
 faithindemocracy.eu, 0
 faithleaks.org, 1
 faithmissionaries.com, 1
 faithwatch.org, 1
+faixaazul.com, 1
 fakeapple.nl, 1
 fakerli.com, 1
 fakti.bg, 1
 faktotum.tech, 1
 fakturi.com, 1
 fakturoid.cz, 1
 falaeapp.org, 1
-falaland.com, 1
 falaowang.com, 1
 falbros.com, 1
 falcona.io, 1
 falconfrag.com, 1
 falconvintners.com, 1
 falcoz.co, 1
 faldoria.de, 1
 falegname-roma.it, 1
@@ -15084,17 +15174,16 @@ fameuxhosting.co.uk, 1
 famfi.co, 1
 familiaperez.net, 1
 familie-kruithof.nl, 1
 familie-kupschke.de, 1
 familie-leu.ch, 1
 familie-monka.de, 1
 familie-poeppinghaus.de, 1
 familie-remke.de, 1
-familiegrottendieck.de, 1
 familieholme.de, 1
 familiekiekjes.nl, 1
 familjenfrodlund.se, 1
 familjenm.se, 1
 familylawhotline.org, 1
 familyparties.co.uk, 1
 familyreal.ru, 1
 familytreehq.com, 1
@@ -15111,16 +15200,17 @@ fanboi.ch, 1
 fancy-bridge.com, 1
 fancy.org.uk, 1
 fancygaming.dk, 1
 fander.it, 1
 fandler.cz, 1
 fandomservices.com, 1
 fanfareunion.ch, 1
 fangs.ink, 1
+fanhouwan.com, 1
 fanjoe.be, 1
 fansided.com, 1
 fantasiapainter.com, 1
 fantasiatravel.hr, 1
 fantasticcleaners.com.au, 1
 fantastichandymanmelbourne.com.au, 1
 fantastici.de, 1
 fantasticservices.com, 1
@@ -15145,16 +15235,17 @@ faradji.nu, 1
 faradome.ws, 1
 faraonplay5.com, 1
 faraonplay7.com, 1
 faraonplay8.com, 1
 faraslot8.com, 1
 faraslot8.net, 1
 farcecrew.de, 1
 faretravel.co.uk, 1
+farfallapets.com.br, 1
 farfetchos.com, 1
 fargtorget.se, 1
 farhadexchange.com, 1
 farhood.org, 1
 farid.is, 1
 farm24.co.uk, 1
 farmacia-discreto.com, 1
 farmacialaboratorio.it, 1
@@ -15203,16 +15294,17 @@ faspirits.com, 1
 fassaden-selleng.de, 1
 fassadenverkleidung24.de, 1
 fassi-sport.it, 1
 fastaim.de, 1
 fastbackmbg.be, 1
 fastbackmbm.be, 1
 fastblit.com, 1
 fastcash.com.br, 1
+fastcommerce.org, 1
 fastconfirm.com, 1
 fastcp.top, 1
 fastest-hosting.co.uk, 1
 fastforwardsociety.nl, 1
 fastforwardthemes.com, 1
 fastlike.co, 1
 fastmail.com, 0
 fastonline.ro, 1
@@ -15221,31 +15313,31 @@ fastrevision.com, 1
 fastvistorias.com.br, 1
 faszienrollen-info.de, 0
 fateandirony.com, 1
 fatecdevday.com.br, 1
 fatedata.com, 1
 fateitalia.it, 1
 fathers4equalrights.org, 1
 fatidique.com, 1
+fatimamoldes.com.br, 1
 fatmixx.com, 1
 fator25.com.br, 1
 fatowltees.com, 1
 fatox.de, 1
 faucetbox.com, 0
 faui2k17.de, 0
 faultlines.org, 1
 faulty.equipment, 1
 fauvettes.be, 1
 favirei.com, 1
 fawong.com, 1
 faxite.com, 1
 faxreader.net, 1
 faxvorlagen-druckvorlagen.de, 1
-fayntic.com, 1
 fb.me, 1
 fbcdn.net, 1
 fbcfairburn.com, 1
 fbcopy.com, 1
 fbf.gov, 1
 fbi.gov, 1
 fbigame.com, 1
 fbiic.gov, 1
@@ -15396,16 +15488,17 @@ ferien-netzwerk.de, 1
 ferienchalet-wallis.ch, 1
 ferienhaeuser-krummin.de, 1
 ferienhaus-polchow-ruegen.de, 0
 ferienhausprovence.ch, 1
 ferienwohnung-hafeninsel-stralsund.de, 1
 ferienwohnungen-lastminute.de, 1
 feriespotter.dk, 1
 ferm-rotterdam.nl, 1
+fermabel.com.br, 1
 fermanacuratampaparts.com, 1
 fernandes.org, 1
 fernandob.com, 1
 fernandobarata.pt, 1
 fernandobarillas.com, 1
 fernandomiguel.net, 1
 feross.org, 1
 ferrariadvisor.it, 1
@@ -15562,17 +15655,16 @@ filmers.net, 1
 filmesonline.online, 1
 filmitis.com, 1
 filmreviewonline.com, 1
 filmserver.de, 1
 filmsite-studio.com, 1
 filmsphoto.com, 1
 filoo.de, 1
 filstop.com, 1
-filterflasche-kaufen.de, 1
 filterlists.com, 1
 filtr.me, 1
 fimsquad.com, 1
 final-expense-quotes.com, 1
 finalprice.net, 1
 finalrewind.org, 1
 finalx.nl, 1
 finance-colleges.com, 1
@@ -16251,16 +16343,17 @@ franke-chemie.de, 1
 franken-lehrmittel.de, 1
 frankenhost.de, 1
 frankenlehrmittel.de, 1
 frankhaala.com, 1
 frankierfachmann.de, 1
 frankierprofi.de, 1
 frankierstar.de, 1
 frankinteriordesign.co.uk, 1
+frankl.in, 1
 franklinhua.com, 1
 frankmorrow.com, 1
 frankopol-sklep.pl, 1
 franksiler.com, 1
 frankslaughterinsurance.com, 1
 frankwei.xyz, 1
 frankyan.com, 1
 frantic1048.com, 1
@@ -16319,16 +16412,17 @@ freeben666.fr, 1
 freebetoffers.co.uk, 1
 freebies.id, 1
 freeblog.me, 1
 freebookmakersbetsandbonuses.com.au, 1
 freeboson.org, 1
 freebus.org, 1
 freecam2cam.site, 1
 freecloud.at, 1
+freecookies.nl, 1
 freedev.cz, 1
 freedom.nl, 1
 freedom.press, 1
 freedom35.org, 1
 freedomfinance.se, 1
 freedomflotilla.org, 1
 freedomfrontier.tk, 1
 freedomkiaparts.com, 1
@@ -16376,16 +16470,17 @@ freeshell.de, 1
 freeshkre.li, 1
 freesitemapgenera