Merge mozilla-central to inbound a=merge on a CLOSED TREE
authorCoroiu Cristina <ccoroiu@mozilla.com>
Tue, 16 Apr 2019 00:39:47 +0300
changeset 469604 afb20612c0e5
parent 469603 34062ef2307c (current diff)
parent 469534 b8f49a14c458 (diff)
child 469605 3bd02d619749
push id35875
push userccoroiu@mozilla.com
push dateTue, 16 Apr 2019 04:06:16 +0000
treeherdermozilla-central@a83cab75b00d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone68.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 mozilla-central to inbound a=merge on a CLOSED TREE
remote/server/Packet.jsm
remote/server/Socket.jsm
remote/server/Transport.jsm
testing/web-platform/meta/webrtc/RTCPeerConnection-setLocalDescription-offer.html.ini
--- a/.eslintignore
+++ b/.eslintignore
@@ -222,16 +222,18 @@ gfx/ots/**
 gfx/skia/**
 gfx/wr/**
 
 # intl/ exclusions
 intl/icu/**
 intl/locale/**
 intl/strres/**
 intl/uconv/**
+# Bug 1527075: This directory is linted in github repository
+intl/l10n/**
 
 # Third-party
 layout/mathml/imptests/**
 
 # Exclude everything but self-hosted JS
 js/ductwork/**
 js/examples/**
 js/ipc/**
--- a/accessible/tests/browser/general/browser_test_urlbar.js
+++ b/accessible/tests/browser/general/browser_test_urlbar.js
@@ -8,17 +8,21 @@ const {UrlbarTestUtils} = ChromeUtils.im
 
 // Checking that the awesomebar popup gets COMBOBOX_LIST role instead of
 // LISTBOX, since its parent is a <panel> (see Bug 1422465)
 add_task(async function testAutocompleteRichResult() {
   let tab = await openNewTab("data:text/html;charset=utf-8,");
   let accService = await initAccessibilityService();
 
   info("Opening the URL bar and entering a key to show the PopupAutoCompleteRichResult panel");
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, "a", waitForFocus);
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "a"
+  });
 
   info("Waiting for accessibility to be created for the richlistbox");
   let resultsView;
   if (UrlbarPrefs.get("quantumbar")) {
     resultsView = gURLBar.view.panel.querySelector("#urlbarView-results");
     await BrowserTestUtils.waitForCondition(() => accService.getAccessibleFor(resultsView));
   } else {
     let urlbarPopup = document.getElementById("PopupAutoCompleteRichResult");
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<blocklist lastupdate="1554976164809" xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist lastupdate="1555100575898" xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
     <emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1211" id="flvto@hotger.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
@@ -2779,16 +2779,48 @@
     <emItem blockID="ed01b7e5-73d1-42a6-9fc8-af2d83879854" id="/^((\{9946bf2f-0aef-4040-bc57-cdae2bde196a\})|(\{d511784e-d088-4fce-b77c-14c186f08641\})|(\{fe59312a-97bd-4ca7-bce3-b0db95b1e251\}))$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="0d86ba71-7baa-4cb3-b3b8-da4ccdfa36b9" id="/^((\{0913599d-3094-44a7-8cc2-b8467d5afc7c\})|(\{7bee7f1b-d8ad-424d-807d-e69e6634988e\}))$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="fc38e782-d55b-4fb7-8f9c-374aa18af09c" id="/^((\{61f433aa-45fd-42a9-9c90-c1d7820661d5\})|(\{86cd46b6-433a-439c-bff2-722846709f44\})|(\{98e126a4-4e70-4300-b893-3b2cca19bc9b\})|(\{8f42dc3a-1c46-4fc2-8c7f-dd76a63b1cf7\})|(\{a24d3582-2fc2-475c-8440-335736e17c6e\})|(\{cf0b5280-cd08-465d-ad7d-70308538f30a\})|(\{936f3c79-5dc9-4694-bca8-47932de3357a\})|(\{e48d5888-8736-4858-83ba-e816378ffef8\})|(\{5305f89c-ceec-4217-8bae-c9c376c7462b\})|(\{a2ac47e5-d225-4718-9b57-18a932f87610\})|(\{79f60f07-6aee-42cd-9105-c0a52f401316\}))$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="6fd3ab94-8e38-47f3-b129-3ca8396d0a22" id="{be6ab6a9-7004-4c5c-8df9-8d36122d8b14}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="036e2e7d-5403-49be-92cf-b5187ceef7ec" id="/^((\{b37f383f-e60f-4eb1-ac0f-9147e0e8f2f7\})|(\{8ad567d2-3fe2-446b-bce9-a3acbe878dba\}))$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="03554696-58fe-4b90-89d1-72b72f88f82e" id="/^((\{8220ccaf-15a4-4f47-a670-a4119a4296a4\})|(\{9da72c11-44d7-423c-b19c-c75cd6188c3e\})|(\{99d0e4d0-c5ef-4567-b74c-80c5ed21ad99\}))$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="ea00841e-8dc2-4e11-9119-7a599e47d800" id="{608f71eb-5bd6-45d8-bc93-b9e812cf17b7}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="53ef1aad-7bdb-4f4e-8d46-55d6ec2d78ab" id="H.264.Addon.Test@firefox.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="371796e4-387a-4dd0-9ddc-47ba1dd85be7" id="{132cb2fd-a6ae-45d2-84cf-b48d591f037d}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="3a921aa8-d44a-4272-be63-0fd102577f59" id="{d8b03707-e39f-4b17-8e56-56354fb14af5}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
   </emItems>
   <pluginItems>
     <pluginItem blockID="p332">
       <match exp="libflashplayer\.so" name="filename"/>
       <match exp="^Shockwave Flash 11.(0|1) r[0-9]{1,3}$" name="description"/>
       <infoURL>https://get.adobe.com/flashplayer/</infoURL>
       <versionRange severity="0" vulnerabilitystatus="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
--- a/browser/base/content/test/performance/head.js
+++ b/browser/base/content/test/performance/head.js
@@ -729,18 +729,21 @@ async function runUrlbarTest(useAwesomeb
       let searchTerm = "ows-10";
       for (let i = 0; i < searchTerm.length; ++i) {
         let char = searchTerm[i];
         EventUtils.synthesizeKey(char, {}, win);
         await UrlbarTestUtils.promiseSearchComplete(win);
         await waitExtra();
       }
     } else {
-      await UrlbarTestUtils.promiseAutocompleteResultPopup(win, URLBar.value,
-                                                           SimpleTest.waitForFocus);
+      await UrlbarTestUtils.promiseAutocompleteResultPopup({
+        window: win,
+        waitForFocus: SimpleTest.waitForFocus,
+        value: URLBar.value,
+      });
       await waitExtra();
     }
 
     await UrlbarTestUtils.promisePopupClose(win);
   };
 
   let dropmarkerRect = win.document.getAnonymousElementByAttribute(URLBar.textbox,
     "anonid", "historydropmarker").getBoundingClientRect();
--- a/browser/components/extensions/test/browser/browser_ext_webNavigation_urlbar_transitions.js
+++ b/browser/components/extensions/test/browser/browser_ext_webNavigation_urlbar_transitions.js
@@ -5,18 +5,22 @@
 ChromeUtils.defineModuleGetter(this, "PlacesUtils",
                                "resource://gre/modules/PlacesUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "UrlbarTestUtils",
                                "resource://testing-common/UrlbarTestUtils.jsm");
 
 const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
 const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
 
-function promiseAutocompleteResultPopup(inputText) {
-  return UrlbarTestUtils.promiseAutocompleteResultPopup(window, inputText, waitForFocus);
+function promiseAutocompleteResultPopup(value) {
+  return UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value,
+  });
 }
 
 async function addBookmark(bookmark) {
   if (bookmark.keyword) {
     await PlacesUtils.keywords.insert({
       keyword: bookmark.keyword,
       url: bookmark.url,
     });
@@ -126,17 +130,17 @@ add_task(async function test_webnavigati
       permissions: ["webNavigation"],
     },
   });
 
   await extension.startup();
   await SimpleTest.promiseFocus(window);
 
   await extension.awaitMessage("ready");
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, "http://example.com/?q=typedClosed", waitForFocus);
+  await promiseAutocompleteResultPopup("http://example.com/?q=typedClosed");
   await UrlbarTestUtils.promiseSearchComplete(window);
   // Closing the popup forces a different code route that handles no results
   // being displayed.
   await UrlbarTestUtils.promisePopupClose(window);
   EventUtils.synthesizeKey("VK_RETURN", {});
 
   await extension.awaitFinish("webNavigation.from_address_bar.typed");
 
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/content-src/asrouter/docs/experiment-guide.md
@@ -0,0 +1,52 @@
+# How to run experiments with ASRouter
+
+This guide will tell you how to run an experiment with ASRouter messages.
+Note that the actual experiment proccess and infrastructure is handled by
+the experiments team (#ask-experimenter).
+
+## Why run an experiment
+
+* To measure the effect of a message on a Firefox metric (e.g. retention)
+* To test a potentially risky message on a smaller group of users
+* To compare the performance of multiple variants of messages in a controlled way
+
+## Choose cohort IDs and request an experiment
+
+First you should decide on a cohort ID (this can be any arbitrary unique string) for each
+individual group you need to segment for your experiment.
+
+For example, if I want to test two variants of an FXA Snippet, I might have two cohort IDs,
+`FXA_SNIPPET_V1` and `FXA_SNIPPET_V2`.
+
+You will then [request](https://experimenter.services.mozilla.com/) a new "pref-flip" study with the Firefox Experiments team.
+The preferences you will submit will be based on the cohort IDs you chose.
+
+For the FXA Snippet example, your preference name would be `browser.newtabpage.activity-stream.asrouter.providers.snippets` and values would be:
+
+Control (default value)
+```json
+{"id":"snippets","enabled":true,"type":"remote","url":"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/release/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/","updateCycleInMs":14400000}
+```
+
+Variant 1:
+```json
+{"id":"snippets", "cohort": "FXA_SNIPPET_V1", "enabled":true,"type":"remote","url":"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/release/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/","updateCycleInMs":14400000}
+```
+
+Variant 2:
+```json
+{"id":"snippets", "cohort": "FXA_SNIPPET_V1", "enabled":true,"type":"remote","url":"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/release/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/","updateCycleInMs":14400000}
+```
+
+## Add targeting to your messages
+
+You must now check for the cohort ID in the `targeting` expression of the messages you want to include in your experiments.
+
+For the previous example, you wold include the following to target the first cohort:
+
+```json
+{
+  "targeting": "providerCohorts.snippets == \"FXA_SNIPPET_V1\""
+}
+
+```
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/content-src/asrouter/schemas/panel/cfr-fxa-bookmark.schema.json
@@ -0,0 +1,128 @@
+{
+  "title": "CFRFxABookmark",
+  "description": "A message shown in the bookmark panel when user adds or edits a bookmark",
+  "version": "1.0.0",
+  "type": "object",
+  "definitions": {
+    "plainText": {
+      "description": "Plain text (no HTML allowed)",
+      "type": "string"
+    },
+    "richText": {
+      "description": "Text with HTML subset allowed: i, b, u, strong, em, br",
+      "type": "string"
+    },
+    "link_url": {
+      "description": "Target for links or buttons",
+      "type": "string",
+      "format": "uri"
+    }
+  },
+  "properties": {
+    "title": {
+      "description": "Shown at the top of the message in the largest font size.",
+      "oneOf": [
+        {
+          "allOf": [
+            {"$ref": "#/definitions/richText"},
+            {"description": "Message to be shown"}
+          ]
+        },
+        {
+          "type": "object",
+          "properties": {
+            "string_id": {
+              "type": "string",
+              "description": "Fluent id of localized string"
+            }
+          },
+          "required": ["string_id"]
+        }
+      ]
+    },
+    "text": {
+      "description": "Longest part of the message, below the title, provides explanation.",
+      "oneOf": [
+        {
+          "allOf": [
+            {"$ref": "#/definitions/richText"},
+            {"description": "Message to be shown"}
+          ]
+        },
+        {
+          "type": "object",
+          "properties": {
+            "string_id": {
+              "type": "string",
+              "description": "Fluent id of localized string"
+            }
+          },
+          "required": ["string_id"]
+        }
+      ]
+    },
+    "link": {
+      "description": "Link shown at the bottom of the message, call to action",
+      "properties": {
+        "text": {
+          "description": "Message shown as part of anchor tag",
+          "oneOf": [
+            {
+              "allOf": [
+                {"$ref": "#/definitions/richText"},
+                {"description": "Message to be shown"}
+              ]
+            },
+            {
+              "type": "object",
+              "properties": {
+                "string_id": {
+                  "type": "string",
+                  "description": "Fluent id of localized string"
+                }
+              },
+              "required": ["string_id"]
+            }
+          ] 
+        },
+        "url": {
+          "description": "Value for href attribute of the anchor",
+          "allOf": [
+            {"$ref": "#/definitions/link_url"},
+            {"description": "Link that opens in a new tab"}
+          ]
+        }
+      },
+      "required": ["text", "url"]
+    },
+    "info_icon": {
+      "type": "object",
+      "description": "The small icon displayed in the top right corner of the panel. Not configurable, only the tooltip text." ,
+      "properties": {
+        "tooltiptext": {
+          "oneOf": [
+            {
+              "allOf": [
+                {"$ref": "#/definitions/plainText"},
+                {"description": "Message to be shown"}
+              ]
+            },
+            {
+              "type": "object",
+              "properties": {
+                "string_id": {
+                  "type": "string",
+                  "description": "Fluent id of localized string"
+                }
+              },
+              "required": ["string_id"]
+            }
+          ]
+        }
+      },
+      "required": ["tooltiptext"]
+    }
+  },
+  "additionalProperties": false,
+  "required": ["title", "text", "link", "info_icon"]
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.jsx
@@ -0,0 +1,34 @@
+import React from "react";
+import {RichText} from "../../components/RichText/RichText";
+import {safeURI} from "../../template-utils";
+import {SnippetBase} from "../../components/SnippetBase/SnippetBase";
+
+const DEFAULT_ICON_PATH = "chrome://branding/content/icon64.png";
+
+export class SimpleBelowSearchSnippet extends React.PureComponent {
+  renderText() {
+    const {props} = this;
+    return (<RichText text={props.content.text}
+      customElements={this.props.customElements}
+      localization_id="text"
+      links={props.content.links}
+      sendClick={props.sendClick} />);
+  }
+
+  render() {
+    const {props} = this;
+    let className = "SimpleBelowSearchSnippet";
+
+    if (props.className) {
+      className += ` ${props.className}`;
+    }
+
+    return (<SnippetBase {...props} className={className} textStyle={this.props.textStyle}>
+      <img src={safeURI(props.content.icon) || DEFAULT_ICON_PATH} className="icon" />
+      <div>
+        <p className="body">{this.renderText()}</p>
+        {this.props.extraContent}
+      </div>
+    </SnippetBase>);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.schema.json
@@ -0,0 +1,59 @@
+{
+  "title": "SimpleBelowSearchSnippet",
+  "description": "A simple template with just an icon and rich text. It gets inserted below the Activity Stream search box.",
+  "version": "1.1.0",
+  "type": "object",
+  "definitions": {
+    "richText": {
+      "description": "Text with HTML subset allowed: i, b, u, strong, em, br",
+      "type": "string"
+    },
+    "link_url": {
+      "description": "Target for links or buttons",
+      "type": "string",
+      "format": "uri"
+    }
+  },
+  "properties": {
+    "text": {
+      "allOf": [
+        {"$ref": "#/definitions/richText"},
+        {"description": "Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}
+      ]
+    },
+    "icon": {
+      "type": "string",
+      "description": "Snippet icon. 64x64px. SVG or PNG preferred."
+    },
+    "block_button_text": {
+      "type": "string",
+      "description": "Tooltip text used for dismiss button.",
+      "default": "Remove this"
+    },
+    "do_not_autoblock": {
+      "type": "boolean",
+      "description": "Used to prevent blocking the snippet after the CTA link has been clicked"
+    },
+    "links": {
+      "additionalProperties": {
+        "url": {
+          "allOf": [
+            {"$ref": "#/definitions/link_url"},
+            {"description": "The url where the link points to."}
+          ]
+        },
+        "metric": {
+          "type": "string",
+          "description": "Custom event name sent with telemetry event."
+        },
+        "args": {
+          "type": "string",
+          "description": "Additional parameters for link action, example which specific menu the button should open"
+        }
+      }
+    }
+  },
+  "additionalProperties": false,
+  "required": ["text"],
+  "dependencies": {}
+}
--- a/browser/components/newtab/content-src/asrouter/templates/template-manifest.jsx
+++ b/browser/components/newtab/content-src/asrouter/templates/template-manifest.jsx
@@ -1,14 +1,16 @@
 import {EOYSnippet} from "./EOYSnippet/EOYSnippet";
 import {FXASignupSnippet} from "./FXASignupSnippet/FXASignupSnippet";
 import {NewsletterSnippet} from "./NewsletterSnippet/NewsletterSnippet";
 import {SendToDeviceSnippet} from "./SendToDeviceSnippet/SendToDeviceSnippet";
+import {SimpleBelowSearchSnippet} from "./SimpleBelowSearchSnippet/SimpleBelowSearchSnippet";
 import {SimpleSnippet} from "./SimpleSnippet/SimpleSnippet";
 
 // Key names matching schema name of templates
 export const SnippetsTemplates = {
   simple_snippet: SimpleSnippet,
   newsletter_snippet: NewsletterSnippet,
   fxa_signup_snippet: FXASignupSnippet,
   send_to_device_snippet: SendToDeviceSnippet,
   eoy_snippet: EOYSnippet,
+  simple_below_search_snippet: SimpleBelowSearchSnippet,
 };
--- a/browser/components/newtab/data/content/activity-stream.bundle.js
+++ b/browser/components/newtab/data/content/activity-stream.bundle.js
@@ -9755,30 +9755,76 @@ const SendToDeviceSnippet = props => {
   return external_React_default.a.createElement(SubmitFormSnippet_SubmitFormSnippet, SendToDeviceSnippet_extends({}, propsWithDefaults, {
     form_method: "POST",
     className: "send_to_device_snippet",
     inputType: propsWithDefaults.content.include_sms ? "text" : "email",
     validateInput: propsWithDefaults.content.include_sms ? validateInput : null,
     processFormData: processFormData
   }));
 };
+// CONCATENATED MODULE: ./content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.jsx
+function SimpleBelowSearchSnippet_extends() { SimpleBelowSearchSnippet_extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return SimpleBelowSearchSnippet_extends.apply(this, arguments); }
+
+
+
+
+
+const SimpleBelowSearchSnippet_DEFAULT_ICON_PATH = "chrome://branding/content/icon64.png";
+class SimpleBelowSearchSnippet_SimpleBelowSearchSnippet extends external_React_default.a.PureComponent {
+  renderText() {
+    const {
+      props
+    } = this;
+    return external_React_default.a.createElement(RichText["RichText"], {
+      text: props.content.text,
+      customElements: this.props.customElements,
+      localization_id: "text",
+      links: props.content.links,
+      sendClick: props.sendClick
+    });
+  }
+
+  render() {
+    const {
+      props
+    } = this;
+    let className = "SimpleBelowSearchSnippet";
+
+    if (props.className) {
+      className += ` ${props.className}`;
+    }
+
+    return external_React_default.a.createElement(SnippetBase_SnippetBase, SimpleBelowSearchSnippet_extends({}, props, {
+      className: className,
+      textStyle: this.props.textStyle
+    }), external_React_default.a.createElement("img", {
+      src: Object(template_utils["safeURI"])(props.content.icon) || SimpleBelowSearchSnippet_DEFAULT_ICON_PATH,
+      className: "icon"
+    }), external_React_default.a.createElement("div", null, external_React_default.a.createElement("p", {
+      className: "body"
+    }, this.renderText()), this.props.extraContent));
+  }
+
+}
 // CONCATENATED MODULE: ./content-src/asrouter/templates/template-manifest.jsx
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SnippetsTemplates", function() { return SnippetsTemplates; });
 
 
 
 
+
  // Key names matching schema name of templates
 
 const SnippetsTemplates = {
   simple_snippet: SimpleSnippet_SimpleSnippet,
   newsletter_snippet: NewsletterSnippet,
   fxa_signup_snippet: FXASignupSnippet,
   send_to_device_snippet: SendToDeviceSnippet,
-  eoy_snippet: EOYSnippet
+  eoy_snippet: EOYSnippet,
+  simple_below_search_snippet: SimpleBelowSearchSnippet_SimpleBelowSearchSnippet
 };
 
 /***/ }),
 /* 56 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
--- a/browser/components/newtab/lib/CFRMessageProvider.jsm
+++ b/browser/components/newtab/lib/CFRMessageProvider.jsm
@@ -38,18 +38,20 @@ const REDDIT_ENHANCEMENT_PARAMS = {
   min_frecency: 10000,
 };
 const PINNED_TABS_TARGET_SITES = [
   "docs.google.com", "www.docs.google.com", "calendar.google.com",
   "messenger.com", "www.messenger.com", "web.whatsapp.com", "mail.google.com",
   "outlook.live.com", "facebook.com", "www.facebook.com", "twitter.com", "www.twitter.com",
   "reddit.com", "www.reddit.com", "github.com", "www.github.com", "youtube.com", "www.youtube.com",
   "feedly.com", "www.feedly.com", "drive.google.com", "amazon.com", "www.amazon.com",
-  "messages.android.com",
+  "messages.android.com", "amazon.ca", "www.amazon.ca", "amazon.com.au", "www.amazon.com.au",
+  "amazon.co.uk", "www.amazon.co.uk", "amazon.fr", "www.amazon.fr", "amazon.de", "www.amazon.de",
 ];
+const PINNED_TABS_TARGET_LOCALES = ["en-US", "en-CA", "en-AU", "en-GB", "en-ZA", "en-NZ", "fr", "de"];
 
 const CFR_MESSAGES = [
   {
     id: "FACEBOOK_CONTAINER_3",
     template: "cfr_doorhanger",
     content: {
       category: "cfrAddons",
       bucket_id: "CFR_M1",
@@ -345,17 +347,17 @@ const CFR_MESSAGES = [
           label: {string_id: "cfr-doorhanger-extension-manage-settings-button"},
           action: {
             type: "OPEN_PREFERENCES_PAGE",
             data: {category: "general-cfrfeatures"},
           },
         }],
       },
     },
-    targeting: `locale == "en-US" && !hasPinnedTabs && recentVisits[.timestamp > (currentDate|date - 3600 * 1000 * 1)]|length >= 3`,
+    targeting: `locale in ${JSON.stringify(PINNED_TABS_TARGET_LOCALES)} && !hasPinnedTabs && recentVisits[.timestamp > (currentDate|date - 3600 * 1000 * 1)]|length >= 3`,
     frequency: {lifetime: 3},
     trigger: {id: "frequentVisits", params: PINNED_TABS_TARGET_SITES},
   },
 ];
 
 const CFRMessageProvider = {
   getMessages() {
     return CFR_MESSAGES.filter(msg => !msg.exclude);
--- a/browser/components/newtab/lib/SnippetsTestMessageProvider.jsm
+++ b/browser/components/newtab/lib/SnippetsTestMessageProvider.jsm
@@ -242,16 +242,26 @@ const MESSAGES = () => ([
       "title": "Firefox Account!",
       "text": "Sync it, link it, take it with you. All this and more with a Firefox Account.",
       "block_button_text": "Block",
       "section_title_icon": "resource://activity-stream/data/content/assets/glyph-pocket-16.svg",
       "section_title_text": "Messages from Mozilla (click for info)",
       "section_title_url": "https://www.mozilla.org/about",
     },
   },
+  {
+    "id": "SIMPLE_BELOW_SEARCH_TEST_1",
+    "template": "simple_below_search_snippet",
+    "content": {
+      "icon": TEST_ICON,
+      "text": "Securely store passwords, bookmarks, and more with a Firefox Account. <syncLink>Sign up</syncLink>",
+      "links": {"syncLink": {"url": "https://www.mozilla.org/en-US/firefox/accounts"}},
+      "block_button_text": "Block",
+    },
+  },
 ]);
 
 const SnippetsTestMessageProvider = {
   getMessages() {
     return MESSAGES()
       // Ensures we never actually show test except when triggered by debug tools
       .map(message => ({...message, targeting: `providerCohorts.snippets_local_testing == "SHOW_TEST"`}));
   },
--- a/browser/components/newtab/test/unit/asrouter/CFRMessageProvider.test.js
+++ b/browser/components/newtab/test/unit/asrouter/CFRMessageProvider.test.js
@@ -27,23 +27,25 @@ describe("CFRMessageProvider", () => {
       // Ensure that the CFR messages that are recommending an addon have this targeting.
       // In the future when we can do targeting based on category, this test will change.
       // See bug 1494778 and 1497653
       if (message.id !== "PIN_TAB") {
         assert.include(message.targeting, `(xpinstallEnabled == true)`);
       }
     }
   });
-  it("should restrict all messages to `en` locale for now", () => {
-    for (const message of messages) {
-      if (message.id !== "PIN_TAB") {
-        assert.include(message.targeting, `localeLanguageCode == "en"`);
-      } else {
-        assert.include(message.targeting, `locale == "en-US"`);
-      }
+  it("should restrict all messages to `en` locale for now (PIN TAB is handled separately)", () => {
+    for (const message of messages.filter(m => m.id !== "PIN_TAB")) {
+      assert.include(message.targeting, `localeLanguageCode == "en"`);
     }
   });
+  it("should restrict locale for PIN_TAB message", () => {
+    const pinTabMessage = messages.find(m => m.id === "PIN_TAB");
+
+    // 6 en-* locales, fr and de
+    assert.lengthOf(pinTabMessage.targeting.match(/en-|fr|de/g), 8);
+  });
   it("should contain `www.` version of the hosts", () => {
     const pinTabMessage = messages.find(m => m.id === "PIN_TAB");
 
     assert.isTrue(pinTabMessage.trigger.params.filter(host => host.startsWith("www.")).length > 0);
   });
 });
--- a/browser/components/newtab/test/unit/asrouter/SnippetsTestMessageProvider.test.js
+++ b/browser/components/newtab/test/unit/asrouter/SnippetsTestMessageProvider.test.js
@@ -1,19 +1,21 @@
 import EOYSnippetSchema from "../../../content-src/asrouter/templates/EOYSnippet/EOYSnippet.schema.json";
+import SimpleBelowSearchSnippetSchema from "../../../content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.schema.json";
 import SimpleSnippetSchema from "../../../content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.schema.json";
 import {SnippetsTestMessageProvider} from "../../../lib/SnippetsTestMessageProvider.jsm";
 import SubmitFormSnippetSchema from "../../../content-src/asrouter/templates/SubmitFormSnippet/SubmitFormSnippet.schema.json";
 
 const schemas = {
   "simple_snippet": SimpleSnippetSchema,
   "newsletter_snippet": SubmitFormSnippetSchema,
   "fxa_signup_snippet": SubmitFormSnippetSchema,
   "send_to_device_snippet": SubmitFormSnippetSchema,
   "eoy_snippet": EOYSnippetSchema,
+  "simple_below_search_snippet": SimpleBelowSearchSnippetSchema,
 };
 
 describe("SnippetsTestMessageProvider", () => {
   let messages = SnippetsTestMessageProvider.getMessages();
 
   it("should return an array of messages", () => {
     assert.isArray(messages);
   });
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/test/unit/asrouter/schemas/panel/cfr-fxa-bookmark.schema.test.js
@@ -0,0 +1,34 @@
+import schema from "content-src/asrouter/schemas/panel/cfr-fxa-bookmark.schema.json";
+
+const DEFAULT_CONTENT = {
+  "title": "Sync your bookmarks everywhere",
+  "text": "Great find! Now don't be left without this bookmark.",
+  "link": {
+    "text": "Sync bookmarks now",
+    "url": "https://mozilla.com",
+  },
+  "info_icon": {
+    "tooltiptext": "Learn more",
+  },
+};
+
+const L10N_CONTENT = {
+  "title": {string_id: "cfr-bookmark-title"},
+  "text": {string_id: "cfr-bookmark-body"},
+  "link": {
+    "text": {string_id: "cfr-bookmark-link-text"},
+    "url": "https://mozilla.com",
+  },
+  "info_icon": {
+    "tooltiptext": {string_id: "cfr-bookmark-tooltip-text"},
+  },
+};
+
+describe("CFR FxA Message Schema", () => {
+  it("should validate DEFAULT_CONTENT", () => {
+    assert.jsonSchema(DEFAULT_CONTENT, schema);
+  });
+  it("should validate L10N_CONTENT", () => {
+    assert.jsonSchema(L10N_CONTENT, schema);
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/test/unit/asrouter/templates/SimpleBelowSearchSnippet.test.jsx
@@ -0,0 +1,47 @@
+import {mount} from "enzyme";
+import React from "react";
+import schema from "content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.schema.json";
+import {SimpleBelowSearchSnippet} from "content-src/asrouter/templates/SimpleBelowSearchSnippet/SimpleBelowSearchSnippet.jsx";
+
+const DEFAULT_CONTENT = {text: "foo"};
+
+describe("SimpleBelowSearchSnippet", () => {
+  let sandbox;
+  let sendUserActionTelemetryStub;
+
+  /**
+   * mountAndCheckProps - Mounts a SimpleBelowSearchSnippet with DEFAULT_CONTENT extended with any props
+   *                      passed in the content param and validates props against the schema.
+   * @param {obj} content Object containing custom message content (e.g. {text, icon})
+   * @returns enzyme wrapper for SimpleSnippet
+   */
+  function mountAndCheckProps(content = {}, provider = "test-provider") {
+    const props = {
+      content: {...DEFAULT_CONTENT, ...content},
+      provider,
+      sendUserActionTelemetry: sendUserActionTelemetryStub,
+      onAction: sandbox.stub(),
+    };
+    assert.jsonSchema(props.content, schema);
+    return mount(<SimpleBelowSearchSnippet {...props} />);
+  }
+
+  beforeEach(() => {
+    sandbox = sinon.createSandbox();
+    sendUserActionTelemetryStub = sandbox.stub();
+  });
+
+  afterEach(() => {
+    sandbox.restore();
+  });
+
+  it("should render .text", () => {
+    const wrapper = mountAndCheckProps({text: "bar"});
+    assert.equal(wrapper.find(".body").text(), "bar");
+  });
+
+  it("should render .icon", () => {
+    const wrapper = mountAndCheckProps({icon: "data:image/gif;base64,R0lGODl"});
+    assert.equal(wrapper.find(".icon").prop("src"), "data:image/gif;base64,R0lGODl");
+  });
+});
--- a/browser/components/search/test/browser/browser_oneOffContextMenu_setDefault.js
+++ b/browser/components/search/test/browser/browser_oneOffContextMenu_setDefault.js
@@ -142,17 +142,21 @@ async function openPopupAndGetEngineButt
   // We have to open the popups in differnt ways.
   if (isSearch) {
     // Open the popup.
     let promise = promiseEvent(popup, "popupshown");
     // Use the search icon to avoid hitting the network.
     EventUtils.synthesizeMouseAtCenter(searchIcon, {});
     await promise;
   } else {
-    await UrlbarTestUtils.promiseAutocompleteResultPopup(window, "a", waitForFocus);
+    await UrlbarTestUtils.promiseAutocompleteResultPopup({
+      window,
+      waitForFocus,
+      value: "a",
+    });
   }
 
   const contextMenu = oneOffInstance.contextMenuPopup;
   const oneOffButtons = oneOffInstance.buttons;
 
   // Get the one-off button for the test engine.
   let oneOffButton;
   for (let node of oneOffButtons.children) {
--- a/browser/components/sessionstore/test/browser_tabs_in_urlbar.js
+++ b/browser/components/sessionstore/test/browser_tabs_in_urlbar.js
@@ -64,17 +64,21 @@ add_task(async function test_unrestored_
     // after that has fired for all tabs. Since 1 tab will be restored though, we
     // also need to wait for 1 SSTabRestored since currentURI will be set, unset, then set.
     gBrowser.tabContainer.addEventListener("SSTabRestoring", handleEvent, true);
     gBrowser.tabContainer.addEventListener("SSTabRestored", handleEvent, true);
     ss.setBrowserState(JSON.stringify(state));
   });
 
   info("Searching open pages.");
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, RESTRICT_TOKEN_OPENPAGE, waitForFocus);
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: RESTRICT_TOKEN_OPENPAGE,
+  });
   const total = UrlbarTestUtils.getResultCount(window);
   info(`Found ${total} matches`);
   const quantumbar = UrlbarPrefs.get("quantumbar");
 
   // Check to see the expected uris and titles match up (in any order)
   for (let i = 0; i < total; i++) {
     const result = await UrlbarTestUtils.getDetailsOfResultAt(window, i);
     if (result.heuristic) {
--- a/browser/components/urlbar/UrlbarController.jsm
+++ b/browser/components/urlbar/UrlbarController.jsm
@@ -141,19 +141,19 @@ class UrlbarController {
   receiveResults(queryContext) {
     if (queryContext.lastResultCount < 1 && queryContext.results.length >= 1) {
       TelemetryStopwatch.finish(TELEMETRY_1ST_RESULT, queryContext);
     }
     if (queryContext.lastResultCount < 6 && queryContext.results.length >= 6) {
       TelemetryStopwatch.finish(TELEMETRY_6_FIRST_RESULTS, queryContext);
     }
 
-    if (queryContext.lastResultCount == 0) {
-      if (queryContext.results.length && queryContext.results[0].autofill) {
-        this.input.setValueFromResult(queryContext.results[0]);
+    if (queryContext.lastResultCount == 0 && queryContext.results.length) {
+      if (queryContext.results[0].autofill) {
+        this.input.autofillFirstResult(queryContext.results[0]);
       }
       // The first time we receive results try to connect to the heuristic
       // result.
       this.speculativeConnect(queryContext, 0, "resultsadded");
     }
 
     this._notify("onQueryResults", queryContext);
     // Update lastResultCount after notifying, so the view can use it.
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -92,16 +92,19 @@ class UrlbarInput {
     this.lastQueryContextPromise = Promise.resolve();
     this._actionOverrideKeyCount = 0;
     this._autofillPlaceholder = "";
     this._lastSearchString = "";
     this._resultForCurrentValue = null;
     this._suppressStartQuery = false;
     this._untrimmedValue = "";
 
+    // This exists only for tests.
+    this._enableAutofillPlaceholder = true;
+
     // Forward textbox methods and properties.
     const METHODS = ["addEventListener", "removeEventListener",
       "setAttribute", "hasAttribute", "removeAttribute", "getAttribute",
       "select"];
     const READ_ONLY_PROPERTIES = ["inputField", "editor"];
     const READ_WRITE_PROPERTIES = ["placeholder", "readOnly",
       "selectionStart", "selectionEnd"];
 
@@ -500,32 +503,65 @@ class UrlbarInput {
         this.value = this._getValueFromResult(result);
       }
     }
     this._resultForCurrentValue = result;
 
     // Also update userTypedValue. See bug 287996.
     this.window.gBrowser.userTypedValue = this.value;
 
-    // The value setter clobbers the actiontype attribute, so update this after that.
+    // The value setter clobbers the actiontype attribute, so update this after
+    // that.
     if (result) {
       switch (result.type) {
         case UrlbarUtils.RESULT_TYPE.TAB_SWITCH:
           this.setAttribute("actiontype", "switchtab");
           break;
         case UrlbarUtils.RESULT_TYPE.OMNIBOX:
           this.setAttribute("actiontype", "extension");
           break;
       }
     }
 
     return !!canonizedUrl;
   }
 
   /**
+   * Called by the controller when the first result of a new search is received.
+   * If it's an autofill result, then it may need to be autofilled, subject to a
+   * few restrictions.
+   *
+   * @param {UrlbarResult} result
+   *   The first result.
+   */
+  autofillFirstResult(result) {
+    if (!result.autofill) {
+      return;
+    }
+
+    let isPlaceholderSelected =
+      this.selectionEnd == this._autofillPlaceholder.length &&
+      this.selectionStart == this._lastSearchString.length &&
+      this._autofillPlaceholder.toLocaleLowerCase()
+        .startsWith(this._lastSearchString.toLocaleLowerCase());
+
+    // Don't autofill if there's already a selection (with one caveat described
+    // next) or the cursor isn't at the end of the input.  But if there is a
+    // selection and it's the autofill placeholder value, then do autofill.
+    if (!isPlaceholderSelected &&
+        (this.selectionStart != this.selectionEnd ||
+         this.selectionEnd != this._lastSearchString.length)) {
+      return;
+    }
+
+    let { value, selectionStart, selectionEnd } = result.autofill;
+    this._autofillValue(value, selectionStart, selectionEnd);
+  }
+
+  /**
    * Starts a query based on the current input value.
    *
    * @param {boolean} [options.allowAutofill]
    *   Whether or not to allow providers to include autofill results.
    * @param {number} [options.lastKey]
    *   The last key the user entered (as a key code).
    * @param {string} [options.searchString]
    *   The search string.  If not given, the current input value is used.
@@ -742,17 +778,18 @@ class UrlbarInput {
     // it starts with the new search string, and we shouldn't autofill anything
     // if the caret isn't at the end of the input.
     if (!allowAutofill ||
         this._autofillPlaceholder.length <= value.length ||
         !this._autofillPlaceholder.toLocaleLowerCase()
           .startsWith(value.toLocaleLowerCase())) {
       this._autofillPlaceholder = "";
     } else if (this._autofillPlaceholder &&
-               this.selectionEnd == this.value.length) {
+               this.selectionEnd == this.value.length &&
+               this._enableAutofillPlaceholder) {
       let autofillValue =
         value + this._autofillPlaceholder.substring(value.length);
       this._autofillValue(autofillValue, value.length, autofillValue.length);
     }
 
     return allowAutofill;
   }
 
@@ -1164,17 +1201,17 @@ class UrlbarInput {
 
   /**
    * This notifies observers that the user has entered or selected something in
    * the URL bar which will cause navigation.
    *
    * We use the observer service, so that we don't need to load extra facilities
    * if they aren't being used, e.g. WebNavigation.
    *
-   * @param {UrlbarResult} [result]
+   * @param {UrlbarResult} result
    *   The result that was selected, if any.
    */
   _notifyStartNavigation(result) {
     Services.obs.notifyObservers({result}, "urlbar-user-start-navigation");
   }
 
   // Event handlers below.
 
--- a/browser/components/urlbar/UrlbarView.jsm
+++ b/browser/components/urlbar/UrlbarView.jsm
@@ -337,21 +337,22 @@ class UrlbarView {
       return;
     }
     this.controller.userSelectionBehavior = "none";
 
     this.panel.removeAttribute("hidden");
     this.panel.removeAttribute("actionoverride");
 
     // Make the panel span the width of the window.
+    let px = number => number.toFixed(2) + "px";
     let documentRect =
       this._getBoundsWithoutFlushing(this.document.documentElement);
     let width = documentRect.right - documentRect.left;
     this.panel.setAttribute("width", width);
-    this._mainContainer.style.maxWidth = width + "px";
+    this._mainContainer.style.maxWidth = px(width);
 
     // Keep the popup items' site icons aligned with the input's identity
     // icon if it's not too far from the edge of the window.  We define
     // "too far" as "more than 30% of the window's width AND more than
     // 250px".
     let contentWidth = width;
     let boundToCheck = this.window.RTL_UI ? "right" : "left";
     let inputRect = this._getBoundsWithoutFlushing(this.input.textbox);
@@ -369,32 +370,32 @@ class UrlbarView {
         endOffset = startOffset;
       }
       let identityIcon = this.document.getElementById("identity-icon");
       let identityRect = this._getBoundsWithoutFlushing(identityIcon);
       let start = this.window.RTL_UI ?
                     documentRect.right - identityRect.right :
                     identityRect.left;
 
-      this.panel.style.setProperty("--item-padding-start", Math.round(start) + "px");
-      this.panel.style.setProperty("--item-padding-end", Math.round(endOffset) + "px");
+      this.panel.style.setProperty("--item-padding-start", px(start));
+      this.panel.style.setProperty("--item-padding-end", px(endOffset));
       contentWidth -= start + endOffset;
     } else {
       this.panel.style.removeProperty("--item-padding-start");
       this.panel.style.removeProperty("--item-padding-end");
     }
-    this.panel.style.setProperty("--item-content-width", Math.round(contentWidth) + "px");
+    this.panel.style.setProperty("--item-content-width", px(contentWidth));
 
     // Align the panel with the input's parent toolbar.
     let toolbarRect =
       this._getBoundsWithoutFlushing(this.input.textbox.closest("toolbar"));
-    this.panel.style.marginInlineStart = Math.round(this.window.RTL_UI ?
+    this.panel.style.marginInlineStart = px(this.window.RTL_UI ?
       inputRect.right - documentRect.right :
-      documentRect.left - inputRect.left) + "px";
-    this.panel.style.marginTop = Math.round(inputRect.top - toolbarRect.top) + "px";
+      documentRect.left - inputRect.left);
+    this.panel.style.marginTop = px(inputRect.top - toolbarRect.top);
 
     this.panel.openPopup(this.input.textbox, "after_start");
   }
 
   _createRow() {
     let item = this._createElement("div");
     item.className = "urlbarView-row";
     item.setAttribute("role", "option");
--- a/browser/components/urlbar/tests/UrlbarTestUtils.jsm
+++ b/browser/components/urlbar/tests/UrlbarTestUtils.jsm
@@ -31,48 +31,62 @@ var UrlbarTestUtils = {
       if (typeof restoreAnimations == "function") {
         restoreAnimationsFn();
       }
     });
   },
 
   /**
    * Starts a search for a given string and waits for the search to be complete.
-   * @param {object} win The window containing the urlbar
-   * @param {string} inputText the search string
-   * @param {function} waitForFocus The Simpletest function
-   * @param {boolean} fireInputEvent whether an input event should be used when
-   *        starting the query (necessary to set userTypedValued)
+   * @param {object} options.window The window containing the urlbar
+   * @param {string} options.value the search string
+   * @param {function} options.waitForFocus The SimpleTest function
+   * @param {boolean} [options.fireInputEvent] whether an input event should be
+   *        used when starting the query (simulates the user's typing, sets
+   *        userTypedValued, etc.)
+   * @param {number} [options.selectionStart] The input's selectionStart
+   * @param {number} [options.selectionEnd] The input's selectionEnd
    */
-  async promiseAutocompleteResultPopup(win, inputText, waitForFocus, fireInputEvent = false) {
-    let urlbar = getUrlbarAbstraction(win);
+  async promiseAutocompleteResultPopup({
+    window,
+    value,
+    waitForFocus,
+    fireInputEvent = false,
+    selectionStart = -1,
+    selectionEnd = -1,
+  } = {}) {
+    let urlbar = getUrlbarAbstraction(window);
     let restoreAnimationsFn = urlbar.disableAnimations();
-    await new Promise(resolve => waitForFocus(resolve, win));
+    await new Promise(resolve => waitForFocus(resolve, window));
     let lastSearchString = urlbar.lastSearchString;
     urlbar.focus();
-    urlbar.value = inputText;
+    urlbar.value = value;
+    if (selectionStart >= 0 && selectionEnd >= 0) {
+      urlbar.selectionEnd = selectionEnd;
+      urlbar.selectionStart = selectionStart;
+    }
     if (fireInputEvent) {
       // This is necessary to get the urlbar to set gBrowser.userTypedValue.
       urlbar.fireInputEvent();
     } else {
-      win.gURLBar.setAttribute("pageproxystate", "invalid");
+      window.gURLBar.setAttribute("pageproxystate", "invalid");
     }
     // An input event will start a new search, with a couple of exceptions, so
     // be careful not to call startSearch if we fired an input event since that
     // would start two searches.  The first exception is when the new search and
     // old search are the same.  Many tests do consecutive searches with the
     // same string and expect new searches to start, so call startSearch
     // directly then.  The second exception is when searching with the legacy
     // urlbar and an empty string.
     if (!fireInputEvent ||
-        inputText == lastSearchString ||
-        (!urlbar.quantumbar && !inputText)) {
-      urlbar.startSearch(inputText);
+        value == lastSearchString ||
+        (!urlbar.quantumbar && !value)) {
+      urlbar.startSearch(value, selectionStart, selectionEnd);
     }
-    return this.promiseSearchComplete(win, restoreAnimationsFn);
+    return this.promiseSearchComplete(window, restoreAnimationsFn);
   },
 
   /**
    * Waits for a result to be added at a certain index. Since we implement lazy
    * results replacement, even if we have a result at an index, it may be
    * related to the previous query, this methods ensures the result is current.
    * @param {object} win The window containing the urlbar
    * @param {number} index The index to look for
@@ -334,19 +348,23 @@ class UrlbarAbstraction {
   get oneOffSearchButtonsVisible() {
     if (!this.quantumbar) {
       return this.window.getComputedStyle(this.oneOffSearchButtons.container).display != "none";
     }
 
     return this.oneOffSearchButtons.style.display != "none";
   }
 
-  startSearch(text) {
+  startSearch(text, selectionStart = -1, selectionEnd = -1) {
     if (this.quantumbar) {
       this.urlbar.value = text;
+      if (selectionStart >= 0 && selectionEnd >= 0) {
+        this.urlbar.selectionEnd = selectionEnd;
+        this.urlbar.selectionStart = selectionStart;
+      }
       this.urlbar.setAttribute("pageproxystate", "invalid");
       this.urlbar.startQuery();
     } else {
       // Force the controller to do consecutive searches for the same string by
       // calling resetInternalState.
       this.urlbar.controller.resetInternalState();
       this.urlbar.controller.startSearch(text);
     }
--- a/browser/components/urlbar/tests/browser/browser.ini
+++ b/browser/components/urlbar/tests/browser/browser.ini
@@ -21,20 +21,22 @@ skip-if = true # Bug 1524539 - need to f
 [browser_autocomplete_enter_race.js]
 [browser_autocomplete_no_title.js]
 [browser_autocomplete_readline_navigation.js]
 skip-if = os != "mac" # Mac only feature
 [browser_autocomplete_tag_star_visibility.js]
 [browser_autoFill_backspaced.js]
 [browser_autoFill_canonize.js]
 [browser_autoFill_caretNotAtEnd.js]
+[browser_autoFill_firstResult.js]
 [browser_autoFill_placeholder.js]
 [browser_autoFill_preserve.js]
 [browser_autoFill_trimURLs.js]
 [browser_autoFill_typed.js]
+[browser_autoFill_undo.js]
 [browser_canonizeURL.js]
 support-files =
   searchSuggestionEngine.xml
   searchSuggestionEngine.sjs
 [browser_caret_navigation.js]
 [browser_downArrowKeySearch.js]
 [browser_dragdropURL.js]
 [browser_dropmarker.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_autoFill_firstResult.js
@@ -0,0 +1,208 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test makes sure that autofilling the first result of a new search works
+// correctly: autofill happens when it should and doesn't when it shouldn't.
+
+"use strict";
+
+add_task(async function init() {
+  await PlacesUtils.bookmarks.eraseEverything();
+  await PlacesUtils.history.clear();
+  await PlacesTestUtils.addVisits([
+    "http://example.com/",
+  ]);
+
+  // Disable placeholder completion.  The point of this test is to make sure the
+  // first result is autofilled (or not) correctly.  Autofilling the placeholder
+  // before the search starts interferes with that.
+  gURLBar._enableAutofillPlaceholder = false;
+  registerCleanupFunction(async () => {
+    gURLBar._enableAutofillPlaceholder = true;
+  });
+});
+
+// The first result should be autofilled when all conditions are met.  This also
+// does a sanity check to make sure that placeholder autofill is correctly
+// disabled, which is helpful for all tasks here and is why this one is first.
+add_task(async function successfulAutofill() {
+  // Do a simple search that should autofill.  This will also set up the
+  // autofill placeholder string, which next we make sure is *not* autofilled.
+  await doInitialAutofillSearch();
+
+  // As a sanity check, do another search to make sure the placeholder is *not*
+  // autofilled.  Make sure it's not autofilled by checking the input value and
+  // selection *before* the search completes.  If placeholder autofill was not
+  // correctly disabled, then these assertions will fail.
+
+  gURLBar.value = "exa";
+  UrlbarTestUtils.fireInputEvent(window);
+
+  // before the search completes: no autofill
+  Assert.equal(gURLBar.value, "exa");
+  Assert.equal(gURLBar.selectionStart, "exa".length);
+  Assert.equal(gURLBar.selectionEnd, "exa".length);
+
+  await UrlbarTestUtils.promiseSearchComplete(window);
+
+  // after the search completes: successful autofill
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "example.com/");
+  Assert.equal(gURLBar.selectionStart, "exa".length);
+  Assert.equal(gURLBar.selectionEnd, "example.com/".length);
+});
+
+// The first result should not be autofilled when it's not an autofill result.
+add_task(async function firstResultNotAutofill() {
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "foo",
+    fireInputEvent: true,
+  });
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(!details.autofill);
+  Assert.equal(gURLBar.value, "foo");
+  Assert.equal(gURLBar.selectionStart, "foo".length);
+  Assert.equal(gURLBar.selectionEnd, "foo".length);
+});
+
+// The first result should *not* be autofilled when the placeholder is not
+// selected, the selection is empty, and the caret is *not* at the end of the
+// search string.
+add_task(async function caretNotAtEndOfSearchString() {
+  // To set up the placeholder, do an initial search that triggers autofill.
+  await doInitialAutofillSearch();
+
+  // Now do another search but set the caret to somewhere else besides the end
+  // of the new search string.
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "exam",
+    selectionStart: "exa".length,
+    selectionEnd: "exa".length,
+  });
+
+  // The first result should be an autofill result, but it should not have been
+  // autofilled.
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "exam");
+  Assert.equal(gURLBar.selectionStart, "exa".length);
+  Assert.equal(gURLBar.selectionEnd, "exa".length);
+
+  await cleanUp();
+});
+
+// The first result should *not* be autofilled when the placeholder is not
+// selected, the selection is *not* empty, and the caret is at the end of the
+// search string.
+add_task(async function selectionNotEmpty() {
+  // To set up the placeholder, do an initial search that triggers autofill.
+  await doInitialAutofillSearch();
+
+  // Now do another search.  Set the selection end at the end of the search
+  // string, but make the selection non-empty.
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "exam",
+    selectionStart: "exa".length,
+    selectionEnd: "exam".length,
+  });
+
+  // The first result should be an autofill result, but it should not have been
+  // autofilled.
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "exam");
+  Assert.equal(gURLBar.selectionStart, "exa".length);
+  Assert.equal(gURLBar.selectionEnd, "exam".length);
+
+  await cleanUp();
+});
+
+// The first result should be autofilled when the placeholder is not selected,
+// the selection is empty, and the caret is at the end of the search string.
+add_task(async function successfulAutofillAfterSettingPlaceholder() {
+  // To set up the placeholder, do an initial search that triggers autofill.
+  await doInitialAutofillSearch();
+
+  // Now do another search.
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "exam",
+    selectionStart: "exam".length,
+    selectionEnd: "exam".length,
+  });
+
+  // It should be autofilled.
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "example.com/");
+  Assert.equal(gURLBar.selectionStart, "exam".length);
+  Assert.equal(gURLBar.selectionEnd, "example.com/".length);
+
+  await cleanUp();
+});
+
+// The first result should be autofilled when the placeholder *is* selected --
+// more precisely, when the portion of the placeholder after the new search
+// string is selected.
+add_task(async function successfulAutofillPlaceholderSelected() {
+  // To set up the placeholder, do an initial search that triggers autofill.
+  await doInitialAutofillSearch();
+
+  // Now do another search and select the portion of the placeholder after the
+  // new search string.
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "exam",
+    selectionStart: "exam".length,
+    selectionEnd: "example.com/".length,
+  });
+
+  // It should be autofilled.
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "example.com/");
+  Assert.equal(gURLBar.selectionStart, "exam".length);
+  Assert.equal(gURLBar.selectionEnd, "example.com/".length);
+
+  await cleanUp();
+});
+
+async function doInitialAutofillSearch() {
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "ex",
+    fireInputEvent: true,
+  });
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "example.com/");
+  Assert.equal(gURLBar.selectionStart, "ex".length);
+  Assert.equal(gURLBar.selectionEnd, "example.com/".length);
+}
+
+async function cleanUp() {
+  // In some cases above, a test task searches for "exam" at the end, and then
+  // the next task searches for "ex".  Autofill results will not be allowed in
+  // the next task in that case since the old search string starts with the new
+  // search string.  To prevent one task from interfering with the next, do a
+  // search that changes the search string.  Also close the popup while we're
+  // here, although that's not really necessary.
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "reset last search string",
+  });
+  await UrlbarTestUtils.promisePopupClose(window, () => {
+    EventUtils.synthesizeKey("KEY_Escape");
+  });
+}
--- a/browser/components/urlbar/tests/browser/browser_autoFill_typed.js
+++ b/browser/components/urlbar/tests/browser/browser_autoFill_typed.js
@@ -150,20 +150,25 @@ async function typeAndCheck(values) {
          `substring="${expectedInputValue.substring(0, i + 1)}"`);
     EventUtils.synthesizeKey(char);
     if (i == 0 && char == "@") {
       // A single "@" doesn't trigger autofill, so skip the checks below.  (It
       // shows all the @ aliases.)
       continue;
     }
     await UrlbarTestUtils.promiseSearchComplete(window);
+    let restIsSpaces = !expectedInputValue.substring(i + 1).trim();
+    if (restIsSpaces && !UrlbarPrefs.get("quantumbar")) {
+      // See below.  In addition to that, in awesomebar, after typing the final
+      // character, autofill incorrectly doesn't include the trailing space.
+      expectedInputValue = expectedInputValue.trim();
+    }
     Assert.equal(gURLBar.value, expectedInputValue);
     Assert.equal(gURLBar.selectionStart, i + 1);
     Assert.equal(gURLBar.selectionEnd, expectedInputValue.length);
-    let restIsSpaces = !expectedInputValue.substring(i + 1).trim();
     if (restIsSpaces) {
       // Autofilled @ aliases have a trailing space.  We should check that the
       // space is autofilled when each preceding character is typed, but once
       // the final non-space char is typed, autofill actually stops and the
       // trailing space is not autofilled.  (Which is maybe not the way it
       // should work...)  Skip the check below.
       continue;
     }
new file mode 100644
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_autoFill_undo.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test checks the behavior of text undo (Ctrl-Z, cmd_undo) in regard to
+// autofill.
+
+"use strict";
+
+add_task(async function test() {
+  await PlacesUtils.bookmarks.eraseEverything();
+  await PlacesUtils.history.clear();
+  await PlacesTestUtils.addVisits([
+    "http://example.com/",
+  ]);
+
+  // Search for "ex".  It should autofill to example.com/.
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "ex",
+    fireInputEvent: true,
+  });
+  let details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "example.com/");
+  Assert.equal(gURLBar.selectionStart, "ex".length);
+  Assert.equal(gURLBar.selectionEnd, "example.com/".length);
+
+  // Type an x.
+  EventUtils.synthesizeKey("x");
+
+  // Nothing should have been autofilled.
+  await UrlbarTestUtils.promiseSearchComplete(window);
+  details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(!details.autofill);
+  Assert.equal(gURLBar.value, "exx");
+  Assert.equal(gURLBar.selectionStart, "exx".length);
+  Assert.equal(gURLBar.selectionEnd, "exx".length);
+
+  // Undo the typed x.
+  goDoCommand("cmd_undo");
+
+  // The text should be restored to ex[ample.com/] (with the part in brackets
+  // autofilled and selected).
+  await UrlbarTestUtils.promiseSearchComplete(window);
+  details = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+  Assert.ok(details.autofill);
+  Assert.equal(gURLBar.value, "example.com/");
+  Assert.equal(gURLBar.selectionStart, "ex".length);
+  Assert.equal(gURLBar.selectionEnd, "example.com/".length);
+
+  await PlacesUtils.history.clear();
+});
--- a/browser/components/urlbar/tests/browser/browser_autocomplete_autoselect.js
+++ b/browser/components/urlbar/tests/browser/browser_autocomplete_autoselect.js
@@ -54,17 +54,17 @@ add_task(async function() {
   let visits = [];
   repeat(maxResults, i => {
     visits.push({
       uri: makeURI("http://example.com/autocomplete/?" + i),
     });
   });
   await PlacesTestUtils.addVisits(visits);
 
-  await promiseAutocompleteResultPopup("example.com/autocomplete");
+  await promiseAutocompleteResultPopup("example.com/autocomplete", window, true);
 
   let resultCount = await UrlbarTestUtils.getResultCount(window);
 
   Assert.equal(resultCount, maxResults,
     "Should get the expected amount of results");
   assertSelected(0);
 
   info("Key Down to select the next item");
--- a/browser/components/urlbar/tests/browser/browser_switchToTab_closes_newtab.js
+++ b/browser/components/urlbar/tests/browser/browser_switchToTab_closes_newtab.js
@@ -26,17 +26,21 @@ add_task(async function test_switchToTab
     "TabClose", false, event => {
       return event.originalTarget == testTab;
     });
   let tabSelectPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer,
     "TabSelect", false, event => {
       return event.originalTarget == baseTab;
     });
 
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, "dummy", waitForFocus);
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "dummy",
+  });
 
   // The first result is the heuristic, the second will be the switch to tab.
   let element = await UrlbarTestUtils.waitForAutocompleteResultAt(window, 1);
   EventUtils.synthesizeMouseAtCenter(element, {}, window);
 
   await Promise.all([tabSelectPromise, tabClosePromise]);
 
   // Confirm that the selected tab is now the base tab
--- a/browser/components/urlbar/tests/browser/browser_switchToTab_fullUrl_repeatedKeydown.js
+++ b/browser/components/urlbar/tests/browser/browser_switchToTab_fullUrl_repeatedKeydown.js
@@ -17,17 +17,22 @@ add_task(async function test_switchToTab
   let testTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
 
   // Functions for TabClose and TabSelect
   let tabClosePromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer,
     "TabClose", false, event => event.target == testTab);
   let tabSelectPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer,
     "TabSelect", false, event => event.target == baseTab);
 
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, TEST_URL, waitForFocus, true);
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: TEST_URL,
+    fireInputEvent: true,
+  });
   // The first result is the heuristic, the second will be the switch to tab.
   await UrlbarTestUtils.waitForAutocompleteResultAt(window, 1);
 
   // Simulate a long press, on some platforms (Windows) it can generate multiple
   // keydown events.
   EventUtils.synthesizeKey("VK_SHIFT", { type: "keydown", repeat: 3 });
   EventUtils.synthesizeKey("VK_SHIFT", { type: "keyup" });
 
--- a/browser/components/urlbar/tests/browser/head-common.js
+++ b/browser/components/urlbar/tests/browser/head-common.js
@@ -50,21 +50,25 @@ async function withHttpServer(details = 
     server = null;
   }
 }
 
 function promiseSearchComplete(win = window, dontAnimate = false) {
   return UrlbarTestUtils.promiseSearchComplete(win, dontAnimate);
 }
 
-function promiseAutocompleteResultPopup(inputText,
+function promiseAutocompleteResultPopup(value,
                                         win = window,
                                         fireInputEvent = false) {
-  return UrlbarTestUtils.promiseAutocompleteResultPopup(win, inputText,
-    waitForFocus, fireInputEvent);
+  return UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window: win,
+    waitForFocus,
+    value,
+    fireInputEvent,
+  });
 }
 
 async function waitForAutocompleteResultAt(index) {
   return UrlbarTestUtils.waitForAutocompleteResultAt(window, index);
 }
 
 function promiseSuggestionsPresent(msg = "") {
   return UrlbarTestUtils.promiseSuggestionsPresent(window, msg);
--- a/browser/components/urlbar/tests/legacy/browser.ini
+++ b/browser/components/urlbar/tests/legacy/browser.ini
@@ -46,16 +46,18 @@ skip-if = (verify && !debug && (os == 'w
 [../browser/browser_autocomplete_enter_race.js]
 [../browser/browser_autocomplete_no_title.js]
 [../browser/browser_autocomplete_readline_navigation.js]
 skip-if = os != "mac" # Mac only feature
 [../browser/browser_autoFill_backspaced.js]
 [../browser/browser_autoFill_canonize.js]
 [../browser/browser_autoFill_preserve.js]
 [../browser/browser_autoFill_trimURLs.js]
+[../browser/browser_autoFill_typed.js]
+[../browser/browser_autoFill_undo.js]
 [../browser/browser_autocomplete_tag_star_visibility.js]
 [../browser/browser_canonizeURL.js]
 [../browser/browser_dragdropURL.js]
 [../browser/browser_ime_composition.js]
 [../browser/browser_keywordBookmarklets.js]
 [../browser/browser_keepStateAcrossTabSwitches.js]
 [../browser/browser_keyword_override.js]
 [../browser/browser_keywordSearch.js]
--- a/browser/modules/test/browser/browser_UsageTelemetry_urlbar.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_urlbar.js
@@ -18,18 +18,23 @@ const ONEOFF_URLBAR_PREF = "browser.urlb
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   SearchTelemetry: "resource:///modules/SearchTelemetry.jsm",
   UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.jsm",
   URLBAR_SELECTED_RESULT_TYPES: "resource:///modules/BrowserUsageTelemetry.jsm",
   URLBAR_SELECTED_RESULT_METHODS: "resource:///modules/BrowserUsageTelemetry.jsm",
 });
 
-function searchInAwesomebar(inputText, win = window) {
-  return UrlbarTestUtils.promiseAutocompleteResultPopup(win, inputText, waitForFocus, true);
+function searchInAwesomebar(value, win = window) {
+  return UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window: win,
+    waitForFocus,
+    value,
+    fireInputEvent: true,
+  });
 }
 
 /**
  * Click one of the entries in the urlbar suggestion popup.
  *
  * @param {String} resultTitle
  *        The title of the result to click on.
  * @param {Number} button [optional]
--- a/browser/modules/test/browser/browser_UsageTelemetry_urlbar_extension.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_urlbar_extension.js
@@ -115,18 +115,22 @@ add_task(async function test_extension()
   });
 
   await extension.startup();
 
   const histograms = snapshotHistograms();
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, "omniboxtest ",
-    waitForFocus, true);
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "omniboxtest ",
+    fireInputEvent: true,
+  });
   EventUtils.synthesizeKey("KEY_Enter");
 
   assertSearchTelemetryEmpty(histograms.search_hist);
   assertHistogramResults(histograms, "extension", 0,
     URLBAR_SELECTED_RESULT_METHODS.enter);
 
   await extension.unload();
   BrowserTestUtils.removeTab(tab);
--- a/browser/modules/test/browser/browser_UsageTelemetry_urlbar_places.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_urlbar_places.js
@@ -15,18 +15,23 @@ const TEST_URL = getRootDirectory(gTestP
   .replace("chrome://mochitests/content", "http://mochi.test:8888");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.jsm",
   URLBAR_SELECTED_RESULT_TYPES: "resource:///modules/BrowserUsageTelemetry.jsm",
   URLBAR_SELECTED_RESULT_METHODS: "resource:///modules/BrowserUsageTelemetry.jsm",
 });
 
-function searchInAwesomebar(inputText, win = window) {
-  return UrlbarTestUtils.promiseAutocompleteResultPopup(win, inputText, waitForFocus, true);
+function searchInAwesomebar(value, win = window) {
+  return UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window: win,
+    waitForFocus,
+    value,
+    fireInputEvent: true,
+  });
 }
 
 function assertSearchTelemetryEmpty(search_hist) {
   const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
   Assert.ok(!(SCALAR_URLBAR in scalars), `Should not have recorded ${SCALAR_URLBAR}`);
 
   // Make sure SEARCH_COUNTS contains identical values.
   TelemetryTestUtils.assertKeyedHistogramSum(search_hist, "other-MozSearch.urlbar", undefined);
--- a/browser/modules/test/browser/browser_UsageTelemetry_urlbar_remotetab.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_urlbar_remotetab.js
@@ -139,17 +139,22 @@ add_task(async function setup() {
 });
 
 add_task(async function test_remotetab() {
   const histograms = snapshotHistograms();
 
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-  await UrlbarTestUtils.promiseAutocompleteResultPopup(window, "example", waitForFocus, true);
+  await UrlbarTestUtils.promiseAutocompleteResultPopup({
+    window,
+    waitForFocus,
+    value: "example",
+    fireInputEvent: true,
+  });
   EventUtils.synthesizeKey("KEY_ArrowDown");
   EventUtils.synthesizeKey("KEY_Enter");
   await p;
 
   assertSearchTelemetryEmpty(histograms.search_hist);
   assertHistogramResults(histograms, "remotetab", 1,
     URLBAR_SELECTED_RESULT_METHODS.arrowEnterSelection);
 
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -433,33 +433,16 @@ already_AddRefed<BasePrincipal> BasePrin
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
 }
 
-already_AddRefed<BasePrincipal>
-BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain() {
-  OriginAttributes attrs = OriginAttributesRef();
-  attrs.StripAttributes(OriginAttributes::STRIP_USER_CONTEXT_ID |
-                        OriginAttributes::STRIP_FIRST_PARTY_DOMAIN);
-
-  nsAutoCString originNoSuffix;
-  nsresult rv = GetOriginNoSuffix(originNoSuffix);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  nsCOMPtr<nsIURI> uri;
-  rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
-}
-
 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingFirstPartyDomain(
     nsIURI* aURI) {
   if (NS_WARN_IF(!IsCodebasePrincipal())) {
     return nullptr;
   }
 
   OriginAttributes attrs = OriginAttributesRef();
   // XXX this is slow. Maybe we should consider to make it faster.
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -161,19 +161,16 @@ class BasePrincipal : public nsJSPrincip
     return mOriginAttributes.mPrivateBrowsingId;
   }
   bool IsInIsolatedMozBrowserElement() const {
     return mOriginAttributes.mInIsolatedMozBrowser;
   }
 
   PrincipalKind Kind() const { return mKind; }
 
-  already_AddRefed<BasePrincipal>
-  CloneStrippingUserContextIdAndFirstPartyDomain();
-
   already_AddRefed<BasePrincipal> CloneForcingFirstPartyDomain(nsIURI* aURI);
 
   already_AddRefed<BasePrincipal> CloneForcingOriginAttributes(
       const OriginAttributes& aOriginAttributes);
 
   // If this is an add-on content script principal, returns its AddonPolicy.
   // Otherwise returns null.
   extensions::WebExtensionPolicy* ContentScriptAddonPolicy();
--- a/devtools/client/aboutdebugging-new/test/browser/browser.ini
+++ b/devtools/client/aboutdebugging-new/test/browser/browser.ini
@@ -53,16 +53,17 @@ skip-if = (os == 'linux' && bits == 32) 
 [browser_aboutdebugging_debug-target-pane_empty.js]
 [browser_aboutdebugging_debug-target-pane_usb_runtime.js]
 [browser_aboutdebugging_devtools.js]
 [browser_aboutdebugging_devtoolstoolbox_contextmenu.js]
 [browser_aboutdebugging_devtoolstoolbox_contextmenu_markupview.js]
 [browser_aboutdebugging_devtoolstoolbox_focus.js]
 [browser_aboutdebugging_devtoolstoolbox_menubar.js]
 [browser_aboutdebugging_devtoolstoolbox_performance.js]
+skip-if = os == 'linux' && e10s && (asan || debug) # Same skip-if as old perf panel test suite. Bug 1254821
 [browser_aboutdebugging_devtoolstoolbox_reload.js]
 skip-if = verify # test loads the toolbox 2 times for each panel, might timeout or OOM
 [browser_aboutdebugging_devtoolstoolbox_shortcuts.js]
 skip-if = (os == "win" && ccov) # Bug 1521349
 [browser_aboutdebugging_devtoolstoolbox_target_destroyed.js]
 skip-if = debug || asan # This test leaks. See bug 1529005
 [browser_aboutdebugging_devtoolstoolbox_tooltip_markupview.js]
 [browser_aboutdebugging_navigate.js]
--- a/devtools/client/inspector/rules/test/browser.ini
+++ b/devtools/client/inspector/rules/test/browser.ini
@@ -36,16 +36,17 @@ support-files =
   doc_style_editor_link.css
   doc_test_image.png
   doc_urls_clickable.css
   doc_urls_clickable.html
   doc_variables_1.html
   doc_variables_2.html
   doc_variables_3.html
   head.js
+  !/devtools/client/debugger/test/mochitest/helpers/context.js
   !/devtools/client/inspector/test/head.js
   !/devtools/client/inspector/test/shared-head.js
   !/devtools/client/shared/test/shared-head.js
   !/devtools/client/shared/test/telemetry-test-helpers.js
   !/devtools/client/shared/test/test-actor.js
   !/devtools/client/shared/test/test-actor-registry.js
 
 [browser_rules_add-property-and-reselect.js]
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -60,17 +60,17 @@ static StaticAutoPtr<BrowsingContextMap<
 
 static void Register(BrowsingContext* aBrowsingContext) {
   MOZ_ALWAYS_TRUE(
       sBrowsingContexts->putNew(aBrowsingContext->Id(), aBrowsingContext));
 
   aBrowsingContext->Group()->Register(aBrowsingContext);
 }
 
-BrowsingContext* BrowsingContext::TopLevelBrowsingContext() {
+BrowsingContext* BrowsingContext::Top() {
   BrowsingContext* bc = this;
   while (bc->mParent) {
     bc = bc->mParent;
   }
   return bc;
 }
 
 /* static */
@@ -302,16 +302,20 @@ void BrowsingContext::CacheChildren(bool
     auto cc = ContentChild::GetSingleton();
     MOZ_DIAGNOSTIC_ASSERT(cc);
     cc->SendDetachBrowsingContext(this, true /* aMoveToBFCache */);
   }
 }
 
 bool BrowsingContext::IsCached() { return sCachedBrowsingContexts->has(Id()); }
 
+bool BrowsingContext::HasOpener() const {
+  return sBrowsingContexts->has(mOpenerId);
+}
+
 void BrowsingContext::GetChildren(
     nsTArray<RefPtr<BrowsingContext>>& aChildren) {
   MOZ_ALWAYS_TRUE(aChildren.AppendElements(mChildren));
 }
 
 // FindWithName follows the rules for choosing a browsing context,
 // with the exception of sandboxing for iframes. The implementation
 // for arbitrarily choosing between two browsing contexts with the
@@ -408,17 +412,17 @@ BrowsingContext* BrowsingContext::FindWi
     return this;
   }
 
   if (aName.LowerCaseEqualsLiteral("_parent")) {
     return mParent && CanAccess(mParent.get()) ? mParent.get() : this;
   }
 
   if (aName.LowerCaseEqualsLiteral("_top")) {
-    BrowsingContext* top = TopLevelBrowsingContext();
+    BrowsingContext* top = Top();
 
     return CanAccess(top) ? top : nullptr;
   }
 
   return nullptr;
 }
 
 BrowsingContext* BrowsingContext::FindWithNameInSubtree(
@@ -485,34 +489,34 @@ JSObject* BrowsingContext::WrapObject(JS
                                       JS::Handle<JSObject*> aGivenProto) {
   return BrowsingContext_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void BrowsingContext::NotifyUserGestureActivation() {
   // We would set the user gesture activation flag on the top level browsing
   // context, which would automatically be sync to other top level browsing
   // contexts which are in the different process.
-  RefPtr<BrowsingContext> topLevelBC = TopLevelBrowsingContext();
+  RefPtr<BrowsingContext> topLevelBC = Top();
   USER_ACTIVATION_LOG("Get top level browsing context 0x%08" PRIx64,
                       topLevelBC->Id());
   topLevelBC->SetIsActivatedByUserGesture(true);
 }
 
 void BrowsingContext::NotifyResetUserGestureActivation() {
   // We would reset the user gesture activation flag on the top level browsing
   // context, which would automatically be sync to other top level browsing
   // contexts which are in the different process.
-  RefPtr<BrowsingContext> topLevelBC = TopLevelBrowsingContext();
+  RefPtr<BrowsingContext> topLevelBC = Top();
   USER_ACTIVATION_LOG("Get top level browsing context 0x%08" PRIx64,
                       topLevelBC->Id());
   topLevelBC->SetIsActivatedByUserGesture(false);
 }
 
 bool BrowsingContext::GetUserGestureActivation() {
-  RefPtr<BrowsingContext> topLevelBC = TopLevelBrowsingContext();
+  RefPtr<BrowsingContext> topLevelBC = Top();
   return topLevelBC->GetIsActivatedByUserGesture();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(BrowsingContext)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell, mChildren, mParent, mGroup)
   if (XRE_IsParentProcess()) {
@@ -597,17 +601,17 @@ void BrowsingContext::Blur(ErrorResult& 
   } else if (ContentParent* cp = Canonical()->GetContentParent()) {
     Unused << cp->SendWindowBlur(this);
   }
 }
 
 Nullable<WindowProxyHolder> BrowsingContext::GetTop(ErrorResult& aError) {
   // We never return null or throw an error, but the implementation in
   // nsGlobalWindow does and we need to use the same signature.
-  return WindowProxyHolder(TopLevelBrowsingContext());
+  return WindowProxyHolder(Top());
 }
 
 void BrowsingContext::GetOpener(JSContext* aCx,
                                 JS::MutableHandle<JS::Value> aOpener,
                                 ErrorResult& aError) const {
   RefPtr<BrowsingContext> opener = GetOpener();
   if (!opener) {
     aOpener.setNull();
@@ -828,30 +832,30 @@ bool IPDLParamTraits<dom::BrowsingContex
     const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor,
     RefPtr<dom::BrowsingContext>* aResult) {
   uint64_t id = 0;
   if (!ReadIPDLParam(aMsg, aIter, aActor, &id)) {
     return false;
   }
 
   if (id == 0) {
-    aResult = nullptr;
+    *aResult = nullptr;
     return true;
   }
 
   *aResult = dom::BrowsingContext::Get(id);
-  MOZ_ASSERT(aResult, "Deserialized absent BrowsingContext!");
+  MOZ_ASSERT(*aResult, "Deserialized absent BrowsingContext!");
 
   // If this is an in-process actor, free the reference taken in ::Write().
   if (!aActor->GetIPCChannel()->IsCrossProcess()) {
     dom::BrowsingContext* bc = *aResult;
     NS_IF_RELEASE(bc);
   }
 
-  return aResult != nullptr;
+  return *aResult != nullptr;
 }
 
 void IPDLParamTraits<dom::BrowsingContext::Transaction>::Write(
     IPC::Message* aMessage, IProtocol* aActor,
     const dom::BrowsingContext::Transaction& aTransaction) {
 #define MOZ_BC_FIELD(name, ...) \
   WriteIPDLParam(aMessage, aActor, aTransaction.m##name);
 #include "mozilla/dom/BrowsingContextFieldList.h"
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -116,16 +116,17 @@ class BrowsingContext : public nsWrapper
   // process? This may be true with a null mDocShell after the Window has been
   // closed.
   bool IsInProcess() const { return mIsInProcess; }
 
   // Get the DocShell for this BrowsingContext if it is in-process, or
   // null if it's not.
   nsIDocShell* GetDocShell() { return mDocShell; }
   void SetDocShell(nsIDocShell* aDocShell);
+  void ClearDocShell() { mDocShell = nullptr; }
 
   // Get the outer window object for this BrowsingContext if it is in-process
   // and still has a docshell, or null otherwise.
   nsPIDOMWindowOuter* GetDOMWindow() const {
     return mDocShell ? mDocShell->GetWindow() : nullptr;
   }
 
   // Attach the current BrowsingContext to its parent, in both the child and the
@@ -151,21 +152,25 @@ class BrowsingContext : public nsWrapper
   bool NameEquals(const nsAString& aName) { return mName.Equals(aName); }
 
   bool IsContent() const { return mType == Type::Content; }
 
   uint64_t Id() const { return mBrowsingContextId; }
 
   BrowsingContext* GetParent() const { return mParent; }
 
+  BrowsingContext* Top();
+
   already_AddRefed<BrowsingContext> GetOpener() const { return Get(mOpenerId); }
   void SetOpener(BrowsingContext* aOpener) {
     SetOpenerId(aOpener ? aOpener->Id() : 0);
   }
 
+  bool HasOpener() const;
+
   void GetChildren(nsTArray<RefPtr<BrowsingContext>>& aChildren);
 
   BrowsingContextGroup* Group() { return mGroup; }
 
   // Using the rules for choosing a browsing context we try to find
   // the browsing context with the given name in the set of
   // transitively reachable browsing contexts. Performs access control
   // with regards to this.
@@ -379,18 +384,16 @@ class BrowsingContext : public nsWrapper
       mWindowProxy = obj;
     }
   }
   // Clear the window proxy object that corresponds to this browsing context.
   // This should be called if the window proxy object is finalized, or it can't
   // reach its browsing context anymore.
   void ClearWindowProxy() { mWindowProxy = nullptr; }
 
-  BrowsingContext* TopLevelBrowsingContext();
-
   friend class Location;
   friend class RemoteLocationProxy;
   /**
    * LocationProxy is the class for the native object stored as a private in a
    * RemoteLocationProxy proxy representing a Location object in a different
    * process. It forwards all operations to its BrowsingContext and aggregates
    * its refcount to that BrowsingContext.
    */
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -2155,16 +2155,21 @@ class Document : public nsINode,
     if (IsSVGDocument()) {
       return false;
     }
     return AllowXULXBL();
   }
 
   bool IsScriptEnabled();
 
+  /**
+   * Returns true if this document was created from a nsXULPrototypeDocument.
+   */
+  bool HasPrototypeDocument() const { return mPrototypeDocument; }
+
   bool IsTopLevelContentDocument() const { return mIsTopLevelContentDocument; }
   void SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument) {
     mIsTopLevelContentDocument = aIsTopLevelContentDocument;
     // When a document is set as TopLevelContentDocument, it must be
     // allowpaymentrequest. We handle the false case while a document is
     // appended in SetSubDocumentFor
     if (aIsTopLevelContentDocument) {
       SetAllowPaymentRequest(true);
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -9570,21 +9570,22 @@ nsresult nsContentUtils::NewXULOrHTMLEle
                                      aFromParser == dom::NOT_FROM_PARSER;
     // Per discussion in https://github.com/w3c/webcomponents/issues/635,
     // use entry global in those places that are called from JS APIs and use the
     // node document's global object if it is called from parser.
     nsIGlobalObject* global;
     if (aFromParser == dom::NOT_FROM_PARSER) {
       global = GetEntryGlobal();
 
-      // XUL documents always use NOT_FROM_PARSER for non-XUL elements. We can
-      // get the global from the document in that case.
+      // Documents created from the PrototypeDocumentSink always use
+      // NOT_FROM_PARSER for non-XUL elements. We can get the global from the
+      // document in that case.
       if (!global) {
         Document* doc = nodeInfo->GetDocument();
-        if (doc && doc->IsXULDocument()) {
+        if (doc && doc->HasPrototypeDocument()) {
           global = doc->GetScopeObject();
         }
       }
     } else {
       global = nodeInfo->GetDocument()->GetScopeObject();
     }
     if (!global) {
       // In browser chrome code, one may have access to a document which doesn't
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -146,58 +146,58 @@ typedef ScrollableLayerGuid::ViewID View
 // does not count chrome frames when determining depth, nor does it
 // prevent chrome recursion.  Number is fairly arbitrary, but meant to
 // keep number of shells to a reasonable number on accidental recursion with a
 // small (but not 1) branching factor.  With large branching factors the number
 // of shells can rapidly become huge and run us out of memory.  To solve that,
 // we'd need to re-institute a fixed version of bug 98158.
 #define MAX_DEPTH_CONTENT_FRAMES 10
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader, mDocShell, mMessageManager,
-                                      mChildMessageManager, mOpener,
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader, mBrowsingContext,
+                                      mMessageManager, mChildMessageManager,
                                       mParentSHistory, mRemoteBrowser)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_CONCRETE(nsFrameLoader)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-nsFrameLoader::nsFrameLoader(Element* aOwner, nsPIDOMWindowOuter* aOpener,
+nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
                              bool aNetworkCreated)
-    : mOwnerContent(aOwner),
+    : mBrowsingContext(aBrowsingContext),
+      mOwnerContent(aOwner),
       mDetachedSubdocFrame(nullptr),
-      mOpener(aOpener),
       mRemoteBrowser(nullptr),
       mChildID(0),
       mDepthTooGreat(false),
       mIsTopLevelContent(false),
       mDestroyCalled(false),
       mNeedsAsyncDestroy(false),
       mInSwap(false),
       mInShow(false),
       mHideCalled(false),
       mNetworkCreated(aNetworkCreated),
       mLoadingOriginalSrc(false),
       mRemoteBrowserShown(false),
       mIsRemoteFrame(false),
       mObservingOwnerContent(false) {
   mIsRemoteFrame = ShouldUseRemoteProcess();
-  MOZ_ASSERT(!mIsRemoteFrame || !aOpener,
+  MOZ_ASSERT(!mIsRemoteFrame || !mBrowsingContext->HasOpener(),
              "Cannot pass aOpener for a remote frame!");
 }
 
-nsFrameLoader::nsFrameLoader(Element* aOwner,
+nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
                              const mozilla::dom::RemotenessOptions& aOptions)
-    : mOwnerContent(aOwner),
+    : mBrowsingContext(aBrowsingContext),
+      mOwnerContent(aOwner),
       mDetachedSubdocFrame(nullptr),
-      mOpener(nullptr),
       mRemoteBrowser(nullptr),
       mChildID(0),
       mDepthTooGreat(false),
       mIsTopLevelContent(false),
       mDestroyCalled(false),
       mNeedsAsyncDestroy(false),
       mInSwap(false),
       mInShow(false),
@@ -206,36 +206,94 @@ nsFrameLoader::nsFrameLoader(Element* aO
       mLoadingOriginalSrc(false),
       mRemoteBrowserShown(false),
       mIsRemoteFrame(false),
       mObservingOwnerContent(false) {
   if (aOptions.mRemoteType.WasPassed() &&
       (!aOptions.mRemoteType.Value().IsVoid())) {
     mIsRemoteFrame = true;
   }
-  bool hasOpener =
-      aOptions.mOpener.WasPassed() && !aOptions.mOpener.Value().IsNull();
-  MOZ_ASSERT(!mIsRemoteFrame || !hasOpener,
-             "Cannot pass aOpener for a remote frame!");
-  if (hasOpener) {
-    // This seems slightly unwieldy.
-    mOpener = aOptions.mOpener.Value().Value().get()->GetDOMWindow();
-  }
 }
 
 nsFrameLoader::~nsFrameLoader() {
   if (mMessageManager) {
     mMessageManager->Disconnect();
   }
   MOZ_RELEASE_ASSERT(mDestroyCalled);
 }
 
-/* static */
-nsFrameLoader* nsFrameLoader::Create(Element* aOwner,
-                                     nsPIDOMWindowOuter* aOpener,
+static void GetFrameName(Element* aOwnerContent, nsAString& aFrameName) {
+  int32_t namespaceID = aOwnerContent->GetNameSpaceID();
+  if (namespaceID == kNameSpaceID_XHTML && !aOwnerContent->IsInHTMLDocument()) {
+    aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aFrameName);
+  } else {
+    aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, aFrameName);
+    // XXX if no NAME then use ID, after a transition period this will be
+    // changed so that XUL only uses ID too (bug 254284).
+    if (aFrameName.IsEmpty() && namespaceID == kNameSpaceID_XUL) {
+      aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aFrameName);
+    }
+  }
+}
+
+static already_AddRefed<BrowsingContext> CreateBrowsingContext(
+    Element* aOwner, BrowsingContext* aOpener) {
+  Document* doc = aOwner->OwnerDoc();
+  // Get our parent docshell off the document of mOwnerContent
+  // XXXbz this is such a total hack.... We really need to have a
+  // better setup for doing this.
+
+  // Determine our parent nsDocShell
+  RefPtr<nsDocShell> parentDocShell = nsDocShell::Cast(doc->GetDocShell());
+
+  if (NS_WARN_IF(!parentDocShell)) {
+    return nullptr;
+  }
+
+  RefPtr<BrowsingContext> parentContext = parentDocShell->GetBrowsingContext();
+
+  MOZ_DIAGNOSTIC_ASSERT(parentContext, "docShell must have BrowsingContext");
+
+  // Don't create a child docshell for a closed browsing context.
+  if (parentContext->GetClosed()) {
+    return nullptr;
+  }
+
+  // Determine the frame name for the new browsing context.
+  nsAutoString frameName;
+  GetFrameName(aOwner, frameName);
+
+  // Check if our new context is chrome or content
+  bool isContent =
+      parentContext->IsContent() ||
+      aOwner->AttrValueIs(
+          kNameSpaceID_None,
+          aOwner->IsXULElement() ? nsGkAtoms::type : nsGkAtoms::mozframetype,
+          nsGkAtoms::content, eIgnoreCase);
+
+  // Force mozbrowser frames to always be content, even if the mozbrowser
+  // interfaces are disabled.
+  nsCOMPtr<nsIMozBrowserFrame> mozbrowser = aOwner->GetAsMozBrowserFrame();
+  if (!isContent && mozbrowser) {
+    mozbrowser->GetMozbrowser(&isContent);
+  }
+
+  // If we're content but our parent isn't, we're going to want to
+  // start a new browsing context tree.
+  if (isContent && !parentContext->IsContent()) {
+    parentContext = nullptr;
+  }
+
+  BrowsingContext::Type type = isContent ? BrowsingContext::Type::Content
+                                         : BrowsingContext::Type::Chrome;
+
+  return BrowsingContext::Create(parentContext, aOpener, frameName, type);
+}
+
+nsFrameLoader* nsFrameLoader::Create(Element* aOwner, BrowsingContext* aOpener,
                                      bool aNetworkCreated) {
   NS_ENSURE_TRUE(aOwner, nullptr);
   Document* doc = aOwner->OwnerDoc();
 
   // We never create nsFrameLoaders for elements in resource documents.
   //
   // We never create nsFrameLoaders for elements in data documents, unless the
   // document is a static document.
@@ -255,27 +313,43 @@ nsFrameLoader* nsFrameLoader::Create(Ele
   // since for a static document we know aOwner will end up in a document and
   // the nsFrameLoader will be used for its docShell.)
   //
   NS_ENSURE_TRUE(!doc->IsResourceDoc() &&
                      ((!doc->IsLoadedAsData() && aOwner->IsInComposedDoc()) ||
                       doc->IsStaticDocument()),
                  nullptr);
 
-  return new nsFrameLoader(aOwner, aOpener, aNetworkCreated);
+  RefPtr<BrowsingContext> context = CreateBrowsingContext(aOwner, aOpener);
+  NS_ENSURE_TRUE(context, nullptr);
+  return new nsFrameLoader(aOwner, context, aNetworkCreated);
 }
 
 /* static */
 nsFrameLoader* nsFrameLoader::Create(
     mozilla::dom::Element* aOwner,
     const mozilla::dom::RemotenessOptions& aOptions) {
   NS_ENSURE_TRUE(aOwner, nullptr);
   // This version of Create is only called for Remoteness updates, so we can
   // assume we need a FrameLoader here and skip the check in the other Create.
-  return new nsFrameLoader(aOwner, aOptions);
+
+  bool hasOpener =
+      aOptions.mOpener.WasPassed() && !aOptions.mOpener.Value().IsNull();
+  MOZ_ASSERT(!aOptions.mRemoteType.WasPassed() ||
+                 aOptions.mRemoteType.Value().IsVoid() || !hasOpener,
+             "Cannot pass aOpener for a remote frame!");
+
+  // This seems slightly unwieldy.
+  RefPtr<BrowsingContext> opener;
+  if (hasOpener) {
+    opener = aOptions.mOpener.Value().Value().get();
+  }
+  RefPtr<BrowsingContext> context = CreateBrowsingContext(aOwner, opener);
+  NS_ENSURE_TRUE(context, nullptr);
+  return new nsFrameLoader(aOwner, context, aOptions);
 }
 
 void nsFrameLoader::LoadFrame(bool aOriginalSrc) {
   if (NS_WARN_IF(!mOwnerContent)) {
     return;
   }
 
   nsAutoString src;
@@ -423,18 +497,18 @@ nsresult nsFrameLoader::ReallyStartLoadi
 
     return NS_OK;
   }
 
   nsresult rv = MaybeCreateDocShell();
   if (NS_FAILED(rv)) {
     return rv;
   }
-  NS_ASSERTION(mDocShell,
-               "MaybeCreateDocShell succeeded with a null mDocShell");
+  MOZ_ASSERT(GetDocShell(),
+             "MaybeCreateDocShell succeeded with a null docShell");
 
   // Just to be safe, recheck uri.
   rv = CheckURILoad(mURIToLoad, mTriggeringPrincipal);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(mURIToLoad);
 
   loadState->SetOriginalFrameSrc(mLoadingOriginalSrc);
@@ -526,17 +600,17 @@ nsresult nsFrameLoader::ReallyStartLoadi
 
   loadState->SetIsFromProcessingFrameAttributes();
 
   // Kick off the load...
   bool tmpState = mNeedsAsyncDestroy;
   mNeedsAsyncDestroy = true;
   loadState->SetLoadFlags(flags);
   loadState->SetFirstParty(false);
-  rv = mDocShell->LoadURI(loadState);
+  rv = GetDocShell()->LoadURI(loadState);
   mNeedsAsyncDestroy = tmpState;
   mURIToLoad = nullptr;
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult nsFrameLoader::CheckURILoad(nsIURI* aURI,
@@ -585,21 +659,21 @@ nsDocShell* nsFrameLoader::GetDocShell(E
   // that. If not, we're most likely in the middle of being torn down,
   // then we just return null.
   if (mOwnerContent) {
     nsresult rv = MaybeCreateDocShell();
     if (NS_FAILED(rv)) {
       aRv.Throw(rv);
       return nullptr;
     }
-    NS_ASSERTION(mDocShell,
-                 "MaybeCreateDocShell succeeded, but null mDocShell");
+    MOZ_ASSERT(GetDocShell(),
+               "MaybeCreateDocShell succeeded, but null docShell");
   }
 
-  return mDocShell;
+  return GetDocShell();
 }
 
 static void SetTreeOwnerAndChromeEventHandlerOnDocshellTree(
     nsIDocShellTreeItem* aItem, nsIDocShellTreeOwner* aOwner,
     EventTarget* aHandler) {
   MOZ_ASSERT(aItem, "Must have item");
 
   aItem->SetTreeOwner(aOwner);
@@ -735,82 +809,82 @@ bool nsFrameLoader::Show(int32_t marginW
   if (IsRemoteFrame()) {
     return ShowRemoteFrame(size, frame);
   }
 
   nsresult rv = MaybeCreateDocShell();
   if (NS_FAILED(rv)) {
     return false;
   }
-  NS_ASSERTION(mDocShell, "MaybeCreateDocShell succeeded, but null mDocShell");
-  if (!mDocShell) {
+  MOZ_ASSERT(GetDocShell(), "MaybeCreateDocShell succeeded, but null docShell");
+  if (!GetDocShell()) {
     return false;
   }
 
-  mDocShell->SetMarginWidth(marginWidth);
-  mDocShell->SetMarginHeight(marginHeight);
-
-  mDocShell->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
-                                            scrollbarPrefX);
-  mDocShell->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
-                                            scrollbarPrefY);
-
-  if (PresShell* presShell = mDocShell->GetPresShell()) {
+  GetDocShell()->SetMarginWidth(marginWidth);
+  GetDocShell()->SetMarginHeight(marginHeight);
+
+  GetDocShell()->SetDefaultScrollbarPreferences(
+      nsIScrollable::ScrollOrientation_X, scrollbarPrefX);
+  GetDocShell()->SetDefaultScrollbarPreferences(
+      nsIScrollable::ScrollOrientation_Y, scrollbarPrefY);
+
+  if (PresShell* presShell = GetDocShell()->GetPresShell()) {
     // Ensure root scroll frame is reflowed in case scroll preferences or
     // margins have changed
     nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
     if (rootScrollFrame) {
       presShell->FrameNeedsReflow(rootScrollFrame, nsIPresShell::eResize,
                                   NS_FRAME_IS_DIRTY);
     }
     return true;
   }
 
   nsView* view = frame->EnsureInnerView();
   if (!view) return false;
 
-  RefPtr<nsDocShell> baseWindow = mDocShell;
+  RefPtr<nsDocShell> baseWindow = GetDocShell();
   baseWindow->InitWindow(nullptr, view->GetWidget(), 0, 0, size.width,
                          size.height);
   // This is kinda whacky, this "Create()" call doesn't really
   // create anything, one starts to wonder why this was named
   // "Create"...
   baseWindow->Create();
   baseWindow->SetVisibility(true);
-  NS_ENSURE_TRUE(mDocShell, false);
+  NS_ENSURE_TRUE(GetDocShell(), false);
 
   // Trigger editor re-initialization if midas is turned on in the
   // sub-document. This shouldn't be necessary, but given the way our
   // editor works, it is. See
   // https://bugzilla.mozilla.org/show_bug.cgi?id=284245
-  if (RefPtr<PresShell> presShell = mDocShell->GetPresShell()) {
+  if (RefPtr<PresShell> presShell = GetDocShell()->GetPresShell()) {
     Document* doc = presShell->GetDocument();
     nsHTMLDocument* htmlDoc =
         doc && doc->IsHTMLOrXHTML() ? doc->AsHTMLDocument() : nullptr;
 
     if (htmlDoc) {
       nsAutoString designMode;
       htmlDoc->GetDesignMode(designMode);
 
       if (designMode.EqualsLiteral("on")) {
         // Hold on to the editor object to let the document reattach to the
         // same editor object, instead of creating a new one.
-        RefPtr<HTMLEditor> htmlEditor = mDocShell->GetHTMLEditor();
+        RefPtr<HTMLEditor> htmlEditor = GetDocShell()->GetHTMLEditor();
         Unused << htmlEditor;
         htmlDoc->SetDesignMode(NS_LITERAL_STRING("off"), Nothing(),
                                IgnoreErrors());
 
         htmlDoc->SetDesignMode(NS_LITERAL_STRING("on"), Nothing(),
                                IgnoreErrors());
       } else {
         // Re-initialize the presentation for contenteditable documents
         bool editable = false, hasEditingSession = false;
-        mDocShell->GetEditable(&editable);
-        mDocShell->GetHasEditingSession(&hasEditingSession);
-        RefPtr<HTMLEditor> htmlEditor = mDocShell->GetHTMLEditor();
+        GetDocShell()->GetEditable(&editable);
+        GetDocShell()->GetHasEditingSession(&hasEditingSession);
+        RefPtr<HTMLEditor> htmlEditor = GetDocShell()->GetHTMLEditor();
         if (editable && hasEditingSession && htmlEditor) {
           htmlEditor->PostCreate();
         }
       }
     }
   }
 
   mInShow = false;
@@ -820,40 +894,44 @@ bool nsFrameLoader::Show(int32_t marginW
     return false;
   }
   return true;
 }
 
 void nsFrameLoader::MarginsChanged(uint32_t aMarginWidth,
                                    uint32_t aMarginHeight) {
   // We assume that the margins are always zero for remote frames.
-  if (IsRemoteFrame()) return;
+  if (IsRemoteFrame()) {
+    return;
+  }
 
   // If there's no docshell, we're probably not up and running yet.
   // nsFrameLoader::Show() will take care of setting the right
   // margins.
-  if (!mDocShell) return;
+  if (!GetDocShell()) {
+    return;
+  }
 
   // Set the margins
-  mDocShell->SetMarginWidth(aMarginWidth);
-  mDocShell->SetMarginHeight(aMarginHeight);
+  GetDocShell()->SetMarginWidth(aMarginWidth);
+  GetDocShell()->SetMarginHeight(aMarginHeight);
 
   // There's a cached property declaration block
   // that needs to be updated
-  if (Document* doc = mDocShell->GetDocument()) {
+  if (Document* doc = GetDocShell()->GetDocument()) {
     for (nsINode* cur = doc; cur; cur = cur->GetNextNode()) {
       if (cur->IsHTMLElement(nsGkAtoms::body)) {
         static_cast<HTMLBodyElement*>(cur)->ClearMappedServoStyle();
       }
     }
   }
 
   // Trigger a restyle if there's a prescontext
   // FIXME: This could do something much less expensive.
-  if (nsPresContext* presContext = mDocShell->GetPresContext()) {
+  if (nsPresContext* presContext = GetDocShell()->GetPresContext()) {
     // rebuild, because now the same nsMappedAttributes* will produce
     // a different style
     presContext->RebuildAllStyleData(nsChangeHint(0),
                                      RestyleHint::RestyleSubtree());
   }
 }
 
 bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
@@ -932,23 +1010,25 @@ void nsFrameLoader::Hide() {
   if (mHideCalled) {
     return;
   }
   if (mInShow) {
     mHideCalled = true;
     return;
   }
 
-  if (!mDocShell) return;
+  if (!GetDocShell()) {
+    return;
+  }
 
   nsCOMPtr<nsIContentViewer> contentViewer;
-  mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
+  GetDocShell()->GetContentViewer(getter_AddRefs(contentViewer));
   if (contentViewer) contentViewer->SetSticky(false);
 
-  RefPtr<nsDocShell> baseWin = mDocShell;
+  RefPtr<nsDocShell> baseWin = GetDocShell();
   baseWin->SetVisibility(false);
   baseWin->SetParentWidget(nullptr);
 }
 
 void nsFrameLoader::ForceLayoutIfNecessary() {
   nsIFrame* frame = GetPrimaryFrameOfOwningContent();
   if (!frame) {
     return;
@@ -1649,36 +1729,36 @@ void nsFrameLoader::StartDestroy() {
     dynamicSubframeRemoval = !mIsTopLevelContent && !doc->InUnlinkOrDeletion();
     doc->SetSubDocumentFor(mOwnerContent, nullptr);
     MaybeUpdatePrimaryTabParent(eTabParentRemoved);
     SetOwnerContent(nullptr);
   }
 
   // Seems like this is a dynamic frame removal.
   if (dynamicSubframeRemoval) {
-    if (mDocShell) {
-      mDocShell->RemoveFromSessionHistory();
+    if (GetDocShell()) {
+      GetDocShell()->RemoveFromSessionHistory();
     }
   }
 
   // Let the tree owner know we're gone.
   if (mIsTopLevelContent) {
-    if (mDocShell) {
+    if (GetDocShell()) {
       nsCOMPtr<nsIDocShellTreeItem> parentItem;
-      mDocShell->GetParent(getter_AddRefs(parentItem));
+      GetDocShell()->GetParent(getter_AddRefs(parentItem));
       nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
       if (owner) {
-        owner->ContentShellRemoved(mDocShell);
+        owner->ContentShellRemoved(GetDocShell());
       }
     }
   }
 
   // Let our window know that we are gone
-  if (mDocShell) {
-    nsCOMPtr<nsPIDOMWindowOuter> win_private(mDocShell->GetWindow());
+  if (GetDocShell()) {
+    nsCOMPtr<nsPIDOMWindowOuter> win_private(GetDocShell()->GetWindow());
     if (win_private) {
       win_private->SetFrameElementInternal(nullptr);
     }
   }
 
   nsCOMPtr<nsIRunnable> destroyRunnable =
       new nsFrameLoaderDestroyRunnable(this);
   if (mNeedsAsyncDestroy || !doc ||
@@ -1748,20 +1828,21 @@ void nsFrameLoader::DestroyDocShell() {
   }
 
   // Fire the "unload" event if we're in-process.
   if (mChildMessageManager) {
     mChildMessageManager->FireUnloadEvent();
   }
 
   // Destroy the docshell.
-  if (mDocShell) {
-    mDocShell->Destroy();
+  if (GetDocShell()) {
+    GetDocShell()->Destroy();
   }
-  mDocShell = nullptr;
+
+  mBrowsingContext = nullptr;
 
   if (mChildMessageManager) {
     // Stop handling events in the in-process frame script.
     mChildMessageManager->DisconnectEventListeners();
   }
 }
 
 void nsFrameLoader::DestroyComplete() {
@@ -1883,47 +1964,18 @@ bool nsFrameLoader::ShouldUseRemoteProce
   // Otherwise, we're remote if we have "remote=true" and we're either a
   // browser frame or a XUL element.
   return (OwnerIsMozBrowserFrame() ||
           mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
          mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::remote,
                                     nsGkAtoms::_true, eCaseMatters);
 }
 
-static already_AddRefed<BrowsingContext> CreateBrowsingContext(
-    BrowsingContext* aParentContext, BrowsingContext* aOpenerContext,
-    const nsAString& aName, bool aIsContent) {
-  // If we're content but our parent isn't, we're going to want to start a new
-  // browsing context tree.
-  if (aIsContent && aParentContext && !aParentContext->IsContent()) {
-    aParentContext = nullptr;
-  }
-
-  BrowsingContext::Type type = aIsContent ? BrowsingContext::Type::Content
-                                          : BrowsingContext::Type::Chrome;
-
-  return BrowsingContext::Create(aParentContext, aOpenerContext, aName, type);
-}
-
-static void GetFrameName(Element* aOwnerContent, nsAString& aFrameName) {
-  int32_t namespaceID = aOwnerContent->GetNameSpaceID();
-  if (namespaceID == kNameSpaceID_XHTML && !aOwnerContent->IsInHTMLDocument()) {
-    aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aFrameName);
-  } else {
-    aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, aFrameName);
-    // XXX if no NAME then use ID, after a transition period this will be
-    // changed so that XUL only uses ID too (bug 254284).
-    if (aFrameName.IsEmpty() && namespaceID == kNameSpaceID_XUL) {
-      aOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aFrameName);
-    }
-  }
-}
-
 nsresult nsFrameLoader::MaybeCreateDocShell() {
-  if (mDocShell) {
+  if (GetDocShell()) {
     return NS_OK;
   }
   if (IsRemoteFrame()) {
     return NS_OK;
   }
   NS_ENSURE_STATE(!mDestroyCalled);
 
   // Get our parent docshell off the document of mOwnerContent
@@ -1942,151 +1994,125 @@ nsresult nsFrameLoader::MaybeCreateDocSh
   }
 
   if (!doc->IsActive()) {
     // Don't allow subframe loads in non-active documents.
     // (See bug 610571 comment 5.)
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  // Determine our parent nsDocShell
   RefPtr<nsDocShell> parentDocShell = nsDocShell::Cast(doc->GetDocShell());
   if (NS_WARN_IF(!parentDocShell)) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  RefPtr<BrowsingContext> parentBC = parentDocShell->GetBrowsingContext();
-  MOZ_ASSERT(parentBC, "docShell must have BrowsingContext");
-
-  // Determine the frame name for the new browsing context.
-  nsAutoString frameName;
-  GetFrameName(mOwnerContent, frameName);
-
-  // Check if our new context is chrome or content
-  bool isContent = parentBC->IsContent() ||
-                   mOwnerContent->AttrValueIs(kNameSpaceID_None, TypeAttrName(),
-                                              nsGkAtoms::content, eIgnoreCase);
-
-  // Force mozbrowser frames to always be content, even if the mozbrowser
-  // interfaces are disabled.
-  nsCOMPtr<nsIMozBrowserFrame> mozbrowser =
-      mOwnerContent->GetAsMozBrowserFrame();
-  if (!isContent && mozbrowser) {
-    mozbrowser->GetMozbrowser(&isContent);
-  }
-
-  RefPtr<BrowsingContext> openerBC =
-      mOpener ? mOpener->GetBrowsingContext() : nullptr;
-  RefPtr<BrowsingContext> browsingContext =
-      CreateBrowsingContext(parentBC, openerBC, frameName, isContent);
-
-  mDocShell = nsDocShell::Create(browsingContext);
-  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
-
-  mIsTopLevelContent = isContent && !parentBC->IsContent();
+  // nsDocShell::Create will attach itself to the passed browsing
+  // context inside of nsDocShell::Create
+  RefPtr<nsDocShell> docShell = nsDocShell::Create(mBrowsingContext);
+  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
+
+  mIsTopLevelContent =
+      mBrowsingContext->IsContent() && !mBrowsingContext->GetParent();
   if (!mNetworkCreated && !mIsTopLevelContent) {
-    mDocShell->SetCreatedDynamically(true);
+    docShell->SetCreatedDynamically(true);
   }
 
   if (mIsTopLevelContent) {
     // Manually add ourselves to our parent's docshell, as BrowsingContext won't
     // have done this for us.
     //
     // XXX(nika): Consider removing the DocShellTree in the future, for
     // consistency between local and remote frames..
-    parentDocShell->AddChild(mDocShell);
+    parentDocShell->AddChild(docShell);
   }
 
   // Now that we are part of the DocShellTree, attach our DocShell to our
   // parent's TreeOwner.
   nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
   parentDocShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
-  AddTreeItemToTreeOwner(mDocShell, parentTreeOwner);
+  AddTreeItemToTreeOwner(docShell, parentTreeOwner);
 
   // Make sure all nsDocShells have links back to the content element in the
   // nearest enclosing chrome shell.
   RefPtr<EventTarget> chromeEventHandler;
-  if (parentBC->IsContent()) {
+  bool parentIsContent = parentDocShell->GetBrowsingContext()->IsContent();
+  if (parentIsContent) {
     // Our parent shell is a content shell. Get the chrome event handler from it
     // and use that for our shell as well.
     parentDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
   } else {
     // Our parent shell is a chrome shell. It is therefore our nearest enclosing
     // chrome shell.
     chromeEventHandler = mOwnerContent;
   }
 
-  mDocShell->SetChromeEventHandler(chromeEventHandler);
-
-  // This is nasty, this code (the mDocShell->GetWindow() below)
+  docShell->SetChromeEventHandler(chromeEventHandler);
+
+  // This is nasty, this code (the docShell->GetWindow() below)
   // *must* come *after* the above call to
-  // mDocShell->SetChromeEventHandler() for the global window to get
+  // docShell->SetChromeEventHandler() for the global window to get
   // the right chrome event handler.
 
   // Tell the window about the frame that hosts it.
-  nsCOMPtr<nsPIDOMWindowOuter> newWindow = mDocShell->GetWindow();
+  nsCOMPtr<nsPIDOMWindowOuter> newWindow = docShell->GetWindow();
   if (NS_WARN_IF(!newWindow)) {
     // Do not call Destroy() here. See bug 472312.
     NS_WARNING("Something wrong when creating the docshell for a frameloader!");
     return NS_ERROR_FAILURE;
   }
 
   newWindow->SetFrameElementInternal(mOwnerContent);
 
-  // Set the opener window if we have one provided here XXX(nika): We
-  // should tell our BrowsingContext this as we create it.
   // TODO(farre): Remove this when nsGlobalWindowOuter::GetOpenerWindowOuter
   // starts using BrowsingContext::GetOpener.
-  if (mOpener) {
-    newWindow->SetOpenerWindow(mOpener, true);
-    mOpener = nullptr;
+  if (RefPtr<BrowsingContext> opener = mBrowsingContext->GetOpener()) {
+    newWindow->SetOpenerWindow(opener->GetDOMWindow(), true);
   }
 
   // Allow scripts to close the docshell if specified.
   if (mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
       mOwnerContent->AttrValueIs(kNameSpaceID_None,
                                  nsGkAtoms::allowscriptstoclose,
                                  nsGkAtoms::_true, eCaseMatters)) {
     nsGlobalWindowOuter::Cast(newWindow)->AllowScriptsToClose();
   }
 
   // This is kinda whacky, this call doesn't really create anything,
   // but it must be called to make sure things are properly
   // initialized.
-  RefPtr<nsDocShell> docShell = mDocShell;
   if (NS_FAILED(docShell->Create())) {
     // Do not call Destroy() here. See bug 472312.
     NS_WARNING("Something wrong when creating the docshell for a frameloader!");
     return NS_ERROR_FAILURE;
   }
 
   // If we are an in-process browser, we want to set up our session history. We
   // do this by creating both the child SHistory (which is in the nsDocShell),
   // and creating the corresponding in-process ParentSHistory.
   if (mIsTopLevelContent && mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
       !mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory)) {
     // XXX(nika): Set this up more explicitly?
-    nsresult rv = mDocShell->InitSessionHistory();
+    nsresult rv = docShell->InitSessionHistory();
     NS_ENSURE_SUCCESS(rv, rv);
     mParentSHistory = new ParentSHistory(this);
   }
 
   OriginAttributes attrs;
-  if (parentDocShell->ItemType() == mDocShell->ItemType()) {
+  if (parentDocShell->ItemType() == docShell->ItemType()) {
     attrs = parentDocShell->GetOriginAttributes();
   }
 
   // Inherit origin attributes from parent document if
   // 1. It's in a content docshell.
   // 2. its nodePrincipal is not a SystemPrincipal.
   // 3. It's not a mozbrowser frame.
   //
   // For example, firstPartyDomain is computed from top-level document, it
   // doesn't exist in the top-level docshell.
-  if (parentBC->IsContent() &&
+  if (parentIsContent &&
       !nsContentUtils::IsSystemPrincipal(doc->NodePrincipal()) &&
       !OwnerIsMozBrowserFrame()) {
     OriginAttributes oa = doc->NodePrincipal()->OriginAttributesRef();
 
     // Assert on the firstPartyDomain from top-level docshell should be empty
     MOZ_ASSERT_IF(mIsTopLevelContent, attrs.mFirstPartyDomain.IsEmpty());
 
     // So far we want to make sure Inherit doesn't override any other origin
@@ -2104,28 +2130,28 @@ nsresult nsFrameLoader::MaybeCreateDocSh
                "attribute.");
 
     attrs = oa;
   }
 
   if (OwnerIsMozBrowserFrame()) {
     attrs.mAppId = nsIScriptSecurityManager::NO_APP_ID;
     attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
-    mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
+    docShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
   } else {
     nsCOMPtr<nsIDocShellTreeItem> parentCheck;
-    mDocShell->GetSameTypeParent(getter_AddRefs(parentCheck));
+    docShell->GetSameTypeParent(getter_AddRefs(parentCheck));
     if (!!parentCheck) {
-      mDocShell->SetIsFrame();
+      docShell->SetIsFrame();
     }
   }
 
   // Apply sandbox flags even if our owner is not an iframe, as this copies
   // flags from our owning content's owning document.
-  // Note: ApplySandboxFlags should be called after mDocShell->SetFrameType
+  // Note: ApplySandboxFlags should be called after docShell->SetFrameType
   // because we need to get the correct presentation URL in ApplySandboxFlags.
   uint32_t sandboxFlags = 0;
   HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
   if (iframe) {
     sandboxFlags = iframe->GetSandboxFlags();
   }
   ApplySandboxFlags(sandboxFlags);
 
@@ -2141,63 +2167,61 @@ nsresult nsFrameLoader::MaybeCreateDocSh
     return rv;
   }
   attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
 
   if (OwnerIsMozBrowserFrame()) {
     // For inproc frames, set the docshell properties.
     nsAutoString name;
     if (mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
-      mDocShell->SetName(name);
+      docShell->SetName(name);
     }
-    mDocShell->SetFullscreenAllowed(
+    docShell->SetFullscreenAllowed(
         mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
         mOwnerContent->HasAttr(kNameSpaceID_None,
                                nsGkAtoms::mozallowfullscreen));
     bool isPrivate = mOwnerContent->HasAttr(kNameSpaceID_None,
                                             nsGkAtoms::mozprivatebrowsing);
     if (isPrivate) {
-      if (mDocShell->GetHasLoadedNonBlankURI()) {
+      if (docShell->GetHasLoadedNonBlankURI()) {
         nsContentUtils::ReportToConsoleNonLocalized(
             NS_LITERAL_STRING("We should not switch to Private Browsing after "
                               "loading a document."),
             nsIScriptError::warningFlag,
             NS_LITERAL_CSTRING("mozprivatebrowsing"), nullptr);
       } else {
         // This handles the case where a frames private browsing is set by
         // chrome flags and not inherited by its parent.
         attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
       }
     }
   }
 
-  nsDocShell::Cast(mDocShell)->SetOriginAttributes(attrs);
+  docShell->SetOriginAttributes(attrs);
 
   // Typically there will be a window, however for some cases such as printing
   // the document is cloned with a docshell that has no window.  We check
   // that the window exists to ensure we don't try to gather ancestors for
   // those cases.
   nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
-  if (!mDocShell->GetIsMozBrowser() &&
-      parentDocShell->ItemType() == mDocShell->ItemType() &&
+  if (!docShell->GetIsMozBrowser() &&
+      parentDocShell->ItemType() == docShell->ItemType() &&
       !doc->IsStaticDocument() && win) {
     // Propagate through the ancestor principals.
     nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
     // Make a copy, so we can modify it.
     ancestorPrincipals = doc->AncestorPrincipals();
     ancestorPrincipals.InsertElementAt(0, doc->NodePrincipal());
-    nsDocShell::Cast(mDocShell)->SetAncestorPrincipals(
-        std::move(ancestorPrincipals));
+    docShell->SetAncestorPrincipals(std::move(ancestorPrincipals));
 
     // Repeat for outer window IDs.
     nsTArray<uint64_t> ancestorOuterWindowIDs;
     ancestorOuterWindowIDs = doc->AncestorOuterWindowIDs();
     ancestorOuterWindowIDs.InsertElementAt(0, win->WindowID());
-    nsDocShell::Cast(mDocShell)->SetAncestorOuterWindowIDs(
-        std::move(ancestorOuterWindowIDs));
+    docShell->SetAncestorOuterWindowIDs(std::move(ancestorOuterWindowIDs));
   }
 
   ReallyLoadFrameScripts();
   InitializeBrowserAPI();
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->NotifyObservers(ToSupports(this), "inprocess-browser-shown", nullptr);
@@ -2244,38 +2268,38 @@ nsresult nsFrameLoader::CheckForRecursiv
   MOZ_ASSERT(!IsRemoteFrame(),
              "Shouldn't call CheckForRecursiveLoad on remote frames.");
 
   mDepthTooGreat = false;
   rv = MaybeCreateDocShell();
   if (NS_FAILED(rv)) {
     return rv;
   }
-  NS_ASSERTION(mDocShell, "MaybeCreateDocShell succeeded, but null mDocShell");
-  if (!mDocShell) {
+  MOZ_ASSERT(GetDocShell(), "MaybeCreateDocShell succeeded, but null docShell");
+  if (!GetDocShell()) {
     return NS_ERROR_FAILURE;
   }
 
   // Check that we're still in the docshell tree.
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
-  mDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
+  GetDocShell()->GetTreeOwner(getter_AddRefs(treeOwner));
   NS_WARNING_ASSERTION(treeOwner,
                        "Trying to load a new url to a docshell without owner!");
   NS_ENSURE_STATE(treeOwner);
 
-  if (mDocShell->ItemType() != nsIDocShellTreeItem::typeContent) {
+  if (GetDocShell()->ItemType() != nsIDocShellTreeItem::typeContent) {
     // No need to do recursion-protection here XXXbz why not??  Do we really
     // trust people not to screw up with non-content docshells?
     return NS_OK;
   }
 
   // Bug 8065: Don't exceed some maximum depth in content frames
   // (MAX_DEPTH_CONTENT_FRAMES)
   nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
-  mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
+  GetDocShell()->GetSameTypeParent(getter_AddRefs(parentAsItem));
   int32_t depth = 0;
   while (parentAsItem) {
     ++depth;
 
     if (depth >= MAX_DEPTH_CONTENT_FRAMES) {
       mDepthTooGreat = true;
       NS_WARNING("Too many nested content frames so giving up");
 
@@ -2297,17 +2321,17 @@ nsresult nsFrameLoader::CheckForRecursiv
   if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("about")) {
     rv = aURI->GetPathQueryRef(buffer);
     if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("srcdoc")) {
       // Duplicates allowed up to depth limits
       return NS_OK;
     }
   }
   int32_t matchCount = 0;
-  mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
+  GetDocShell()->GetSameTypeParent(getter_AddRefs(parentAsItem));
   while (parentAsItem) {
     // Check the parent URI with the URI we're loading
     nsCOMPtr<nsIWebNavigation> parentAsNav(do_QueryInterface(parentAsItem));
     if (parentAsNav) {
       // Does the URI match the one we're about to load?
       nsCOMPtr<nsIURI> parentURI;
       parentAsNav->GetCurrentURI(getter_AddRefs(parentURI));
       if (parentURI) {
@@ -2575,37 +2599,25 @@ bool nsFrameLoader::TryRemoteBrowser() {
       Unused << window->GetNextTabParentId(&nextTabParentId);
     }
   }
 
   nsCOMPtr<Element> ownerElement = mOwnerContent;
 
   // If we're in a content process, create a BrowserBridgeChild actor.
   if (XRE_IsContentProcess()) {
-    // Determine the frame name for the new browsing context.
-    nsAutoString frameName;
-    GetFrameName(mOwnerContent, frameName);
-
-    RefPtr<BrowsingContext> parentBC;
-    parentDocShell->GetBrowsingContext(getter_AddRefs(parentBC));
-    MOZ_ASSERT(parentBC, "docShell must have BrowsingContext");
-
-    // XXX(nika): due to limitations with Browsing Context Groups and multiple
-    // processes, we can't link up aParent yet! (Bug 1532661)
-    RefPtr<BrowsingContext> browsingContext =
-        CreateBrowsingContext(parentBC, nullptr, frameName, true);
-
     mBrowserBridgeChild = BrowserBridgeChild::Create(
-        this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE), browsingContext);
+        this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
+        mBrowsingContext);
     return !!mBrowserBridgeChild;
   }
 
-  mRemoteBrowser =
-      ContentParent::CreateBrowser(context, ownerElement, openerContentParent,
-                                   sameTabGroupAs, nextTabParentId);
+  mRemoteBrowser = ContentParent::CreateBrowser(
+      context, ownerElement, mBrowsingContext, openerContentParent,
+      sameTabGroupAs, nextTabParentId);
   if (!mRemoteBrowser) {
     return false;
   }
 
   // We no longer need the remoteType attribute on the frame element.
   // The remoteType can be queried by asking the message manager instead.
   ownerElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType, false);
 
@@ -2654,17 +2666,17 @@ bool nsFrameLoader::TryRemoteBrowser() {
   ReallyLoadFrameScripts();
   InitializeBrowserAPI();
 
   return true;
 }
 
 bool nsFrameLoader::IsRemoteFrame() {
   if (mIsRemoteFrame) {
-    MOZ_ASSERT(!mDocShell, "Found a remote frame with a DocShell");
+    MOZ_ASSERT(!GetDocShell(), "Found a remote frame with a DocShell");
     return true;
   }
   return false;
 }
 
 mozilla::dom::PBrowserParent* nsFrameLoader::GetRemoteBrowser() const {
   return mRemoteBrowser;
 }
@@ -2727,32 +2739,32 @@ void nsFrameLoader::ActivateFrameEvent(c
   bool ok = mRemoteBrowser->SendActivateFrameEvent(nsString(aType), aCapture);
   if (!ok) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
   }
 }
 
 nsresult nsFrameLoader::CreateStaticClone(nsFrameLoader* aDest) {
   aDest->MaybeCreateDocShell();
-  NS_ENSURE_STATE(aDest->mDocShell);
-
-  nsCOMPtr<Document> kungFuDeathGrip = aDest->mDocShell->GetDocument();
+  NS_ENSURE_STATE(aDest->GetDocShell());
+
+  nsCOMPtr<Document> kungFuDeathGrip = aDest->GetDocShell()->GetDocument();
   Unused << kungFuDeathGrip;
 
   nsCOMPtr<nsIContentViewer> viewer;
-  aDest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
+  aDest->GetDocShell()->GetContentViewer(getter_AddRefs(viewer));
   NS_ENSURE_STATE(viewer);
 
   nsIDocShell* origDocShell = GetDocShell(IgnoreErrors());
   NS_ENSURE_STATE(origDocShell);
 
   nsCOMPtr<Document> doc = origDocShell->GetDocument();
   NS_ENSURE_STATE(doc);
 
-  nsCOMPtr<Document> clonedDoc = doc->CreateStaticClone(aDest->mDocShell);
+  nsCOMPtr<Document> clonedDoc = doc->CreateStaticClone(aDest->GetDocShell());
 
   viewer->SetDocument(clonedDoc);
   return NS_OK;
 }
 
 bool nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL,
                                                bool aRunInGlobalScope) {
   auto* tabParent = TabParent::GetFrom(GetRemoteBrowser());
@@ -2880,23 +2892,23 @@ nsresult nsFrameLoader::EnsureMessageMan
   }
 
   mMessageManager = new ChromeMessageSender(parentManager);
   if (!IsRemoteFrame()) {
     nsresult rv = MaybeCreateDocShell();
     if (NS_FAILED(rv)) {
       return rv;
     }
-    NS_ASSERTION(mDocShell,
-                 "MaybeCreateDocShell succeeded, but null mDocShell");
-    if (!mDocShell) {
+    MOZ_ASSERT(GetDocShell(),
+               "MaybeCreateDocShell succeeded, but null docShell");
+    if (!GetDocShell()) {
       return NS_ERROR_FAILURE;
     }
     mChildMessageManager = InProcessTabChildMessageManager::Create(
-        mDocShell, mOwnerContent, mMessageManager);
+        GetDocShell(), mOwnerContent, mMessageManager);
     NS_ENSURE_TRUE(mChildMessageManager, NS_ERROR_UNEXPECTED);
   }
   return NS_OK;
 }
 
 nsresult nsFrameLoader::ReallyLoadFrameScripts() {
   nsresult rv = EnsureMessageManager();
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -2932,31 +2944,31 @@ void nsFrameLoader::SetDetachedSubdocFra
 
 nsIFrame* nsFrameLoader::GetDetachedSubdocFrame(
     Document** aContainerDoc) const {
   NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
   return mDetachedSubdocFrame.GetFrame();
 }
 
 void nsFrameLoader::ApplySandboxFlags(uint32_t sandboxFlags) {
-  if (mDocShell) {
+  if (GetDocShell()) {
     uint32_t parentSandboxFlags = mOwnerContent->OwnerDoc()->GetSandboxFlags();
 
     // The child can only add restrictions, never remove them.
     sandboxFlags |= parentSandboxFlags;
 
     // If this frame is a receiving browsing context, we should add
     // sandboxed auxiliary navigation flag to sandboxFlags. See
     // https://w3c.github.io/presentation-api/#creating-a-receiving-browsing-context
     nsAutoString presentationURL;
-    nsContentUtils::GetPresentationURL(mDocShell, presentationURL);
+    nsContentUtils::GetPresentationURL(GetDocShell(), presentationURL);
     if (!presentationURL.IsEmpty()) {
       sandboxFlags |= SANDBOXED_AUXILIARY_NAVIGATION;
     }
-    mDocShell->SetSandboxFlags(sandboxFlags);
+    GetDocShell()->SetSandboxFlags(sandboxFlags);
   }
 }
 
 /* virtual */
 void nsFrameLoader::AttributeChanged(mozilla::dom::Element* aElement,
                                      int32_t aNameSpaceID, nsAtom* aAttribute,
                                      int32_t aModType,
                                      const nsAttrValue* aOldValue) {
@@ -2972,23 +2984,23 @@ void nsFrameLoader::AttributeChanged(moz
   }
 
   // Note: This logic duplicates a lot of logic in
   // MaybeCreateDocshell.  We should fix that.
 
   // Notify our enclosing chrome that our type has changed.  We only do this
   // if our parent is chrome, since in all other cases we're random content
   // subframes and the treeowner shouldn't worry about us.
-  if (!mDocShell) {
+  if (!GetDocShell()) {
     MaybeUpdatePrimaryTabParent(eTabParentChanged);
     return;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> parentItem;
-  mDocShell->GetParent(getter_AddRefs(parentItem));
+  GetDocShell()->GetParent(getter_AddRefs(parentItem));
   if (!parentItem) {
     return;
   }
 
   if (parentItem->ItemType() != nsIDocShellTreeItem::typeChrome) {
     return;
   }
 
@@ -3000,24 +3012,26 @@ void nsFrameLoader::AttributeChanged(moz
 
   bool is_primary = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::primary,
                                           nsGkAtoms::_true, eIgnoreCase);
 
 #ifdef MOZ_XUL
   // when a content panel is no longer primary, hide any open popups it may have
   if (!is_primary) {
     nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-    if (pm) pm->HidePopupsInDocShell(mDocShell);
+    if (pm) {
+      pm->HidePopupsInDocShell(GetDocShell());
+    }
   }
 #endif
 
-  parentTreeOwner->ContentShellRemoved(mDocShell);
+  parentTreeOwner->ContentShellRemoved(GetDocShell());
   if (aElement->AttrValueIs(kNameSpaceID_None, TypeAttrName(),
                             nsGkAtoms::content, eIgnoreCase)) {
-    parentTreeOwner->ContentShellAdded(mDocShell, is_primary);
+    parentTreeOwner->ContentShellAdded(GetDocShell(), is_primary);
   }
 }
 
 /**
  * Send the RequestNotifyAfterRemotePaint message to the current Tab.
  */
 void nsFrameLoader::RequestNotifyAfterRemotePaint() {
   // If remote browsing (e10s), handle this with the TabParent.
@@ -3112,17 +3126,18 @@ already_AddRefed<mozilla::dom::Promise> 
   }
 
   gfx::IntRect rect = gfx::IntRect::RoundOut(gfx::Rect(aX, aY, aW, aH));
 
   if (IsRemoteFrame()) {
     gfx::CrossProcessPaint::StartRemote(mRemoteBrowser->GetTabId(), rect,
                                         aScale, color, promise);
   } else {
-    gfx::CrossProcessPaint::StartLocal(mDocShell, rect, aScale, color, promise);
+    gfx::CrossProcessPaint::StartLocal(GetDocShell(), rect, aScale, color,
+                                       promise);
   }
 
   return promise.forget();
 }
 
 already_AddRefed<nsITabParent> nsFrameLoader::GetTabParent() {
   return do_AddRef(mRemoteBrowser);
 }
@@ -3147,17 +3162,17 @@ already_AddRefed<BrowsingContext> nsFram
   if (IsRemoteFrame() &&
       (mRemoteBrowser || mBrowserBridgeChild || TryRemoteBrowser())) {
     if (mRemoteBrowser) {
       browsingContext = mRemoteBrowser->GetBrowsingContext();
     } else {
       browsingContext = mBrowserBridgeChild->GetBrowsingContext();
     }
   } else if (GetDocShell(IgnoreErrors())) {
-    browsingContext = nsDocShell::Cast(mDocShell)->GetBrowsingContext();
+    browsingContext = GetDocShell()->GetBrowsingContext();
   }
   return browsingContext.forget();
 }
 
 void nsFrameLoader::InitializeBrowserAPI() {
   if (!OwnerIsMozBrowserFrame()) {
     return;
   }
@@ -3194,17 +3209,18 @@ void nsFrameLoader::StartPersistence(
     ErrorResult& aRv) {
   MOZ_ASSERT(aRecv);
 
   if (mRemoteBrowser) {
     mRemoteBrowser->StartPersistence(aOuterWindowID, aRecv, aRv);
     return;
   }
 
-  nsCOMPtr<Document> rootDoc = mDocShell ? mDocShell->GetDocument() : nullptr;
+  nsCOMPtr<Document> rootDoc =
+      GetDocShell() ? GetDocShell()->GetDocument() : nullptr;
   nsCOMPtr<Document> foundDoc;
   if (aOuterWindowID) {
     foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc,
                                                                aOuterWindowID);
   } else {
     foundDoc = rootDoc;
   }
 
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -15,16 +15,17 @@
 #include "nsDocShell.h"
 #include "nsStringFwd.h"
 #include "nsPoint.h"
 #include "nsSize.h"
 #include "nsWrapperCache.h"
 #include "nsIURI.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/BrowsingContext.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ParentSHistory.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "nsStubMutationObserver.h"
 #include "Units.h"
 #include "nsIFrame.h"
 #include "nsPluginTags.h"
@@ -44,17 +45,16 @@ class nsIPrintSettings;
 class nsIWebBrowserPersistDocumentReceiver;
 class nsIWebProgressListener;
 
 namespace mozilla {
 
 class OriginAttributes;
 
 namespace dom {
-class BrowsingContext;
 class ChromeMessageSender;
 class ContentParent;
 class InProcessTabChildMessageManager;
 class MessageSender;
 class PBrowserParent;
 class ProcessMessageManager;
 class Promise;
 class TabParent;
@@ -94,17 +94,17 @@ class nsFrameLoader final : public nsStu
   typedef mozilla::dom::PBrowserParent PBrowserParent;
   typedef mozilla::dom::Document Document;
   typedef mozilla::dom::TabParent TabParent;
   typedef mozilla::layout::RenderFrame RenderFrame;
 
  public:
   // Called by Frame Elements to create a new FrameLoader.
   static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
-                               nsPIDOMWindowOuter* aOpener,
+                               mozilla::dom::BrowsingContext* aOpener,
                                bool aNetworkCreated);
 
   // Called by nsFrameLoaderOwner::ChangeRemoteness when switching out
   // FrameLoaders.
   static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
                                const mozilla::dom::RemotenessOptions& aOptions);
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID)
@@ -113,17 +113,19 @@ class nsFrameLoader final : public nsStu
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsFrameLoader)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   nsresult CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
   void StartDestroy();
   void DestroyDocShell();
   void DestroyComplete();
-  nsIDocShell* GetExistingDocShell() { return mDocShell; }
+  nsIDocShell* GetExistingDocShell() const {
+    return mBrowsingContext ? mBrowsingContext->GetDocShell() : nullptr;
+  }
   mozilla::dom::InProcessTabChildMessageManager* GetTabChildMessageManager()
       const {
     return mChildMessageManager;
   }
   nsresult CreateStaticClone(nsFrameLoader* aDest);
   nsresult UpdatePositionAndSize(nsSubDocumentFrame* aIFrame);
 
   // WebIDL methods
@@ -363,19 +365,21 @@ class nsFrameLoader final : public nsStu
   // public because a callback needs these.
   RefPtr<mozilla::dom::ChromeMessageSender> mMessageManager;
   RefPtr<mozilla::dom::InProcessTabChildMessageManager> mChildMessageManager;
 
   virtual JSObject* WrapObject(JSContext* cx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
  private:
-  nsFrameLoader(mozilla::dom::Element* aOwner, nsPIDOMWindowOuter* aOpener,
+  nsFrameLoader(mozilla::dom::Element* aOwner,
+                mozilla::dom::BrowsingContext* aBrowsingContext,
                 bool aNetworkCreated);
   nsFrameLoader(mozilla::dom::Element* aOwner,
+                mozilla::dom::BrowsingContext* aBrowsingContext,
                 const mozilla::dom::RemotenessOptions& aOptions);
   ~nsFrameLoader();
 
   void SetOwnerContent(mozilla::dom::Element* aContent);
 
   bool ShouldUseRemoteProcess();
 
   /**
@@ -395,16 +399,20 @@ class nsFrameLoader final : public nsStu
 
   /**
    * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
    * initialize mDocShell.
    */
   nsresult MaybeCreateDocShell();
   nsresult EnsureMessageManager();
   nsresult ReallyLoadFrameScripts();
+  nsDocShell* GetDocShell() const {
+    return mBrowsingContext ? nsDocShell::Cast(mBrowsingContext->GetDocShell())
+                            : nullptr;
+  }
 
   // Updates the subdocument position and size. This gets called only
   // when we have our own in-process DocShell.
   void UpdateBaseWindowPositionAndSize(nsSubDocumentFrame* aIFrame);
 
   /**
    * Checks whether a load of the given URI should be allowed, and returns an
    * error result if it should not.
@@ -438,17 +446,17 @@ class nsFrameLoader final : public nsStu
   nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext,
                             nsIURI* aURI = nullptr);
 
   enum TabParentChange { eTabParentRemoved, eTabParentChanged };
   void MaybeUpdatePrimaryTabParent(TabParentChange aChange);
 
   nsresult PopulateUserContextIdFromAttribute(mozilla::OriginAttributes& aAttr);
 
-  RefPtr<nsDocShell> mDocShell;
+  RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
   nsCOMPtr<nsIURI> mURIToLoad;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsCOMPtr<nsIContentSecurityPolicy> mCsp;
   mozilla::dom::Element* mOwnerContent;  // WEAK
 
   // After the frameloader has been removed from the DOM but before all of the
   // messages from the frame have been received, we keep a strong reference to
   // our <browser> element.
@@ -459,19 +467,16 @@ class nsFrameLoader final : public nsStu
   WeakFrame mDetachedSubdocFrame;
   // Stores the containing document of the frame corresponding to this
   // frame loader. This is reference is kept valid while the subframe's
   // presentation is detached and stored in mDetachedSubdocFrame. This
   // enables us to detect whether the frame has moved documents during
   // a reframe, so that we know not to restore the presentation.
   RefPtr<Document> mContainerDocWhileDetached;
 
-  // An opener window which should be used when the docshell is created.
-  nsCOMPtr<nsPIDOMWindowOuter> mOpener;
-
   RefPtr<TabParent> mRemoteBrowser;
   uint64_t mChildID;
 
   // This is used when this refers to a remote sub frame
   RefPtr<mozilla::dom::BrowserBridgeChild> mBrowserBridgeChild;
 
   // Holds the last known size of the frame.
   mozilla::ScreenIntSize mLazySize;
--- a/dom/base/nsFrameLoaderOwner.cpp
+++ b/dom/base/nsFrameLoaderOwner.cpp
@@ -34,16 +34,20 @@ void nsFrameLoaderOwner::ChangeRemotenes
   }
 
   // In this case, we're not reparenting a frameloader, we're just destroying
   // our current one and creating a new one, so we can use ourselves as the
   // owner.
   RefPtr<Element> owner = do_QueryObject(this);
   MOZ_ASSERT(owner);
   mFrameLoader = nsFrameLoader::Create(owner, aOptions);
+
+  if (NS_WARN_IF(!mFrameLoader)) {
+    return;
+  }
   mFrameLoader->LoadFrame(false);
 
   // Now that we've got a new FrameLoader, we need to reset our
   // nsSubDocumentFrame to use the new FrameLoader.
   nsIFrame* ourFrame = owner->GetPrimaryFrame();
   if (ourFrame) {
     nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
     if (ourFrameFrame) {
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -2469,16 +2469,17 @@ void nsGlobalWindowOuter::DetachFromDocS
     nsJSContext::PokeGC(JS::GCReason::SET_DOC_SHELL,
                         (mTopLevelOuterContentWindow || mIsChrome)
                             ? nullptr
                             : GetWrapperPreserveColor());
     mContext = nullptr;
   }
 
   mDocShell = nullptr;
+  mBrowsingContext->ClearDocShell();
 
   if (mFrames) {
     mFrames->SetDocShell(nullptr);
   }
 
   MaybeForgiveSpamCount();
   CleanUp();
 }
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1718,17 +1718,16 @@ void nsJSContext::EndCycleCollectionCall
   sForgetSkippableBeforeCC = 0;
   sNeedsFullCC = false;
   sNeedsGCAfterCC = false;
   gCCStats.Clear();
 }
 
 // static
 bool InterSliceGCRunnerFired(TimeStamp aDeadline, void* aData) {
-  nsJSContext::KillInterSliceGCRunner();
   MOZ_ASSERT(sActiveIntersliceGCBudget > 0);
   // We use longer budgets when the CC has been locked out but the CC has tried
   // to run since that means we may have significant amount garbage to collect
   // and better to GC in several longer slices than in a very long one.
   int64_t budget =
       aDeadline.IsNull()
           ? int64_t(sActiveIntersliceGCBudget * 2)
           : int64_t((aDeadline - TimeStamp::Now()).ToMilliseconds());
@@ -1770,28 +1769,32 @@ bool InterSliceGCRunnerFired(TimeStamp a
     Telemetry::Accumulate(Telemetry::GC_SLICE_DURING_IDLE, percent);
   }
   return true;
 }
 
 // static
 void GCTimerFired(nsITimer* aTimer, void* aClosure) {
   nsJSContext::KillGCTimer();
-  nsJSContext::KillInterSliceGCRunner();
   if (sShuttingDown) {
+    nsJSContext::KillInterSliceGCRunner();
+    return;
+  }
+
+  if (sInterSliceGCRunner) {
     return;
   }
 
   // Now start the actual GC after initial timer has fired.
   sInterSliceGCRunner = IdleTaskRunner::Create(
       [aClosure](TimeStamp aDeadline) {
         return InterSliceGCRunnerFired(aDeadline, aClosure);
       },
       "GCTimerFired::InterSliceGCRunnerFired", NS_INTERSLICE_GC_DELAY,
-      sActiveIntersliceGCBudget, false, [] { return sShuttingDown; },
+      sActiveIntersliceGCBudget, true, [] { return sShuttingDown; },
       TaskCategory::GarbageCollection);
 }
 
 // static
 void ShrinkingGCTimerFired(nsITimer* aTimer, void* aClosure) {
   nsJSContext::KillShrinkingGCTimer();
   sIsCompactingOnUserInactive = true;
   nsJSContext::GarbageCollectNow(JS::GCReason::USER_INACTIVE,
@@ -2236,25 +2239,28 @@ static void DOMGCSliceCallback(JSContext
 
     case JS::GC_SLICE_BEGIN:
       break;
 
     case JS::GC_SLICE_END:
       sGCUnnotifiedTotalTime +=
           aDesc.lastSliceEnd(aCx) - aDesc.lastSliceStart(aCx);
 
-      // Schedule another GC slice if the GC has more work to do.
-      nsJSContext::KillInterSliceGCRunner();
-      if (!sShuttingDown && !aDesc.isComplete_) {
+      if (sShuttingDown || aDesc.isComplete_) {
+        nsJSContext::KillInterSliceGCRunner();
+      } else if (!sInterSliceGCRunner) {
+        // If incremental GC wasn't triggered by GCTimerFired, we may not
+        // have a runner to ensure all the slices are handled. So, create
+        // the runner here.
         sInterSliceGCRunner = IdleTaskRunner::Create(
             [](TimeStamp aDeadline) {
               return InterSliceGCRunnerFired(aDeadline, nullptr);
             },
             "DOMGCSliceCallback::InterSliceGCRunnerFired",
-            NS_INTERSLICE_GC_DELAY, sActiveIntersliceGCBudget, false,
+            NS_INTERSLICE_GC_DELAY, sActiveIntersliceGCBudget, true,
             [] { return sShuttingDown; }, TaskCategory::GarbageCollection);
       }
 
       if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
         nsCycleCollector_dispatchDeferredDeletion();
       }
 
       if (StaticPrefs::javascript_options_mem_log()) {
--- a/dom/chrome-webidl/BrowsingContext.webidl
+++ b/dom/chrome-webidl/BrowsingContext.webidl
@@ -11,16 +11,18 @@ interface BrowsingContext {
 
   BrowsingContext? findChildWithName(DOMString name);
   BrowsingContext? findWithName(DOMString name);
 
   readonly attribute DOMString name;
 
   readonly attribute BrowsingContext? parent;
 
+  readonly attribute BrowsingContext top;
+
   sequence<BrowsingContext> getChildren();
 
   readonly attribute nsIDocShell? docShell;
 
   readonly attribute unsigned long long id;
 
   readonly attribute BrowsingContext? opener;
 
--- a/dom/chrome-webidl/JSWindowActor.webidl
+++ b/dom/chrome-webidl/JSWindowActor.webidl
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
+interface nsISupports;
+
 [NoInterfaceObject]
 interface JSWindowActor {
   [Throws]
   void sendAsyncMessage(DOMString messageName,
                         optional any obj,
                         optional any transfers);
 };
 
@@ -17,9 +19,18 @@ interface JSWindowActorParent {
   readonly attribute WindowGlobalParent manager;
 };
 JSWindowActorParent implements JSWindowActor;
 
 [ChromeOnly, ChromeConstructor]
 interface JSWindowActorChild {
   readonly attribute WindowGlobalChild manager;
 };
-JSWindowActorChild implements JSWindowActor;
\ No newline at end of file
+JSWindowActorChild implements JSWindowActor;
+
+// WebIDL callback interface version of the nsIObserver interface for use when
+// calling the observe method on JSWindowActors.
+//
+// NOTE: This isn't marked as ChromeOnly, as it has no interface object, and
+// thus cannot be conditionally exposed.
+callback interface MozObserverCallback {
+  void observe(nsISupports subject, ByteString topic, DOMString? data);
+};
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -104,22 +104,18 @@ BrowsingContext* nsGenericHTMLFrameEleme
     return nullptr;
   }
 
   if (mFrameLoader->DepthTooGreat()) {
     // Claim to have no contentWindow
     return nullptr;
   }
 
-  RefPtr<nsDocShell> doc_shell = mFrameLoader->GetDocShell(IgnoreErrors());
-  if (!doc_shell) {
-    return nullptr;
-  }
-
-  return doc_shell->GetBrowsingContext();
+  RefPtr<BrowsingContext> bc = mFrameLoader->GetBrowsingContext();
+  return bc;
 }
 
 Nullable<WindowProxyHolder> nsGenericHTMLFrameElement::GetContentWindow() {
   RefPtr<BrowsingContext> bc = GetContentWindowInternal();
   if (!bc) {
     return nullptr;
   }
   return WindowProxyHolder(bc);
@@ -128,19 +124,17 @@ Nullable<WindowProxyHolder> nsGenericHTM
 void nsGenericHTMLFrameElement::EnsureFrameLoader() {
   if (!IsInComposedDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
     // If frame loader is there, we just keep it around, cached
     return;
   }
 
   // Strangely enough, this method doesn't actually ensure that the
   // frameloader exists.  It's more of a best-effort kind of thing.
-  mFrameLoader = nsFrameLoader::Create(
-      this, mOpenerWindow ? mOpenerWindow->GetDOMWindow() : nullptr,
-      mNetworkCreated);
+  mFrameLoader = nsFrameLoader::Create(this, mOpenerWindow, mNetworkCreated);
 }
 
 nsresult nsGenericHTMLFrameElement::CreateRemoteFrameLoader(
     nsITabParent* aTabParent) {
   MOZ_ASSERT(!mFrameLoader);
   EnsureFrameLoader();
   NS_ENSURE_STATE(mFrameLoader);
   mFrameLoader->SetRemoteBrowser(aTabParent);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1082,16 +1082,17 @@ mozilla::ipc::IPCResult ContentParent::R
   }
 
   return IPC_OK();
 }
 
 /*static*/
 TabParent* ContentParent::CreateBrowser(const TabContext& aContext,
                                         Element* aFrameElement,
+                                        BrowsingContext* aBrowsingContext,
                                         ContentParent* aOpenerContentParent,
                                         TabParent* aSameTabGroupAs,
                                         uint64_t aNextTabParentId) {
   AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
 
   if (!sCanLaunchSubprocesses) {
     return nullptr;
   }
@@ -1142,26 +1143,19 @@ TabParent* ContentParent::CreateBrowser(
           GetNewOrUsedBrowserProcess(aFrameElement, remoteType, initialPriority,
                                      nullptr, isPreloadBrowser);
     }
     if (!constructorSender) {
       return nullptr;
     }
   }
 
-  // FIXME: This BrowsingContext should be provided by the nsFrameLoader.
-  // (bug 1523636)
-  RefPtr<CanonicalBrowsingContext> browsingContext =
-      BrowsingContext::Create(nullptr, nullptr, EmptyString(),
-                              BrowsingContext::Type::Content)
-          .downcast<CanonicalBrowsingContext>();
-
   // Ensure that our content process is subscribed to our newly created
   // BrowsingContextGroup.
-  browsingContext->Group()->EnsureSubscribed(constructorSender);
+  aBrowsingContext->Group()->EnsureSubscribed(constructorSender);
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
   cpm->RegisterRemoteFrame(tabId, ContentParentId(0), openerTabId,
                            aContext.AsIPCTabContext(),
                            constructorSender->ChildID());
 
   if (constructorSender) {
     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
@@ -1183,27 +1177,29 @@ TabParent* ContentParent::CreateBrowser(
     }
     if (docShell->GetAffectPrivateSessionLifetime()) {
       chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
     }
 
     if (tabId == 0) {
       return nullptr;
     }
-    RefPtr<TabParent> tp = new TabParent(constructorSender, tabId, aContext,
-                                         browsingContext, chromeFlags);
-
-    browsingContext->SetOwnerProcessId(constructorSender->ChildID());
+    RefPtr<TabParent> tp =
+        new TabParent(constructorSender, tabId, aContext,
+                      aBrowsingContext->Canonical(), chromeFlags);
+
+    aBrowsingContext->Canonical()->SetOwnerProcessId(
+        constructorSender->ChildID());
 
     PBrowserParent* browser = constructorSender->SendPBrowserConstructor(
         // DeallocPBrowserParent() releases this ref.
         tp.forget().take(), tabId,
         aSameTabGroupAs ? aSameTabGroupAs->GetTabId() : TabId(0),
         aContext.AsIPCTabContext(), chromeFlags, constructorSender->ChildID(),
-        browsingContext, constructorSender->IsForBrowser());
+        aBrowsingContext, constructorSender->IsForBrowser());
 
     if (remoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
       // Tell the TabChild object that it was created due to a Large-Allocation
       // request.
       Unused << browser->SendAwaitLargeAlloc();
     }
 
     if (browser) {
@@ -5706,16 +5702,27 @@ mozilla::ipc::IPCResult ContentParent::R
   if (!child) {
     RefPtr<BrowsingContextGroup> group =
         BrowsingContextGroup::Select(aInit.mParentId, aInit.mOpenerId);
     child = BrowsingContext::CreateFromIPC(std::move(aInit), group, this);
   }
 
   child->Attach(/* aFromIPC */ true);
 
+  for (auto iter = child->Group()->ContentParentsIter(); !iter.Done();
+       iter.Next()) {
+    nsRefPtrHashKey<ContentParent>* entry = iter.Get();
+    if (entry->GetKey() == this) {
+      continue;
+    }
+
+    Unused << entry->GetKey()->SendAttachBrowsingContext(
+      child->GetIPCInitializer());
+  }
+
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvDetachBrowsingContext(
     BrowsingContext* aContext, bool aMoveToBFCache) {
   if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
             ("ParentIPC: Trying to detach already detached"));
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -203,16 +203,17 @@ class ContentParent final : public PCont
 
   /**
    * Get or create a content process for the given TabContext.  aFrameElement
    * should be the frame/iframe element with which this process will
    * associated.
    */
   static TabParent* CreateBrowser(const TabContext& aContext,
                                   Element* aFrameElement,
+                                  BrowsingContext* aBrowsingContext,
                                   ContentParent* aOpenerContentParent,
                                   TabParent* aSameTabGroupAs,
                                   uint64_t aNextTabParentId);
 
   static void GetAll(nsTArray<ContentParent*>& aArray);
 
   static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray);
 
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -186,16 +186,17 @@ struct PerformanceInfo
   // Counters per category. For workers, a single entry
   CategoryDispatch[] items;
 };
 
 
 struct WindowGlobalInit
 {
   nsIPrincipal principal;
+  nsIURI documentURI;
   BrowsingContext browsingContext;
   uint64_t innerWindowId;
   uint64_t outerWindowId;
 };
 
 struct DocShellLoadStateInit
 {
   nsIURI URI;
--- a/dom/ipc/JSWindowActorService.cpp
+++ b/dom/ipc/JSWindowActorService.cpp
@@ -2,91 +2,33 @@
 
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/dom/JSWindowActorService.h"
 #include "mozilla/dom/ChromeUtilsBinding.h"
+#include "mozilla/dom/EventListenerBinding.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/EventTarget.h"
+#include "mozilla/dom/JSWindowActorBinding.h"
 #include "mozilla/dom/PContent.h"
 #include "mozilla/StaticPtr.h"
 #include "mozJSComponentLoader.h"
 #include "mozilla/extensions/WebExtensionContentScript.h"
 #include "mozilla/Logging.h"
 
 namespace mozilla {
 namespace dom {
 namespace {
 StaticRefPtr<JSWindowActorService> gJSWindowActorService;
 }
 
 /**
- * Helper for calling a named method on a JS Window Actor object with a single
- * parameter.
- *
- * It will do the following:
- *  1. Enter the actor object's compartment.
- *  2. Convert the given parameter into a JS parameter with ToJSValue.
- *  3. Call the named method, passing the single parameter.
- *  4. Place the return value in aRetVal.
- *
- * If an error occurs during this process, this method clears any pending
- * exceptions, and returns a nsresult.
- */
-template <typename T>
-nsresult CallJSActorMethod(nsWrapperCache* aActor, const char* aName,
-                           T& aNativeArg, JS::MutableHandleValue aRetVal) {
-  // FIXME(nika): We should avoid atomizing and interning the |aName| strings
-  // every time we do this call. Given the limited set of possible IDs, it would
-  // be better to cache the `jsid` values.
-
-  aRetVal.setUndefined();
-
-  // Get the wrapper for our actor. If we don't have a wrapper, the target
-  // method won't be defined on it. so there's no reason to continue.
-  JS::Rooted<JSObject*> actor(RootingCx(), aActor->GetWrapper());
-  if (NS_WARN_IF(!actor)) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
-  // Enter the realm of our actor object to begin running script.
-  AutoEntryScript aes(actor, "CallJSActorMethod");
-  JSContext* cx = aes.cx();
-  JSAutoRealm ar(cx, actor);
-
-  // Get the method we want to call, and produce NS_ERROR_NOT_IMPLEMENTED if
-  // it is not present.
-  JS::Rooted<JS::Value> func(cx);
-  if (NS_WARN_IF(!JS_GetProperty(cx, actor, aName, &func) ||
-                 func.isPrimitive())) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
-  // Convert the native argument to a JS value.
-  JS::Rooted<JS::Value> argv(cx);
-  if (NS_WARN_IF(!ToJSValue(cx, aNativeArg, &argv))) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_FAILURE;
-  }
-
-  // Call our method.
-  if (NS_WARN_IF(!JS_CallFunctionValue(cx, actor, func,
-                                       JS::HandleValueArray(argv), aRetVal))) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-/**
  * Object corresponding to a single actor protocol. This object acts as an
  * Event listener for the actor which is called for events which would
  * trigger actor creation.
  *
  * This object also can act as a carrier for methods and other state related to
  * a single protocol managed by the JSWindowActorService.
  */
 class JSWindowActorProtocol final : public nsIObserver,
@@ -295,19 +237,23 @@ NS_IMETHODIMP JSWindowActorProtocol::Han
 
     // Don't raise an error if creation of our actor was vetoed.
     if (rv == NS_ERROR_NOT_AVAILABLE) {
       return NS_OK;
     }
     return rv;
   }
 
-  // Call the "handleEvent" method on our actor.
-  JS::Rooted<JS::Value> dummy(RootingCx());
-  return CallJSActorMethod(actor, "handleEvent", aEvent, &dummy);
+  // Build our event listener & call it.
+  JS::Rooted<JSObject*> global(RootingCx(),
+                               JS::GetNonCCWObjectGlobal(actor->GetWrapper()));
+  RefPtr<EventListener> eventListener =
+      new EventListener(actor->GetWrapper(), global, nullptr, nullptr);
+  eventListener->HandleEvent(*aEvent, "JSWindowActorProtocol::HandleEvent");
+  return NS_OK;
 }
 
 NS_IMETHODIMP JSWindowActorProtocol::Observe(nsISupports* aSubject,
                                              const char* aTopic,
                                              const char16_t* aData) {
   nsCOMPtr<nsPIDOMWindowInner> inner = do_QueryInterface(aSubject);
   if (NS_WARN_IF(!inner)) {
     return NS_ERROR_FAILURE;
@@ -326,54 +272,23 @@ NS_IMETHODIMP JSWindowActorProtocol::Obs
 
     // Don't raise an error if creation of our actor was vetoed.
     if (rv == NS_ERROR_NOT_AVAILABLE) {
       return NS_OK;
     }
     return rv;
   }
 
-  // Get the wrapper for our actor. If we don't have a wrapper, the target
-  // method won't be defined on it. so there's no reason to continue.
-  JS::Rooted<JSObject*> obj(RootingCx(), actor->GetWrapper());
-  if (NS_WARN_IF(!obj)) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
-  // Enter the realm of our actor object to begin running script.
-  AutoEntryScript aes(obj, "JSWindowActorProtocol::Observe");
-  JSContext* cx = aes.cx();
-  JSAutoRealm ar(cx, obj);
-
-  JS::AutoValueArray<3> argv(cx);
-  if (NS_WARN_IF(
-          !ToJSValue(cx, aSubject, argv[0]) ||
-          !NonVoidByteStringToJsval(cx, nsDependentCString(aTopic), argv[1]))) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_FAILURE;
-  }
-
-  // aData is an optional parameter.
-  if (aData) {
-    if (NS_WARN_IF(!ToJSValue(cx, nsDependentString(aData), argv[2]))) {
-      JS_ClearPendingException(cx);
-      return NS_ERROR_FAILURE;
-    }
-  } else {
-    argv[2].setNull();
-  }
-
-  // Call the "observe" method on our actor.
-  JS::Rooted<JS::Value> dummy(cx);
-  if (NS_WARN_IF(!JS_CallFunctionName(cx, obj, "observe",
-                                      JS::HandleValueArray(argv), &dummy))) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_FAILURE;
-  }
-
+  // Build a observer callback.
+  JS::Rooted<JSObject*> global(RootingCx(),
+                               JS::GetNonCCWObjectGlobal(actor->GetWrapper()));
+  RefPtr<MozObserverCallback> observerCallback =
+      new MozObserverCallback(actor->GetWrapper(), global, nullptr, nullptr);
+  observerCallback->Observe(aSubject, nsDependentCString(aTopic),
+                            aData ? nsDependentString(aData) : VoidString());
   return NS_OK;
 }
 
 void JSWindowActorProtocol::RegisterListenersFor(EventTarget* aRoot) {
   EventListenerManager* elm = aRoot->GetOrCreateListenerManager();
 
   for (auto& event : mChild.mEvents) {
     elm->AddEventListenerByType(EventListenerHolder(this), event.mName,
@@ -652,42 +567,37 @@ void JSWindowActorService::ReceiveMessag
   RootedDictionary<ReceiveMessageArgument> argument(cx);
   argument.mObjects = JS_NewPlainObject(cx);
   argument.mTarget = aTarget;
   argument.mName = aMessageName;
   argument.mData = json;
   argument.mJson = json;
   argument.mSync = false;
 
-  JS::RootedValue argv(cx);
-  if (NS_WARN_IF(!ToJSValue(cx, argument, &argv))) {
-    return;
-  }
+  JS::Rooted<JSObject*> global(cx, JS::GetNonCCWObjectGlobal(aObj));
+  RefPtr<MessageListener> messageListener =
+      new MessageListener(aObj, global, nullptr, nullptr);
 
-  // Now that we have finished, call the recvAsyncMessage callback.
-  JS::RootedValue dummy(cx);
-  if (NS_WARN_IF(!JS_CallFunctionName(cx, aObj, "recvAsyncMessage",
-                                      JS::HandleValueArray(argv), &dummy))) {
-    JS_ClearPendingException(cx);
-    return;
-  }
+  JS::Rooted<JS::Value> dummy(cx);
+  messageListener->ReceiveMessage(argument, &dummy,
+                                  "JSWindowActorService::ReceiveMessage");
 }
 
 void JSWindowActorService::RegisterWindowRoot(EventTarget* aRoot) {
   MOZ_ASSERT(!mRoots.Contains(aRoot));
   mRoots.AppendElement(aRoot);
 
   // Register event listeners on the newly added Window Root.
   for (auto iter = mDescriptors.Iter(); !iter.Done(); iter.Next()) {
     iter.Data()->RegisterListenersFor(aRoot);
   }
 }
 
-/* static */ void JSWindowActorService::UnregisterWindowRoot(
-    EventTarget* aRoot) {
+/* static */
+void JSWindowActorService::UnregisterWindowRoot(EventTarget* aRoot) {
   if (gJSWindowActorService) {
     // NOTE: No need to unregister listeners here, as the root is going away.
     gJSWindowActorService->mRoots.RemoveElement(aRoot);
   }
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/ipc/WindowGlobalChild.cpp
+++ b/dom/ipc/WindowGlobalChild.cpp
@@ -55,18 +55,25 @@ already_AddRefed<WindowGlobalChild> Wind
       do_QueryInterface(aWindow->GetDocument()->GetChannel());
   nsILoadInfo::CrossOriginOpenerPolicy policy;
   if (chan && NS_SUCCEEDED(chan->GetCrossOriginOpenerPolicy(&policy))) {
     bc->SetOpenerPolicy(policy);
   }
 
   RefPtr<WindowGlobalChild> wgc = new WindowGlobalChild(aWindow, bc);
 
-  WindowGlobalInit init(principal, bc, wgc->mInnerWindowId,
-                        wgc->mOuterWindowId);
+  // If we have already closed our browsing context, return a pre-closed
+  // WindowGlobalChild actor.
+  if (bc->GetClosed()) {
+    wgc->ActorDestroy(FailedConstructor);
+    return wgc.forget();
+  }
+
+  WindowGlobalInit init(principal, aWindow->GetDocumentURI(), bc,
+                        wgc->mInnerWindowId, wgc->mOuterWindowId);
 
   // Send the link constructor over PInProcessChild or PBrowser.
   if (XRE_IsParentProcess()) {
     InProcessChild* ipc = InProcessChild::Singleton();
     if (!ipc) {
       return nullptr;
     }
 
@@ -86,18 +93,16 @@ already_AddRefed<WindowGlobalChild> Wind
   if (!gWindowGlobalChildById) {
     gWindowGlobalChildById = new WGCByIdMap();
     ClearOnShutdown(&gWindowGlobalChildById);
   }
   auto entry = gWindowGlobalChildById->LookupForAdd(wgc->mInnerWindowId);
   MOZ_RELEASE_ASSERT(!entry, "Duplicate WindowGlobalChild entry for ID!");
   entry.OrInsert([&] { return wgc; });
 
-  // Send down our initial document URI.
-  wgc->SendUpdateDocumentURI(aWindow->GetDocumentURI());
   return wgc.forget();
 }
 
 /* static */
 already_AddRefed<WindowGlobalChild> WindowGlobalChild::GetByInnerWindowId(
     uint64_t aInnerWindowId) {
   if (!gWindowGlobalChildById) {
     return nullptr;
--- a/dom/ipc/WindowGlobalParent.cpp
+++ b/dom/ipc/WindowGlobalParent.cpp
@@ -36,16 +36,17 @@ namespace mozilla {
 namespace dom {
 
 typedef nsRefPtrHashtable<nsUint64HashKey, WindowGlobalParent> WGPByIdMap;
 static StaticAutoPtr<WGPByIdMap> gWindowGlobalParentsById;
 
 WindowGlobalParent::WindowGlobalParent(const WindowGlobalInit& aInit,
                                        bool aInProcess)
     : mDocumentPrincipal(aInit.principal()),
+      mDocumentURI(aInit.documentURI()),
       mInnerWindowId(aInit.innerWindowId()),
       mOuterWindowId(aInit.outerWindowId()),
       mInProcess(aInProcess),
       mIPCClosed(true)  // Closed until WGP::Init
 {
   MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "Parent process only");
   MOZ_RELEASE_ASSERT(mDocumentPrincipal, "Must have a valid principal");
 
--- a/dom/ipc/tests/test_force_oop_iframe.html
+++ b/dom/ipc/tests/test_force_oop_iframe.html
@@ -42,16 +42,19 @@ add_task(async function() {
   iframe.setAttribute("fission", "true");
   iframe.setAttribute("src", "file_dummy.html");
   document.body.appendChild(iframe);
 
   // Check that this isn't loaded in-process, or using a nested tabParent object.
   let frameLoader = SpecialPowers.wrap(iframe).frameLoader;
   is(frameLoader.docShell, null);
   is(frameLoader.tabParent, null);
+  let browsingContext = frameLoader.browsingContext;
+  isnot(browsingContext, null);
+  is(browsingContext.docShell, null);
 
   await contentCreated;
 
   ok(frameLoader.browsingContext, "Has BrowsingContext");
   ok(frameLoader.browsingContext.parent, "BrowsingContext has parent");
 
   let wgc = SpecialPowers.wrap(window).getWindowGlobalChild();
   ok(wgc, "we have a WindowGlobalChild");
--- a/dom/permission/PermissionStatus.cpp
+++ b/dom/permission/PermissionStatus.cpp
@@ -6,16 +6,17 @@
 
 #include "mozilla/dom/PermissionStatus.h"
 
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Services.h"
 #include "nsIPermissionManager.h"
 #include "PermissionObserver.h"
 #include "PermissionUtils.h"
+#include "nsPermission.h"
 
 namespace mozilla {
 namespace dom {
 
 /* static */
 already_AddRefed<PermissionStatus> PermissionStatus::Create(
     nsPIDOMWindowInner* aWindow, PermissionName aName, ErrorResult& aRv) {
   RefPtr<PermissionStatus> status = new PermissionStatus(aWindow, aName);
@@ -91,18 +92,17 @@ already_AddRefed<nsIPrincipal> Permissio
   }
 
   Document* doc = window->GetExtantDoc();
   if (NS_WARN_IF(!doc)) {
     return nullptr;
   }
 
   nsCOMPtr<nsIPrincipal> principal =
-      mozilla::BasePrincipal::Cast(doc->NodePrincipal())
-          ->CloneStrippingUserContextIdAndFirstPartyDomain();
+      nsPermission::ClonePrincipalForPermission(doc->NodePrincipal());
   NS_ENSURE_TRUE(principal, nullptr);
 
   return principal.forget();
 }
 
 void PermissionStatus::PermissionChanged() {
   auto oldState = mState;
   UpdateState();
--- a/dom/permission/moz.build
+++ b/dom/permission/moz.build
@@ -14,13 +14,17 @@ EXPORTS.mozilla.dom += [
 
 UNIFIED_SOURCES += [
     'PermissionObserver.cpp',
     'Permissions.cpp',
     'PermissionStatus.cpp',
     'PermissionUtils.cpp',
 ]
 
+LOCAL_INCLUDES += [
+    '/extensions/cookie',
+]
+
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/prototype/PrototypeDocumentContentSink.cpp
+++ b/dom/prototype/PrototypeDocumentContentSink.cpp
@@ -410,16 +410,27 @@ nsresult PrototypeDocumentContentSink::I
 
 void PrototypeDocumentContentSink::CloseElement(Element* aElement) {
   if (aElement->IsXULElement(nsGkAtoms::linkset)) {
     aElement->DoneAddingChildren(false);
   }
 }
 
 nsresult PrototypeDocumentContentSink::ResumeWalk() {
+  nsresult rv = ResumeWalkInternal();
+  if (NS_FAILED(rv)) {
+    nsContentUtils::ReportToConsoleNonLocalized(
+        NS_LITERAL_STRING("Failed to load document from prototype document."),
+        nsIScriptError::errorFlag, NS_LITERAL_CSTRING("Prototype Document"),
+        mDocument, mDocumentURI);
+  }
+  return rv;
+}
+
+nsresult PrototypeDocumentContentSink::ResumeWalkInternal() {
   MOZ_ASSERT(mStillWalking);
   // Walk the prototype and build the delegate content model. The
   // walk is performed in a top-down, left-to-right fashion. That
   // is, a parent is built before any of its children; a node is
   // only built after all of its siblings to the left are fully
   // constructed.
   //
   // It is interruptable so that transcluded documents (e.g.,
--- a/dom/prototype/PrototypeDocumentContentSink.h
+++ b/dom/prototype/PrototypeDocumentContentSink.h
@@ -178,21 +178,27 @@ class PrototypeDocumentContentSink final
   /**
    * The current prototype that we are walking to construct the
    * content model.
    */
   RefPtr<nsXULPrototypeDocument> mCurrentPrototype;
   nsresult CreateAndInsertPI(const nsXULPrototypePI* aProtoPI);
   nsresult ExecuteScript(nsXULPrototypeScript* aScript);
   nsresult LoadScript(nsXULPrototypeScript* aScriptProto, bool* aBlock);
+
+  /**
+   * A wrapper around ResumeWalkInternal to report walking errors.
+   */
+  nsresult ResumeWalk();
+
   /**
    * Resume (or initiate) an interrupted (or newly prepared)
    * prototype walk.
    */
-  nsresult ResumeWalk();
+  nsresult ResumeWalkInternal();
 
   /**
    * Called at the end of ResumeWalk(), from StyleSheetLoaded(),
    * and from DocumentL10n.
    * If walking, stylesheets and l10n are not blocking, it
    * will trigger `DoneWalking()`.
    */
   nsresult MaybeDoneWalking();
--- a/dom/webbrowserpersist/WebBrowserPersistSerializeChild.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistSerializeChild.cpp
@@ -4,17 +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/. */
 
 #include "WebBrowserPersistSerializeChild.h"
 
 #include <algorithm>
 
 #include "nsThreadUtils.h"
-#include "ipc/IPCMessageUtils.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(WebBrowserPersistSerializeChild,
                   nsIWebBrowserPersistWriteCompletion,
                   nsIWebBrowserPersistURIMap, nsIOutputStream)
 
 WebBrowserPersistSerializeChild::WebBrowserPersistSerializeChild(
@@ -77,24 +76,28 @@ WebBrowserPersistSerializeChild::Write(c
   // thread (which also means it's difficult to test the
   // thread-safety code this class doesn't yet have).
   //
   // This is *not* an NS_ERROR_NOT_IMPLEMENTED, because at this
   // point we've probably already misused the non-thread-safe
   // refcounting.
   MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Fix this class to be thread-safe.");
 
+  // Limit the message size to 64k because large messages are
+  // potentially bad for the latency of other messages on the same channel.
+  static const uint32_t kMaxWrite = 65536;
+
   // Work around bug 1181433 by sending multiple messages if
   // necessary to write the entire aCount bytes, even though
   // nsIOutputStream.idl says we're allowed to do a short write.
   const char* buf = aBuf;
   uint32_t count = aCount;
   *aWritten = 0;
   while (count > 0) {
-    uint32_t toWrite = std::min(IPC::MAX_MESSAGE_SIZE, count);
+    uint32_t toWrite = std::min(kMaxWrite, count);
     nsTArray<uint8_t> arrayBuf;
     // It would be nice if this extra copy could be avoided.
     arrayBuf.AppendElements(buf, toWrite);
     SendWriteData(std::move(arrayBuf));
     *aWritten += toWrite;
     buf += toWrite;
     count -= toWrite;
   }
--- a/dom/xul/XULFrameElement.cpp
+++ b/dom/xul/XULFrameElement.cpp
@@ -87,18 +87,17 @@ void XULFrameElement::LoadSrc() {
       }
     }
     mOpener = nullptr;
 
     // false as the last parameter so that xul:iframe/browser/editor
     // session history handling works like dynamic html:iframes.
     // Usually xul elements are used in chrome, which doesn't have
     // session history at all.
-    mFrameLoader = nsFrameLoader::Create(
-        this, opener ? opener->GetDOMWindow() : nullptr, false);
+    mFrameLoader = nsFrameLoader::Create(this, opener, false);
     if (NS_WARN_IF(!mFrameLoader)) {
       return;
     }
 
     (new AsyncEventDispatcher(this, NS_LITERAL_STRING("XULFrameLoaderCreated"),
                               CanBubble::eYes))
         ->RunDOMEventWhenSafe();
   }
--- a/extensions/cookie/nsPermission.cpp
+++ b/extensions/cookie/nsPermission.cpp
@@ -18,26 +18,44 @@ nsPermission::nsPermission(nsIPrincipal*
                            uint32_t aCapability, uint32_t aExpireType,
                            int64_t aExpireTime)
     : mPrincipal(aPrincipal),
       mType(aType),
       mCapability(aCapability),
       mExpireType(aExpireType),
       mExpireTime(aExpireTime) {}
 
+already_AddRefed<nsIPrincipal> nsPermission::ClonePrincipalForPermission(
+    nsIPrincipal* aPrincipal) {
+  MOZ_ASSERT(aPrincipal);
+
+  mozilla::OriginAttributes attrs = aPrincipal->OriginAttributesRef();
+  attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID |
+                        mozilla::OriginAttributes::STRIP_FIRST_PARTY_DOMAIN);
+
+  nsAutoCString originNoSuffix;
+  nsresult rv = aPrincipal->GetOriginNoSuffix(originNoSuffix);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  nsCOMPtr<nsIURI> uri;
+  rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  return mozilla::BasePrincipal::CreateCodebasePrincipal(uri, attrs);
+}
+
 already_AddRefed<nsPermission> nsPermission::Create(nsIPrincipal* aPrincipal,
                                                     const nsACString& aType,
                                                     uint32_t aCapability,
                                                     uint32_t aExpireType,
                                                     int64_t aExpireTime) {
   NS_ENSURE_TRUE(aPrincipal, nullptr);
+
   nsCOMPtr<nsIPrincipal> principal =
-      mozilla::BasePrincipal::Cast(aPrincipal)
-          ->CloneStrippingUserContextIdAndFirstPartyDomain();
-
+      nsPermission::ClonePrincipalForPermission(aPrincipal);
   NS_ENSURE_TRUE(principal, nullptr);
 
   RefPtr<nsPermission> permission =
       new nsPermission(principal, aType, aCapability, aExpireType, aExpireTime);
   return permission.forget();
 }
 
 NS_IMETHODIMP
@@ -75,19 +93,17 @@ NS_IMETHODIMP
 nsPermission::Matches(nsIPrincipal* aPrincipal, bool aExactHost,
                       bool* aMatches) {
   NS_ENSURE_ARG_POINTER(aPrincipal);
   NS_ENSURE_ARG_POINTER(aMatches);
 
   *aMatches = false;
 
   nsCOMPtr<nsIPrincipal> principal =
-      mozilla::BasePrincipal::Cast(aPrincipal)
-          ->CloneStrippingUserContextIdAndFirstPartyDomain();
-
+      nsPermission::ClonePrincipalForPermission(aPrincipal);
   if (!principal) {
     *aMatches = false;
     return NS_OK;
   }
 
   // If the principals are equal, then they match.
   if (mPrincipal->Equals(principal)) {
     *aMatches = true;
--- a/extensions/cookie/nsPermission.h
+++ b/extensions/cookie/nsPermission.h
@@ -18,16 +18,22 @@ class nsPermission : public nsIPermissio
   NS_DECL_NSIPERMISSION
 
   static already_AddRefed<nsPermission> Create(nsIPrincipal* aPrincipal,
                                                const nsACString& aType,
                                                uint32_t aCapability,
                                                uint32_t aExpireType,
                                                int64_t aExpireTime);
 
+  // This method creates a new nsIPrincipal with a stripped OriginAttributes (no
+  // userContextId, and no FirstPartyDomain) and a codebase equal to the origin
+  // of 'aPrincipal'.
+  static already_AddRefed<nsIPrincipal> ClonePrincipalForPermission(
+      nsIPrincipal* aPrincipal);
+
  protected:
   nsPermission(nsIPrincipal* aPrincipal, const nsACString& aType,
                uint32_t aCapability, uint32_t aExpireType, int64_t aExpireTime);
 
   virtual ~nsPermission(){};
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCString mType;
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_clippath.html
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Hit-testing an iframe covered by an element with a clip-path</title>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  <meta name="viewport" content="width=device-width"/>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<style>
+    html, body { margin: 0; }
+    #clipped {
+        width: 400px;
+        height: 400px;
+        background-color: green;
+        position: absolute;
+        top: 100px;
+        left: 100px;
+        clip-path: circle(150px);
+    }
+    iframe {
+        width: 400px;
+        height: 300px;
+        border: 0px solid black;
+    }
+</style>
+</head>
+<body style="height: 5000px">
+<iframe id="sub" srcdoc="<!DOCTYPE html><body style='height: 5000px'><div style='position: absolute; top: 150px; left: 150px; width: 300px; height: 300px; background-color: blue;'></div>
+when this page loads, the blue rect should be behind the green circle. mousing over the area with the blue rect and scrolling with the wheel or trackpad should cause the iframe to scroll."></iframe>
+<div id="clipped"></div>
+<script>
+
+function* test(testDriver) {
+  var config = getHitTestConfig();
+  var utils = config.utils;
+
+  // layerize the iframe
+  var subwindow = document.getElementById("sub").contentWindow;
+  var subscroller = subwindow.document.scrollingElement;
+  var subutils = SpecialPowers.getDOMWindowUtils(subwindow);
+  subutils.setDisplayPortForElement(0, 0, 400, 1000, subscroller, 1);
+  yield waitForApzFlushedRepaints(testDriver);
+
+  var rootViewId = utils.getViewId(document.scrollingElement);
+  var iframeViewId = subutils.getViewId(subscroller);
+
+  checkHitResult(hitTest({ x: 10, y: 10 }),
+      APZHitResultFlags.VISIBLE,
+      iframeViewId,
+      "(simple) uninteresting point inside the iframe");
+  checkHitResult(hitTest({ x: 500, y: 10 }),
+      APZHitResultFlags.VISIBLE,
+      rootViewId,
+      "(simple) uninteresting point in the root scroller");
+  checkHitResult(hitTest({ x: 110, y: 110 }),
+      APZHitResultFlags.VISIBLE,
+      iframeViewId,
+      "(simple) point in the iframe behind overlaying div, but outside the bounding box of the clip path");
+  checkHitResult(hitTest({ x: 160, y: 160 }),
+      config.isWebRender ? APZHitResultFlags.VISIBLE
+                         : APZHitResultFlags.VISIBLE | APZHitResultFlags.IRREGULAR_AREA,
+      config.isWebRender ? iframeViewId : rootViewId,
+      "(simple) point in the iframe behind overlaying div, inside the bounding box of the clip path, but outside the actual clip shape");
+  checkHitResult(hitTest({ x: 300, y: 200 }),
+      config.isWebRender ? APZHitResultFlags.VISIBLE
+                         : APZHitResultFlags.VISIBLE | APZHitResultFlags.IRREGULAR_AREA,
+      rootViewId,
+      "(simple) point inside the clip shape of the overlaying div");
+
+  // Now we turn the "simple" clip-path that WR can handle into a more complex
+  // one that needs a mask. Then run the checks again; the expected results for
+  // WR are slightly different
+  document.getElementById("clipped").style.clipPath = "polygon(50px 200px, 75px 75px, 200px 50px, 350px 200px, 200px 350px)";
+  yield waitForApzFlushedRepaints(testDriver);
+
+  checkHitResult(hitTest({ x: 10, y: 10 }),
+      APZHitResultFlags.VISIBLE,
+      iframeViewId,
+      "(complex) uninteresting point inside the iframe");
+  checkHitResult(hitTest({ x: 500, y: 10 }),
+      APZHitResultFlags.VISIBLE,
+      rootViewId,
+      "(complex) uninteresting point in the root scroller");
+  checkHitResult(hitTest({ x: 110, y: 110 }),
+      APZHitResultFlags.VISIBLE,
+      iframeViewId,
+      "(complex) point in the iframe behind overlaying div, but outside the bounding box of the clip path");
+  checkHitResult(hitTest({ x: 160, y: 160 }),
+      APZHitResultFlags.VISIBLE | APZHitResultFlags.IRREGULAR_AREA,
+      rootViewId,
+      "(complex) point in the iframe behind overlaying div, inside the bounding box of the clip path, but outside the actual clip shape");
+  checkHitResult(hitTest({ x: 300, y: 200 }),
+      APZHitResultFlags.VISIBLE | APZHitResultFlags.IRREGULAR_AREA,
+      rootViewId,
+      "(complex) point inside the clip shape of the overlaying div");
+}
+
+waitUntilApzStable()
+    .then(runContinuation(test))
+    .then(subtestDone);
+</script>
+</body></html>
--- a/gfx/layers/apz/test/mochitest/test_group_hittest.html
+++ b/gfx/layers/apz/test/mochitest/test_group_hittest.html
@@ -33,16 +33,17 @@ var subtests = [
   {"file": "helper_hittest_float_bug1443518.html", "prefs": prefs},
   {"file": "helper_hittest_checkerboard.html", "prefs": prefs},
   {"file": "helper_hittest_backface_hidden.html", "prefs": prefs},
   {"file": "helper_hittest_touchaction.html", "prefs": prefs},
   {"file": "helper_hittest_nested_transforms_bug1459696.html", "prefs": prefs},
   {"file": "helper_hittest_sticky_bug1478304.html", "prefs": prefs},
   {"file": "helper_hittest_clipped_fixed_modal.html", "prefs": prefs},
   {"file": "helper_hittest_pointerevents_svg.html", "prefs": prefs},
+  {"file": "helper_hittest_clippath.html", "prefs": prefs},
 ];
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
     .then(SimpleTest.finish, SimpleTest.finish);
   };
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -2524,42 +2524,39 @@ impl PicturePrimitive {
         let local_rect = match original_local_rect
             .intersection(combined_local_clip_rect)
         {
             Some(rect) => rect.cast(),
             None => return false,
         };
         let world_rect = world_rect.cast();
 
-        match transform.transform_kind() {
-            TransformedRectKind::AxisAligned => {
-                let inv_transform = transforms
-                    .get_world_inv_transform(prim_instance.spatial_node_index);
-                let polygon = Polygon::from_transformed_rect_with_inverse(
+        if transform.is_simple_translation() {
+            let inv_transform = transforms
+                .get_world_inv_transform(prim_instance.spatial_node_index);
+            let polygon = Polygon::from_transformed_rect_with_inverse(
+                local_rect,
+                &matrix,
+                &inv_transform.cast(),
+                plane_split_anchor,
+            ).unwrap();
+            splitter.add(polygon);
+        } else {
+            let mut clipper = Clipper::new();
+            let results = clipper.clip_transformed(
+                Polygon::from_rect(
                     local_rect,
-                    &matrix,
-                    &inv_transform.cast(),
                     plane_split_anchor,
-                ).unwrap();
-                splitter.add(polygon);
-            }
-            TransformedRectKind::Complex => {
-                let mut clipper = Clipper::new();
-                let results = clipper.clip_transformed(
-                    Polygon::from_rect(
-                        local_rect,
-                        plane_split_anchor,
-                    ),
-                    &matrix,
-                    Some(world_rect),
-                );
-                if let Ok(results) = results {
-                    for poly in results {
-                        splitter.add(poly);
-                    }
+                ),
+                &matrix,
+                Some(world_rect),
+            );
+            if let Ok(results) = results {
+                for poly in results {
+                    splitter.add(poly);
                 }
             }
         }
 
         true
     }
 
     pub fn resolve_split_planes(
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/transforms/big-axis-aligned-scale-ref.yaml
@@ -0,0 +1,6 @@
+---
+root:
+  items:
+    - type: rect
+      bounds: [ 0, 0, 200, 44 ]
+      color: green
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/transforms/big-axis-aligned-scale.yaml
@@ -0,0 +1,10 @@
+---
+root:
+  items:
+    - type: stacking-context
+      transform-style: preserve-3d
+      transform: scale(-2, 44, 44727)
+      items:
+        - type: rect
+          bounds: [ -100, -100, 200, 101 ]
+          color: green
--- a/gfx/wr/wrench/reftests/transforms/reftest.list
+++ b/gfx/wr/wrench/reftests/transforms/reftest.list
@@ -33,8 +33,9 @@ platform(linux,mac) fuzzy(9,348) == pers
 platform(linux,mac) fuzzy(1,122) == border-scale.yaml border-scale.png
 platform(linux,mac) fuzzy(1,16) == border-scale-2.yaml border-scale-2.png
 platform(linux,mac) fuzzy(1,69) == border-scale-3.yaml border-scale-3.png
 platform(linux,mac) fuzzy(1,74) == border-scale-4.yaml border-scale-4.png
 # Just make sure we aren't crashing here
 != large-raster-root.yaml blank.yaml
 == flatten-preserve-3d-root.yaml flatten-preserve-3d-root-ref.yaml
 == strange-w.yaml strange-w-ref.yaml
+== big-axis-aligned-scale.yaml big-axis-aligned-scale-ref.yaml
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -99,21 +99,16 @@ struct SerializedStructuredCloneBuffer f
   JSStructuredCloneData data;
 };
 
 }  // namespace mozilla
 
 namespace IPC {
 
 /**
- * Maximum size, in bytes, of a single IPC message.
- */
-static const uint32_t MAX_MESSAGE_SIZE = 65536;
-
-/**
  * Generic enum serializer.
  *
  * Consider using the specializations below, such as ContiguousEnumSerializer.
  *
  * This is a generic serializer for any enum type used in IPDL.
  * Programmers can define ParamTraits<E> for enum type E by deriving
  * EnumSerializer<E, MyEnumValidator> where MyEnumValidator is a struct
  * that has to define a static IsLegalValue function returning whether
--- a/js/src/fuzz-tests/testWasm.cpp
+++ b/js/src/fuzz-tests/testWasm.cpp
@@ -22,17 +22,17 @@
 using namespace js;
 using namespace js::wasm;
 
 // These are defined and pre-initialized by the harness (in tests.cpp).
 extern JS::PersistentRootedObject gGlobal;
 extern JSContext* gCx;
 
 static int testWasmInit(int* argc, char*** argv) {
-  if (!wasm::HasSupport(gCx)) {
+  if (!wasm::HasSupport(gCx) || !InitWebAssemblyClass(gCx, gCx->global())) {
     MOZ_CRASH("Failed to initialize wasm support");
   }
 
   return 0;
 }
 
 static bool emptyNativeFunction(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1708,20 +1708,26 @@ void nsRefreshDriver::RunFrameRequestCal
 
 struct RunnableWithDelay {
   nsCOMPtr<nsIRunnable> mRunnable;
   uint32_t mDelay;
 };
 
 static AutoTArray<RunnableWithDelay, 8>* sPendingIdleRunnables = nullptr;
 
-void nsRefreshDriver::DispatchIdleRunnableAfterTick(nsIRunnable* aRunnable,
-                                                    uint32_t aDelay) {
+void nsRefreshDriver::DispatchIdleRunnableAfterTickUnlessExists(
+    nsIRunnable* aRunnable, uint32_t aDelay) {
   if (!sPendingIdleRunnables) {
     sPendingIdleRunnables = new AutoTArray<RunnableWithDelay, 8>();
+  } else {
+    for (uint32_t i = 0; i < sPendingIdleRunnables->Length(); ++i) {
+      if ((*sPendingIdleRunnables)[i].mRunnable == aRunnable) {
+        return;
+      }
+    }
   }
 
   RunnableWithDelay rwd = {aRunnable, aDelay};
   sPendingIdleRunnables->AppendElement(rwd);
 }
 
 void nsRefreshDriver::CancelIdleRunnable(nsIRunnable* aRunnable) {
   if (!sPendingIdleRunnables) {
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -410,18 +410,18 @@ class nsRefreshDriver final : public moz
   static mozilla::TimeStamp GetIdleDeadlineHint(mozilla::TimeStamp aDefault);
 
   /**
    * It returns the expected timestamp of the next tick or nothing if the next
    * tick is missed.
    */
   static mozilla::Maybe<mozilla::TimeStamp> GetNextTickHint();
 
-  static void DispatchIdleRunnableAfterTick(nsIRunnable* aRunnable,
-                                            uint32_t aDelay);
+  static void DispatchIdleRunnableAfterTickUnlessExists(nsIRunnable* aRunnable,
+                                                        uint32_t aDelay);
   static void CancelIdleRunnable(nsIRunnable* aRunnable);
 
   void NotifyDOMContentLoaded();
 
   // Schedule a refresh so that any delayed events will run soon.
   void RunDelayedEventsSoon();
 
   void InitializeTimer() {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -10899,16 +10899,25 @@ CompositorHitTestInfo nsIFrame::GetCompo
     return result;
   }
   if (!StyleVisibility()->IsVisible()) {
     return result;
   }
 
   // Anything that didn't match the above conditions is visible to hit-testing.
   result = CompositorHitTestFlags::eVisibleToHitTest;
+  if (nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this)) {
+    // If WebRender is enabled, simple clip-paths can be converted into WR
+    // clips that WR knows how to hit-test against, so we don't need to mark
+    // it as an irregular area.
+    if (!gfxVars::UseWebRender() ||
+        !nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(this)) {
+      result += CompositorHitTestFlags::eIrregularArea;
+    }
+  }
 
   if (aBuilder->IsBuildingNonLayerizedScrollbar()) {
     // Scrollbars may be painted into a layer below the actual layer they will
     // scroll, and therefore wheel events may be dispatched to the outer frame
     // instead of the intended scrollframe. To address this, we force a d-t-c
     // region on scrollbar frames that won't be placed in their own layer. See
     // bug 1213324 for details.
     result += CompositorHitTestFlags::eInactiveScrollframe;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9527,29 +9527,22 @@ void nsDisplayMasksAndClipPaths::PaintWi
 }
 
 static Maybe<wr::WrClipId> CreateSimpleClipRegion(
     const nsDisplayMasksAndClipPaths& aDisplayItem,
     wr::DisplayListBuilder& aBuilder) {
   nsIFrame* frame = aDisplayItem.Frame();
   auto* style = frame->StyleSVGReset();
   MOZ_ASSERT(style->HasClipPath() || style->HasMask());
-  if (style->HasMask()) {
+  if (!nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(frame)) {
     return Nothing();
   }
 
   const auto& clipPath = style->mClipPath;
-  if (clipPath.GetType() != StyleShapeSourceType::Shape) {
-    return Nothing();
-  }
-
   const auto& shape = clipPath.BasicShape();
-  if (shape.GetShapeType() == StyleBasicShapeType::Polygon) {
-    return Nothing();
-  }
 
   auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
   const nsRect refBox =
       nsLayoutUtils::ComputeGeometryBox(frame, clipPath.GetReferenceBox());
 
   AutoTArray<wr::ComplexClipRegion, 1> clipRegions;
 
   wr::LayoutRect rect;
@@ -9597,18 +9590,18 @@ static Maybe<wr::WrClipId> CreateSimpleC
       rect = wr::ToRoundedLayoutRect(
           LayoutDeviceRect::FromAppUnits(ellipseRect, appUnitsPerDevPixel));
       break;
     }
     default:
       // Please don't add more exceptions, try to find a way to define the clip
       // without using a mask image.
       //
-      // And if you _really really_ need to add an exception, add it to where
-      // the polygon check is.
+      // And if you _really really_ need to add an exception, add it to
+      // nsSVGIntegrationUtils::UsingSimpleClipPathForFrame
       MOZ_ASSERT_UNREACHABLE("Unhandled shape id?");
       return Nothing();
   }
   wr::WrClipId clipId =
       aBuilder.DefineClip(Nothing(), rect, &clipRegions, nullptr);
   return Some(clipId);
 }
 
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -164,16 +164,32 @@ bool nsSVGIntegrationUtils::UsingEffects
 }
 
 bool nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(
     const nsIFrame* aFrame) {
   const nsStyleSVGReset* style = aFrame->StyleSVGReset();
   return style->HasClipPath() || style->HasMask();
 }
 
+bool nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(
+    const nsIFrame* aFrame) {
+  const nsStyleSVGReset* style = aFrame->StyleSVGReset();
+  if (!style->HasClipPath() || style->HasMask()) {
+    return false;
+  }
+
+  const auto& clipPath = style->mClipPath;
+  if (clipPath.GetType() != StyleShapeSourceType::Shape) {
+    return false;
+  }
+
+  const auto& shape = clipPath.BasicShape();
+  return (shape.GetShapeType() != StyleBasicShapeType::Polygon);
+}
+
 nsPoint nsSVGIntegrationUtils::GetOffsetToBoundingBox(nsIFrame* aFrame) {
   if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     // Do NOT call GetAllInFlowRectsUnion for SVG - it will get the
     // covered region relative to the nsSVGOuterSVGFrame, which is absolutely
     // not what we want. SVG frames are always in user space, so they have
     // no offset adjustment to make.
     return nsPoint();
   }
--- a/layout/svg/nsSVGIntegrationUtils.h
+++ b/layout/svg/nsSVGIntegrationUtils.h
@@ -64,16 +64,22 @@ class nsSVGIntegrationUtils final {
   static bool UsingEffectsForFrame(const nsIFrame* aFrame);
 
   /**
    * Returns true if mask or clippath are currently applied to this frame.
    */
   static bool UsingMaskOrClipPathForFrame(const nsIFrame* aFrame);
 
   /**
+   * Returns true if the element has a clippath that is simple enough to
+   * be represented without a mask in WebRender.
+   */
+  static bool UsingSimpleClipPathForFrame(const nsIFrame* aFrame);
+
+  /**
    * Returns the size of the union of the border-box rects of all of
    * aNonSVGFrame's continuations.
    */
   static nsSize GetContinuationUnionSize(nsIFrame* aNonSVGFrame);
 
   /**
    * When SVG effects need to resolve percentage, userSpaceOnUse lengths, they
    * need a coordinate context to resolve them against. This method provides
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
@@ -345,17 +345,17 @@ nsresult JsepSessionImpl::GetRemoteIds(c
 
   return rv;
 }
 
 JsepSession::Result JsepSessionImpl::CreateOffer(
     const JsepOfferOptions& options, std::string* offer) {
   mLastError.clear();
 
-  if (mState != kJsepStateStable) {
+  if (mState != kJsepStateStable && mState != kJsepStateHaveLocalOffer) {
     JSEP_SET_ERROR("Cannot create offer in state " << GetStateStr(mState));
     // Spec doesn't seem to say this is an error. It probably should.
     return dom::PCError::InvalidStateError;
   }
 
   // This is one of those places where CreateOffer sets some state.
   SetIceRestarting(options.mIceRestart.isSome() && *(options.mIceRestart));
 
@@ -637,16 +637,21 @@ JsepSession::Result JsepSessionImpl::Set
       if (!mGeneratedOffer) {
         JSEP_SET_ERROR(
             "Cannot set local offer when createOffer has not been called.");
         return dom::PCError::InvalidModificationError;
       }
       if (sdp.empty()) {
         sdp = mGeneratedOffer->ToString();
       }
+      if (mState == kJsepStateHaveLocalOffer) {
+        // Rollback previous offer before applying the new one.
+        SetLocalDescription(kJsepSdpRollback, "");
+        MOZ_ASSERT(mState == kJsepStateStable);
+      }
       break;
     case kJsepSdpAnswer:
     case kJsepSdpPranswer:
       if (!mGeneratedAnswer) {
         JSEP_SET_ERROR(
             "Cannot set local answer when createAnswer has not been called.");
         return dom::PCError::InvalidModificationError;
       }
@@ -785,16 +790,22 @@ nsresult JsepSessionImpl::SetLocalDescri
 JsepSession::Result JsepSessionImpl::SetRemoteDescription(
     JsepSdpType type, const std::string& sdp) {
   mLastError.clear();
 
   MOZ_MTLOG(ML_DEBUG, "[" << mName << "]: SetRemoteDescription type=" << type
                           << "\nSDP=\n"
                           << sdp);
 
+  if (mState == kJsepStateHaveRemoteOffer && type == kJsepSdpOffer) {
+    // Rollback previous offer before applying the new one.
+    SetRemoteDescription(kJsepSdpRollback, "");
+    MOZ_ASSERT(mState == kJsepStateStable);
+  }
+
   if (type == kJsepSdpRollback) {
     if (mState != kJsepStateHaveRemoteOffer) {
       JSEP_SET_ERROR("Cannot rollback remote description in "
                      << GetStateStr(mState));
       return dom::PCError::InvalidStateError;
     }
 
     mPendingRemoteDescription.reset();
@@ -961,16 +972,17 @@ nsresult JsepSessionImpl::HandleNegotiat
     // Skip disabled m-sections.
     if (answer.GetMediaSection(i).GetPort() == 0) {
       transceiver->mTransport.Close();
       transceiver->Stop();
       transceiver->Disassociate();
       transceiver->ClearBundleLevel();
       transceiver->mSendTrack.SetActive(false);
       transceiver->mRecvTrack.SetActive(false);
+      transceiver->SetCanRecycle();
       // Do not clear mLevel yet! That will happen on the next negotiation.
       continue;
     }
 
     rv = MakeNegotiatedTransceiver(remote->GetMediaSection(i),
                                    local->GetMediaSection(i), transceiver);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -1373,17 +1385,17 @@ JsepTransceiver* JsepSessionImpl::GetTra
     }
   }
 
   return nullptr;
 }
 
 JsepTransceiver* JsepSessionImpl::GetTransceiverForLocal(size_t level) {
   if (JsepTransceiver* transceiver = GetTransceiverForLevel(level)) {
-    if (WasMsectionDisabledLastNegotiation(level) && transceiver->IsStopped() &&
+    if (transceiver->CanRecycle() &&
         transceiver->GetMediaType() != SdpMediaSection::kApplication) {
       // Attempt to recycle. If this fails, the old transceiver stays put.
       transceiver->Disassociate();
       JsepTransceiver* newTransceiver =
           FindUnassociatedTransceiver(transceiver->GetMediaType(), false);
       if (newTransceiver) {
         newTransceiver->SetLevel(level);
         transceiver->ClearLevel();
@@ -1415,18 +1427,17 @@ JsepTransceiver* JsepSessionImpl::GetTra
 
   return nullptr;
 }
 
 JsepTransceiver* JsepSessionImpl::GetTransceiverForRemote(
     const SdpMediaSection& msection) {
   size_t level = msection.GetLevel();
   if (JsepTransceiver* transceiver = GetTransceiverForLevel(level)) {
-    if (!WasMsectionDisabledLastNegotiation(level) ||
-        !transceiver->IsStopped()) {
+    if (!transceiver->CanRecycle()) {
       return transceiver;
     }
     transceiver->Disassociate();
     transceiver->ClearLevel();
   }
 
   // No transceiver for |level|
 
@@ -1504,26 +1515,16 @@ nsresult JsepSessionImpl::UpdateTranscei
     }
 
     transceiver->mRecvTrack.UpdateRecvTrack(remote, msection);
   }
 
   return NS_OK;
 }
 
-bool JsepSessionImpl::WasMsectionDisabledLastNegotiation(size_t level) const {
-  const Sdp* answer(GetAnswer());
-
-  if (answer && (level < answer->GetMediaSectionCount())) {
-    return mSdpHelper.MsectionIsDisabled(answer->GetMediaSection(level));
-  }
-
-  return false;
-}
-
 JsepTransceiver* JsepSessionImpl::FindUnassociatedTransceiver(
     SdpMediaSection::MediaType type, bool magic) {
   // Look through transceivers that are not mapped to an m-section
   for (RefPtr<JsepTransceiver>& transceiver : mTransceivers) {
     if (type == SdpMediaSection::kApplication &&
         type == transceiver->GetMediaType()) {
       transceiver->RestartDatachannelTransceiver();
       return transceiver.get();
@@ -1537,49 +1538,49 @@ JsepTransceiver* JsepSessionImpl::FindUn
 
   return nullptr;
 }
 
 void JsepSessionImpl::RollbackLocalOffer() {
   for (size_t i = 0; i < mTransceivers.size(); ++i) {
     RefPtr<JsepTransceiver>& transceiver(mTransceivers[i]);
     if (i < mOldTransceivers.size()) {
-      transceiver->Rollback(*mOldTransceivers[i]);
+      transceiver->Rollback(*mOldTransceivers[i], false);
       continue;
     }
 
     RefPtr<JsepTransceiver> temp(
         new JsepTransceiver(transceiver->GetMediaType()));
     temp->mSendTrack.PopulateCodecs(mSupportedCodecs);
     temp->mRecvTrack.PopulateCodecs(mSupportedCodecs);
-    transceiver->Rollback(*temp);
+    transceiver->Rollback(*temp, false);
   }
 
   mOldTransceivers.clear();
 }
 
 void JsepSessionImpl::RollbackRemoteOffer() {
   for (size_t i = 0; i < mTransceivers.size(); ++i) {
     RefPtr<JsepTransceiver>& transceiver(mTransceivers[i]);
     if (i < mOldTransceivers.size()) {
-      transceiver->Rollback(*mOldTransceivers[i]);
+      transceiver->Rollback(*mOldTransceivers[i], true);
       continue;
     }
 
     // New transceiver!
     bool shouldRemove = !transceiver->HasAddTrackMagic() &&
                         transceiver->WasCreatedBySetRemote();
 
     // We rollback even for transceivers we will remove, just to ensure we end
     // up at the starting state.
     RefPtr<JsepTransceiver> temp(
         new JsepTransceiver(transceiver->GetMediaType()));
     temp->mSendTrack.PopulateCodecs(mSupportedCodecs);
     temp->mRecvTrack.PopulateCodecs(mSupportedCodecs);
-    transceiver->Rollback(*temp);
+    transceiver->Rollback(*temp, true);
 
     if (shouldRemove) {
       transceiver->Stop();
       transceiver->SetRemoved();
       mTransceivers.erase(mTransceivers.begin() + i);
       --i;
     }
   }
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h
@@ -167,17 +167,16 @@ class JsepSessionImpl : public JsepSessi
   nsresult SetLocalDescriptionAnswer(JsepSdpType type, UniquePtr<Sdp> answer);
   nsresult SetRemoteDescriptionOffer(UniquePtr<Sdp> offer);
   nsresult SetRemoteDescriptionAnswer(JsepSdpType type, UniquePtr<Sdp> answer);
   nsresult ValidateLocalDescription(const Sdp& description, JsepSdpType type);
   nsresult ValidateRemoteDescription(const Sdp& description);
   nsresult ValidateOffer(const Sdp& offer);
   nsresult ValidateAnswer(const Sdp& offer, const Sdp& answer);
   nsresult UpdateTransceiversFromRemoteDescription(const Sdp& remote);
-  bool WasMsectionDisabledLastNegotiation(size_t level) const;
   JsepTransceiver* GetTransceiverForLevel(size_t level);
   JsepTransceiver* GetTransceiverForMid(const std::string& mid);
   JsepTransceiver* GetTransceiverForLocal(size_t level);
   JsepTransceiver* GetTransceiverForRemote(const SdpMediaSection& msection);
   JsepTransceiver* GetTransceiverWithTransport(const std::string& transportId);
   // The w3c and IETF specs have a lot of "magical" behavior that happens when
   // addTrack is used. This was a deliberate design choice. Sadface.
   JsepTransceiver* FindUnassociatedTransceiver(SdpMediaSection::MediaType type,
--- a/media/webrtc/signaling/src/jsep/JsepTransceiver.h
+++ b/media/webrtc/signaling/src/jsep/JsepTransceiver.h
@@ -31,42 +31,46 @@ class JsepTransceiver {
         mSendTrack(type, sdp::kSend),
         mRecvTrack(type, sdp::kRecv),
         mLevel(SIZE_MAX),
         mBundleLevel(SIZE_MAX),
         mAddTrackMagic(false),
         mWasCreatedBySetRemote(false),
         mStopped(false),
         mRemoved(false),
-        mNegotiated(false) {}
+        mNegotiated(false),
+        mCanRecycle(false) {}
 
   // Can't use default copy c'tor because of the refcount members. Ugh.
   JsepTransceiver(const JsepTransceiver& orig)
       : mJsDirection(orig.mJsDirection),
         mSendTrack(orig.mSendTrack),
         mRecvTrack(orig.mRecvTrack),
         mTransport(orig.mTransport),
         mMid(orig.mMid),
         mLevel(orig.mLevel),
         mBundleLevel(orig.mBundleLevel),
         mAddTrackMagic(orig.mAddTrackMagic),
         mWasCreatedBySetRemote(orig.mWasCreatedBySetRemote),
         mStopped(orig.mStopped),
         mRemoved(orig.mRemoved),
-        mNegotiated(orig.mNegotiated) {}
+        mNegotiated(orig.mNegotiated),
+        mCanRecycle(orig.mCanRecycle) {}
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTransceiver);
 
-  void Rollback(JsepTransceiver& oldTransceiver) {
+  void Rollback(JsepTransceiver& oldTransceiver, bool rollbackLevel) {
     MOZ_ASSERT(oldTransceiver.GetMediaType() == GetMediaType());
     MOZ_ASSERT(!oldTransceiver.IsNegotiated() || !oldTransceiver.HasLevel() ||
                !HasLevel() || oldTransceiver.GetLevel() == GetLevel());
     mTransport = oldTransceiver.mTransport;
-    mLevel = oldTransceiver.mLevel;
-    mBundleLevel = oldTransceiver.mBundleLevel;
+    if (rollbackLevel) {
+      mLevel = oldTransceiver.mLevel;
+      mBundleLevel = oldTransceiver.mBundleLevel;
+    }
     mRecvTrack = oldTransceiver.mRecvTrack;
 
     // stop() caused by a disabled m-section in a remote offer cannot be
     // rolled back.
     if (!IsStopped()) {
       mMid = oldTransceiver.mMid;
     }
   }
@@ -148,16 +152,20 @@ class JsepTransceiver {
   void SetNegotiated() {
     MOZ_ASSERT(IsAssociated());
     MOZ_ASSERT(HasLevel());
     mNegotiated = true;
   }
 
   bool IsNegotiated() const { return mNegotiated; }
 
+  void SetCanRecycle() { mCanRecycle = true; }
+
+  bool CanRecycle() const { return mCanRecycle; }
+
   // Convenience function
   SdpMediaSection::MediaType GetMediaType() const {
     MOZ_ASSERT(mRecvTrack.GetMediaType() == mSendTrack.GetMediaType());
     return mRecvTrack.GetMediaType();
   }
 
   bool HasOwnTransport() const {
     if (mTransport.mComponents &&
@@ -182,13 +190,14 @@ class JsepTransceiver {
   size_t mBundleLevel;  // SIZE_MAX if no bundle level
   // The w3c and IETF specs have a lot of "magical" behavior that happens
   // when addTrack is used. This was a deliberate design choice. Sadface.
   bool mAddTrackMagic;
   bool mWasCreatedBySetRemote;
   bool mStopped;
   bool mRemoved;
   bool mNegotiated;
+  bool mCanRecycle;
 };
 
 }  // namespace mozilla
 
 #endif  // _JSEPTRANSCEIVER_H_
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -27,16 +27,17 @@ import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.AnyThread;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
@@ -259,16 +260,19 @@ public class GeckoView extends FrameLayo
         }
     }
 
     /**
      * Unsets the current session from this instance and returns it, if any. You must call
      * this before {@link #setSession(GeckoSession)} if there is already an open session
      * set for this instance.
      *
+     * Note: this method does not close the session and the session remains active. The
+     * caller is responsible for calling {@link GeckoSession#close()} when appropriate.
+     *
      * @return The {@link GeckoSession} that was set for this instance. May be null.
      */
     @UiThread
     public @Nullable GeckoSession releaseSession() {
         ThreadUtils.assertOnUiThread();
 
         if (mSession == null) {
             return null;
@@ -422,17 +426,18 @@ public class GeckoView extends FrameLayo
     public @NonNull DynamicToolbarAnimator getDynamicToolbarAnimator() {
         ThreadUtils.assertOnUiThread();
         return mSession.getDynamicToolbarAnimator();
     }
 
     @Override
     public void onAttachedToWindow() {
         if (mSession == null) {
-            setSession(new GeckoSession(), GeckoRuntime.getDefault(getContext()));
+            Log.w(LOGTAG, "No GeckoSession attached to this GeckoView instance. Call setSession to attach a GeckoSession to this instance.");
+            return;
         }
 
         if (!mSession.isOpen()) {
             mSession.open(mRuntime);
         }
         mRuntime.orientationChanged();
 
         super.onAttachedToWindow();
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -55,16 +55,19 @@ exclude: true
 [68.11]: ../ContentBlocking.html#AT_FINGERPRINTING
 
 - Added `HistoryItem` and `HistoryList` interfaces and `onHistoryStateChange` to 
   [`HistoryDelegate`][68.12] and added `gotoHistoryIndex` to [`GeckoSession`][68.13].
 
 [68.12]: ../GeckoSession.HistoryDelegate.html
 [68.13]: ../GeckoSession.html
 
+- [`GeckoView`][65.5] will not create a [`GeckoSession`][65.9] anymore when
+  attached to a window without a session.
+
 ## v67
 - Added [`setAutomaticFontSizeAdjustment`][67.2] to
   [`GeckoRuntimeSettings`][67.3] for automatically adjusting font size settings
   depending on the OS-level font size setting.
 
 [67.2]: ../GeckoRuntimeSettings.html#setAutomaticFontSizeAdjustment-boolean-
 [67.3]: ../GeckoRuntimeSettings.html
 
--- a/netwerk/dns/effective_tld_names.dat
+++ b/netwerk/dns/effective_tld_names.dat
@@ -6186,44 +6186,43 @@ turen.tn
 to
 com.to
 gov.to
 net.to
 org.to
 edu.to
 mil.to
 
-// subTLDs: https://www.nic.tr/forms/eng/policies.pdf
-//     and: https://www.nic.tr/forms/politikalar.pdf
-// Submitted by <mehmetgurevin@gmail.com>
+// tr : https://nic.tr/
+// https://nic.tr/forms/eng/policies.pdf
+// https://nic.tr/index.php?USRACTN=PRICELST
 tr
+av.tr
+bbs.tr
+bel.tr
+biz.tr
 com.tr
+dr.tr
+edu.tr
+gen.tr
+gov.tr
 info.tr
-biz.tr
+mil.tr
+k12.tr
+kep.tr
+name.tr
 net.tr
 org.tr
-web.tr
-gen.tr
-tv.tr
-av.tr
-dr.tr
-bbs.tr
-name.tr
+pol.tr
 tel.tr
-gov.tr
-bel.tr
-pol.tr
-mil.tr
-k12.tr
-edu.tr
-kep.tr
-
+tsk.tr
+tv.tr
+web.tr
 // Used by Northern Cyprus
 nc.tr
-
 // Used by government agencies of Northern Cyprus
 gov.nc.tr
 
 // tt : http://www.nic.tt/
 tt
 co.tt
 com.tt
 org.tt
@@ -10874,16 +10873,17 @@ bplaced.net
 square7.net
 
 // BrowserSafetyMark
 // Submitted by Dave Tharp <browsersafetymark.io@quicinc.com>
 browsersafetymark.io
 
 // Bytemark Hosting : https://www.bytemark.co.uk
 // Submitted by Paul Cammish <paul.cammish@bytemark.co.uk>
+uk0.bigv.io
 dh.bytemark.co.uk
 vm.bytemark.co.uk
 
 // callidomus : https://www.callidomus.com/
 // Submitted by Marcus Popp <admin@callidomus.com>
 mycd.eu
 
 // CentralNic : http://www.centralnic.com/names/domains
@@ -11716,16 +11716,21 @@ service.gov.uk
 // Submitted by Patrick Toomey <security@github.com>
 github.io
 githubusercontent.com
 
 // GitLab, Inc.
 // Submitted by Alex Hanselka <alex@gitlab.com>
 gitlab.io
 
+// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/
+// Submitted by Tom Whitwell <tom.whitwell@digital.cabinet-office.gov.uk>
+cloudapps.digital
+london.cloudapps.digital
+
 // UKHomeOffice : https://www.gov.uk/government/organisations/home-office
 // Submitted by Jon Shanks <jon.shanks@digital.homeoffice.gov.uk>
 homeoffice.gov.uk
 
 // GlobeHosting, Inc.
 // Submitted by Zoltan Egresi <egresi@globehosting.com>
 ro.im
 shop.ro
@@ -12083,16 +12088,20 @@ mozilla-iot.org
 bmoattachments.org
 
 // MSK-IX : https://www.msk-ix.ru/
 // Submitted by Khannanov Roman <r.khannanov@msk-ix.ru>
 net.ru
 org.ru
 pp.ru
 
+// Nabu Casa : https://www.nabucasa.com
+// Submitted by Paulus Schoutsen <infra@nabucasa.com>
+ui.nabu.casa
+
 // Netlify : https://www.netlify.com
 // Submitted by Jessica Parsons <jessica@netlify.com>
 bitballoon.com
 netlify.com
 
 // Neustar Inc.
 // Submitted by Trung Tran <Trung.Tran@neustar.biz>
 4u.com
--- a/remote/Log.jsm
+++ b/remote/Log.jsm
@@ -1,28 +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/. */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["Log"];
 
-const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 const {Log: StdLog} = ChromeUtils.import("resource://gre/modules/Log.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 const LOG_LEVEL = "remote.log.level";
 
 /** E10s compatible wrapper for the standard logger from Log.jsm. */
 class Log {
   static get() {
     const logger = StdLog.repository.getLogger("RemoteAgent");
     if (logger.ownAppenders.length == 0) {
       logger.addAppender(new StdLog.DumpAppender());
       logger.manageLevelFromPref(LOG_LEVEL);
     }
     return logger;
   }
 
   static get verbose() {
-    return StdLog.Level[Preferences.get(LOG_LEVEL)] >= StdLog.Level.Info;
+    // we can't use Preferences.jsm before first paint,
+    // see ../browser/base/content/test/performance/browser_startup.js
+    const level = Services.prefs.getStringPref(LOG_LEVEL, "Info");
+    return StdLog.Level[level] >= StdLog.Level.Info;
   }
 }
--- a/remote/jar.mn
+++ b/remote/jar.mn
@@ -41,14 +41,11 @@ remote.jar:
   content/domains/content/Performance.jsm (domains/content/Performance.jsm)
   content/domains/content/Runtime.jsm (domains/content/Runtime.jsm)
   content/domains/content/Security.jsm (domains/content/Security.jsm)
   content/domains/parent/Browser.jsm (domains/parent/Browser.jsm)
   content/domains/parent/Target.jsm (domains/parent/Target.jsm)
 
   # transport layer
   content/server/HTTPD.jsm (../netwerk/test/httpserver/httpd.js)
-  content/server/Packet.jsm (server/Packet.jsm)
-  content/server/Socket.jsm (server/Socket.jsm)
   content/server/Stream.jsm (server/Stream.jsm)
-  content/server/Transport.jsm (server/Transport.jsm)
   content/server/WebSocket.jsm (server/WebSocket.jsm)
   content/server/WebSocketTransport.jsm (server/WebSocketTransport.jsm)
deleted file mode 100644
--- a/remote/server/Packet.jsm
+++ /dev/null
@@ -1,413 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This is an XPCOM service-ified copy of ../devtools/shared/transport/packets.js.
-
-"use strict",
-
-var EXPORTED_SYMBOLS = [
-  "RawPacket",
-  "Packet",
-  "JSONPacket",
-  "BulkPacket",
-];
-
-/**
- * Packets contain read / write functionality for the different packet types
- * supported by the debugging protocol, so that a transport can focus on
- * delivery and queue management without worrying too much about the specific
- * packet types.
- *
- * They are intended to be "one use only", so a new packet should be
- * instantiated for each incoming or outgoing packet.
- *
- * A complete Packet type should expose at least the following:
- *   * read(stream, scriptableStream)
- *     Called when the input stream has data to read
- *   * write(stream)
- *     Called when the output stream is ready to write
- *   * get done()
- *     Returns true once the packet is done being read / written
- *   * destroy()
- *     Called to clean up at the end of use
- */
-
-const {Stream} = ChromeUtils.import("chrome://remote/content/server/Stream.jsm");
-
-const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
-    .createInstance(Ci.nsIScriptableUnicodeConverter);
-unicodeConverter.charset = "UTF-8";
-
-const defer = function() {
-  let deferred = {
-    promise: new Promise((resolve, reject) => {
-      deferred.resolve = resolve;
-      deferred.reject = reject;
-    }),
-  };
-  return deferred;
-};
-
-// The transport's previous check ensured the header length did not
-// exceed 20 characters.  Here, we opt for the somewhat smaller, but still
-// large limit of 1 TiB.
-const PACKET_LENGTH_MAX = Math.pow(2, 40);
-
-/**
- * A generic Packet processing object (extended by two subtypes below).
- *
- * @class
- */
-function Packet(transport) {
-  this._transport = transport;
-  this._length = 0;
-}
-
-/**
- * Attempt to initialize a new Packet based on the incoming packet header
- * we've received so far.  We try each of the types in succession, trying
- * JSON packets first since they are much more common.
- *
- * @param {string} header
- *     Packet header string to attempt parsing.
- * @param {DebuggerTransport} transport
- *     Transport instance that will own the packet.
- *
- * @return {Packet}
- *     Parsed packet of the matching type, or null if no types matched.
- */
-Packet.fromHeader = function(header, transport) {
-  return JSONPacket.fromHeader(header, transport) ||
-         BulkPacket.fromHeader(header, transport);
-};
-
-Packet.prototype = {
-
-  get length() {
-    return this._length;
-  },
-
-  set length(length) {
-    if (length > PACKET_LENGTH_MAX) {
-      throw new Error("Packet length " + length +
-                      " exceeds the max length of " + PACKET_LENGTH_MAX);
-    }
-    this._length = length;
-  },
-
-  destroy() {
-    this._transport = null;
-  },
-};
-
-/**
- * With a JSON packet (the typical packet type sent via the transport),
- * data is transferred as a JSON packet serialized into a string,
- * with the string length prepended to the packet, followed by a colon
- * ([length]:[packet]). The contents of the JSON packet are specified in
- * the Remote Debugging Protocol specification.
- *
- * @param {DebuggerTransport} transport
- *     Transport instance that will own the packet.
- */
-function JSONPacket(transport) {
-  Packet.call(this, transport);
-  this._data = "";
-  this._done = false;
-}
-
-/**
- * Attempt to initialize a new JSONPacket based on the incoming packet
- * header we've received so far.
- *
- * @param {string} header
- *     Packet header string to attempt parsing.
- * @param {DebuggerTransport} transport
- *     Transport instance that will own the packet.
- *
- * @return {JSONPacket}
- *     Parsed packet, or null if it's not a match.
- */
-JSONPacket.fromHeader = function(header, transport) {
-  let match = this.HEADER_PATTERN.exec(header);
-
-  if (!match) {
-    return null;
-  }
-
-  let packet = new JSONPacket(transport);
-  packet.length = +match[1];
-  return packet;
-};
-
-JSONPacket.HEADER_PATTERN = /^(\d+):$/;
-
-JSONPacket.prototype = Object.create(Packet.prototype);
-
-Object.defineProperty(JSONPacket.prototype, "object", {
-  /**
-   * Gets the object (not the serialized string) being read or written.
-   */
-  get() {
-    return this._object;
-  },
-
-  /**
-   * Sets the object to be sent when write() is called.
-   */
-  set(object) {
-    this._object = object;
-    let data = JSON.stringify(object);
-    this._data = unicodeConverter.ConvertFromUnicode(data);
-    this.length = this._data.length;
-  },
-});
-
-JSONPacket.prototype.read = function(stream, scriptableStream) {
-
-  // Read in more packet data.
-  this._readData(stream, scriptableStream);
-
-  if (!this.done) {
-    // Don't have a complete packet yet.
-    return;
-  }
-
-  let json = this._data;
-  try {
-    json = unicodeConverter.ConvertToUnicode(json);
-    this._object = JSON.parse(json);
-  } catch (e) {
-    let msg = "Error parsing incoming packet: " + json + " (" + e +
-              " - " + e.stack + ")";
-    console.error(msg);
-    dump(msg + "\n");
-    return;
-  }
-
-  this._transport._onJSONObjectReady(this._object);
-};
-
-JSONPacket.prototype._readData = function(stream, scriptableStream) {
-  let bytesToRead = Math.min(
-      this.length - this._data.length,
-      stream.available());
-  this._data += scriptableStream.readBytes(bytesToRead);
-  this._done = this._data.length === this.length;
-};
-
-JSONPacket.prototype.write = function(stream) {
-
-  if (this._outgoing === undefined) {
-    // Format the serialized packet to a buffer
-    this._outgoing = this.length + ":" + this._data;
-  }
-
-  let written = stream.write(this._outgoing, this._outgoing.length);
-  this._outgoing = this._outgoing.slice(written);
-  this._done = !this._outgoing.length;
-};
-
-Object.defineProperty(JSONPacket.prototype, "done", {
-  get() {
-    return this._done;
-  },
-});
-
-JSONPacket.prototype.toString = function() {
-  return JSON.stringify(this._object, null, 2);
-};
-
-/**
- * With a bulk packet, data is transferred by temporarily handing over
- * the transport's input or output stream to the application layer for
- * writing data directly.  This can be much faster for large data sets,
- * and avoids various stages of copies and data duplication inherent in
- * the JSON packet type.  The bulk packet looks like:
- *
- *     bulk [actor] [type] [length]:[data]
- *
- * The interpretation of the data portion depends on the kind of actor and
- * the packet's type.  See the Remote Debugging Protocol Stream Transport
- * spec for more details.
- *
- * @param {DebuggerTransport} transport
- *     Transport instance that will own the packet.
- */
-function BulkPacket(transport) {
-  Packet.call(this, transport);
-  this._done = false;
-  this._readyForWriting = defer();
-}
-
-/**
- * Attempt to initialize a new BulkPacket based on the incoming packet
- * header we've received so far.
- *
- * @param {string} header
- *     Packet header string to attempt parsing.
- * @param {DebuggerTransport} transport
- *     Transport instance that will own the packet.
- *
- * @return {BulkPacket}
- *     Parsed packet, or null if it's not a match.
- */
-BulkPacket.fromHeader = function(header, transport) {
-  let match = this.HEADER_PATTERN.exec(header);
-
-  if (!match) {
-    return null;
-  }
-
-  let packet = new BulkPacket(transport);
-  packet.header = {
-    actor: match[1],
-    type: match[2],
-    length: +match[3],
-  };
-  return packet;
-};
-
-BulkPacket.HEADER_PATTERN = /^bulk ([^: ]+) ([^: ]+) (\d+):$/;
-
-BulkPacket.prototype = Object.create(Packet.prototype);
-
-BulkPacket.prototype.read = function(stream) {
-  // Temporarily pause monitoring of the input stream
-  this._transport.pauseIncoming();
-
-  let deferred = defer();
-
-  this._transport._onBulkReadReady({
-    actor: this.actor,
-    type: this.type,
-    length: this.length,
-    copyTo: (output) => {
-      let copying = StreamUtils.copyStream(stream, output, this.length);
-      deferred.resolve(copying);
-      return copying;
-    },
-    stream,
-    done: deferred,
-  });
-
-  // Await the result of reading from the stream
-  deferred.promise.then(() => {
-    this._done = true;
-    this._transport.resumeIncoming();
-  }, this._transport.close);
-
-  // Ensure this is only done once
-  this.read = () => {
-    throw new Error("Tried to read() a BulkPacket's stream multiple times.");
-  };
-};
-
-BulkPacket.prototype.write = function(stream) {
-  if (this._outgoingHeader === undefined) {
-    // Format the serialized packet header to a buffer
-    this._outgoingHeader = "bulk " + this.actor + " " + this.type + " " +
-                           this.length + ":";
-  }
-
-  // Write the header, or whatever's left of it to write.
-  if (this._outgoingHeader.length) {
-    let written = stream.write(this._outgoingHeader,
-        this._outgoingHeader.length);
-    this._outgoingHeader = this._outgoingHeader.slice(written);
-    return;
-  }
-
-  // Temporarily pause the monitoring of the output stream
-  this._transport.pauseOutgoing();
-
-  let deferred = defer();
-
-  this._readyForWriting.resolve({
-    copyFrom: (input) => {
-      let copying = StreamUtils.copyStream(input, stream, this.length);
-      deferred.resolve(copying);
-      return copying;
-    },
-    stream,
-    done: deferred,
-  });
-
-  // Await the result of writing to the stream
-  deferred.promise.then(() => {
-    this._done = true;
-    this._transport.resumeOutgoing();
-  }, this._transport.close);
-
-  // Ensure this is only done once
-  this.write = () => {
-    throw new Error("Tried to write() a BulkPacket's stream multiple times.");
-  };
-};
-
-Object.defineProperty(BulkPacket.prototype, "streamReadyForWriting", {
-  get() {
-    return this._readyForWriting.promise;
-  },
-});
-
-Object.defineProperty(BulkPacket.prototype, "header", {
-  get() {
-    return {
-      actor: this.actor,
-      type: this.type,
-      length: this.length,
-    };
-  },
-
-  set(header) {
-    this.actor = header.actor;
-    this.type = header.type;
-    this.length = header.length;
-  },
-});
-
-Object.defineProperty(BulkPacket.prototype, "done", {
-  get() {
-    return this._done;
-  },
-});
-
-BulkPacket.prototype.toString = function() {
-  return "Bulk: " + JSON.stringify(this.header, null, 2);
-};
-
-/**
- * RawPacket is used to test the transport's error handling of malformed
- * packets, by writing data directly onto the stream.
- * @param transport DebuggerTransport
- *        The transport instance that will own the packet.
- * @param data string
- *        The raw string to send out onto the stream.
- */
-function RawPacket(transport, data) {
-  Packet.call(this, transport);
-  this._data = data;
-  this.length = data.length;
-  this._done = false;
-}
-
-RawPacket.prototype = Object.create(Packet.prototype);
-
-RawPacket.prototype.read = function() {
-  // this has not yet been needed for testing
-  throw new Error("Not implemented");
-};
-
-RawPacket.prototype.write = function(stream) {
-  let written = stream.write(this._data, this._data.length);
-  this._data = this._data.slice(written);
-  this._done = !this._data.length;
-};
-
-Object.defineProperty(RawPacket.prototype, "done", {
-  get() {
-    return this._done;
-  },
-});
deleted file mode 100644
--- a/remote/server/Socket.jsm
+++ /dev/null
@@ -1,270 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-var EXPORTED_SYMBOLS = [
-  "ConnectionHandshake",
-  "SocketListener",
-];
-
-// This is an XPCOM-service-ified copy of ../devtools/shared/security/socket.js.
-
-const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm");
-const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm");
-const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetters(this, {
-  DebuggerTransport: "chrome://remote/content/server/Transport.jsm",
-  WebSocketDebuggerTransport: "chrome://remote/content/server/WebSocketTransport.jsm",
-  WebSocketServer: "chrome://remote/content/server/WebSocket.jsm",
-});
-
-XPCOMUtils.defineLazyGetter(this, "log", Log.get);
-XPCOMUtils.defineLazyGetter(this, "nsFile", () => CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath"));
-
-const LOOPBACKS = ["localhost", "127.0.0.1"];
-
-const {KeepWhenOffline, LoopbackOnly} = Ci.nsIServerSocket;
-
-this.SocketListener = class SocketListener {
-  constructor() {
-    this.socket = null;
-    this.network = null;
-
-    this.nextConnID = 0;
-
-    this.onConnectionCreated = null;
-    this.onConnectionClose = null;
-
-    EventEmitter.decorate(this);
-  }
-
-  get listening() {
-    return !!this.socket;
-  }
-
-  /**
-   * @param {String} addr
-   *     [<network>][:<host>][:<port>]
-   *     networks: ws, unix, tcp
-   */
-  listen(addr) {
-    const [network, host, port] = addr.split(":");
-    try {
-      this._listen(network, host, port);
-    } catch (e) {
-      this.close();
-      throw new Error(`Unable to start socket server on ${addr}: ${e.message}`, e);
-    }
-  }
-
-  _listen(network = "tcp", host = "localhost", port = 0) {
-    if (typeof network != "string" ||
-        typeof host != "string" ||
-        (network != "unix" && typeof port != "number")) {
-      throw new TypeError();
-    }
-    if (network != "unix" && (!Number.isInteger(port) || port < 0)) {
-      throw new RangeError();
-    }
-    if (!SocketListener.Networks.includes(network)) {
-      throw new Error("Unexpected network: " + network);
-    }
-    if (!LOOPBACKS.includes(host)) {
-      throw new Error("Restricted to listening on loopback devices");
-    }
-
-    const flags = KeepWhenOffline | LoopbackOnly;
-
-    const backlog = 4;
-    this.socket = createSocket();
-    this.network = network;
-
-    switch (this.network) {
-      case "tcp":
-      case "ws":
-        // -1 means kernel-assigned port in Gecko
-        if (port == 0) {
-          port = -1;
-        }
-        
-        this.socket.initSpecialConnection(port, flags, backlog);
-        break;
-
-      case "unix":
-        // concrete Unix socket
-        if (host.startsWith("/")) {
-          const file = nsFile(host);
-          if (file.exists()) {
-            file.remove(false);
-          }
-          this.socket.initWithFilename(file, Number.parseInt("666", 8), backlog);
-        // abstract Unix socket
-        } else {
-          this.socket.initWithAbstractAddress(host, backlog);
-        }
-        break;
-    }
-
-    this.socket.asyncListen(this);
-  }
-
-  close() {
-    if (this.socket) {
-      this.socket.close();
-      this.socket = null;
-    }
-    // TODO(ato): removeSocketListener?
-  }
-
-  get host() {
-    if (this.socket) {
-      // TODO(ato): Don't hardcode:
-      return "localhost";
-    }
-    return null;
-  }
-
-  get port() {
-    if (this.socket) {
-      return this.socket.port;
-    }
-    return null;
-  }
-
-  onAllowedConnection(eventName, transport) {
-    this.emit("accepted", transport, this);
-  }
-
-  // nsIServerSocketListener implementation
-
-  onSocketAccepted(socket, socketTransport) {
-    const conn = new ConnectionHandshake(this, socketTransport);
-    conn.once("allowed", this.onAllowedConnection.bind(this));
-    conn.handle();
-  }
-
-  onStopListening(socket, status) {
-    dump("onStopListening: " + status + "\n");
-  }
-};
-
-SocketListener.Networks = ["tcp", "unix", "ws"];
-
-/**
- * Created by SocketListener for each accepted incoming socket.
- * This is a short-lived object used to implement a handshake,
- * before the socket transport is handed back to RemoteAgent.
- */
-this.ConnectionHandshake = class ConnectionHandshake {
-  constructor(listener, socketTransport) {
-    this.listener = listener;
-    this.socket = socketTransport;
-    this.transport = null;
-    this.destroyed = false;
-
-    EventEmitter.decorate(this);
-  }
-
-  destructor() {
-    this.listener = null;
-    this.socket = null;
-    this.transport = null;
-    this.destroyed = true;
-  }
-
-  get address() {
-    return `${this.host}:${this.port}`;
-  }
-
-  get host() {
-    return this.socket.host;
-  }
-
-  get port() {
-    return this.socket.port;
-  }
-
-  async handle() {
-    try {
-      await this.createTransport();
-      this.allow();
-    } catch (e) {
-      this.deny(e);
-    }
-  }
-
-  async createTransport() {
-    const rx = this.socket.openInputStream(0, 0, 0);
-    const tx = this.socket.openOutputStream(0, 0, 0);
-
-    if (this.listener.network == "ws") {
-      const so = await WebSocketServer.accept(this.socket, rx, tx);
-      this.transport = new WebSocketDebuggerTransport(so);
-    } else {
-      this.transport = new DebuggerTransport(rx, tx);
-    }
-
-    // This handles early disconnects from clients, primarily for failed TLS negotiation.
-    // We don't support TLS connections in RDP, but might be useful for future blocklist.
-    this.transport.hooks = {
-      onClosed: reason => this.deny(reason),
-    };
-    // TODO(ato): Review if this is correct:
-    this.transport.ready();
-  }
-
-  allow() {
-    if (this.destroyed) {
-      return;
-    }
-    log.debug(`Accepted connection from ${this.address}`);
-    this.emit("allowed", this.transport);
-    this.destructor();
-  }
-
-  deny(result) {
-    if (this.destroyed) {
-      return;
-    }
-
-    let err = legibleError(result);
-    log.warn(`Connection from ${this.address} denied: ${err.message}`, err.stack);
-
-    if (this.transport) {
-      this.transport.hooks = null;
-      this.transport.close(result); 
-    }
-    this.socket.close(result);
-    this.destructor();
-  }
-};
-
-function createSocket() {
-  return Cc["@mozilla.org/network/server-socket;1"]
-      .createInstance(Ci.nsIServerSocket);
-}
-
-// TODO(ato): Move to separate module
-function legibleError(obj) {
-  if (obj instanceof Ci.nsIException) {
-    for (const result in Cr) {
-      if (obj.result == Cr[result]) {
-        return {
-          message: result,
-          stack: obj.location.formattedStack,
-        };
-      }
-    }
-
-    return {
-      message: "nsIException",
-      stack: obj,
-    };
-  } else {
-    return obj;
-  }
-}
deleted file mode 100644
--- a/remote/server/Transport.jsm
+++ /dev/null
@@ -1,527 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This is an XPCOM service-ified copy of ../devtools/shared/transport/transport.js.
-
-/* global Pipe, ScriptableInputStream */
-
-"use strict";
-
-var EXPORTED_SYMBOLS = ["DebuggerTransport"];
-
-const CC = Components.Constructor;
-
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm");
-const {Stream} = ChromeUtils.import("chrome://remote/content/server/Stream.jsm");
-const {
-  Packet,
-  JSONPacket,
-  BulkPacket,
-} = ChromeUtils.import("chrome://remote/content/server/Packet.jsm");
-
-const executeSoon = function(func) {
-  Services.tm.dispatchToMainThread(func);
-};
-
-const flags = {wantVerbose: true, wantLogging: true};
-
-const dumpv =
-  flags.wantVerbose ?
-  function(msg) {
-    dump(msg + "\n");
-  } :
-  function() {};
-
-const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
-    "nsIScriptableInputStream", "init");
-
-const PACKET_HEADER_MAX = 200;
-
-/**
- * An adapter that handles data transfers between the debugger client
- * and server. It can work with both nsIPipe and nsIServerSocket
- * transports so long as the properly created input and output streams
- * are specified.  (However, for intra-process connections,
- * LocalDebuggerTransport, below, is more efficient than using an nsIPipe
- * pair with DebuggerTransport.)
- *
- * @param {nsIAsyncInputStream} input
- *     The input stream.
- * @param {nsIAsyncOutputStream} output
- *     The output stream.
- *
- * Given a DebuggerTransport instance dt:
- * 1) Set dt.hooks to a packet handler object (described below).
- * 2) Call dt.ready() to begin watching for input packets.
- * 3) Call dt.send() / dt.startBulkSend() to send packets.
- * 4) Call dt.close() to close the connection, and disengage from
- *    the event loop.
- *
- * A packet handler is an object with the following methods:
- *
- * - onPacket(packet) - called when we have received a complete packet.
- *   |packet| is the parsed form of the packet --- a JavaScript value, not
- *   a JSON-syntax string.
- *
- * - onBulkPacket(packet) - called when we have switched to bulk packet
- *   receiving mode. |packet| is an object containing:
- *   * actor:  Name of actor that will receive the packet
- *   * type:   Name of actor's method that should be called on receipt
- *   * length: Size of the data to be read
- *   * stream: This input stream should only be used directly if you
- *             can ensure that you will read exactly |length| bytes and
- *             will not close the stream when reading is complete
- *   * done:   If you use the stream directly (instead of |copyTo|
- *             below), you must signal completion by resolving/rejecting
- *             this deferred.  If it's rejected, the transport will
- *             be closed.  If an Error is supplied as a rejection value,
- *             it will be logged via |dump|.  If you do use |copyTo|,
- *             resolving is taken care of for you when copying completes.
- *   * copyTo: A helper function for getting your data out of the
- *             stream that meets the stream handling requirements above,
- *             and has the following signature:
- *
- *             @param nsIAsyncOutputStream {output}
- *                 The stream to copy to.
- *
- *             @return {Promise}
- *                 The promise is resolved when copying completes or
- *                 rejected if any (unexpected) errors occur.  This object
- *                 also emits "progress" events for each chunk that is
- *                 copied.  See stream-utils.js.
- *
- * - onClosed(reason) - called when the connection is closed. |reason|
- *   is an optional nsresult or object, typically passed when the
- *   transport is closed due to some error in a underlying stream.
- *
- * See ./packets.js and the Remote Debugging Protocol specification for
- * more details on the format of these packets.
- *
- * @class
- */
-function DebuggerTransport(input, output) {
-  EventEmitter.decorate(this);
-
-  this._input = input;
-  this._scriptableInput = new ScriptableInputStream(input);
-  this._output = output;
-
-  // The current incoming (possibly partial) header, which will determine
-  // which type of Packet |_incoming| below will become.
-  this._incomingHeader = "";
-  // The current incoming Packet object
-  this._incoming = null;
-  // A queue of outgoing Packet objects
-  this._outgoing = [];
-
-  this.hooks = null;
-  this.active = false;
-
-  this._incomingEnabled = true;
-  this._outgoingEnabled = true;
-
-  this.close = this.close.bind(this);
-}
-
-DebuggerTransport.prototype = {
-  /**
-   * Transmit an object as a JSON packet.
-   *
-   * This method returns immediately, without waiting for the entire
-   * packet to be transmitted, registering event handlers as needed to
-   * transmit the entire packet. Packets are transmitted in the order they
-   * are passed to this method.
-   */
-  send(object) {
-    this.emit("send", object);
-
-    const packet = new JSONPacket(this);
-    packet.object = object;
-    this._outgoing.push(packet);
-    this._flushOutgoing();
-  },
-
-  /**
-   * Transmit streaming data via a bulk packet.
-   *
-   * This method initiates the bulk send process by queuing up the header
-   * data.  The caller receives eventual access to a stream for writing.
-   *
-   * N.B.: Do *not* attempt to close the stream handed to you, as it
-   * will continue to be used by this transport afterwards.  Most users
-   * should instead use the provided |copyFrom| function instead.
-   *
-   * @param {Object} header
-   *     This is modeled after the format of JSON packets above, but does
-   *     not actually contain the data, but is instead just a routing
-   *     header:
-   *
-   *       - actor:  Name of actor that will receive the packet
-   *       - type:   Name of actor's method that should be called on receipt
-   *       - length: Size of the data to be sent
-   *
-   * @return {Promise}
-   *     The promise will be resolved when you are allowed to write to
-   *     the stream with an object containing:
-   *
-   *       - stream:   This output stream should only be used directly
-   *                   if you can ensure that you will write exactly
-   *                   |length| bytes and will not close the stream when
-   *                    writing is complete.
-   *       - done:     If you use the stream directly (instead of
-   *                   |copyFrom| below), you must signal completion by
-   *                   resolving/rejecting this deferred.  If it's
-   *                   rejected, the transport will be closed.  If an
-   *                   Error is supplied as a rejection value, it will
-   *                   be logged via |dump|.  If you do use |copyFrom|,
-   *                   resolving is taken care of for you when copying
-   *                   completes.
-   *       - copyFrom: A helper function for getting your data onto the
-   *                   stream that meets the stream handling requirements
-   *                   above, and has the following signature:
-   *
-   *                   @param {nsIAsyncInputStream} input
-   *                       The stream to copy from.
-   *
-   *                   @return {Promise}
-   *                       The promise is resolved when copying completes
-   *                       or rejected if any (unexpected) errors occur.
-   *                       This object also emits "progress" events for
-   *                       each chunkthat is copied.  See stream-utils.js.
-   */
-  startBulkSend(header) {
-    this.emit("startbulksend", header);
-
-    const packet = new BulkPacket(this);
-    packet.header = header;
-    this._outgoing.push(packet);
-    this._flushOutgoing();
-    return packet.streamReadyForWriting;
-  },
-
-  /**
-   * Close the transport.
-   *
-   * @param {(nsresult|object)=} reason
-   *     The status code or error message that corresponds to the reason
-   *     for closing the transport (likely because a stream closed
-   *     or failed).
-   */
-  close(reason) {
-    this.emit("close", reason);
-
-    this.active = false;
-    this._input.close();
-    this._scriptableInput.close();
-    this._output.close();
-    this._destroyIncoming();
-    this._destroyAllOutgoing();
-    if (this.hooks) {
-      this.hooks.onClosed(reason);
-      this.hooks = null;
-    }
-    if (reason) {
-      dumpv("Transport closed: " + reason);
-    } else {
-      dumpv("Transport closed.");
-    }
-  },
-
-  /**
-   * The currently outgoing packet (at the top of the queue).
-   */
-  get _currentOutgoing() {
-    return this._outgoing[0];
-  },
-
-  /**
-   * Flush data to the outgoing stream.  Waits until the output
-   * stream notifies us that it is ready to be written to (via
-   * onOutputStreamReady).
-   */
-  _flushOutgoing() {
-    if (!this._outgoingEnabled || this._outgoing.length === 0) {
-      return;
-    }
-
-    // If the top of the packet queue has nothing more to send, remove it.
-    if (this._currentOutgoing.done) {
-      this._finishCurrentOutgoing();
-    }
-
-    if (this._outgoing.length > 0) {
-      const threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
-      this._output.asyncWait(this, 0, 0, threadManager.currentThread);
-    }
-  },
-
-  /**
-   * Pause this transport's attempts to write to the output stream.
-   * This is used when we've temporarily handed off our output stream for
-   * writing bulk data.
-   */
-  pauseOutgoing() {
-    this._outgoingEnabled = false;
-  },
-
-  /**
-   * Resume this transport's attempts to write to the output stream.
-   */
-  resumeOutgoing() {
-    this._outgoingEnabled = true;
-    this._flushOutgoing();
-  },
-
-  // nsIOutputStreamCallback
-  /**
-   * This is called when the output stream is ready for more data to
-   * be written.  The current outgoing packet will attempt to write some
-   * amount of data, but may not complete.
-   */
-  onOutputStreamReady(stream) {
-    if (!this._outgoingEnabled || this._outgoing.length === 0) {
-      return;
-    }
-
-    try {
-      this._currentOutgoing.write(stream);
-    } catch (e) {
-      if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) {
-        this.close(e.result);
-        return;
-      }
-      throw e;
-    }
-
-    this._flushOutgoing();
-  },
-
-  /**
-   * Remove the current outgoing packet from the queue upon completion.
-   */
-  _finishCurrentOutgoing() {
-    if (this._currentOutgoing) {
-      this._currentOutgoing.destroy();
-      this._outgoing.shift();
-    }
-  },
-
-  /**
-   * Clear the entire outgoing queue.
-   */
-  _destroyAllOutgoing() {
-    for (const packet of this._outgoing) {
-      packet.destroy();
-    }
-    this._outgoing = [];
-  },
-
-  /**
-   * Initialize the input stream for reading. Once this method has been
-   * called, we watch for packets on the input stream, and pass them to
-   * the appropriate handlers via this.hooks.
-   */
-  ready() {
-    this.active = true;
-    this._waitForIncoming();
-  },
-
-  /**
-   * Asks the input stream to notify us (via onInputStreamReady) when it is
-   * ready for reading.
-   */
-  _waitForIncoming() {
-    if (this._incomingEnabled) {
-      const threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
-      this._input.asyncWait(this, 0, 0, threadManager.currentThread);
-    }
-  },
-
-  /**
-   * Pause this transport's attempts to read from the input stream.
-   * This is used when we've temporarily handed off our input stream for
-   * reading bulk data.
-   */
-  pauseIncoming() {
-    this._incomingEnabled = false;
-  },
-
-  /**
-   * Resume this transport's attempts to read from the input stream.
-   */
-  resumeIncoming() {
-    this._incomingEnabled = true;
-    this._flushIncoming();
-    this._waitForIncoming();
-  },
-
-  // nsIInputStreamCallback
-  /**
-   * Called when the stream is either readable or closed.
-   */
-  onInputStreamReady(stream) {
-    try {
-      while (stream.available() && this._incomingEnabled &&
-             this._processIncoming(stream, stream.available())) {
-         // Loop until there is nothing more to process
-      }
-      this._waitForIncoming();
-    } catch (e) {
-      if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) {
-        this.close(e.result);
-      } else {
-        throw e;
-      }
-    }
-  },
-
-  /**
-   * Process the incoming data.  Will create a new currently incoming
-   * Packet if needed.  Tells the incoming Packet to read as much data
-   * as it can, but reading may not complete.  The Packet signals that
-   * its data is ready for delivery by calling one of this transport's
-   * _on*Ready methods (see ./packets.js and the _on*Ready methods below).
-   *
-   * @return {boolean}
-   *     Whether incoming stream processing should continue for any
-   *     remaining data.
-   */
-  _processIncoming(stream, count) {
-    dumpv("Data available: " + count);
-
-    if (!count) {
-      dumpv("Nothing to read, skipping");
-      return false;
-    }
-
-    try {
-      if (!this._incoming) {
-        dumpv("Creating a new packet from incoming");
-
-        if (!this._readHeader(stream)) {
-          // Not enough data to read packet type
-          return false;
-        }
-
-        // Attempt to create a new Packet by trying to parse each possible
-        // header pattern.
-        this._incoming = Packet.fromHeader(this._incomingHeader, this);
-        if (!this._incoming) {
-          throw new Error("No packet types for header: " +
-                        this._incomingHeader);
-        }
-      }
-
-      if (!this._incoming.done) {
-        // We have an incomplete packet, keep reading it.
-        dumpv("Existing packet incomplete, keep reading");
-        this._incoming.read(stream, this._scriptableInput);
-      }
-    } catch (e) {
-      dump(`Error reading incoming packet: (${e} - ${e.stack})\n`);
-
-      // Now in an invalid state, shut down the transport.
-      this.close();
-      return false;
-    }
-
-    if (!this._incoming.done) {
-      // Still not complete, we'll wait for more data.
-      dumpv("Packet not done, wait for more");
-      return true;
-    }
-
-    // Ready for next packet
-    this._flushIncoming();
-    return true;
-  },
-
-  /**
-   * Read as far as we can into the incoming data, attempting to build
-   * up a complete packet header (which terminates with ":").  We'll only
-   * read up to PACKET_HEADER_MAX characters.
-   *
-   * @return {boolean}
-   *     True if we now have a complete header.
-   */
-  _readHeader() {
-    const amountToRead = PACKET_HEADER_MAX - this._incomingHeader.length;
-    this._incomingHeader +=
-    Stream.delimitedRead(this._scriptableInput, ":", amountToRead);
-    if (flags.wantVerbose) {
-      dumpv("Header read: " + this._incomingHeader);
-    }
-
-    if (this._incomingHeader.endsWith(":")) {
-      if (flags.wantVerbose) {
-        dumpv("Found packet header successfully: " + this._incomingHeader);
-      }
-      return true;
-    }
-
-    if (this._incomingHeader.length >= PACKET_HEADER_MAX) {
-      throw new Error("Failed to parse packet header!");
-    }
-
-    // Not enough data yet.
-    return false;
-  },
-
-  /**
-   * If the incoming packet is done, log it as needed and clear the buffer.
-   */
-  _flushIncoming() {
-    if (!this._incoming.done) {
-      return;
-    }
-    if (flags.wantLogging) {
-      dumpv("Got: " + this._incoming);
-    }
-    this._destroyIncoming();
-  },
-
-  /**
-   * Handler triggered by an incoming JSONPacket completing it's |read|
-   * method.  Delivers the packet to this.hooks.onPacket.
-   */
-  _onJSONObjectReady(object) {
-    executeSoon(() => {
-    // Ensure the transport is still alive by the time this runs.
-      if (this.active) {
-        this.emit("packet", object);
-        this.hooks.onPacket(object);
-      }
-    });
-  },
-
-  /**
-   * Handler triggered by an incoming BulkPacket entering the |read|
-   * phase for the stream portion of the packet.  Delivers info about the
-   * incoming streaming data to this.hooks.onBulkPacket.  See the main
-   * comment on the transport at the top of this file for more details.
-   */
-  _onBulkReadReady(...args) {
-    executeSoon(() => {
-    // Ensure the transport is still alive by the time this runs.
-      if (this.active) {
-        this.emit("bulkpacket", ...args);
-        this.hooks.onBulkPacket(...args);
-      }
-    });
-  },
-
-  /**
-   * Remove all handlers and references related to the current incoming
-   * packet, either because it is now complete or because the transport
-   * is closing.
-   */
-  _destroyIncoming() {
-    if (this._incoming) {
-      this._incoming.destroy();
-    }
-    this._incomingHeader = "";
-    this._incoming = null;
-  },
-};
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1147,9 +1147,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 = 485;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1563452699718000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1563798212237000);
--- 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(1565871896419000);
+const PRTime gPreloadListExpirationTime = INT64_C(1566217406629000);
 %%
 0-1.party, 1
 000books.net, 1
 00100010.net, 1
 0010100.net, 1
 00120012.net, 1
 00130013.net, 1
 00140014.net, 1
@@ -183,17 +183,16 @@ 087010.com, 1
 087059.com, 1
 087065.com, 1
 087540.com, 1
 087569.com, 1
 087580.com, 1
 08845.cc, 1
 089818.com, 1
 08detaxe.fr, 1
-09115.com, 1
 095598.cc, 1
 09892.net, 1
 098955.com, 1
 0akarma.me, 1
 0au.de, 1
 0c3.de, 1
 0cdn.ga, 1
 0day.agency, 1
@@ -260,18 +259,16 @@ 100k.eu, 1
 100kredite.de, 1
 100lat.pl, 1
 100mani.it, 1
 100onrainkajino.com, 1
 100pounds.co.uk, 1
 101.qa, 1
 101010.pl, 1
 1011100.com, 1
-101sauna.kz, 1
-101sauna.ru, 1
 1041263497.rsc.cdn77.org, 1
 10414.org, 1
 10430.net, 1
 10435.net, 1
 10436.net, 1
 10438.net, 1
 10439.net, 1
 10453.net, 1
@@ -313,16 +310,17 @@ 1236.be, 1
 123apps.net, 1
 123bearing.co.uk, 1
 123bearing.com, 1
 123bearing.eu, 1
 123comparer.fr, 1
 123djdrop.com, 1
 123midterm.com, 1
 123nutricion.es, 1
+123opstalverzekeringen.nl, 1
 123plons.nl, 1
 123roulement.be, 1
 123roulement.com, 1
 123termpapers.com, 1
 123writings.com, 1
 124133.com, 1
 124633.com, 1
 125m125.de, 1
@@ -429,17 +427,16 @@ 177603.com, 1
 17kpw.cc, 1
 17xile.com, 1
 1811559.com, 1
 182162.com, 1
 1844329061.rsc.cdn77.org, 1
 186kb.com, 1
 1876996.com, 1
 188198.net, 1
-18888msc.com, 1
 1888zr.com, 1
 188da.com, 1
 188dv.com, 1
 1895media.com, 1
 189dv.com, 1
 189fc.com, 1
 18f.gov, 1
 18f.gsa.gov, 0
@@ -600,16 +597,17 @@ 263.info, 1
 267221.com, 1
 267661.com, 1
 2718282.net, 1
 276771.com, 1
 27728522.com, 1
 28-industries.com, 1
 281180.de, 1
 2858958.com, 1
+286.com, 1
 288game.net, 1
 28peaks.com, 1
 28spots.net, 1
 291167.xyz, 1
 2912.nl, 1
 29227.com, 1
 2948.ca, 1
 297computers.com, 1
@@ -1352,24 +1350,26 @@ 8212p.com, 1
 8213p.com, 1
 8214p.com, 1
 8215p.com, 1
 8216p.com, 1
 833792.com, 1
 8349822.com, 1
 848jz.com, 1
 850226.com, 1
+8522.am, 1
 8522club.com, 1
 8522hk.com, 1
 8522ph.com, 1
 8522top.com, 1
 8522tw.com, 1
 8522usa.com, 1
 85383838.com, 1
 8560.be, 1
+86286286.com, 1
 86499.com, 1
 8649955.com, 1
 8649966.com, 1
 8649977.com, 1
 8688fc.com, 1
 86metro.ru, 1
 8722.am, 1
 8722am.com, 1
@@ -1870,16 +1870,17 @@ acefreightco.com, 1
 aceinflatables.com, 1
 aceinstituteonline.com, 1
 acelpb.com, 1
 acem.org.au, 1
 acemobileforce.com, 1
 acemypaper.com, 1
 acen.eu, 1
 acerentalandsales.com, 1
+acerislaw.com, 1
 acessoeducacao.com, 1
 acfun.eu.org, 1
 acg.mn, 1
 acg.social, 1
 acgaudio.com, 1
 acgmoon.com, 1
 acgmoon.org, 1
 acgpiano.club, 1
@@ -2222,16 +2223,17 @@ adventurousway.com, 1
 advertis.biz, 1
 advertisemant.com, 1
 adviserplus.com, 1
 advocate-europe.eu, 1
 advocatenalkmaar.org, 1
 advocator.ca, 1
 advocoeurdehaan.nl, 1
 advogatech.com.br, 1
+advokat-romanov.com, 1
 advtran.com, 1
 adware.pl, 0
 adwokatkosterka.pl, 1
 adwokatzdunek.pl, 1
 adws.io, 1
 adxperience.com, 1
 adzie.xyz, 1
 adzuna.at, 1
@@ -2414,34 +2416,32 @@ agiserv.fr, 1
 agks5.com, 1
 agliamici.it, 1
 agnesk.blog, 1
 agoodmind.com, 1
 agoravm.tk, 1
 agoravox.fr, 1
 agoravox.it, 1
 agoravox.tv, 1
-agostinhoenascimento.com.br, 1
 agotnes.com, 1
 agouraelectrical.com, 1
 agouraelectrician.com, 1
 agouraexteriorlighting.com, 1
 agourahillselectric.com, 1
 agourahillselectrical.com, 1
 agourahillselectrician.com, 1
 agourahillsexteriorlighting.com, 1
 agourahillslandscapelighting.com, 1
 agourahillslighting.com, 1
 agourahillsoutdoorlighting.com, 1
 agouralandscapelighting.com, 1
 agouralighting.com, 1
 agouraoutdoorlighting.com, 1
 agowa338.de, 1
 agr.asia, 1
-agracan.com, 1
 agrajag.nl, 1
 agrarking.com, 1
 agrarking.de, 1
 agrarshop4u.de, 1
 agrekov.ru, 1
 agreor.com, 1
 agrichamber.com.ua, 1
 agricolo.ch, 1
@@ -2648,17 +2648,16 @@ airlibre-parachutisme.com, 1
 airlinesettlement.com, 1
 airmail.cc, 1
 airmaxinflatables.com, 1
 airnow.gov, 1
 airpbx.com, 1
 airplay-inflatable-hire.co.uk, 1
 airplayradio.nl, 1
 airport-charlotte.com, 1
-airportal.cn, 0
 airportlimototoronto.com, 1
 airpurifierproductsonline.com, 1
 airrestoration.ch, 1
 airsnore.com, 1
 airsoft.ch, 1
 airswap.io, 1
 airtec-france.fr, 1
 airtimerewards.co.uk, 1
@@ -2749,17 +2748,16 @@ akropolis-ravensburg.de, 1
 aksehir.bel.tr, 1
 akselinurmio.fi, 1
 akshay.in.eu.org, 1
 akshi.in, 1
 aktan.com.br, 1
 aktin.cz, 1
 aktin.sk, 1
 aktion-vielfalt.ch, 1
-aktiv-naturheilmittel.at, 1
 aktiv-naturheilmittel.ch, 1
 aktiv-naturheilmittel.de, 1
 aktivace.eu, 1
 aktivierungscenter.de, 1
 aktuelle-uhrzeit.at, 1
 akuislam.com, 1
 akukas.com, 1
 akul.co.in, 1
@@ -3038,17 +3036,16 @@ allladyboys.com, 1
 allmend-ru.de, 1
 allmousepads.com, 1
 allns.fr, 1
 allo-credit.ch, 1
 allofthestops.com, 1
 allontanamentovolatili.it, 1
 allontanamentovolatili.milano.it, 1
 alloutatl.com, 1
-alloutofgum.com, 1
 alloutsec.com, 1
 alloverthehill.com, 1
 allplayer.tk, 1
 allpointsblog.com, 1
 allpointsheating.com, 1
 allproptonline.com, 1
 allrad-buck.de, 1
 allram.one, 1
@@ -3114,17 +3111,16 @@ alpertron.com.ar, 1
 alpes-deis-tools.com, 1
 alpha-assistant.com, 1
 alpha-force.net, 0
 alpha.ch, 1
 alpha88uat.com, 1
 alphaantileak.net, 1
 alphabetsigns.com, 1
 alphabouncycastles.co.uk, 1
-alphabrock.cn, 1
 alphachat.net, 1
 alphadote.com, 1
 alphaetomega3d.fr, 1
 alphafiduciaryservices.ch, 1
 alphafitnesslibya.com, 1
 alphagateanddoor.com, 1
 alphahunks.com, 1
 alphainflatablehire.com, 1
@@ -3487,17 +3483,16 @@ andrehansen.de, 1
 andrei-nakov.org, 1
 andrejbenz.com, 1
 andrelauzier.com, 1
 andreoliveira.io, 1
 andrepicard.de, 1
 andrespaz.com, 1
 andreundnina.de, 1
 andrew.fi, 1
-andrew.london, 1
 andrewbdesign.com, 1
 andrewbennett.ltd, 1
 andrewdaws.co, 1
 andrewdaws.info, 1
 andrewdaws.io, 1
 andrewdaws.me, 1
 andrewdaws.tv, 1
 andrewensley.com, 1
@@ -3580,17 +3575,17 @@ anglersconservation.net, 1
 anglertanke.de, 1
 anglesgirl.eu.org, 1
 anglesya.win, 1
 anglictina-sojcak.cz, 1
 anglictinasojcak.cz, 1
 anglingactive.co.uk, 1
 anglirl.eu.org, 1
 angrapa.ru, 1
-angrido.com, 0
+angrido.com, 1
 angristan.fr, 1
 angristan.xyz, 1
 angrut.com, 1
 angry-monk.com, 1
 angry.im, 1
 angrydragonproductions.com, 1
 angrysnarl.com, 1
 angryteeth.net, 1
@@ -3622,16 +3617,17 @@ anime1.pw, 1
 anime1.top, 1
 animeai.com, 1
 animefluxxx.com, 1
 animeinsights.net, 1
 animeone.me, 1
 animesharp.com, 1
 animetriad.com, 1
 animojis.es, 1
+animorphsfanforum.com, 1
 anipassion.com, 0
 anitaalbersen.nl, 1
 anitaxcph.dk, 1
 anitube-nocookie.ch, 1
 anitube.ch, 1
 aniwhen.com, 1
 anjocerdena.com, 1
 anjoola.com, 1
@@ -4200,17 +4196,16 @@ arnoldkontz-occasions.lu, 1
 arnonerba.com, 1
 arnor.org, 1
 arnoudraeven.nl, 1
 arnoudvandalen.nl, 1
 arnove.net, 1
 arnsmedia.nl, 1
 arocloud.de, 1
 arogov.com, 1
-arogyadhamhealth.com, 1
 arokha.com, 1
 aromacos.ch, 1
 aromatlas.com, 1
 aron.host, 1
 aroonchande.com, 1
 aros.pl, 1
 arose.io, 1
 around-cms.de, 1
@@ -4281,16 +4276,17 @@ arthurlaw.ca, 1
 arthurmelo.com, 0
 arthuryidi.com, 1
 articaexports.com, 1
 articu.no, 1
 artificial.army, 1
 artificialgrassandlandscaping.com, 1
 artik.cloud, 1
 artimpact.ch, 1
+artioml.net, 1
 artionet.ch, 1
 artis-game.net, 1
 artisan-cheminees-poeles-design.fr, 1
 artisanhd.com, 1
 artisans-libres.com, 1
 artisansoftaste.com, 1
 artisavotins.com, 1
 artisense.de, 1
@@ -4317,16 +4313,17 @@ artofwhere.com, 1
 artozoul.fr, 1
 artratio.net, 1
 artroot.jp, 1
 artroscopiaperlosport.it, 1
 arts.gov, 1
 artschmidtoptical.com, 1
 artspac.es, 1
 arturkohut.com, 1
+arturopinto.com.mx, 1
 arturrossa.de, 1
 arturszalak.com, 1
 artweby.cz, 1
 artworxbathrooms.com.au, 1
 arty.name, 1
 arubasunsetbeach.com, 1
 arunjoshua.com, 1
 arveron.ch, 1
@@ -4706,16 +4703,17 @@ augix.net, 1
 augmentable.de, 0
 august-don.site, 1
 augustian-life.cz, 1
 augustiner-kantorei-erfurt.de, 1
 augustiner-kantorei.de, 1
 aukaraoke.su, 1
 aulaschrank.gq, 1
 aulasvirtualesperu.com, 1
+aulica-conseil.com, 1
 aulo.in, 0
 aumilieudumonde.gf, 1
 aunali1.com, 1
 auntie-eileens.com.au, 1
 auntmia.com, 1
 aupasdecourses.com, 1
 auplidespages.fr, 1
 aurelieburn.fr, 1
@@ -4731,17 +4729,16 @@ aurorarecordings.com, 1
 auroware.com, 1
 auroz.tech, 1
 auroz.video, 1
 aus-ryugaku.info, 1
 ausec.ch, 1
 ausmwoid.de, 1
 auspicacious.org, 1
 ausrecord.com, 1
-ausschreibungen-suedtirol.it, 1
 aussiefunadvisor.com, 1
 aussieservicedown.com, 1
 aussiestoresonline.com, 1
 austenplumbing.com, 1
 austin-pearce.com, 1
 austin-security-cameras.com, 1
 austincardiac.com, 1
 austinheap.com, 0
@@ -4787,17 +4784,16 @@ autoauctionsohio.com, 1
 autoauctionsvirginia.com, 1
 autobahnco.com, 1
 autobarn.co.nz, 1
 autobedrijfgarant.nl, 1
 autobella-hurtownia.pl, 1
 autobelle.it, 1
 autobourcier.com, 1
 autoclean-plus.ch, 1
-autocmall.com, 1
 autocontrol.online, 1
 autocorner.com, 1
 autocrypt.org, 1
 autod.hu, 1
 autodalmacija.com, 1
 autodidactic.ai, 1
 autodidacticstudios.com, 1
 autodidacticstudios.net, 1
@@ -5274,16 +5270,17 @@ badbee.cc, 1
 badblock.fr, 1
 badboyzclub.de, 1
 badf00d.de, 1
 badgersystems.de, 1
 badges.fedoraproject.org, 1
 badges.stg.fedoraproject.org, 1
 badgesenpatches.nl, 1
 badgirlsbible.com, 1
+badgr.io, 1
 badhusky.com, 0
 badkamermarkt.nl, 1
 badmania.fr, 1
 badmintonbible.com, 1
 badoo.com, 1
 badoo.de, 1
 badoo.eu, 1
 badoo.us, 1
@@ -5636,16 +5633,17 @@ bayportuganda.com, 1
 bayportzambia.com, 1
 baytalebaa.com, 1
 baywatch.io, 1
 bayz.de, 1
 baza-gai.com.ua, 1
 bazaarbhaav.com, 1
 bazaarcompass.com, 1
 bazdell.com, 1
+bazinga-events.nl, 1
 bazos.at, 1
 bazos.cz, 1
 bazos.pl, 1
 bazos.sk, 1
 bazziergraphik.com, 1
 bb37roma.it, 1
 bbalposticino.it, 1
 bbb1991.me, 0
@@ -5840,16 +5838,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
 befreewifi.info, 1
 befundonline.de, 1
 begabungsfoerderung.info, 1
 begbie.com, 1
 beginner.nl, 1
 beginwp.top, 1
@@ -6022,16 +6021,17 @@ bereginy.com.ua, 1
 bergenhave.nl, 1
 berger-chiro.com, 1
 bergevoet-fa.nl, 1
 berglust-pur.de, 1
 bergmanbeachproperties.com, 1
 bergstoneware.com, 1
 berichtsheft-vorlage.de, 1
 berikod.ru, 1
+beringsoegaard.dk, 1
 berlin.dating, 1
 bermeitinger.eu, 1
 bermos.net, 1
 bermytraq.bm, 1
 berna.fr, 1
 bernadetteanderes.ch, 1
 bernar.do, 1
 bernardcontainers.be, 1
@@ -6049,17 +6049,16 @@ bernhard-seidenspinner.de, 1
 bernhardkau.de, 1
 bernhardluginbuehl.ch, 1
 bernhardluginbuehl.com, 1
 bernieware.de, 1
 bernyweb.net, 1
 berodes.be, 1
 berr.yt, 1
 berra.se, 1
-berruezoabogados.com, 1
 berrus.com, 1
 berry.cat, 1
 berrypay.com, 1
 bersierservices.ch, 1
 bersotavocats.fr, 1
 berst.cz, 1
 berthabailey.com, 1
 berthelier.me, 1
@@ -6168,17 +6167,16 @@ bet-99.net, 1
 bet.eu, 1
 bet168wy.com, 1
 bet168wy.net, 1
 bet909.com, 1
 bet990.com, 1
 bet9bet9.net, 1
 betaal.my, 1
 betacavi.com, 1
-betacloud.io, 1
 betaclouds.net, 1
 betaprofiles.com, 1
 betaworx.de, 1
 betaworx.eu, 1
 betecnet.de, 1
 betformular.com, 1
 betgo9.cc, 1
 bethanyduke.com, 1
@@ -6317,18 +6315,16 @@ bi1gif.radio, 1
 bia.gov, 0
 biaggeo.com, 1
 bianinapiccanovias.com, 1
 biano-ai.com, 1
 biasmath.es, 1
 biathloncup.ru, 1
 bibica.net, 1
 bible-maroc.com, 1
-bibles.com.tw, 1
-biblethoughts.blog, 1
 bibliaon.com, 1
 biblio.wiki, 1
 biblioblog.fr, 1
 bibliomarkt.ch, 1
 biblionaut.net, 1
 biblioporn.com, 1
 bibliotekarien.se, 1
 biboumail.fr, 1
@@ -6385,17 +6381,16 @@ bigcakes.dk, 1
 bigclassaction.com, 1
 bigdinosaur.org, 1
 bigerbio.com, 1
 biggreenexchange.com, 1
 bighouse-events.co.uk, 1
 bight.ca, 1
 bigideasnetwork.com, 1
 biglou.com, 0
-bignumworks.com, 1
 bigorbitgallery.org, 1
 bigpicture-learning.com, 1
 bigserp.com, 1
 bigshopper.com, 1
 bigshopper.nl, 1
 bigshort.org, 1
 bigsisterchannel.com, 1
 bigskylifestylerealestate.com, 1
@@ -6539,22 +6534,22 @@ bioharmony.ca, 1
 biointelligence-explosion.com, 1
 bioknowme.com, 1
 bioleev.sklep.pl, 1
 bioligo.ch, 1
 biolindo.com, 0
 biologis.ch, 1
 biology-colleges.com, 1
 biomag.it, 1
-biomasscore.com, 0
+biomasscore.com, 1
 biomathalliance.org, 1
 biomed-hospital.ch, 1
 biomed.ch, 1
 biometrics.es, 1
-biomin.co.uk, 1
+biomin.co.uk, 0
 biomodra.cz, 1
 bionima.com, 1
 biopreferred.gov, 1
 biopronut.com, 1
 biopsychiatry.com, 1
 bioresonanz-ibiza.com, 1
 biosafe.ch, 1
 biosalts.it, 1
@@ -6661,17 +6656,16 @@ bitenose.org, 1
 bitex.la, 1
 bitfasching.de, 0
 bitfehler.net, 1
 bitfence.io, 1
 bitfinder.nl, 1
 bitfuse.net, 1
 bitgo.com, 1
 bitgrapes.com, 1
-bithap.com, 1
 bithir.co.uk, 1
 bititrain.com, 1
 bitlish.com, 1
 bitlo.com, 1
 bitlo.com.tr, 1
 bitlo.io, 1
 bitlo.org, 1
 bitmain.com.ua, 1
@@ -6872,29 +6866,31 @@ blayneallan.com, 1
 blazeit.io, 1
 blazing.cz, 1
 blazor.nl, 1
 blblblblbl.fr, 1
 bleaching-tipps.de, 1
 blechbuexn.de, 1
 bleche-onlineshop.at, 1
 bleche-onlineshop.de, 1
+blechinger.io, 1
 blechschmidt.saarland, 1
 bleep.zone, 1
 blenderinsider.com, 1
 blenderrecipereviews.com, 1
 blending.kr, 1
 blendle.com, 1
 blendle.nl, 1
 blendr.com, 1
 blendstudios.com, 1
 blenneros.net, 0
 blessedguy.com, 1
 blewebprojects.com, 1
 blichmann.eu, 1
+blicy.net, 1
 blidz.com, 1
 blieque.co.uk, 1
 bliesekow.net, 1
 bliker.ga, 1
 blikk.no, 1
 blikund.swedbank.se, 1
 blindaryproduction.tk, 1
 blinder.com.co, 1
@@ -6979,16 +6975,17 @@ bloglyric.com, 1
 blognr.com, 1
 blogom.at, 1
 blogpentrusuflet.ro, 1
 blogpronto.com.br, 1
 blogreen.org, 1
 blogsdna.com, 1
 blogthedayaway.com, 1
 blogtroterzy.pl, 1
+blok56.nl, 1
 blokmy.com, 1
 blood4pets.tk, 1
 bloodhunt.pl, 1
 bloodsports.org, 1
 bloody.pw, 1
 bloom-avenue.com, 1
 bloom.sh, 0
 blopezabogado.es, 1
@@ -7276,17 +7273,16 @@ boop.gq, 1
 boop.pro, 1
 booplab.com, 1
 booquiz.com, 1
 boosinflatablegames.co.uk, 1
 boosmanpoolservice.com, 1
 boost.fyi, 1
 boost.ink, 1
 boostgame.win, 1
-booter.es, 1
 boothlabs.me, 1
 bootjp.me, 0
 bootsschule-weiss.de, 1
 boozinyan.com, 1
 bopera.co.uk, 1
 bopiweb.com, 1
 bopp.org, 1
 borahan.net, 1
@@ -7810,17 +7806,16 @@ brudkista.nu, 1
 brudkista.se, 1
 brudkistan.nu, 1
 brudkistan.se, 1
 brueser-gmbh.de, 1
 bruna-cdn.nl, 1
 brunick.de, 0
 brunn.email, 1
 brunner.ninja, 1
-brunohenc.from.hr, 1
 brunoproduit.ch, 1
 brunoramos.com, 1
 brunoramos.org, 1
 brunosouza.org, 1
 brush.ninja, 1
 brushcreekyachts.com, 1
 brutus2.ga, 0
 bruun.co, 1
@@ -8244,17 +8239,17 @@ bythisverse.com, 1
 bytrain.net, 1
 byvshie.com, 1
 bywin9.com, 1
 bzh.tf, 1
 bzhub.bid, 1
 bziaks.xyz, 1
 bzsparks.com, 0
 bztech.com.br, 1
-bztraveler.com, 0
+bztraveler.com, 1
 bztraveler.net, 0
 bzv-fr.eu, 1
 c-aeroconsult.com, 1
 c-ma-copro.com, 1
 c-path.org, 1
 c-rom.fr, 1
 c-rtx.com, 1
 c-shock.org, 1
@@ -8782,17 +8777,16 @@ carriedin.com, 1
 carrierplatform.com, 1
 carringtonrealtygroup.com, 1
 carroattrezzimilanodaluiso.it, 1
 carroceriascarluis.com, 1
 carrouselcompany.fr, 1
 cars4salecy.com, 1
 carseatchecks.ca, 1
 carshippingcarriers.com, 1
-carson-aviation-adventures.com, 1
 carson-matthews.co.uk, 1
 carsoug.com, 1
 carspneu.cz, 1
 cartelloni.roma.it, 1
 carterdan.net, 1
 carterorland.com, 1
 carterstad.se, 1
 cartertonscouts.org.nz, 1
@@ -8857,16 +8851,17 @@ cashfazz.com, 1
 cashfortulsahouses.com, 1
 cashlogic.ch, 1
 cashmaxtexas.com, 1
 cashplk.com, 1
 cashsector.ga, 1
 casian.ir, 1
 casino-cash-flow.su, 1
 casino-cashflow.ru, 1
+casino-online.info, 1
 casino-trio.com, 1
 casinobonuscodes.online, 1
 casinocashflow.ru, 1
 casinolegal.pt, 1
 casinolistings.com, 1
 casinoluck.com, 1
 casinomucho.com, 1
 casinomucho.org, 1
@@ -8934,17 +8929,16 @@ catering-xanadu.cz, 1
 catfooddispensersreviews.com, 1
 catgirl.pics, 1
 catgirl.science, 1
 catharinesomerville.com, 1
 catharisme.eu, 1
 catharisme.net, 1
 catharisme.org, 1
 catherinejf.com, 1
-catherinesofpartick.co.uk, 1
 catholics.dating, 1
 catholicteacherresources.com, 1
 cathosa.nl, 1
 cathosting.org, 1
 cathy.guru, 1
 cathy.website, 1
 cathyfitzpatrick.com, 1
 cathyjf.ca, 1
@@ -8958,17 +8952,17 @@ catmoose.ca, 1
 catnet.dk, 0
 catnmeow.com, 1
 catram.org, 1
 catsmagic.pp.ua, 1
 cattivo.nl, 0
 catuniverse.org, 1
 catveteran.com, 1
 caudo.net, 1
-caudohay.com, 0
+caudohay.com, 1
 caughtredhanded.co.nz, 1
 caulfieldeastapartments.com.au, 1
 caulfieldracecourseapartments.com.au, 1
 caulong-ao.net, 1
 cav.ac, 1
 cavac.at, 1
 cavalierkingcharlesspaniel.com.br, 1
 cave-reynard.ch, 1
@@ -9261,17 +9255,17 @@ chaleur.com, 1
 chalker.io, 1
 chalkfestival.org, 0
 challengeblog.org, 1
 challengeskins.com, 1
 challstrom.com, 1
 chamathellawala.com, 1
 chambion.ch, 1
 chameleon-ents.co.uk, 1
-chameth.com, 1
+chameth.com, 0
 chamicro.com, 1
 champdogs.co.uk, 1
 champdogs.com, 1
 champicreuse.fr, 1
 championcastles.ie, 1
 championnat-romand-cuisiniers-amateurs.ch, 1
 champions.co, 1
 championsofpowerfulliving.com, 1
@@ -9630,16 +9624,17 @@ chollima.pro, 1
 chomp.life, 1
 chon.io, 1
 chonghe.org, 1
 chook.as, 1
 choootto.net, 1
 choosemypc.net, 1
 chopperdesign.com, 1
 chopperforums.com, 1
+chordify.net, 1
 chorkley.co.uk, 1
 chorkley.com, 1
 chorkley.me, 1
 chorkley.uk, 1
 chorpinkpoemps.de, 1
 chosenplaintext.org, 1
 chourishi-shigoto.com, 1
 chovancova.sk, 1
@@ -9815,17 +9810,16 @@ cilloc.be, 1
 cima-idf.fr, 1
 cimbalino.org, 1
 cimballa.com, 1
 cimfax.com, 1
 cinafilm.com, 1
 cinay.pw, 1
 cindey.io, 1
 cine-music.de, 1
-cine.to, 1
 cinefilia.tk, 1
 cinefilzonen.se, 1
 cinefun.net, 1
 cinemaclub.co, 1
 cinemarxism.com, 1
 cinemasetfree.com, 1
 cinemysticism.com, 1
 cineplex.my, 1
@@ -9866,17 +9860,17 @@ circu.ml, 1
 circuitcityelectricaladelaide.com.au, 1
 circulatedigital.com, 1
 circule.cc, 1
 cirfi.com, 1
 ciri.com.co, 1
 cirrus0.de, 1
 cirujanooral.com, 1
 cisa.gov, 1
-ciscodude.net, 0
+ciscodude.net, 1
 cisoaid.com, 1
 cisofy.com, 1
 cispeo.org, 1
 ciss.ltd, 1
 cistitguru.ru, 1
 cisum-cycling.com, 1
 cisy.me, 1
 citadelnet.works, 1
@@ -9984,17 +9978,16 @@ classical-guitar-school.com, 1
 classicalpilates.ca, 1
 classics.io, 1
 classictheatrecumbria.co.uk, 1
 classpoint.cz, 1
 classroom.google.com, 1
 classroomconductor.com, 1
 classroomcountdown.co.nz, 1
 classteaching.com.au, 1
-classyvaper.de, 0
 claude.tech, 1
 claudia-urio.com, 1
 claudiney.info, 1
 claudiolemos.com, 1
 claus-bahr.de, 1
 clauseriksen.net, 1
 clav1d.com, 1
 clawe.de, 1
@@ -10346,17 +10339,16 @@ codefordus.nrw, 1
 codefoundry.it, 0
 codehz.one, 1
 codein.ca, 1
 codeine.co.uk, 1
 codeit.guru, 1
 codeit.us, 1
 codejots.com, 1
 codejunkie.de, 0
-codeknights.com, 1
 codeloop.pw, 1
 codemahrt.com, 1
 codemill.se, 1
 codemonster.eu, 1
 codemperium.com, 1
 codenlife.xyz, 1
 codenode.io, 1
 codeofhonor.tech, 1
@@ -10381,34 +10373,33 @@ codesplain.in, 1
 codesport.io, 1
 codespromo.be, 1
 codestep.io, 1
 codestudies.net, 1
 codesyncro.com, 1
 codetheworld.com, 1
 codetipi.com, 1
 codetripping.net, 1
-codeux.com, 0
-codeux.info, 0
-codeux.net, 0
+codeux.com, 1
+codeux.info, 1
+codeux.net, 1
 codevat.com, 1
 codeventure.de, 1
 codeversetech.com, 1
 codewild.de, 1
 codewiz.xyz, 1
 codexpo.net, 1
 codeyellow.nl, 1
 codific.com, 1
 codific.eu, 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
 codxg.org, 1
 codyevanscomputer.com, 1
 codymoniz.com, 1
 codyqx4.com, 1
@@ -10834,26 +10825,25 @@ consideredgifts.com, 1
 consideryourways.net, 1
 consilium-vitae.ch, 1
 consiliumvitae.ch, 1
 consill.com, 1
 console.ninja, 1
 console.rest, 1
 consommateuraverti.com, 1
 consonare.de, 1
-conspiracyservers.com, 1
 constant-rough.de, 1
 constares.de, 1
 constituenttracker.com, 1
 constitution.website, 1
 constructexpres.ro, 1
 constructieve.nl, 1
 construction-colleges.com, 1
 construction-student.co.uk, 1
-constructionjobs.com, 1
+constructionjobs.com, 0
 constructive.men, 1
 consul.io, 1
 consulenza.pro, 1
 consultation.biz.tr, 1
 consultcelerity.com, 1
 consultimator.com, 1
 consultimedia.de, 1
 consulting-cloud.com, 1
@@ -11032,17 +11022,16 @@ corpusslayer.com, 1
 corrbee.com, 1
 correct.cf, 1
 correcthorse.cf, 1
 correctiv.org, 1
 correctpaardbatterijnietje.nl, 1
 corrick.io, 1
 corrupted.io, 1
 corsa-b.uk, 1
-corscanplus.com, 1
 corsectra.com, 1
 corsihaccpsicurezzalavoro.it, 1
 corso-antincendio.org, 1
 cortexitrecruitment.com, 1
 cortexx.nl, 1
 cortis-consulting.ch, 1
 cortisolsupplement.com, 1
 corvax.kiev.ua, 1
@@ -11065,17 +11054,16 @@ cosmicworlds.com, 1
 cosmicworlds.mobi, 1
 cosmintataru.ro, 1
 cosmodacollection.com, 1
 cosmofunnel.com, 1
 cosmundi.de, 1
 cosni.co, 1
 cosplayer.com, 1
 cospol.ch, 1
-costa-rica-reisen.de, 1
 costablanca.villas, 1
 costablancavoorjou.com, 1
 costcoinsider.com, 1
 costellofc.co.uk, 1
 costinstefan.eu, 1
 costreportdata.com, 0
 costruzioni.milano.it, 1
 costulessdirect.com, 1
@@ -11203,16 +11191,17 @@ craftist.de, 1
 craftngo.hu, 1
 craftsmandruggets.com, 1
 craftsmany.net, 1
 craftwmcp.xyz, 1
 craftydev.design, 1
 craftyguy.net, 1
 craftyphotons.net, 1
 crag.com.tw, 1
+craigary.net, 1
 craigbates.co.uk, 1
 craigfrancis.co.uk, 1
 craigleclaireteam.com, 1
 craigrouse.com, 1
 craigwfox.com, 1
 crain.com.au, 1
 cralarm.de, 1
 cramersoft.com, 1
@@ -11296,16 +11285,17 @@ creators-design.com, 1
 creators.co, 1
 creators.direct, 1
 creatujoya.com, 1
 crecips.com, 1
 crecman.fr, 1
 credential.eu, 1
 credex.bg, 1
 credigo.se, 1
+creditkarma.com, 1
 creditos-rapidos.com, 1
 creditozen.es, 1
 creditozen.mx, 1
 creditproautos.com, 0
 creditscoretalk.com, 1
 creditta.com, 1
 credittoken.io, 1
 creeks-coworking.com, 1
@@ -11332,16 +11322,17 @@ cribcore.com, 1
 crickey.eu, 1
 cricklewood.condos, 1
 criena.com, 1
 criena.net, 1
 crimbotrees.co.uk, 1
 crimefreeliving.com, 1
 crimesolutions.gov, 1
 crimevictims.gov, 1
+criminal-attorney.ru, 1
 criminal.enterprises, 1
 crinesdanzantes.be, 1
 crip-usk.ba, 1
 criptolog.com, 1
 criscitos.it, 1
 crisisactual.com, 1
 crisisnextdoor.gov, 1
 crismatthews.com, 1
@@ -11804,17 +11795,16 @@ cyberstatus.de, 1
 cybertorsk.org, 1
 cybertu.be, 1
 cyberwars.dk, 1
 cyberwire.nl, 1
 cyberxpert.nl, 1
 cybit.io, 1
 cybozu.cn, 1
 cybozu.com, 1
-cybozulive-dev.com, 1
 cybozulive.com, 1
 cyclebeads.com, 1
 cycledownunder.com, 1
 cyclehackluxembourgcity.lu, 1
 cycleluxembourg.lu, 1
 cyclinggoodso.com, 1
 cyclisjumper.gallery, 1
 cyclop-editorial.fr, 1
@@ -12129,17 +12119,16 @@ dantransports.fr, 1
 danw.io, 1
 danwin1210.me, 1
 danwolff.se, 1
 danyabanya.com, 1
 danzac.com, 1
 dao.spb.su, 1
 daop.co.uk, 1
 daoro.net, 1
-dapianw.com, 1
 dapim.co.il, 1
 daplie.com, 1
 dapps.earth, 1
 dappworld.com, 1
 dara-berlin.de, 1
 daracokorilo.com, 1
 daravk.ch, 1
 darbi.org, 1
@@ -12308,17 +12297,16 @@ davecardwell.com, 1
 daveedave.de, 1
 davelynes.com, 1
 daveoc64.co.uk, 1
 daveops.net, 1
 davepage.me.uk, 1
 davepearce.com, 1
 daverandom.com, 1
 davescomputertips.com, 1
-davesharpe.com, 1
 davesinclair.com.au, 1
 davetempleton.com, 1
 davethom.net, 1
 davevelopment.net, 1
 davewardle.com, 1
 davewood.com.au, 1
 david-corry.com, 1
 david-hinschberger.me, 1
@@ -12564,17 +12552,16 @@ decodeanddestroy.com, 1
 decompiled.de, 1
 deconsolas.tk, 1
 decoora.com, 1
 decor-d.com, 1
 decor-live.ru, 1
 decoratingadvice.co.uk, 1
 decoratore.roma.it, 1
 decoratrix.com, 1
-decorauvent.ca, 1
 decorincasa.com.br, 1
 decormiernissanparts.com, 1
 decorumcomics.com, 1
 decosoftware.com, 1
 decrousaz-ceramique.ch, 1
 decrypto.net, 1
 decs.es, 1
 dede.ml, 1
@@ -12703,17 +12690,16 @@ delta-data.ch, 1
 delta-smart.ch, 1
 delta.ru, 1
 delta23.de, 0
 deltaacademy.org, 1
 deltadata.ch, 1
 deltafinanceiro.com.br, 1
 deltanio.nl, 1
 deltaonlineguards.com, 1
-deltaservers.blog.br, 1
 deltaservers.com.br, 1
 deltasigmachi.org, 1
 deltava.org, 1
 deltawolf.tk, 1
 demarle.ch, 1
 dementiapraecox.de, 1
 demeyere-usedcars.be, 1
 demfloro.ru, 1
@@ -12889,17 +12875,16 @@ despachomartinyasociados.com, 1
 despertadoronline.com.es, 1
 desplats.com.ar, 1
 despora.de, 0
 despotika.de, 1
 dessinemoilademocratie.ch, 1
 destech.nl, 1
 desterman.ru, 1
 destileria.net.br, 1
-destinationsofnewyorkstate.com, 1
 destinattorneyjohngreene.com, 1
 destinoytarot.com, 1
 destinyofthephoenix.me, 0
 desu.ne.jp, 1
 desuchan.eu, 1
 desuchan.org, 1
 desveja.com.br, 1
 det-te.ch, 1
@@ -13543,17 +13528,16 @@ djboekingskantoor.nl, 1
 djc.me, 1
 djcursuszwolle.nl, 1
 djdavid98.hu, 1
 djeung.org, 1
 djiconsulting.com, 1
 djipanov.com, 1
 djleon.net, 1
 djlinux.cz, 1
-djlive.pl, 1
 djlnetworks.co.uk, 1
 djroynomden.nl, 1
 djsbouncycastlehire.com, 1
 djsk.nl, 1
 djt-vom-chausseehaus.de, 1
 djul.net, 1
 djvintagevinyl.nl, 1
 djwaynepryke.com, 1
@@ -13614,17 +13598,16 @@ dmparish.com, 1
 dmschilderwerken.nl, 1
 dmwall.cn, 1
 dmx.xyz, 1
 dmxledlights.com, 1
 dmzlab.se, 1
 dn3s.me, 1
 dn42.us, 1
 dna.li, 1
-dnacloud.pl, 1
 dnakids.co.uk, 1
 dnalounge.com, 1
 dnapizza.com, 1
 dnastatic.com, 1
 dnc.org.nz, 1
 dndtools.net, 1
 dnfc.rocks, 1
 dnlr.tech, 1
@@ -13839,26 +13822,25 @@ domyzitrka.cz, 1
 donabeneko.jp, 1
 donaldm.co.uk, 1
 donateaday.net, 1
 donation.ph, 1
 donboscogroep.nl, 1
 donetsk24.su, 1
 donfelino.tk, 0
 dongjingre.net, 1
-dongthucvat.com, 0
+dongthucvat.com, 1
 dongxuwang.com, 1
 donjusto.nl, 1
 donkennedyandsons.com, 1
 donkeytrekkingkefalonia.com, 1
 donmaldeamores.com, 1
 donnaandscottmcelweerealestate.com, 1
 donnacha.blog, 1
 donnachie.net, 1
-donnajeanbooks.com, 1
 donner-reuschel.de, 1
 donnons.org, 0
 donnoval.ru, 0
 donotcall.gov, 1
 donotlink.it, 1
 donovankraag.nl, 1
 donpomodoro.com.co, 1
 dont.re, 1
@@ -14237,16 +14219,17 @@ drlangsdon.com, 1
 drlinkcheck.com, 1
 drlutfi.com, 1
 drmayakato.com, 1
 drmcdaniel.com, 1
 drms.us, 1
 drmtransit.com, 1
 drobniuch.pl, 0
 drogoz.moe, 1
+drogueriaelbarco.com, 1
 droidandy.com, 1
 droidapp.nl, 1
 droidgyan.com, 1
 droidhere.com, 1
 droidim.com, 0
 droidwiki.de, 1
 drone-it.net, 1
 dronebl.org, 1
@@ -14273,17 +14256,16 @@ drpetervoigt.de, 1
 drphillipsmwc.com, 1
 drpico.com.au, 1
 drpure.top, 1
 drros.ru, 1
 drrr.chat, 1
 drrr.wiki, 1
 drsajjadian.com, 1
 drsamuelkoo.com, 1
-drschlarb.eu, 1
 drschruefer.de, 1
 drsturgeonfreitas.com, 1
 drtimmarch.com, 1
 drtimothybradley.com, 1
 drtti.io, 1
 drubn.de, 0
 druckerei-huesgen.de, 1
 drugs.com, 1
@@ -14730,17 +14712,16 @@ easyoutdoor.nl, 1
 easypay.bg, 1
 easypayments.pro, 1
 easyproperty.com, 1
 easypv.ch, 1
 easyqr.codes, 1
 easyreal.ru, 1
 easyroad.fr, 1
 easyslide.be, 1
-easyssl.com.cn, 1
 easystore.co, 1
 easytechguides.com, 1
 easytechsecurity.com, 1
 easyweenies.com, 1
 eat-sleep-code.com, 1
 eat-the-world.ch, 1
 eatery.co.il, 1
 eatfitoutlet.com.br, 1
@@ -15388,17 +15369,19 @@ elglobo.com.mx, 0
 elgosblanc.com, 1
 elguadia.faith, 1
 elguillatun.cl, 1
 elhamadimi.com, 1
 elhorizontal.com, 1
 elhossari.com, 1
 elia.cloud, 1
 elian-art.de, 1
+elias-nicolas.com, 1
 eliaskordelakos.com, 1
+eliasojala.me, 1
 eliaswendt.com, 1
 eliaswendt.de, 1
 elibom.com, 1
 elie.net, 1
 elifesciences.org, 1
 eligibilis.com, 1
 eligible.com, 1
 eligibleapi.com, 1
@@ -15566,17 +15549,16 @@ emily.moe, 1
 emilybellydance.com.au, 1
 emilyjohnson.ga, 1
 emilypennock.com, 1
 eminhuseynov.com, 1
 emirabiz.com, 0
 emirichardson.com, 1
 emisia.com, 1
 emivauthey.com, 1
-emkanrecords.com, 1
 emkrivoy.com, 1
 emma-o.com, 1
 emma.ly, 1
 emmababy420.com, 1
 emmagraystore.com, 1
 emmanuelle-et-julien.ch, 1
 emmehair.com, 1
 emo-poris.com, 1
@@ -15627,17 +15609,16 @@ en-crypt.me, 1
 en-maktoob.search.yahoo.com, 0
 en4rab.co.uk, 1
 en4u.org, 1
 enaah.de, 1
 enalean.com, 1
 enamae.net, 1
 enbecom.net, 1
 enbulleiugnen.com, 1
-encens.boutique, 1
 encfs.win, 1
 encircleapp.com, 1
 encnet.de, 1
 encode.host, 1
 encodecloud.net, 1
 encoderx.uk, 1
 encore.io, 0
 encouragemarketing.com, 1
@@ -15780,16 +15761,17 @@ enteente.com, 1
 entercenter.ru, 1
 enterprisey.enterprises, 1
 entersoftsecurity.com, 1
 entersynapse.com, 1
 entheogens.com, 1
 entheorie.net, 1
 enthusiaformazione.com, 1
 entradaweb.cl, 1
+entrainr.com, 1
 entravex.com, 1
 entrecieletpierres.com, 1
 entropia.de, 0
 entropy.su, 1
 entrusted.io, 1
 entryboss.cc, 1
 entrypoint.sh, 1
 entwickler.land, 1
@@ -16376,17 +16358,17 @@ eu-darlehen-finanzierung.de, 1
 eu-datenbank.de, 1
 eu-gamers.com, 1
 eu-stellenangebot.de, 1
 euaggelion.blog.br, 1
 euanbarrett.com, 1
 euchre.us, 1
 eucollegetours.com, 1
 euexia.fr, 1
-eugenechae.com, 1
+eugenechae.com, 0
 eugenekay.com, 1
 eugenetech.org, 1
 eujuicers.bg, 1
 eujuicers.com, 1
 eujuicers.com.hr, 1
 eujuicers.com.tr, 1
 eujuicers.com.ua, 1
 eujuicers.cz, 1
@@ -16551,16 +16533,17 @@ evidentiasoftware.com, 1
 evilbeasts.ru, 1
 evilbunnyfufu.com, 1
 evileden.com, 1
 evilized.de, 1
 evilmartians.com, 1
 evilness.nl, 1
 evilsite.cf, 1
 evion.nl, 1
+evitacion.com, 1
 evlann.com, 0
 evlear.com, 1
 evoco.vc, 1
 evodation.com, 1
 evodation.org, 1
 evodia-spirits.de, 1
 evok.com.co, 0
 evokepk.com, 1
@@ -16605,17 +16588,16 @@ ex-deli.jp, 1
 exactlyinfinite.com, 1
 exactphilosophy.net, 1
 exadime.net, 1
 exagoni.com.au, 1
 exagoni.com.my, 1
 examedge.com, 1
 examenpilotos.com, 0
 exampleessays.com, 1
-examplesu.com, 1
 examsmate.in, 1
 exaplac.com, 1
 exarpy.com, 1
 exatmiseis.net, 0
 excaliburtitle.com, 0
 exceed.global, 1
 exceedagency.com, 1
 excel-mechanical.com, 1
@@ -16697,26 +16679,26 @@ explodingcamera.com, 1
 exploflex.com.br, 1
 exploit-db.com, 1
 exploit.cz, 0
 exploit.party, 1
 exploit.ph, 1
 exploited.cz, 1
 exploitit.com.au, 1
 exploodo.rocks, 1
-exploration.ga, 1
 exploravacations.in, 1
 explorebigideas.com, 1
 exploremonero.com, 1
 exploringenderby.com, 1
 expmind.co.in, 1
 expo-america.ru, 1
 expo-asia.ru, 1
 expo-europe.ru, 1
 expo-larionov.org, 1
+exponentialnews.net, 1
 expoort.co.uk, 1
 expoort.com, 1
 expoort.com.br, 1
 expoort.es, 1
 expoort.fr, 1
 expoort.it, 1
 expopodium.com, 1
 exporta.cz, 1
@@ -16878,17 +16860,16 @@ fabriziorocca.it, 1
 fabrykowski.com, 1
 fabrysociety.org, 1
 fabse.net, 1
 fabulouslyyouthfulskin.com, 1
 fabulouslyyouthfulskineyeserum.com, 1
 facai666.cc, 1
 facai888.cc, 1
 facarospauls.com, 1
-faccess.it, 1
 facciadastile.it, 1
 face-fashion.de, 1
 face-mania.com, 1
 facealacrise.fr, 1
 facebattle.com, 1
 facebook-atom.appspot.com, 1
 facebook.ax, 1
 facebook.com, 0
@@ -17516,17 +17497,16 @@ figure.nz, 1
 figuurzagers.nl, 0
 fiilr.com, 1
 fiix.io, 1
 fijnefeestdageneneengelukkignieuwjaar.nl, 1
 fijnewoensdag.nl, 1
 fiken.no, 1
 fikst.com, 1
 fil-tec-rixen.com, 1
-fil.fi, 1
 filamentia.nl, 1
 filanthropystar.org, 1
 filaretihairlove.gr, 1
 file-cloud.eu, 1
 file-pdf.it, 1
 filebox.space, 1
 filecopa.com, 1
 filehash.de, 1
@@ -17553,17 +17533,16 @@ film-colleges.com, 1
 film-op-tv.nl, 1
 film-storyboards.fr, 1
 film-tutorial.com, 1
 filmatiporno.xxx, 1
 filme-onlines.com, 1
 filmers.net, 1
 filmitis.com, 1
 filmreviewonline.com, 1
-filmserver.de, 1
 filmsite-studio.com, 1
 filmsphoto.com, 1
 filoo.de, 1
 filstop.com, 1
 filterlists.com, 1
 filtr.me, 1
 fimsquad.com, 1
 finagosolo.com, 1
@@ -18044,17 +18023,16 @@ folio.no, 1
 foliumbiosciences.com, 1
 foljeton.dk, 1
 folk.as, 1
 folkadelic.de, 1
 follandviolins.com, 1
 followback.net, 1
 follower98.ir, 1
 followerrocket.com, 1
-followersya.com, 1
 followings-live.com, 1
 followmystaff.com, 1
 followthatpage.com, 1
 followthedog.co.uk, 1
 foluomeng.net, 1
 folv.es, 1
 folwark.krakow.pl, 1
 folwarkwiazy.pl, 1
@@ -18179,16 +18157,17 @@ forstbetrieb-hennecke.de, 1
 forstprodukte.de, 1
 forsyththeatre.com, 1
 forteggz.nl, 1
 fortesanshop.it, 1
 forthetoys.com, 1
 fortnine.ca, 1
 fortnitemagic.ga, 1
 fortoglethorpega.gov, 1
+fortran.io, 1
 fortress.no, 1
 fortuna-apotheke-lahnstein.de, 1
 fortuna-loessnitz.de, 1
 fortuna-s.com, 1
 forty-two.nl, 1
 forty8creates.com, 1
 fortytwo.cloud, 1
 forum-bonn.de, 1
@@ -18616,28 +18595,28 @@ frozen-solid.net, 1
 frozenjam.com, 1
 frp-roleplay.de, 1
 frpg.gov, 1
 frprn.com, 1
 frprn.es, 1
 frprn.xxx, 1
 frsnpwr.net, 1
 frtn.com, 1
-frtr.gov, 1
 frtrains.com, 1
 fruchthof24.de, 1
 fruchtikus.net, 1
 fruend-hausgeraeteshop.de, 1
 frugalfamilyhome.com, 1
 frugalmechanic.com, 1
 frugro.be, 1
 fruition.co.jp, 1
 fruitscale.com, 1
 fruityfitness.com, 1
 fruityten.co.uk, 1
+frusky.de, 1
 frusky.net, 1
 fruttini.de, 1
 frydrychit.cz, 1
 fs-community.nl, 0
 fs-fitness.eu, 1
 fs-g.org, 1
 fs-maistadt.de, 1
 fs257.com, 1
@@ -19192,22 +19171,21 @@ gasnews.net, 1
 gassouthkenticoqa.azurewebsites.net, 1
 gastauftritt.net, 1
 gastoudererenda.nl, 1
 gastritisolucion.com, 1
 gastromedicalcenter.com.br, 1
 gastrotiger.at, 1
 gastrotiger.de, 1
 gatapro.net, 0
-gate2home.com, 0
+gate2home.com, 1
 gateaucreation.fr, 1
 gatekiller.co.uk, 1
 gatemoves.com, 1
 gatewaybridal.com, 1
-gatewaybronco.com, 1
 gathu.co.ke, 1
 gatilagata.com.br, 1
 gatomix.net, 1
 gauche.com, 1
 gaudeamus-folklor.cz, 1
 gaudere.co.jp, 1
 gaurl.ga, 1
 gaussianwaves.com, 1
@@ -19439,17 +19417,17 @@ geocommunicator.gov, 1
 geocompass.at, 1
 geoffsec.org, 1
 geography-schools.com, 1
 geoinstinct.com, 1
 geoip.fedoraproject.org, 1
 geoip.stg.fedoraproject.org, 1
 geojs.io, 1
 geology-schools.com, 1
-geomac.gov, 0
+geomac.gov, 1
 geometra.roma.it, 1
 geometra24.it, 1
 geomex.be, 1
 geomonkeys.com, 1
 geoponika.gr, 1
 geoport.al, 1
 georadar-algerie.com, 1
 george-brighton.co.uk, 1
@@ -19691,17 +19669,16 @@ gifts.best, 1
 gifts365.co.uk, 1
 giftsn.com.sg, 0
 giftya.com, 1
 gifudodo.com, 1
 gifzilla.net, 0
 gig-raiffeisen.de, 1
 gig.ru, 0
 giga.nl, 1
-gigabitz.pw, 0
 gigacog.com, 1
 gigantism.com, 1
 gigawa.lt, 1
 giggletotz.co.uk, 1
 gigin.eu, 1
 gigin.me, 1
 gigis-pizzeria.de, 1
 gigis.cloud, 1
@@ -19754,16 +19731,17 @@ girlan.net, 1
 girlsforum.com, 1
 girlsgenerationgoods.com, 1
 girlsgonesporty.com, 1
 girlsnet.work, 1
 girlz.jp, 1
 girsa.org, 1
 girvas.ru, 1
 gisac.org, 1
+gisch.tk, 1
 gisgov.be, 1
 gisher.news, 1
 gisher.org, 1
 gisher.video, 1
 gishiko.net, 1
 gistr.io, 1
 git.ac.cn, 1
 git.co, 1
@@ -20074,25 +20052,25 @@ golik.net.pl, 0
 golkala.com, 1
 golser-schuh.at, 1
 golser.info, 1
 gomasy.jp, 1
 gomel.chat, 1
 gomel.city, 1
 gomelchat.com, 1
 gomelphoto.com, 1
+gomiblog.com, 1
 gommista.roma.it, 1
 gondawa.com, 1
 gondelvaartdwarsgracht.nl, 1
 gongjianwei.com, 1
 gongjuhao.com, 1
 gonx.dk, 0
 gonzalesca.gov, 1
 goo.gl, 1
-good-tips.pro, 1
 good588.com, 1
 gooday.life, 1
 gooddomainna.me, 1
 goodfeels.net, 1
 goodhealthtv.com, 1
 goodiesoftware.xyz, 1
 goodquote.gq, 1
 goodryb.top, 1
@@ -20632,16 +20610,17 @@ guidedselling.net, 1
 guidedsteps.com, 1
 guideline.gov, 0
 guidelines.gov, 0
 guideo.ch, 1
 guidepointsecurity.com, 1
 guides-peche64.com, 1
 guidesacademe.com, 1
 guidetoiceland.is, 0
+guildbase.de, 1
 guildgearscore.cf, 0
 guildofmusicsupervisors.co.uk, 1
 guillaume-briand.fr, 1
 guillaumecote.me, 1
 guillaumeperrin.io, 1
 guillemaud.me, 1
 guim.co.uk, 1
 guineapigmustach.es, 1
@@ -20659,34 +20638,35 @@ gummientchen.net, 1
 gunauc.net, 1
 gunhunter.com, 1
 gunn.ee, 1
 gunsofshadowvalley.com, 1
 gunwatch.co.uk, 1
 gunworld.com.au, 1
 gunz.net, 1
 guochang.xyz, 1
+guodong.net, 1
 guohuageng.com, 1
 guoke.com, 1
 guolaw.ca, 1
 guoliang.me, 1
 guozeyu.com, 1
 gupfen.ch, 1
-guphi.net, 0
 gurkan.in, 1
 gurmel.ru, 1
 guru-naradi.cz, 1
 gurucomi.com, 1
 gurueffect.com, 1
 gurugardener.co.nz, 1
 gurunpa.com, 1
 gururi.com, 1
 gus.host, 1
 gus.moe, 1
 gustaff.de, 1
+gustiaux.com, 0
 gut8er.com.de, 1
 guthabenkarten-billiger.de, 1
 gutools.co.uk, 1
 guts.me, 1
 guts.moe, 1
 gutschein-spezialist.de, 1
 gutscheingeiz.de, 1
 gutuia.blue, 1
@@ -20761,17 +20741,16 @@ h1ctf.com, 1
 h1z1swap.com, 1
 h24.org, 1
 h2b.me, 1
 h2cdn.cloud, 1
 h2rul.eu, 1
 h2s-design.de, 1
 h2u.tv, 1
 h3artbl33d.nl, 1
-h3b.nl, 1
 h3x.jp, 0
 h3x.net, 1
 h3z.jp, 1
 h404bi.com, 1
 ha-kunamatata.de, 1
 ha.com, 1
 ha3.eu, 1
 ha6.ru, 1
@@ -20944,17 +20923,16 @@ hammer-sms.com, 1
 hammerpondkennels.co.uk, 1
 hampl.tv, 1
 hampshiretechservices.co.uk, 1
 hamsters-uk.org, 1
 hamu.blue, 1
 hana.ondemand.com, 1
 hanakaraku.com, 1
 hanakatova.com, 1
-hanashi.eu, 1
 hanbing.it, 1
 handbrake.fr, 1
 handcraft.eu.org, 1
 handgelenkbandage-test.de, 1
 handknit.com.np, 1
 handlecoin.com, 1
 handleidingkwijt.com, 1
 handmade-workshop.de, 1
@@ -21004,17 +20982,16 @@ hansminten.com, 1
 hansmund.com, 1
 hansolrella.com, 1
 hansonian.com, 1
 hansvaneijsden.com, 1
 hansvaneijsden.nl, 1
 hantse.com, 1
 hanu.la, 1
 hanyibo.com, 1
-hanying6.com, 1
 hanys.xyz, 1
 hanzcollection.online, 1
 hanzubon.jp, 1
 hao-zhang.com, 1
 haocq3.com, 1
 haogoodair.ca, 1
 haoqi.men, 1
 haorenka.org, 1
@@ -21033,17 +21010,17 @@ happy-life-food.de, 1
 happyagain.de, 1
 happyagain.se, 1
 happyandrelaxeddogs.eu, 1
 happybeerdaytome.com, 1
 happybirthdaywisher.com, 1
 happybounce.co.uk, 1
 happycarb.de, 1
 happychat.io, 1
-happycoder.net, 0
+happycoder.net, 1
 happydietplan.com, 1
 happydoq.ch, 1
 happygadget.me, 1
 happyhealthylifestyle.com, 1
 happykidscastles.co.uk, 1
 happylifestyle.com, 1
 happyschnapper.com, 1
 happyteamlabs.com, 1
@@ -21784,17 +21761,16 @@ hivatal-info.hu, 1
 hivatalinfo.hu, 1
 hiverlune.net, 1
 hiwiki.tk, 1
 hiyacar.co.uk, 1
 hiyobi.me, 1
 hizzacked.xxx, 1
 hj-mosaiques.be, 1
 hj.rs, 1
-hj3455.com, 1
 hj99vip.com, 1
 hjartasmarta.se, 1
 hjertingfysioterapi.dk, 1
 hjes.com.ve, 1
 hjkbm.cn, 1
 hjort.land, 1
 hjortland.org, 1
 hjphoto.co.uk, 1
@@ -21847,17 +21823,17 @@ hochdorf-tennis.de, 1
 hochhaus.us, 1
 hochoukikikiraku.com, 1
 hochyi.com, 1
 hochzeit-dana-laurens.de, 1
 hochzeitsfotograf-deinfoto.ch, 1
 hochzeitsplanerin-hamburg.de, 1
 hockeyapp.ch, 1
 hockeymotion.ch, 1
-hoctap.net, 0
+hoctap.net, 1
 hodgephotography.com, 1
 hodnos.com, 1
 hoe.re, 1
 hoeft-autolackierung.de, 1
 hoekvanholland.eu, 1
 hoelty.network, 1
 hoeren.club, 1
 hoesnelwasik.nl, 1
@@ -22130,17 +22106,16 @@ hotelflow.com.br, 1
 hotelident.de, 1
 hotelkaj.hr, 1
 hotello.io, 1
 hotelmadhuwanvihar.com, 1
 hotelmap.com, 1
 hotelmarinaadria.com, 1
 hotelneptundalmatien.com, 1
 hotelpostaorvieto.it, 1
-hotelromacuernavaca.com.mx, 1
 hotels-insolites.com, 1
 hotels3d.com, 1
 hotels4teams.com, 1
 hotelsinbuxton.com, 1
 hotelsinformer.com, 1
 hotelsinncoventry.com, 1
 hotelsolinebrela.com, 1
 hotelvalena.com, 1
@@ -22163,17 +22138,16 @@ hotting.nl, 1
 hottubhirenewcastle.co.uk, 1
 hottubspasnewcastle.co.uk, 1
 hotwifer.com, 1
 houdremont-la-courneuve.info, 1
 houraiteahouse.net, 1
 house-sparrow.com, 1
 houseandgarden.co.uk, 1
 houseboydesigns.com, 1
-houseinvestor.com, 1
 housekeeperlondon.co.uk, 1
 houselocal.co.uk, 1
 houseofherbs.gr, 1
 houseofhouston.com, 1
 houseofyee.com, 1
 houser.lu, 1
 housese.at, 1
 houstonapartmentinsiders.com, 1
@@ -22575,17 +22549,16 @@ hypothesis.link, 1
 hypothyroidmom.com, 1
 hyr.mn, 1
 hysh.jp, 1
 hytale.com, 1
 hytzongxuan.com, 1
 hyundai.no, 1
 hyvanilmankampaamo.fi, 1
 hyvinvointineuvoja.fi, 1
-hyvive.com, 1
 hywlovexyc.info, 1
 hyyen.com, 1
 hztgzz.com, 1
 i--b.com, 1
 i-0v0.in, 1
 i-aloks.ru, 1
 i-geld.de, 1
 i-hakul.net, 1
@@ -22686,17 +22659,16 @@ ibericartechnik.es, 1
 ibestreview.com, 1
 ibexcore.com, 1
 ibigawamizueco.com, 1
 ibin.co, 1
 ibiz.mk, 1
 iblackfriday.ro, 1
 ibna.online, 1
 ibodyiq.com, 1
-iboy1069.com, 1
 ibpegasus.tk, 1
 ibps-recruitment.in, 1
 ibpsrecruitment.co.in, 1
 ibrainmedicine.org, 1
 ibrom.eu, 1
 ibron.co, 0
 ibsafrica.co.za, 1
 ibsglobal.co.za, 1
@@ -22737,19 +22709,16 @@ ichbinkeinreh.de, 1
 ichmachdas.net, 1
 ickerseashop.com, 1
 iclart.com, 1
 iclinic.ua, 1
 icloudlogin.com, 1
 icmhd.ch, 1
 icmp2018.org, 1
 icnc.ga, 1
-icnsoft.cf, 1
-icnsoft.ga, 1
-icnsoft.ml, 1
 icnsoft.org, 1
 icobench.com, 1
 icodeconnect.com, 1
 icoh.it, 1
 iconomi.net, 1
 icowhitepapers.co, 1
 icpc.pp.ua, 1
 icpc2016.in.th, 1
@@ -22914,17 +22883,16 @@ igcc.jp, 1
 igdn.de, 1
 igeh-immo.at, 1
 igglabs.com, 1
 iggprivate.com, 1
 iggsoft.com, 1
 iggsoftware.com, 1
 igimusic.com, 1
 igk.nz, 1
-igm-be.ch, 1
 igmus.org, 1
 ignace72.eu, 1
 ignacjanskiednimlodziezy.pl, 1
 ignat-mag.com, 1
 ignat.by, 1
 ignatovich.by, 1
 ignatovich.me, 1
 ignet.gov, 1
@@ -23297,16 +23265,17 @@ indiaflowermall.com, 1
 indian-elephant.com, 1
 indianaantlersupply.com, 1
 indianaberry.com, 1
 indianaffairs.gov, 0
 indianafoundationpros.com, 1
 indianamoldrepairpros.com, 1
 indianawaterdamagerepairpros.com, 1
 indiansmartpanel.com, 1
+indiapur.com, 1
 indiatrademarkwatch.com, 1
 indiawise.co.uk, 1
 indiayogastudio.net, 1
 indicateurs-flash.fr, 1
 indie.dog, 1
 indiecongdr.it, 1
 indiegame.space, 1
 indievelopment.nl, 1
@@ -23603,16 +23572,17 @@ insecret.co.ua, 1
 insecret.com.ua, 1
 insecret.trade, 1
 insecure.org.je, 1
 insegne.roma.it, 1
 insertcoins.net, 1
 insgesamt.net, 1
 inside19.com, 1
 insideaudit.com, 1
+insidebedroom.com, 1
 insidesolutions.nl, 1
 insidethefirewall.tk, 1
 insighti.com, 1
 insighti.eu, 1
 insighti.org, 1
 insighti.sk, 1
 insignificant.space, 1
 insinuator.net, 1
@@ -23743,16 +23713,17 @@ interiordesignsconcept.com, 1
 interiorprofesional.com.ar, 1
 interisaudit.com, 1
 interlijn.nl, 1
 interlingvo.biz, 1
 intermax.nl, 1
 intermedinet.nl, 1
 intern.tax, 1
 internalkmc.com, 1
+international-arbitration-attorney.com, 1
 international-books.org, 1
 international-nash-day.com, 1
 internationalfashionjobs.com, 1
 internationalschool.it, 1
 internationalschoolnewyork.com, 1
 internationalstudentassociation.com, 1
 internationaltalento.it, 1
 internect.co.za, 1
@@ -23775,17 +23746,16 @@ internetmuseum.se, 1
 internetnz.nz, 1
 internetofdon.gs, 1
 internetoffensive.fail, 1
 internetofinsecurethings.com, 1
 internetovehazardnihry.cz, 1
 internetpro.me, 1
 internetstaff.com, 1
 internetzentrale.net, 1
-interociter-enterprises.com, 0
 interparcel.com, 1
 interpol.gov, 1
 interracial.dating, 1
 interseller.io, 1
 interspot.nl, 1
 interssl.com, 1
 interstateautomotiveinc.com, 1
 intertime.services, 1
@@ -23915,23 +23885,23 @@ ioslo.net, 1
 iosmods.com, 1
 iosnoops.com, 1
 iossifovlab.com, 1
 iostream.by, 1
 iotfen.com, 1
 iotsms.io, 1
 iowaent.com, 1
 iowaschoolofbeauty.com, 1
+iowen.cn, 1
 ip-blacklist.net, 1
 ip-hahn.de, 1
 ip-ra.com, 1
 ip-tanz.com, 1
 ip.or.at, 1
 ip.sb, 1
-ip2country.info, 1
 ip3office.com, 1
 ip6.li, 0
 ipad.li, 1
 ipadkaitori.jp, 1
 ipal.im, 1
 ipal.name, 1
 ipal.pl, 1
 ipal.tel, 1
@@ -24645,17 +24615,16 @@ janoberst.com, 1
 janokacer.sk, 1
 janschaumann.de, 1
 janssen.fm, 1
 janterpstra.eu, 1
 jantinaboelens.nl, 1
 janvari.com, 1
 janvaribalint.com, 1
 janz.online, 1
-jaot.info, 1
 japanesemotorsports.net, 1
 japangids.nl, 1
 japaniac.de, 0
 japanphilosophy.com, 0
 japansm.com, 1
 japanwatches.xyz, 1
 japaripark.com, 0
 jape.today, 1
@@ -24801,16 +24770,17 @@ jedepannetonordi.fr, 1
 jedidiah.eu, 0
 jedipedia.net, 1
 jediweb.com.au, 1
 jedmud.com, 1
 jedwarddurrett.com, 1
 jeec.ist, 1
 jeemain.org, 1
 jeepeg.com, 1
+jeepmafia.com, 0
 jeeran.com, 1
 jeeranservices.com, 1
 jeerbl.com, 1
 jeff.forsale, 1
 jeffanderson.me, 1
 jeffcloninger.net, 1
 jeffersonkyattorney.gov, 1
 jeffersonregan.co.uk, 1
@@ -25147,31 +25117,31 @@ joerss.at, 1
 joeseago.com, 1
 joeskup.com, 1
 joesniderman.com, 1
 joespaintingpgh.com, 1
 joestead.codes, 0
 joetsutj.com, 1
 joetyson.io, 1
 joetyson.me, 1
-joeyfelix.com, 1
 joeygitalian.com, 1
 joeyhoer.com, 1
 joeysmith.com, 1
 joeyvanvenrooij.nl, 1
 joeyvilaro.com, 1
 jogi-server.de, 1
 jogjacar.com, 1
 jogorama.com.br, 0
 jogwitz.de, 1
 johanbissemattsson.se, 0
 johand.io, 1
 johanli.com, 1
 johannaojanen.com, 1
 johannes-bauer.com, 1
+johannes-zinke.de, 1
 johannes.io, 1
 johannes.wtf, 1
 johannesburg-escorts.co.za, 1
 johannesen.tv, 1
 johanneskonrad.de, 1
 johannespichler.com, 0
 johanpeeters.com, 1
 johansf.tech, 1
@@ -25286,17 +25256,16 @@ jonpads.com, 1
 jonpavelich.com, 1
 jons.org, 1
 jonscaife.com, 1
 jonssheds.direct, 1
 jooksms.com, 1
 jooksuratas.ee, 1
 joomlant.org, 1
 joompress.biz, 1
-joona.pw, 1
 joonatoona.me, 1
 joostrijneveld.nl, 1
 joostvanderlaan.nl, 1
 jopsens.de, 1
 joran.org, 1
 jorcus.com, 1
 jordan-jungk.de, 1
 jordandevelopment.com, 1
@@ -25426,17 +25395,17 @@ jsnfwlr.com, 1
 jsnfwlr.io, 1
 json.download, 1
 jsonsinc.com, 1
 jsproxy.tk, 1
 jsteward.moe, 1
 jstore.ch, 1
 jsvr.tk, 0
 jsxc.ch, 1
-jtcat.com, 1
+jtcat.com, 0
 jtcjewelry.com, 1
 jtconsultancy.sg, 1
 jtl-software.com, 1
 jtmar.me, 1
 jtp.id, 1
 jts3servermod.com, 1
 jtslay.com, 1
 ju.io, 1
@@ -25738,18 +25707,17 @@ kalevlamps.co.uk, 1
 kaliaa.fi, 1
 kalian.cz, 1
 kalilinux.tech, 1
 kalkulacka-havarijni.cz, 1
 kall.is, 1
 kallies-net.de, 1
 kalmar.com, 1
 kaloix.de, 1
-kalolina.com, 0
-kalombo.ru, 1
+kalolina.com, 1
 kalsbouncies.com, 1
 kaltenbrunner.it, 1
 kalterersee.ch, 1
 kalugadeti.ru, 1
 kalwestelectric.com, 1
 kalyanmatka.guru, 1
 kam-serwis.pl, 1
 kamalame.co, 1
@@ -27027,17 +26995,16 @@ kuaza.com, 1
 kub.hr, 1
 kubica.ch, 1
 kubierecki.pl, 1
 kubik-rubik.de, 0
 kubkprf.ru, 1
 kublis.ch, 1
 kubusadvocaten.nl, 1
 kuchen-am-stiel.de, 1
-kuchenfeelisa.de, 1
 kuchentraum.eu, 0
 kucloud.win, 1
 kucnibudzet.com, 1
 kucukayvaz.com, 1
 kudo.co.id, 1
 kuechenprofi-group.de, 0
 kuechenserver.de, 1
 kuechenserver.org, 1
@@ -27144,29 +27111,29 @@ kx197.com, 1
 kxah35.com, 1
 kxnrl.com, 1
 kyberna.xyz, 1
 kybi.sk, 1
 kydara.com, 1
 kyle.place, 1
 kyledrake.net, 1
 kylegutschow.com, 1
+kylejohnson.io, 1
 kylelaker.com, 1
 kylerwood.com, 1
 kylinj.com, 0
 kylling.io, 1
 kynaston.org.uk, 1
 kynastonwedding.co.uk, 1
 kyobostory-events.com, 1
 kyoko.org, 1
 kyosaku.org, 1
 kyoto-k9.com, 0
 kyoto-mic.com, 1
 kyoto-sake.net, 1
-kyoto-tomikawa.jp, 1
 kyoto-tomoshibi.jp, 1
 kyprexxo.com, 1
 kyras-castles.co.uk, 1
 kys.host, 1
 kysil.org, 1
 kyujin-office.net, 1
 kyunyuki.com, 1
 kyusyu.org, 1
@@ -27198,16 +27165,17 @@ la-kaz-a-velo.fr, 1
 la-laitonnerie.com, 1
 la-maison.ch, 1
 la-maison.eu, 1
 la-petite-entreprise.com, 1
 la-tourmaline.ch, 1
 laac.io, 1
 laan247.dk, 1
 laassari.me, 0
+laatikko.io, 1
 laatjeniethackmaken.nl, 1
 labande-annonce.fr, 1
 labanochjonas.se, 1
 labanote.com, 1
 labanskoller.se, 1
 labanskollermark.se, 1
 labcenter.com, 1
 labcoat.jp, 1
@@ -27220,16 +27188,17 @@ labortogether.com, 1
 labouncycastlehire.co.uk, 1
 labourreedevergheas.fr, 1
 laboutiquedejuliette.com, 1
 laboutiquemarocaineduconvoyeur.com, 1
 laboutiquemarocaineduconvoyeur.ma, 1
 laboxfaitsoncinema.com, 1
 labradorpuppiesforsalebyregisteredlabradorbreeders.com, 0
 labrat.mobi, 0
+labspack.com, 1
 labtest.ltd, 1
 lacaey.se, 1
 lacantine.xyz, 1
 lacasa.fr, 1
 lacasabelucci.com, 1
 lacaserita.org, 1
 lacasseroy.com, 1
 lacaveducinquantenaire.com, 1
@@ -27623,21 +27592,23 @@ lawrencemurgatroyd.com, 1
 lawrencewhiteside.com, 1
 lawyerdigital.co.bw, 1
 lawyerkf.com, 1
 layazc.com, 1
 laylo.io, 1
 laylo.nl, 1
 laymans911.info, 1
 layordesign.co.uk, 1
+layoutsatzunddruck.de, 1
 lazau.com, 1
 lazerus.net, 1
 lazistance.com, 1
 lazowik.pl, 1
 lazulu.com, 1
+lazurit.com, 1
 lazyboston.com, 1
 lazyclock.com, 1
 lazyframe.com, 1
 lazyhelp.com, 1
 lazytux.org, 1
 lb-toner.de, 1
 lbarrios.es, 1
 lbayer.com, 1
@@ -27711,17 +27682,16 @@ leamsigc.com, 0
 leanclub.org, 1
 leandre.cn, 1
 leankit.com, 1
 leanplando.com, 1
 leaodarodesia.com.br, 1
 leap-it.be, 1
 leapandjump.co.uk, 1
 leapworks.io, 1
-learndev.info, 1
 learnedhacker.com, 1
 learnerdriving.com, 0
 learnflakes.net, 1
 learnforestry.com, 1
 learning-id.com, 1
 learningis1.st, 1
 learninglaw.com, 1
 learningman.top, 1
@@ -27802,31 +27772,29 @@ lega-dental.com, 1
 legabot.fr, 1
 legadental.com, 1
 legaillart.fr, 1
 legal.farm, 1
 legalcontrol.info, 1
 legaldesk.com, 1
 legaleus.co.uk, 1
 legalforms.ng, 1
-legalinmotion.es, 1
 legalrobot-uat.com, 1
 legalrobot.com, 1
 legaltip.eu, 1
 legatofmrc.fr, 1
 legendary.camera, 1
 legendarycamera.com, 1
 legendcatz.com, 1
 legendesdechine.ch, 1
 legendofkrystal.com, 1
 legends-game.ru, 0
 legible.es, 1
 legilimens.de, 1
 legioniv.org, 1
-legionminecraft.com, 1
 legiscontabilidade.com.br, 1
 legissa.ovh, 1
 legit.nz, 1
 legjobblogo.hu, 1
 legland.fr, 1
 legnami24.it, 1
 legoutdesplantes.be, 1
 legrandvtc.fr, 1
@@ -27869,17 +27837,16 @@ lemouillour.fr, 1
 lemuslimpost.com, 1
 lenagroben.de, 1
 lenalio.fr, 1
 lenaneva.ru, 1
 lence.net, 1
 lencia.ga, 1
 lendahandmissionteams.org, 1
 lendingclub.com, 1
-lenget.com, 1
 lenguajedeprogramacion.com, 1
 lengyelnyelvoktatas.hu, 1
 lengyelul.hu, 1
 lengzzz.com, 1
 lenidh.de, 1
 leninalbertop.com.ve, 1
 lenkunz.me, 1
 lennyobez.be, 1
@@ -27945,16 +27912,17 @@ lesberger.ch, 1
 lesbiansslaves.com, 1
 lesbofight.com, 1
 lesbrillantsdaristide.com, 1
 lescomptoirsdepierrot.com, 1
 lesconteursavis.org, 1
 lescrapdesfilles.fr, 1
 lesdouceursdeliyana.com, 1
 leseditionsbraquage.com, 1
+lesfilmsavivre.com, 1
 lesgoodnews.fr, 1
 lesh.eu, 1
 leshervelines.com, 1
 lesjardinsdemathieu.net, 1
 lesjardinsdubanchet.fr, 1
 lesmamy.ch, 1
 lesmontagne.net, 1
 lesnet.co.uk, 1
@@ -28024,16 +27992,17 @@ levelaccordingly.com, 1
 levelonetrainingandfitness.com, 1
 leveluplv.com, 1
 leveluprails.com, 1
 levendwater.org, 1
 levensbron.nl, 1
 leventismotors.com.ng, 1
 leveragedtokens.com, 1
 leveredge.net, 1
+leverj.io, 1
 levermann.eu, 1
 leviaan.nl, 1
 leviathan-studio.com, 1
 levindesalpes.fr, 0
 levineteamestates.com, 1
 levinus.de, 1
 leviscop.com, 1
 leviscop.de, 1
@@ -28095,16 +28064,17 @@ lian-in.com, 1
 lian-in.net, 1
 liang-li88.com, 1
 liang-li88.net, 1
 liangxingai.com, 1
 liangyichen.net, 1
 lianhongrui.com, 1
 lianwen.kim, 1
 lianye1.cc, 1
+lianye2.cc, 1
 lianye3.cc, 1
 lianye4.cc, 1
 lianye5.cc, 1
 lianye6.cc, 1
 liaozheqi.cn, 1
 liaronce.com, 1
 liaronce.win, 1
 liautard.fr, 1
@@ -28589,17 +28559,16 @@ liyin.date, 1
 liyinjia.com, 1
 liz.ee, 1
 lizardsystems.com, 1
 lizheng.de, 1
 lizhi.io, 1
 lizhi123.net, 1
 lizhuogui.ga, 1
 lizzaran.io, 1
-lizzwood.com, 1
 ljason.cn, 1
 ljc.ro, 1
 ljoonal.xyz, 1
 ljs.io, 1
 lk-hardware.cz, 1
 lk1.bid, 1
 lkbk.uk, 1
 lkellar.org, 1
@@ -28712,17 +28681,16 @@ lockoutgroup.com, 1
 lockpick.nl, 1
 lockpicks.se, 1
 locksmith--sanantoniotx.com, 1
 locksmith-durbannorth.co.za, 1
 locksmith-sanantonio-tx.com, 1
 locksmithbalchsprings.com, 1
 locksmithballito.com, 1
 locksmithbluff.co.za, 1
-locksmithcarrolltontx.com, 1
 locksmithdearborn.com, 1
 locksmithdrippingspringstx.com, 1
 locksmithedmonds.com, 1
 locksmithfriendswoodtexas.com, 1
 locksmithgarland-tx.com, 1
 locksmithgrapevinetx.com, 1
 locksmithhillcrest.co.za, 1
 locksmithhumbletx.com, 1
@@ -28949,17 +28917,16 @@ lotl.ru, 1
 lotn.mobi, 1
 lotn.nl, 1
 lotnonline.com, 1
 lotnonline.nl, 1
 loto-tele.com, 1
 lotro-wiki.com, 1
 lotsofbargains.com, 1
 lottospielen24.org, 0
-lotuswebsolutions.tk, 1
 lotw.de, 1
 lotz.li, 1
 lou.lt, 1
 louange-reconvilier.ch, 1
 loucanfixit.com, 1
 louerunhacker.fr, 1
 louisapolicefoundation.com, 1
 louisapolicefoundation.org, 1
@@ -29335,16 +29302,17 @@ maaya.jp, 1
 maayogashram.com, 1
 mabankonline.com, 1
 mabulledu.net, 1
 mac-i-tea.ch, 1
 mac-service-stockholm.se, 1
 mac-servicen.se, 1
 mac-support.nu, 1
 mac-support.se, 1
+mac-world.pl, 1
 mac.biz.tr, 1
 mac1.net, 1
 macaque.io, 0
 macaw.nl, 1
 macaws.org, 1
 macbook.es, 1
 maceinturecuir.com, 1
 maces-net.de, 1
@@ -29901,17 +29869,17 @@ mariemiramont.fr, 1
 mariereichl.cz, 1
 marietrap.ch, 1
 marijnfidder.nl, 1
 marikafranke.de, 1
 marilsnijders.nl, 1
 marilynmartin.com.au, 1
 marilynstreats.com, 1
 marin-business-center.ch, 1
-marin-dom.ru, 1
+marin-dom.ru, 0
 marin-tullet.com, 1
 marinazarza.es, 1
 marinbusinesscenter.ch, 1
 marine.gov, 1
 marinecadastre.gov, 1
 marinekaplama.com, 1
 marinela.com.mx, 0
 marinelausa.com, 0
@@ -30025,17 +29993,17 @@ marqperso.ch, 1
 marquepersonnelle.ch, 1
 marqueswines.co.uk, 1
 marrai.de, 1
 marriage-shrine.jp, 1
 marrickvilleapartments.com.au, 1
 marron-dietrecipe.com, 1
 marsanvet.com, 1
 marsatapp.com, 1
-marsble.com, 0
+marsble.com, 1
 marseillekiteclub.com, 1
 marshallford.me, 1
 marshallscastles.com, 1
 marshallwilson.com, 1
 marshmallow.co, 1
 marshmallow.com, 1
 marshyplay.live, 1
 marsikelektro.cz, 1
@@ -30967,16 +30935,17 @@ metafurquest.net, 1
 metallomania.it, 1
 metallosajding.ru, 1
 metalu.ch, 1
 metanic.services, 1
 metanodo.com, 1
 metapeen.nl, 1
 metasquare.com.au, 1
 metasquare.nyc, 1
+metasyntactic.xyz, 1
 metasysteminfo.com, 1
 metaurl.io, 1
 metaword.com, 1
 metaword.net, 1
 metaword.org, 1
 metebalci.com, 0
 meteenonline.nl, 1
 meteo-parc.com, 1
@@ -31020,16 +30989,17 @@ metsasta.com, 1
 mettekopp.dk, 1
 meubanco7.com.br, 1
 meubleko.com, 1
 meujeitodigital.com.br, 0
 meupainel.me, 1
 meurisse.org, 1
 meusigno.com, 1
 mevanshop.com, 0
+mevo.xyz, 1
 mevs.cz, 1
 mexican.dating, 1
 mexicanjokes.net, 1
 mexico.sh, 1
 mexicodental.co, 1
 mexicom.org, 1
 mexior.nl, 1
 meyash.co, 1
@@ -31221,17 +31191,16 @@ migueldemoura.com, 1
 migueldominguez.ch, 1
 miguelgaton.es, 1
 miguelmartinez.ch, 1
 miguelmenendez.pro, 1
 miguelmoura.com, 1
 miguia.tv, 1
 mihgroup.eu.org, 1
 mihgroup.net, 1
-mihijoesdislexico.es, 1
 mihnea.net, 1
 mijcorijneveld.nl, 1
 mijn-financien.be, 1
 mijnetickets.nl, 0
 mijnetz.nl, 1
 mijnkerstkaarten.be, 1
 mijnkinderkleding.com, 1
 mijnpartijhandel.nl, 1
@@ -31250,16 +31219,17 @@ mike-bland.com, 1
 mike-burns.com, 1
 mike-et-pascale-sanger.com, 1
 mike2k.de, 1
 mikeandersondj.com, 1
 mikebelanger.ca, 1
 mikeblog.site, 1
 mikebutcher.ca, 1
 mikecb.org, 1
+mikedugan.org, 1
 mikegao.net, 0
 mikegao.org, 1
 mikegarnett.co.uk, 1
 mikegerwitz.com, 1
 mikeguy.co.uk, 1
 mikehamburg.com, 1
 mikehilldesign.co.uk, 1
 mikeklidjian.com, 1
@@ -31285,17 +31255,17 @@ mikkonen.bio, 1
 miklcct.com, 1
 miknight.com, 1
 mikonmaa.fi, 1
 mikrom.cz, 0
 mikropixel.de, 1
 mikroskeem.eu, 1
 miku.cloud, 1
 miku.party, 1
-miku.ro, 0
+miku.ro, 1
 mikumaycry.com, 1
 mikumiku.stream, 1
 mikupic.com, 1
 mikusa.xyz, 1
 mil-spec.ch, 1
 mil0.com, 1
 milahendri.com, 1
 milakirschner.de, 1
@@ -31462,17 +31432,16 @@ mionerve.org, 1
 mipapo.de, 1
 miproximopaso.org, 1
 mipueblohoy.com, 1
 mipymesenlinea.com, 1
 mir.pe, 1
 miraheze.org, 1
 miraidenshi.com, 1
 miramar.ca, 1
-miraste.com.br, 1
 mirazonline.tk, 1
 mirazperu.com, 1
 mircarfinder.ru, 1
 mirch.com, 1
 mirco-grams.de, 1
 mireiaseuba.com, 1
 mireillewendling.com.br, 1
 mirepublic.co.nz, 1
@@ -31616,17 +31585,16 @@ mkacg.com, 1
 mkaciuba.com, 0
 mkakh.com, 1
 mkakh.xyz, 1
 mkbouncycastles.co.uk, 1
 mkbouncyhire.co.uk, 1
 mkcert.org, 1
 mkchandler.com, 1
 mkd.mk, 1
-mkes.com, 1
 mkfs.fr, 1
 mkg-scherer.de, 1
 mkg-wiebelskirchen.de, 1
 mkhsoft.eu, 1
 mkie.cf, 1
 mkimage.com, 1
 mkinteriores.com.br, 1
 mkjl.ml, 1
@@ -32107,30 +32075,31 @@ motoreflex.com, 1
 motorpointarenacardiff.co.uk, 1
 motorring.ru, 1
 motorsplus.com, 0
 motorsportdiesel.com, 1
 motoryachtclub-radolfzell.de, 1
 motosikletevi.com, 1
 motospaya.com, 1
 mototax.ch, 1
-motovated.co.nz, 0
+motovated.co.nz, 1
 motovio.de, 1
 motowilliams.com, 1
 motransportinfo.com, 1
 motstats.co.uk, 1
 moube.fr, 1
 moulinaparoles.ca, 1
 moumaobuchiyu.com, 1
 mountain-rock.ru, 1
 mountainactivitysection.org.uk, 1
 mountainbatchers.de, 1
 mountainchalet.blue, 1
 mountainspringsrentals.ca, 1
 mountairymd.gov, 1
+mountfarmer.de, 1
 mousepotato.uk, 1
 moutiezhaller.com, 1
 movacare.de, 1
 move.mil, 1
 moveltix.net, 1
 movember.com, 0
 movepin.com, 1
 movewellapp.com, 1
@@ -32547,17 +32516,16 @@ mx5international.com, 1
 mxawei.cn, 1
 mxdanggui.org, 1
 mxdvl.com, 1
 mxihan.xyz, 1
 mxn8.com, 1
 my-aftershave-store.co.uk, 1
 my-best-wishes.com, 1
 my-cdn.de, 1
-my-co.ir, 1
 my-contract.ch, 1
 my-contract.info, 1
 my-contract.net, 1
 my-demo.co, 1
 my-ebook.es, 1
 my-floor.com, 1
 my-gode.fr, 1
 my-host.ovh, 1
@@ -32657,17 +32625,16 @@ mydomaindesk.com, 1
 mydreamlifelab.com, 1
 mydreamshaadi.in, 1
 mydroneservices.ca, 1
 mydroneservices.com, 1
 myduffyfamily.com, 1
 myeasybooking.de, 1
 myeberspaecher.com, 1
 myedumundo.com, 1
-myeffect.today, 1
 myeisenbahn.de, 1
 myeml.net, 0
 myepass.bg, 1
 myepass.de, 1
 myessaygeek.com, 1
 myetherwallet.com, 1
 myf.cloud, 1
 myfae.eu, 1
@@ -32867,17 +32834,17 @@ myrnabiondo.com.br, 1
 myrotvorets.center, 1
 myrotvorets.news, 1
 myrp.co, 1
 myruststats.com, 1
 mysad.de, 1
 mysber.ru, 1
 myschoolphoto.org, 1
 myseatime.com, 1
-mysecretcase.com, 0
+mysecretcase.com, 1
 mysectools.org, 1
 myself5.de, 1
 myseo.ga, 1
 myserv.one, 1
 myservice.store, 0
 myservicearl.com, 1
 mysexydate24.com, 1
 mysignal.com, 1
@@ -33193,17 +33160,16 @@ natenom.de, 1
 natenom.name, 1
 natgeofreshwater.com, 1
 nathaliebaron.ch, 1
 nathaliebaroncoaching.ch, 1
 nathaliedijkxhoorn.com, 1
 nathaliedijkxhoorn.nl, 1
 nathan.io, 1
 nathan.ovh, 1
-nathanaeldawe.com, 1
 nathankonopinski.com, 1
 nathanmfarrugia.com, 1
 nathansmetana.com, 1
 nathumarket.com.br, 1
 nation-contracting.com.hk, 1
 nationalbank.gov, 1
 nationalbanknet.gov, 1
 nationalcentereg.org, 1
@@ -33937,17 +33903,16 @@ nicolasfriedli.ch, 1
 nicolashess.de, 1
 nicolasiung.me, 1
 nicolaszambetti.ch, 1
 nicolaw.uk, 1
 nicolemathew.com, 1
 niconico.ooo, 1
 niconode.com, 0
 nicoobook.com, 1
-nicoobook.net, 1
 nicorevin.ru, 1
 nicsezcheckfbi.gov, 1
 nicul.in, 1
 nidro.de, 1
 nidsuber.ch, 1
 niduxcomercial.com, 1
 niederohmig.de, 1
 niehage.name, 1
@@ -34234,17 +34199,16 @@ noortronic.com, 1
 nootroic.com, 1
 nootronerd.com, 1
 nootropic.com, 1
 nootropicpedia.com, 1
 noovell.com, 1
 nopaste.xyz, 1
 nopaynocure.com, 1
 norad.sytes.net, 1
-noradevot.com, 1
 norbertschneider-music.com, 1
 nord-restaurant-bar.de, 1
 nord-sud.be, 1
 nordakademie.de, 1
 norden.eu.org, 1
 nordfinck.de, 1
 nordicess.dk, 1
 nordicirc.com, 1
@@ -34374,17 +34338,16 @@ notsafefor.work, 1
 nottres.com, 1
 noudjalink.nl, 1
 nourishandnestle.com, 1
 noustique.com, 1
 nova-dess.ch, 1
 nova-it.pl, 1
 nova-kultura.org, 1
 nova-wd.org.uk, 1
-nova.com.hk, 1
 nova.live, 1
 novabench.com, 1
 novacal.ga, 1
 novacoast.com, 0
 novadermis.es, 1
 novafreixo.pt, 1
 novaiguacu.net.br, 1
 novascan.net, 1
@@ -34491,17 +34454,16 @@ nti.de, 1
 ntia.gov, 1
 ntlabs.org, 1
 ntotten.com, 1
 ntppool.org, 0
 ntsb.gov, 1
 ntut.net, 1
 ntwt.us, 1
 ntx360grad-fallakte.de, 1
-ntzwrk.org, 1
 nu-pogodi.net, 1
 nu3tion.com, 1
 nu3tion.cz, 1
 nuacht.ie, 1
 nuamooreaindonesia.com, 1
 nubu.at, 1
 nuclea.id, 1
 nuclea.site, 1
@@ -34921,17 +34883,16 @@ okonetwork.org.uk, 1
 okotoksbeach.ca, 1
 okqubit.net, 1
 oksafe-t.org, 1
 oktime.cz, 1
 oktoberfeststore.nl, 1
 oktomus.com, 1
 okukan.com.au, 1
 okurapictures.com, 1
-okuscapital.com, 1
 okusiassociates.com, 1
 okviz.com, 1
 olanderflorist.com, 1
 olandiz.com, 1
 olasouris.com, 1
 olastrafford.org, 1
 olback.net, 1
 olbat.net, 1
@@ -35126,16 +35087,17 @@ onewebdev.info, 1
 onfarma.it, 1
 ongea.io, 1
 ongiaenegogoa.com, 1
 onhistory.co.uk, 1
 onhub1.com, 1
 oni.nl, 1
 onice.ch, 1
 onionbot.me, 1
+onionplay.net, 1
 onionsburg.com, 0
 onionscan.org, 1
 onionyst.com, 1
 oniria.ch, 1
 onix.eu.com, 1
 onixcco.com.br, 1
 onkentessegertdij.hu, 1
 onkfaktor.de, 1
@@ -35444,17 +35406,16 @@ oreka.online, 1
 oreshinya.xyz, 1
 oreskylaw.com, 1
 oreto.de, 0
 orf-digitalsatkarte.at, 0
 orf-kartentausch.at, 0
 orfeo-engineering.ch, 1
 organica.co.za, 1
 organisatieteam.nl, 1
-organisationsberatung-jacobi.de, 1
 orgasmium.com, 1
 orgsyn.in, 1
 orhideous.name, 1
 orians.eu, 1
 oribia.net, 1
 oricejoc.com, 0
 orientalart.nl, 1
 orientravelmacas.com, 1
@@ -35868,17 +35829,16 @@ palavalbasket.it, 1
 palavatv.com, 1
 palawan.jp, 0
 palazzo.link, 1
 palazzo.work, 1
 palebluedot.de, 1
 paleo.io, 1
 paleodietfoodlist.com, 1
 paleodietrecipes.com, 1
-paleolowcarb.de, 1
 paleorecipepro.com, 1
 paleoself.com, 1
 paleoso.com, 1
 paleosquawk.com, 1
 paleotraining.com, 1
 palermopride.it, 1
 palestra.roma.it, 1
 palladium46.com, 1
@@ -35954,16 +35914,17 @@ pantallasled.com.mx, 1
 pantallasled.mx, 1
 pantallasyescenarios.com, 1
 pantheoncrafters.com, 1
 panthur.com.au, 0
 pantographe.info, 1
 pantou.org, 0
 pants-off.xyz, 1
 panzer72.ru, 1
+panzerscreen.dk, 1
 paolotagliaferri.com, 1
 pap.la, 0
 papa-webzeit.de, 1
 papabearsautocenter.com, 1
 papadopoulos.me, 1
 papakatsu-life.com, 1
 papapa-members.club, 1
 papatest24.de, 1
@@ -35989,16 +35950,17 @@ papillon-events.be, 1
 papion.it, 1
 papiweb.ca, 1
 papotage.net, 1
 paprikas.fr, 1
 paraborsa.net, 1
 parachute70.com, 1
 paracomer.es, 1
 paradais-sphynx.com, 1
+paradependentesquimicos.com.br, 1
 paradiesgirls.ch, 1
 paradise-engineer.com, 1
 paradise-engineering.com, 1
 paradise-engineers.com, 1
 paradise-travel.net, 1
 paradiselost.com, 1
 paradoxdesigns.org, 1
 paragonie.com, 0
@@ -36332,17 +36294,16 @@ pbourhis.me, 1
 pbqs.site, 1
 pbr.so, 1
 pbraunschdash.com, 1
 pbren.com, 1
 pbrumby.com, 1
 pbscreens.com, 1
 pbytes.com, 1
 pbz.im, 1
-pbz.pw, 1
 pc-rescue.me, 0
 pc-servis-brno.com, 1
 pc-warriors.com, 1
 pc28yc.com, 1
 pcbricole.fr, 1
 pccentral.nl, 1
 pcdocjim.com, 1
 pcel.com, 1
@@ -37502,17 +37463,16 @@ pogrebisky.net, 1
 pogs.us, 1
 pohlednice-tap.cz, 1
 pohlmann.io, 1
 poinsot.info, 1
 pointaction.com, 1
 pointagri.com, 1
 pointcab.vn, 1
 pointhost.de, 1
-pointmaquininha.com, 1
 points4unitedway.com, 1
 pointsgame.net, 1
 pointsixtyfive.com, 1
 pointum.com, 1
 pointworksacademy.com, 1
 poiru.net, 1
 poitiers-ttacc-86.eu.org, 1
 pojer.me, 1
@@ -37738,16 +37698,17 @@ posalji.me, 1
 posaunenchor-senden.de, 1
 posbank.co.uk, 1
 poschtiliste.ch, 1
 poseidonwaterproofing.com, 1
 poshcastles.co.uk, 1
 poshlashes.se, 1
 poshsecurity.com, 1
 posijson.stream, 1
+positionus.io, 1
 positive.com.cy, 1
 positivenames.net, 1
 posobota.cz, 1
 posoiu.net, 1
 post-darwinian.com, 1
 post-darwinism.com, 1
 post.com.ar, 1
 post.io, 1
@@ -37771,17 +37732,16 @@ postfalls-naturopathic.com, 1
 postfinance.ch, 1
 postimages.org, 1
 postimg.cc, 1
 postmatescode.com, 1
 postn.eu, 1
 postpot.co.kr, 1
 postsubmeta.net, 1
 posttigo.com, 1
-postura-corretta.it, 1
 posyperfume.com, 1
 potatiz.com, 1
 potato.im, 1
 potatofrom.space, 1
 potatopro.com, 1
 potatron.tech, 1
 potature.rimini.it, 1
 potature.roma.it, 1
@@ -37934,17 +37894,17 @@ preludes.org, 1
 prelved.com, 1
 prelved.es, 1
 prelved.fi, 1
 prelved.fr, 1
 prelved.it, 1
 prelved.nl, 1
 prelved.pl, 1
 prelved.se, 1
-premaritalsex.info, 1
+prematureacceleration.club, 1
 preme.name, 1
 premieravenue.net, 1
 premierbouncycastles.co.uk, 1
 premierdisco.co.uk, 1
 premieresloges.ca, 0
 premierevents.ie, 1
 premierheart.com, 1
 premierjewelersjax.com, 1
@@ -38293,16 +38253,17 @@ promorder.ru, 1
 promoscuola.net, 1
 promoteiq.com, 1
 promoterms.com.au, 1
 promotioncentre.co.uk, 1
 promotiongeeks.com, 0
 promozione.info, 1
 promuovi.tv, 1
 pronto-intervento.net, 1
+prontocleaners.co.uk, 1
 prontointerventoimmediato.it, 1
 prontossl.com, 1
 proofwiki.org, 1
 proos.nl, 1
 proovn.com, 1
 propagandablog.de, 1
 propagationtools.com, 1
 propermatches.com, 1
@@ -38392,17 +38353,16 @@ proxybay.eu.org, 1
 proxybay.ist, 1
 proxybay.la, 1
 proxybay.one, 1
 proxybay.tv, 1
 proxyportal.eu, 1
 proxyportal.net, 1
 proxyportal.org, 1
 proyectafengshui.com, 1
-proyecto13.com, 1
 prpferrara.it, 1
 prplz.io, 1
 prpr.cloud, 1
 prstatic.com, 1
 prt.in.th, 1
 prtimes.com, 1
 prtpe.com, 1
 prtscloud.ddns.net, 1
@@ -38794,17 +38754,16 @@ qqiao.me, 1
 qqj.net, 1
 qqrss.com, 1
 qr-city.org, 1
 qr.cl, 1
 qrbird.com, 1
 qrcontagion.com, 1
 qrlfinancial.com, 1
 qrpatrol.com, 1
-qrpth.eu, 1
 qruiser.com, 1
 qscloud.de, 1
 qtl.me, 1
 qtmsheep.com, 1
 qtn.net, 1
 qto.com, 1
 qto.net, 1
 qto.org, 1
@@ -38978,27 +38937,29 @@ ra.co.ke, 1
 ra.vc, 1
 ra4wvpn.com, 1
 raah.co, 1
 rabbit.wales, 0
 rabbitfinance.com, 1
 rabbitinternet.com, 1
 rabica.de, 1
 rabota-x.ru, 0
+rabotaescort.com, 1
 rabynska.eu, 1
 racasdecachorro.org, 1
 raccoltarifiuti.com, 1
 raccoon.fun, 1
 racermaster.xyz, 1
 racesport.nl, 0
 raceviewcycles.com, 1
 raceviewequestrian.com, 1
 rachelchen.me, 1
 racheldiensthuette.de, 1
 rachelmoorelaw.com, 1
+rachelreagan.com, 1
 rachelsbouncycastles.co.uk, 1
 rachida-dati.eu, 1
 rachurch.net, 1
 racing-planet.cz, 1
 rackblue.com, 1
 rackerlab.com, 1
 raclet.co.uk, 1
 raconconsulting.co.uk, 1
@@ -39150,17 +39111,16 @@ rambo.codes, 1
 rametrix.com, 1
 ramitmittal.com, 1
 rammstein-portugal.com, 1
 ramrecha.com, 0
 ramsdensforcash.co.uk, 1
 ramsdensplc.com, 1
 ramsor-gaming.de, 1
 ranasinha.com, 1
-randallbollig.com, 1
 randc.org, 1
 randewoo.ru, 1
 randolf.ca, 1
 random-samplings.org, 1
 random.org, 1
 randomadversary.com, 1
 randombit.eu, 0
 randomcode.org, 1
@@ -39363,17 +39323,17 @@ readonly.de, 1
 readouble.com, 0
 reads.wang, 1
 readtldr.com, 1
 ready4bf.tk, 1
 readybetwin.com, 1
 readyrowan.com, 1
 readyrowan.org, 1
 readysell.net, 1
-readytobattle.net, 0
+readytobattle.net, 1
 readytongue.com, 1
 readytowear.es, 1
 reaganlibrary.gov, 1
 reaiaer.com, 1
 reaksi.id, 1
 real-bits.com, 1
 real-digital.co.uk, 1
 real-it.nl, 1
@@ -39484,17 +39444,16 @@ red-button.hu, 1
 red-t-shirt.ru, 1
 red-trigger.net, 1
 red2fred2.com, 1
 redable.hosting, 1
 redable.nl, 1
 redactieco.nl, 1
 redb.cz, 1
 redballoonsecurity.com, 1
-redburn.com, 1
 redcatrampageforum.com, 1
 redchat.cz, 1
 redcoded.com, 1
 redcone.net, 1
 redcorus.com, 1
 redd.it, 1
 reddepsicologosdecr.com, 1
 reddingo.at, 1
@@ -39946,17 +39905,16 @@ retractableawningssydney.com.au, 1
 retro.rocks, 1
 retro.sx, 1
 retroarms.com, 1
 retroarms.cz, 1
 retrocdn.net, 1
 retrofitlab.com, 1
 retroity.net, 1
 retrojar.top, 1
-retropack.org, 1
 retroride.cz, 1
 retroroundup.com, 1
 retrotown.ws, 1
 retrotracks.net, 1
 retrovideospiele.com, 1
 retrowave.eu, 1
 returnonerror.com, 1
 returnpath.com, 1
@@ -40082,17 +40040,17 @@ richardson.systems, 1
 richardson.tw, 1
 richardstonerealestate.com, 1
 richardwarrender.com, 1
 richbutler.co.uk, 1
 richcat.tw, 1
 richecommecresus.com, 1
 richeyweb.com, 1
 richeza.com, 1
-richie.cloud, 1
+richie.cloud, 0
 richie.fi, 1
 richie.one, 1
 richlj.net, 1
 richmtdriver.com, 1
 ricketyspace.net, 1
 ricki-z.com, 1
 rickmakes.com, 1
 rickrongen.nl, 1
@@ -40102,17 +40060,17 @@ rickvanderzwet.nl, 1
 rickweijers.nl, 1
 rickyromero.com, 1
 rico-brase.de, 0
 rico.ovh, 1
 ricobaldegger.ch, 1
 ricochet.im, 1
 ricoydesign.com, 1
 ricozienke.de, 1
-riddler.com.ar, 0
+riddler.com.ar, 1
 rideintaxi.com, 1
 rides-japan.jp, 1
 rideways.com, 1
 rideyourdamn.bike, 1
 ridgelandchurch.org, 1
 ridhaan.co, 1
 ridingboutique.de, 1
 ridingoklahoma.com, 1
@@ -40602,16 +40560,17 @@ rowansheriff.com, 1
 rowansheriff.org, 1
 rowantransit.com, 1
 rowantransit.org, 1
 rowlog.com, 1
 roxiesbouncycastlehire.co.uk, 1
 roxtri.cz, 1
 royal-rangers.de, 1
 royal853.com, 0
+royal869.com, 0
 royal876.com, 1
 royal88.com, 1
 royalacademy.org.uk, 1
 royalasianescorts.co.uk, 1
 royalbeautyclinic.ir, 1
 royalbluewa3.cc, 1
 royalcitytaxi.ca, 1
 royalcitytaxi.com, 1
@@ -40647,17 +40606,16 @@ rpmdrivingschool.com.au, 1
 rprevost.fr, 1
 rpus.co, 1
 rpy.xyz, 1
 rq-labo.jp, 1
 rraesthetics.com, 1
 rrbts.com, 1
 rrdesignsuisse.com, 1
 rrg-partner.ch, 1
-rring.me, 1
 rritv.com, 1
 rro.rs, 1
 rrssww.space, 1
 rrudnik.com, 1
 rrwolfe.com, 1
 rs-cloud.ddns.net, 1
 rs-devdemo.host, 1
 rs-maschinenverleih.de, 1
@@ -40700,17 +40658,16 @@ rteinternational.ie, 1
 rtejr.ie, 1
 rtek.se, 1
 rtenews.eu, 1
 rteone.ie, 1
 rteplayer.com, 1
 rtesport.eu, 1
 rteworld.com, 1
 rths.tk, 0
-rthsoftware.cn, 1
 rthsoftware.net, 0
 rtrappman.com, 1
 rtrinflatables.co.uk, 1
 rtsak.com, 1
 rtsr.ch, 1
 rttss.com, 1
 rttvvip.com, 1
 rtwcourse.com, 1
@@ -40740,17 +40697,16 @@ rubyquincunx.com, 1
 rubyquincunx.org, 1
 rubytune.com, 1
 rucksack-rauf-und-weg.de, 1
 ruckzuck-privatpatient.de, 1
 rucnerobene.eu, 1
 ruconsole.com, 1
 rud.is, 1
 rudd-o.com, 1
-rudelune.fr, 1
 rudewiki.com, 1
 rudhaulidirectory.com, 1
 rudloff.pro, 1
 rudnikas.com, 1
 rudolph.life, 1
 rudolphmarketing.com, 1
 rudrastyh.com, 1
 ruediger-voigt.eu, 1
@@ -40827,16 +40783,17 @@ rusi-ns.ca, 1
 ruska-modra.cz, 1
 ruskamodra.cz, 1
 ruskod.net, 1
 rusmolotok.ru, 1
 russellupevents.co.uk, 1
 russia.dating, 1
 russiaeconomy.org, 1
 russianorthodoxchurch.co.uk, 1
+russpuss.ru, 1
 russt.me, 1
 rust.mn, 1
 rustable.com, 1
 rustikalwallis.ch, 1
 rustyrambles.com, 1
 rusxakep.com, 1
 rutgerschimmel.nl, 1
 ruthbarrettmusic.com, 1
@@ -41362,16 +41319,17 @@ sarkisozleri.us, 1
 sarkoziadam.hu, 1
 sarndipity.com, 1
 sarny.at, 1
 saro.me, 1
 saronikos.city, 1
 sarpsb.org, 1
 sarumtechnologies.com, 1
 sas-snowboarding.sk, 1
+sasanika.org, 1
 sascha.io, 1
 sascha.is, 1
 saschaeggenberger.ch, 1
 saschaeggenberger.com, 1
 sash.pw, 1
 sashaokun.com, 1
 sashascollections.com, 1
 sasioglu.co.uk, 1
@@ -41548,17 +41506,16 @@ scheemadigital.com, 1
 schefczyk.com, 1
 schefczyk.de, 1
 schefczyk.eu, 1
 schefczyk.net, 1
 scheidtweiler.de, 1
 scheinlichter.de, 1
 schelberts.de, 1
 scheldestromen.nl, 1
-schellevis.net, 1
 schemingmind.com, 1
 schenkes.de, 0
 scherfke.de, 1
 scheuchenstuel.at, 1
 schgroup.com, 1
 schier.info, 1
 schil.li, 1
 schildbach.de, 1
@@ -41567,17 +41524,16 @@ schimmel-test.info, 1
 schippendale.de, 1
 schippers-it.nl, 1
 schizoids.net, 1
 schlachter.ca, 1
 schlaf.guru, 1
 schlafguru.com, 1
 schlagenhauf.info, 1
 schlagma.de, 0
-schlarb.eu, 1
 schlarp.com, 1
 schlechtewitze.com, 1
 schlick.wedding, 1
 schlossereieder.at, 1
 schlossfuchs.de, 1
 schluesseldienst-berlin.de, 1
 schluesseldienst-hannover24.de, 1
 schlueter-software.de, 1
@@ -41907,16 +41863,17 @@ sebastianboegl.de, 1
 sebastiaperis.com, 1
 sebastiensenechal.com, 1
 sebasveeke.nl, 1
 sebepoznani.eu, 1
 seberova.cz, 1
 sebi.cf, 1
 sebi.org, 1
 sebjacobs.com, 1
+sebster.com, 1
 seby.io, 1
 sec-mails.de, 1
 sec-research.com, 1
 sec-wiki.com, 1
 sec.ec, 1
 sec.gd, 1
 sec.gov, 1
 sec.red, 1
@@ -41970,22 +41927,20 @@ secure-graphic.de, 1
 secure-gw.de, 1
 secure-server-hosting.com, 1
 secure.advancepayroll.com.au, 1
 secure.chat, 1
 secure.co.hu, 1
 secure.facebook.com, 0
 securecloudplatform.nl, 1
 securecomms.cz, 1
-securedns.zone, 1
 securedrop.org, 1
 secureesolutions.com, 1
 securefiletransfer.nl, 1
 secureheaders.com, 1
-secureideas.com, 1
 secureim.de, 1
 secureindia.co, 1
 securejabber.me, 1
 securelect-inspection.com, 1
 securemailbox.com, 1
 securemessage.nl, 1
 securemind.ch, 1
 securemy.website, 1
@@ -42124,16 +42079,17 @@ selectel.com, 0
 selectel.ru, 1
 selectionengine.ca, 1
 selectionengine.com, 1
 selectionengine.net, 1
 selectionengine.org, 1
 selectorders.com, 1
 selectsplat.com, 1
 selegiline.com, 1
+selekzo.com, 1
 selent.me, 1
 seleondar.ru, 1
 self-evident.org, 1
 self-xss.info, 1
 selfassess.govt.nz, 1
 selfdestruct.net, 1
 selfhosters.com, 1
 selfici.com, 1
@@ -42208,16 +42164,17 @@ sensavi.ua, 1
 sense.hamburg, 1
 sensebridge.com, 1
 sensebridge.net, 1
 senseict.com.au, 1
 sensepixel.com, 1
 senshudo.tv, 1
 sensoft-int.com, 1
 sensoft-int.net, 1
+sensoft-int.org, 1
 sensor-dream.ru, 1
 sensory-brands.com, 1
 sensound.ml, 1
 sensualism.com, 1
 sentandsecure.com, 1
 sentencing.net, 1
 sentic.info, 1
 sentidosdelatierra.org, 1
@@ -42538,17 +42495,16 @@ shamara.info, 1
 shamariki.ru, 1
 shampoo63.ru, 1
 shan.io, 0
 shan.si, 1
 shanae.nl, 1
 shanahanstrategy.com, 1
 shanetully.com, 1
 shanevandermeer.com, 1
-shanewadleigh.com, 1
 shang-yu.cn, 1
 shankangke.com, 1
 shansing.cn, 1
 shansing.com, 1
 shansing.net, 1
 shansing.space, 1
 shanxiapark.com, 1
 shaobin.wang, 1
@@ -42706,17 +42662,16 @@ shiqi.ca, 1
 shiqi.lol, 1
 shiqi.one, 1
 shiqi.online, 1
 shiqi.se, 1
 shiqi.tv, 1
 shiqi1.com, 1
 shiqishidai.cc, 1
 shiqisifu.cc, 1
-shirakaba-cc.com, 1
 shiroki-k.net, 1
 shirt2go.shop, 1
 shirtsdelivered.com, 1
 shirtsofholland.com, 1
 shishamania.de, 1
 shishkin.us, 1
 shishlik.net, 1
 shitagi-shop.com, 1
@@ -42764,17 +42719,16 @@ shopapi.cz, 1
 shopatkei.com, 1
 shopbakersnook.com, 1
 shopcord.co.uk, 1
 shopcoupon.co.za, 1
 shopcoupons.co.id, 1
 shopcoupons.my, 1
 shopcoupons.ph, 1
 shopcoupons.sg, 1
-shopdongho.com, 1
 shopfinale.com, 1
 shophisway.com, 1
 shopific.co, 1
 shopific.com, 1
 shopifycloud.com, 1
 shopkini.com, 1
 shoplandia.co, 1
 shopperexperts.com, 1
@@ -43971,17 +43925,16 @@ solvingproblems.com.au, 1
 solvops.com, 1
 solymar.co, 1
 somaini.li, 1
 somali-derp.com, 1
 somaliagenda.com, 1
 somaliaonline.com, 1
 somanao.com, 1
 somecrazy.com, 1
-somepills.com, 1
 somersetscr.nhs.uk, 1
 somersetwellbeing.nhs.uk, 1
 somethingsimilar.com, 1
 somethingsketchy.net, 1
 somethingsomething.work, 1
 sommefeldt.com, 1
 somnomedics.eu, 1
 somoshuemul.cl, 1
@@ -44078,16 +44031,17 @@ souki.cz, 1
 soukodou.jp, 1
 soul-source.co.uk, 1
 soulcrazy.org, 1
 soulema.com, 1
 soulike.tech, 1
 soulmate.dating, 1
 soulmating.de, 1
 soulogic.com, 1
+soulsteer.com, 0
 souly.cc, 1
 soumikghosh.com, 1
 soumya.xyz, 1
 soumya92.me, 1
 soundabout.nl, 1
 soundbytemedia.com, 1
 soundeo.com, 1
 soundeo.net, 1
@@ -44372,17 +44326,16 @@ spot-lumiere-led.com, 1
 spot.su, 1
 spotfake.news, 1
 spotlightsrule.com, 1
 spotrebitelskecentrum.sk, 1
 spotsee.io, 1
 spotswoodvet.com, 1
 spottedpenguin.co.uk, 1
 spotterpix.de, 1
-spotty.tech, 1
 spotupload.com, 1
 spotypal.com, 1
 sppin.fr, 1
 spr.id.au, 1
 sprachfreudehoch3.de, 1
 sprax2013.de, 1
 sprayforce.com, 1
 spreadsheetgear.com, 1
@@ -44393,17 +44346,17 @@ spreed.me, 1
 spricknet.de, 1
 springerundpartner.de, 1
 springfieldbricks.com, 1
 springhillmaine.com, 1
 springsoffthegrid.com, 1
 springtxcarpetcleaning.com, 1
 spritmonitor.de, 1
 spritsail.io, 1
-spro.in, 1
+spro.in, 0
 sprock.io, 0
 sproktz.com, 1
 spron.in, 1
 sproutways.com, 1
 sprucecreekclubs.com, 1
 sprucecreekgcc.com, 1
 sprueche-zum-valentinstag.de, 1
 sprueche-zur-geburt.info, 1
@@ -44643,17 +44596,16 @@ starka.st, 1
 starkbim.com, 1
 starking.net.cn, 1
 starlim.co.in, 1
 starlim.org, 1
 starmtech.fr, 1
 starpeak.org, 1
 starphotoboothsni.co.uk, 1
 starplatinum.jp, 1
-starport.com.au, 1
 starryvoid.com, 1
 starsam80.net, 1
 starsbattle.net, 1
 starsguru.com, 1
 starsing.bid, 1
 starskim.cn, 1
 startablog.tv, 1
 startaninflatablebusiness.com, 1
@@ -44721,17 +44673,16 @@ stbartholomewmanchester.org, 1
 stbennett.org, 1
 stbl.org, 1
 stbridgeteastfalls.org, 1
 stcatharine-stmargaret.org, 1
 stceciliakearny.org, 1
 stclementmatawan.org, 1
 stclementreligioused.org, 1
 stcplasticsurgery.com, 1
-stcu.org, 0
 std-home-test.com, 1
 stdemianabookstore.org, 1
 stderr.cc, 1
 stdev.org, 1
 stdev.top, 1
 stdrc.cc, 0
 steakovercooked.com, 1
 stealingheather.com, 1
@@ -44874,16 +44825,17 @@ stevenwooding.com, 1
 stevenz.net, 1
 stevenz.science, 1
 stevenz.xyz, 1
 stevereedmp.co.uk, 1
 stevesdrivingschooltyneside.com, 1
 stevezheng.cf, 1
 stevezheng.tk, 1
 stewartswines.com, 1
+stewonet.nl, 1
 stewpolley.com, 0
 steyaert.be, 0
 stforex.com, 0
 stfrancisnaugatuck.org, 1
 stfw.info, 1
 stgabrielavondalepa.org, 1
 stgabrielstowepa.org, 1
 stgeorgecomfortinn.com, 1
@@ -45112,16 +45064,17 @@ striata.com, 1
 striatadev.com, 1
 stricted.net, 1
 strictlyguitar.de, 1
 strictlynormal.com, 1
 strijkshop.be, 1
 stringtoolbox.com, 1
 stringvox.com, 1
 stripe.com, 1
+striped.horse, 1
 strivephysmed.com, 0
 strm.hu, 1
 strming.com, 1
 strobeltobias.de, 1
 strobeto.de, 1
 strobotti.com, 1
 stroccounioncity.org, 1
 stroeder.com, 1
@@ -45325,16 +45278,17 @@ suisui.stream, 1
 suitesapp.com, 1
 suitocracy.com, 1
 sujal.com, 1
 sujatadev.in, 1
 sujoydhar.in, 1
 suka.moe, 1
 suke3.jp, 1
 suki.moe, 1
+suko.pe, 1
 sukoyakapp.com, 1
 sukrie.net, 1
 suksit.com, 1
 sulek.eu, 1
 sullenholland.nl, 1
 suluvir.com, 1
 sumguy.com, 1
 summa.eu, 0
@@ -45381,30 +45335,28 @@ sunfulong.me, 1
 sungreen.info, 1
 sunhaoxiang.net, 1
 sunjaydhama.com, 1
 sunjiutuo.com, 1
 sunlit.cloud, 1
 sunn.ie, 1
 sunnibangla.com, 1
 sunny.co.uk, 1
-sunnysidechurchofchrist.org, 1
 sunoikisis.org, 1
 sunplay.host, 1
 sunred.info, 1
 sunred.org, 1
 sunsetwx.com, 1
 sunshinesf.org, 1
 sunsmartresorts.com, 1
 sunsong.org, 1
 sunstar.bg, 1
 sunwolf.studio, 1
 sunxchina.com, 1
 suool.net, 1
-suourl.com, 1
 supa.sexy, 1
 supastuds.com, 1
 supcoronado.com, 1
 supedi.com, 1
 supedi.de, 1
 supedio.com, 1
 super-erotica.ru, 1
 super-o-blog.com, 1
@@ -45853,17 +45805,16 @@ t4cc0.re, 1
 t5118.com, 1
 t7e.de, 0
 t9i.in, 1
 ta-65.com, 1
 ta65.com, 1
 taabe.net, 1
 taalcursusvolgen.nl, 1
 taartbesteld.nl, 1
-taartenfeesies.nl, 1
 tabarnak.ga, 1
 tabernastudios.pe, 1
 tabi-news.com, 1
 tabi-runrun.com, 1
 tabithawebb.co.uk, 1
 tabledusud.be, 1
 tabledusud.nl, 1
 tablescraps.com, 1
@@ -45874,17 +45825,16 @@ tablotv.com, 0
 taborsky.cz, 1
 tac-volley.com, 1
 tachi.uk, 1
 tachyonapp.com, 1
 tacklinglife.com, 1
 tacomafia.net, 1
 tacostea.net, 1
 tacticalavocado.com, 1
-tacticalsquare.com, 1
 tadata.me, 1
 taddiestales.com, 1
 tadeo.ca, 1
 tadiranbatteries.de, 1
 tadj-mahalat.com, 1
 tadlab.cl, 1
 tadluedtke.com, 1
 tadtadya.com, 1
@@ -46001,16 +45951,17 @@ tanacio.com, 1
 tanak3n.xyz, 0
 tanchynski.com, 1
 tancredi.nl, 1
 tandartszilverschoon.nl, 1
 tandblekningidag.com, 1
 tandem-trade.ru, 0
 tandemexhibits.com, 1
 tandempartnerships.com, 1
+tandk.com.vn, 1
 tandzorg.link, 1
 tangel.me, 1
 tangemann.org, 1
 tangledmeditations.com, 1
 tango-cats.de, 1
 tango-ouest.com, 1
 tangoalpha.co.uk, 1
 tangsisi.com, 1
@@ -46392,16 +46343,17 @@ tekanswer.com, 1
 teknemodus.com.au, 1
 teknik.io, 1
 tekniksnack.se, 1
 tekniskakustik.se, 1
 tekno.de, 1
 teknoforums.com, 1
 teknogeek.id, 1
 teknoroit.com, 1
+tekstschrijvers.net, 1
 tektuts.com, 1
 telamon.eu, 1
 telamon.fr, 1
 telco.at, 1
 tele-alarme.ch, 1
 tele-assistance.ch, 1
 tele-online.com, 1
 telealarme.ch, 1
@@ -46418,17 +46370,16 @@ telefoncek.si, 1
 telefonkonferenz.ch, 1
 telefonni-ustredna.cz, 1
 telefonseelsorge-paderborn.de, 1
 telefoon.nl, 1
 telefoonabonnement.nl, 1
 telegenisys.com, 1
 telegra.ph, 1
 telegram.org, 1
-telegramdr.com, 1
 telehealthventures.com, 0
 telekollektiv.org, 1
 telekothonbd.com, 1
 telemessage.com, 1
 telemovi.com, 1
 teleogistic.net, 1
 telepass.me, 1
 telephonedirectories.us, 1
@@ -46613,17 +46564,17 @@ text-shirt.com, 1
 textbrawlers.com, 1
 textburst.com, 1
 texter-linz.at, 1
 texter.at, 1
 texterseo.at, 1
 texterseo.de, 1
 textinmate.com, 1
 textpattern.com, 1
-textualapp.com, 0
+textualapp.com, 1
 textundblog.de, 1
 texture.net.au, 1
 texus.me, 1
 texy.info, 1
 teysens.com, 1
 teyssedre.ca, 1
 tezcam.tk, 1
 tf2b.com, 1
@@ -47108,17 +47059,16 @@ thesteins.org, 0
 thestoneage.de, 1
 thestory.ie, 1
 thestoryshack.com, 1
 thestral.pro, 1
 thestralbot.com, 1
 thestrategyagency.com.au, 1
 thestreamable.com, 1
 thestudyla.com, 1
-thestyle.city, 1
 thestyleforme.com, 1
 thesuppercircle.com, 1
 theswissbay.ch, 1
 thetapirsmouth.com, 1
 thetassos.com, 1
 theteacherscorner.net, 1
 thetechbasket.com, 1
 thetenscrolls.com, 1
@@ -47193,17 +47143,17 @@ thietbithoathiem.net, 1
 thijmenmathijs.nl, 1
 thijsbekke.nl, 1
 thijsslop.nl, 1
 thijsvanderveen.net, 1
 thinegen.de, 1
 thing.vn, 1
 thing4everyone.com, 1
 thingies.site, 1
-thingsimplied.com, 1
+thingsimplied.com, 0
 thingsof.org, 1
 think-asia.org, 1
 think-pink.info, 1
 think-positive-watches.de, 1
 thinkcash.nl, 1
 thinkheaddesign.com, 1
 thinkindifferent.net, 1
 thinkingandcomputing.com, 1
@@ -47359,17 +47309,17 @@ tibicinagarricola.com, 1
 tibipg.com, 1
 tibovanheule.site, 1
 tibovanheule.space, 1
 ticfleet.com, 1
 tichieru.pw, 1
 ticketassist.nl, 1
 ticketcity.com, 1
 ticketdriver.com, 1
-ticketmaze.com, 0
+ticketmaze.com, 1
 ticketpro.ca, 0
 ticketrunway.com, 1
 ticketslover.com, 1
 ticketsmate.com, 1
 ticketsource.co.uk, 1
 ticketsource.eu, 1
 ticketsource.io, 1
 ticketsource.us, 1
@@ -47621,17 +47571,17 @@ tmd.cool, 1
 tmdb.biz, 1
 tmdc.ddns.net, 1
 tmf.ru, 1
 tmhr.moe, 1
 tmi-products.eu, 1
 tmi-produkter.se, 1
 tmin.cf, 1
 tmm.cx, 1
-tmonitoring.com, 0
+tmonitoring.com, 1
 tmpraider.net, 1
 tmpsantos.com.br, 1
 tmsdiesel.com, 1
 tmtopup.com, 1
 tn0.club, 1
 tnb-plattform.de, 1
 tndentalwellness.com, 1
 tnes.dk, 1
@@ -47779,17 +47729,16 @@ tomasjacik.cz, 1
 tomaskavalek.cz, 0
 tomaspatera.cz, 1
 tomasvecera.cz, 1
 tomasz.com, 1
 tomatenaufdenaugen.de, 1
 tomatis-nantes.com, 1
 tombaker.me, 1
 tomberek.info, 1
-tombroker.org, 1
 tombrossman.com, 1
 tomd.ai, 1
 tomend.es, 1
 tomershemesh.me, 1
 tomfisher.eu, 1
 tomharling.co.uk, 1
 tomharling.uk, 1
 tomharris.tech, 1
@@ -48025,17 +47974,16 @@ totalaccessnicaragua.co, 1
 totalcarcheck.co.uk, 1
 totalchecklist.com, 1
 totalclean.co.uk, 1
 totalemaildelivery.com, 1
 totalforcegym.com, 1
 totalhomecareinc.com, 1
 totallylegitimatehosting.ru, 1
 totallynotaserver.com, 1
-totalpackers.com, 1
 totalpahire.com, 1
 totalparts.com.au, 1
 totalprint.hu, 1
 totalsport-bg.com, 1
 totaltriathlon.com, 1
 totalwebmedia.nl, 1
 totch.de, 1
 totem-international.com, 1
@@ -49022,16 +48970,17 @@ ukas.com, 0
 ukchemicalresearch.org, 0
 ukclimbing.com, 1
 ukdefencejournal.org.uk, 1
 ukhas.net, 1
 ukhillwalking.com, 1
 ukkeyholdingcompany.co.uk, 1
 ukmeetandgreet.com, 1
 ukmortgagecompare.co.uk, 1
+ukne.cn, 0
 ukooku.com, 1
 ukozliku.cz, 1
 ukpirate.org, 1
 ukrainians.ch, 1
 ukrigging.net, 1
 ukrn.io, 1
 ukrnet.co.uk, 1
 uktw.co.uk, 1
@@ -49208,16 +49157,17 @@ uniteasia.org, 1
 united-coders.com, 1
 united-german-commander.de, 1
 united-schools.net, 1
 united.com, 0
 unitedadmins.com, 1
 unitedcyberdevelopment.com, 1
 unitedkingdoms-guild.com, 1
 unitedpsychological.com, 1
+unitedstreamers.de, 1
 unitel2000.de, 1
 unityconsciousnessbooks.com, 1
 univate.berlin, 1
 univercite.ch, 1
 univeril.com, 0
 univerkeys.com, 1
 univerpack.net, 1
 universal-happiness.com, 1
@@ -49347,17 +49297,17 @@ uradisam.rs, 1
 uraimo.com, 1
 uraniborg.net, 1
 uranius.eu, 1
 urbackups.com, 1
 urbalex.ch, 1
 urban-culture.fr, 1
 urban.melbourne, 1
 urbancreators.dk, 1
-urbandance.club, 0
+urbandance.club, 1
 urbane-london.com, 1
 urbanesecurity.com, 1
 urbanfi.sh, 1
 urbanguerillas.de, 1
 urbangymfirenze.com, 1
 urbanhotbed.eu, 1
 urbanietz-immobilien.de, 1
 urbanmelbourne.info, 1
@@ -49804,17 +49754,16 @@ vecerkaracing.cz, 1
 vecozo.nl, 1
 vectortrack.com.au, 1
 vectorwish.com, 1
 vectro.me, 1
 vedma-praktik.com, 1
 veg-leiden.nl, 1
 vegalitarian.org, 1
 vegane-proteine.com, 1
-veganforum.org, 0
 vegangaymer.blog, 1
 veganism.co.uk, 1
 veganism.com, 1
 veganmasterrace.com, 1
 vegasluxuryestates.com, 1
 vegavio.com, 1
 vegekoszyk.pl, 1
 vegepa.com, 1
@@ -49894,17 +49843,16 @@ vergessen.cn, 1
 verhovs.ky, 0
 veri2.com, 1
 verifalia.com, 1
 verifiedjoseph.com, 1
 verifiny.com, 1
 verifyos.com, 1
 veriny.tf, 1
 veriomed.com, 1
-verios.com.br, 1
 veritafineviolins.com, 1
 veritas-data.de, 1
 veritasinvestmentwealth.com, 1
 verizonconnect.com, 0
 verizonguidelines.com, 1
 verkeersschoolrichardschut.nl, 1
 verlagdrkovac.de, 1
 verliefde-jongens.nl, 1
@@ -50049,16 +49997,17 @@ victornet.de, 1
 victoroilpress.com, 1
 victorricemill.com, 1
 victory.radio, 1
 victoryalliance.us, 1
 victorzambrano.com, 1
 vicugna.nl, 1
 vicyu.com, 1
 vid-immobilien.de, 1
+vid.me, 0
 vida-it.com, 1
 vida.es, 1
 vidadu.com, 1
 vidb.me, 1
 vidbooster.com, 1
 vide-dressing.org, 0
 vide-greniers.org, 0
 vide-maisons.org, 0
@@ -50245,17 +50194,16 @@ virtualspeech.com, 1
 virtualvaults.com, 1
 virtubox.net, 1
 virtuebags.com, 1
 virtus-group.com, 1
 virtusaero.com, 1
 virus.pm, 1
 virvum.ch, 1
 visadaifu.com, 1
-visaexpert.co.za, 1
 visalist.io, 1
 visalogy.com, 1
 visaop.com, 1
 visapourailleurs.fr, 1
 visasofoz.com, 1
 visaya.com.co, 1
 viscopic.com, 1
 viseum.co.uk, 1
@@ -50439,16 +50387,17 @@ voids.org, 1
 voidshift.com, 1
 voidx.top, 1
 voidzehn.com, 1
 voipdigit.nl, 1
 voipsun.com, 1
 vojtechpavelka.cz, 1
 vokativy.cz, 1
 vokeapp.com, 1
+vokurka.net, 1
 volatimer.com, 1
 volcain.io, 1
 volcanconcretos.com, 1
 volcano-kazan.ru, 1
 volcano-spb.ru, 1
 volcano-vts.ru, 1
 volcano24.ru, 1
 volcanov.ru, 1
@@ -50503,17 +50452,16 @@ voss-klinik.com, 1
 vosselaer.com, 1
 vossenack.nrw, 1
 vosser.de, 1
 vostronet.com, 1
 voter-info.uk, 1
 votesandymurman.com, 1
 votewa.gov, 1
 votocek.cz, 1
-votockova.cz, 1
 votoot.com, 1
 votresiteweb.ch, 1
 vouchinsurance.sg, 1
 vovladikavkaze.ru, 1
 vow.vn, 1
 vowsy.club, 0
 voxfilmeonline.net, 1
 voxml.com, 1
@@ -50561,26 +50509,24 @@ vroedvrouwella.be, 1
 vroyaltours.com, 1
 vrtak-cz.net, 1
 vrtouring.org, 1
 vrzl.pro, 1
 vsamsonov.com, 1
 vscale.io, 1
 vsd.sk, 1
 vsean.net, 1
-vseomedia.com, 1
 vserver-preis-vergleich.de, 1
 vsesrazu-raiffeisen.ru, 1
 vsestoki.com, 1
 vsl-defi.ch, 1
 vsl.de, 1
 vsoy.co.th, 1
 vssnederland.nl, 1
 vstehn.ru, 1
-vsund.de, 1
 vtaxi.se, 1
 vtipe-vylez.cz, 1
 vtt-hautsdefrance.fr, 1
 vtuber-schedule.info, 1
 vtuber.art, 1
 vuakhuyenmai.vn, 1
 vuasinhly.com, 1
 vuatruyen.com, 1
@@ -50980,17 +50926,16 @@ weather.gov, 1
 weathermyway.rocks, 1
 web-advisor.co.uk, 1
 web-apps.tech, 1
 web-art.cz, 1
 web-demarche.com, 1
 web-design.co.il, 1
 web-fox23.ru, 1
 web-hotel.gr, 1
-web-jive.com, 1
 web-kouza.com, 1
 web-mail.info, 1
 web-odyssey.com, 1
 web-redacteuren.nl, 1
 web-siena.it, 1
 web-smart.com, 1
 web-thinker.ru, 1
 web-wave.jp, 1
@@ -51014,17 +50959,16 @@ webandsun.com, 1
 webapky.cz, 1
 webappky.cz, 1
 webart-factory.de, 1
 webartex.ru, 1
 webbhuset.se, 0
 webbiz.co.uk, 1
 webbson.net, 0
 webcamtoy.com, 1
-webcasinos.com, 1
 webcatchers.nl, 0
 webcatechism.com, 0
 webclimbers.ch, 1
 webcollect.org.uk, 1
 webcontentspinning.com, 1
 webcookies.org, 1
 webcrm.com, 1
 webcurtaincall.com, 1
@@ -51410,17 +51354,16 @@ westside-pediatrics.com, 1
 westsuburbanbank.com, 1
 westthorntonlabour.co.uk, 1
 westtulsa.com, 1
 wesupportthebadge.org, 1
 weswitch4u.com, 1
 wetofu.top, 1
 wetrepublic.com, 1
 wettbonus.eu, 1
-wette.de, 1
 wetten.eu, 0
 wetthost.com, 1
 wevenues.com, 1
 wevg.org, 1
 wew881.com, 1
 wew882.com, 1
 wewin88.com, 1
 wewin88.net, 1
@@ -51550,16 +51493,17 @@ whitejaguars.com, 1
 whiteknightsafelockinc.com, 1
 whitelabelcashback.nl, 1
 whitelabeltickets.com, 0
 whitepack.ru, 1
 whitepharmacy.co.uk, 1
 whiterose.goip.de, 1
 whiteshadowimperium.com, 1
 whitevpn.cz, 1
+whitewebhosting.co.za, 1
 whitewebhosting.com, 1
 whitewinterwolf.com, 1
 whitkirk.com, 1
 whitkirkartsguild.com, 1
 whitkirkchurch.org.uk, 1
 whittome.com, 1
 whitworth.nyc, 1
 whizdomcenter.com, 1
@@ -52119,18 +52063,16 @@ wp-tao.com, 1
 wp-webagentur.de, 1
 wpac.de, 1
 wpandup.org, 1
 wpbook-pacificmall.work, 1
 wpboot.com, 1
 wpcanban.com, 1
 wpccu-cdn.org, 1
 wpccu.org, 1
-wpcdn.bid, 1
-wpcharged.nz, 1
 wpcheck.io, 1
 wpcs.pro, 1
 wpdublin.com, 1
 wpenhance.com, 1
 wpexplorer.com, 1
 wpfast.net, 1
 wpformation.com, 1
 wpgoblin.com, 1
@@ -52449,16 +52391,17 @@ xb913.com, 1
 xb917.com, 1
 xb925.com, 1
 xb927.com, 1
 xb965.com, 1
 xb983.com, 1
 xbb.hk, 1
 xbb.li, 1
 xbc.nz, 1
+xbertschy.com, 1
 xblau.com, 1
 xboxdownloadthat.com, 1
 xboxlivegoldshop.nl, 1
 xboxonex.shop, 1
 xbpay88.com, 1
 xbrl.online, 1
 xbrlsuccess.appspot.com, 1
 xbt.co, 1
@@ -52495,17 +52438,16 @@ xdty.org, 1
 xecure.zone, 1
 xecureit.com, 1
 xeedbeam.me, 1
 xega.org, 1
 xehost.com, 1
 xeiropraktiki.gr, 1
 xelesante.jp, 1
 xendo.net, 1
-xenolith.eu, 1
 xenomedia.nl, 1
 xenon.cloud, 1
 xenoncloud.net, 1
 xenophile.name, 1
 xenosphere.tk, 1
 xenotropegames.com, 1
 xenoworld.de, 1
 xentho.net, 1
@@ -52571,17 +52513,16 @@ xiecongan.org, 1
 xif.at, 1
 xight.org, 1
 xilef.org, 1
 xilegames.com, 1
 xiliant.com, 0
 xilo.net, 1
 xilou.org, 1
 ximble.com, 1
-ximbo.net, 1
 xin-in.com, 1
 xin-in.net, 1
 xinbo270.com, 1
 xinbo676.com, 1
 xinboyule.com, 0
 xing-in.net, 1
 xing.ml, 1
 xinj.com, 1
@@ -54026,17 +53967,16 @@ zuppy.pm, 1
 zuralski.net, 1
 zurgl.com, 0
 zuviel.space, 1
 zuzumba.es, 1
 zvps.uk, 1
 zvxr.net, 1
 zvz.im, 1
 zwartendijkstalling.nl, 1
-zwembadheeten.nl, 1
 zwergenfeste.ch, 1
 zwerimex.com, 1
 zwierslanguagetraining.nl, 1
 zwk.de, 1
 zwollemag.nl, 1
 zwollemagazine.nl, 1
 zwy.ch, 1
 zwy.me, 0
--- a/services/settings/dumps/blocklists/addons.json
+++ b/services/settings/dumps/blocklists/addons.json
@@ -1,1 +1,1 @@
-{"data":[{"guid":"/^((\\{0913599d-3094-44a7-8cc2-b8467d5afc7c\\})|(\\{7bee7f1b-d8ad-424d-807d-e69e6634988e\\}))$/","prefs":[],"schema":1554898779160,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543462","why":"This add-on violates Mozilla's policies by exfiltrating user data without their consent or control.","name":"Malware exfiltrating user data"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"0d86ba71-7baa-4cb3-b3b8-da4ccdfa36b9","last_modified":1554976164809},{"guid":"/^((\\{9946bf2f-0aef-4040-bc57-cdae2bde196a\\})|(\\{d511784e-d088-4fce-b77c-14c186f08641\\})|(\\{fe59312a-97bd-4ca7-bce3-b0db95b1e251\\}))$/","prefs":[],"schema":1554897771015,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543118","why":"This add-on violates Mozilla's add-on policies by overriding search behavior without user consent or control.","name":"Invert (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"ed01b7e5-73d1-42a6-9fc8-af2d83879854","last_modified":1554898652923},{"guid":"{c75432cb-980d-4e64-98c8-d7947b382a2c}","prefs":[],"schema":1554897109129,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543255","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Concrete Tech"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"7fd0eb9c-9f6c-40ea-ba39-645cafb1d5a0","last_modified":1554897390260},{"guid":"/^((\\{6a99a9ec-f149-4ad3-b644-15e44290d00c\\})|(\\{cd9d1582-13dc-4ce1-9c83-4aaa31c6bc36\\})|(\\{3414a827-ee54-4331-85eb-736a824bb7e0\\}))$/","prefs":[],"schema":1554896836686,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543181","why":"This add-on violates Mozilla's add-on policies by overriding search behavior without users' consent or control.","name":"Drag (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"a4f0ac78-ba85-4b5a-9d1f-f3f2c6ae4f7c","last_modified":1554897104624},{"guid":"/^((\\{4b6e66db-ee0b-4fc3-abe6-b97cb4798faf\\})|(\\{8aff5f41-86f8-40f1-896d-954eae7fb670\\}))$/","prefs":[],"schema":1554817097951,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543049","why":"Search hijacking","name":"Fit"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"8a7efe6b-8670-4714-b4b2-08ce5f202ee7","last_modified":1554818136441},{"guid":"{81425b21-cc8c-42d0-98e8-69844bcb7404}","prefs":[],"schema":1554811583185,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543048","why":"Remote Script Injection","name":"Tech Chip"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"dafcc63d-37e0-42e2-b439-59727cf9de48","last_modified":1554811754967},{"guid":"{d85aa6ef-639b-43a1-8560-ddeb59935d10}","prefs":[],"schema":1554803024628,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1543047","why":"Remote Script Injection","name":"BatchSerialize"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"204b7b05-d8e1-4de3-86f9-fcf95edb40c0","last_modified":1554811583171},{"guid":"/^((\\{bf163ed1-e9f9-4c98-ae4b-8391133472d1\\})|(\\{ec283482-2d66-49b2-9dc5-0d03bcbffe65\\})|(\\{0a19856e-4168-4765-a8ab-a3a34fa88ec1\\})|(\\{e2019dd1-4591-42e2-864a-535a99972b1a\\})|(\\{88a65f0c-f952-41f0-8868-f22fa12597b3\\}))$/","prefs":[],"schema":1554754247858,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540998","why":"Exfiltrating user data to a remote site while masking as a different add-on","name":"More Flash Player Clones"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"ddd97fae-7040-4758-811f-1dd53116e6ab","last_modified":1554755273775},{"guid":"/^((\\{743fc0de-1085-4078-8611-848024989608\\})|(\\{02acc043-f402-4e48-aa15-56ee1364e17c\\})|(\\{1b7892ab-6dbe-49d1-9c71-bbb70458c830\\})|(\\{25b3b5bc-b77a-49d1-ab56-c0e760fe02ff\\})|(\\{2c78aa89-8cdd-4a96-821a-e35628aea2fb\\})|(\\{2f154b99-05c2-4629-b687-f2aa031d9f65\\})|(\\{36df6f78-16c4-42c2-a6b8-9210a2953739\\})|(\\{40ada62f-72a8-46b7-8e50-4153f660ce34\\})|(\\{49f58462-fc24-472c-b85a-4a3dbbf48741\\})|(\\{4a8cb3fd-0400-47b3-a799-9f2964229bfa\\})|(\\{5429f6da-d7fe-4f1b-a85e-6dc721ec0037\\})|(\\{74480b2f-1198-45b3-86b3-ca0778482216\\})|(\\{777f1169-a824-459d-8a2d-ca2ffaf59424\\})|(\\{81e610be-656a-4a71-866d-dd94b5096c60\\})|(\\{81ee3e70-b6e4-44d0-b5c2-94ded26bb5ac\\})|(\\{881c71c1-6800-4e8b-89de-0d14ef67d588\\})|(\\{9b5d7f59-be9c-4f1e-bf0c-31f085c17726\\})|(\\{9eff0ead-25a4-429c-b4b2-280ba3c6f2d9\\})|(\\{ad1b7e87-e260-4aee-a602-ef234743443e\\})|(\\{b54a530a-cacc-4c76-a7c3-feafd4ce0b13\\})|(\\{bd0d7634-770e-4d9f-8309-d264a5fbbfa9\\})|(\\{bdf16cc8-3da6-4317-a1eb-2ab8adce6b66\\})|(\\{bf484a7f-49fd-4681-afa5-8a063d010a14\\})|(\\{c7cf6d86-207b-4231-a96a-bbfdc9fe59aa\\})|(\\{d33f83c2-dbc6-41d2-a8b9-28fdaa96985e\\})|(\\{d71757ee-edc7-44d5-b536-cb0370d7d9f6\\})|(\\{daf86db4-7dd4-47d4-a1d1-7c31f6b9bbe3\\})|(\\{e27060a0-5fb5-4844-b446-d2655d7681fa\\})|(\\{fae0d133-05dd-44e6-88e1-e218ca2b2caf\\})|(\\{fbf69005-55d8-4360-a562-255a8c285fea\\})|(\\{fd6d1b53-89f5-4d91-9234-fb3e1b067c1b\\}))$/","prefs":[],"schema":1554753973658,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540998","why":"Exfiltrating user data to a remote site while masking as a different add-on","name":"Adobe Flash fakes"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"e12a97c7-2c83-4e1c-a2c3-66a653bc6048","last_modified":1554754247845},{"guid":"{ea173fdc-f27a-482a-8a0a-61fd1aa2ee2e}","prefs":[],"schema":1554744706554,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1541005","why":"Masks as a legit add-on and includes a remote script that is against our policies","name":"InterpreterInvocation"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"8742ec6a-2e51-4e94-bc6a-653dac08521b","last_modified":1554753973644},{"guid":"{16768af9-4120-4566-95cf-c4234effa084}","prefs":[],"schema":1554733900697,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540999","why":"This add-on changes the search settings in a way that is not allowed per our policies","name":"Unknown search hijacking add-on"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"3fb0ed8e-6e5d-489e-8c9d-b6f48705a742","last_modified":1554736392840},{"guid":"{35b9640e-ebbb-44b7-85af-d9ec3af3c6a6}","prefs":[],"schema":1554730607333,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540690","why":"Malicious remote script injection","name":"Patagonia Bit"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"0eb3a151-ca6b-4dbb-81b3-c10635660c84","last_modified":1554733900683},{"guid":"{d574e1f8-537d-4b6c-97bb-9f7a138f4d67}","prefs":[],"schema":1554728269766,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540686","why":"Injects remote scripts and masks as a different add-on","name":"DistributedConsumer"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"a158055b-3387-4961-a4a3-a820d9299e15","last_modified":1554730607318},{"guid":"one-search@mozzilla.xpi","prefs":[],"schema":1554666099983,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1542208","why":"The add-on violates Mozilla's add-on policies by overriding search behavior without user consent or control.","name":"One Search"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"1344c583-9593-412f-a565-c6cc96a07c28","last_modified":1554718843138},{"guid":"/^((\\{00b4b65b-79d9-4e92-bc1e-2b926918b91c\\})|(\\{0cb66591-e935-47e4-95c2-3063786f6555\\})|(\\{6cf25884-f86d-4a4e-a924-d95282ce5b71\\})|(\\{22cce9c6-a1de-457f-8938-c981b976b6f4\\})|(\\{89d99d4c-e7c4-4601-91a8-216e597a826b\\})|(\\{998d3ac7-b475-410e-ad3d-2eeb526c1853\\})|(\\{9423e8df-6200-45c0-877a-479c46e91b30\\})|(\\{64937e0b-6e00-4d5f-bf19-190d6614aae2\\})|(\\{91507dc4-c005-4534-80af-d8fbdeac29ed\\})|(\\{a2247e60-7b89-4857-a2fa-0eaee1cad460\\})|(\\{c9c28751-5865-449f-8e45-b3363edf9fb7\\})|(\\{cdfd004f-cddc-4ad7-8e2d-a58457e42b1f\\})|(\\{d3e7f35d-7d9f-4d38-9a2b-1581f6b3e870\\})|(\\{df574ffe-cce0-42db-857b-627cb164a4d4\\})|(\\{e06afe6e-ed52-40f8-82bf-d070a37387fb\\})|(\\{e7e7fb96-cfab-4a5b-85fe-20f621e1bc2e\\})|(\\{e12e5afd-bd1e-43c6-9288-321dc485cb1c\\})|(\\{e92d8545-0396-4808-96de-830c61c0d1b3\\})|(\\{e883b012-1987-4f37-8053-02e59e20c242\\})|(\\{ed3386c6-76c6-4786-a37b-9816d5f2a260\\}))$/","prefs":[],"schema":1554462951082,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1541662","why":"These add-ons violate Mozilla's add-on policies by overriding search preferences without user control or consent.","name":"Search overriding malware"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"a1c376fe-20c5-4da3-9126-3fe95b874dce","last_modified":1554463075420},{"guid":"sourcegraph-for-firefox@sourcegraph.com","prefs":[],"schema":1554375072708,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1541010","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Sourcegraph for Firefox"},"enabled":true,"versionRange":[{"severity":1,"maxVersion":"19.4.2.1038","minVersion":"0"}],"id":"9fde5729-9be6-4955-9627-67742c5ed62a","last_modified":1554395912709},{"guid":"/^((\\{6ab41e83-2a91-4c2a-babb-86107a1d1f75\\})|(\\{d84a9d0d-7a31-459e-b45a-2ad111884d1f\\}))$/","prefs":[],"schema":1554293659259,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1541405","why":"This add-on violates Mozilla's add-on policies by overriding search settings without user control or notice.","name":"PopWin (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"04b2954e-4f83-4557-968e-2139a277bf1c","last_modified":1554301860877},{"guid":"/^((@searchlock-staging-automation)|(@searchlock-automation)|(@searchlock-fx)|(@searchlock-staging)|(jid1-vRJA7N8VwBoiXw@jetpack))$/","prefs":[],"schema":1554293340413,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540868","why":"This add-on violates Mozilla's add-on policies by executing remote code and overriding search preferences.","name":"SearchLock"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"aacb25e1-71c5-4bee-ad16-e39e732210ba","last_modified":1554293606641},{"guid":"{03dfffe0-509f-11e9-aa00-e7e13d49f3de}","prefs":[],"schema":1554290590697,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540113","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Addon (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"9c75fe89-7011-47ad-b213-57f5a81a4c89","last_modified":1554290693618},{"guid":"{e555c358-121b-13fa-bf23-bb57da32d184}","prefs":[],"schema":1554290541557,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540111","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Security (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"1809ea7a-8155-4ae7-8c83-ee7c749d30f5","last_modified":1554290590689},{"guid":"{a9c33302-4c97-11e9-9a9d-af400df725e1}","prefs":[],"schema":1554147700324,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1539514","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Security (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"5b4e4e75-cc96-4ca9-aa9f-6a2d2f6cd96a","last_modified":1554290541548},{"guid":"{a3f765c3-8dde-4467-ad6e-fd70c3333e50}","prefs":[],"schema":1554119395186,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538143","why":"Remote script injection","name":"Angelic Bit"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"93dc42cc-4ff3-460d-a8f2-12f1d947b530","last_modified":1554119427564},{"guid":"{91f77263-866e-4acb-a569-f66ac47889f8}","prefs":[],"schema":1553974898434,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1539226","why":"Remote script injection","name":"Bit Apex"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"c528f48a-9b2c-48ca-8b4a-eac442cc0bd0","last_modified":1554119395177},{"guid":"{2256fabf-19f1-4e12-9951-5d126dd9e928}","prefs":[],"schema":1553899022464,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540086","why":"Search hijacking","name":"Twit"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"7c705f73-9d1d-4ee9-ad11-347d18729adb","last_modified":1553900528324},{"guid":"/^((\\{00f77164-eca9-4353-916d-8ea493a54c8d\\})|(\\{0716b2a5-8181-45b8-b675-915e38903761\\})|(\\{26124967-7e32-4577-b998-7296c68d3eb9\\})|(\\{273052bc-fc67-4fc1-a6fd-e62acc3ddad1\\})|(\\{4b5f53ac-36ac-4018-80cb-f1106f60ef96\\})|(\\{61065f61-51aa-462c-aca0-f1addbfa202b\\})|(\\{63383006-d617-4a00-9ca7-30a6864782ee\\})|(\\{7629c987-59ea-4e2f-bcde-b55646ecd268\\})|(\\{78e8c8fa-32ce-432b-9a40-b615bff7cd96\\})|(\\{8e9c05df-e0f5-479f-abb9-858650cb471e\\})|(\\{947f1ac0-09f2-4016-a345-dad0d2ee8f57\\})|(\\{9b9f8124-47bc-4699-8557-45573995b0af\\})|(\\{ab159932-d1dd-4d16-9332-8302a01e0ced\\})|(\\{b7340504-f6ba-43cb-8bd6-5ead88d29898\\})|(\\{bcb9265f-20fd-4311-a33f-212c2d08043a\\})|(\\{f8701822-2814-4d5d-af01-cf7fde4fd510\\}))$/","prefs":[],"schema":1553898687988,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1539910","why":"Data exfiltration, is not actually a flash player","name":"Adobe Flash Player fakes"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"64fc6369-b504-4920-abab-f2cf3cc5424a","last_modified":1553899022456},{"guid":"/^((\\{7dd03112-82a0-4c82-9957-117dedaac14a\\})|(\\{59fd3cac-1a4d-4f0f-a129-c241b203eb51\\}))$/","prefs":[],"schema":1553897736388,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540287","why":"Search hijacking","name":"Song"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"b32b14f5-0024-48fb-a4b6-1496add1dac0","last_modified":1553898687980},{"guid":"/^((\\{70c2cef0-6cc6-41b8-ad6b-bbd11182a101\\})|(\\{a0366612-376e-47e3-b5fa-b805c7176088\\}))$/","prefs":[],"schema":1553810805293,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1540055","why":"Search hijacking, masking as legit add-on","name":"Pix"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"d78262b0-ecfc-475e-9759-f7319451cb43","last_modified":1553847044919},{"guid":"/^((\\{10f1b84d-79ca-41d0-97f6-abb53cec0765\\})|(\\{7891c029-0071-4534-b7f0-7288f14ee0ad\\}))$/","prefs":[],"schema":1553810612956,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538476","why":"Remote script injection, search hijacking","name":"FX"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"50197dbd-71bc-492f-a0f1-6658ec454df4","last_modified":1553810696456},{"guid":"/^((\\{058769c7-784e-47a9-a2c4-dfd81bbf6c8c\\})|(\\{2a58598a-f951-4fb0-af2b-12fb7482bf33\\}))$/","prefs":[],"schema":1553810234714,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1539910","why":"Keylogger","name":"Fake adobe flash player"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"e1355888-e1cd-4d21-9652-c3000662ed88","last_modified":1553810612947},{"guid":"/^((\\{54c7e57f-8ef0-48d5-92a0-6e95d193a12c\\})|(\\{32d262da-e3cd-4300-aa0b-c284eb4e17bf\\}))$/","prefs":[],"schema":1553802101395,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538536","why":"Search hijacking, masking as legit add-on","name":"TxP"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"fa6c7cdb-e477-4478-8dd4-3e1106be6aa3","last_modified":1553810234705},{"guid":"/^((\\{36261798-4c2a-4206-89cc-6c28932b2e98\\})|(\\{b2b9bb64-78d5-43ca-b0cf-a9ee8460521b\\}))$/","prefs":[],"schema":1553616425198,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538234","why":"Clone of Feedbro with added remote scripts and search hijacking","name":"Feedbro Fake"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"e00b2639-8a4f-427a-80d8-7c4937c58f31","last_modified":1553620435398},{"guid":"new-tab-search@mozzilla.xpi","prefs":[],"schema":1553616311575,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538500","why":"Search hijacking","name":"New Tab Search"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"a4dca16a-9fa1-4b55-899c-0f8d5eda1a57","last_modified":1553616386570},{"guid":"{a9c33302-4c97-11e9-9a9d-af400df725e3}","prefs":[],"schema":1553616259023,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538141","why":"remote code execution","name":"Fake Security add-on"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"0c09f067-6e5f-4ee0-9040-08b4297ebe02","last_modified":1553616311567},{"guid":"{7ab5c514-4ebe-22e9-a925-9b7c7317c373}","prefs":[],"schema":1553548654429,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538266","why":"remote code injection","name":"Eval"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"a1f04f09-f4d5-4875-b4b1-a2c772178e8e","last_modified":1553616158755},{"guid":"{bc919484-f20e-48e2-a7c8-6642e111abce}","prefs":[],"schema":1553519202849,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1538962","why":"Inserting monetization iframes and masking as a legit add-on. Contains patterns for known malicious add-ons.","name":"Pinterest Save Button clone"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"7abbecfb-5512-47d1-ba9b-96d6a61b85ee","last_modified":1553548325261},{"guid":"/^((\\{157cd8f9-48f0-43a1-9bcf-c4316753e087\\})|(\\{157cd8f9-48f0-43a1-9bcf-c4316753e086\\})|(\\{157cd8f9-48f0-43a1-9bcf-c4316753e088\\}))$/","prefs":[],"schema":1553186907495,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1537895","why":"This add-on violates Mozilla's add-on policies by overriding search settings.","name":"SD App (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"e263fbec-7155-442f-aa82-cdf218f9e3d7","last_modified":1553193746700},{"guid":"/^((\\{1c94bc8a-3ac1-12e1-aae7-0b314772229c\\})|(\\{8a22255c-4737-11e9-a86b-0bb66337cb31\\})|(\\{3fab603e-3ee1-1222-a859-5f85a3441216\\}))$/","prefs":[],"schema":1553166786114,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535655","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"'Security' add-ons (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"6cf1b676-f0b8-4fea-8a5f-64957650dc2e","last_modified":1553172061896},{"guid":"{28ac81f1-b04d-448f-94be-1b8cc8fbd58d}","prefs":[],"schema":1553079961735,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1536513","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"UtilsBridge (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"f60b3eec-b8b8-4bd7-8d2b-3f7912c3451f","last_modified":1553080348264},{"guid":"/^((\\{9332d73d-7991-46bf-8b67-6db1a21f0167\\})|(\\{b33715d3-eff8-4186-a252-0af5094b8644\\})|(\\{eb7aff78-6145-4a31-a7f5-f3c353ddb312\\})|(\\{6c5cd693-2919-4458-b776-2ac5b6ab1cb0\\})|(\\{daacefee-aaba-4f10-8d4d-059904d8a153\\})|(\\{94d8d504-838c-4392-9971-cd2f6e21ca21\\})|(\\{6574bb31-c971-454f-b08c-a75bfee00855\\})|(\\{1688ecb0-e382-481f-8c70-541d70bdd2e9\\})|(\\{f7b9f777-7b01-4f73-8eb8-f2ad85d4da1c\\})|(\\{598d7ac6-1789-4573-ae6a-5798ed7f6d83\\})|(\\{c0eb4d03-d18e-40bf-b21b-8237ee1bed76\\})|(\\{d0513185-1f20-4045-a232-f3a4252af379\\})|(\\{9ae8269f-eea1-4097-87fd-b7d2f102184d\\})|(\\{5683f95b-2517-4ca7-9d19-83d7f309b62a\\})|(\\{013d3691-0dd6-471b-bf0d-2750d7406a22\\})|(\\{ae73a262-1a27-4d1d-9be7-4b41a84dfd23\\})|(\\{1d92fc5d-5353-401f-8c5f-373b3b6dae67\\})|(\\{e8a81b54-3728-4a9c-8c63-18ef803ef9be\\})|(\\{d604961b-3a3d-4f60-87ae-35977c10b787\\})|(\\{cbe9b620-fac0-407a-b3be-b0a61b319ef8\\})|(\\{1cdb403e-11c7-421b-9c87-0c0d90263626\\})|(\\{f5fa0bfe-a981-48ff-b809-8faa3126f0bc\\})|(\\{7dc6d0d2-b2f0-4334-979d-6ebeff77785a\\})|(\\{13623b47-de82-4226-85f8-d3ae343e619b\\})|(\\{db7b6ea7-2605-44c7-807b-2419d7eec531\\})|(\\{b9298a4a-acca-446d-aa72-d37f5e1576cd\\})|(\\{2e689bc0-735f-445c-bcc7-2cc495f5eb40\\})|(\\{04acd977-4c2b-4162-af33-8c585bea90c5\\})|(\\{2436dde0-3230-4933-9020-c15b3b9e693b\\})|(\\{dcb556aa-ef6e-4778-9f60-c5ae18a72cfb\\})|(\\{5a24385f-ada4-455d-95ad-62cb6256360d\\})|(\\{97f88a13-5b79-4345-a85e-2560d54f577c\\})|(\\{12f4cde8-7d1c-4a9e-9ef7-431f5ecd53a4\\})|(\\{18a93813-7deb-40cf-b3a6-402369e6d817\\})|(\\{9cee5c92-eb1e-4892-86ff-d2d1c627f5b9\\})|(\\{cb1c544e-d444-4c85-8224-64aa26e82230\\})|(\\{1c3b247f-2ef4-4483-93a6-0a3da7bc3548\\})|(\\{1f6913f2-dead-4f96-bf96-0e64affd46ae\\})|(\\{109adc7d-f308-43a5-aa0e-07ccdc5dad2c\\})|(\\{7170e23c-c706-48a7-919f-c1c22548dbfb\\})|(\\{6aa47f05-1f3f-4798-908a-0ed01b2361e0\\})|(\\{33ef0e7b-15ea-4b08-a779-173731ac20b3\\})|(\\{a0361564-9461-4da0-8ec0-7dc6f418f707\\})|(\\{c12631ed-993a-4c2e-9bf0-37867ae40491\\})|(\\{00b79649-3f0e-4b12-a8f0-376a7b2db716\\})|(\\{89096e44-c8b4-4ce5-aad2-f5bac765f608\\})|(\\{6f4eff89-0e32-42bd-a5c1-354adc8417fd\\})|(\\{482c54ae-e080-4596-bf7c-ae972fdff9a3\\})|(\\{04868575-532f-4b43-9325-7e707c109c25\\})|(\\{042c3065-1291-4409-bae5-8d11f3c268e2\\})|(\\{126e7fc4-bf2d-4467-88b1-f3b17bc10da4\\})|(\\{cea21739-b9ce-46c7-ad3e-3607b1ff6538\\})|(\\{06eea1e7-a8be-4794-8cd5-ed12e5f86161\\})|(\\{50993bc5-011c-4322-b522-41e6f3997163\\})|(\\{219a2146-5d9b-472a-8630-4c96a0994bec\\})|(\\{1db94c2f-d957-4b12-a1dc-903bb28f5ff5\\})|(\\{2f7d887c-7d56-41fa-bf9b-eadf6e500427\\})|(\\{2b16f4ab-a2a9-43fd-8fd6-ad6f354b0d28\\})|(\\{034d2b14-29e6-42ad-b2db-2c31286f3fb7\\})|(\\{77058195-5ae1-440c-8f86-c60a96d12ca9\\})|(\\{8082ff2f-2151-4281-8134-1423e5961ca1\\})|(\\{9fa797e8-d7d4-4851-b7e9-76b61ecf046f\\})|(\\{87178fbe-17a5-4d8d-b5ed-48d17179b101\\})|(\\{f010d9e9-0878-4c83-af45-df966cbe8d26\\})|(\\{2aa8c5cd-18fa-4991-b354-d6f459efeca9\\})|(\\{4021839d-3f4a-4866-94fb-9fa809c5245b\\}))$/","prefs":[],"schema":1553024292304,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535088","why":"This add-on violates Mozilla's add-on policies by exfiltration user data and tracking online activities.","name":"Search overriding malware"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"478d4acd-3c01-4dd5-b784-4e06b69d1c05","last_modified":1553079818962},{"guid":"{781b89d4-fa53-45a1-bea4-151dd4c8b288}","prefs":[],"schema":1553013598703,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535280","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Drop Tech (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"81759002-967e-4856-9f55-61d7c30cdb3b","last_modified":1553013656506},{"guid":"{3b52063a-0683-4de2-b6e1-6192c78b6ba3}","prefs":[],"schema":1553013551744,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1536042","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Project Tech (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"6a7f932a-3911-4884-8cb9-d282d282c0cc","last_modified":1553013598695},{"guid":"{47610aad-982f-4822-93ca-8c27dc96a13b}","prefs":[],"schema":1552938092086,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534773","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Tech Hand (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"12874e4d-28b5-4e98-8c33-b6cf5eb032bf","last_modified":1553013551736},{"guid":"amqp-dwn-all-vd@artur.brown","prefs":[],"schema":1552916969263,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1536052","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Video Downloader Plus (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"a3f5ce2f-d8ef-4dae-9fce-1d7fb69d2b37","last_modified":1552917123606},{"guid":"/^((\\{1d758385-fddd-478e-85a0-13eef59f60e5\\})|(\\{1ec3e92a-fd3c-4e16-82e2-56d44bd7bdf4\\})|(\\{3dadda0d-d67c-4452-9475-246c33198192\\})|(\\{4a48f6a8-c9d6-4ae2-8513-a7e9fe785a56\\})|(\\{4d2da172-b160-42b5-9fea-0ede63e0ab52\\})|(\\{5bcd4feb-ce52-4e6f-9da6-eef2a75a4f70\\})|(\\{5eb45d74-0f46-4269-bc0e-8a2a49d64267\\})|(\\{7e8c27c0-b94c-4026-8068-2d152143f073\\})|(\\{9ede19b2-bb97-4d1c-abab-b1d72e7d4c74\\})|(\\{19abb7a0-fb4d-41ff-97d4-65f1680c1348\\})|(\\{25efbdeb-04fa-4998-a9f8-99c1293c7b7f\\})|(\\{0049a401-f02d-4d16-8b5e-5933e5855a4c\\})|(\\{65b91ca5-cd06-42a6-9637-8ecde3a69fd6\\})|(\\{146ec14e-f623-4cb2-88ed-7d3bb8101090\\})|(\\{790d2797-82f3-4bc3-8759-c00d426bbf2f\\})|(\\{865f42b5-e073-4a36-84b1-47d09096b48b\\})|(\\{90055a5b-45a8-45c1-b0a0-979ab2a9064f\\})|(\\{a4f5c163-7b64-46c4-bfd3-348ecc99873a\\})|(\\{a8c40ee7-a376-417b-8022-40909a10181b\\})|(\\{a1031346-14d3-464f-9e50-c30dfd88ad92\\})|(\\{abd16535-2fa8-4bfd-b84e-ed09c9c60e53\\})|(\\{b5ee8c58-b5e5-4ba0-a899-9a54a2f0e386\\})|(\\{b246bb42-577e-4587-adf2-7274b378b0b4\\})|(\\{bb43765b-fe06-4d50-9802-0c6742b220aa\\})|(\\{bf3f628d-9e52-4727-b940-054c65a5a304\\})|(\\{c6bc710d-8cc8-4224-9287-44ecfa452a81\\})|(\\{c232edce-83c9-4184-9782-22df800f65e2\\})|(\\{c5397be4-b756-45b8-a247-339846fada52\\})|(\\{c6675bc5-f7ea-4a11-8252-1152d3783ae3\\})|(\\{cc6a088b-5a84-4e48-8de8-d2f6be3abae7\\})|(\\{e6c12219-f67e-4ea0-a9c3-2c541febeff1\\})|(\\{eb3a7ef7-a4d0-49a4-8b21-2a91c1758100\\})|(\\{ec34588b-86b4-4de3-a3bf-f4d1d8386475\\})|(\\{f4fd8825-648f-4b63-a499-3fd702d42149\\})|(\\{fc4f31f6-c5ed-4afd-8c19-df96e107ce7d\\})|(\\{fe337ef5-bb69-44bf-82a8-ee5c13406165\\})|(\\{ff285a1c-5672-44c3-890e-6c4f25976b83\\}))$/","prefs":[],"schema":1552908996320,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535421","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Flash Player (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"25f18cc5-6ecc-419f-b093-b79e9f261062","last_modified":1552916969252},{"guid":"{a4491aab-e273-4bc3-b45e-a7b9b9414a5f}","prefs":[],"schema":1552695264438,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534792","why":"Search takeover not according to policies, masking as a different add-on","name":"FFCop"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"d2da9c45-59f8-4257-9d7e-07c4fa5de958","last_modified":1552695747900},{"guid":"/^((\\{0f6b717d-1625-4434-b770-5ae33eb64b16\\})|(\\{6d092be7-0bad-46af-9489-04e4b3988644\\})|(\\{7f6049d6-e8b0-4c42-8028-204d1458ddb6\\})|(\\{12b75028-c038-40bd-be5b-2809b7d18d78\\})|(\\{46f35a01-faaf-4fab-95e6-7dfc8b6d8b73\\})|(\\{55d2c6f7-62fa-4091-988b-7f4c4b3c1bff\\})|(\\{75aeaeec-d415-404d-84ba-bd70bcc5e70c\\})|(\\{76b8cf24-227d-4e2b-af4c-39ec5b47babf\\})|(\\{77b725cc-5d0e-4b82-88f0-ec6961acd697\\})|(\\{90fc8426-06ba-43ab-8110-7478ff86f531\\})|(\\{90fc8426-06ba-43ab-8110-7478ff86f539\\})|(\\{157cd8f9-48f0-43a1-9bcf-c4316753e084\\})|(\\{157cd8f9-48f0-43a1-9bcf-c4316753e085\\})|(\\{201ec7f7-57b1-48dd-945c-b1ea7489195d\\})|(\\{280fc0f5-6dfb-4a3c-92ae-acb2d5352175\\})|(\\{388f6d65-4a1b-43ac-b791-387882c30599\\})|(\\{0575cabd-38f3-4964-bdc3-0141a2f062e9\\})|(\\{927e4189-4f56-437e-a0d4-5e232612b5c7\\})|(\\{7277d7cf-c598-420b-ab6e-ab066e1e2fdd\\})|(\\{67775ec2-c879-438b-9409-89fba7ffc684\\})|(\\{397386d2-bb76-4b69-8121-86fad15c5216\\})|(\\{bd7f03dc-b362-4744-b118-43ab916205f9\\})|(\\{c133fb29-c967-4aec-953a-4974e8cbdb26\\})|(\\{cc94c8a7-efa3-435c-91fe-ca305f70e39d\\})|(\\{cfd2ff68-6579-4448-8a26-561bdb63877c\\})|(\\{d00f0050-a66c-49fc-9236-1498d4d29f67\\})|(\\{daa287a2-5916-413e-9b61-52c00b5aa061\\})|(\\{dcfac76f-2fd2-4477-9a60-22d167cabcb4\\})|(\\{dd1bbcf4-bff3-4f15-8a2c-3d52ce987f70\\})|(\\{ddb546b5-6490-4af5-8813-8e701bc06e26\\})|(\\{ead6848b-4bd6-4f9a-93bd-b8460c6f6973\\})|(\\{eb8f7a97-ffb0-40f1-9321-5ab1de884f1c\\})|(\\{ec3e8a3d-df39-4f84-ab31-dae369a225e4\\})|(\\{ef986f55-2dc9-4e39-8c87-618cf4fe5e69\\})|(\\{f8b4b601-7917-40c1-94ec-8efbbf125a46\\})|(\\{f8bc456c-0fb4-4d5d-a85f-dfeb25459e76\\})|(\\{f0458469-cc09-407e-a891-be8606553341\\})|(\\{fa73622c-8b41-45b8-9d93-6d66e7633765\\})|(@loveroms)|(loveroms-ash1280@jetpack)|(searchdimension@gmail\\.com))$/","prefs":[],"schema":1552655172725,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535402","why":"    This add-on violates Mozilla add-on policies by including abusive search behavior.","name":"Add-ons including abusive search behavior"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"f9cd41dd-9e52-4506-bb58-a31e189f4ab9","last_modified":1552655392045},{"guid":"{b6f5f2d0-1aa3-4e43-b536-6db1b1bf7d1c}","prefs":[],"schema":1552592498693,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535601","why":"This add-on violates Mozilla's add-on policies by exfiltrating user data.","name":"FFcanu (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"5b807d5f-a192-450a-a0b3-98113c4beff1","last_modified":1552655172717},{"guid":"{e19fed8c-637a-42e3-b62a-3a6c4040ded8}","prefs":[],"schema":1552570939014,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535345","why":"This add-on violates Mozilla's add-policies by executing remote code.","name":"Flash Player (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"5027a1c1-e050-434f-ba77-56417bc2d7cf","last_modified":1552589019976},{"guid":"{fb62e856-f09b-4cbc-ba07-642ab55f6cb4}","prefs":[],"schema":1552567880022,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534781","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"EncDNA module (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"ce66baec-1237-481c-87db-ccc1bcf0359d","last_modified":1552567941331},{"guid":"{54fc344c-e8ba-462a-a6d9-9ce1b794ce46}","prefs":[],"schema":1552567837850,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534817","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Flash Player (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"4bec4aaf-dd5b-4754-bd01-461fdc7ea5ca","last_modified":1552567880014},{"guid":"{7b6def45-d585-431a-a479-5bb2badf2506}","prefs":[],"schema":1552567781490,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1535055","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"PredicitionR (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"e9227d28-b627-48b8-8392-e9fb5a00d9b6","last_modified":1552567837842},{"guid":"{6fb28b6b-abf2-4937-af28-340851faa971}","prefs":[],"schema":1552567721181,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534769","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"metamedian (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"ed853ce8-83e0-42b7-8d93-7f48041d4987","last_modified":1552567781482},{"guid":"{ae5b30dd-b29d-4ae6-844b-5d7bfc3d7915}","prefs":[],"schema":1552567676370,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534807","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"Crypto Valuator (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"3cfd9af5-a7d0-49d3-971b-7af5e2eab78f","last_modified":1552567721173},{"guid":"web-private@ext.com","prefs":[],"schema":1552567616148,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534828","why":"This add-on violates Mozilla's add-on policies by overriding search preferences.","name":"Flash Player (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"3d52fe32-71e5-47bd-8eda-d98fa0c489e9","last_modified":1552567676362},{"guid":"/^((ads@firefox\\.pl)|(adsfinland@firefox\\.pl)|(adsfrance@firefox\\.pl)|(dodateknowy@o2\\.pl)|(dodateksuper1@firefox\\.pl)|(dodateksuper2@firefox\\.pl)|(dodateksuper3@firefox\\.pl)|(dodateksuper5@firefox\\.pl)|(dodateksuper6@firefox\\.pl)|(dodateksuper@firefox\\.pl)|(test_b@iext\\.pro)|(\\{697be03c-cdd2-430e-b6cf-0f9b5f0556ee\\})|(\\{c9ced03f-a5cf-4dbf-b5ba-67673e442590\\})|(\\{cbe59f66-a23a-45c1-81ac-d0cbedf9ea4e\\})|(\\{dbf0a186-d41c-40ae-8841-e9d8a6b49d8d\\}))$/","prefs":[],"schema":1552493457658,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534940","why":"This add-on violates Mozilla's add-on policies by using a deceiving name and exfiltrating user data.","name":"Flash Player (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"67025e3b-860c-4680-949f-ec472cd72fae","last_modified":1552567437766},{"guid":"/^((\\{86c18738-11ed-4c16-af92-786aa036c83c\\})|(\\{d0fee16a-f4eb-4dc1-9961-82b913e5943d\\})|(\\{1c4937a1-c678-4607-8665-a16384ee302e\\})|(\\{22caeb02-38a3-415d-b168-64fadccbb4a4\\})|(\\{1c9372e7-5f0e-4541-99cf-dfbf2ab00b01\\})|(\\{9fe66994-8ed1-4317-a20a-1d0544ca062f\\})|(\\{6df222d8-97c7-42bf-9683-1cf8119c1e9e\\})|(\\{4c2dda03-bad0-4160-a8a1-6d089200420e\\})|(\\{7aae7d4f-55b9-42eb-b683-932591265e17\\})|(\\{e6f8ab99-3c96-410c-95d1-267ad48ed3e2\\})|(\\{6d8c5068-d0cb-47a5-af5e-3f23064f4608\\})|(\\{90481f38-d06a-465e-a54c-206bbb1ee9ae\\})|(\\{4b75aeb8-f14a-4ef3-b1ad-09733b40dac3\\})|(\\{3a8ca495-f5ab-4320-b070-4f44266fe3d1\\})|(\\{84f8914f-0dec-48ed-a0fd-4a7712c06793\\})|(\\{aa613fce-603c-41df-bf49-9b09614cebe6\\})|(\\{30314350-199a-4951-9c05-c3537a946492\\})|(\\{a2edce1d-10ab-483d-8c01-5e5fe0c82902\\})|(\\{ec91a3d4-8311-4700-aa15-b3941f21a052\\})|(\\{e9049687-164a-4cf3-be1f-1291cfb0f44a\\})|(\\{2be73925-ebaf-43ca-8b26-bd820887f591\\})|(\\{840eadea-1c68-411f-b4e9-08d9f236385d\\})|(\\{0a89d040-5fb1-46d7-bf81-43b55e83695d\\})|(\\{6a1e76ed-4ac2-4a0c-8beb-43ae63558b36\\})|(\\{1b90c930-e7d7-486a-9085-8b57129489c7\\})|(\\{eab649ca-af76-4de9-95b0-8036e35a66cc\\})|(\\{0628e652-98f4-4e58-9ecb-ad996b061aef\\})|(elfr@geckoaddon\\.org)|(else@geckoaddon\\.org)|(fr_b@iext\\.pro)|(it_b@iext\\.pro)|(sv_b@iext\\.pro)|(no_b1@iext\\.pro)|(fi_b@iext\\.pro)|(au_b@iext\\.pro)|(elfr12@geckoaddon\\.org)|(test@informations\\.to)|(se_pop@informations\\.to)|(it@spongebog\\.funny-ok\\.com)|(it@tsunami\\.funny-ok\\.com)|(fi@spongebog\\.funny-ok\\.com)|(fi@tsunami\\.funny-ok\\.com)|(no@spongebog\\.funny-ok\\.com)|(no@tsunami\\.funny-ok\\.com)|(fr@tsunami\\.funny-ok\\.com)|(fr@spongebog\\.funny-ok\\.com)|(se@tsunami\\.funny-ok\\.com)|(se@spongebog\\.funny-ok\\.com)|(au@spongebog\\.funny-ok\\.com)|(au@tsunami\\.funny-ok\\.com)|(nz@spongebog\\.funny-ok\\.com)|(nz@tsunami\\.funny-ok\\.com)|(gr@spongebog\\.funny-ok\\.com)|(gr@tsunami\\.funny-ok\\.com)|(nz_fnew@tsunami\\.funny-ok\\.com))$/","prefs":[],"schema":1552320039514,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1534103","why":"Stealing cookies, browsing history and other information","name":"Rogue Updater add-ons"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"b57d9505-21bf-4a24-accb-05ceac50dadc","last_modified":1552323475989},{"guid":"{c04d9d7d-1c8c-4eab-a51a-828c47e1b8b7}","prefs":[],"schema":1552246898392,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1533780","why":"This add-on violates Mozilla's add-on policies by executing remote code.","name":"asin (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"2c739daa-ffee-48d9-a825-e53c8fd2bb3c","last_modified":1552300402314},{"guid":"/^((\\{ee2d725e-9726-43ac-8040-60ce9ff2831b\\})|(\\{55417a80-e6f7-4d77-8d73-f59045e5e890\\}))$/","prefs":[],"schema":1551728497880,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1532269","why":"This add-on violates Mozilla's add-on policies by using a deceptive name.","name":"Flash Player (Malware)"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"aca80fb4-760e-4cd4-9fec-649fb38b2947","last_modified":1551794995188},{"guid":"/^((\\{5084f455-bc8f-483c-b145-91245bcbfd64\\})|(\\{bd69d5d0-4b2f-48cb-bab5-dcf1e0f9c63b\\}))$/","prefs":[],"schema":1551398716775,"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1531416","why":"Maliciously collecting form data and cookie modification","name":"Adblock/Adobe Flash fakes"},"enabled":true,"versionRange":[{"severity":3,"maxVersion":"*","minVersion":"0"}],"id":"7718be46-8e84-4bc7-a5a9-4c5de1