Merge mozilla-central to mozilla-inbound r=merge
authorDorel Luca <dluca@mozilla.com>
Thu, 11 Jan 2018 00:05:23 +0200
changeset 450448 02f8ce099ade4c097dab1685c58deacc7608cbed
parent 450447 28f876e75d47e8c2843332e631145b6a1acf0263 (current diff)
parent 450369 4db166f0442dddc5b9011c722d7499501fedf283 (diff)
child 450449 f10263c3babef5f70e1e8fdb9e52c2de15cf22e1
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone59.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 mozilla-inbound r=merge
devtools/client/netmonitor/index.js
devtools/client/styleeditor/test/doc_uncached.css
devtools/client/styleeditor/test/doc_uncached.html
testing/web-platform/meta/MANIFEST.json
toolkit/components/places/tests/unit/default.sqlite
--- a/browser/base/content/newtab/sites.js
+++ b/browser/base/content/newtab/sites.js
@@ -242,21 +242,22 @@ Site.prototype = {
     } catch (e) {}
   },
 
   /**
    * Handles site click events.
    */
   onClick: function Site_onClick(aEvent) {
     let pinned = this.isPinned();
-    let tileIndex = this.cell.index;
     let {button, target} = aEvent;
+    const isLinkClick = target.classList.contains("newtab-link") ||
+      target.parentElement.classList.contains("newtab-link");
 
-    // Only handle primary clicks for the remaining targets
-    if (button == 0) {
+    // Handle primary click for pin and block
+    if (button == 0 && !isLinkClick) {
       aEvent.preventDefault();
       if (target.classList.contains("newtab-control-block")) {
         this.block();
       }
       else if (pinned && target.classList.contains("newtab-control-pin")) {
         this.unpin();
       }
       else if (!pinned && target.classList.contains("newtab-control-pin")) {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -27,16 +27,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
   AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
   AutoCompletePopup: "resource://gre/modules/AutoCompletePopup.jsm",
   BookmarkHTMLUtils: "resource://gre/modules/BookmarkHTMLUtils.jsm",
   BookmarkJSONUtils: "resource://gre/modules/BookmarkJSONUtils.jsm",
   BrowserUITelemetry: "resource:///modules/BrowserUITelemetry.jsm",
   BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
   ContentClick: "resource:///modules/ContentClick.jsm",
   ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
+  CustomizableUI: "resource:///modules/CustomizableUI.jsm",
   DateTimePickerHelper: "resource://gre/modules/DateTimePickerHelper.jsm",
   DirectoryLinksProvider: "resource:///modules/DirectoryLinksProvider.jsm",
   ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
   Feeds: "resource:///modules/Feeds.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
   FileSource: "resource://gre/modules/L10nRegistry.jsm",
   FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
   HybridContentTelemetry: "resource://gre/modules/HybridContentTelemetry.jsm",
@@ -433,16 +434,18 @@ BrowserGlue.prototype = {
         } else if (data == "mock-alerts-service") {
           Object.defineProperty(this, "AlertsService", {
             value: subject.wrappedJSObject
           });
         } else if (data == "places-browser-init-complete") {
           if (this._placesBrowserInitComplete) {
             Services.obs.notifyObservers(null, "places-browser-init-complete");
           }
+        } else if (data == "migrateMatchBucketsPrefForUIVersion60") {
+          this._migrateMatchBucketsPrefForUIVersion60();
         }
         break;
       case "initial-migration-will-import-default-bookmarks":
         this._migrationImportsDefaultBookmarks = true;
         break;
       case "initial-migration-did-import-default-bookmarks":
         this._initPlaces(true);
         break;
@@ -1766,17 +1769,17 @@ BrowserGlue.prototype = {
       if (toolbarIsCustomized || getToolbarFolderCount() > NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE) {
         xulStore.setValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed", "false");
       }
     }
   },
 
   // eslint-disable-next-line complexity
   _migrateUI: function BG__migrateUI() {
-    const UI_VERSION = 59;
+    const UI_VERSION = 60;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
 
     let currentUIVersion;
     if (Services.prefs.prefHasUserValue("browser.migration.version")) {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } else {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
@@ -2251,16 +2254,22 @@ BrowserGlue.prototype = {
             } catch (e) { /* Don't panic if the value is not a valid locale code. */ }
           }
         }
         Services.prefs.clearUserPref(SELECTED_LOCALE_PREF);
         Services.prefs.clearUserPref(MATCHOS_LOCALE_PREF);
       }
     }
 
+    if (currentUIVersion < 60) {
+      // Set whether search suggestions or history results come first in the
+      // urlbar results.
+      this._migrateMatchBucketsPrefForUIVersion60();
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _checkForDefaultBrowser() {
     // Perform default browser checking.
     if (!ShellService) {
       return;
@@ -2332,16 +2341,36 @@ BrowserGlue.prototype = {
                         .add(promptCount);
     } catch (ex) { /* Don't break the default prompt if telemetry is broken. */ }
 
     if (willPrompt) {
       DefaultBrowserCheck.prompt(RecentWindow.getMostRecentBrowserWindow());
     }
   },
 
+  _migrateMatchBucketsPrefForUIVersion60() {
+    let prefName = "browser.urlbar.matchBuckets";
+    let pref = Services.prefs.getCharPref(prefName, "");
+    if (!pref) {
+      // Set the pref based on the search bar's current placement.  If it's
+      // placed (the urlbar and search bar are not unified), then set the pref
+      // (so that history results will come before search suggestions).  If it's
+      // not placed (the urlbar and search bar are unified), then leave the pref
+      // cleared so that UnifiedComplete.js uses the default value (so that
+      // search suggestions will come before history results).
+      if (CustomizableUI.getPlacementOfWidget("search-container")) {
+        Services.prefs.setCharPref(prefName, "general:5,suggestion:Infinity");
+      }
+    }
+    // Else, the pref has already been set.  Normally this pref does not exist.
+    // Either the user customized it, or they were enrolled in the Shield study
+    // in Firefox 57 that effectively already migrated the pref.  Either way,
+    // leave it at its current value.
+  },
+
   // ------------------------------
   // public nsIBrowserGlue members
   // ------------------------------
 
   sanitize: function BG_sanitize(aParentWindow) {
     this._sanitizer.sanitize(aParentWindow);
   },
 
--- a/browser/components/preferences/in-content/search.js
+++ b/browser/components/preferences/in-content/search.js
@@ -10,16 +10,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionSettingsStore",
                                   "resource://gre/modules/ExtensionSettingsStore.jsm");
 
 Preferences.addAll([
   { id: "browser.search.suggest.enabled", type: "bool" },
   { id: "browser.urlbar.suggest.searches", type: "bool" },
   { id: "browser.search.hiddenOneOffs", type: "unichar" },
   { id: "browser.search.widget.inNavBar", type: "bool" },
+  { id: "browser.urlbar.matchBuckets", type: "string" },
 ]);
 
 const ENGINE_FLAVOR = "text/x-moz-search-engine";
 const SEARCH_TYPE = "default_search";
 const SEARCH_KEY = "defaultSearch";
 
 var gEngineView = null;
 
@@ -55,16 +56,57 @@ var gSearchPane = {
       Services.obs.removeObserver(this, "browser-search-engine-modified");
     });
 
     this._initAutocomplete();
 
     let suggestsPref = Preferences.get("browser.search.suggest.enabled");
     suggestsPref.on("change", this.updateSuggestsCheckbox.bind(this));
     this.updateSuggestsCheckbox();
+
+    this._initShowSearchSuggestionsFirst();
+  },
+
+  _initShowSearchSuggestionsFirst() {
+    let pref = Preferences.get("browser.urlbar.matchBuckets");
+    let checkbox =
+      document.getElementById("showSearchSuggestionsFirstCheckbox");
+
+    pref.on("change", () => {
+      this.syncFromShowSearchSuggestionsFirstPref(checkbox, pref);
+    });
+    this._syncFromShowSearchSuggestionsFirstPref(checkbox, pref);
+
+    checkbox.addEventListener("command", () => {
+      this._syncToShowSearchSuggestionsFirstPref(checkbox.checked, pref);
+    });
+  },
+
+  _syncFromShowSearchSuggestionsFirstPref(checkbox, pref) {
+    if (!pref.value) {
+      // The pref is cleared, meaning search suggestions are shown first.
+      checkbox.checked = true;
+      return;
+    }
+    // The pref has a value.  If the first bucket in the pref is search
+    // suggestions, then check the checkbox.
+    let bucketPair = pref.value.split(",")[0];
+    let bucketName = bucketPair.split(":")[0];
+    checkbox.checked = bucketName == "suggestion";
+  },
+
+  _syncToShowSearchSuggestionsFirstPref(checked, pref) {
+    if (checked) {
+      // Show search suggestions first, so clear the pref since that's the
+      // default.
+      pref.reset();
+      return;
+    }
+    // Show history first.
+    pref.value = "general:5,suggestion:Infinity";
   },
 
   updateSuggestsCheckbox() {
     let suggestsPref = Preferences.get("browser.search.suggest.enabled");
     let permanentPB =
       Services.prefs.getBoolPref("browser.privatebrowsing.autostart");
     let urlbarSuggests = document.getElementById("urlBarSuggestion");
     urlbarSuggests.disabled = !suggestsPref.value || permanentPB;
--- a/browser/components/preferences/in-content/search.xul
+++ b/browser/components/preferences/in-content/search.xul
@@ -13,16 +13,18 @@
     <groupbox id="searchbarGroup" data-category="paneSearch">
       <caption><label id="searchbarLabel">&searchBar.label;</label></caption>
       <radiogroup id="searchBarVisibleGroup" aria-labelledby="searchbarLabel" preference="browser.search.widget.inNavBar">
         <radio id="searchBarHiddenRadio" value="false" label="&searchBar.hidden.label;"/>
         <image class="searchBarImage searchBarHiddenImage" role="presentation"/>
         <radio id="searchBarShownRadio" value="true" label="&searchBar.shown.label;"/>
         <image class="searchBarImage searchBarShownImage" role="presentation"/>
       </radiogroup>
+      <checkbox id="showSearchSuggestionsFirstCheckbox"
+                label="&showSearchSuggestionsAboveHistory.label;"/>
     </groupbox>
 
     <!-- Default Search Engine -->
     <groupbox id="defaultEngineGroup" data-category="paneSearch">
       <caption><label>&defaultSearchEngine.label;</label></caption>
       <description>&chooseYourDefaultSearchEngine2.label;</description>
 
       <hbox id="browserDefaultSearchExtensionContent" align="center" hidden="true">
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -62,16 +62,17 @@ skip-if = e10s
 [browser_permissions_urlFieldHidden.js]
 [browser_proxy_backup.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
 [browser_privacypane_4.js]
 [browser_privacypane_5.js]
 [browser_privacypane_8.js]
 [browser_sanitizeOnShutdown_prefLocked.js]
+[browser_searchShowSuggestionsFirst.js]
 [browser_searchsuggestions.js]
 [browser_security-1.js]
 [browser_security-2.js]
 [browser_siteData.js]
 [browser_siteData2.js]
 [browser_siteData3.js]
 [browser_spotlight.js]
 [browser_site_login_exceptions.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_searchShowSuggestionsFirst.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const PREF_NAME = "browser.urlbar.matchBuckets";
+const HISTORY_FIRST_PREF_VALUE = "general:5,suggestion:Infinity";
+const CHECKBOX_ID = "showSearchSuggestionsFirstCheckbox";
+
+// Open preferences with search suggestions shown first (the default).
+add_task(async function openWithSearchSuggestionsShownFirst() {
+  // The pref should be cleared initially so that search suggestions are shown
+  // first (the default).
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
+               "Pref should be cleared initially");
+
+  // Open preferences.  The checkbox should be checked.
+  await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
+  let doc = gBrowser.selectedBrowser.contentDocument;
+  let checkbox = doc.getElementById(CHECKBOX_ID);
+  Assert.equal(checkbox.checked, true, "Checkbox should be checked");
+
+  // Uncheck the checkbox.
+  checkbox.checked = false;
+  checkbox.doCommand();
+
+  // The pref should now be set so that history is shown first.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""),
+               HISTORY_FIRST_PREF_VALUE,
+               "Pref should now be set to show history first");
+
+  gBrowser.removeCurrentTab();
+});
+
+// Open preferences with history shown first.
+add_task(async function openWithHistoryShownFirst() {
+  // Set the pref to show history first.
+  Services.prefs.setCharPref(PREF_NAME, HISTORY_FIRST_PREF_VALUE);
+
+  // Open preferences.  The checkbox should be unchecked.
+  await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
+  let doc = gBrowser.selectedBrowser.contentDocument;
+  let checkbox = doc.getElementById(CHECKBOX_ID);
+  Assert.equal(checkbox.checked, false, "Checkbox should be unchecked");
+
+  // Check the checkbox.
+  checkbox.checked = true;
+  checkbox.doCommand();
+
+  // The pref should now be cleared so that search suggestions are shown first.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
+               "Pref should now be cleared to show search suggestions first");
+
+  gBrowser.removeCurrentTab();
+});
--- a/browser/components/resistfingerprinting/test/browser/browser_navigator.js
+++ b/browser/components/resistfingerprinting/test/browser/browser_navigator.js
@@ -1,24 +1,53 @@
 /**
  * Bug 1333651 - A test case for making sure the navigator object has been
  *   spoofed/disabled correctly.
  */
 
 const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
 
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+  "resource://gre/modules/AppConstants.jsm");
+
 const TEST_PATH = "http://example.net/browser/browser/" +
                   "components/resistfingerprinting/test/browser/";
 
 var spoofedUserAgent;
 
-const SPOOFED_APPNAME        = "Netscape";
-const SPOOFED_APPVERSION     = "5.0 (Windows)";
-const SPOOFED_PLATFORM       = "Win64";
-const SPOOFED_OSCPU          = "Windows NT 6.1; Win64; x64";
+const SPOOFED_APPNAME = "Netscape";
+
+const SPOOFED_APPVERSION = {
+  linux: "5.0 (X11)",
+  win: "5.0 (Windows)",
+  macosx: "5.0 (Macintosh)",
+  android: "5.0 (Android 6.0)",
+  other: "5.0 (X11)",
+};
+const SPOOFED_PLATFORM = {
+  linux: "Linux x86_64",
+  win: "Win64",
+  macosx: "MacIntel",
+  android: "Linux armv7l",
+  other: "Linux x86_64",
+};
+const SPOOFED_OSCPU = {
+  linux: "Linux x86_64",
+  win: "Windows NT 6.1; Win64; x64",
+  macosx: "Intel Mac OS X 10.13",
+  android: "Linux armv7l",
+  other: "Linux x86_64",
+};
+const SPOOFED_UA_OS = {
+  linux: "X11; Linux x86_64",
+  win: "Windows NT 6.1; Win64; x64",
+  macosx: "Macintosh; Intel Mac OS X 10.13",
+  android: "Android 6.0; Mobile",
+  other: "X11; Linux x86_64",
+};
 const SPOOFED_BUILDID        = "20100101";
 const SPOOFED_HW_CONCURRENCY = 2;
 
 const CONST_APPCODENAME = "Mozilla";
 const CONST_PRODUCT     = "Gecko";
 const CONST_PRODUCTSUB  = "20100101";
 const CONST_VENDOR      = "";
 const CONST_VENDORSUB   = "";
@@ -30,22 +59,22 @@ async function testNavigator() {
 
   let result = await ContentTask.spawn(tab.linkedBrowser, null, function() {
     return content.document.getElementById("result").innerHTML;
   });
 
   result = JSON.parse(result);
 
   is(result.appName, SPOOFED_APPNAME, "Navigator.appName is correctly spoofed.");
-  is(result.appVersion, SPOOFED_APPVERSION, "Navigator.appVersion is correctly spoofed.");
-  is(result.platform, SPOOFED_PLATFORM, "Navigator.platform is correctly spoofed.");
+  is(result.appVersion, SPOOFED_APPVERSION[AppConstants.platform], "Navigator.appVersion is correctly spoofed.");
+  is(result.platform, SPOOFED_PLATFORM[AppConstants.platform], "Navigator.platform is correctly spoofed.");
   is(result.userAgent, spoofedUserAgent, "Navigator.userAgent is correctly spoofed.");
   is(result.mimeTypesLength, 0, "Navigator.mimeTypes has a length of 0.");
   is(result.pluginsLength, 0, "Navigator.plugins has a length of 0.");
-  is(result.oscpu, SPOOFED_OSCPU, "Navigator.oscpu is correctly spoofed.");
+  is(result.oscpu, SPOOFED_OSCPU[AppConstants.platform], "Navigator.oscpu is correctly spoofed.");
   is(result.buildID, SPOOFED_BUILDID, "Navigator.buildID is correctly spoofed.");
   is(result.hardwareConcurrency, SPOOFED_HW_CONCURRENCY, "Navigator.hardwareConcurrency is correctly spoofed.");
 
   is(result.appCodeName, CONST_APPCODENAME, "Navigator.appCodeName reports correct constant value.");
   is(result.product, CONST_PRODUCT, "Navigator.product reports correct constant value.");
   is(result.productSub, CONST_PRODUCTSUB, "Navigator.productSub reports correct constant value.");
   is(result.vendor, CONST_VENDOR, "Navigator.vendor reports correct constant value.");
   is(result.vendorSub, CONST_VENDORSUB, "Navigator.vendorSub reports correct constant value.");
@@ -68,35 +97,35 @@ async function testWorkerNavigator() {
     });
 
     return res;
   });
 
   result = JSON.parse(result);
 
   is(result.appName, SPOOFED_APPNAME, "Navigator.appName is correctly spoofed.");
-  is(result.appVersion, SPOOFED_APPVERSION, "Navigator.appVersion is correctly spoofed.");
-  is(result.platform, SPOOFED_PLATFORM, "Navigator.platform is correctly spoofed.");
+  is(result.appVersion, SPOOFED_APPVERSION[AppConstants.platform], "Navigator.appVersion is correctly spoofed.");
+  is(result.platform, SPOOFED_PLATFORM[AppConstants.platform], "Navigator.platform is correctly spoofed.");
   is(result.userAgent, spoofedUserAgent, "Navigator.userAgent is correctly spoofed.");
   is(result.hardwareConcurrency, SPOOFED_HW_CONCURRENCY, "Navigator.hardwareConcurrency is correctly spoofed.");
 
   is(result.appCodeName, CONST_APPCODENAME, "Navigator.appCodeName reports correct constant value.");
   is(result.product, CONST_PRODUCT, "Navigator.product reports correct constant value.");
 
   await BrowserTestUtils.removeTab(tab);
 }
 
 add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({"set":
     [["privacy.resistFingerprinting", true]]
   });
 
   let appVersion = parseInt(Services.appinfo.version);
   let spoofedVersion = appVersion - ((appVersion - 3) % 7);
-  spoofedUserAgent = `Mozilla/5.0 (${SPOOFED_OSCPU}; rv:${spoofedVersion}.0) Gecko/20100101 Firefox/${spoofedVersion}.0`;
+  spoofedUserAgent = `Mozilla/5.0 (${SPOOFED_UA_OS[AppConstants.platform]}; rv:${spoofedVersion}.0) Gecko/20100101 Firefox/${spoofedVersion}.0`;
 });
 
 add_task(async function runNavigatorTest() {
   await testNavigator();
 });
 
 add_task(async function runWorkerNavigatorTest() {
   await testWorkerNavigator();
--- a/browser/components/tests/browser/browser.ini
+++ b/browser/components/tests/browser/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 
 [browser_bug538331.js]
 skip-if = !updater
 reason = test depends on update channel
 [browser_contentpermissionprompt.js]
 [browser_default_bookmark_toolbar_visibility.js]
+[browser_urlbar_matchBuckets_migration59.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/browser/browser_urlbar_matchBuckets_migration59.js
@@ -0,0 +1,100 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Makes sure the browser.urlbar.matchBuckets pref is set correctly starting in
+// Firefox 59 (nsBrowserGlue UI version 60).
+
+const SEARCHBAR_WIDGET_ID = "search-container";
+const PREF_NAME = "browser.urlbar.matchBuckets";
+const SEARCHBAR_PRESENT_PREF_VALUE = "general:5,suggestion:Infinity";
+
+add_task(async function test() {
+  // Initial checks.
+  Assert.equal(CustomizableUI.getPlacementOfWidget(SEARCHBAR_WIDGET_ID), null,
+               "Searchbar should not be placed initially");
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
+               "Pref should be cleared initially");
+
+  // Add the searchbar.
+  let widgetPromise = promiseWidget("onWidgetAdded");
+  CustomizableUI.addWidgetToArea(SEARCHBAR_WIDGET_ID,
+                                 CustomizableUI.AREA_NAVBAR);
+  info("Waiting for searchbar to be added");
+  await widgetPromise;
+
+  // Force nsBrowserGlue to attempt update the pref again via UI version
+  // migration.  It shouldn't actually though since the UI version has already
+  // been migrated.  If it erroneously does, then the matchBuckets pref will be
+  // set since the searchbar is now placed.
+  messageBrowserGlue("force-ui-migration");
+
+  // The pref should remain cleared since the migration already happened even
+  // though the searchbar is now present.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
+               "Pref should remain cleared even though searchbar present");
+
+  // Force nsBrowserGlue to update the pref.
+  forceBrowserGlueUpdatePref();
+
+  // The pref should be set since the searchbar is present.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""),
+               SEARCHBAR_PRESENT_PREF_VALUE,
+               "Pref should be set to show history first");
+
+  // Set the pref to something custom.
+  let customValue = "test:Infinity";
+  Services.prefs.setCharPref(PREF_NAME, customValue);
+
+  // Force nsBrowserGlue to update the pref again.
+  forceBrowserGlueUpdatePref();
+
+  // The pref should remain the custom value.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), customValue,
+               "Pref should remain the custom value");
+
+  // Remove the searchbar.
+  widgetPromise = promiseWidget("onWidgetRemoved");
+  CustomizableUI.removeWidgetFromArea(SEARCHBAR_WIDGET_ID);
+  info("Waiting for searchbar to be removed");
+  await widgetPromise;
+
+  // Force nsBrowserGlue to update the pref again.
+  forceBrowserGlueUpdatePref();
+
+  // The pref should remain the custom value.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), customValue,
+               "Pref should remain the custom value");
+
+  // Clear the pref.
+  Services.prefs.clearUserPref(PREF_NAME);
+
+  // Force nsBrowserGlue to update the pref again.
+  forceBrowserGlueUpdatePref();
+
+  // The pref should remain cleared since the searchbar isn't placed.
+  Assert.equal(Services.prefs.getCharPref(PREF_NAME, ""), "",
+               "Pref should remain cleared");
+});
+
+function promiseWidget(observerName) {
+  return new Promise(resolve => {
+    let listener = {};
+    listener[observerName] = widgetID => {
+      if (widgetID == SEARCHBAR_WIDGET_ID) {
+        CustomizableUI.removeListener(listener);
+        executeSoon(resolve);
+      }
+    };
+    CustomizableUI.addListener(listener);
+  });
+}
+
+function messageBrowserGlue(msgName) {
+  Cc["@mozilla.org/browser/browserglue;1"]
+    .getService(Ci.nsIObserver)
+    .observe(null, "browser-glue-test", msgName);
+}
+
+function forceBrowserGlueUpdatePref() {
+  messageBrowserGlue("migrateMatchBucketsPrefForUIVersion60");
+}
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -98,17 +98,17 @@ AutofillProfileAutoCompleteSearch.protot
     let {activeInput, activeSection, activeFieldDetail, savedFieldNames} = FormAutofillContent;
     this.forceStop = false;
 
     this.log.debug("startSearch: for", searchString, "with input", activeInput);
 
     let isAddressField = FormAutofillUtils.isAddressField(activeFieldDetail.fieldName);
     let isInputAutofilled = activeFieldDetail.state == FIELD_STATES.AUTO_FILLED;
     let allFieldNames = activeSection.allFieldNames;
-    let filledRecordGUID = activeSection.getFilledRecordGUID();
+    let filledRecordGUID = activeSection.filledRecordGUID;
     let searchPermitted = isAddressField ?
                           FormAutofillUtils.isAutofillAddressesEnabled :
                           FormAutofillUtils.isAutofillCreditCardsEnabled;
     let AutocompleteResult = isAddressField ? AddressResult : CreditCardResult;
 
     ProfileAutocomplete.lastProfileAutoCompleteFocusedInput = activeInput;
     // Fallback to form-history if ...
     //   - specified autofill feature is pref off.
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -26,246 +26,157 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 this.log = null;
 FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
 
 const {FIELD_STATES} = FormAutofillUtils;
 
 class FormAutofillSection {
   constructor(fieldDetails, winUtils) {
-    this.address = {
-      /**
-       * Similar to the `_validDetails` but contains address fields only.
-       */
-      fieldDetails: [],
-      /**
-       * String of the filled address' guid.
-       */
-      filledRecordGUID: null,
-    };
-    this.creditCard = {
-      /**
-       * Similar to the `_validDetails` but contains credit card fields only.
-       */
-      fieldDetails: [],
-      /**
-       * String of the filled creditCard's' guid.
-       */
-      filledRecordGUID: null,
-    };
+    this.fieldDetails = fieldDetails;
+    this.filledRecordGUID = null;
+    this.winUtils = winUtils;
 
     /**
      * Enum for form autofill MANUALLY_MANAGED_STATES values
      */
     this._FIELD_STATE_ENUM = {
       // not themed
       [FIELD_STATES.NORMAL]: null,
       // highlighted
       [FIELD_STATES.AUTO_FILLED]: "-moz-autofill",
       // highlighted && grey color text
       [FIELD_STATES.PREVIEW]: "-moz-autofill-preview",
     };
 
-    this.winUtils = winUtils;
-
-    this.address.fieldDetails = fieldDetails.filter(
-      detail => FormAutofillUtils.isAddressField(detail.fieldName)
-    );
-    if (this.address.fieldDetails.length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD) {
-      log.debug("Ignoring address related fields since the section has only",
-                this.address.fieldDetails.length,
-                "field(s)");
-      this.address.fieldDetails = [];
-    }
-
-    this.creditCard.fieldDetails = fieldDetails.filter(
-      detail => FormAutofillUtils.isCreditCardField(detail.fieldName)
-    );
-    if (!this._isValidCreditCardForm(this.creditCard.fieldDetails)) {
-      log.debug("Invalid credit card section.");
-      this.creditCard.fieldDetails = [];
+    if (!this.isValidSection()) {
+      this.fieldDetails = [];
+      log.debug(`Ignoring ${this.constructor.name} related fields since it is an invalid section`);
     }
 
     this._cacheValue = {
       allFieldNames: null,
-      oneLineStreetAddress: null,
       matchingSelectOption: null,
     };
+  }
 
-    this._validDetails = Array.of(...(this.address.fieldDetails),
-                                  ...(this.creditCard.fieldDetails));
-    log.debug(this._validDetails.length, "valid fields in the section is collected.");
+  /*
+   * Examine the section is a valid section or not based on its fieldDetails or
+   * other information. This method must be overrided.
+   *
+   * @returns {boolean} True for a valid section, otherwise false
+   *
+   */
+  isValidSection() {
+    throw new TypeError("isValidSection method must be overrided");
+  }
+
+  /*
+   * Examine the section is an enabled section type or not based on its
+   * preferences. This method must be overrided.
+   *
+   * @returns {boolean} True for an enabled section type, otherwise false
+   *
+   */
+  isEnabled() {
+    throw new TypeError("isEnabled method must be overrided");
+  }
+
+  /*
+   * Examine the section is createable for storing the profile. This method
+   * must be overrided.
+   *
+   * @param {Object} record The record for examining createable
+   * @returns {boolean} True for the record is createable, otherwise false
+   *
+   */
+  isRecordCreatable(record) {
+    throw new TypeError("isRecordCreatable method must be overrided");
   }
 
-  get validDetails() {
-    return this._validDetails;
+  /**
+   * Override this method if the profile is needed to apply some transformers.
+   *
+   * @param {Object} profile
+   *        A profile should be converted based on the specific requirement.
+   */
+  applyTransformers(profile) {}
+
+  /**
+   * Override this method if the profile is needed to be customized for
+   * previewing values.
+   *
+   * @param {Object} profile
+   *        A profile for pre-processing before previewing values.
+   */
+  preparePreviewProfile(profile) {}
+
+  /**
+   * Override this method if the profile is needed to be customized for filling
+   * values.
+   *
+   * @param {Object} profile
+   *        A profile for pre-processing before filling values.
+   */
+  async prepareFillingProfile(profile) {}
+
+  /*
+   * Override this methid if any data for `createRecord` is needed to be
+   * normailized before submitting the record.
+   *
+   * @param {Object} profile
+   *        A record for normalization.
+   */
+  normalizeCreatingRecord(data) {}
+
+  /*
+   * Override this method if there is any field value needs to compute for a
+   * specific case. Return the original value in the default case.
+   * @param {String} value
+   *        The original field value.
+   * @param {Object} fieldDetail
+   *        A fieldDetail of the related element.
+   * @param {HTMLElement} element
+   *        A element for checking converting value.
+   *
+   * @returns {String}
+   *          A string of the converted value.
+   */
+  computeFillingValue(value, fieldName, element) {
+    return value;
   }
 
   set focusedInput(element) {
     this._focusedDetail = this.getFieldDetailByElement(element);
   }
 
   getFieldDetailByElement(element) {
-    return this._validDetails.find(
+    return this.fieldDetails.find(
       detail => detail.elementWeakRef.get() == element
     );
   }
 
-  _isValidCreditCardForm(fieldDetails) {
-    let ccNumberReason = "";
-    let hasCCNumber = false;
-    let hasExpiryDate = false;
-
-    for (let detail of fieldDetails) {
-      switch (detail.fieldName) {
-        case "cc-number":
-          hasCCNumber = true;
-          ccNumberReason = detail._reason;
-          break;
-        case "cc-exp":
-        case "cc-exp-month":
-        case "cc-exp-year":
-          hasExpiryDate = true;
-          break;
-      }
-    }
-
-    return hasCCNumber && (ccNumberReason == "autocomplete" || hasExpiryDate);
-  }
-
   get allFieldNames() {
     if (!this._cacheValue.allFieldNames) {
-      this._cacheValue.allFieldNames = this._validDetails.map(record => record.fieldName);
+      this._cacheValue.allFieldNames = this.fieldDetails.map(record => record.fieldName);
     }
     return this._cacheValue.allFieldNames;
   }
 
-  _getFieldDetailByName(fieldName) {
-    return this._validDetails.find(detail => detail.fieldName == fieldName);
-  }
-
-  _getTargetSet() {
-    let fieldDetail = this._focusedDetail;
-    if (!fieldDetail) {
-      return null;
-    }
-    if (FormAutofillUtils.isAddressField(fieldDetail.fieldName)) {
-      return this.address;
-    }
-    if (FormAutofillUtils.isCreditCardField(fieldDetail.fieldName)) {
-      return this.creditCard;
-    }
-    return null;
-  }
-
-  _getFieldDetails() {
-    let targetSet = this._getTargetSet();
-    return targetSet ? targetSet.fieldDetails : [];
-  }
-
-  getFilledRecordGUID() {
-    let targetSet = this._getTargetSet();
-    return targetSet ? targetSet.filledRecordGUID : null;
-  }
-
-  _getOneLineStreetAddress(address) {
-    if (!this._cacheValue.oneLineStreetAddress) {
-      this._cacheValue.oneLineStreetAddress = {};
-    }
-    if (!this._cacheValue.oneLineStreetAddress[address]) {
-      this._cacheValue.oneLineStreetAddress[address] = FormAutofillUtils.toOneLineAddress(address);
-    }
-    return this._cacheValue.oneLineStreetAddress[address];
+  getFieldDetailByName(fieldName) {
+    return this.fieldDetails.find(detail => detail.fieldName == fieldName);
   }
 
-  _addressTransformer(profile) {
-    if (profile["street-address"]) {
-      // "-moz-street-address-one-line" is used by the labels in
-      // ProfileAutoCompleteResult.
-      profile["-moz-street-address-one-line"] = this._getOneLineStreetAddress(profile["street-address"]);
-      let streetAddressDetail = this._getFieldDetailByName("street-address");
-      if (streetAddressDetail &&
-          (streetAddressDetail.elementWeakRef.get() instanceof Ci.nsIDOMHTMLInputElement)) {
-        profile["street-address"] = profile["-moz-street-address-one-line"];
-      }
-
-      let waitForConcat = [];
-      for (let f of ["address-line3", "address-line2", "address-line1"]) {
-        waitForConcat.unshift(profile[f]);
-        if (this._getFieldDetailByName(f)) {
-          if (waitForConcat.length > 1) {
-            profile[f] = FormAutofillUtils.toOneLineAddress(waitForConcat);
-          }
-          waitForConcat = [];
-        }
-      }
-    }
-  }
-
-  /**
-   * Replace tel with tel-national if tel violates the input element's
-   * restriction.
-   * @param {Object} profile
-   *        A profile to be converted.
-   */
-  _telTransformer(profile) {
-    if (!profile.tel || !profile["tel-national"]) {
-      return;
-    }
-
-    let detail = this._getFieldDetailByName("tel");
-    if (!detail) {
-      return;
-    }
-
-    let element = detail.elementWeakRef.get();
-    let _pattern;
-    let testPattern = str => {
-      if (!_pattern) {
-        // The pattern has to match the entire value.
-        _pattern = new RegExp("^(?:" + element.pattern + ")$", "u");
-      }
-      return _pattern.test(str);
-    };
-    if (element.pattern) {
-      if (testPattern(profile.tel)) {
-        return;
-      }
-    } else if (element.maxLength) {
-      if (detail._reason == "autocomplete" && profile.tel.length <= element.maxLength) {
-        return;
-      }
-    }
-
-    if (detail._reason != "autocomplete") {
-      // Since we only target people living in US and using en-US websites in
-      // MVP, it makes more sense to fill `tel-national` instead of `tel`
-      // if the field is identified by heuristics and no other clues to
-      // determine which one is better.
-      // TODO: [Bug 1407545] This should be improved once more countries are
-      // supported.
-      profile.tel = profile["tel-national"];
-    } else if (element.pattern) {
-      if (testPattern(profile["tel-national"])) {
-        profile.tel = profile["tel-national"];
-      }
-    } else if (element.maxLength) {
-      if (profile["tel-national"].length <= element.maxLength) {
-        profile.tel = profile["tel-national"];
-      }
-    }
-  }
-
-  _matchSelectOptions(profile) {
+  matchSelectOptions(profile) {
     if (!this._cacheValue.matchingSelectOption) {
       this._cacheValue.matchingSelectOption = new WeakMap();
     }
 
     for (let fieldName in profile) {
-      let fieldDetail = this._getFieldDetailByName(fieldName);
+      let fieldDetail = this.getFieldDetailByName(fieldName);
       if (!fieldDetail) {
         continue;
       }
 
       let element = fieldDetail.elementWeakRef.get();
       if (ChromeUtils.getClassName(element) !== "HTMLSelectElement") {
         continue;
       }
@@ -287,55 +198,19 @@ class FormAutofillSection {
         }
         // Delete the field so the phishing hint won't treat it as a "also fill"
         // field.
         delete profile[fieldName];
       }
     }
   }
 
-  _creditCardExpDateTransformer(profile) {
-    if (!profile["cc-exp"]) {
-      return;
-    }
-
-    let detail = this._getFieldDetailByName("cc-exp");
-    if (!detail) {
-      return;
-    }
-
-    let element = detail.elementWeakRef.get();
-    if (element.tagName != "INPUT" || !element.placeholder) {
-      return;
-    }
-
-    let result,
-      ccExpMonth = profile["cc-exp-month"],
-      ccExpYear = profile["cc-exp-year"],
-      placeholder = element.placeholder;
-
-    result = /(?:[^m]|\b)(m{1,2})\s*([-/\\]*)\s*(y{2,4})(?!y)/i.exec(placeholder);
-    if (result) {
-      profile["cc-exp"] = String(ccExpMonth).padStart(result[1].length, "0") +
-                          result[2] +
-                          String(ccExpYear).substr(-1 * result[3].length);
-      return;
-    }
-
-    result = /(?:[^y]|\b)(y{2,4})\s*([-/\\]*)\s*(m{1,2})(?!m)/i.exec(placeholder);
-    if (result) {
-      profile["cc-exp"] = String(ccExpYear).substr(-1 * result[1].length) +
-                          result[2] +
-                          String(ccExpMonth).padStart(result[3].length, "0");
-    }
-  }
-
-  _adaptFieldMaxLength(profile) {
+  adaptFieldMaxLength(profile) {
     for (let key in profile) {
-      let detail = this._getFieldDetailByName(key);
+      let detail = this.getFieldDetailByName(key);
       if (!detail) {
         continue;
       }
 
       let element = detail.elementWeakRef.get();
       if (!element) {
         continue;
       }
@@ -350,59 +225,39 @@ class FormAutofillSection {
       } else {
         delete profile[key];
       }
     }
   }
 
   getAdaptedProfiles(originalProfiles) {
     for (let profile of originalProfiles) {
-      this._addressTransformer(profile);
-      this._telTransformer(profile);
-      this._matchSelectOptions(profile);
-      this._creditCardExpDateTransformer(profile);
-      this._adaptFieldMaxLength(profile);
+      this.applyTransformers(profile);
     }
     return originalProfiles;
   }
 
   /**
    * Processes form fields that can be autofilled, and populates them with the
    * profile provided by backend.
    *
    * @param {Object} profile
    *        A profile to be filled in.
    */
   async autofillFields(profile) {
     let focusedDetail = this._focusedDetail;
     if (!focusedDetail) {
       throw new Error("No fieldDetail for the focused input.");
     }
-    let targetSet = this._getTargetSet();
-    if (FormAutofillUtils.isCreditCardField(focusedDetail.fieldName)) {
-      // When Master Password is enabled by users, the decryption process
-      // should prompt Master Password dialog to get the decrypted credit
-      // card number. Otherwise, the number can be decrypted with the default
-      // password.
-      if (profile["cc-number-encrypted"]) {
-        let decrypted = await this._decrypt(profile["cc-number-encrypted"], true);
 
-        if (!decrypted) {
-          // Early return if the decrypted is empty or undefined
-          return;
-        }
-
-        profile["cc-number"] = decrypted;
-      }
-    }
-
+    await this.prepareFillingProfile(profile);
     log.debug("profile in autofillFields:", profile);
 
-    targetSet.filledRecordGUID = profile.guid;
-    for (let fieldDetail of targetSet.fieldDetails) {
+    this.filledRecordGUID = profile.guid;
+    for (let fieldDetail of this.fieldDetails) {
       // Avoid filling field value in the following cases:
       // 1. a non-empty input field for an unfocused input
       // 2. the invalid value set
       // 3. value already chosen in select element
 
       let element = fieldDetail.elementWeakRef.get();
       if (!element) {
         continue;
@@ -445,24 +300,19 @@ class FormAutofillSection {
    * Populates result to the preview layers with given profile.
    *
    * @param {Object} profile
    *        A profile to be previewed with
    */
   previewFormFields(profile) {
     log.debug("preview profile: ", profile);
 
-    // Always show the decrypted credit card number when Master Password is
-    // disabled.
-    if (profile["cc-number-decrypted"]) {
-      profile["cc-number"] = profile["cc-number-decrypted"];
-    }
+    this.preparePreviewProfile(profile);
 
-    let fieldDetails = this._getFieldDetails();
-    for (let fieldDetail of fieldDetails) {
+    for (let fieldDetail of this.fieldDetails) {
       let element = fieldDetail.elementWeakRef.get();
       let value = profile[fieldDetail.fieldName] || "";
 
       // Skip the field that is null
       if (!element) {
         continue;
       }
 
@@ -488,18 +338,17 @@ class FormAutofillSection {
   }
 
   /**
    * Clear preview text and background highlight of all fields.
    */
   clearPreviewedFormFields() {
     log.debug("clear previewed fields in:", this.form);
 
-    let fieldDetails = this._getFieldDetails();
-    for (let fieldDetail of fieldDetails) {
+    for (let fieldDetail of this.fieldDetails) {
       let element = fieldDetail.elementWeakRef.get();
       if (!element) {
         log.warn(fieldDetail.fieldName, "is unreachable");
         continue;
       }
 
       element.previewValue = "";
 
@@ -512,18 +361,17 @@ class FormAutofillSection {
       this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
     }
   }
 
   /**
    * Clear value and highlight style of all filled fields.
    */
   clearPopulatedForm() {
-    let fieldDetails = this._getFieldDetails();
-    for (let fieldDetail of fieldDetails) {
+    for (let fieldDetail of this.fieldDetails) {
       let element = fieldDetail.elementWeakRef.get();
       if (!element) {
         log.warn(fieldDetail.fieldName, "is unreachable");
         continue;
       }
 
       // Only reset value for input element.
       if (fieldDetail.state == FIELD_STATES.AUTO_FILLED &&
@@ -582,151 +430,276 @@ class FormAutofillSection {
         break;
       }
     }
 
     fieldDetail.state = nextState;
   }
 
   resetFieldStates() {
-    for (let fieldDetail of this._validDetails) {
+    for (let fieldDetail of this.fieldDetails) {
       const element = fieldDetail.elementWeakRef.get();
       element.removeEventListener("input", this, {mozSystemGroup: true});
       this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
     }
-    this.address.filledRecordGUID = null;
-    this.creditCard.filledRecordGUID = null;
+    this.filledRecordGUID = null;
   }
 
   isFilled() {
-    return !!(this.address.filledRecordGUID || this.creditCard.filledRecordGUID);
+    return !!this.filledRecordGUID;
+  }
+
+  /**
+   * Return the record that is converted from `fieldDetails` and only valid
+   * form record is included.
+   *
+   * @returns {Object|null}
+   *          A record object consists of three properties:
+   *            - guid: The id of the previously-filled profile or null if omitted.
+   *            - record: A valid record converted from details with trimmed result.
+   *            - untouchedFields: Fields that aren't touched after autofilling.
+   *          Return `null` for any uncreatable or invalid record.
+   */
+  createRecord() {
+    let details = this.fieldDetails;
+    if (!this.isEnabled() || !details || details.length == 0) {
+      return null;
+    }
+
+    let data = {
+      guid: this.filledRecordGUID,
+      record: {},
+      untouchedFields: [],
+    };
+
+    details.forEach(detail => {
+      let element = detail.elementWeakRef.get();
+      // Remove the unnecessary spaces
+      let value = element && element.value.trim();
+      value = this.computeFillingValue(value, detail, element);
+
+      if (!value || value.length > FormAutofillUtils.MAX_FIELD_VALUE_LENGTH) {
+        // Keep the property and preserve more information for updating
+        data.record[detail.fieldName] = "";
+        return;
+      }
+
+      data.record[detail.fieldName] = value;
+
+      if (detail.state == FIELD_STATES.AUTO_FILLED) {
+        data.untouchedFields.push(detail.fieldName);
+      }
+    });
+
+    this.normalizeCreatingRecord(data);
+
+    if (!this.isRecordCreatable(data.record)) {
+      return null;
+    }
+
+    return data;
   }
 
-  _isAddressRecordCreatable(record) {
+  handleEvent(event) {
+    switch (event.type) {
+      case "input": {
+        if (!event.isTrusted) {
+          return;
+        }
+        const target = event.target;
+        const targetFieldDetail = this.getFieldDetailByElement(target);
+
+        this._changeFieldState(targetFieldDetail, FIELD_STATES.NORMAL);
+
+        let isAutofilled = false;
+        let dimFieldDetails = [];
+        for (const fieldDetail of this.fieldDetails) {
+          const element = fieldDetail.elementWeakRef.get();
+
+          if (ChromeUtils.getClassName(element) === "HTMLSelectElement") {
+            // Dim fields are those we don't attempt to revert their value
+            // when clear the target set, such as <select>.
+            dimFieldDetails.push(fieldDetail);
+          } else {
+            isAutofilled |= fieldDetail.state == FIELD_STATES.AUTO_FILLED;
+          }
+        }
+        if (!isAutofilled) {
+          // Restore the dim fields to initial state as well once we knew
+          // that user had intention to clear the filled form manually.
+          for (const fieldDetail of dimFieldDetails) {
+            this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
+          }
+          this.filledRecordGUID = null;
+        }
+        break;
+      }
+    }
+  }
+}
+
+class FormAutofillAddressSection extends FormAutofillSection {
+  constructor(fieldDetails, winUtils) {
+    super(fieldDetails, winUtils);
+
+    this._cacheValue.oneLineStreetAddress = null;
+  }
+
+  isValidSection() {
+    return this.fieldDetails.length >= FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD;
+  }
+
+  isEnabled() {
+    return FormAutofillUtils.isAutofillAddressesEnabled;
+  }
+
+  isRecordCreatable(record) {
     let hasName = 0;
     let length = 0;
     for (let key of Object.keys(record)) {
       if (!record[key]) {
         continue;
       }
       if (FormAutofillUtils.getCategoryFromFieldName(key) == "name") {
         hasName = 1;
         continue;
       }
       length++;
     }
     return (length + hasName) >= FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD;
   }
 
-  _isCreditCardRecordCreatable(record) {
-    return record["cc-number"] && FormAutofillUtils.isCCNumber(record["cc-number"]);
+  _getOneLineStreetAddress(address) {
+    if (!this._cacheValue.oneLineStreetAddress) {
+      this._cacheValue.oneLineStreetAddress = {};
+    }
+    if (!this._cacheValue.oneLineStreetAddress[address]) {
+      this._cacheValue.oneLineStreetAddress[address] = FormAutofillUtils.toOneLineAddress(address);
+    }
+    return this._cacheValue.oneLineStreetAddress[address];
+  }
+
+  addressTransformer(profile) {
+    if (profile["street-address"]) {
+      // "-moz-street-address-one-line" is used by the labels in
+      // ProfileAutoCompleteResult.
+      profile["-moz-street-address-one-line"] = this._getOneLineStreetAddress(profile["street-address"]);
+      let streetAddressDetail = this.getFieldDetailByName("street-address");
+      if (streetAddressDetail &&
+          (streetAddressDetail.elementWeakRef.get() instanceof Ci.nsIDOMHTMLInputElement)) {
+        profile["street-address"] = profile["-moz-street-address-one-line"];
+      }
+
+      let waitForConcat = [];
+      for (let f of ["address-line3", "address-line2", "address-line1"]) {
+        waitForConcat.unshift(profile[f]);
+        if (this.getFieldDetailByName(f)) {
+          if (waitForConcat.length > 1) {
+            profile[f] = FormAutofillUtils.toOneLineAddress(waitForConcat);
+          }
+          waitForConcat = [];
+        }
+      }
+    }
   }
 
   /**
-   * Return the records that is converted from address/creditCard fieldDetails and
-   * only valid form records are included.
-   *
-   * @returns {Object}
-   *          Consists of two record objects: address, creditCard. Each one can
-   *          be omitted if there's no valid fields. A record object consists of
-   *          three properties:
-   *            - guid: The id of the previously-filled profile or null if omitted.
-   *            - record: A valid record converted from details with trimmed result.
-   *            - untouchedFields: Fields that aren't touched after autofilling.
+   * Replace tel with tel-national if tel violates the input element's
+   * restriction.
+   * @param {Object} profile
+   *        A profile to be converted.
    */
-  createRecords() {
-    let data = {};
-    let target = [];
+  telTransformer(profile) {
+    if (!profile.tel || !profile["tel-national"]) {
+      return;
+    }
 
-    if (FormAutofillUtils.isAutofillAddressesEnabled) {
-      target.push("address");
-    }
-    if (FormAutofillUtils.isAutofillCreditCardsEnabled) {
-      target.push("creditCard");
+    let detail = this.getFieldDetailByName("tel");
+    if (!detail) {
+      return;
     }
 
-    target.forEach(type => {
-      let details = this[type].fieldDetails;
-      if (!details || details.length == 0) {
+    let element = detail.elementWeakRef.get();
+    let _pattern;
+    let testPattern = str => {
+      if (!_pattern) {
+        // The pattern has to match the entire value.
+        _pattern = new RegExp("^(?:" + element.pattern + ")$", "u");
+      }
+      return _pattern.test(str);
+    };
+    if (element.pattern) {
+      if (testPattern(profile.tel)) {
+        return;
+      }
+    } else if (element.maxLength) {
+      if (detail._reason == "autocomplete" && profile.tel.length <= element.maxLength) {
         return;
       }
-
-      data[type] = {
-        guid: this[type].filledRecordGUID,
-        record: {},
-        untouchedFields: [],
-      };
-
-      details.forEach(detail => {
-        let element = detail.elementWeakRef.get();
-        // Remove the unnecessary spaces
-        let value = element && element.value.trim();
-
-        // Try to abbreviate the value of select element.
-        if (type == "address" &&
-            detail.fieldName == "address-level1" &&
-            ChromeUtils.getClassName(element) === "HTMLSelectElement") {
-          // Don't save the record when the option value is empty *OR* there
-          // are multiple options being selected. The empty option is usually
-          // assumed to be default along with a meaningless text to users.
-          if (!value || element.selectedOptions.length != 1) {
-            // Keep the property and preserve more information for address updating
-            data[type].record[detail.fieldName] = "";
-            return;
-          }
-
-          let text = element.selectedOptions[0].text.trim();
-          value = FormAutofillUtils.getAbbreviatedSubregionName([value, text]) || text;
-        }
-
-        if (!value || value.length > FormAutofillUtils.MAX_FIELD_VALUE_LENGTH) {
-          // Keep the property and preserve more information for updating
-          data[type].record[detail.fieldName] = "";
-          return;
-        }
-
-        data[type].record[detail.fieldName] = value;
-
-        if (detail.state == FIELD_STATES.AUTO_FILLED) {
-          data[type].untouchedFields.push(detail.fieldName);
-        }
-      });
-    });
-
-    this._normalizeAddress(data.address);
-
-    if (data.address && !this._isAddressRecordCreatable(data.address.record)) {
-      log.debug("No address record saving since there are only",
-                Object.keys(data.address.record).length,
-                "usable fields");
-      delete data.address;
     }
 
-    if (data.creditCard && !this._isCreditCardRecordCreatable(data.creditCard.record)) {
-      log.debug("No credit card record saving since card number is invalid");
-      delete data.creditCard;
+    if (detail._reason != "autocomplete") {
+      // Since we only target people living in US and using en-US websites in
+      // MVP, it makes more sense to fill `tel-national` instead of `tel`
+      // if the field is identified by heuristics and no other clues to
+      // determine which one is better.
+      // TODO: [Bug 1407545] This should be improved once more countries are
+      // supported.
+      profile.tel = profile["tel-national"];
+    } else if (element.pattern) {
+      if (testPattern(profile["tel-national"])) {
+        profile.tel = profile["tel-national"];
+      }
+    } else if (element.maxLength) {
+      if (profile["tel-national"].length <= element.maxLength) {
+        profile.tel = profile["tel-national"];
+      }
     }
-
-    // If both address and credit card exists, skip this metrics because it not a
-    // general case and each specific histogram might contains insufficient data set.
-    if (data.address && data.creditCard) {
-      this.timeStartedFillingMS = null;
-    }
-
-    return data;
   }
 
-  _normalizeAddress(address) {
+  /*
+   * Apply all address related transformers.
+   *
+   * @param {Object} profile
+   *        A profile for adjusting address related value.
+   * @override
+   */
+  applyTransformers(profile) {
+    this.addressTransformer(profile);
+    this.telTransformer(profile);
+    this.matchSelectOptions(profile);
+    this.adaptFieldMaxLength(profile);
+  }
+
+  computeFillingValue(value, fieldDetail, element) {
+    // Try to abbreviate the value of select element.
+    if (fieldDetail.fieldName == "address-level1" &&
+      ChromeUtils.getClassName(element) === "HTMLSelectElement") {
+      // Don't save the record when the option value is empty *OR* there
+      // are multiple options being selected. The empty option is usually
+      // assumed to be default along with a meaningless text to users.
+      if (!value || element.selectedOptions.length != 1) {
+        // Keep the property and preserve more information for address updating
+        value = "";
+      } else {
+        let text = element.selectedOptions[0].text.trim();
+        value = FormAutofillUtils.getAbbreviatedSubregionName([value, text]) || text;
+      }
+    }
+    return value;
+  }
+
+  normalizeCreatingRecord(address) {
     if (!address) {
       return;
     }
 
     // Normalize Country
     if (address.record.country) {
-      let detail = this._getFieldDetailByName("country");
+      let detail = this.getFieldDetailByName("country");
       // Try identifying country field aggressively if it doesn't come from
       // @autocomplete.
       if (detail._reason != "autocomplete") {
         let countryCode = FormAutofillUtils.identifyCountryCode(address.record.country);
         if (countryCode) {
           address.record.country = countryCode;
         }
       }
@@ -751,63 +724,149 @@ class FormAutofillSection {
         // (The maximum length of a valid number in E.164 format is 15 digits
         //  according to https://en.wikipedia.org/wiki/E.164 )
         if (!/^(\+?)[\da-zA-Z]{5,15}$/.test(strippedNumber)) {
           address.record.tel = "";
         }
       }
     }
   }
+}
+
+class FormAutofillCreditCardSection extends FormAutofillSection {
+  constructor(fieldDetails, winUtils) {
+    super(fieldDetails, winUtils);
+  }
+
+  isValidSection() {
+    let ccNumberReason = "";
+    let hasCCNumber = false;
+    let hasExpiryDate = false;
+
+    for (let detail of this.fieldDetails) {
+      switch (detail.fieldName) {
+        case "cc-number":
+          hasCCNumber = true;
+          ccNumberReason = detail._reason;
+          break;
+        case "cc-exp":
+        case "cc-exp-month":
+        case "cc-exp-year":
+          hasExpiryDate = true;
+          break;
+      }
+    }
+
+    return hasCCNumber && (ccNumberReason == "autocomplete" || hasExpiryDate);
+  }
+
+  isEnabled() {
+    return FormAutofillUtils.isAutofillCreditCardsEnabled;
+  }
+
+  isRecordCreatable(record) {
+    return record["cc-number"] && FormAutofillUtils.isCCNumber(record["cc-number"]);
+  }
+
+  creditCardExpDateTransformer(profile) {
+    if (!profile["cc-exp"]) {
+      return;
+    }
+
+    let detail = this.getFieldDetailByName("cc-exp");
+    if (!detail) {
+      return;
+    }
+
+    let element = detail.elementWeakRef.get();
+    if (element.tagName != "INPUT" || !element.placeholder) {
+      return;
+    }
+
+    let result,
+      ccExpMonth = profile["cc-exp-month"],
+      ccExpYear = profile["cc-exp-year"],
+      placeholder = element.placeholder;
+
+    result = /(?:[^m]|\b)(m{1,2})\s*([-/\\]*)\s*(y{2,4})(?!y)/i.exec(placeholder);
+    if (result) {
+      profile["cc-exp"] = String(ccExpMonth).padStart(result[1].length, "0") +
+                          result[2] +
+                          String(ccExpYear).substr(-1 * result[3].length);
+      return;
+    }
+
+    result = /(?:[^y]|\b)(y{2,4})\s*([-/\\]*)\s*(m{1,2})(?!m)/i.exec(placeholder);
+    if (result) {
+      profile["cc-exp"] = String(ccExpYear).substr(-1 * result[1].length) +
+                          result[2] +
+                          String(ccExpMonth).padStart(result[3].length, "0");
+    }
+  }
 
   async _decrypt(cipherText, reauth) {
     return new Promise((resolve) => {
       Services.cpmm.addMessageListener("FormAutofill:DecryptedString", function getResult(result) {
         Services.cpmm.removeMessageListener("FormAutofill:DecryptedString", getResult);
         resolve(result.data);
       });
 
       Services.cpmm.sendAsyncMessage("FormAutofill:GetDecryptedString", {cipherText, reauth});
     });
   }
 
-  handleEvent(event) {
-    switch (event.type) {
-      case "input": {
-        if (!event.isTrusted) {
-          return;
-        }
-        const target = event.target;
-        const targetFieldDetail = this.getFieldDetailByElement(target);
-        const targetSet = this._getTargetSet(target);
-
-        this._changeFieldState(targetFieldDetail, FIELD_STATES.NORMAL);
-
-        let isAutofilled = false;
-        let dimFieldDetails = [];
-        for (const fieldDetail of targetSet.fieldDetails) {
-          const element = fieldDetail.elementWeakRef.get();
+  /*
+   * Apply all credit card related transformers.
+   *
+   * @param {Object} profile
+   *        A profile for adjusting credit card related value.
+   * @override
+   */
+  applyTransformers(profile) {
+    this.matchSelectOptions(profile);
+    this.creditCardExpDateTransformer(profile);
+    this.adaptFieldMaxLength(profile);
+  }
 
-          if (ChromeUtils.getClassName(element) === "HTMLSelectElement") {
-            // Dim fields are those we don't attempt to revert their value
-            // when clear the target set, such as <select>.
-            dimFieldDetails.push(fieldDetail);
-          } else {
-            isAutofilled |= fieldDetail.state == FIELD_STATES.AUTO_FILLED;
-          }
-        }
-        if (!isAutofilled) {
-          // Restore the dim fields to initial state as well once we knew
-          // that user had intention to clear the filled form manually.
-          for (const fieldDetail of dimFieldDetails) {
-            this._changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
-          }
-          targetSet.filledRecordGUID = null;
-        }
-        break;
+  /**
+   * Customize for previewing prorifle.
+   *
+   * @param {Object} profile
+   *        A profile for pre-processing before previewing values.
+   * @override
+   */
+  preparePreviewProfile(profile) {
+    // Always show the decrypted credit card number when Master Password is
+    // disabled.
+    if (profile["cc-number-decrypted"]) {
+      profile["cc-number"] = profile["cc-number-decrypted"];
+    }
+  }
+
+  /**
+   * Customize for filling prorifle.
+   *
+   * @param {Object} profile
+   *        A profile for pre-processing before filling values.
+   * @override
+   */
+  async prepareFillingProfile(profile) {
+    // When Master Password is enabled by users, the decryption process
+    // should prompt Master Password dialog to get the decrypted credit
+    // card number. Otherwise, the number can be decrypted with the default
+    // password.
+    if (profile["cc-number-encrypted"]) {
+      let decrypted = await this._decrypt(profile["cc-number-encrypted"], true);
+
+      if (!decrypted) {
+        // Early return if the decrypted is empty or undefined
+        return;
       }
+
+      profile["cc-number"] = decrypted;
     }
   }
 }
 
 /**
  * Handles profile autofill for a DOM Form element.
  */
 class FormAutofillHandler {
@@ -930,20 +989,27 @@ class FormAutofillHandler {
    * @param {boolean} allowDuplicates
    *        true to remain any duplicated field details otherwise to remove the
    *        duplicated ones.
    * @returns {Array} The valid address and credit card details.
    */
   collectFormFields(allowDuplicates = false) {
     let sections = FormAutofillHeuristics.getFormInfo(this.form, allowDuplicates);
     let allValidDetails = [];
-    for (let fieldDetails of sections) {
-      let section = new FormAutofillSection(fieldDetails, this.winUtils);
+    for (let {fieldDetails, type} of sections) {
+      let section;
+      if (type == FormAutofillUtils.SECTION_TYPES.ADDRESS) {
+        section = new FormAutofillAddressSection(fieldDetails, this.winUtils);
+      } else if (type == FormAutofillUtils.SECTION_TYPES.CREDIT_CARD) {
+        section = new FormAutofillCreditCardSection(fieldDetails, this.winUtils);
+      } else {
+        throw new Error("Unknown field type.");
+      }
       this.sections.push(section);
-      allValidDetails.push(...section.validDetails);
+      allValidDetails.push(...section.fieldDetails);
     }
 
     for (let detail of allValidDetails) {
       let input = detail.elementWeakRef.get();
       if (!input) {
         continue;
       }
       input.addEventListener("input", this, {mozSystemGroup: true});
@@ -1021,17 +1087,24 @@ class FormAutofillHandler {
    */
   createRecords() {
     const records = {
       address: [],
       creditCard: [],
     };
 
     for (const section of this.sections) {
-      const secRecords = section.createRecords();
-      for (const [type, record] of Object.entries(secRecords)) {
-        records[type].push(record);
+      const secRecord = section.createRecord();
+      if (!secRecord) {
+        continue;
+      }
+      if (section instanceof FormAutofillAddressSection) {
+        records.address.push(secRecord);
+      } else if (section instanceof FormAutofillCreditCardSection) {
+        records.creditCard.push(secRecord);
+      } else {
+        throw new Error("Unknown section type");
       }
     }
     log.debug("Create records:", records);
     return records;
   }
 }
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -144,30 +144,31 @@ class FieldScanner {
    * able to identify all sections in the heuristic way.
    *
    * @returns {Array<Object>}
    *          The array with the sections, and the belonging fieldDetails are in
    *          each section.
    */
   getSectionFieldDetails() {
     // When the section feature is disabled, `getSectionFieldDetails` should
-    // provide a single section result.
+    // provide a single address and credit card section result.
     if (!this._sectionEnabled) {
-      return [this._getFinalDetails(this.fieldDetails)];
+      return this._getFinalDetails(this.fieldDetails);
     }
     if (this._sections.length == 0) {
       return [];
     }
     if (this._sections.length == 1 && this._sections[0].name == DEFAULT_SECTION_NAME) {
       this._classifySections();
     }
 
-    return this._sections.map(section =>
-      this._getFinalDetails(section.fieldDetails)
-    );
+    return this._sections.reduce((sections, current) => {
+      sections.push(...this._getFinalDetails(current.fieldDetails));
+      return sections;
+    }, []);
   }
 
   /**
    * This function will prepare an autocomplete info object with getInfo
    * function and push the detail to fieldDetails property.
    * Any field will be pushed into `this._sections` based on the section name
    * in `autocomplete` attribute.
    *
@@ -234,36 +235,60 @@ class FieldScanner {
   }
 
   /**
    * Provide the final field details without invalid field name, and the
    * duplicated fields will be removed as well. For the debugging purpose,
    * the final `fieldDetails` will include the duplicated fields if
    * `_allowDuplicates` is true.
    *
+   * Each item should contain one type of fields only, and the two valid types
+   * are Address and CreditCard.
+   *
    * @param   {Array<Object>} fieldDetails
    *          The field details for trimming.
    * @returns {Array<Object>}
    *          The array with the field details without invalid field name and
    *          duplicated fields.
    */
   _getFinalDetails(fieldDetails) {
-    if (this._allowDuplicates) {
-      return fieldDetails.filter(f => f.fieldName);
+    let addressFieldDetails = [];
+    let creditCardFieldDetails = [];
+    for (let fieldDetail of fieldDetails) {
+      let fieldName = fieldDetail.fieldName;
+      if (FormAutofillUtils.isAddressField(fieldName)) {
+        addressFieldDetails.push(fieldDetail);
+      } else if (FormAutofillUtils.isCreditCardField(fieldName)) {
+        creditCardFieldDetails.push(fieldDetail);
+      } else {
+        log.debug("Not collecting a field with a unknown fieldName", fieldDetail);
+      }
     }
 
-    let dedupedFieldDetails = [];
-    for (let fieldDetail of fieldDetails) {
-      if (fieldDetail.fieldName && !dedupedFieldDetails.find(f => this._isSameField(fieldDetail, f))) {
-        dedupedFieldDetails.push(fieldDetail);
-      } else {
-        log.debug("Not collecting an invalid field or matching another with the same info:", fieldDetail);
+    return [
+      {
+        type: FormAutofillUtils.SECTION_TYPES.ADDRESS,
+        fieldDetails: addressFieldDetails,
+      },
+      {
+        type: FormAutofillUtils.SECTION_TYPES.CREDIT_CARD,
+        fieldDetails: creditCardFieldDetails,
+      },
+    ].map(section => {
+      if (this._allowDuplicates) {
+        return section;
       }
-    }
-    return dedupedFieldDetails;
+      // Deduplicate each set of fieldDetails
+      let details = section.fieldDetails;
+      section.fieldDetails = details.filter((detail, index) => {
+        let previousFields = details.slice(0, index);
+        return !previousFields.find(f => this._isSameField(detail, f));
+      });
+      return section;
+    }).filter(section => section.fieldDetails.length > 0);
   }
 
   elementExisting(index) {
     return index < this._elements.length;
   }
 }
 
 this.LabelUtils = {
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -28,16 +28,20 @@ const EDIT_ADDRESS_KEYWORDS = [
 ];
 const MANAGE_CREDITCARDS_KEYWORDS = ["manageCreditCardsTitle", "addNewCreditCardTitle", "showCreditCardsBtnLabel"];
 const EDIT_CREDITCARD_KEYWORDS = ["cardNumber", "nameOnCard", "cardExpires"];
 const FIELD_STATES = {
   NORMAL: "NORMAL",
   AUTO_FILLED: "AUTO_FILLED",
   PREVIEW: "PREVIEW",
 };
+const SECTION_TYPES = {
+  ADDRESS: "address",
+  CREDIT_CARD: "creditCard",
+};
 
 // The maximum length of data to be saved in a single field for preventing DoS
 // attacks that fill the user's hard drive(s).
 const MAX_FIELD_VALUE_LENGTH = 200;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
@@ -175,16 +179,17 @@ this.FormAutofillUtils = {
   ADDRESSES_FIRST_TIME_USE_PREF,
   CREDITCARDS_USED_STATUS_PREF,
   MANAGE_ADDRESSES_KEYWORDS,
   EDIT_ADDRESS_KEYWORDS,
   MANAGE_CREDITCARDS_KEYWORDS,
   EDIT_CREDITCARD_KEYWORDS,
   MAX_FIELD_VALUE_LENGTH,
   FIELD_STATES,
+  SECTION_TYPES,
 
   _fieldNameInfo: {
     "name": "name",
     "given-name": "name",
     "additional-name": "name",
     "family-name": "name",
     "organization": "organization",
     "street-address": "address",
--- a/browser/extensions/formautofill/content/editAddress.xhtml
+++ b/browser/extensions/formautofill/content/editAddress.xhtml
@@ -1,22 +1,25 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 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/. -->
-<!DOCTYPE html>
+<!DOCTYPE html [
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+]>
 <html xmlns="http://www.w3.org/1999/xhtml" width="620">
 <head>
   <title data-localization="addNewAddressTitle"/>
   <link rel="stylesheet" href="chrome://formautofill-shared/skin/editDialog.css"/>
   <link rel="stylesheet" href="chrome://formautofill-shared/skin/editAddress.css"/>
   <link rel="stylesheet" href="chrome://formautofill/skin/editDialog.css"/>
   <script src="chrome://formautofill/content/editDialog.js"></script>
 </head>
-<body>
+<body dir="&locale.dir;">
   <form id="form" autocomplete="off">
     <div>
       <div id="name-container">
         <label id="given-name-container">
           <span data-localization="givenName"/>
           <input id="given-name" type="text"/>
         </label>
         <label id="additional-name-container">
--- a/browser/extensions/formautofill/content/editCreditCard.xhtml
+++ b/browser/extensions/formautofill/content/editCreditCard.xhtml
@@ -1,22 +1,25 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 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/. -->
-<!DOCTYPE html>
+<!DOCTYPE html [
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+]>
 <html xmlns="http://www.w3.org/1999/xhtml" width="500" style="width: 500px">
 <head>
   <title data-localization="addNewCreditCardTitle"/>
   <link rel="stylesheet" href="chrome://formautofill-shared/skin/editDialog.css"/>
   <link rel="stylesheet" href="chrome://formautofill-shared/skin/editCreditCard.css"/>
   <link rel="stylesheet" href="chrome://formautofill/skin/editDialog.css"/>
   <script src="chrome://formautofill/content/editDialog.js"></script>
 </head>
-<body>
+<body dir="&locale.dir;">
   <form id="form" autocomplete="off">
     <label>
       <span data-localization="cardNumber"/>
       <input id="cc-number" type="text"/>
     </label>
     <label>
       <span data-localization="nameOnCard"/>
       <input id="cc-name" type="text"/>
--- a/browser/extensions/formautofill/content/manageAddresses.xhtml
+++ b/browser/extensions/formautofill/content/manageAddresses.xhtml
@@ -1,21 +1,24 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 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/. -->
-<!DOCTYPE html>
+<!DOCTYPE html [
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+]>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title data-localization="manageAddressesTitle"/>
   <link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
   <link rel="stylesheet" href="chrome://formautofill/content/manageDialog.css" />
   <script src="chrome://formautofill/content/manageDialog.js"></script>
 </head>
-<body>
+<body dir="&locale.dir;">
   <fieldset>
     <legend data-localization="addressesListHeader"/>
     <select id="addresses" size="9" multiple="multiple"/>
   </fieldset>
   <div id="controls-container">
     <button id="remove" disabled="disabled" data-localization="removeBtnLabel"/>
     <!-- Wrapper is used to properly compute the search tooltip position -->
     <div>
--- a/browser/extensions/formautofill/content/manageCreditCards.xhtml
+++ b/browser/extensions/formautofill/content/manageCreditCards.xhtml
@@ -1,21 +1,24 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 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/. -->
-<!DOCTYPE html>
+<!DOCTYPE html [
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+]>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title data-localization="manageCreditCardsTitle"/>
   <link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
   <link rel="stylesheet" href="chrome://formautofill/content/manageDialog.css" />
   <script src="chrome://formautofill/content/manageDialog.js"></script>
 </head>
-<body>
+<body dir="&locale.dir;">
   <fieldset>
     <legend data-localization="creditCardsListHeader"/>
     <select id="credit-cards" size="9" multiple="multiple"/>
   </fieldset>
   <div id="controls-container">
     <button id="remove" disabled="disabled" data-localization="removeBtnLabel"/>
     <button id="show-hide-credit-cards" data-localization="showCreditCardsBtnLabel"/>
     <!-- Wrapper is used to properly compute the search tooltip position -->
--- a/browser/extensions/formautofill/test/unit/head.js
+++ b/browser/extensions/formautofill/test/unit/head.js
@@ -113,17 +113,20 @@ function runHeuristicsTest(patterns, fix
           forms.push(formLike);
         }
       }
 
       Assert.equal(forms.length, testPattern.expectedResult.length, "Expected form count.");
 
       forms.forEach((form, formIndex) => {
         let sections = FormAutofillHeuristics.getFormInfo(form);
-        verifySectionFieldDetails(sections, testPattern.expectedResult[formIndex]);
+        verifySectionFieldDetails(
+          sections.map(section => section.fieldDetails),
+          testPattern.expectedResult[formIndex],
+        );
       });
     });
   });
 }
 
 /**
  * Returns the Sync change counter for a profile storage record. Synced records
  * store additional metadata for tracking changes and resolving merge conflicts.
--- a/browser/extensions/formautofill/test/unit/heuristics/test_basic.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/test_basic.js
@@ -22,16 +22,17 @@ runHeuristicsTest([
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line3"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
+      ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
       ]],
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
--- a/browser/extensions/formautofill/test/unit/heuristics/test_cc_exp.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/test_cc_exp.js
@@ -6,17 +6,16 @@ runHeuristicsTest([
   {
     fixturePath: "heuristics_cc_exp.html",
     expectedResult: [
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
       ]],
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
       ]],
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CDW.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CDW.js
@@ -37,16 +37,17 @@ runHeuristicsTest([
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // state
         {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
 
         // FIXME: bug 1392932 - misdetect ZIP ext string
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
+      ], [
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
 
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
       ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_HomeDepot.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_HomeDepot.js
@@ -9,17 +9,17 @@ runHeuristicsTest([
       [
         [
           {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
-
+        ], [
           // FIXME: bug 1392944 - the uncommented cc-exp-month and cc-exp-year are
           // both invisible <input> elements, and the following two <select>
           // elements are the correct ones. BTW, they are both applied
           // autocomplete attr.
           {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
           {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
 //        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Macys.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Macys.js
@@ -17,31 +17,32 @@ runHeuristicsTest([
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
       ]],
       [],
     ],
   }, {
     fixturePath: "Checkout_Payment.html",
     expectedResult: [
       [[
-//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // ac-off
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, // ac-off
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, // ac-off
-//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
-//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
         {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // state
         {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
+      ], [
+//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // ac-off
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, // ac-off
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, // ac-off
+//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
+//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
       ]],
       [],
     ],
   }, {
     fixturePath: "SignIn.html",
     expectedResult: [
       [[ // Sign in
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_NewEgg.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_NewEgg.js
@@ -22,28 +22,29 @@ runHeuristicsTest([
     ],
   }, {
     fixturePath: "BillingInfo.html",
     expectedResult: [
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
       ], [
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
-//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // state
         {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
+      ], [
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
+//      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
       ]],
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
       ]],
       [],
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_OfficeDepot.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_OfficeDepot.js
@@ -24,34 +24,34 @@ runHeuristicsTest([
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
       ]],
       [],
     ],
   }, {
     fixturePath: "Payment.html",
     expectedResult: [
       [[
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // state
 
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
 
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
-
+      ], [
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
         // FIXME: bug 1392950 - the membership number should not be detected
         // as cc-number.
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
       ]],
     ],
   }, {
     fixturePath: "SignIn.html",
     expectedResult: [
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_QVC.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_QVC.js
@@ -7,16 +7,17 @@ runHeuristicsTest([
     fixturePath: "YourInformation.html",
     expectedResult: [
       [[
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, // ac-off
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"}, // select
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"},
+      ], [
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
       ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
       ]],
       [[
@@ -27,16 +28,17 @@ runHeuristicsTest([
     fixturePath: "PaymentMethod.html",
     expectedResult: [
       [[
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, // ac-off
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"}, // select
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"}, // select
+      ], [
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // select
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
       ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
       ]],
       [[
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Sears.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Sears.js
@@ -70,27 +70,27 @@ runHeuristicsTest([
         {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
       ]],
       [[ // check out
         {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
 
-        // FIXME: bug 1392950 - the bank routing number should not be detected
-        // as cc-number.
-        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
-
         // FIXME: bug 1392934 - this should be detected as address-level1 since
         // it's for Driver's license or state identification.
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"},
 
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"},
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"},
 //      {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"},
+      ], [
+        // FIXME: bug 1392950 - the bank routing number should not be detected
+        // as cc-number.
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
       ]],
       [[
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
       ]],
     ],
   },
 ], "../../../fixtures/third_party/Sears/");
 
--- a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Walmart.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Walmart.js
@@ -25,21 +25,22 @@ runHeuristicsTest([
   }, {
     fixturePath: "Payment.html",
     expectedResult: [
       [],
       [
         [
           {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "given-name"},
           {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "family-name"},
+          {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "tel"},
+        ], [
           {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-number"},
           {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
           {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
 //        {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
-          {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "tel"},
         ], [
           // FIXME bug 1392932 - the following field shouldn't be recognized as
           // "tel-extension".
           // The wrong prediction is caused by the name attr "brwsrAutofillText"
           // which matches the regexp "ext\\b".
           {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
         ],
       ],
--- a/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
+++ b/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
@@ -11,17 +11,16 @@ let {MasterPassword} = Cu.import("resour
 const TESTCASES = [
   {
     description: "Form without autocomplete property",
     document: `<form><input id="given-name"><input id="family-name">
                <input id="street-addr"><input id="city"><select id="country"></select>
                <input id='email'><input id="tel"></form>`,
     focusedInputId: "given-name",
     profileData: {},
-    expectedFillingForm: "address",
     expectedResult: {
       "street-addr": "",
       "city": "",
       "country": "",
       "email": "",
       "tel": "",
     },
   },
@@ -42,17 +41,16 @@ const TESTCASES = [
       "guid": "123",
       "street-address": "2 Harrison St line2",
       "-moz-street-address-one-line": "2 Harrison St line2",
       "address-level2": "San Francisco",
       "country": "US",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "street-addr": "2 Harrison St line2",
       "city": "San Francisco",
       "country": "US",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
   },
@@ -72,17 +70,16 @@ const TESTCASES = [
     profileData: {
       "guid": "123",
       "street-address": "2 Harrison St",
       "address-level2": "San Francisco",
       "country": "US",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "street-addr": "2 Harrison St",
       "city": "San Francisco",
       "country": "US",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
   },
@@ -99,17 +96,16 @@ const TESTCASES = [
     profileData: {
       "guid": "123",
       "street-address": "2 Harrison St",
       "address-level2": "San Francisco",
       "country": "US",
       "email": "",
       "tel": "",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "street-addr": "2 Harrison St",
       "city": "San Francisco",
       "country": "US",
       "email": "",
       "tel": "",
     },
   },
@@ -126,17 +122,16 @@ const TESTCASES = [
     profileData: {
       "guid": "123",
       "street-address": "",
       "address-level2": "",
       "country": "",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "street-addr": "",
       "city": "",
       "country": "",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
   },
@@ -155,17 +150,16 @@ const TESTCASES = [
                </select>
                </form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
       "address-level1": "CA",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "US",
       "state": "CA",
     },
   },
   {
     description: "Form with autocomplete select elements and matching option texts",
     document: `<form>
@@ -181,17 +175,16 @@ const TESTCASES = [
                </select>
                </form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "United States",
       "address-level1": "California",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "US",
       "state": "CA",
     },
   },
   {
     description: "Fill address fields in a form with addr and CC fields.",
     document: `<form>
@@ -215,17 +208,16 @@ const TESTCASES = [
       "guid": "123",
       "street-address": "2 Harrison St line2",
       "-moz-street-address-one-line": "2 Harrison St line2",
       "address-level2": "San Francisco",
       "country": "US",
       "email": "foo@mozilla.com",
       "tel": "1234567",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "street-addr": "2 Harrison St line2",
       "city": "San Francisco",
       "country": "US",
       "email": "foo@mozilla.com",
       "tel": "1234567",
       "cc-number": "",
       "cc-name": "",
@@ -254,17 +246,16 @@ const TESTCASES = [
     focusedInputId: "cc-number",
     profileData: {
       "guid": "123",
       "cc-number": "1234000056780000",
       "cc-name": "test name",
       "cc-exp-month": "06",
       "cc-exp-year": "25",
     },
-    expectedFillingForm: "creditCard",
     expectedResult: {
       "street-addr": "",
       "city": "",
       "country": "",
       "email": "",
       "tel": "",
       "cc-number": "1234000056780000",
       "cc-name": "test name",
@@ -291,17 +282,16 @@ const TESTCASES_INPUT_UNCHANGED = [
                </select>
                </form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
       "address-level1": "unknown state",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "US",
       "state": "",
     },
   },
 ];
 
 const TESTCASES_FILL_SELECT = [
@@ -316,17 +306,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value="CA">California</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
       "address-level1": "CA",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "state": "CA",
     },
   },
   {
     description: "Form with US states select elements; with lower case state key",
     document: `<form>
                <input id="given-name" autocomplete="shipping given-name">
@@ -336,17 +325,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value="ca">ca</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
       "address-level1": "CA",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "state": "ca",
     },
   },
   {
     description: "Form with US states select elements; with state name and extra spaces",
     document: `<form>
                <input id="given-name" autocomplete="shipping given-name">
@@ -356,17 +344,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value="CA">CA</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
       "address-level1": " California ",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "state": "CA",
     },
   },
   {
     description: "Form with US states select elements; with partial state key match",
     document: `<form>
                <input id="given-name" autocomplete="shipping given-name">
@@ -376,17 +363,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value="US-WA">WA-Washington</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
       "address-level1": "WA",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "state": "US-WA",
     },
   },
 
   // Country
   {
     description: "Form with country select elements",
@@ -397,17 +383,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value=""></option>
                  <option value="US">United States</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "US",
     },
   },
   {
     description: "Form with country select elements; with lower case key",
     document: `<form>
                <input id="given-name" autocomplete="given-name">
@@ -416,17 +401,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value=""></option>
                  <option value="us">us</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "us",
     },
   },
   {
     description: "Form with country select elements; with alternative name 1",
     document: `<form>
                <input id="given-name" autocomplete="given-name">
@@ -435,17 +419,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value=""></option>
                  <option value="XX">United States</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "XX",
     },
   },
   {
     description: "Form with country select elements; with alternative name 2",
     document: `<form>
                <input id="given-name" autocomplete="given-name">
@@ -454,17 +437,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value=""></option>
                  <option value="XX">America</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "XX",
     },
   },
   {
     description: "Form with country select elements; with partial matching value",
     document: `<form>
                <input id="given-name" autocomplete="given-name">
@@ -473,17 +455,16 @@ const TESTCASES_FILL_SELECT = [
                  <option value=""></option>
                  <option value="XX">Ship to America</option>
                </select></form>`,
     focusedInputId: "given-name",
     profileData: {
       "guid": "123",
       "country": "US",
     },
-    expectedFillingForm: "address",
     expectedResult: {
       "country": "XX",
     },
   },
 ];
 
 function do_test(testcases, testFn) {
   for (let tc of testcases) {
@@ -513,39 +494,37 @@ function do_test(testcases, testFn) {
               throw e;
             }
             info("User canceled master password entry");
           }
           return string;
         };
 
         handler.collectFormFields();
+
+        let focusedInput = doc.getElementById(testcase.focusedInputId);
+        handler.focusedInput = focusedInput;
+
         for (let section of handler.sections) {
           section._decrypt = decryptHelper;
         }
 
-        // TODO [Bug 1415077] We can assume all test cases with only one section
-        // should be filled. Eventually, the test needs to verify the filling
-        // feature in a multiple section case.
-        let handlerInfo = handler.sections[0][testcase.expectedFillingForm];
-        handlerInfo.fieldDetails.forEach(field => {
+        handler.activeSection.fieldDetails.forEach(field => {
           let element = field.elementWeakRef.get();
           if (!testcase.profileData[field.fieldName]) {
             // Avoid waiting for `change` event of a input with a blank value to
             // be filled.
             return;
           }
           promises.push(...testFn(testcase, element));
         });
 
-        let focusedInput = doc.getElementById(testcase.focusedInputId);
-        handler.focusedInput = focusedInput;
         let [adaptedProfile] = handler.activeSection.getAdaptedProfiles([testcase.profileData]);
         await handler.autofillFormFields(adaptedProfile, focusedInput);
-        Assert.equal(handlerInfo.filledRecordGUID, testcase.profileData.guid,
+        Assert.equal(handler.activeSection.filledRecordGUID, testcase.profileData.guid,
                      "Check if filledRecordGUID is set correctly");
         await Promise.all(promises);
       });
     })();
   }
 }
 
 do_test(TESTCASES, (testcase, element) => {
--- a/browser/extensions/formautofill/test/unit/test_collectFormFields.js
+++ b/browser/extensions/formautofill/test/unit/test_collectFormFields.js
@@ -7,28 +7,27 @@
 Cu.import("resource://formautofill/FormAutofillHandler.jsm");
 
 const TESTCASES = [
   {
     description: "Form without autocomplete property",
     document: `<form><input id="given-name"><input id="family-name">
                <input id="street-addr"><input id="city"><select id="country"></select>
                <input id='email'><input id="phone"></form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
@@ -45,33 +44,32 @@ const TESTCASES = [
                <select id="country" autocomplete="country"></select>
                <input id="email" autocomplete="email">
                <input id="tel" autocomplete="tel">
                <input id="cc-number" autocomplete="cc-number">
                <input id="cc-name" autocomplete="cc-name">
                <input id="cc-exp-month" autocomplete="cc-exp-month">
                <input id="cc-exp-year" autocomplete="cc-exp-year">
                </form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
-      ],
-      creditCardFieldDetails: [
+      ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
       ],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
@@ -85,28 +83,27 @@ const TESTCASES = [
     description: "An address form with autocomplete properties and 2 tokens",
     document: `<form><input id="given-name" autocomplete="shipping given-name">
                <input id="family-name" autocomplete="shipping family-name">
                <input id="street-addr" autocomplete="shipping street-address">
                <input id="city" autocomplete="shipping address-level2">
                <input id="country" autocomplete="shipping country">
                <input id='email' autocomplete="shipping email">
                <input id="tel" autocomplete="shipping tel"></form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
@@ -116,28 +113,27 @@ const TESTCASES = [
     description: "Form with autocomplete properties and profile is partly matched",
     document: `<form><input id="given-name" autocomplete="shipping given-name">
                <input id="family-name" autocomplete="shipping family-name">
                <input id="street-addr" autocomplete="shipping street-address">
                <input autocomplete="shipping address-level2">
                <select autocomplete="shipping country"></select>
                <input id='email' autocomplete="shipping email">
                <input id="tel" autocomplete="shipping tel"></form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
@@ -146,122 +142,109 @@ const TESTCASES = [
   {
     description: "It's a valid address and credit card form.",
     document: `<form>
                <input id="given-name" autocomplete="shipping given-name">
                <input id="family-name" autocomplete="shipping family-name">
                <input id="street-addr" autocomplete="shipping street-address">
                <input id="cc-number" autocomplete="shipping cc-number">
                </form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
-      ],
-      creditCardFieldDetails: [
+      ], [
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "cc-number"},
       ],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "cc-number"},
     ],
   },
   {
     description: "An invalid address form due to less than 3 fields.",
     document: `<form>
                <input id="given-name" autocomplete="shipping given-name">
                <input autocomplete="shipping address-level2">
                </form>`,
-    sections: [{
-      addressFieldDetails: [],
-      creditCardFieldDetails: [],
-    }],
+    sections: [[]],
     validFieldDetails: [],
   },
   {
     description: "An invalid credit card form due to omitted cc-number.",
     document: `<form>
                <input id="cc-name" autocomplete="cc-name">
                <input id="cc-exp-month" autocomplete="cc-exp-month">
                <input id="cc-exp-year" autocomplete="cc-exp-year">
                </form>`,
-    sections: [{
-      addressFieldDetails: [],
-      creditCardFieldDetails: [],
-    }],
+    sections: [[]],
     validFieldDetails: [],
   },
   {
     description: "An invalid credit card form due to non-autocomplete-attr cc-number and omitted cc-exp-*.",
     document: `<form>
                <input id="cc-name" autocomplete="cc-name">
                <input id="cc-number" name="card-number">
                </form>`,
-    sections: [{
-      addressFieldDetails: [],
-      creditCardFieldDetails: [],
-    }],
+    sections: [[]],
     validFieldDetails: [],
   },
   {
     description: "A valid credit card form with autocomplete-attr cc-number only.",
     document: `<form>
                <input id="cc-number" autocomplete="cc-number">
                </form>`,
-    sections: [{
-      addressFieldDetails: [],
-      creditCardFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
       ],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
     ],
   },
   {
     description: "A valid credit card form with non-autocomplete-attr cc-number and cc-exp.",
     document: `<form>
                <input id="cc-number" name="card-number">
                <input id="cc-exp" autocomplete="cc-exp">
                </form>`,
-    sections: [{
-      addressFieldDetails: [],
-      creditCardFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
       ],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
     ],
     ids: [
       "cc-number",
       "cc-exp",
     ],
   },
   {
     description: "A valid credit card form with non-autocomplete-attr cc-number and cc-exp-month/cc-exp-year.",
     document: `<form>
                <input id="cc-number" name="card-number">
                <input id="cc-exp-month" autocomplete="cc-exp-month">
                <input id="cc-exp-year" autocomplete="cc-exp-year">
                </form>`,
-    sections: [{
-      addressFieldDetails: [],
-      creditCardFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
       ],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
     ],
     ids: [
       "cc-number",
       "cc-exp-month",
@@ -281,44 +264,37 @@ const TESTCASES = [
                  <input id="billingSuffix" name="phone" maxlength="4">
 
                  <input id="otherCC" name="phone" maxlength="3">
                  <input id="otherAC" name="phone" maxlength="3">
                  <input id="otherPrefix" name="phone" maxlength="3">
                  <input id="otherSuffix" name="phone" maxlength="4">
                </form>`,
     allowDuplicates: true,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
-      ],
-      creditCardFieldDetails: [],
-    }, {
-      addressFieldDetails: [
+      ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
 
         // TODO Bug 1421181 - "tel-country-code" field should belong to the next
         // section. There should be a way to group the related fields during the
         // parsing stage.
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-country-code"},
-      ],
-      creditCardFieldDetails: [],
-    }, {
-      addressFieldDetails: [
+      ], [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
@@ -340,26 +316,25 @@ const TESTCASES = [
                  <input id="i2" autocomplete="family-name">
                  <input id="i3" autocomplete="street-address">
                  <input id="i4" autocomplete="email">
 
                  <input id="homePhone" maxlength="10">
                  <input id="mobilePhone" maxlength="10">
                  <input id="officePhone" maxlength="10">
                </form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
       {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
     ],
     ids: ["i1", "i2", "i3", "i4", "homePhone"],
@@ -371,33 +346,32 @@ const TESTCASES = [
                  <input id="i2" autocomplete="shipping family-name">
                  <input id="i3" autocomplete="shipping street-address">
                  <input id="i4" autocomplete="shipping email">
                  <input id="singlePhone" autocomplete="shipping tel">
                  <input id="shippingAreaCode" autocomplete="shipping tel-area-code">
                  <input id="shippingPrefix" autocomplete="shipping tel-local-prefix">
                  <input id="shippingSuffix" autocomplete="shipping tel-local-suffix">
                </form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
 
         // NOTES: Ideally, there is only one full telephone field(s) in a form for
         // this case. We can see if there is any better solution later.
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
 
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-area-code"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-prefix"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-suffix"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-area-code"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel-local-prefix"},
@@ -410,24 +384,23 @@ const TESTCASES = [
     description: "Always adopt the info from autocomplete attribute.",
     document: `<form>
                  <input id="given-name" autocomplete="shipping given-name">
                  <input id="family-name" autocomplete="shipping family-name">
                  <input id="dummyAreaCode" autocomplete="shipping tel" maxlength="3">
                  <input id="dummyPrefix" autocomplete="shipping tel" maxlength="3">
                  <input id="dummySuffix" autocomplete="shipping tel" maxlength="4">
                </form>`,
-    sections: [{
-      addressFieldDetails: [
+    sections: [
+      [
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
         {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
       ],
-      creditCardFieldDetails: [],
-    }],
+    ],
     validFieldDetails: [
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "given-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "family-name"},
       {"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
     ],
     ids: ["given-name", "family-name", "dummyAreaCode"],
   },
 ];
@@ -459,36 +432,35 @@ for (let tc of TESTCASES) {
         });
       }
 
       function verifyDetails(handlerDetails, testCaseDetails) {
         if (handlerDetails === null) {
           Assert.equal(handlerDetails, testCaseDetails);
           return;
         }
-        Assert.equal(handlerDetails.length, testCaseDetails.length);
+        Assert.equal(handlerDetails.length, testCaseDetails.length, "field count");
         handlerDetails.forEach((detail, index) => {
           Assert.equal(detail.fieldName, testCaseDetails[index].fieldName, "fieldName");
           Assert.equal(detail.section, testCaseDetails[index].section, "section");
           Assert.equal(detail.addressType, testCaseDetails[index].addressType, "addressType");
           Assert.equal(detail.contactType, testCaseDetails[index].contactType, "contactType");
           Assert.equal(detail.elementWeakRef.get(), testCaseDetails[index].elementWeakRef.get(), "DOM reference");
         });
       }
       setElementWeakRef(testcase.sections.reduce((fieldDetails, section) => {
-        fieldDetails.push(...section.addressFieldDetails, ...section.creditCardFieldDetails);
+        fieldDetails.push(...section);
         return fieldDetails;
       }, []));
       setElementWeakRef(testcase.validFieldDetails);
 
       let handler = new FormAutofillHandler(formLike);
       let validFieldDetails = handler.collectFormFields(testcase.allowDuplicates);
 
-      Assert.equal(handler.sections.length, testcase.sections.length);
+      Assert.equal(handler.sections.length, testcase.sections.length, "section count");
       for (let i = 0; i < handler.sections.length; i++) {
         let section = handler.sections[i];
-        verifyDetails(section.address.fieldDetails, testcase.sections[i].addressFieldDetails);
-        verifyDetails(section.creditCard.fieldDetails, testcase.sections[i].creditCardFieldDetails);
+        verifyDetails(section.fieldDetails, testcase.sections[i]);
       }
       verifyDetails(validFieldDetails, testcase.validFieldDetails);
     });
   })();
 }
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -11,17 +11,17 @@ browser.jar:
 * skin/classic/browser/syncedtabs/sidebar.css     (syncedtabs/sidebar.css)
 * skin/classic/browser/browser.css
 * skin/classic/browser/compacttheme.css
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
-  skin/classic/browser/searchbar.css
+* skin/classic/browser/searchbar.css
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/slowStartup-16.png
   skin/classic/browser/webRTC-indicator.css  (../shared/webRTC-indicator.css)
 * skin/classic/browser/controlcenter/panel.css        (controlcenter/panel.css)
 * skin/classic/browser/customizableui/panelUI.css (customizableui/panelUI.css)
 * skin/classic/browser/downloads/allDownloadsViewOverlay.css   (downloads/allDownloadsViewOverlay.css)
 * skin/classic/browser/downloads/downloads.css        (downloads/downloads.css)
   skin/classic/browser/feeds/feedIcon.png             (feeds/feedIcon.png)
--- a/browser/themes/linux/searchbar.css
+++ b/browser/themes/linux/searchbar.css
@@ -1,253 +1,13 @@
 /* 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/. */
 
-.searchbar-engine-image {
-  height: 16px;
-  width: 16px;
-  list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
-  margin-inline-start: -1px;
-}
+%include ../shared/searchbar.inc.css
 
 menuitem[cmd="cmd_clearhistory"] {
   list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
 }
 
 menuitem[cmd="cmd_clearhistory"][disabled] {
   list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
 }
-
-.search-panel-current-engine {
-  -moz-box-align: center;
-}
-
-/**
- * The borders of the various elements are specified as follows.
- *
- * The current engine always has a bottom border.
- * The search results never have a border.
- *
- * When the search results are not collapsed:
- * - The elements underneath the search results all have a top border.
- *
- * When the search results are collapsed:
- * - The elements underneath the search results all have a bottom border, except
- *   the lowest one: search-setting-button.
- */
-
-.search-panel-current-engine {
-  border-top: none !important;
-  border-bottom: 1px solid var(--panel-separator-color) !important;
-}
-
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
-.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
-  border-top: none !important;
-}
-
-.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
-.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
-  border-bottom: 1px solid var(--panel-separator-color) !important;
-}
-
-.search-panel-header {
-  font-weight: normal;
-  background-color: var(--arrowpanel-dimmed);
-  border: none;
-  border-top: 1px solid var(--panel-separator-color);
-  padding: 3px 5px;
-  color: GrayText;
-}
-
-.search-panel-header > label {
-  margin-top: 2px !important;
-  margin-bottom: 1px !important;
-}
-
-.search-panel-current-input > label {
-  margin: 2px 0 1px !important;
-}
-
-.search-panel-input-value {
-  color: -moz-fieldtext;
-}
-
-.search-panel-one-offs {
-  margin: 0 !important;
-  border-top: 1px solid var(--panel-separator-color);
-  background-color: var(--arrowpanel-dimmed);
-}
-
-.searchbar-engine-one-off-item {
-  -moz-appearance: none;
-  display: inline-block;
-  border: none;
-  min-width: 48px;
-  height: 32px;
-  margin: 0;
-  padding: 0;
-  background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
-  background-size: 1px auto;
-  background-repeat: no-repeat;
-  background-position: right center;
-  color: GrayText;
-}
-
-.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
-  background-position: left center;
-}
-
-.searchbar-engine-one-off-item:not(.last-row) {
-  box-sizing: content-box;
-  border-bottom: 1px solid var(--panel-separator-color);
-}
-
-.search-setting-button-compact {
-  border-bottom: none !important;
-}
-
-.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
-.search-setting-button-compact {
-  background-image: none;
-}
-
-.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
-.addengine-item:hover {
-  background-color: var(--arrowpanel-dimmed-further);
-  color: inherit;
-}
-
-.searchbar-engine-one-off-item[selected] {
-  background-color: Highlight;
-  background-image: none;
-  color: HighlightText;
-}
-
-.searchbar-engine-one-off-item > .button-box {
-  padding: 0;
-}
-
-.searchbar-engine-one-off-item > .button-box > .button-text {
-  display: none;
-}
-
-.searchbar-engine-one-off-item > .button-box > .button-icon {
-  display: -moz-box;
-  margin-inline-end: 0;
-  width: 16px;
-  height: 16px;
-}
-
-.search-add-engines {
-  background-color: var(--arrowpanel-dimmed);
-}
-
-.addengine-item {
-  -moz-appearance: none;
-  background-color: transparent;
-  color: inherit;
-  border: none;
-  height: 32px;
-  margin: 0;
-  padding: 0 10px;
-}
-
-.addengine-item:first-of-type {
-  border-top: 1px solid var(--panel-separator-color);
-}
-
-.addengine-item[selected] {
-  background-color: Highlight;
-  color: HighlightText;
-}
-
-.addengine-item[type=menu][selected] {
-  color: inherit;
-  background-color: var(--arrowpanel-dimmed-further);
-}
-
-.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
-  width: 16px;
-  height: 16px;
-}
-
-.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
-  display: -moz-box;
-  background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
-  box-shadow: none;
-  /* "!important" is necessary to override the rule in toolbarbutton.css */
-  margin: -4px 0 0 !important;
-  margin-inline-end: -4px !important;
-  width: 11px;
-  height: 11px;
-  min-width: 11px;
-  min-height: 11px;
-}
-
-.addengine-item > .toolbarbutton-text {
-  text-align: start;
-  padding-inline-start: 10px;
-}
-
-.addengine-item:not([image]) {
-  list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
-}
-
-@media (min-resolution: 1.1dppx) {
-  .addengine-item:not([image]) {
-    list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
-  }
-}
-
-.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
-  display: -moz-box;
-  -moz-appearance: menuarrow !important;
-  list-style-image: none;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
-  border-top: none !important;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
-  padding-inline-start: 4px;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-  padding-inline-start: 5px;
-  width: 14px;
-  height: 14px;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
-  list-style-image: url("chrome://browser/skin/history.svg");
-  -moz-context-properties: fill;
-  fill: graytext;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
-  fill: HighlightText;
-}
-
-.search-setting-button {
-  -moz-appearance: none;
-  margin: 0;
-  min-height: 32px;
-}
-
-.search-setting-button:hover,
-.search-setting-button[selected] {
-  background-color: var(--arrowpanel-dimmed-further);
-}
-
-.search-setting-button-compact > .button-box > .button-icon {
-  list-style-image: url("chrome://browser/skin/settings.svg");
-  -moz-context-properties: fill;
-  fill: currentColor;
-}
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -13,17 +13,17 @@ browser.jar:
   skin/classic/browser/subtle-pattern.png
   skin/classic/browser/panel-expander-closed.png
   skin/classic/browser/panel-expander-closed@2x.png
   skin/classic/browser/panel-expander-open.png
   skin/classic/browser/panel-expander-open@2x.png
   skin/classic/browser/panel-plus-sign.png
   skin/classic/browser/page-livemarks.png
 * skin/classic/browser/pageInfo.css
-  skin/classic/browser/searchbar.css
+* skin/classic/browser/searchbar.css
   skin/classic/browser/slowStartup-16.png
   skin/classic/browser/toolbarbutton-dropmarker.png
   skin/classic/browser/toolbarbutton-dropmarker@2x.png
   skin/classic/browser/webRTC-indicator.css
 * skin/classic/browser/controlcenter/panel.css        (controlcenter/panel.css)
 * skin/classic/browser/customizableui/panelUI.css    (customizableui/panelUI.css)
 * skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
 * skin/classic/browser/downloads/downloads.css              (downloads/downloads.css)
--- a/browser/themes/osx/searchbar.css
+++ b/browser/themes/osx/searchbar.css
@@ -1,247 +1,27 @@
 /* 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/. */
 
-.searchbar-textbox {
-  border-radius: 10000px;
+%include ../shared/searchbar.inc.css
+
+.search-panel-header,
+.addengine-item {
+  font-size: 10px;
 }
 
 .searchbar-popup {
   margin-top: 4px;
   margin-inline-start: 3px;
 }
 
-.searchbar-engine-image {
-  width: 16px;
-  height: 16px;
-  list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
+#PopupSearchAutoComplete {
+  border-radius: 4px;
 }
 
 .search-panel-current-engine {
   border-radius: 4px 4px 0 0;
 }
 
-/**
- * The borders of the various elements are specified as follows.
- *
- * The current engine always has a bottom border.
- * The search results never have a border.
- *
- * When the search results are not collapsed:
- * - The elements underneath the search results all have a top border.
- *
- * When the search results are collapsed:
- * - The elements underneath the search results all have a bottom border, except
- *   the lowest one: search-setting-button.
- */
-
-.search-panel-current-engine {
-  border-top: none !important;
-  border-bottom: 1px solid var(--panel-separator-color);
-}
-
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
-.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
-  border-top: none;
-}
-
-.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
-.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
-  border-bottom: 1px solid var(--panel-separator-color);
-}
-
-.search-panel-header {
-  font-size: 10px;
-  font-weight: normal;
-  background-color: var(--arrowpanel-dimmed);
-  border-top: 1px solid var(--panel-separator-color);
-  margin: 0;
-  padding: 3px 6px;
-  color: GrayText;
-}
-
-.search-panel-header > label {
-  margin-top: 2px !important;
-  margin-bottom: 2px !important;
-}
-
-.search-panel-current-input > label {
-  margin: 2px 0 !important;
-}
-
-.search-panel-input-value {
-  color: -moz-fieldtext;
-}
-
-.search-panel-one-offs {
-  margin: 0 !important;
-  border-top: 1px solid var(--panel-separator-color);
-  background-color: var(--arrowpanel-dimmed);
-}
-
-.searchbar-engine-one-off-item {
-  -moz-appearance: none;
-  display: inline-block;
-  min-width: 48px;
-  height: 32px;
-  margin: 0;
-  padding: 0;
-  background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
-  background-size: 1px auto;
-  background-repeat: no-repeat;
-  background-position: right center;
-  color: GrayText;
-}
-
-.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
-  background-position: left center;
-}
-
-.searchbar-engine-one-off-item:not(.last-row) {
-  box-sizing: content-box;
-  border-bottom: 1px solid var(--panel-separator-color);
-}
-
-.search-setting-button-compact {
-  border-bottom: none !important;
-}
-
-.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
-.search-setting-button-compact {
-  background-image: none;
-}
-
-.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
-.addengine-item:hover {
-  background-color: var(--arrowpanel-dimmed-further);
-  color: inherit;
-}
-
-.searchbar-engine-one-off-item[selected] {
-  background-color: Highlight;
-  background-image: none;
-  color: HighlightText;
-}
-
-.searchbar-engine-one-off-item > .button-box > .button-text {
-  display: none;
+.search-setting-button {
+  border-radius: 0 0 4px 4px;
 }
-
-.searchbar-engine-one-off-item > .button-box > .button-icon {
-  margin-inline-start: 0;
-  width: 16px;
-  height: 16px;
-}
-
-.search-add-engines {
-  background-color: var(--arrowpanel-dimmed);
-}
-
-.addengine-item {
-  -moz-appearance: none;
-  font-size: 10px;
-  height: 32px;
-  margin: 0;
-  padding: 0 10px;
-}
-
-.addengine-item:first-of-type {
-  border-top: 1px solid var(--panel-separator-color);
-}
-
-.addengine-item[selected] {
-  background-color: Highlight;
-  color: HighlightText;
-}
-
-.addengine-item[type=menu][selected] {
-  color: inherit;
-  background-color: var(--arrowpanel-dimmed-further);
-}
-
-.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
-  width: 16px;
-  height: 16px;
-}
-
-.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
-  display: -moz-box;
-  background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
-  box-shadow: none;
-  /* "!important" is necessary to override the rule in toolbarbutton.css */
-  margin: -4px 0 0 !important;
-  margin-inline-end: -4px !important;
-  width: 11px;
-  height: 11px;
-  min-width: 11px;
-  min-height: 11px;
-}
-
-.addengine-item > .toolbarbutton-text {
-  text-align: start;
-  padding-inline-start: 10px;
-}
-
-.addengine-item:not([image]) {
-  list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
-}
-
-@media (min-resolution: 2dppx) {
-  .addengine-item:not([image]) {
-    list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
-  }
-}
-
-.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
-  display: -moz-box;
-  -moz-appearance: menuarrow !important;
-  list-style-image: none;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
-  border-top: none !important;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-  padding-inline-start: 4px;
-  padding-inline-end: 2px;
-  width: 14px;
-  height: 14px;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
-  list-style-image: url("chrome://browser/skin/history.svg");
-  -moz-context-properties: fill;
-  fill: graytext;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
-  fill: HighlightText;
-}
-
-#PopupSearchAutoComplete {
-  border-radius: 4px;
-}
-
-.search-setting-button {
-  -moz-appearance: none;
-  border-radius: 0 0 4px 4px;
-  min-height: 32px;
-}
-
-.search-setting-button:hover,
-.search-setting-button[selected] {
-  background-color: var(--arrowpanel-dimmed-further);
-}
-
-.search-setting-button-compact > .button-box > .button-icon {
-  list-style-image: url("chrome://browser/skin/settings.svg");
-  -moz-context-properties: fill;
-  fill: currentColor;
-}
--- a/browser/themes/shared/incontentprefs/search.css
+++ b/browser/themes/shared/incontentprefs/search.css
@@ -7,18 +7,19 @@
   width: 631px;
   margin-left: 33px;
 }
 
 .searchBarHiddenImage {
   list-style-image: url("chrome://browser/skin/preferences/in-content/no-search-bar.svg");
 }
 
-#searchBarShownRadio {
-  /* Allow a little visual space to separate the radio from the image above it. */
+#searchBarShownRadio,
+#showSearchSuggestionsFirstCheckbox {
+  /* A little space to separate these from the elements above them. */
   margin-top: 10px;
 }
 
 .searchBarShownImage  {
   list-style-image: url("chrome://browser/skin/preferences/in-content/search-bar.svg");
 }
 
 .searchBarImage:-moz-locale-dir(rtl) {
copy from browser/themes/linux/searchbar.css
copy to browser/themes/shared/searchbar.inc.css
--- a/browser/themes/linux/searchbar.css
+++ b/browser/themes/shared/searchbar.inc.css
@@ -1,29 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 .searchbar-engine-image {
+  width: 16px;
   height: 16px;
-  width: 16px;
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
-  margin-inline-start: -1px;
-}
-
-menuitem[cmd="cmd_clearhistory"] {
-  list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
-}
-
-menuitem[cmd="cmd_clearhistory"][disabled] {
-  list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
-}
-
-.search-panel-current-engine {
-  -moz-box-align: center;
 }
 
 /**
  * The borders of the various elements are specified as follows.
  *
  * The current engine always has a bottom border.
  * The search results never have a border.
  *
@@ -31,78 +18,80 @@ menuitem[cmd="cmd_clearhistory"][disable
  * - The elements underneath the search results all have a top border.
  *
  * When the search results are collapsed:
  * - The elements underneath the search results all have a bottom border, except
  *   the lowest one: search-setting-button.
  */
 
 .search-panel-current-engine {
+  -moz-box-align: center;
   border-top: none !important;
-  border-bottom: 1px solid var(--panel-separator-color) !important;
+  border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
 .search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
 .search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
-  border-top: none !important;
+  border-top: none;
 }
 
 .search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
 .search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
 .search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
 .search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
-  border-bottom: 1px solid var(--panel-separator-color) !important;
+  border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .search-panel-header {
   font-weight: normal;
   background-color: var(--arrowpanel-dimmed);
-  border: none;
   border-top: 1px solid var(--panel-separator-color);
-  padding: 3px 5px;
+  margin: 0;
+  padding: 3px 6px;
   color: GrayText;
 }
 
 .search-panel-header > label {
   margin-top: 2px !important;
   margin-bottom: 1px !important;
 }
 
 .search-panel-current-input > label {
-  margin: 2px 0 1px !important;
+  margin: 2px 0 !important;
 }
 
 .search-panel-input-value {
   color: -moz-fieldtext;
 }
 
 .search-panel-one-offs {
   margin: 0 !important;
   border-top: 1px solid var(--panel-separator-color);
   background-color: var(--arrowpanel-dimmed);
+  /* Bug 1108841: prevent font-size from affecting the layout */
+  line-height: 0;
 }
 
 .searchbar-engine-one-off-item {
   -moz-appearance: none;
   display: inline-block;
-  border: none;
   min-width: 48px;
   height: 32px;
   margin: 0;
   padding: 0;
   background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
   background-size: 1px auto;
   background-repeat: no-repeat;
   background-position: right center;
   color: GrayText;
 }
 
 .searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
-  background-position: left center;
+  background-position-x: left;
 }
 
 .searchbar-engine-one-off-item:not(.last-row) {
   box-sizing: content-box;
   border-bottom: 1px solid var(--panel-separator-color);
 }
 
 .search-setting-button-compact {
@@ -133,31 +122,29 @@ menuitem[cmd="cmd_clearhistory"][disable
   padding: 0;
 }
 
 .searchbar-engine-one-off-item > .button-box > .button-text {
   display: none;
 }
 
 .searchbar-engine-one-off-item > .button-box > .button-icon {
-  display: -moz-box;
+  margin-inline-start: 0;
   margin-inline-end: 0;
   width: 16px;
   height: 16px;
 }
 
 .search-add-engines {
   background-color: var(--arrowpanel-dimmed);
 }
 
 .addengine-item {
   -moz-appearance: none;
-  background-color: transparent;
   color: inherit;
-  border: none;
   height: 32px;
   margin: 0;
   padding: 0 10px;
 }
 
 .addengine-item:first-of-type {
   border-top: 1px solid var(--panel-separator-color);
 }
@@ -210,22 +197,19 @@ menuitem[cmd="cmd_clearhistory"][disable
   -moz-appearance: menuarrow !important;
   list-style-image: none;
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
   border-top: none !important;
 }
 
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
-  padding-inline-start: 4px;
-}
-
 .search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-  padding-inline-start: 5px;
+  padding-inline-start: 2px;
+  padding-inline-end: 2px;
   width: 14px;
   height: 14px;
 }
 
 .search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
   list-style-image: url("chrome://browser/skin/history.svg");
   -moz-context-properties: fill;
   fill: graytext;
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -9,17 +9,17 @@ browser.jar:
   skin/classic/browser/aboutSessionRestore-window-icon.png
 * skin/classic/browser/syncedtabs/sidebar.css     (syncedtabs/sidebar.css)
 * skin/classic/browser/browser.css
 * skin/classic/browser/compacttheme.css
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
-  skin/classic/browser/searchbar.css
+* skin/classic/browser/searchbar.css
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/slowStartup-16.png
   skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/webRTC-indicator.css  (../shared/webRTC-indicator.css)
 * skin/classic/browser/controlcenter/panel.css                 (controlcenter/panel.css)
   skin/classic/browser/customizableui/menu-arrow.svg           (customizableui/menu-arrow.svg)
 * skin/classic/browser/customizableui/panelUI.css       (customizableui/panelUI.css)
--- a/browser/themes/windows/searchbar.css
+++ b/browser/themes/windows/searchbar.css
@@ -1,246 +1,9 @@
 /* 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/. */
 
-.searchbar-engine-image {
-  height: 16px;
-  width: 16px;
-  list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
-  margin-inline-start: -1px;
-}
-
-.search-panel-current-engine {
-  -moz-box-align: center;
-}
-
-/**
- * The borders of the various elements are specified as follows.
- *
- * The current engine always has a bottom border.
- * The search results never have a border.
- *
- * When the search results are not collapsed:
- * - The elements underneath the search results all have a top border.
- *
- * When the search results are collapsed:
- * - The elements underneath the search results all have a bottom border, except
- *   the lowest one: search-setting-button.
- */
-
-.search-panel-current-engine {
-  border-top: none !important;
-  border-bottom: 1px solid var(--panel-separator-color) !important;
-}
-
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
-.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type {
-  border-top: none !important;
-}
-
-.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input,
-.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs,
-.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type {
-  border-bottom: 1px solid var(--panel-separator-color) !important;
-}
-
-.search-panel-header {
-  font-weight: normal;
-  background-color: var(--arrowpanel-dimmed);
-  border: none;
-  border-top: 1px solid var(--panel-separator-color);
-  margin: 0;
-  padding: 3px 6px;
-  color: GrayText;
-}
-
-.search-panel-header > label {
-  margin-top: 2px !important;
-  margin-bottom: 1px !important;
-}
-
-.search-panel-current-input > label {
-  margin: 2px 0 1px !important;
-}
-
-.search-panel-input-value {
-  color: -moz-fieldtext;
-}
-
-.search-panel-one-offs {
-  margin: 0 !important;
-  border-top: 1px solid var(--panel-separator-color);
-  line-height: 0;
-  background-color: var(--arrowpanel-dimmed);
-}
-
-.searchbar-engine-one-off-item {
-  -moz-appearance: none;
-  display: inline-block;
-  border: none;
-  min-width: 48px;
-  height: 32px;
-  margin: 0;
-  padding: 0;
-  background: linear-gradient(transparent 15%, var(--panel-separator-color) 15%, var(--panel-separator-color) 85%, transparent 85%);
-  background-size: 1px auto;
-  background-repeat: no-repeat;
-  background-position: right center;
-  color: GrayText;
-}
-
-.searchbar-engine-one-off-item:-moz-locale-dir(rtl) {
-  background-position: left center;
-}
-
-.searchbar-engine-one-off-item:not(.last-row) {
-  box-sizing: content-box;
-  border-bottom: 1px solid var(--panel-separator-color);
-}
+%include ../shared/searchbar.inc.css
 
 .searchbar-engine-one-off-item:-moz-focusring {
   outline: none;
 }
-
-.search-setting-button-compact {
-  border-bottom: none !important;
-}
-
-.search-panel-one-offs:not([compact=true]) > .searchbar-engine-one-off-item.last-of-row,
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-of-row:not(.dummy),
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.dummy:not(.last-of-row),
-.search-panel-one-offs[compact=true] > .searchbar-engine-one-off-item.last-engine,
-.search-setting-button-compact {
-  background-image: none;
-}
-
-.searchbar-engine-one-off-item:not([selected]):not(.dummy):hover,
-.addengine-item:hover {
-  background-color: var(--arrowpanel-dimmed-further);
-  color: inherit;
-}
-
-.searchbar-engine-one-off-item[selected] {
-  background-color: Highlight;
-  background-image: none;
-  color: HighlightText;
-}
-
-.searchbar-engine-one-off-item > .button-box {
-  padding: 0;
-}
-
-.searchbar-engine-one-off-item > .button-box > .button-text {
-  display: none;
-}
-
-.searchbar-engine-one-off-item > .button-box > .button-icon {
-  width: 16px;
-  height: 16px;
-}
-
-.search-add-engines {
-  background-color: var(--arrowpanel-dimmed);
-}
-
-.addengine-item {
-  -moz-appearance: none;
-  border: none;
-  height: 32px;
-  margin: 0;
-  padding: 0 10px;
-}
-
-.addengine-item:first-of-type {
-  border-top: 1px solid var(--panel-separator-color);
-}
-
-.addengine-item[selected] {
-  background-color: Highlight;
-  color: HighlightText;
-}
-
-.addengine-item[type=menu][selected] {
-  color: inherit;
-  background-color: var(--arrowpanel-dimmed-further);
-}
-
-.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-icon {
-  width: 16px;
-  height: 16px;
-}
-
-.addengine-item > .toolbarbutton-badge-stack > .toolbarbutton-badge {
-  display: -moz-box;
-  background: url(chrome://browser/skin/search-indicator-badge-add.svg) no-repeat center;
-  box-shadow: none;
-  /* "!important" is necessary to override the rule in toolbarbutton.css */
-  margin: -4px 0 0 !important;
-  margin-inline-end: -4px !important;
-  width: 11px;
-  height: 11px;
-  min-width: 11px;
-  min-height: 11px;
-}
-
-.addengine-item > .toolbarbutton-text {
-  text-align: start;
-  padding-inline-start: 10px;
-}
-
-.addengine-item:not([image]) {
-  list-style-image: url("chrome://browser/skin/search-engine-placeholder.png");
-}
-
-@media (min-resolution: 1.1dppx) {
-  .addengine-item:not([image]) {
-    list-style-image: url("chrome://browser/skin/search-engine-placeholder@2x.png");
-  }
-}
-
-.addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
-  display: -moz-box;
-  -moz-appearance: menuarrow !important;
-  list-style-image: none;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
-  border-top: none !important;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
-  padding-inline-start: 4px;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-  padding-inline-start: 5px;
-  width: 14px;
-  height: 14px;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
-  list-style-image: url("chrome://browser/skin/history.svg");
-  -moz-context-properties: fill;
-  fill: graytext;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
-  fill: HighlightText;
-}
-
-.search-setting-button {
-  -moz-appearance: none;
-  min-height: 32px;
-}
-
-.search-setting-button:hover,
-.search-setting-button[selected] {
-  background-color: var(--arrowpanel-dimmed-further);
-}
-
-.search-setting-button-compact > .button-box > .button-icon {
-  list-style-image: url("chrome://browser/skin/settings.svg");
-  -moz-context-properties: fill;
-  fill: currentColor;
-}
new file mode 100644
--- /dev/null
+++ b/build/debian-packages/cmake-wheezy.diff
@@ -0,0 +1,148 @@
+diff -Nru cmake-3.7.1/debian/changelog cmake-3.7.1/debian/changelog
+--- cmake-3.7.1/debian/changelog	2016-12-04 09:01:26.000000000 +0900
++++ cmake-3.7.1/debian/changelog	2017-12-21 15:46:11.000000000 +0900
+@@ -1,3 +1,22 @@
++cmake (3.7.1-1.deb7moz1) wheezy; urgency=medium
++
++  * Mozilla backport for wheezy.
++  * debian/rules, debian/control:
++    - Remove versioned dependencies on dpkg/dpkg-dev/debhelper.
++    - Don't build against system libraries. libuv is missing on wheezy, there
++      are API incompatibilities with libjsoncpp, and it's just simpler to
++      disable the use of system libraries altogether.
++    - Remove Qt GUI. Build profiles are not supported on Wheezy, and Qt5 is
++      not available either. It's not like we need the feature.
++    - Don't build a dbgsym package through dh_strip, that's not supported on
++      Wheezy.
++  * debian/*.maintscript: Remove symlink_to_dir entries, they're not supported
++    on Wheezy. Ideally, we'd replace them with the proper preinst snippet, but
++    it's only needed for upgrades of the package from older versions, and we
++    don't actually care that this works properly.
++
++ -- Mike Hommey <glandium@mozilla.com>  Thu, 21 Dec 2017 15:46:11 +0900
++
+ cmake (3.7.1-1) unstable; urgency=medium
+ 
+   * New upstream release.
+diff -Nru cmake-3.7.1/debian/cmake-curses-gui.maintscript cmake-3.7.1/debian/cmake-curses-gui.maintscript
+--- cmake-3.7.1/debian/cmake-curses-gui.maintscript	2016-10-31 02:20:34.000000000 +0900
++++ cmake-3.7.1/debian/cmake-curses-gui.maintscript	2017-12-21 15:46:11.000000000 +0900
+@@ -1 +0,0 @@
+-symlink_to_dir /usr/share/doc/cmake-curses-gui /usr/share/doc/cmake-data 2.8.12.2-2~
+diff -Nru cmake-3.7.1/debian/cmake-dbg.maintscript cmake-3.7.1/debian/cmake-dbg.maintscript
+--- cmake-3.7.1/debian/cmake-dbg.maintscript	2016-10-31 02:20:34.000000000 +0900
++++ cmake-3.7.1/debian/cmake-dbg.maintscript	2017-12-21 15:46:11.000000000 +0900
+@@ -1 +0,0 @@
+-symlink_to_dir /usr/share/doc/cmake-dbg /usr/share/doc/cmake-data 2.8.12.2-2~
+diff -Nru cmake-3.7.1/debian/cmake-qt-gui.maintscript cmake-3.7.1/debian/cmake-qt-gui.maintscript
+--- cmake-3.7.1/debian/cmake-qt-gui.maintscript	2016-10-31 02:20:34.000000000 +0900
++++ cmake-3.7.1/debian/cmake-qt-gui.maintscript	2017-12-21 15:46:11.000000000 +0900
+@@ -1 +0,0 @@
+-symlink_to_dir /usr/share/doc/cmake-qt-gui /usr/share/doc/cmake-data 2.8.12.2-2~
+diff -Nru cmake-3.7.1/debian/cmake.maintscript cmake-3.7.1/debian/cmake.maintscript
+--- cmake-3.7.1/debian/cmake.maintscript	2016-10-31 02:20:34.000000000 +0900
++++ cmake-3.7.1/debian/cmake.maintscript	2017-12-21 15:46:11.000000000 +0900
+@@ -1,4 +1,3 @@
+-symlink_to_dir /usr/share/doc/cmake /usr/share/doc/cmake-data 2.8.12.2-2~
+ rm_conffile /etc/bash_completion.d/cmake 3.2.2-3~
+ rm_conffile /etc/bash_completion.d/cpack 3.2.2-3~
+ rm_conffile /etc/bash_completion.d/ctest 3.2.2-3~
+diff -Nru cmake-3.7.1/debian/control cmake-3.7.1/debian/control
+--- cmake-3.7.1/debian/control	2016-11-12 19:55:11.000000000 +0900
++++ cmake-3.7.1/debian/control	2017-12-21 15:46:11.000000000 +0900
+@@ -4,20 +4,12 @@
+ Maintainer: Debian CMake Team <pkg-cmake-team@lists.alioth.debian.org>
+ Uploaders: Lisandro Damián Nicanor Pérez Meyer <lisandro@debian.org>,
+            Felix Geyer <fgeyer@debian.org>
+-Build-Depends: debhelper (>= 9.20160114~),
+-               dpkg-dev (>= 1.17.14~),
+-               libarchive-dev (>= 2.8.0),
+-               libbz2-dev,
++Build-Depends: debhelper,
++               dpkg-dev,
+                libcurl4-openssl-dev | libcurl-ssl-dev,
+-               libexpat1-dev,
+-               libjsoncpp-dev,
+-               liblzma-dev,
+                libncurses5-dev,
+-               libuv1-dev,
+                procps [!hurd-any],
+-               python-sphinx,
+-               qtbase5-dev <!stage1>,
+-               zlib1g-dev
++               python-sphinx
+ Standards-Version: 3.9.6
+ Vcs-Git: https://anonscm.debian.org/git/pkg-cmake/cmake.git
+ Vcs-Browser: https://anonscm.debian.org/cgit/pkg-cmake/cmake.git/
+@@ -26,7 +18,6 @@
+ Package: cmake
+ Architecture: any
+ Multi-Arch: foreign
+-Pre-Depends: dpkg (>= 1.17.5~)
+ Depends: cmake-data (= ${source:Version}),
+          procps [!hurd-any],
+          ${misc:Depends},
+@@ -59,7 +50,6 @@
+ 
+ Package: cmake-curses-gui
+ Architecture: any
+-Pre-Depends: dpkg (>= 1.17.5~)
+ Depends: cmake (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
+ Description: curses based user interface for CMake (ccmake)
+  CMake is used to control the software compilation process using simple
+@@ -72,23 +62,6 @@
+  are provided at the bottom of the terminal when the program is running. The
+  main executable file for this GUI is "ccmake".
+ 
+-Package: cmake-qt-gui
+-Architecture: any
+-Build-Profiles: <!stage1>
+-Pre-Depends: dpkg (>= 1.17.5~)
+-Depends: cmake (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
+-Provides: cmake-gui
+-Description: Qt based user interface for CMake (cmake-gui)
+- CMake is used to control the software compilation process using simple
+- platform and compiler independent configuration files. CMake generates native
+- makefiles and workspaces that can be used in the compiler environment of your
+- choice.
+- .
+- This package provides the CMake Qt based GUI. Project configuration
+- settings may be specified interactively. Brief instructions are provided at
+- the bottom of the window when the program is running. The main executable
+- file for this GUI is "cmake-gui".
+-
+ Package: cmake-doc
+ Architecture: all
+ Section: doc
+diff -Nru cmake-3.7.1/debian/rules cmake-3.7.1/debian/rules
+--- cmake-3.7.1/debian/rules	2016-12-04 07:30:25.000000000 +0900
++++ cmake-3.7.1/debian/rules	2017-12-21 15:46:11.000000000 +0900
+@@ -29,9 +29,6 @@
+ 	$(call $(flag_action),CMAKE_CXX_FLAGS,"$(CXXFLAGS)","C++ flags")
+ 	$(call $(flag_action),CMAKE_SKIP_BOOTSTRAP_TEST,ON,"Skip BootstrapTest")
+ 	$(call $(flag_action),BUILD_CursesDialog,ON,"Build curses GUI")
+-ifeq ($(filter stage1,$(DEB_BUILD_PROFILES)),)
+-	$(call $(flag_action),BUILD_QtDialog,ON,"Build Qt GUI")
+-endif
+ ifeq ($(DEB_HOST_ARCH_OS),hurd)
+ 	$(call $(flag_action),CMAKE_USE_LIBUV,0,"Do not use libuv")
+ endif
+@@ -44,7 +41,7 @@
+ override_dh_auto_configure: $(BUILD_FLAGS_FILE)
+ 	rm -rf Build && mkdir -p Build
+ 	cd Build && ../bootstrap --prefix=/usr --docdir=/share/doc/cmake --mandir=/share/man \
+-	                         --init=../$(BUILD_FLAGS_FILE) --system-libs \
++	                         --init=../$(BUILD_FLAGS_FILE) \
+ 	                         --sphinx-man --sphinx-html --sphinx-flags="-D today=\"$(BUILD_DATE)\"" \
+ 	                         $(BOOTSTRAP_PARALLEL) --verbose
+ 
+@@ -68,9 +65,6 @@
+ override_dh_sphinxdoc:
+ 	dh_sphinxdoc -pcmake-doc
+ 
+-override_dh_strip:
+-	dh_strip --dbgsym-migration='cmake-dbg (<< 3.5.0-1~)'
+-
+ %:
+ 	dh $@ --with=sphinxdoc --parallel --builddirectory=Build
+ 
new file mode 100644
--- /dev/null
+++ b/build/debian-packages/ninja-wheezy.diff
@@ -0,0 +1,13 @@
+diff -Nru ninja-build-1.6.0/debian/changelog ninja-build-1.6.0/debian/changelog
+--- ninja-build-1.6.0/debian/changelog	2016-02-09 04:54:03.000000000 +0900
++++ ninja-build-1.6.0/debian/changelog	2017-12-21 16:38:47.000000000 +0900
+@@ -1,3 +1,9 @@
++ninja-build (1.6.0-1.deb7moz1) wheezy; urgency=medium
++
++  * Mozilla backport for wheezy.
++
++ -- Mike Hommey <glandium@mozilla.com>  Thu, 21 Dec 2017 16:38:47 +0900
++
+ ninja-build (1.6.0-1) unstable; urgency=medium
+ 
+   * New maintainer. (Closes: #810025)
--- a/build/unix/build-hfsplus/build-hfsplus.sh
+++ b/build/unix/build-hfsplus/build-hfsplus.sh
@@ -1,10 +1,11 @@
 #!/bin/bash
 
+set -e
 set -x
 
 hfplus_version=540.1.linux3
 md5sum=0435afc389b919027b69616ad1b05709
 filename=diskdev_cmds-${hfplus_version}.tar.gz
 make_flags="-j$(getconf _NPROCESSORS_ONLN)"
 
 root_dir="$1"
@@ -25,16 +26,29 @@ echo "${md5sum} *${TMPDIR}/${filename}" 
 # Download the source of the specified version of hfsplus
 wget -c -P $TMPDIR http://pkgs.fedoraproject.org/repo/pkgs/hfsplus-tools/${filename}/${md5sum}/${filename} || exit 1
 md5sum -c $TMPDIR/hfsplus.MD5 || exit 1
 mkdir hfsplus-source
 tar xzf $TMPDIR/${filename} -C hfsplus-source --strip-components=1
 
 # Build
 cd hfsplus-source
+# We want to statically link against libcrypto. On CentOS, that requires zlib
+# and libdl, because of FIPS functions pulling in more than necessary from
+# libcrypto (only SHA1 functions are used), but not on Debian, thus
+# --as-needed.
+patch -p1 << 'EOF'
+--- a/newfs_hfs.tproj/Makefile.lnx
++++ b/newfs_hfs.tproj/Makefile.lnx
+@@ -6,3 +6,3 @@
+ newfs_hfs: $(OFILES)
+-	${CC} ${CFLAGS} ${LDFLAGS} -o newfs_hfs ${OFILES} -lcrypto
++	${CC} ${CFLAGS} ${LDFLAGS} -o newfs_hfs ${OFILES} -Wl,-Bstatic -lcrypto -Wl,-Bdynamic,--as-needed,-lz,-ldl
+ 
+EOF
 make $make_flags || exit 1
 cd ..
 
 mkdir hfsplus-tools
 cp hfsplus-source/newfs_hfs.tproj/newfs_hfs hfsplus-tools/newfs_hfs
 ## XXX fsck_hfs is unused, but is small and built from the package.
 cp hfsplus-source/fsck_hfs.tproj/fsck_hfs hfsplus-tools/fsck_hfs
 
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -323,8 +323,9 @@ devtools.jar:
     content/netmonitor/src/assets/styles/NetworkDetailsPanel.css (netmonitor/src/assets/styles/NetworkDetailsPanel.css)
     content/netmonitor/src/assets/styles/RequestList.css (netmonitor/src/assets/styles/RequestList.css)
     content/netmonitor/src/assets/styles/StatisticsPanel.css (netmonitor/src/assets/styles/StatisticsPanel.css)
     content/netmonitor/src/assets/styles/StatusBar.css (netmonitor/src/assets/styles/StatusBar.css)
     content/netmonitor/src/assets/styles/Toolbar.css (netmonitor/src/assets/styles/Toolbar.css)
     content/netmonitor/src/assets/styles/variables.css (netmonitor/src/assets/styles/variables.css)
     content/netmonitor/src/assets/icons/play.svg (netmonitor/src/assets/icons/play.svg)
     content/netmonitor/index.html (netmonitor/index.html)
+    content/netmonitor/initializer.js (netmonitor/initializer.js)
--- a/devtools/client/netmonitor/README.md
+++ b/devtools/client/netmonitor/README.md
@@ -90,17 +90,17 @@ Files used to run the Network Monitor in
 * `src/connector/` wrap function call for Browser specific API. Current support Firefox and Chrome(experimental).
 
 ### Run in the browser tab (experimental)
 
 Files used to run the Network Monitor in the browser tab
 
 * `bin/` files to launch test server.
 * `configs/` dev configs.
-* `index.js` the entry point, equivalent to `index.html`.
+* `launchpad.js` the entry point, equivalent to `index.html`.
 * `webpack.config.js` the webpack config file, including plenty of module alias map to shims and polyfills.
 * `package.json` declare every required packages and available commands.
 
 To run in the browser tab, the Network Monitor needs to get some dependencies from npm module. Check `package.json` to see all dependencies. Check `webpack.config.js` to find the module alias, and check [devtools-core](https://github.com/devtools-html/devtools-core) packages to dive into actual modules used by the Network Monitor and other Devtools.
 
 ### UI
 
 The Network Monitor UI is built using [React](http://searchfox.org/mozilla-central/source/devtools/docs/frontend/react.md) components (in `src/components/`).
--- a/devtools/client/netmonitor/index.html
+++ b/devtools/client/netmonitor/index.html
@@ -4,149 +4,11 @@
 <!DOCTYPE html>
 <html dir="">
   <head>
     <link rel="stylesheet" href="chrome://devtools/content/netmonitor/src/assets/styles/netmonitor.css"/>
     <script src="chrome://devtools/content/shared/theme-switching.js"></script>
   </head>
   <body class="theme-body" role="application">
     <div id="mount"></div>
-    <script>
-      "use strict";
-
-      const { BrowserLoader } = Components.utils.import(
-        "resource://devtools/client/shared/browser-loader.js", {});
-      const require = window.windowRequire = BrowserLoader({
-        baseURI: "resource://devtools/client/netmonitor/",
-        window,
-      }).require;
-
-      const EventEmitter = require("devtools/shared/old-event-emitter");
-      const { createFactory } = require("devtools/client/shared/vendor/react");
-      const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom");
-      const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
-      const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
-      const { Connector } = require("./src/connector/index");
-      const { configureStore } = require("./src/utils/create-store");
-      const App = createFactory(require("./src/components/App"));
-      const { getDisplayedRequestById } = require("./src/selectors/index");
-      const { EVENTS } = require("./src/constants");
-
-      // Inject EventEmitter into global window.
-      EventEmitter.decorate(window);
-
-      // Configure store/state object.
-      let connector = new Connector();
-      const store = configureStore(connector);
-      const actions = bindActionCreators(require("./src/actions/index"), store.dispatch);
-
-      // Inject to global window for testing
-      window.store = store;
-      window.connector = connector;
-
-      window.Netmonitor = {
-        bootstrap({ toolbox, panel }) {
-          this.mount = document.querySelector("#mount");
-
-          const connection = {
-            tabConnection: {
-              tabTarget: toolbox.target,
-            },
-            toolbox,
-            panel,
-          };
-
-          const openLink = (link) => {
-            let parentDoc = toolbox.doc;
-            let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
-            let top = iframe.ownerDocument.defaultView.top;
-            top.openUILinkIn(link, "tab");
-          };
-
-          // Render the root Application component.
-          const sourceMapService = toolbox.sourceMapURLService;
-          const app = App({ connector, openLink, sourceMapService });
-          render(Provider({ store }, app), this.mount);
-
-          // Connect to the Firefox backend by default.
-          return connector.connectFirefox(connection, actions, store.getState);
-        },
-
-        destroy() {
-          unmountComponentAtNode(this.mount);
-          return connector.disconnect();
-        },
-
-        /**
-         * Selects the specified request in the waterfall and opens the details view.
-         * This is a firefox toolbox specific API, which providing an ability to inspect
-         * a network request directly from other internal toolbox panel.
-         *
-         * @param {string} requestId The actor ID of the request to inspect.
-         * @return {object} A promise resolved once the task finishes.
-         */
-        inspectRequest(requestId) {
-          // Look for the request in the existing ones or wait for it to appear, if
-          // the network monitor is still loading.
-          return new Promise((resolve) => {
-            let request = null;
-            let inspector = () => {
-              request = getDisplayedRequestById(store.getState(), requestId);
-              if (!request) {
-                // Reset filters so that the request is visible.
-                actions.toggleRequestFilterType("all");
-                request = getDisplayedRequestById(store.getState(), requestId);
-              }
-
-              // If the request was found, select it. Otherwise this function will be
-              // called again once new requests arrive.
-              if (request) {
-                window.off(EVENTS.REQUEST_ADDED, inspector);
-                actions.selectRequest(request.id);
-                resolve();
-              }
-            };
-
-            inspector();
-
-            if (!request) {
-              window.on(EVENTS.REQUEST_ADDED, inspector);
-            }
-          });
-        }
-      };
-
-      // Implement support for:
-      // chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
-      // where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
-      // Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
-
-      // URL constructor doesn't support chrome: scheme
-      let href = window.location.href.replace(/chrome:/, "http://");
-      let url = new window.URL(href);
-
-      // If query parameters are given in a chrome tab, the inspector
-      // is running in standalone.
-      if (window.location.protocol === "chrome:" && url.search.length > 1) {
-        const { targetFromURL } = require("devtools/client/framework/target-from-url");
-
-        (async function () {
-          let target = await targetFromURL(url);
-          // Start the network event listening as it is done in the toolbox code
-          await target.activeConsole.startListeners([
-            "NetworkActivity",
-          ]);
-          // Create a fake toolbox object
-          let toolbox = {
-            target,
-            viewSourceInDebugger() {
-              throw new Error("toolbox.viewSourceInDebugger is not implement from a tab");
-            }
-          };
-          window.Netmonitor.bootstrap({ toolbox });
-        })().catch(e => {
-          window.alert("Unable to start the network monitor:" +
-            e.message + "\n" + e.stack);
-        });
-      }
-    </script>
+    <script src="initializer.js"></script>
   </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/initializer.js
@@ -0,0 +1,155 @@
+/* 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";
+
+/**
+ * This script is the entry point of Network monitor panel.
+ * See README.md for more information.
+ */
+const { BrowserLoader } = Components.utils.import(
+  "resource://devtools/client/shared/browser-loader.js", {});
+
+const require = window.windowRequire = BrowserLoader({
+  baseURI: "resource://devtools/client/netmonitor/",
+  window,
+}).require;
+
+const EventEmitter = require("devtools/shared/old-event-emitter");
+const { createFactory } = require("devtools/client/shared/vendor/react");
+const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom");
+const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
+const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
+const { Connector } = require("./src/connector/index");
+const { configureStore } = require("./src/utils/create-store");
+const App = createFactory(require("./src/components/App"));
+const { getDisplayedRequestById } = require("./src/selectors/index");
+const { EVENTS } = require("./src/constants");
+
+// Inject EventEmitter into global window.
+EventEmitter.decorate(window);
+
+// Configure store/state object.
+let connector = new Connector();
+const store = configureStore(connector);
+const actions = bindActionCreators(require("./src/actions/index"), store.dispatch);
+
+// Inject to global window for testing
+window.store = store;
+window.connector = connector;
+
+/**
+ * Global Netmonitor object in this panel. This object can be consumed
+ * by other panels (e.g. Console is using inspectRequest), by the
+ * Launchpad (bootstrap), etc.
+ */
+window.Netmonitor = {
+  bootstrap({ toolbox, panel }) {
+    this.mount = document.querySelector("#mount");
+
+    const connection = {
+      tabConnection: {
+        tabTarget: toolbox.target,
+      },
+      toolbox,
+      panel,
+    };
+
+    const openLink = (link) => {
+      let parentDoc = toolbox.doc;
+      let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
+      let top = iframe.ownerDocument.defaultView.top;
+      top.openUILinkIn(link, "tab");
+    };
+
+    // Render the root Application component.
+    const sourceMapService = toolbox.sourceMapURLService;
+    const app = App({ connector, openLink, sourceMapService });
+    render(Provider({ store }, app), this.mount);
+
+    // Connect to the Firefox backend by default.
+    return connector.connectFirefox(connection, actions, store.getState);
+  },
+
+  destroy() {
+    unmountComponentAtNode(this.mount);
+    return connector.disconnect();
+  },
+
+  /**
+   * Selects the specified request in the waterfall and opens the details view.
+   * This is a firefox toolbox specific API, which providing an ability to inspect
+   * a network request directly from other internal toolbox panel.
+   *
+   * @param {string} requestId The actor ID of the request to inspect.
+   * @return {object} A promise resolved once the task finishes.
+   */
+  inspectRequest(requestId) {
+    // Look for the request in the existing ones or wait for it to appear, if
+    // the network monitor is still loading.
+    return new Promise((resolve) => {
+      let request = null;
+      let inspector = () => {
+        request = getDisplayedRequestById(store.getState(), requestId);
+        if (!request) {
+          // Reset filters so that the request is visible.
+          actions.toggleRequestFilterType("all");
+          request = getDisplayedRequestById(store.getState(), requestId);
+        }
+
+        // If the request was found, select it. Otherwise this function will be
+        // called again once new requests arrive.
+        if (request) {
+          window.off(EVENTS.REQUEST_ADDED, inspector);
+          actions.selectRequest(request.id);
+          resolve();
+        }
+      };
+
+      inspector();
+
+      if (!request) {
+        window.on(EVENTS.REQUEST_ADDED, inspector);
+      }
+    });
+  }
+};
+
+// Implement support for:
+// chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
+// where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
+// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
+
+// URL constructor doesn't support chrome: scheme
+let href = window.location.href.replace(/chrome:/, "http://");
+let url = new window.URL(href);
+
+// If query parameters are given in a chrome tab, the inspector
+// is running in standalone.
+if (window.location.protocol === "chrome:" && url.search.length > 1) {
+  const { targetFromURL } = require("devtools/client/framework/target-from-url");
+
+  (async function () {
+    try {
+      let target = await targetFromURL(url);
+
+      // Start the network event listening as it is done in the toolbox code
+      await target.activeConsole.startListeners([
+        "NetworkActivity",
+      ]);
+
+      // Create a fake toolbox object
+      let toolbox = {
+        target,
+        viewSourceInDebugger() {
+          throw new Error("toolbox.viewSourceInDebugger is not implement from a tab");
+        }
+      };
+
+      window.Netmonitor.bootstrap({ toolbox });
+    } catch (err) {
+      window.alert("Unable to start the network monitor:" + err);
+    }
+  })();
+}
rename from devtools/client/netmonitor/index.js
rename to devtools/client/netmonitor/launchpad.js
--- a/devtools/client/netmonitor/webpack.config.js
+++ b/devtools/client/netmonitor/webpack.config.js
@@ -9,17 +9,17 @@
 
 const path = require("path");
 const { NormalModuleReplacementPlugin } = require("webpack");
 const { toolboxConfig } = require("./node_modules/devtools-launchpad/index");
 const { getConfig } = require("./bin/configure");
 
 let webpackConfig = {
   entry: {
-    netmonitor: [path.join(__dirname, "index.js")]
+    netmonitor: [path.join(__dirname, "launchpad.js")]
   },
 
   module: {
     rules: [
       {
         test: /\.(png|svg)$/,
         loader: "file-loader?name=[path][name].[ext]",
       },
--- a/devtools/client/styleeditor/test/browser.ini
+++ b/devtools/client/styleeditor/test/browser.ini
@@ -45,19 +45,20 @@ support-files =
   sourcemap-sass/media-rules.scss
   sourcemap-styl/test-stylus.styl
   sourcemaps.html
   sourcemaps-inline.html
   sourcemaps-large.html
   sourcemaps-watching.html
   test_private.css
   test_private.html
+  doc_fetch_from_netmonitor.html
+  doc_long_string.css
   doc_long.css
-  doc_uncached.css
-  doc_uncached.html
+  doc_short_string.css
   doc_xulpage.xul
   sync.html
   utf-16.css
   !/devtools/client/commandline/test/helpers.js
   !/devtools/client/framework/test/shared-head.js
   !/devtools/client/inspector/shared/test/head.js
   !/devtools/client/inspector/test/head.js
   !/devtools/client/inspector/test/shared-head.js
--- a/devtools/client/styleeditor/test/browser_styleeditor_fetch-from-netmonitor.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_fetch-from-netmonitor.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-// A test to ensure Style Editor only issues 1 request for a stylesheet (instead of 2) by
-// using the network monitor's request history (bug 1306892).
+// A test to ensure Style Editor only issues 1 request for each stylesheet (instead of 2)
+// by using the network monitor's request history (bug 1306892).
 
-const TEST_URL = TEST_BASE_HTTP + "doc_uncached.html";
+const TEST_URL = TEST_BASE_HTTP + "doc_fetch_from_netmonitor.html";
 
 add_task(function* () {
   info("Opening netmonitor");
   let tab = yield addTab("about:blank");
   let target = TargetFactory.forTab(tab);
   let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
   let monitor = toolbox.getPanel("netmonitor");
   let { store, windowRequire } = monitor.panelWin;
@@ -22,23 +22,32 @@ add_task(function* () {
 
   store.dispatch(Actions.batchEnable(false));
 
   info("Navigating to test page");
   yield navigateTo(TEST_URL);
 
   info("Opening Style Editor");
   let styleeditor = yield toolbox.selectTool("styleeditor");
+  let ui = styleeditor.UI;
 
-  info("Waiting for the source to be loaded.");
-  yield styleeditor.UI.editors[0].getSourceEditor();
+  info("Waiting for the sources to be loaded.");
+  yield ui.editors[0].getSourceEditor();
+  yield ui.selectStyleSheet(ui.editors[1].styleSheet);
+  yield ui.editors[1].getSourceEditor();
 
   info("Checking Netmonitor contents.");
-  let items = [];
+  let shortRequests = [];
+  let longRequests = [];
   for (let item of getSortedRequests(store.getState())) {
-    if (item.url.endsWith("doc_uncached.css")) {
-      items.push(item);
+    if (item.url.endsWith("doc_short_string.css")) {
+      shortRequests.push(item);
+    }
+    if (item.url.endsWith("doc_long_string.css")) {
+      longRequests.push(item);
     }
   }
 
-  is(items.length, 1,
-     "Got one request for doc_uncached.css after Style Editor was loaded.");
+  is(shortRequests.length, 1,
+     "Got one request for doc_short_string.css after Style Editor was loaded.");
+  is(longRequests.length, 1,
+     "Got one request for doc_long_string.css after Style Editor was loaded.");
 });
new file mode 100644
--- /dev/null
+++ b/devtools/client/styleeditor/test/doc_fetch_from_netmonitor.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+<head>
+  <title>Fetch from netmonitor testcase</title>
+  <link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_short_string.css"/>
+  <link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_long_string.css"/>
+</head>
+<body>
+	<div>Fetch from netmonitor</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/devtools/client/styleeditor/test/doc_long_string.css
@@ -0,0 +1,43 @@
+/* CSS file longer than the server's long string limit of 10000 bytes */
+
+/*
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+.yui-calcontainer{position:relative;float:left;_overflow:hidden}.yui-calcontainer iframe{position:absolute;border:0;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0;top:0}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative}.yui-calcontainer .title{position:relative;z-index:1}.yui-calcontainer .close-icon{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden}.yui-calendar{position:relative}.yui-calendar .calnavleft{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden}.yui-calendar .calnavright{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden}.yui-calendar .calheader{position:relative;width:100%;text-align:center}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inline-block}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:0;background-color:transparent;cursor:pointer}.yui-calendar .calbody a:hover{background:inherit}p#clear{clear:left;padding-top:10px}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:0;padding:10px 5px 10px 5px;margin:0}.yui-skin-sam .yui-calcontainer .title{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 0;border-bottom:1px solid #ccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0}.yui-skin-sam .yui-calcontainer .calclose{background:url(../js/yui/assets/skins/sam/sprite.png) no-repeat 0 -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:pointer}.yui-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:0;vertical-align:middle;padding:0}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center}.yui-skin-sam .yui-calendar .calheader img{border:0}.yui-skin-sam .yui-calendar .calnavleft{background:url(../js/yui/assets/skins/sam/sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer}.yui-skin-sam .yui-calendar .calnavright{background:url(../js/yui/assets/skins/sam/sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:0}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:0}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #ccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap}.yui-skin-sam .yui-calendar td.calcell a{color:#06c;display:block;height:100%;text-decoration:none}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#ccc;color:#a6a6a6;cursor:default}.yui-skin-sam .yui-calendar td.calcell.oom a{color:#a6a6a6}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000}.yui-skin-sam .yui-calendar td.calcell.selected a{background-color:#b3d4ff;color:#000}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;color:#fff;cursor:pointer}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#cf9}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#9cf}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#fcc}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#cf9}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 0;border-color:#a0a0a0;cursor:pointer}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:.25;filter:alpha(opacity=25)}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#edf5ff;border-top:1px solid black;display:none}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold}
+.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#ffee69;border:1px solid #000}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px solid #808080;background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 -1400px}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff}
+
+/*
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2}.yui-panel{position:relative}.yui-panel-container form{margin:0}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0}.mask.block-scrollbars{overflow:auto}.masked select,.drag select,.hide-select select{_visibility:hidden}.yui-panel-container select{_visibility:inherit}.hide-scrollbars,.hide-scrollbars *{overflow:hidden}.hide-scrollbars select{display:none}.show-scrollbars{overflow:auto}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px}.yui-effect-fade .underlay,.yui-effect-fade .yui-tt-shadow{display:none}.yui-tt-shadow{position:absolute}.yui-override-padding{padding:0!important}.yui-panel-container .container-close{overflow:hidden;text-indent:-10000em;text-decoration:none}.yui-overlay.yui-force-redraw,.yui-panel-container.yui-force-redraw{margin-bottom:1px}.yui-skin-sam .mask{background-color:#000;opacity:.25;filter:alpha(opacity=25)}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px}.yui-skin-sam .yui-panel{position:relative;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;*border-width:1px;*zoom:1;_zoom:normal}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;*margin:0;*border:0}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#f2f2f2}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 -200px}.yui-skin-sam .yui-panel .bd{padding:10px}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(../js/yui/assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px}.yui-skin-sam .yui-panel-container.matte{padding:9px 10px;background-color:#fff}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 4px 0 2px}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;left:-3px;right:-3px;bottom:-3px;*top:4px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_left:0;_right:0;_bottom:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;filter:alpha(opacity=12)}.yui-skin-sam .yui-dialog .ft{border-top:0;padding:0 10px 10px 10px;font-size:100%}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled{background-position:0 -1500px;border-color:#ccc}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled .first-child{border-color:#ccc}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled button{color:#a6a6a6}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(../js/yui/assets/skins/sam/sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#d4c237 #A6982b #a6982b #A6982B;border-width:1px;border-style:solid;background-color:#ffee69}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;filter:alpha(opacity=12)}
+
+/*
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+.yui-skin-sam .yui-dt-mask{position:absolute;z-index:9500}.yui-dt-tmp{position:absolute;left:-9000px}.yui-dt-scrollable .yui-dt-bd{overflow:auto}.yui-dt-scrollable .yui-dt-hd{overflow:hidden;position:relative}.yui-dt-scrollable .yui-dt-bd thead tr,.yui-dt-scrollable .yui-dt-bd thead th{position:absolute;left:-1500px}.yui-dt-scrollable tbody{-moz-outline:0}.yui-skin-sam thead .yui-dt-sortable{cursor:pointer}.yui-skin-sam thead .yui-dt-draggable{cursor:move}.yui-dt-coltarget{position:absolute;z-index:999}.yui-dt-hd{zoom:1}th.yui-dt-resizeable .yui-dt-resizerliner{position:relative}.yui-dt-resizer{position:absolute;right:0;bottom:0;height:100%;cursor:e-resize;cursor:col-resize;background-color:#CCC;opacity:0;filter:alpha(opacity=0)}.yui-dt-resizerproxy{visibility:hidden;position:absolute;z-index:9000;background-color:#CCC;opacity:0;filter:alpha(opacity=0)}th.yui-dt-hidden .yui-dt-liner,td.yui-dt-hidden .yui-dt-liner,th.yui-dt-hidden .yui-dt-resizer{display:none}.yui-dt-editor,.yui-dt-editor-shim{position:absolute;z-index:9000}.yui-skin-sam .yui-dt table{margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:separate;*border-collapse:collapse;border-spacing:0;border:1px solid #7f7f7f}.yui-skin-sam .yui-dt thead{border-spacing:0}.yui-skin-sam .yui-dt caption{color:#000;font-size:85%;font-weight:normal;font-style:italic;line-height:1;padding:1em 0;text-align:center}.yui-skin-sam .yui-dt th{background:#d8d8da url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 0}.yui-skin-sam .yui-dt th,.yui-skin-sam .yui-dt th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom}.yui-skin-sam .yui-dt th{margin:0;padding:0;border:0;border-right:1px solid #cbcbcb}.yui-skin-sam .yui-dt tr.yui-dt-first td{border-top:1px solid #7f7f7f}.yui-skin-sam .yui-dt th .yui-dt-liner{white-space:nowrap}.yui-skin-sam .yui-dt-liner{margin:0;padding:0;padding:4px 10px 4px 10px}.yui-skin-sam .yui-dt-coltarget{width:5px;background-color:red}.yui-skin-sam .yui-dt td{margin:0;padding:0;border:0;border-right:1px solid #cbcbcb;text-align:left}.yui-skin-sam .yui-dt-list td{border-right:0}.yui-skin-sam .yui-dt-resizer{width:6px}.yui-skin-sam .yui-dt-mask{background-color:#000;opacity:.25;filter:alpha(opacity=25)}.yui-skin-sam .yui-dt-message{background-color:#FFF}.yui-skin-sam .yui-dt-scrollable table{border:0}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd{border-left:1px solid #7f7f7f;border-top:1px solid #7f7f7f;border-right:1px solid #7f7f7f}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd{border-left:1px solid #7f7f7f;border-bottom:1px solid #7f7f7f;border-right:1px solid #7f7f7f;background-color:#FFF}.yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td{border-bottom:1px solid #7f7f7f}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 -100px}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:10px}.yui-skin-sam th.yui-dt-asc .yui-dt-liner{background:url(../js/yui/assets/skins/sam/dt-arrow-up.png) no-repeat right}.yui-skin-sam th.yui-dt-desc .yui-dt-liner{background:url(../js/yui/assets/skins/sam/dt-arrow-dn.png) no-repeat right}tbody .yui-dt-editable{cursor:pointer}.yui-dt-editor{text-align:left;background-color:#f2f2f2;border:1px solid #808080;padding:6px}.yui-dt-editor label{padding-left:4px;padding-right:6px}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right}.yui-dt-editor .yui-dt-button button{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 -1400px;background-color:#5584e0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 -1300px;color:#000}.yui-dt-editor .yui-dt-button button:active{background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 -1700px;color:#000}.yui-skin-sam tr.yui-dt-even{background-color:#FFF}.yui-skin-sam tr.yui-dt-odd{background-color:#edf5ff}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#edf5ff}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#dbeaff}.yui-skin-sam .yui-dt-list tr.yui-dt-even{background-color:#FFF}.yui-skin-sam .yui-dt-list tr.yui-dt-odd{background-color:#FFF}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#edf5ff}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#edf5ff}.yui-skin-sam th.yui-dt-highlighted,.yui-skin-sam th.yui-dt-highlighted a{background-color:#b2d2ff}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#b2d2ff}.yui-skin-sam .yui-dt-list th.yui-dt-highlighted,.yui-skin-sam .yui-dt-list th.yui-dt-highlighted a{background-color:#b2d2ff}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#b2d2ff}.yui-skin-sam th.yui-dt-selected,.yui-skin-sam th.yui-dt-selected a{background-color:#446cd7}.yui-skin-sam tr.yui-dt-selected td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426fd9;color:#FFF}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446cd7;color:#FFF}.yui-skin-sam .yui-dt-list th.yui-dt-selected,.yui-skin-sam .yui-dt-list th.yui-dt-selected a{background-color:#446cd7}
+.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426fd9;color:#FFF}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected{background-color:#446cd7;color:#FFF}.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap}.yui-skin-sam .yui-dt-paginator .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px}.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none}.yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none}.yui-skin-sam a.yui-dt-page{border:1px solid #cbcbcb;padding:2px 6px;text-decoration:none;background-color:#fff}.yui-skin-sam .yui-dt-selected{border:1px solid #fff;background-color:#fff}
+
+/*
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+.yui-button{display:-moz-inline-box;display:inline-block;vertical-align:text-bottom;}.yui-button .first-child{display:block;*display:inline-block;}.yui-button button,.yui-button a{display:block;*display:inline-block;border:none;margin:0;}.yui-button button{background-color:transparent;*overflow:visible;cursor:pointer;}.yui-button a{text-decoration:none;}.yui-skin-sam .yui-button{border-width:1px 0;border-style:solid;border-color:#808080;background:url(../js/yui/assets/skins/sam/sprite.png) repeat-x 0 0;margin:auto .25em;}.yui-skin-sam .yui-button .first-child{border-width:0 1px;border-style:solid;border-color:#808080;margin:0 -1px;_margin:0;}.yui-skin-sam .yui-button button,.yui-skin-sam .yui-button a,.yui-skin-sam .yui-button a:visited{padding:0 10px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-button a{*line-height:1.875;*padding-bottom:1px;}.yui-skin-sam .yui-split-button button,.yui-skin-sam .yui-menu-button button{padding-right:20px;background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-button button{background-image:url(../js/yui/assets/skins/sam/menu-button-arrow.png);}.yui-skin-sam .yui-split-button button{background-image:url(../js/yui/assets/skins/sam/split-button-arrow.png);}.yui-skin-sam .yui-button-focus{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-focus .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-focus button{background-image:url(../js/yui/assets/skins/sam/split-button-arrow-focus.png);}.yui-skin-sam .yui-button-hover{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-hover .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-hover button{background-image:url(../js/yui/assets/skins/sam/split-button-arrow-hover.png);}.yui-skin-sam .yui-button-active{border-color:#7D98B8;background-position:0 -1700px;}.yui-skin-sam .yui-button-active .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-activeoption{border-color:#808080;background-position:0 0;}.yui-skin-sam .yui-split-button-activeoption .first-child{border-color:#808080;}.yui-skin-sam .yui-split-button-activeoption button{background-image:url(../js/yui/assets/skins/sam/split-button-arrow-active.png);}.yui-skin-sam .yui-radio-button-checked,.yui-skin-sam .yui-checkbox-button-checked{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-radio-button-checked .first-child,.yui-skin-sam .yui-checkbox-button-checked .first-child{border-color:#304369;}.yui-skin-sam .yui-radio-button-checked button,.yui-skin-sam .yui-checkbox-button-checked button{color:#fff;}.yui-skin-sam .yui-button-disabled{border-color:#ccc;background-position:0 -1500px;}.yui-skin-sam .yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-button-disabled button,.yui-skin-sam .yui-button-disabled a,.yui-skin-sam .yui-button-disabled a:visited{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-menu-button-disabled button{background-image:url(../js/yui/assets/skins/sam/menu-button-arrow-disabled.png);}.yui-skin-sam .yui-split-button-disabled button{background-image:url(../js/yui/assets/skins/sam/split-button-arrow-disabled.png);}
+
+/*
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+.yui-skin-sam .yui-pg-container{display:block;margin:6px 0;white-space:nowrap}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-previous,.yui-skin-sam .yui-pg-next,.yui-skin-sam .yui-pg-last,.yui-skin-sam .yui-pg-current,.yui-skin-sam .yui-pg-pages,.yui-skin-sam .yui-pg-page{display:inline-block;font-family:arial,helvetica,clean,sans-serif;padding:3px 6px;zoom:1}.yui-skin-sam .yui-pg-pages{padding:0}.yui-skin-sam .yui-pg-current{padding:3px 0}.yui-skin-sam a.yui-pg-first:link,.yui-skin-sam a.yui-pg-first:visited,.yui-skin-sam a.yui-pg-first:active,.yui-skin-sam a.yui-pg-first:hover,.yui-skin-sam a.yui-pg-previous:link,.yui-skin-sam a.yui-pg-previous:visited,.yui-skin-sam a.yui-pg-previous:active,.yui-skin-sam a.yui-pg-previous:hover,.yui-skin-sam a.yui-pg-next:link,.yui-skin-sam a.yui-pg-next:visited,.yui-skin-sam a.yui-pg-next:active,.yui-skin-sam a.yui-pg-next:hover,.yui-skin-sam a.yui-pg-last:link,.yui-skin-sam a.yui-pg-last:visited,.yui-skin-sam a.yui-pg-last:active,.yui-skin-sam a.yui-pg-last:hover,.yui-skin-sam a.yui-pg-page:link,.yui-skin-sam a.yui-pg-page:visited,.yui-skin-sam a.yui-pg-page:active,.yui-skin-sam a.yui-pg-page:hover{color:#06c;text-decoration:underline;outline:0}.yui-skin-sam span.yui-pg-first,.yui-skin-sam span.yui-pg-previous,.yui-skin-sam span.yui-pg-next,.yui-skin-sam span.yui-pg-last{color:#a6a6a6}.yui-skin-sam .yui-pg-page{background-color:#fff;border:1px solid #cbcbcb;padding:2px 6px;text-decoration:none}.yui-skin-sam .yui-pg-current-page{background-color:transparent;border:0;font-weight:bold;padding:3px 6px}.yui-skin-sam .yui-pg-page{margin-left:1px;margin-right:1px}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-previous{padding-left:0}.yui-skin-sam .yui-pg-next,.yui-skin-sam .yui-pg-last{padding-right:0}.yui-skin-sam .yui-pg-current,.yui-skin-sam .yui-pg-rpp-options{margin-left:1em;margin-right:1em}
rename from devtools/client/styleeditor/test/doc_uncached.css
rename to devtools/client/styleeditor/test/doc_short_string.css
deleted file mode 100644
--- a/devtools/client/styleeditor/test/doc_uncached.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<html>
-<head>
-  <title>uncached testcase</title>
-  <link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_uncached.css"/>
-</head>
-<body>
-	<div>uncached <span>testcase</span></div>
-</body>
-</html>
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
@@ -263,17 +263,16 @@ subsuite = clipboard
 [browser_webconsole_context_menu_object_in_sidebar.js]
 [browser_webconsole_context_menu_open_url.js]
 [browser_webconsole_context_menu_store_as_global.js]
 [browser_webconsole_csp_ignore_reflected_xss_message.js]
 skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these on windows
 [browser_webconsole_cspro.js]
 [browser_webconsole_document_focus.js]
 [browser_webconsole_duplicate_errors.js]
-skip-if = true #	Bug 1403907
 [browser_webconsole_errors_after_page_reload.js]
 [browser_webconsole_eval_in_debugger_stackframe.js]
 [browser_webconsole_eval_in_debugger_stackframe2.js]
 [browser_webconsole_execution_scope.js]
 [browser_webconsole_external_script_errors.js]
 [browser_webconsole_file_uri.js]
 skip-if = true #	Bug 1404382
 [browser_webconsole_filter_scroll.js]
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_duplicate_errors.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_duplicate_errors.js
@@ -1,49 +1,27 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that exceptions thrown by content don't show up twice in the Web
 // Console. See Bug 582201.
 
 "use strict";
 
 const INIT_URI = "data:text/html;charset=utf8,hello world";
 const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
-                 "test/test-duplicate-error.html";
+  "new-console-output/test/mochitest/test-duplicate-error.html";
 
-add_task(function* () {
-  yield loadTab(INIT_URI);
-
-  let hud = yield openConsole();
-
+add_task(async function () {
   // On e10s, the exception is triggered in child process
   // and is ignored by test harness
   if (!Services.appinfo.browserTabsRemoteAutostart) {
     expectUncaughtException();
   }
+  let hud = await openNewTabAndConsole(TEST_URI);
 
-  BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
+  await waitFor(() => findMessage(hud, "fooDuplicateError1", ".message.error"));
 
-  yield waitForMessages({
-    webconsole: hud,
-    messages: [{
-      text: "fooDuplicateError1",
-      category: CATEGORY_JS,
-      severity: SEVERITY_ERROR,
-    },
-    {
-      text: "test-duplicate-error.html",
-      category: CATEGORY_NETWORK,
-      severity: SEVERITY_LOG,
-    }],
-  });
-
-  let text = hud.outputNode.textContent;
-  let error1pos = text.indexOf("fooDuplicateError1");
-  ok(error1pos > -1, "found fooDuplicateError1");
-  if (error1pos > -1) {
-    ok(text.indexOf("fooDuplicateError1", error1pos + 1) == -1,
-      "no duplicate for fooDuplicateError1");
-  }
+  const errorMessages = hud.outputNode.querySelectorAll(".message.error");
+  is(errorMessages.length, 1, "There's only one error message for fooDuplicateError1");
+  is(errorMessages[0].querySelector(".message-repeats"), null,
+    "There is no repeat bubble on the error message")
 });
--- a/devtools/server/actors/stylesheets.js
+++ b/devtools/server/actors/stylesheets.js
@@ -489,18 +489,30 @@ var StyleSheetActor = protocol.ActorClas
     let request = consoleActor.getNetworkEventActorForURL(href);
     if (!request) {
       return null;
     }
     let content = request._response.content;
     if (request._discardResponseBody || !content) {
       return null;
     }
+    if (content.text.type != "longString") {
+      // For short strings, the text is available directly.
+      return {
+        content: content.text,
+        contentType: content.mimeType,
+      };
+    }
+    // For long strings, look up the actor that holds the full text.
+    let longStringActor = this.conn._getOrCreateActor(content.text.actor);
+    if (!longStringActor) {
+      return null;
+    }
     return {
-      content: content.text,
+      content: longStringActor.rawValue(),
       contentType: content.mimeType,
     };
   },
 
   /**
    * Protocol method to get the media rules for the stylesheet.
    */
   getMediaRules: function () {
--- a/devtools/server/tests/browser/browser_navigateEvents.js
+++ b/devtools/server/tests/browser/browser_navigateEvents.js
@@ -2,22 +2,26 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const URL1 = MAIN_DOMAIN + "navigate-first.html";
 const URL2 = MAIN_DOMAIN + "navigate-second.html";
 
-var EventEmitter = require("devtools/shared/event-emitter");
-var client;
+var isE10s = Services.appinfo.browserTabsRemoteAutostart;
 
 SpecialPowers.pushPrefEnv(
   {"set": [["dom.require_user_interaction_for_beforeunload", false]]});
 
+var signalAllEventsReceived;
+var onAllEventsReceived = new Promise(resolve => {
+  signalAllEventsReceived = resolve;
+});
+
 // State machine to check events order
 var i = 0;
 function assertEvent(event, data) {
   switch (i++) {
     case 0:
       is(event, "request", "Get first page load");
       is(data, URL1);
       break;
@@ -26,137 +30,147 @@ function assertEvent(event, data) {
       break;
     case 2:
       is(event, "unload-dialog", "We get the dialog on first page unload");
       break;
     case 3:
       is(event, "will-navigate", "The very first event is will-navigate on server side");
       is(data.newURI, URL2, "newURI property is correct");
       break;
-    case 4:
-      is(event, "request",
-        "RDP is async with messageManager, the request happens after will-navigate");
-      is(data, URL2);
-      break;
-    case 5:
+    case isE10s ? 4 : 5: // When e10s is disabled tabNavigated/request order is swapped
       is(event, "tabNavigated", "After the request, the client receive tabNavigated");
       is(data.state, "start", "state is start");
       is(data.url, URL2, "url property is correct");
       is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
       break;
+    case isE10s ? 5 : 4:
+      is(event, "request",
+        "RDP is async with messageManager, the request happens after will-navigate");
+      is(data, URL2);
+      break;
     case 6:
       is(event, "DOMContentLoaded");
-      // eslint-disable-next-line mozilla/no-cpows-in-tests
-      is(content.document.readyState, "interactive");
+      is(data.readyState, "interactive");
       break;
     case 7:
       is(event, "load");
-      // eslint-disable-next-line mozilla/no-cpows-in-tests
-      is(content.document.readyState, "complete");
+      is(data.readyState, "complete");
       break;
     case 8:
       is(event, "navigate",
         "Then once the second doc is loaded, we get the navigate event");
-      // eslint-disable-next-line mozilla/no-cpows-in-tests
-      is(content.document.readyState, "complete",
+      is(data.readyState, "complete",
         "navigate is emitted only once the document is fully loaded");
       break;
     case 9:
       is(event, "tabNavigated", "Finally, the receive the client event");
       is(data.state, "stop", "state is stop");
       is(data.url, URL2, "url property is correct");
       is(data.nativeConsoleAPI, true, "nativeConsoleAPI is correct");
 
-      // End of test!
-      cleanup();
+      signalAllEventsReceived();
       break;
   }
 }
 
 function waitForOnBeforeUnloadDialog(browser, callback) {
-  browser.addEventListener("DOMWillOpenModalDialog", function () {
-    executeSoon(() => {
-      let stack = browser.parentNode;
-      let dialogs = stack.getElementsByTagName("tabmodalprompt");
-      let {button0, button1} = dialogs[0].ui;
-      callback(button0, button1);
-    });
+  browser.addEventListener("DOMWillOpenModalDialog", async function (event) {
+    let stack = browser.parentNode;
+    let dialogs = stack.getElementsByTagName("tabmodalprompt");
+    await waitUntil(() => dialogs[0]);
+    let {button0, button1} = dialogs[0].ui;
+    callback(button0, button1);
   }, {capture: true, once: true});
 }
 
 var httpObserver = function (subject, topic, state) {
   let channel = subject.QueryInterface(Ci.nsIHttpChannel);
   let url = channel.URI.spec;
   // Only listen for our document request, as many other requests can happen
   if (url == URL1 || url == URL2) {
     assertEvent("request", url);
   }
 };
 Services.obs.addObserver(httpObserver, "http-on-modify-request");
 
-function onDOMContentLoaded() {
-  assertEvent("DOMContentLoaded");
-}
-function onLoad() {
-  assertEvent("load");
+function onMessage({ data }) {
+  assertEvent(data.event, data.data);
 }
 
-function getServerTabActor(callback) {
+async function connectAndAttachTab() {
   // Ensure having a minimal server
   initDebuggerServer();
 
   // Connect to this tab
   let transport = DebuggerServer.connectPipe();
-  client = new DebuggerClient(transport);
-  connectDebuggerClient(client).then(form => {
-    let actorID = form.actor;
-    client.attachTab(actorID, function (response, tabClient) {
-      // !Hack! Retrieve a server side object, the BrowserTabActor instance
-      let tabActor = DebuggerServer.searchAllConnectionsForActor(actorID);
-      callback(tabActor);
-    });
-  });
-
+  let client = new DebuggerClient(transport);
   client.addListener("tabNavigated", function (event, packet) {
     assertEvent("tabNavigated", packet);
   });
+  let form = await connectDebuggerClient(client);
+  let actorID = form.actor;
+  await client.attachTab(actorID);
+  return { client, actorID };
 }
 
-function test() {
+add_task(async function () {
   // Open a test tab
-  addTab(URL1).then(function (browser) {
-    getServerTabActor(function (tabActor) {
-      // In order to listen to internal will-navigate/navigate events
-      EventEmitter.on(tabActor, "will-navigate", function (data) {
-        assertEvent("will-navigate", data);
-      });
-      EventEmitter.on(tabActor, "navigate", function (data) {
-        assertEvent("navigate", data);
-      });
+  let browser = await addTab(URL1);
+
+  // Listen for alert() call being made in navigate-first during unload
+  waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) {
+    assertEvent("unload-dialog");
+    // accept to quit this page to another
+    btnLeave.click();
+  });
 
-      // Start listening for page load events
-      browser.addEventListener("DOMContentLoaded", onDOMContentLoaded, true);
-      browser.addEventListener("load", onLoad, true);
+  // Listen for messages sent by the content task
+  browser.messageManager.addMessageListener("devtools-test:event", onMessage);
+
+  let { client, actorID } = await connectAndAttachTab();
+  await ContentTask.spawn(browser, [actorID], async function (actorId) {
+    const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
+    const { DebuggerServer } = require("devtools/server/main");
+    const EventEmitter = require("devtools/shared/event-emitter");
 
-      // Listen for alert() call being made in navigate-first during unload
-      waitForOnBeforeUnloadDialog(browser, function (btnLeave, btnStay) {
-        assertEvent("unload-dialog");
-        // accept to quit this page to another
-        btnLeave.click();
+    // !Hack! Retrieve a server side object, the BrowserTabActor instance
+    let tabActor = DebuggerServer.searchAllConnectionsForActor(actorId);
+    // In order to listen to internal will-navigate/navigate events
+    EventEmitter.on(tabActor, "will-navigate", function (data) {
+      sendSyncMessage("devtools-test:event", {
+        event: "will-navigate",
+        data: { newURI: data.newURI }
+      });
+    });
+    EventEmitter.on(tabActor, "navigate", function (data) {
+      sendSyncMessage("devtools-test:event", {
+        event: "navigate",
+        data: { readyState: content.document.readyState }
       });
-
-      // Load another document in this doc to dispatch these events
-      assertEvent("load-new-document");
-      BrowserTestUtils.loadURI(gBrowser.selectedBrowser, URL2);
     });
+    // Forward DOMContentLoaded and load events
+    addEventListener("DOMContentLoaded", function () {
+      sendSyncMessage("devtools-test:event", {
+        event: "DOMContentLoaded",
+        data: { readyState: content.document.readyState }
+      });
+    }, { capture: true });
+    addEventListener("load", function () {
+      sendSyncMessage("devtools-test:event", {
+        event: "load",
+        data: { readyState: content.document.readyState }
+      });
+    }, { capture: true });
   });
-}
+
+  // Load another document in this doc to dispatch these events
+  assertEvent("load-new-document");
+  BrowserTestUtils.loadURI(browser, URL2);
 
-function cleanup() {
-  let browser = gBrowser.selectedBrowser;
-  browser.removeEventListener("DOMContentLoaded", onDOMContentLoaded);
-  browser.removeEventListener("load", onLoad);
-  client.close().then(function () {
-    Services.obs.addObserver(httpObserver, "http-on-modify-request");
-    DebuggerServer.destroy();
-    finish();
-  });
-}
+  // Wait for all events to be received
+  await onAllEventsReceived;
+
+  // Cleanup
+  browser.messageManager.removeMessageListener("devtools-test:event", onMessage);
+  await client.close();
+  Services.obs.addObserver(httpObserver, "http-on-modify-request");
+  DebuggerServer.destroy();
+});
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1580,16 +1580,21 @@ HTMLMediaElement::MozRequestDebugInfo(Er
   RefPtr<Promise> promise = CreateDOMPromise(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   nsAutoString result;
   GetMozDebugReaderData(result);
 
+  if (mVideoFrameContainer) {
+    result.AppendPrintf("Compositor dropped frame(including when element's invisible): %u\n",
+                        mVideoFrameContainer->GetDroppedImageCount());
+  }
+
   if (mMediaKeys) {
     nsString EMEInfo;
     GetEMEInfo(EMEInfo);
     result.AppendLiteral("EME Info: ");
     result.Append(EMEInfo);
     result.AppendLiteral("\n");
   }
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -432,16 +432,19 @@ TabChild::TabChild(nsIContentChild* aMan
 #if defined(XP_WIN) && defined(ACCESSIBILITY)
   , mNativeWindowHandle(0)
 #endif
 #if defined(ACCESSIBILITY)
   , mTopLevelDocAccessibleChild(nullptr)
 #endif
   , mPendingDocShellIsActive(false)
   , mPendingDocShellReceivedMessage(false)
+  , mPendingRenderLayers(false)
+  , mPendingRenderLayersReceivedMessage(false)
+  , mPendingLayerObserverEpoch(0)
   , mPendingDocShellBlockers(0)
   , mWidgetNativeData(0)
 {
   mozilla::HoldJSObjects(this);
 
   nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this)));  // for capture by the lambda
   mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
                                                    const nsTArray<TouchBehaviorFlags>& aFlags)
@@ -2658,16 +2661,20 @@ TabChild::AddPendingDocShellBlocker()
 void
 TabChild::RemovePendingDocShellBlocker()
 {
   mPendingDocShellBlockers--;
   if (!mPendingDocShellBlockers && mPendingDocShellReceivedMessage) {
     mPendingDocShellReceivedMessage = false;
     InternalSetDocShellIsActive(mPendingDocShellIsActive);
   }
+  if (!mPendingDocShellBlockers && mPendingRenderLayersReceivedMessage) {
+    mPendingRenderLayersReceivedMessage = false;
+    RecvRenderLayers(mPendingRenderLayers, mPendingLayerObserverEpoch);
+  }
 }
 
 void
 TabChild::InternalSetDocShellIsActive(bool aIsActive)
 {
   // docshell is consider prerendered only if not active yet
   mIsPrerendered &= !aIsActive;
   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
@@ -2691,16 +2698,23 @@ TabChild::RecvSetDocShellIsActive(const 
 
   InternalSetDocShellIsActive(aIsActive);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverEpoch)
 {
+  if (mPendingDocShellBlockers > 0) {
+    mPendingRenderLayersReceivedMessage = true;
+    mPendingRenderLayers = aEnabled;
+    mPendingLayerObserverEpoch = aLayerObserverEpoch;
+    return IPC_OK();
+  }
+
   // Since requests to change the rendering state come in from both the hang
   // monitor channel and the PContent channel, we have an ordering problem. This
   // code ensures that we respect the order in which the requests were made and
   // ignore stale requests.
   if (mLayerObserverEpoch >= aLayerObserverEpoch) {
     return IPC_OK();
   }
   mLayerObserverEpoch = aLayerObserverEpoch;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -978,18 +978,30 @@ private:
   uintptr_t mNativeWindowHandle;
 #endif // defined(XP_WIN)
 
 #if defined(ACCESSIBILITY)
   PDocAccessibleChild* mTopLevelDocAccessibleChild;
 #endif
   bool mCoalesceMouseMoveEvents;
 
+  // In some circumstances, a DocShell might be in a state where it is
+  // "blocked", and we should not attempt to change its active state or
+  // the underlying PresShell state until the DocShell becomes unblocked.
+  // It is possible, however, for the parent process to send commands to
+  // change those states while the DocShell is blocked. We store those
+  // states temporarily as "pending", and only apply them once the DocShell
+  // is no longer blocked.
   bool mPendingDocShellIsActive;
   bool mPendingDocShellReceivedMessage;
+  bool mPendingRenderLayers;
+  bool mPendingRenderLayersReceivedMessage;
+  uint64_t mPendingLayerObserverEpoch;
+  // When mPendingDocShellBlockers is greater than 0, the DocShell is blocked,
+  // and once it reaches 0, it is no longer blocked.
   uint32_t mPendingDocShellBlockers;
 
   WindowsHandle mWidgetNativeData;
 
   // This state is used to keep track of the current visible tabs (the ones rendering
   // layers). There may be more than one if there are multiple browser windows open, or
   // tabs are being warmed up. There may be none if this process does not host any
   // visible or warming tabs.
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -152,17 +152,17 @@ TabParent::TabParent(nsIContentParent* a
   , mDimensions(0, 0)
   , mOrientation(0)
   , mDPI(0)
   , mRounding(0)
   , mDefaultScale(0)
   , mUpdatedDimensions(false)
   , mSizeMode(nsSizeMode_Normal)
   , mManager(aManager)
-  , mDocShellIsActive(false)
+  , mDocShellIsActive(true)
   , mMarkedDestroying(false)
   , mIsDestroyed(false)
   , mChromeFlags(aChromeFlags)
   , mDragValid(false)
   , mInitedByParent(false)
   , mTabId(aTabId)
   , mCreatingWindow(false)
   , mCursor(eCursorInvalid)
--- a/dom/media/ChannelMediaDecoder.cpp
+++ b/dom/media/ChannelMediaDecoder.cpp
@@ -408,16 +408,18 @@ ChannelMediaDecoder::DurationChanged()
 }
 
 void
 ChannelMediaDecoder::DownloadProgressed()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
 
+  GetOwner()->DownloadProgressed();
+
   using StatsPromise = MozPromise<MediaStatistics, bool, true>;
   InvokeAsync(GetStateMachine()->OwnerThread(),
               __func__,
               [
                 playbackStats = mPlaybackStatistics,
                 res = RefPtr<BaseMediaResource>(mResource),
                 duration = mDuration,
                 pos = mPlaybackPosition
@@ -432,18 +434,18 @@ ChannelMediaDecoder::DownloadProgressed(
       __func__,
       [ =, self = RefPtr<ChannelMediaDecoder>(this) ](MediaStatistics aStats) {
         if (IsShutdown()) {
           return;
         }
         mCanPlayThrough = aStats.CanPlayThrough();
         GetStateMachine()->DispatchCanPlayThrough(mCanPlayThrough);
         mResource->ThrottleReadahead(ShouldThrottleDownload(aStats));
-        AbstractThread::AutoEnter context(AbstractMainThread());
-        GetOwner()->DownloadProgressed();
+        // Update readyState since mCanPlayThrough might have changed.
+        GetOwner()->UpdateReadyState();
       },
       []() { MOZ_ASSERT_UNREACHABLE("Promise not resolved"); });
 }
 
 /* static */ ChannelMediaDecoder::PlaybackRateInfo
 ChannelMediaDecoder::ComputePlaybackRate(const MediaChannelStatistics& aStats,
                                          BaseMediaResource* aResource,
                                          double aDuration)
--- a/dom/media/systemservices/CamerasChild.h
+++ b/dom/media/systemservices/CamerasChild.h
@@ -148,37 +148,37 @@ class CamerasChild final : public PCamer
 
 public:
   // We are owned by the PBackground thread only. CamerasSingleton
   // takes a non-owning reference.
   NS_INLINE_DECL_REFCOUNTING(CamerasChild)
 
   // IPC messages recevied, received on the PBackground thread
   // these are the actual callbacks with data
-  virtual mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&,
-                                                   mozilla::ipc::Shmem&&,
-                                                   const VideoFrameProperties & prop) override;
-  virtual mozilla::ipc::IPCResult RecvFrameSizeChange(const CaptureEngine&, const int&,
-                                                      const int& w, const int& h) override;
+  mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&,
+                                           mozilla::ipc::Shmem&&,
+                                           const VideoFrameProperties & prop) override;
+  mozilla::ipc::IPCResult RecvFrameSizeChange(const CaptureEngine&, const int&,
+                                              const int& w, const int& h) override;
 
-  virtual mozilla::ipc::IPCResult RecvDeviceChange() override;
-  virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
+  mozilla::ipc::IPCResult RecvDeviceChange() override;
+  int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
   int SetFakeDeviceChangeEvents();
 
   // these are response messages to our outgoing requests
-  virtual mozilla::ipc::IPCResult RecvReplyNumberOfCaptureDevices(const int&) override;
-  virtual mozilla::ipc::IPCResult RecvReplyNumberOfCapabilities(const int&) override;
-  virtual mozilla::ipc::IPCResult RecvReplyAllocateCaptureDevice(const int&) override;
-  virtual mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
-  virtual mozilla::ipc::IPCResult RecvReplyGetCaptureDevice(const nsCString& device_name,
+  mozilla::ipc::IPCResult RecvReplyNumberOfCaptureDevices(const int&) override;
+  mozilla::ipc::IPCResult RecvReplyNumberOfCapabilities(const int&) override;
+  mozilla::ipc::IPCResult RecvReplyAllocateCaptureDevice(const int&) override;
+  mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
+  mozilla::ipc::IPCResult RecvReplyGetCaptureDevice(const nsCString& device_name,
                                                             const nsCString& device_id,
                                                             const bool& scary) override;
-  virtual mozilla::ipc::IPCResult RecvReplyFailure(void) override;
-  virtual mozilla::ipc::IPCResult RecvReplySuccess(void) override;
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+  mozilla::ipc::IPCResult RecvReplyFailure(void) override;
+  mozilla::ipc::IPCResult RecvReplySuccess(void) override;
+  void ActorDestroy(ActorDestroyReason aWhy) override;
 
   // the webrtc.org ViECapture calls are mirrored here, but with access
   // to a specific PCameras instance to communicate over. These also
   // run on the MediaManager thread
   int NumberOfCaptureDevices(CaptureEngine aCapEngine);
   int NumberOfCapabilities(CaptureEngine aCapEngine,
                            const char* deviceUniqueIdUTF8);
   int ReleaseCaptureDevice(CaptureEngine aCapEngine,
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -467,17 +467,17 @@ CamerasParent::RecvNumberOfCaptureDevice
       int num = -1;
       if (auto engine = self->EnsureInitialized(aCapEngine)) {
         if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
           num = devInfo->NumberOfDevices();
         }
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, num]() -> nsresult {
-          if (self->IsShuttingDown()) {
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           if (num < 0) {
             LOG(("RecvNumberOfCaptureDevices couldn't find devices"));
             Unused << self->SendReplyFailure();
             return NS_ERROR_FAILURE;
           } else {
             LOG(("RecvNumberOfCaptureDevices: %d", num));
@@ -499,17 +499,17 @@ CamerasParent::RecvEnsureInitialized(con
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, aCapEngine]() -> nsresult {
       bool result = self->EnsureInitialized(aCapEngine);
 
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, result]() -> nsresult {
-          if (self->IsShuttingDown()) {
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           if (!result) {
             LOG(("RecvEnsureInitialized failed"));
             Unused << self->SendReplyFailure();
             return NS_ERROR_FAILURE;
           } else {
             LOG(("RecvEnsureInitialized succeeded"));
@@ -537,17 +537,17 @@ CamerasParent::RecvNumberOfCapabilities(
       int num = -1;
       if (auto engine = self->EnsureInitialized(aCapEngine)) {
         if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
           num = devInfo->NumberOfCapabilities(unique_id.get());
         }
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, num]() -> nsresult {
-          if (self->IsShuttingDown()) {
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           if (num < 0) {
             LOG(("RecvNumberOfCapabilities couldn't find capabilities"));
             Unused << self->SendReplyFailure();
             return NS_ERROR_FAILURE;
           } else {
             LOG(("RecvNumberOfCapabilities: %d", num));
@@ -588,17 +588,17 @@ CamerasParent::RecvGetCaptureCapability(
             self->mAllCandidateCapabilities.emplace(nsCString(unique_id), candidateCapabilities);
           } else {
             (iter->second).emplace(num, webrtcCaps);
           }
         }
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, webrtcCaps, error]() -> nsresult {
-          if (self->IsShuttingDown()) {
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           VideoCaptureCapability capCap(webrtcCaps.width,
                                    webrtcCaps.height,
                                    webrtcCaps.maxFPS,
                                    webrtcCaps.expectedCaptureDelay,
                                    webrtcCaps.rawType,
                                    webrtcCaps.codecType,
@@ -648,17 +648,17 @@ CamerasParent::RecvGetCaptureDevice(cons
         }
       }
       if (!error) {
         name.Assign(deviceName);
         uniqueId.Assign(deviceUniqueId);
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, error, name, uniqueId, devicePid]() {
-          if (self->IsShuttingDown()) {
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           if (error) {
             LOG(("GetCaptureDevice failed: %d", error));
             Unused << self->SendReplyFailure();
             return NS_ERROR_FAILURE;
           }
           bool scary = (devicePid == getpid());
@@ -759,17 +759,17 @@ CamerasParent::RecvAllocateCaptureDevice
           engine->WithEntry(numdev, [&error](VideoEngine::CaptureEntry& cap) {
             if (cap.VideoCapture()) {
               error = 0;
             }
           });
         }
         RefPtr<nsIRunnable> ipc_runnable =
           media::NewRunnableFrom([self, numdev, error]() -> nsresult {
-            if (self->IsShuttingDown()) {
+            if (!self->mChildIsAlive) {
               return NS_ERROR_FAILURE;
             }
             if (error) {
               Unused << self->SendReplyFailure();
               return NS_ERROR_FAILURE;
             } else {
               LOG(("Allocated device nr %d", numdev));
               Unused << self->SendReplyAllocateCaptureDevice(numdev);
@@ -805,18 +805,17 @@ CamerasParent::RecvReleaseCaptureDevice(
   LOG(("RecvReleaseCamera device nr %d", numdev));
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, aCapEngine, numdev]() -> nsresult {
       int error = self->ReleaseCaptureDevice(aCapEngine, numdev);
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, error, numdev]() -> nsresult {
-          if (self->IsShuttingDown()) {
-            LOG(("In Shutdown, not Releasing"));
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           if (error) {
             Unused << self->SendReplyFailure();
             LOG(("Failed to free device nr %d", numdev));
             return NS_ERROR_FAILURE;
           } else {
             Unused << self->SendReplySuccess();
@@ -928,17 +927,17 @@ CamerasParent::RecvStartCapture(const Ca
           if (!error) {
             cap.VideoCapture()->RegisterCaptureDataCallback(
               static_cast<rtc::VideoSinkInterface<webrtc::VideoFrame>*>(*cbh));
           }
         });
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, error]() -> nsresult {
-          if (self->IsShuttingDown()) {
+          if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           if (!error) {
             Unused << self->SendReplySuccess();
             return NS_OK;
           } else {
             Unused << self->SendReplyFailure();
             return NS_ERROR_FAILURE;
@@ -989,17 +988,17 @@ CamerasParent::RecvStopCapture(const Cap
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, aCapEngine, capnum]() -> nsresult {
       self->StopCapture(aCapEngine, capnum);
       return NS_OK;
     });
   nsresult rv = DispatchToVideoCaptureThread(webrtc_runnable);
-  if (self->IsShuttingDown()) {
+  if (!self->mChildIsAlive) {
     if (NS_FAILED(rv)) {
       return IPC_FAIL_NO_REASON(this);
     }
   } else {
     if (NS_SUCCEEDED(rv)) {
       if (!SendReplySuccess()) {
         return IPC_FAIL_NO_REASON(this);
       }
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -41,17 +41,17 @@ class CallbackHelper :
   public rtc::VideoSinkInterface<webrtc::VideoFrame>
 {
 public:
   CallbackHelper(CaptureEngine aCapEng, uint32_t aStreamId, CamerasParent *aParent)
     : mCapEngine(aCapEng), mStreamId(aStreamId), mParent(aParent) {};
 
   // These callbacks end up running on the VideoCapture thread.
   // From  VideoCaptureCallback
-  virtual void OnFrame(const webrtc::VideoFrame& videoFrame) override;
+  void OnFrame(const webrtc::VideoFrame& videoFrame) override;
 
   friend CamerasParent;
 
 private:
   CaptureEngine mCapEngine;
   uint32_t mStreamId;
   CamerasParent *mParent;
 };
@@ -78,35 +78,35 @@ class CamerasParent :  public PCamerasPa
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
 public:
   static already_AddRefed<CamerasParent> Create();
 
   // Messages received form the child. These run on the IPC/PBackground thread.
-  virtual mozilla::ipc::IPCResult
+  mozilla::ipc::IPCResult
   RecvAllocateCaptureDevice(const CaptureEngine& aEngine,
                             const nsCString& aUnique_idUTF8,
                             const ipc::PrincipalInfo& aPrincipalInfo) override;
-  virtual mozilla::ipc::IPCResult RecvReleaseCaptureDevice(const CaptureEngine&,
-                                                           const int&) override;
-  virtual mozilla::ipc::IPCResult RecvNumberOfCaptureDevices(const CaptureEngine&) override;
-  virtual mozilla::ipc::IPCResult RecvNumberOfCapabilities(const CaptureEngine&,
-                                                           const nsCString&) override;
-  virtual mozilla::ipc::IPCResult RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
-                                                           const int&) override;
-  virtual mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
-  virtual mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
-                                                   const VideoCaptureCapability&) override;
-  virtual mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
-  virtual mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
-  virtual mozilla::ipc::IPCResult RecvAllDone() override;
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
-  virtual mozilla::ipc::IPCResult RecvEnsureInitialized(const CaptureEngine&) override;
+  mozilla::ipc::IPCResult RecvReleaseCaptureDevice(const CaptureEngine&,
+                                                   const int&) override;
+  mozilla::ipc::IPCResult RecvNumberOfCaptureDevices(const CaptureEngine&) override;
+  mozilla::ipc::IPCResult RecvNumberOfCapabilities(const CaptureEngine&,
+                                                   const nsCString&) override;
+  mozilla::ipc::IPCResult RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
+                                                   const int&) override;
+  mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
+  mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
+                                           const VideoCaptureCapability&) override;
+  mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
+  mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
+  mozilla::ipc::IPCResult RecvAllDone() override;
+  void ActorDestroy(ActorDestroyReason aWhy) override;
+  mozilla::ipc::IPCResult RecvEnsureInitialized(const CaptureEngine&) override;
 
   nsIEventTarget* GetBackgroundEventTarget() { return mPBackgroundEventTarget; };
   bool IsShuttingDown()
   {
     return !mChildIsAlive || mDestroyed || !mWebRTCAlive;
   };
   ShmemBuffer GetBuffer(size_t aSize);
 
--- a/dom/media/test/test_bug686942.html
+++ b/dom/media/test/test_bug686942.html
@@ -10,20 +10,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686942">Mozilla Bug 686942</a>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-if (navigator.platform.startsWith("Win")) {
-  SimpleTest.expectAssertions(0, 2);
-}
-
 var manager = new MediaTestManager;
 
 function onloaded(event) {
   var v = event.target;
   v.removeEventListener("loadedmetadata", onloaded);
   v.currentTime = v.duration;
   return;
 }
--- a/dom/media/test/test_seek_out_of_range.html
+++ b/dom/media/test/test_seek_out_of_range.html
@@ -5,78 +5,44 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-if (navigator.platform.startsWith("Win")) {
-  SimpleTest.expectAssertions(0, 10);
-}
-
 var manager = new MediaTestManager;
 
 // Test if the ended event works correctly.
 
-function startTest(e) {
-  var v = e.target;
-  checkMetadata(v._name, v, v._test);
-  is(v._loadedMetadata, false, "Should only receive one loadedmetadata event for " + v._name);
-  v._loadedMetadata = true;
-  v.currentTime = 3.0 * v.duration;
-}
-
-function playbackEnded(e) {
-  var v = e.target;
-  // We should have dispatched an ended event when we seeked to the end of
-  // media, but we want the ended event which dispatches once playback has
-  // completed after the seek to the beginning.
-  if (!v._played)
-    return;
-  ok(v.ended, "Checking ended set after seeking to EOF and playing for " + v._name);
-  ok(!v._finished, "Should only hit the end once for " + v._name);
-  v._finished = true;
-  removeNodeAndSource(v);
-  manager.finished(v.token);
-}
-
-function endSeek(e) {
-  var v = e.target;
-  if (v._seeked)
-    return;
-  v._seeked = true;
-  ok(Math.abs(v.duration - v.currentTime) < 0.1,
-     "Should be at end of media for " + v._name + " t=" + v.currentTime + " d=" + v.duration);
-  v.play();
-}
-
-function playing(e) {
-  e.target._played = true;
-}
-
-function initTest(test, token) {
+async function initTest(test, token) {
   var type = getMajorMimeType(test.type);
   var v = document.createElement(type);
   v.preload = "auto";
   v.token = token;
   manager.started(token);
   v.src = test.name;
   v._name = test.name;
-  v._finished = false;
-  v._test = test;
-  v._loadedMetadata = false;
-  v._seeked = false;
-  v._played = false;
-  v.addEventListener("loadedmetadata", startTest);
-  v.addEventListener("playing", playing);
-  v.addEventListener("seeked", endSeek);
-  v.addEventListener("ended", playbackEnded);
   document.body.appendChild(v);
+
+  await once(v, "loadedmetadata");
+  info(`${v._name}: seeking to the end of the media.`);
+  v.currentTime = 3.0 * v.duration;
+  // Wait for 'seeked' and 'ended' to be fired.
+  await Promise.all([once(v, "seeked"), once(v, "ended")]);
+  // Check currentTime is near the end of the media.
+  ok(Math.abs(v.duration - v.currentTime) < 0.1,
+     "Should be at end of media for " + v._name + " t=" + v.currentTime + " d=" + v.duration);
+  // Call play() to start playback from the beginning.
+  v.play();
+  await once(v, "ended");
+  ok(v.ended, "Checking ended set after seeking to EOF and playing for " + v._name);
+  removeNodeAndSource(v);
+  manager.finished(v.token);
 }
 
 manager.runTests(gSmallTests, initTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -238,30 +238,28 @@ ContentClient::BeginPaint(PaintedLayer* 
   // types, or we failed to unrotate the buffer when requested. In any case,
   // we need to allocate a new one and prepare it for drawing.
   if (!dest.mCanReuseBuffer) {
     uint32_t bufferFlags = 0;
     if (dest.mBufferMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
       bufferFlags |= BUFFER_COMPONENT_ALPHA;
     }
 
-    RefPtr<RotatedBuffer> newBuffer;
-    if (Factory::ReasonableSurfaceSize(IntSize(dest.mBufferRect.Width(), dest.mBufferRect.Height()))) {
-      newBuffer = CreateBuffer(result.mContentType, dest.mBufferRect, bufferFlags);
+    RefPtr<RotatedBuffer> newBuffer = CreateBuffer(result.mContentType,
+                                                   dest.mBufferRect,
+                                                   bufferFlags);
 
-      if (!newBuffer) {
+    if (!newBuffer) {
+      if (Factory::ReasonableSurfaceSize(IntSize(dest.mBufferRect.Width(), dest.mBufferRect.Height()))) {
         gfxCriticalNote << "Failed buffer for "
                         << dest.mBufferRect.X() << ", "
                         << dest.mBufferRect.Y() << ", "
                         << dest.mBufferRect.Width() << ", "
                         << dest.mBufferRect.Height();
       }
-    }
-
-    if (!newBuffer) {
       Clear();
       return result;
     }
 
     if (!newBuffer->Lock(lockMode)) {
       gfxCriticalNote << "Failed to lock new back buffer.";
       Clear();
       return result;
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -7212,39 +7212,40 @@ nsCSSFrameConstructor::CheckBitsForLazyF
 // Returns true if this operation can be lazy, false if not.
 //
 // FIXME(emilio, bug 1410020): This function assumes that the flattened tree
 // parent of all the appended children is the same, which, afaict, is not
 // necessarily true.
 //
 // But we disable lazy frame construction for shadow trees... We should fix
 // that, too.
+//
+// NOTE(emilio): The IsXULElement check is pretty unfortunate, but there's tons
+// of browser chrome code that rely on XBL bindings getting synchronously loaded
+// as soon as the elements get inserted in the DOM.
 bool
 nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
                                             nsIContent* aContainer,
                                             nsIContent* aChild)
 {
-  if (mPresShell->GetPresContext()->IsChrome() || !aContainer ||
-      aContainer->IsInNativeAnonymousSubtree() || aContainer->IsXULElement()) {
+  if (!aContainer || aContainer->IsInNativeAnonymousSubtree() ||
+      aContainer->IsXULElement()) {
     return false;
   }
 
   if (aOperation == CONTENTINSERT) {
-    if (aChild->IsRootOfAnonymousSubtree() ||
-        (aChild->HasFlag(NODE_IS_IN_SHADOW_TREE) &&
-         !aChild->IsInNativeAnonymousSubtree()) ||
-        aChild->IsXULElement()) {
+    if (aChild->IsRootOfAnonymousSubtree() || aChild->IsXULElement()) {
       return false;
     }
   } else { // CONTENTAPPEND
     NS_ASSERTION(aOperation == CONTENTAPPEND,
                  "operation should be either insert or append");
     for (nsIContent* child = aChild; child; child = child->GetNextSibling()) {
       NS_ASSERTION(!child->IsRootOfAnonymousSubtree(),
-                   "Should be coming through the CONTENTAPPEND case");
+                   "Should be coming through the CONTENTINSERT case");
       if (child->IsXULElement()) {
         return false;
       }
     }
   }
 
   // We can construct lazily; just need to set suitable bits in the content
   // tree.
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -438,32 +438,48 @@ OffsetToAlignedStaticPos(const ReflowInp
   WritingMode pcWM = aPlaceholderContainer->GetWritingMode();
 
   // Find what axis aAbsPosCBAxis corresponds to, in placeholder's parent's
   // writing-mode.
   LogicalAxis pcAxis = (pcWM.IsOrthogonalTo(aAbsPosCBWM)
                         ? GetOrthogonalAxis(aAbsPosCBAxis)
                         : aAbsPosCBAxis);
 
+  const bool placeholderContainerIsContainingBlock =
+    aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame;
+
   LayoutFrameType parentType = aPlaceholderContainer->Type();
   LogicalSize alignAreaSize(pcWM);
   if (parentType == LayoutFrameType::FlexContainer) {
-    // The alignment container is the flex container's content box:
-    alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
-    LogicalMargin pcBorderPadding =
-      aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
-    alignAreaSize -= pcBorderPadding.Size(pcWM);
+    // We store the frame rect in FinishAndStoreOverflow, which runs _after_
+    // reflowing the absolute frames, so handle the special case of the frame
+    // being the actual containing block here, by getting the size from
+    // aAbsPosCBSize.
+    //
+    // The alignment container is the flex container's content box.
+    if (placeholderContainerIsContainingBlock) {
+      alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
+      // aAbsPosCBSize is the padding-box, so substract the padding to get the
+      // content box.
+      alignAreaSize -=
+        aPlaceholderContainer->GetLogicalUsedPadding(pcWM).Size(pcWM);
+    } else {
+      alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
+      LogicalMargin pcBorderPadding =
+        aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
+      alignAreaSize -= pcBorderPadding.Size(pcWM);
+    }
   } else if (parentType == LayoutFrameType::GridContainer) {
     // This abspos elem's parent is a grid container. Per CSS Grid 10.1 & 10.2:
     //  - If the grid container *also* generates the abspos containing block (a
     // grid area) for this abspos child, we use that abspos containing block as
     // the alignment container, too. (And its size is aAbsPosCBSize.)
     //  - Otherwise, we use the grid's padding box as the alignment container.
     // https://drafts.csswg.org/css-grid/#static-position
-    if (aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame) {
+    if (placeholderContainerIsContainingBlock) {
       // The alignment container is the grid area that we're using as the
       // absolute containing block.
       alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
     } else {
       // The alignment container is a the grid container's padding box (which
       // we can get by subtracting away its border from frame's size):
       alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
       LogicalMargin pcBorder =
--- a/layout/printing/ipc/RemotePrintJobParent.cpp
+++ b/layout/printing/ipc/RemotePrintJobParent.cpp
@@ -271,12 +271,20 @@ RemotePrintJobParent::~RemotePrintJobPar
 void
 RemotePrintJobParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (mPrintDeviceContext) {
     mPrintDeviceContext->UnregisterPageDoneCallback();
   }
 
   mIsDoingPrinting = false;
+
+  // If progress dialog is opened, notify closing it.
+  for (auto listener : mPrintProgressListeners) {
+    listener->OnStateChange(nullptr,
+                            nullptr,
+                            nsIWebProgressListener::STATE_STOP,
+                            NS_OK);
+  }
 }
 
 } // namespace layout
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-001-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<meta charset="utf-8">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: block;
+  width: 200px;
+  height: 200px;
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  left: 50px;
+  top: 50px;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-001.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>CSS Test: Absolutely positioned children of flex container with CSS align</title>
+<meta charset="utf-8">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1386654">
+<link rel="match" href="position-absolute-containing-block-001-ref.html">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 200px;
+  height: 200px;
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-002-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<meta charset="utf-8">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: block;
+  width: 200px;
+  height: 200px;
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  left: 60px;
+  top: 60px;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-002.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>CSS Test: Absolutely positioned children of flex container with CSS align</title>
+<meta charset="utf-8">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1386654">
+<link rel="match" href="position-absolute-containing-block-002-ref.html">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 180px;
+  height: 180px;
+
+  /* Expand the background area to 200px, without touching the content-box,
+     which is what flex absolute children should be aligned relative to. */
+  border-top: 5px solid yellow;
+  padding-top: 15px;
+  border-left: 5px solid yellow;
+  padding-left: 15px;
+
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
--- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list
+++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list
@@ -208,8 +208,12 @@ fails == flexbox-min-height-auto-002b.ht
 == flexbox-writing-mode-007.html flexbox-writing-mode-007-ref.html
 == flexbox-writing-mode-008.html flexbox-writing-mode-008-ref.html
 == flexbox-writing-mode-009.html flexbox-writing-mode-009-ref.html
 
 # Single-line size clamping
 == flexbox-single-line-clamp-1.html flexbox-single-line-clamp-1-ref.html
 == flexbox-single-line-clamp-2.html flexbox-single-line-clamp-2-ref.html
 == flexbox-single-line-clamp-3.html flexbox-single-line-clamp-3-ref.html
+
+# Flexbox as an absolute containing block.
+== position-absolute-containing-block-001.html position-absolute-containing-block-001-ref.html
+== position-absolute-containing-block-002.html position-absolute-containing-block-002-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/style/CachedAnonBoxStyles.cpp
@@ -0,0 +1,71 @@
+/* -*- 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/. */
+
+#include "nsIMemoryReporter.h"
+#include "mozilla/CachedAnonBoxStyles.h"
+#include "mozilla/ServoStyleContext.h"
+
+namespace mozilla {
+
+void
+CachedAnonBoxStyles::Insert(ServoStyleContext* aStyle)
+{
+  MOZ_ASSERT(aStyle);
+  MOZ_ASSERT(aStyle->IsInheritingAnonBox());
+
+  if (IsEmpty()) {
+    RefPtr<ServoStyleContext> s = aStyle;
+    mBits = reinterpret_cast<uintptr_t>(s.forget().take());
+    MOZ_ASSERT(!IsEmpty() && !IsIndirect());
+  } else if (IsIndirect()) {
+    AsIndirect()->AppendElement(aStyle);
+  } else {
+    IndirectCache* cache = new IndirectCache();
+    cache->AppendElement(dont_AddRef(AsDirect()));
+    cache->AppendElement(aStyle);
+    mBits = reinterpret_cast<uintptr_t>(cache) | 1;
+    MOZ_ASSERT(IsIndirect());
+  }
+}
+
+ServoStyleContext*
+CachedAnonBoxStyles::Lookup(nsAtom* aAnonBox) const
+{
+  MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
+  if (IsIndirect()) {
+    for (auto& style : *AsIndirect()) {
+      if (style->GetPseudo() == aAnonBox) {
+        return style;
+      }
+    }
+
+    return nullptr;
+  }
+
+  ServoStyleContext* direct = AsDirect();
+  return direct && direct->GetPseudo() == aAnonBox ? direct : nullptr;
+}
+
+void
+CachedAnonBoxStyles::AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const
+{
+  if (IsIndirect()) {
+    for (auto& style : *AsIndirect()) {
+      if (!aSizes.mState.HaveSeenPtr(style)) {
+        style->AddSizeOfIncludingThis(aSizes, aCVsSize);
+      }
+    }
+
+    return;
+  }
+
+  ServoStyleContext* direct = AsDirect();
+  if (direct && !aSizes.mState.HaveSeenPtr(direct)) {
+    direct->AddSizeOfIncludingThis(aSizes, aCVsSize);
+  }
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/style/CachedAnonBoxStyles.h
@@ -0,0 +1,67 @@
+/* -*- 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/. */
+
+#ifndef mozilla_CachedAnonBoxStyles_h
+#define mozilla_CachedAnonBoxStyles_h
+
+#include "nsAtom.h"
+#include "nsTArray.h"
+
+class nsWindowSizes;
+
+namespace mozilla {
+
+class ServoStyleContext;
+
+// Cache of anonymous box styles that inherit from a given style.
+//
+// To minimize memory footprint, the cache is word-sized with a tagged pointer
+// If there is only one entry, it's stored inline. If there are more, they're
+// stored in an out-of-line buffer. See bug 1429126 comment 0 and comment 1 for
+// the measurements and rationale that influenced the design.
+class CachedAnonBoxStyles
+{
+public:
+  void Insert(ServoStyleContext* aStyle);
+  ServoStyleContext* Lookup(nsAtom* aAnonBox) const;
+
+  CachedAnonBoxStyles() : mBits(0) {}
+  ~CachedAnonBoxStyles()
+  {
+    if (IsIndirect()) {
+      delete AsIndirect();
+    } else if (!IsEmpty()) {
+      RefPtr<ServoStyleContext> ref = dont_AddRef(AsDirect());
+    }
+  }
+
+  void AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const;
+
+private:
+  // See bug 1429126 comment 1 for the choice of four here.
+  typedef AutoTArray<RefPtr<ServoStyleContext>, 4> IndirectCache;
+
+  bool IsEmpty() const { return !mBits; }
+  bool IsIndirect() const { return (mBits & 1); }
+
+  ServoStyleContext* AsDirect() const
+  {
+    MOZ_ASSERT(!IsIndirect());
+    return reinterpret_cast<ServoStyleContext*>(mBits);
+  }
+
+  IndirectCache* AsIndirect() const
+  {
+    MOZ_ASSERT(IsIndirect());
+    return reinterpret_cast<IndirectCache*>(mBits & ~1);
+  }
+
+  uintptr_t mBits;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_CachedAnonBoxStyles_h
--- a/layout/style/MediaList.h
+++ b/layout/style/MediaList.h
@@ -4,16 +4,17 @@
  * 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/. */
 
 /* base class for representation of media lists */
 
 #ifndef mozilla_dom_MediaList_h
 #define mozilla_dom_MediaList_h
 
+#include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/ServoUtils.h"
 #include "mozilla/StyleBackendType.h"
 
 #include "nsIDOMMediaList.h"
 #include "nsWrapperCache.h"
 
 class nsIDocument;
--- a/layout/style/ServoStyleContext.cpp
+++ b/layout/style/ServoStyleContext.cpp
@@ -29,36 +29,16 @@ ServoStyleContext::ServoStyleContext(
   AddStyleBit(Servo_ComputedValues_GetStyleBits(this));
   MOZ_ASSERT(ComputedData());
 
   // No need to call ApplyStyleFixups here, since fixups are handled by Servo when
   // producing the ServoComputedData.
 }
 
 ServoStyleContext*
-ServoStyleContext::GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
-{
-  MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
-
-  // See the reasoning in SetCachedInheritingAnonBoxStyle to understand why we
-  // can't use the cache in this case.
-  if (IsInheritingAnonBox()) {
-    return nullptr;
-  }
-
-  auto* current = mNextInheritingAnonBoxStyle.get();
-
-  while (current && current->GetPseudo() != aAnonBox) {
-    current = current->mNextInheritingAnonBoxStyle.get();
-  }
-
-  return current;
-}
-
-ServoStyleContext*
 ServoStyleContext::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const
 {
   MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo &&
              aPseudo != CSSPseudoElementType::InheritingAnonBox &&
              aPseudo != CSSPseudoElementType::NonInheritingAnonBox);
   MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "Lazy pseudos can't inherit lazy pseudos");
 
   if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aPseudo)) {
--- a/layout/style/ServoStyleContext.h
+++ b/layout/style/ServoStyleContext.h
@@ -7,16 +7,18 @@
 #ifndef mozilla_ServoStyleContext_h
 #define mozilla_ServoStyleContext_h
 
 #include "nsIMemoryReporter.h"
 #include "nsStyleContext.h"
 #include "nsWindowSizes.h"
 #include <algorithm>
 
+#include "mozilla/CachedAnonBoxStyles.h"
+
 namespace mozilla {
 
 namespace dom {
 class Element;
 } // namespace dom
 
 MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoComputedValuesMallocEnclosingSizeOf)
 
@@ -40,36 +42,26 @@ public:
   }
 
   bool IsLazilyCascadedPseudoElement() const
   {
     return IsPseudoElement() &&
            !nsCSSPseudoElements::IsEagerlyCascadedInServo(GetPseudoType());
   }
 
-  ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const;
+  ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
+  {
+    MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
+    return mInheritingAnonBoxStyles.Lookup(aAnonBox);
+  }
 
-  void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox,
-                                      ServoStyleContext* aStyle)
+  void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox, ServoStyleContext* aStyle)
   {
     MOZ_ASSERT(!GetCachedInheritingAnonBoxStyle(aAnonBox));
-    MOZ_ASSERT(!aStyle->mNextInheritingAnonBoxStyle);
-
-    // NOTE(emilio): Since we use it to cache inheriting anon boxes in a linked
-    // list, we can't use that cache if the style we're inheriting from is an
-    // inheriting anon box itself, since otherwise our parent would mistakenly
-    // think that the style we're caching inherits from it.
-    //
-    // See the documentation of mNextInheritingAnonBoxStyle.
-    if (IsInheritingAnonBox()) {
-      return;
-    }
-
-    mNextInheritingAnonBoxStyle.swap(aStyle->mNextInheritingAnonBoxStyle);
-    mNextInheritingAnonBoxStyle = aStyle;
+    mInheritingAnonBoxStyles.Insert(aStyle);
   }
 
   ServoStyleContext* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const;
 
   void SetCachedLazyPseudoStyle(ServoStyleContext* aStyle)
   {
     MOZ_ASSERT(aStyle->GetPseudo() && !aStyle->IsAnonBox());
     MOZ_ASSERT(!GetCachedLazyPseudoStyle(aStyle->GetPseudoType()));
@@ -106,38 +98,31 @@ public:
   void AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const
   {
     // Note: |this| sits within a servo_arc::Arc, i.e. it is preceded by a
     // refcount. So we need to measure it with a function that can handle an
     // interior pointer. We use ServoComputedValuesMallocEnclosingSizeOf to
     // clearly identify in DMD's output the memory measured here.
     *aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
     mSource.AddSizeOfExcludingThis(aSizes);
-
-    if (mNextInheritingAnonBoxStyle &&
-        !aSizes.mState.HaveSeenPtr(mNextInheritingAnonBoxStyle)) {
-      mNextInheritingAnonBoxStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
-    }
+    mInheritingAnonBoxStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
 
     if (mNextLazyPseudoStyle &&
         !aSizes.mState.HaveSeenPtr(mNextLazyPseudoStyle)) {
       mNextLazyPseudoStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
     }
   }
 
 private:
   nsPresContext* mPresContext;
   ServoComputedData mSource;
 
-  // A linked-list cache of inheriting anon boxes inheriting from this style _if
-  // the style isn't an inheriting anon-box_.
-  //
-  // Otherwise it represents the next entry in the cache of the parent style
-  // context.
-  RefPtr<ServoStyleContext> mNextInheritingAnonBoxStyle;
+  // A cache of inheriting anon boxes inheriting from this style _if the style
+  // isn't an inheriting anon-box_.
+  CachedAnonBoxStyles mInheritingAnonBoxStyles;
 
   // A linked-list cache of lazy pseudo styles inheriting from this style _if
   // the style isn't a lazy pseudo style itself_.
   //
   // Otherwise it represents the next entry in the cache of the parent style
   // context.
   //
   // Note that we store these separately from inheriting anonymous boxes so that
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -76,16 +76,17 @@ EXPORTS += [
     'nsStyleStructInlines.h',
     'nsStyleTransformMatrix.h',
     'nsStyleUtil.h',
 ]
 
 EXPORTS.mozilla += [
     'AnimationCollection.h',
     'BindingStyleRule.h',
+    'CachedAnonBoxStyles.h',
     'CSSEnabledState.h',
     'CSSStyleSheet.h',
     'CSSVariableDeclarations.h',
     'CSSVariableResolver.h',
     'CSSVariableValues.h',
     'DeclarationBlock.h',
     'DeclarationBlockInlines.h',
     'DocumentStyleRootIterator.h',
@@ -174,16 +175,17 @@ EXPORTS.mozilla.css += [
     'StreamLoader.h',
     'StyleRule.h',
     'URLMatchingFunction.h',
 ]
 
 UNIFIED_SOURCES += [
     'AnimationCollection.cpp',
     'BindingStyleRule.cpp',
+    'CachedAnonBoxStyles.cpp',
     'CounterStyleManager.cpp',
     'CSS.cpp',
     'CSSFontFeatureValuesRule.cpp',
     'CSSImportRule.cpp',
     'CSSKeyframeRule.cpp',
     'CSSKeyframesRule.cpp',
     'CSSLexer.cpp',
     'CSSMediaRule.cpp',
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -30,16 +30,17 @@
 #include "nsIPresShell.h"
 #include "nsIPresShellInlines.h"
 #include <algorithm> // std::stable_sort
 #include <math.h>
 
 using namespace mozilla;
 using namespace mozilla::css;
 using mozilla::dom::Animation;
+using mozilla::dom::AnimationEffectReadOnly;
 using mozilla::dom::AnimationPlayState;
 using mozilla::dom::KeyframeEffectReadOnly;
 using mozilla::dom::CSSAnimation;
 
 typedef mozilla::ComputedTiming::AnimationPhase AnimationPhase;
 
 namespace {
 
--- a/media/webrtc/signaling/gtest/videoconduit_unittests.cpp
+++ b/media/webrtc/signaling/gtest/videoconduit_unittests.cpp
@@ -69,18 +69,20 @@ public:
 class MockVideoSink : public rtc::VideoSinkInterface<webrtc::VideoFrame>
 {
 public:
   ~MockVideoSink() override = default;
 
   void OnFrame(const webrtc::VideoFrame& frame) override
   {
     mVideoFrame = frame;
+    ++mOnFrameCount;
   }
 
+  size_t mOnFrameCount = 0;
   webrtc::VideoFrame mVideoFrame;
 };
 
 class VideoConduitTest : public ::testing::Test {
 public:
 
   VideoConduitTest()
     : mCall(new MockCall())
@@ -980,26 +982,29 @@ TEST_F(VideoConduitTest, TestReconfigure
   rtc::VideoSinkWants wants;
   mVideoConduit->AddOrUpdateSink(sink.get(), wants);
 
   mVideoConduit->StartTransmitting();
   SendVideoFrame(1280, 720, 1);
   ASSERT_EQ(sink->mVideoFrame.width(), 1280);
   ASSERT_EQ(sink->mVideoFrame.height(), 720);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
+  ASSERT_EQ(sink->mOnFrameCount, 1U);
 
   SendVideoFrame(640, 360, 2);
   ASSERT_EQ(sink->mVideoFrame.width(), 640);
   ASSERT_EQ(sink->mVideoFrame.height(), 360);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
+  ASSERT_EQ(sink->mOnFrameCount, 2U);
 
   SendVideoFrame(1920, 1280, 3);
   ASSERT_EQ(sink->mVideoFrame.width(), 960);
   ASSERT_EQ(sink->mVideoFrame.height(), 640);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
+  ASSERT_EQ(sink->mOnFrameCount, 3U);
   mVideoConduit->StopTransmitting();
 }
 
 TEST_F(VideoConduitTest, TestReconfigureSendMediaCodecWhileTransmitting)
 {
   MediaConduitErrorCode ec;
   EncodingConstraints constraints;
   VideoCodecConfig::SimulcastEncoding encoding;
@@ -1071,26 +1076,29 @@ TEST_F(VideoConduitTest, TestReconfigure
   UniquePtr<MockVideoSink> sink(new MockVideoSink());
   rtc::VideoSinkWants wants;
   mVideoConduit->AddOrUpdateSink(sink.get(), wants);
 
   SendVideoFrame(1280, 720, 1);
   ASSERT_EQ(sink->mVideoFrame.width(), 1280);
   ASSERT_EQ(sink->mVideoFrame.height(), 720);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
+  ASSERT_EQ(sink->mOnFrameCount, 1U);
 
   SendVideoFrame(640, 360, 2);
   ASSERT_EQ(sink->mVideoFrame.width(), 640);
   ASSERT_EQ(sink->mVideoFrame.height(), 360);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
+  ASSERT_EQ(sink->mOnFrameCount, 2U);
 
   SendVideoFrame(1920, 1280, 3);
   ASSERT_EQ(sink->mVideoFrame.width(), 960);
   ASSERT_EQ(sink->mVideoFrame.height(), 640);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
+  ASSERT_EQ(sink->mOnFrameCount, 3U);
 
   mVideoConduit->StopTransmitting();
 }
 
 TEST_F(VideoConduitTest, TestVideoEncode)
 {
   MediaConduitErrorCode ec;
   EncodingConstraints constraints;
@@ -1106,26 +1114,29 @@ TEST_F(VideoConduitTest, TestVideoEncode
   rtc::VideoSinkWants wants;
   mVideoConduit->AddOrUpdateSink(sink.get(), wants);
 
   mVideoConduit->StartTransmitting();
   SendVideoFrame(1280, 720, 1);
   ASSERT_EQ(sink->mVideoFrame.width(), 1280);
   ASSERT_EQ(sink->mVideoFrame.height(), 720);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
+  ASSERT_EQ(sink->mOnFrameCount, 1U);
 
   SendVideoFrame(640, 360, 2);
   ASSERT_EQ(sink->mVideoFrame.width(), 640);
   ASSERT_EQ(sink->mVideoFrame.height(), 360);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
+  ASSERT_EQ(sink->mOnFrameCount, 2U);
 
   SendVideoFrame(1920, 1280, 3);
   ASSERT_EQ(sink->mVideoFrame.width(), 1920);
   ASSERT_EQ(sink->mVideoFrame.height(), 1280);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
+  ASSERT_EQ(sink->mOnFrameCount, 3U);
 
   mVideoConduit->StopTransmitting();
   mVideoConduit->RemoveSink(sink.get());
 }
 
 TEST_F(VideoConduitTest, TestVideoEncodeMaxFs)
 {
   MediaConduitErrorCode ec;
@@ -1143,46 +1154,52 @@ TEST_F(VideoConduitTest, TestVideoEncode
   rtc::VideoSinkWants wants;
   mVideoConduit->AddOrUpdateSink(sink.get(), wants);
 
   mVideoConduit->StartTransmitting();
   SendVideoFrame(1280, 720, 1);
   ASSERT_EQ(sink->mVideoFrame.width(), 1280);
   ASSERT_EQ(sink->mVideoFrame.height(), 720);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
+  ASSERT_EQ(sink->mOnFrameCount, 1U);
 
   SendVideoFrame(640, 360, 2);
   ASSERT_EQ(sink->mVideoFrame.width(), 640);
   ASSERT_EQ(sink->mVideoFrame.height(), 360);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
+  ASSERT_EQ(sink->mOnFrameCount, 2U);
 
   SendVideoFrame(1920, 1280, 3);
   ASSERT_EQ(sink->mVideoFrame.width(), 960);
   ASSERT_EQ(sink->mVideoFrame.height(), 640);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
+  ASSERT_EQ(sink->mOnFrameCount, 3U);
 
   // maxFs should not force pixel count above what a sink has requested.
   // We set 3600 macroblocks (16x16 pixels), so we request 3500 here.
   wants.max_pixel_count = rtc::Optional<int>(3500*16*16);
   mVideoConduit->AddOrUpdateSink(sink.get(), wants);
 
   SendVideoFrame(1280, 720, 4);
   ASSERT_EQ(sink->mVideoFrame.width(), 960);
   ASSERT_EQ(sink->mVideoFrame.height(), 540);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 4000U);
+  ASSERT_EQ(sink->mOnFrameCount, 4U);
 
   SendVideoFrame(640, 360, 5);
   ASSERT_EQ(sink->mVideoFrame.width(), 640);
   ASSERT_EQ(sink->mVideoFrame.height(), 360);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 5000U);
+  ASSERT_EQ(sink->mOnFrameCount, 5U);
 
   SendVideoFrame(1920, 1280, 6);
   ASSERT_EQ(sink->mVideoFrame.width(), 960);
   ASSERT_EQ(sink->mVideoFrame.height(), 640);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 6000U);
+  ASSERT_EQ(sink->mOnFrameCount, 6U);
 
   mVideoConduit->StopTransmitting();
   mVideoConduit->RemoveSink(sink.get());
 }
 
 // Disabled: See Bug 1420493
 TEST_F(VideoConduitTest, DISABLED_TestVideoEncodeMaxWidthAndHeight)
 {
@@ -1202,24 +1219,27 @@ TEST_F(VideoConduitTest, DISABLED_TestVi
   rtc::VideoSinkWants wants;
   mVideoConduit->AddOrUpdateSink(sink.get(), wants);
 
   mVideoConduit->StartTransmitting();
   SendVideoFrame(1280, 720, 1);
   ASSERT_EQ(sink->mVideoFrame.width(), 1280);
   ASSERT_EQ(sink->mVideoFrame.height(), 720);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 1000U);
+  ASSERT_EQ(sink->mOnFrameCount, 1U);
 
   SendVideoFrame(640, 360, 2);
   ASSERT_EQ(sink->mVideoFrame.width(), 640);
   ASSERT_EQ(sink->mVideoFrame.height(), 360);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 2000U);
+  ASSERT_EQ(sink->mOnFrameCount, 2U);
 
   SendVideoFrame(1920, 1280, 3);
   ASSERT_EQ(sink->mVideoFrame.width(), 1080);
   ASSERT_EQ(sink->mVideoFrame.height(), 720);
   ASSERT_EQ(sink->mVideoFrame.timestamp_us(), 3000U);
+  ASSERT_EQ(sink->mOnFrameCount, 3U);
 
   mVideoConduit->StopTransmitting();
   mVideoConduit->RemoveSink(sink.get());
 }
 
 } // End namespace test.
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -241,17 +241,16 @@ WebrtcVideoConduit::WebrtcVideoConduit(R
   : mTransportMonitor("WebrtcVideoConduit")
   , mRenderer(nullptr)
   , mVideoAdapter(std::move(aVideoAdapter))
   , mVideoBroadcaster()
   , mEngineTransmitting(false)
   , mEngineReceiving(false)
   , mCapId(-1)
   , mCodecMutex("VideoConduit codec db")
-  , mInReconfig(false)
   , mRecvStream(nullptr)
   , mSendStream(nullptr)
   , mLastWidth(0)
   , mLastHeight(0) // initializing as 0 forces a check for reconfig at start
   , mSendingWidth(0)
   , mSendingHeight(0)
   , mReceivingWidth(0)
   , mReceivingHeight(0)
@@ -1692,22 +1691,19 @@ WebrtcVideoConduit::SelectBitrates(
   }
   out_start = std::min(out_max, std::max(out_start, out_min));
 
   MOZ_ASSERT(mPrefMaxBitrate == 0 || out_max <= mPrefMaxBitrate);
 }
 
 // XXX we need to figure out how to feed back changes in preferred capture
 // resolution to the getUserMedia source.
-// Returns boolean if we've submitted an async change (and took ownership
-// of *frame's data)
-bool
+void
 WebrtcVideoConduit::SelectSendResolution(unsigned short width,
-                                         unsigned short height,
-                                         const webrtc::VideoFrame* frame) // may be null
+                                         unsigned short height)
 {
   mCodecMutex.AssertCurrentThreadOwns();
   // XXX This will do bandwidth-resolution adaptation as well - bug 877954
 
   mLastWidth = width;
   mLastHeight = height;
   // Enforce constraints
   if (mCurSendCodecConfig) {
@@ -1726,105 +1722,37 @@ WebrtcVideoConduit::SelectSendResolution
       if (max_fs > mLastSinkWanted.max_pixel_count.value_or(max_fs)) {
         max_fs = mLastSinkWanted.max_pixel_count.value_or(max_fs);
       }
       mVideoAdapter->OnResolutionRequest(rtc::Optional<int>(max_fs),
                                          rtc::Optional<int>());
     }
   }
 
-  // Adapt to getUserMedia resolution changes
-  // check if we need to reconfigure the sending resolution.
+  // Update on resolution changes
   // NOTE: mSendingWidth != mLastWidth, because of maxwidth/height/etc above
-  bool changed = false;
   if (mSendingWidth != width || mSendingHeight != height) {
     CSFLogDebug(LOGTAG, "%s: resolution changing to %ux%u (from %ux%u)",
                 __FUNCTION__, width, height, mSendingWidth, mSendingHeight);
     // This will avoid us continually retrying this operation if it fails.
     // If the resolution changes, we'll try again.  In the meantime, we'll
     // keep using the old size in the encoder.
     mSendingWidth = width;
     mSendingHeight = height;
-    changed = true;
   }
 
   unsigned int framerate = SelectSendFrameRate(mCurSendCodecConfig,
                                                mSendingFramerate,
                                                mSendingWidth,
                                                mSendingHeight);
   if (mSendingFramerate != framerate) {
     CSFLogDebug(LOGTAG, "%s: framerate changing to %u (from %u)",
                 __FUNCTION__, framerate, mSendingFramerate);
     mSendingFramerate = framerate;
-    changed = true;
   }
-
-  if (changed) {
-    // On a resolution change, bounce this to the correct thread to
-    // re-configure (same as used for Init().  Do *not* block the calling
-    // thread since that may be the MSG thread.
-
-    // MUST run on the same thread as Init()/etc
-    if (!NS_IsMainThread()) {
-      // Note: on *initial* config (first frame), best would be to drop
-      // frames until the config is done, then encode the most recent frame
-      // provided and continue from there.  We don't do this, but we do drop
-      // all frames while in the process of a reconfig and then encode the
-      // frame that started the reconfig, which is close.  There may be
-      // barely perceptible glitch in the video due to the dropped frame(s).
-      mInReconfig = true;
-
-      // We can't pass a UniquePtr<> or unique_ptr<> to a lambda directly
-      webrtc::VideoFrame* new_frame = nullptr;
-      if (frame) {
-        // the internal buffer pointer is refcounted, so we don't have 2 copies here
-        new_frame = new webrtc::VideoFrame(*frame);
-      }
-      RefPtr<WebrtcVideoConduit> self(this);
-      RefPtr<Runnable> webrtc_runnable =
-        media::NewRunnableFrom([self, width, height, new_frame]() -> nsresult {
-            UniquePtr<webrtc::VideoFrame> local_frame(new_frame); // Simplify cleanup
-
-            MutexAutoLock lock(self->mCodecMutex);
-            return self->ReconfigureSendCodec(width, height, new_frame);
-          });
-      // new_frame now owned by lambda
-      CSFLogDebug(LOGTAG, "%s: proxying lambda to WebRTC thread for reconfig (width %u/%u, height %u/%u",
-                  __FUNCTION__, width, mLastWidth, height, mLastHeight);
-      NS_DispatchToMainThread(webrtc_runnable.forget());
-      if (new_frame) {
-        return true; // queued it
-      }
-    } else {
-      // already on the right thread
-      ReconfigureSendCodec(width, height, frame);
-    }
-  }
-  return false;
-}
-
-nsresult
-WebrtcVideoConduit::ReconfigureSendCodec(unsigned short width,
-                                         unsigned short height,
-                                         const webrtc::VideoFrame* frame)
-{
-  mCodecMutex.AssertCurrentThreadOwns();
-
-  // Test in case the stream hasn't started yet!  We could get a frame in
-  // before we get around to StartTransmitting(), and that would dispatch a
-  // runnable to call this.
-  mInReconfig = false;
-  if (mSendStream) {
-    mSendStream->ReconfigureVideoEncoder(mEncoderConfig.CopyConfig());
-    if (frame) {
-      mVideoBroadcaster.OnFrame(*frame);
-      CSFLogDebug(LOGTAG, "%s Inserted a frame from reconfig lambda", __FUNCTION__);
-    }
-  }
-  return NS_OK;
 }
 
 unsigned int
 WebrtcVideoConduit::SelectSendFrameRate(const VideoCodecConfig* codecConfig,
                                         unsigned int old_framerate,
                                         unsigned short sending_width,
                                         unsigned short sending_height) const
 {
@@ -1958,38 +1886,32 @@ MediaConduitErrorCode
 WebrtcVideoConduit::SendVideoFrame(const webrtc::VideoFrame& frame)
 {
   // XXX Google uses a "timestamp_aligner" to translate timestamps from the
   // camera via TranslateTimestamp(); we should look at doing the same.  This
   // avoids sampling error when capturing frames, but google had to deal with some
   // broken cameras, include Logitech c920's IIRC.
 
   CSFLogVerbose(LOGTAG, "%s (send SSRC %u (0x%x))", __FUNCTION__,
-              mSendStreamConfig.rtp.ssrcs.front(), mSendStreamConfig.rtp.ssrcs.front());
+                mSendStreamConfig.rtp.ssrcs.front(), mSendStreamConfig.rtp.ssrcs.front());
   // See if we need to recalculate what we're sending.
   // Don't compute mSendingWidth/Height, since those may not be the same as the input.
   {
-    MutexAutoLock lock(mCodecMutex);
-    if (mInReconfig) {
-      // Waiting for it to finish
-      return kMediaConduitNoError;
-    }
     // mLastWidth/Height starts at 0, so we'll never call SelectSendResolution with a 0 size.
     // We in some cases set them back to 0 to force SelectSendResolution to be called again.
     if (frame.width() != mLastWidth || frame.height() != mLastHeight) {
       CSFLogVerbose(LOGTAG, "%s: call SelectSendResolution with %ux%u",
                     __FUNCTION__, frame.width(), frame.height());
       MOZ_ASSERT(frame.width() != 0 && frame.height() != 0);
       // Note coverity will flag this since it thinks they can be 0
-      if (SelectSendResolution(frame.width(), frame.height(), &frame)) {
-        // SelectSendResolution took ownership of the data in i420_frame.
-        // Submit the frame after reconfig is done
-        return kMediaConduitNoError;
-      }
+
+      MutexAutoLock lock(mCodecMutex);
+      SelectSendResolution(frame.width(), frame.height());
     }
+
     // adapt input video to wants of sink
     if (!mVideoBroadcaster.frame_wanted()) {
       return kMediaConduitNoError;
     }
 
     int adapted_width;
     int adapted_height;
     int crop_width;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -166,29 +166,18 @@ public:
                       webrtc::VideoStream& aVideoStream);
 
   /**
    * Function to select and change the encoding resolution based on incoming frame size
    * and current available bandwidth.
    * @param width, height: dimensions of the frame
    * @param frame: optional frame to submit for encoding after reconfig
    */
-  bool SelectSendResolution(unsigned short width,
-                            unsigned short height,
-                            const webrtc::VideoFrame* frame);
-
-  /**
-   * Function to reconfigure the current send codec for a different
-   * width/height/framerate/etc.
-   * @param width, height: dimensions of the frame
-   * @param frame: optional frame to submit for encoding after reconfig
-   */
-  nsresult ReconfigureSendCodec(unsigned short width,
-                                unsigned short height,
-                                const webrtc::VideoFrame* frame);
+  void SelectSendResolution(unsigned short width,
+                            unsigned short height);
 
   /**
    * Function to select and change the encoding frame rate based on incoming frame rate
    * and max-mbps setting.
    * @param current framerate
    * @result new framerate
    */
   unsigned int SelectSendFrameRate(const VideoCodecConfig* codecConfig,
@@ -501,20 +490,19 @@ private:
   // Engine state we are concerned with.
   mozilla::Atomic<bool> mEngineTransmitting; // If true ==> Transmit Subsystem is up and running
   mozilla::Atomic<bool> mEngineReceiving;    // if true ==> Receive Subsystem up and running
 
   int mCapId;   // Capturer for this conduit
   //Local database of currently applied receive codecs
   nsTArray<UniquePtr<VideoCodecConfig>> mRecvCodecList;
 
-  // protects mCurSendCodecConfig, mInReconfig,mVideoSend/RecvStreamStats, mSend/RecvStreams, mSendPacketCounts, mRecvPacketCounts
+  // protects mCurSendCodecConfig, mVideoSend/RecvStreamStats, mSend/RecvStreams, mSendPacketCounts, mRecvPacketCounts
   Mutex mCodecMutex;
   nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig;
-  bool mInReconfig;
   SendStreamStatistics mSendStreamStats;
   ReceiveStreamStatistics mRecvStreamStats;
   webrtc::RtcpPacketTypeCounter mSendPacketCounts;
   webrtc::RtcpPacketTypeCounter mRecvPacketCounts;
 
   // Must call webrtc::Call::DestroyVideoReceive/SendStream to delete these:
   webrtc::VideoReceiveStream* mRecvStream;
   webrtc::VideoSendStream* mSendStream;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSDemuxerWrapper.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSDemuxerWrapper.java
@@ -10,17 +10,17 @@ import android.util.Log;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.mozilla.geckoview.BuildConfig;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.mozglue.JNIObject;
 
 public final class GeckoHLSDemuxerWrapper {
     private static final String LOGTAG = "GeckoHLSDemuxerWrapper";
-    private static final boolean DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;;
+    private static final boolean DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
 
     // NOTE : These TRACK definitions should be synced with Gecko.
     public enum TrackType {
         UNDEFINED(0),
         AUDIO(1),
         VIDEO(2),
         TEXT(3);
         private int mType;
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSResourceWrapper.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSResourceWrapper.java
@@ -7,17 +7,17 @@ package org.mozilla.gecko.media;
 import android.util.Log;
 
 import org.mozilla.geckoview.BuildConfig;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.mozglue.JNIObject;
 
 public class GeckoHLSResourceWrapper {
     private static final String LOGTAG = "GeckoHLSResourceWrapper";
-    private static final boolean DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;
+    private static final boolean DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
     private BaseHlsPlayer mPlayer = null;
     private boolean mDestroy = false;
 
     public static class Callbacks extends JNIObject
     implements BaseHlsPlayer.ResourceCallbacks {
         @WrapForJNI(calledFrom = "gecko")
         Callbacks() {}
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsAudioRenderer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsAudioRenderer.java
@@ -23,17 +23,17 @@ import com.google.android.exoplayer2.uti
 
 import java.nio.ByteBuffer;
 
 public class GeckoHlsAudioRenderer extends GeckoHlsRendererBase {
     public GeckoHlsAudioRenderer(GeckoHlsPlayer.ComponentEventDispatcher eventDispatcher) {
         super(C.TRACK_TYPE_AUDIO, eventDispatcher);
         assertTrue(Build.VERSION.SDK_INT >= 16);
         LOGTAG = getClass().getSimpleName();
-        DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;;
+        DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
     }
 
     @Override
     public final int supportsFormat(Format format) {
         /*
          * FORMAT_EXCEEDS_CAPABILITIES : The Renderer is capable of rendering
          *                               formats with the same mime type, but
          *                               the properties of the format exceed
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
@@ -45,17 +45,17 @@ import org.mozilla.geckoview.BuildConfig
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 
 @ReflectionTarget
 public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
     private static final String LOGTAG = "GeckoHlsPlayer";
     private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
     private static final int MAX_TIMELINE_ITEM_LINES = 3;
-    private static final boolean DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;
+    private static final boolean DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
 
     private static final AtomicInteger sPlayerId = new AtomicInteger(0);
     /*
      *  Because we treat GeckoHlsPlayer as a source data provider.
      *  It will be created and initialized with a URL by HLSResource in
      *  Gecko media pipleine (in cpp). Once HLSDemuxer is created later, we
      *  need to bridge this HLSResource to the created demuxer. And they share
      *  the same GeckoHlsPlayer.
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsVideoRenderer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsVideoRenderer.java
@@ -51,17 +51,17 @@ public class GeckoHlsVideoRenderer exten
     // prepending each keyframe. When video format changes, this information
     // changes accordingly.
     private byte[] mCSDInfo = null;
 
     public GeckoHlsVideoRenderer(GeckoHlsPlayer.ComponentEventDispatcher eventDispatcher) {
         super(C.TRACK_TYPE_VIDEO, eventDispatcher);
         assertTrue(Build.VERSION.SDK_INT >= 16);
         LOGTAG = getClass().getSimpleName();
-        DEBUG = BuildConfig.NIGHTLY_BUILD || BuildConfig.DEBUG_BUILD;;
+        DEBUG = !BuildConfig.MOZILLA_OFFICIAL;
     }
 
     @Override
     public final int supportsMixedMimeTypeAdaptation() {
         return ADAPTIVE_NOT_SEAMLESS;
     }
 
     @Override
--- a/old-configure.in
+++ b/old-configure.in
@@ -2160,17 +2160,17 @@ dnl = Enable the toolkit as needed      
 dnl ========================================================
 
 case "$MOZ_WIDGET_TOOLKIT" in
 
 cocoa)
     LDFLAGS="$LDFLAGS -framework Cocoa -lobjc"
     # Use -Wl as a trick to avoid -framework and framework names from
     # being separated by AC_SUBST_LIST.
-    TK_LIBS='-Wl,-framework,CoreLocation -Wl,-framework,QuartzCore -Wl,-framework,Carbon -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,AddressBook -Wl,-framework,OpenGL -Wl,-framework,Security -Wl,-framework,ServiceManagement'
+    TK_LIBS='-Wl,-framework,Foundation -Wl,-framework,CoreFoundation -Wl,-framework,CoreLocation -Wl,-framework,QuartzCore -Wl,-framework,Carbon -Wl,-framework,CoreAudio -Wl,-framework,CoreVideo -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,AddressBook -Wl,-framework,OpenGL -Wl,-framework,Security -Wl,-framework,ServiceManagement -Wl,-framework,CoreServices -Wl,-framework,ApplicationServices -Wl,-framework,AppKit'
     TK_CFLAGS=""
     CFLAGS="$CFLAGS $TK_CFLAGS"
     CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
     MOZ_USER_DIR="Mozilla"
     MOZ_FS_LAYOUT=bundle
     ;;
 
 uikit)
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1155,9 +1155,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 = 482;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1523991760932000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1524078583869000);
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -1,40 +1,40 @@
 00220022.net: could not connect to host
-00881919.com: could not connect to host
 01100010011001010111001101110100.com: could not connect to host
+0513c.com: could not connect to host
 06se.com: could not connect to host
 07733.win: could not connect to host
 0day.su: could not connect to host
 0i0.nl: could not connect to host
 10gb.io: could not connect to host
 135vv.com: could not connect to host
 13826145000.com: could not connect to host
 1395kj.com: could not connect to host
+13th-dover.uk: could not connect to host
+166166.com: could not connect to host
 1nian.vip: could not connect to host
 1q365a.com: could not connect to host
 24hrs.shopping: could not connect to host
 28spots.net: could not connect to host
 314chan.org: could not connect to host
 41844.de: could not connect to host
 439191.com: could not connect to host
 47tech.com: could not connect to host
 4d2.xyz: could not connect to host
 4loc.us: could not connect to host
 4web-hosting.com: could not connect to host
 4x4.lk: could not connect to host
 5000yz.com: could not connect to host
-517vpn.cn: could not connect to host
 52neptune.com: could not connect to host
 5ece.de: could not connect to host
 68277.me: could not connect to host
 692b8c32.de: could not connect to host
 69mentor.com: could not connect to host
 7261696e626f77.net: could not connect to host
-7kicks.com: could not connect to host
 8560.be: could not connect to host
 87577.com: could not connect to host
 8887999.com: could not connect to host
 88laohu.cc: could not connect to host
 88laohu.com: could not connect to host
 8ballbombom.uk: could not connect to host
 8t88.biz: could not connect to host
 91-freedom.com: could not connect to host
@@ -42,16 +42,17 @@ 9ss6.com: could not connect to host
 abloop.com: could not connect to host
 abolition.co: could not connect to host
 accwing.com: could not connect to host
 achterhoekseveiligheidsbeurs.nl: could not connect to host
 acrossgw.com: could not connect to host
 ad-disruptio.fr: could not connect to host
 adamdixon.co.uk: could not connect to host
 adec-emsa.ae: could not connect to host
+adult.properties: could not connect to host
 adventureally.com: could not connect to host
 aevpn.org: could not connect to host
 affily.io: could not connect to host
 afterstack.net: could not connect to host
 agilebits.net: could not connect to host
 aiicy.org: could not connect to host
 aim-consultants.com: could not connect to host
 akiba-server.info: could not connect to host
@@ -61,17 +62,16 @@ akoww.de: could not connect to host
 akul.co.in: could not connect to host
 al-f.net: could not connect to host
 alasta.info: could not connect to host
 alauda-home.de: could not connect to host
 alcatraz.online: could not connect to host
 alcnutrition.com: could not connect to host
 alexandernorth.ch: could not connect to host
 alexandros.io: could not connect to host
-alexberts.ch: could not connect to host
 alexei.su: could not connect to host
 alexey-shamara.ru: could not connect to host
 alexmol.tk: could not connect to host
 alexperry.io: could not connect to host
 alilialili.ga: could not connect to host
 alldm.ru: could not connect to host
 allscammers.exposed: could not connect to host
 altahrim.net: could not connect to host
@@ -86,51 +86,59 @@ andiplusben.com: could not connect to ho
 andreas-kluge.eu: could not connect to host
 andreaskluge.eu: could not connect to host
 andrei-coman.com: could not connect to host
 andrewdaws.co: could not connect to host
 andrewdaws.info: could not connect to host
 andrewdaws.me: could not connect to host
 andrewdaws.tv: could not connect to host
 andrewrdaws.com: could not connect to host
+andronika.net: could not connect to host
 angrydragonproductions.com: could not connect to host
 annetaan.fi: could not connect to host
 annonasoftware.com: could not connect to host
 answers-online.ru: could not connect to host
 anttitenhunen.com: could not connect to host
 anyways.at: could not connect to host
 aojiao.org: could not connect to host
+apila.us: could not connect to host
 apkoyunlar.club: could not connect to host
 apparels24.com: could not connect to host
 appdrinks.com: could not connect to host
 apple.ax: could not connect to host
-aquaundine.net: could not connect to host
 arai21.net: could not connect to host
 area3.org: could not connect to host
 arenlor.com: could not connect to host
 arenlor.info: could not connect to host
 arenns.com: could not connect to host
 arent.kz: could not connect to host
 argh.io: could not connect to host
 arksan.com.tr: could not connect to host
 armenians.online: could not connect to host
 arne-petersen.net: could not connect to host
 arresttracker.com: could not connect to host
 articaexports.com: could not connect to host
 artisense.de: could not connect to host
 artisticedgegranite.net: could not connect to host
+aseith.com: could not connect to host
+ashleyadum.com: could not connect to host
 askmagicconch.com: could not connect to host
 asphaltfruehling.de: could not connect to host
+asr.cloud: could not connect to host
+asr.li: could not connect to host
+asr.rocks: could not connect to host
+asr.solar: could not connect to host
 asral7.com: could not connect to host
 assdecoeur.org: could not connect to host
 asthon.cn: could not connect to host
 astral.gq: could not connect to host
 astrea-voetbal-groningen.nl: could not connect to host
 asuhe.xyz: could not connect to host
 at1.co: could not connect to host
+athena-garage.co.uk: could not connect to host
 athi.pl: could not connect to host
 atigerseye.com: could not connect to host
 atrevillot.com: could not connect to host
 aufmerksamkeitsstudie.com: could not connect to host
 ausec.ch: could not connect to host
 austinsutphin.com: could not connect to host
 australiancattle.dog: could not connect to host
 authint.com: could not connect to host
@@ -189,33 +197,33 @@ bitcoinjpn.com: could not connect to hos
 bitmaincare.com.ua: could not connect to host
 bitmaincare.ru: could not connect to host
 bitmessage.ch: could not connect to host
 bityes.org: could not connect to host
 bizeau.ch: could not connect to host
 bjgongyi.com: could not connect to host
 bjtxl.cn: could not connect to host
 blackdiam.net: could not connect to host
+blantik.net: could not connect to host
 blayneallan.com: could not connect to host
+blazeit.io: could not connect to host
 blindaryproduction.tk: could not connect to host
 blinkenlight.co.uk: could not connect to host
 blinkenlight.com.au: could not connect to host
 blog.gparent.org: could not connect to host
 blokuhaka.fr: could not connect to host
 blumen-garage.de: could not connect to host
 bm-i.ch: could not connect to host
 bodrumfarm.com: could not connect to host
 bolwerk.com.br: could not connect to host
 bomberus.de: could not connect to host
 bonesserver.com: could not connect to host
-bonnin.fr: could not connect to host
 bonobo.cz: could not connect to host
 boozinyan.com: could not connect to host
 borisbesemer.com: could not connect to host
-bosabosa.org: could not connect to host
 boxdevigneron.fr: could not connect to host
 bqcp.net: could not connect to host
 brage.info: could not connect to host
 braintensive.com: could not connect to host
 brandontaylor-black.com: could not connect to host
 branw.xyz: could not connect to host
 breathingblanket.com: could not connect to host
 briangarcia.ga: could not connect to host
@@ -225,50 +233,51 @@ brooke-fan.com: could not connect to hos
 brookframework.org: could not connect to host
 brrr.fr: could not connect to host
 bruckner.li: could not connect to host
 brynnan.nl: could not connect to host
 bsalyzer.com: could not connect to host
 bsktweetup.info: could not connect to host
 bslim-e-boutique.com: could not connect to host
 bsuess.de: could not connect to host
-btsoft.eu: could not connect to host
-budgetlovers.nl: could not connect to host
 bugginslab.co.uk: could not connect to host
 bugsmashed.com: could not connect to host
 buka.jp: could not connect to host
 businessfurs.info: could not connect to host
 businesshub.cz: could not connect to host
 businessmodeler.se: could not connect to host
 buyingsellingflorida.com: could not connect to host
 buyshoe.org: could not connect to host
 bvexplained.co.uk: could not connect to host
 by1898.com: could not connect to host
+byji.com: could not connect to host
 bypass.kr: could not connect to host
 byteshift.ca: could not connect to host
 cafesg.net: could not connect to host
 caipai.fm: could not connect to host
 calculatoaresecondhand.xyz: could not connect to host
 callabs.net: could not connect to host
 callsigns.ca: could not connect to host
 camda.online: could not connect to host
 campingcarlovers.com: could not connect to host
 canarymod.net: could not connect to host
 cancelmyprofile.com: could not connect to host
 caps.is: could not connect to host
+capturethepen.co.uk: could not connect to host
 cardloan-manual.net: could not connect to host
 cardse.net: could not connect to host
 carloshmm.stream: could not connect to host
 carlovanwyk.com: could not connect to host
 casinoreal.com: could not connect to host
 caughtredhanded.co.nz: could not connect to host
 cctld.com: could not connect to host
 cdnk39.com: could not connect to host
 cee.io: could not connect to host
 cegfw.com: could not connect to host
+celuliteonline.com: could not connect to host
 cencalvia.org: could not connect to host
 centos.pub: could not connect to host
 centrallead.net: could not connect to host
 cgan.pw: could not connect to host
 cgtx.us: could not connect to host
 challengeskins.com: could not connect to host
 championnat-romand-cuisiniers-amateurs.ch: could not connect to host
 champserver.net: could not connect to host
@@ -281,17 +290,16 @@ childrendeservebetter.org: could not con
 china-line.org: could not connect to host
 chinternet.xyz: could not connect to host
 chiropracticwpb.com: could not connect to host
 chloe.re: could not connect to host
 chosenplaintext.org: could not connect to host
 christianhoffmann.info: could not connect to host
 christophersole.com: could not connect to host
 chromaryu.net: could not connect to host
-chuckame.fr: could not connect to host
 chziyue.com: could not connect to host
 cima-idf.fr: could not connect to host
 cinemysticism.com: could not connect to host
 cipher.land: could not connect to host
 cjr.host: could not connect to host
 cjtkfan.club: could not connect to host
 clearchatsandbox.com: could not connect to host
 clearviewwealthprojector.com.au: could not connect to host
@@ -322,30 +330,30 @@ conniesacademy.com: could not connect to
 construct-trust.com: could not connect to host
 conve.eu: could not connect to host
 corecdn.org: could not connect to host
 corinnanese.de: could not connect to host
 correct.horse: could not connect to host
 cosmeticosdelivery.com.br: could not connect to host
 cosplayer.com: could not connect to host
 coumoul.fr: could not connect to host
-cousincouples.com: could not connect to host
 cpaneltips.com: could not connect to host
 crackpfer.de: could not connect to host
 creative-wave.fr: could not connect to host
 creativecommonscatpictures.com: could not connect to host
 cristianhares.com: could not connect to host
 criticalaim.com: could not connect to host
 crox.co: could not connect to host
 cryptopartynewcastle.org: could not connect to host
 crystalmachine.net: could not connect to host
 csgo.help: could not connect to host
 csgo77.com: could not connect to host
 cspeti.hu: could not connect to host
 ctj.im: could not connect to host
+cunha.be: could not connect to host
 cuonic.com: could not connect to host
 customfilmworks.com: could not connect to host
 cyber-computer.club: could not connect to host
 cyberpeace.nl: could not connect to host
 cyberstatus.de: could not connect to host
 cypherpunk.ws: could not connect to host
 czlx.co: could not connect to host
 d-bood.site: could not connect to host
@@ -365,16 +373,17 @@ davros.ru: could not connect to host
 dawnson.is: could not connect to host
 day.vip: could not connect to host
 days.one: could not connect to host
 dbcom.ru: could not connect to host
 dbox.ga: could not connect to host
 dden.website: could not connect to host
 dden.xyz: could not connect to host
 de-servers.de: could not connect to host
+deadmann.com: could not connect to host
 decoyrouting.com: could not connect to host
 deepcreampie.com: could not connect to host
 deepsouthsounds.com: could not connect to host
 deloittequant.com: could not connect to host
 derchris.me: could not connect to host
 derivativeshub.pro: could not connect to host
 dermacarecomplex.com: could not connect to host
 derrickemery.com: could not connect to host
@@ -386,24 +395,23 @@ devafterdark.com: could not connect to h
 devcu.net: could not connect to host
 developersclub.website: could not connect to host
 deviltraxxx.de: could not connect to host
 devkid.net: could not connect to host
 devops.moe: could not connect to host
 dhl-smart.ch: could not connect to host
 dhub.xyz: could not connect to host
 dhuy.net: could not connect to host
-dibiphp.com: could not connect to host
 diceduels.com: could not connect to host
 dicgaming.net: could not connect to host
 dick.red: could not connect to host
 didierlaumen.be: could not connect to host
-didikhari.web.id: could not connect to host
 diemogebhardt.com: could not connect to host
 dieser.me: could not connect to host
+dietagespresse.com: could not connect to host
 digihyp.ch: could not connect to host
 digioccumss.ddns.net: could not connect to host
 digitalhurricane.io: could not connect to host
 diguass.us: could not connect to host
 dijks.com: could not connect to host
 dirtycat.ru: could not connect to host
 disability.gov: could not connect to host
 disadattamentolavorativo.it: could not connect to host
@@ -421,27 +429,29 @@ dojifish.space: could not connect to hos
 dolphin-hosting.com: could not connect to host
 domengrad.ru: could not connect to host
 domfee.com: could not connect to host
 dostavkakurierom.ru: could not connect to host
 doyoulyft.com: could not connect to host
 doze-cloud.tech: could not connect to host
 drdim.ru: could not connect to host
 dreaming.solutions: could not connect to host
+dreizwosechs.de: could not connect to host
+drgn.no: could not connect to host
 driving-lessons.co.uk: could not connect to host
 drivinghorror.com: could not connect to host
 drixn.cn: could not connect to host
 drixn.info: could not connect to host
 drixn.net: could not connect to host
 drizz.com.br: could not connect to host
 drogoz.moe: could not connect to host
 dronexpertos.com: could not connect to host
 droomhuis-in-zuid-holland-kopen.nl: could not connect to host
 drunkscifi.com: could not connect to host
-dtx.sk: could not connect to host
+dstamou.de: could not connect to host
 dubrovskiy.net: could not connect to host
 dubrovskiy.pro: could not connect to host
 duch.cloud: could not connect to host
 duelsow.eu: could not connect to host
 duesee.org: could not connect to host
 duks.com.br: could not connect to host
 duo.money: could not connect to host
 durangoenergyllc.com: could not connect to host
@@ -457,16 +467,17 @@ egbert.net: could not connect to host
 ehuber.info: could not connect to host
 einsatzstiefel.info: could not connect to host
 ekobudisantoso.net: could not connect to host
 eladgames.com: could not connect to host
 elbetech.net: could not connect to host
 eldisagjapi.com: could not connect to host
 elementarywave.com: could not connect to host
 elenorsmadness.org: could not connect to host
+elia.cloud: could not connect to host
 eliott.be: could not connect to host
 elisabeth-strunz.de: could not connect to host
 elonbase.com: could not connect to host
 elsword.moe: could not connect to host
 eltransportquevolem.org: could not connect to host
 emilyjohnson.ga: could not connect to host
 empese.com: could not connect to host
 emrenovation.com: could not connect to host
@@ -476,25 +487,27 @@ engg.ca: could not connect to host
 epulsar.ru: could not connect to host
 er-music.com: could not connect to host
 eriser.fr: could not connect to host
 erkaelderbarenaaben.dk: could not connect to host
 erspro.net: could not connect to host
 erwinwensveen.nl: could not connect to host
 esailinggear.com: could not connect to host
 estoic.net: could not connect to host
+etath.com: could not connect to host
 ethiobaba.com: could not connect to host
 euexia.fr: could not connect to host
 eurostrategy.vn.ua: could not connect to host
 ev-zertifikate.de: could not connect to host
 evankurniawan.com: could not connect to host
 eveshaiwu.com: could not connect to host
 evileden.com: could not connect to host
 exo.do: could not connect to host
 eytosh.net: could not connect to host
+f42.net: could not connect to host
 f8842.com: could not connect to host
 faber.org.ru: could not connect to host
 fabian-kluge.de: could not connect to host
 facebook.ax: could not connect to host
 facilitrak.com: could not connect to host
 factureenlinea.com: could not connect to host
 fafatiger.com: could not connect to host
 faithwatch.org: could not connect to host
@@ -526,16 +539,17 @@ firexarxa.de: could not connect to host
 fix-the-timeline.com: could not connect to host
 fix-the-timeline.org: could not connect to host
 fixmyglitch.com: could not connect to host
 fixthetimeline.com: could not connect to host
 fixthetimeline.org: could not connect to host
 flopy.club: could not connect to host
 flow.su: could not connect to host
 flugplatz-edvc.de: could not connect to host
+fly.moe: could not connect to host
 flygpost.com: could not connect to host
 flyingdoggy.net: could not connect to host
 focalforest.com: could not connect to host
 folioapp.io: could not connect to host
 forcamp.ga: could not connect to host
 formersessalaries.com: could not connect to host
 forsyththeatre.com: could not connect to host
 fortuna-loessnitz.de: could not connect to host
@@ -551,16 +565,17 @@ franzt.ovh: could not connect to host
 fredliang.cn: could not connect to host
 fredtec.ru: could not connect to host
 freejidi.com: could not connect to host
 freelansir.com: could not connect to host
 freemanning.de: could not connect to host
 freeshkre.li: could not connect to host
 freshcode.nl: could not connect to host
 frickenate.com: could not connect to host
+friedhelm-wolf.de: could not connect to host
 frodriguez.xyz: could not connect to host
 frolov.net: could not connect to host
 fromlemaytoz.com: could not connect to host
 fromthesoutherncross.com: could not connect to host
 frosty-gaming.xyz: could not connect to host
 frp-roleplay.de: could not connect to host
 frusky.net: could not connect to host
 fs-gamenet.de: could not connect to host
@@ -646,32 +661,34 @@ gozel.com.tr: could not connect to host
 gradsm-ci.net: could not connect to host
 granth.io: could not connect to host
 graphire.io: could not connect to host
 gratisonlinesex.com: could not connect to host
 greg.red: could not connect to host
 gregmartyn.com: could not connect to host
 greuel.online: could not connect to host
 gritte.net: could not connect to host
+gropp.org: could not connect to host
 grossmisconduct.news: could not connect to host
 gtts.space: could not connect to host
 gugaltika-ipb.org: could not connect to host
 gus.moe: could not connect to host
 gvchannel.xyz: could not connect to host
 gvt2.com: could not connect to host
 gvt3.com: could not connect to host
 h2cdn.cloud: could not connect to host
 h3artbl33d.nl: could not connect to host
 habeo.si: could not connect to host
 hackbubble.me: could not connect to host
 hakugin.me: could not connect to host
 halcyonsbastion.com: could not connect to host
 halkyon.net: could not connect to host
 handinhandfoundation.org.uk: could not connect to host
 hapijs.cn: could not connect to host
+harmfarm.nl: could not connect to host
 harrypottereditor.net: could not connect to host
 hasabig.wang: could not connect to host
 hasalittle.wang: could not connect to host
 hashplex.com: could not connect to host
 haze.network: could not connect to host
 hbbet.com: could not connect to host
 hbvip.com: could not connect to host
 hcstr.com: could not connect to host
@@ -681,40 +698,41 @@ hearty.ink: could not connect to host
 heavenlysmokenc.com: could not connect to host
 heisenberg.co: could not connect to host
 hejsupport.se: could not connect to host
 hellofilters.com: could not connect to host
 hellomouse.tk: could not connect to host
 helpantiaging.com: could not connect to host
 helpekwendenihospital.com: could not connect to host
 helsingfors.guide: could not connect to host
-hemdal.se: could not connect to host
 henriknoerr.com: could not connect to host
 hentai.design: could not connect to host
 hentaimaster.net: could not connect to host
 here.ml: could not connect to host
 heribe-maruo.com: could not connect to host
 heroin.org.uk: could not connect to host
+hethely.ch: could not connect to host
 hetmeisjeachterpauw.nl: could not connect to host
 hexobind.com: could not connect to host
 hfi.me: could not connect to host
-hg71851.com: could not connect to host
 hg881.com: could not connect to host
 hill.selfip.net: could not connect to host
 hintermeier-rae.at: could not connect to host
 hirte-digital.de: could not connect to host
 hitrek.ml: could not connect to host
 hohm.in: could not connect to host
 holidayincotswolds.co.uk: could not connect to host
 homoglyph.net: could not connect to host
 hoodoo.io: could not connect to host
 hoodoo.tech: could not connect to host
 hopglass.eu: could not connect to host
 hopglass.net: could not connect to host
 horvathd.eu: could not connect to host
+hosted-oswa.org: could not connect to host
+hotelmadhuwanvihar.com: could not connect to host
 howardtyson.com: could not connect to host
 hozinga.de: could not connect to host
 hr98.tk: could not connect to host
 hserver.top: could not connect to host
 hudingyuan.cn: could not connect to host
 huiser.nl: could not connect to host
 hukkatavara.com: could not connect to host
 hunger.im: could not connect to host
@@ -740,72 +758,73 @@ ikzoekeengoedkopeauto.nl: could not conn
 ileat.com: could not connect to host
 immersionwealth.com: could not connect to host
 imperdintechnologies.com: could not connect to host
 impulse-clan.de: could not connect to host
 increasetestosteronelevels.org: could not connect to host
 inexpensivecomputers.net: could not connect to host
 informatik.zone: could not connect to host
 infoworm.org: could not connect to host
+injust.eu.org: could not connect to host
 injust.me: could not connect to host
 inondation.ch: could not connect to host
 inscript.pl: could not connect to host
 insouciant.org: could not connect to host
-installgentoo.net: could not connect to host
 instaquiz.ru: could not connect to host
 instasex.ch: could not connect to host
-intarweb.ca: could not connect to host
 intelldynamics.com: could not connect to host
 interviewpipeline.co.uk: could not connect to host
 investorloanshub.com: could not connect to host
 ip.or.at: could not connect to host
 iphonechina.net: could not connect to host
 ipnetworking.net: could not connect to host
 irinkeby.nu: could not connect to host
 isamiok.com: could not connect to host
-isocom.eu: could not connect to host
 isopres.de: could not connect to host
-ispsoft.pro: could not connect to host
 itad.top: could not connect to host
 itpro-mg.de: could not connect to host
 its-schindler.de: could not connect to host
 itsatrap.nl: could not connect to host
 ivanilla.org: could not connect to host
 ivanpolchenko.com: could not connect to host
 j0ng.xyz: could not connect to host
+jahofmann.de: could not connect to host
 jaimechanaga.com: could not connect to host
 jaion.ml: could not connect to host
 jakincode.army: could not connect to host
+jaksel.id: could not connect to host
 jamesheald.com: could not connect to host
 janssen.fm: could not connect to host
 japan4you.org: could not connect to host
 jaredfraser.com: could not connect to host
 javascriptlab.fr: could not connect to host
 jccars-occasions.be: could not connect to host
 jccrew.org: could not connect to host
 jcraft.us: could not connect to host
 jean-remy.ch: could not connect to host
 jeffersonregan.org: could not connect to host
 jens.hk: could not connect to host
 jeproteste.info: could not connect to host
+jeremyc.ca: could not connect to host
 jettlarue.com: could not connect to host
 jhburton.co.uk: could not connect to host
 jiangzm.com: could not connect to host
 jiaqiang.vip: could not connect to host
 jkirsche.com: could not connect to host
 jmoreau.ddns.net: could not connect to host
 jobmedic.com: could not connect to host
+joearodriguez.com: could not connect to host
 joecod.es: could not connect to host
 joelfries.com: could not connect to host
 joetyson.io: could not connect to host
-johannes-bauer.com: could not connect to host
 johngo.tk: could not connect to host
 johnkastler.net: could not connect to host
 jonarcher.info: could not connect to host
 jonathansanchez.pro: could not connect to host
+jordanhamilton.me: could not connect to host
 js88.sg: could not connect to host
 jsc7776.com: could not connect to host
 jsjyhzy.cc: could not connect to host
 juliaoantiguidades.com.br: could not connect to host
 juliawebber.co.za: could not connect to host
 jumbopan.com: could not connect to host
 jumbopan.net: could not connect to host
 just-pools.co.za: could not connect to host
@@ -830,31 +849,28 @@ kawaiiku.com: could not connect to host
 kawaiiku.de: could not connect to host
 kayipmurekkep.com: could not connect to host
 kelm.me: could not connect to host
 kenyons.info: could not connect to host
 kevinbowers.me: could not connect to host
 kevindekoninck.com: could not connect to host
 keyserver.sexy: could not connect to host
 kgb.us: could not connect to host
-khs1994.com: could not connect to host
 kidbacker.com: could not connect to host
 kiedys.net: could not connect to host
 kieranweightman.me: could not connect to host
 kievradio.com: could not connect to host
 kinepolis-studio.ga: could not connect to host
 kingbird.me: could not connect to host
 kingclass.cn: could not connect to host
 kirill.ws: could not connect to host
-kittyhacker101.tk: could not connect to host
 kj1396.net: could not connect to host
 kjchernov.info: could not connect to host
 kjoglum.me: could not connect to host
 klingeletest.de: could not connect to host
-knegten-agilis.com: could not connect to host
 kngk-azs.ru: could not connect to host
 knightsweep.com: could not connect to host
 knownsec.cf: could not connect to host
 koez-mangal.ch: could not connect to host
 koezmangal.ch: could not connect to host
 kollawat.me: could not connect to host
 kongbaofang.com: could not connect to host
 konicaprinterdriver.com: could not connect to host
@@ -865,16 +881,17 @@ kozmik.co: could not connect to host
 krampus-fischamend.at: could not connect to host
 kriptosec.com: could not connect to host
 ksero.center: could not connect to host
 kteen.info: could not connect to host
 ktube.yt: could not connect to host
 kubusadvocaten.nl: could not connect to host
 kuechenplan.online: could not connect to host
 kuko-crews.org: could not connect to host
+kwikmed.eu: could not connect to host
 kyle.place: could not connect to host
 kylebaldw.in: could not connect to host
 kylling.io: could not connect to host
 kyujin-office.net: could not connect to host
 l18.io: could not connect to host
 laboutiquemarocaineduconvoyeur.com: could not connect to host
 laboutiquemarocaineduconvoyeur.ma: could not connect to host
 lacasa.fr: could not connect to host
@@ -890,24 +907,24 @@ lanonfire.com: could not connect to host
 lathamlabs.com: could not connect to host
 lathamlabs.net: could not connect to host
 lathamlabs.org: could not connect to host
 lavapot.com: could not connect to host
 lazulu.com: could not connect to host
 lbrls.tk: could not connect to host
 lcti.biz: could not connect to host
 ldcraft.pw: could not connect to host
-le-page.info: could not connect to host
 lebal.se: could not connect to host
 leebiblestudycentre.net: could not connect to host
 leebiblestudycentre.org: could not connect to host
 legal.farm: could not connect to host
 legaltip.eu: could not connect to host
 lenkunz.me: could not connect to host
 leolana.com: could not connect to host
+leon-tech.com: could not connect to host
 leonardcamacho.me: could not connect to host
 lerlivros.online: could not connect to host
 lescomptoirsdepierrot.com: could not connect to host
 lesdouceursdeliyana.com: could not connect to host
 lessets-graphiques.com: could not connect to host
 leticiagomeztagle.com: could not connect to host
 leveredge.net: could not connect to host
 lezdomsm.com: could not connect to host
@@ -922,16 +939,17 @@ likenosis.com: could not connect to host
 linkages.org: could not connect to host
 linksanitizer.com: could not connect to host
 linksextremist.at: could not connect to host
 linley.de: could not connect to host
 linux-admin-california.com: could not connect to host
 linux.sb: could not connect to host
 linuxcode.net: could not connect to host
 linvx.org: could not connect to host
+lisieuxarquitetura.com.br: could not connect to host
 lissabon.guide: could not connect to host
 littlelundgrenladies.com: could not connect to host
 littleservice.cn: could not connect to host
 litz.ca: could not connect to host
 litzenberger.ca: could not connect to host
 liukang.tech: could not connect to host
 livi.co: could not connect to host
 livnev.me: could not connect to host
@@ -951,37 +969,40 @@ lovelive.us: could not connect to host
 lowt.us: could not connect to host
 loyaltech.ch: could not connect to host
 ltransferts.com: could not connect to host
 lucasantarella.com: could not connect to host
 lukasunger.cz: could not connect to host
 lukasunger.net: could not connect to host
 luom.net: could not connect to host
 luxonetwork.com: could not connect to host
+lwl.moe: could not connect to host
 m4570.xyz: could not connect to host
 m4g.ru: could not connect to host
 maartenterpstra.xyz: could not connect to host
 machbach.net: could not connect to host
 macustar.eu: could not connect to host
 madeintucson.org: could not connect to host
-madirc.net: could not connect to host
+madusecurity.com: could not connect to host
 magnacumlaude.co: could not connect to host
 maik-mahlow.de: could not connect to host
 mailon.ga: could not connect to host
 malesbdsm.com: could not connect to host
 malgraph.net: could not connect to host
 marcelmarnitz.com: could not connect to host
 marche-nordic-jorat.ch: could not connect to host
 mare92.cz: could not connect to host
+mariposah.ch: could not connect to host
 marketingdesignu.cz: could not connect to host
 martynhare.co.uk: could not connect to host
 martynhare.uk: could not connect to host
 marxist.party: could not connect to host
 mastodon.expert: could not connect to host
 mastodon.my: could not connect to host
+matarrosabierzo.com: could not connect to host
 mathieui.net: could not connect to host
 mathijskingma.nl: could not connect to host
 mattia98.org: could not connect to host
 mattli.us: could not connect to host
 mattwb65.com: could not connect to host
 maynardnetworks.com: could not connect to host
 mb-is.info: could not connect to host
 mbdrogenbos-usedcars.be: could not connect to host
@@ -1002,29 +1023,30 @@ meeko.cc: could not connect to host
 melhorproduto.com.br: could not connect to host
 melonstudios.net: could not connect to host
 melvinlow.com: could not connect to host
 menchez.me: could not connect to host
 menzaijia.com: could not connect to host
 mercanix.co.uk: could not connect to host
 metrix-money-ptc.com: could not connect to host
 metrix.design: could not connect to host
+mexior.nl: could not connect to host
 mhjuma.com: could not connect to host
 michaelsulzer.com: could not connect to host
 michaelsulzer.eu: could not connect to host
-mikeybot.com: could not connect to host
 milktea.info: could not connect to host
 mingy.ddns.net: could not connect to host
 minitruckin.net: could not connect to host
 mkfs.fr: could not connect to host
 mm13.at: could not connect to host
 mmstick.tk: could not connect to host
 modded-minecraft-server-list.com: could not connect to host
 moderntld.net: could not connect to host
 moe-max.jp: could not connect to host
+moellers.systems: could not connect to host
 moeyi.xyz: could not connect to host
 mongla168.net: could not connect to host
 mongla88.net: could not connect to host
 monitori.ng: could not connect to host
 moobo.xyz: could not connect to host
 mooselook.de: could not connect to host
 moparcraft.com: could not connect to host
 moparcraft.org: could not connect to host
@@ -1049,27 +1071,22 @@ murraycolin.org: could not connect to ho
 muslimbanter.co.za: could not connect to host
 mybeautyjobs.de: could not connect to host
 mycamda.com: could not connect to host
 mycustomwriting.com: could not connect to host
 myfappening.org: could not connect to host
 myicare.org: could not connect to host
 mykeepsake.xyz: could not connect to host
 mynetworkingbuddy.com: could not connect to host
-mynewleaf.co: could not connect to host
 mytravelblog.de: could not connect to host
-mziulu.me: could not connect to host
 mzlog.win: could not connect to host
 n0099.cf: could not connect to host
 naano.org: could not connect to host
 naphex.rocks: could not connect to host
 narodsovety.ru: could not connect to host
-nba2k.cn: could not connect to host
-nba2k.com.cn: could not connect to host
-nbalive.cn: could not connect to host
 ncdesigns-studio.com: could not connect to host
 neer.io: could not connect to host
 negativecurvature.net: could not connect to host
 nejnamc.org: could not connect to host
 nephy.jp: could not connect to host
 nerull7.info: could not connect to host
 nestone.ru: could not connect to host
 nevadafiber.net: could not connect to host
@@ -1087,17 +1104,16 @@ nikolasbradshaw.com: could not connect t
 niouininon.eu: could not connect to host
 nirada.info: could not connect to host
 nishikino-maki.com: could not connect to host
 niva.synology.me: could not connect to host
 nkadvertising.online: could not connect to host
 nodeselect.com: could not connect to host
 nonemu.ninja: could not connect to host
 norad.sytes.net: could not connect to host
-norrkemi.se: could not connect to host
 northernselfstorage.co.za: could not connect to host
 nosbenevolesontdutalent.com: could not connect to host
 notarobot.fr: could not connect to host
 note7forever.com: could not connect to host
 notesforpebble.com: could not connect to host
 notevencode.com: could not connect to host
 novascan.net: could not connect to host
 nowremindme.com: could not connect to host
@@ -1106,37 +1122,39 @@ nudel.ninja: could not connect to host
 nullpointer.io: could not connect to host
 nunnun.jp: could not connect to host
 nyanpasu.tv: could not connect to host
 nyxi.eu: could not connect to host
 obdolbacca.ru: could not connect to host
 oberam.de: could not connect to host
 oberhof.co: could not connect to host
 oblondata.io: could not connect to host
+octothorpe.ninja: could not connect to host
+oec-music.com: could not connect to host
 off-the-clock.us: could not connect to host
 offgames.pro: could not connect to host
 office-ruru.com: could not connect to host
 oliverspringer.eu: could not connect to host
 omarh.net: could not connect to host
 omnibot.tv: could not connect to host
 onewebdev.info: could not connect to host
 onstud.com: could not connect to host
 onwie.fr: could not connect to host
 ooeste.com: could not connect to host
+opatut.de: could not connect to host
 openintelligence.uk: could not connect to host
 openmirrors.cf: could not connect to host
 opium.io: could not connect to host
 oscsdp.cz: could not connect to host
 osmanlitorunu.com: could not connect to host
 otinane.eu: could not connect to host
 ourchoice2016.com: could not connect to host
 outetc.com: could not connect to host
 owlscrap.ru: could not connect to host
 oxynux.xyz: could not connect to host
-padovani.de: could not connect to host
 paichai.space: could not connect to host
 panasca.is: could not connect to host
 panascais.co: could not connect to host
 panascais.com: could not connect to host
 panascais.de: could not connect to host
 panascais.eu: could not connect to host
 panascais.host: could not connect to host
 panascais.io: could not connect to host
@@ -1164,20 +1182,23 @@ pcvirusclear.com: could not connect to h
 pear2pear.de: could not connect to host
 peirong.me: could not connect to host
 pengisatelier.net: could not connect to host
 persjrp.ca: could not connect to host
 persoform.ch: could not connect to host
 petlife.od.ua: could not connect to host
 peuf.shop: could not connect to host
 peykezamin.ir: could not connect to host
+pfadfinder-aurich.de: could not connect to host
+pgmsource.com: could not connect to host
 phdwuda.com: could not connect to host
 phil.tw: could not connect to host
 philippa.cool: could not connect to host
 philosopherswool.com: could not connect to host
+phoenixlogan.com: could not connect to host
 photops.fr: could not connect to host
 picallo.es: could not connect to host
 picone.com.au: could not connect to host
 pierrejeansuau.fr: could not connect to host
 pimspage.nl: could not connect to host
 pinebaylibrary.org: could not connect to host
 piwko.co: could not connect to host
 pixelgliders.de: could not connect to host
@@ -1188,33 +1209,33 @@ playsharp.com: could not connect to host
 plussizereviews.com: could not connect to host
 pmbremer.de: could not connect to host
 pnsc.is: could not connect to host
 pogs.us: could not connect to host
 pointagri.com: could not connect to host
 polit.im: could not connect to host
 ponteencima.com: could not connect to host
 poolinstallers.co.za: could not connect to host
-posobota.cz: could not connect to host
 postn.eu: could not connect to host
+potbar.com: could not connect to host
+potlytics.com: could not connect to host
 pouets.ovh: could not connect to host
 powerentertainment.tv: could not connect to host
 poy-tech.com: could not connect to host
 prepaid-cards.xyz: could not connect to host
 princessbackpack.de: could not connect to host
 printsos.com: could not connect to host
 prism-communication.com: could not connect to host
 privacymanatee.com: could not connect to host
 privcloud.org: could not connect to host
 proactive.run: could not connect to host
 progressivecfo.co.nz: could not connect to host
 projectasterk.com: could not connect to host
 projectx.top: could not connect to host
 prokop.ovh: could not connect to host
-prolan.pw: could not connect to host
 propmag.co: could not connect to host
 provitacare.com: could not connect to host
 proxydesk.eu: could not connect to host
 prpsss.com: could not connect to host
 pruikshop.nl: could not connect to host
 prytkov.com: could not connect to host
 psncardplus.be: could not connect to host
 psncardplus.com: could not connect to host
@@ -1238,16 +1259,17 @@ qscloud.de: could not connect to host
 qto.net: could not connect to host
 quay.net: could not connect to host
 r40.us: could not connect to host
 ra.co.ke: could not connect to host
 rackblue.com: could not connect to host
 rainbin.com: could not connect to host
 rally-vysledky.cz: could not connect to host
 ranos.org: could not connect to host
+rantanda.com: could not connect to host
 rapdogg.com: could not connect to host
 ravse.dk: could not connect to host
 raxion.cf: could not connect to host
 rcoliveira.com: could not connect to host
 rdfz.tech: could not connect to host
 readify.com.au: could not connect to host
 readityourself.net: could not connect to host
 reaiaer.com: could not connect to host
@@ -1280,16 +1302,17 @@ robust.ga: could not connect to host
 rocketgnomes.com: could not connect to host
 rodehutskors.net: could not connect to host
 rofrank.space: could not connect to host
 rohanbassett.com: could not connect to host
 romanticvillas.com.au: could not connect to host
 ronghexx.com: could not connect to host
 roolevoi.ru: could not connect to host
 rospa100.com: could not connect to host
+roten.email: could not connect to host
 rotterdamjazz.info: could not connect to host
 royzez.com: could not connect to host
 rozalynne-dawn.ga: could not connect to host
 rpasafrica.com: could not connect to host
 rs-devdemo.host: could not connect to host
 rsldb.com: could not connect to host
 rtc.fun: could not connect to host
 rubendv.be: could not connect to host
@@ -1298,30 +1321,29 @@ ruht.ro: could not connect to host
 runcarina.com: could not connect to host
 rundumcolumn.xyz: could not connect to host
 runementors.com: could not connect to host
 ruudkoot.nl: could not connect to host
 rzegroup.com: could not connect to host
 s0923.com: could not connect to host
 s3n.se: could not connect to host
 sa.net: could not connect to host
-safe.moe: could not connect to host
 saferedirectlink.com: could not connect to host
+sahkotyot.eu: could not connect to host
 sajdowski.de: could not connect to host
 sallysubs.com: could not connect to host
 salzamt.tk: could not connect to host
 samaritan.tech: could not connect to host
 sanael.net: could not connect to host
 sanatrans.com: could not connect to host
 sanik.my: could not connect to host
 sarindia.com: could not connect to host
 sarindia.de: could not connect to host
 sarndipity.com: could not connect to host
 satragreen.com: could not connect to host
-saudeintimadamulher.com.br: could not connect to host
 sbiewald.de: could not connect to host
 schaafenstrasse.koeln: could not connect to host
 schatmeester.be: could not connect to host
 schnapke.name: could not connect to host
 sciencemonster.co.uk: could not connect to host
 scottainslie.me.uk: could not connect to host
 scripthost.org: could not connect to host
 scriptjunkie.us: could not connect to host
@@ -1336,17 +1358,16 @@ secureobscure.com: could not connect to 
 security.xn--q9jyb4c: could not connect to host
 securityprimes.in: could not connect to host
 securitysoapbox.com: could not connect to host
 securon.io: could not connect to host
 securoswiss.ch: could not connect to host
 seefirm.com: could not connect to host
 seen.life: could not connect to host
 seleondar.ru: could not connect to host
-self-signed.com: could not connect to host
 selfmade4u.de: could not connect to host
 selfserverx.com: could not connect to host
 sellmoretires.com: could not connect to host
 seoscribe.net: could not connect to host
 servecrypt.com: could not connect to host
 server-essentials.com: could not connect to host
 serverlauget.no: could not connect to host
 serverpedia.de: could not connect to host
@@ -1354,18 +1375,18 @@ servfefe.com: could not connect to host
 seryovpn.com: could not connect to host
 sesha.co.za: could not connect to host
 sgtsnookums.net: could not connect to host
 shadex.net: could not connect to host
 shadiku.com: could not connect to host
 shadowplus.net: could not connect to host
 shadowrocket.net: could not connect to host
 shaitan.eu: could not connect to host
+shang-yu.cn: could not connect to host
 shanxiapark.com: could not connect to host
-sharevari.com: could not connect to host
 shavingks.com: could not connect to host
 sheying.tm: could not connect to host
 shirakaba-cc.com: could not connect to host
 shoppingreview.org: could not connect to host
 shortr.li: could not connect to host
 shred.ch: could not connect to host
 shredoptics.ch: could not connect to host
 shuzicai.cn: could not connect to host
@@ -1379,18 +1400,18 @@ silvistefi.com: could not connect to hos
 simbolo.co.uk: could not connect to host
 simplerses.com: could not connect to host
 sims4hub.ga: could not connect to host
 siqi.wang: could not connect to host
 skarox.ru: could not connect to host
 sky-aroma.com: could not connect to host
 skylocker.net: could not connect to host
 skylocker.nl: could not connect to host
-sl1pkn07.wtf: could not connect to host
 slaps.be: could not connect to host
+sliceone.com: could not connect to host
 slovoice.org: could not connect to host
 slytech.ch: could not connect to host
 smallchat.nl: could not connect to host
 smith.is: could not connect to host
 sml.lc: could not connect to host
 smspodmena.ru: could not connect to host
 soboleva-pr.com.ua: could not connect to host
 socialworkout.com: could not connect to host
@@ -1400,20 +1421,20 @@ socialworkout.tv: could not connect to h
 socketize.com: could not connect to host
 sojingle.net: could not connect to host
 solidtuesday.com: could not connect to host
 sonafe.info: could not connect to host
 sortaweird.net: could not connect to host
 sowingseasons.com: could not connect to host
 sowncloud.de: could not connect to host
 spanien.guide: could not connect to host
+spdf.net: could not connect to host
 sphinx.network: could not connect to host
 spicywombat.com: could not connect to host
 split.is: could not connect to host
-spornkuller.de: could not connect to host
 sportsmanadvisor.com: could not connect to host
 squaddraft.com: could not connect to host
 squids.space: could not connect to host
 sqzryang.com: could not connect to host
 sritest.io: could not connect to host
 srvonfire.com: could not connect to host
 stadionmanager.com: could not connect to host
 stadtgartenla.com: could not connect to host
@@ -1441,81 +1462,84 @@ summer.ga: could not connect to host
 suneilpatel.com: could not connect to host
 sunfireshop.com.br: could not connect to host
 sunxchina.com: could not connect to host
 superpase.com: could not connect to host
 susconam.org: could not connect to host
 suspiciousdarknet.xyz: could not connect to host
 sussexwebdesigns.com: could not connect to host
 swaggerdile.com: could not connect to host
+synergisticsoccer.com: could not connect to host
 t3rror.net: could not connect to host
 takusan.ru: could not connect to host
 talktwincities.com: could not connect to host
 tangyue.date: could not connect to host
 tangzhao.net: could not connect to host
-tasta.ro: could not connect to host
 tcpweb.net: could not connect to host
 tdsb.cf: could not connect to host
 tdsbhack.tk: could not connect to host
 tearoy.faith: could not connect to host
 tebieer.com: could not connect to host
 techask.it: could not connect to host
 techpit.us: could not connect to host
 telekollektiv.org: could not connect to host
 tenispopular.com: could not connect to host
 terra-x.net: could not connect to host
 terrax.net: could not connect to host
 testovaci.ml: could not connect to host
 tetsai.com: could not connect to host
-texy.info: could not connect to host
 the-digitale.com: could not connect to host
 the-finance-blog.com: could not connect to host
 the-gist.io: could not connect to host
 thedarkartsandcrafts.com: could not connect to host
 thefox.co: could not connect to host
 thefrk.xyz: could not connect to host
 thenrdhrd.nl: could not connect to host
 theprincegame.com: could not connect to host
 theprivacysolution.com: could not connect to host
 thequillmagazine.org: could not connect to host
 thermique.ch: could not connect to host
 thesehighsandlows.com: could not connect to host
 theserver201.tk: could not connect to host
 thierryhayoz.ch: could not connect to host
 thinkcash.nl: could not connect to host
-thinkindifferent.net: could not connect to host
 thompsonfamily.cloud: could not connect to host
 tianxicaipiao.win: could not connect to host
 tianxicp.com: could not connect to host
 timco.cloud: could not connect to host
 tink.network: could not connect to host
+tkn.tokyo: could not connect to host
 tnb-plattform.de: could not connect to host
 todosrv.com: could not connect to host
 tokoindo.top: could not connect to host
 tollsjekk.no: could not connect to host
 tomm.yt: could not connect to host
 tommounsey.com: could not connect to host
+tooolroc.org: could not connect to host
 topdetoxcleanse.com: could not connect to host
 topnotchendings.com: could not connect to host
 tor2web.org: could not connect to host
 totallynotaserver.com: could not connect to host
 totalsystemcare.com: could not connect to host
 totch.de: could not connect to host
 totot.net: could not connect to host
 touch-up-net.com: could not connect to host
 toxicip.com: could not connect to host
 tpblist.xyz: could not connect to host
+tpolemis.com: could not connect to host
 trajano.net: could not connect to host
 transcendmotor.sg: could not connect to host
 travotion.com: could not connect to host
 treker.us: could not connect to host
 tristanfarkas.one: could not connect to host
 trynowrinkleseyeserum.com: could not connect to host
 tsaro.io: could not connect to host
+tsironis-olivenoel.de: could not connect to host
 tsurezurematome.ga: could not connect to host
+tu6.pm: could not connect to host
 tucidi.net: could not connect to host
 tucnak.eu: could not connect to host
 tucuxi.org: could not connect to host
 tumelum.de: could not connect to host
 tupizm.com: could not connect to host
 turkiet.guide: could not connect to host
 turn-sticks.com: could not connect to host
 tursiae.org: could not connect to host
@@ -1525,17 +1549,16 @@ twiri.net: could not connect to host
 twitter.ax: could not connect to host
 twotube.ie: could not connect to host
 tykoon.com: could not connect to host
 tyler.rs: could not connect to host
 tyleromeara.com: could not connect to host
 tzwe.com: could not connect to host
 ubi.gg: could not connect to host
 ubicv.com: could not connect to host
-uborcare.com: could not connect to host
 udo-luetkemeier.de: could not connect to host
 ueu.me: could not connect to host
 uicchy.com: could not connect to host
 ulti.gq: could not connect to host
 umsapi.com: could not connect to host
 unefuite.ch: could not connect to host
 unhu.fr: could not connect to host
 uni2share.com: could not connect to host
@@ -1565,46 +1588,48 @@ venturavwparts.com: could not connect to
 verdeandco.co.uk: could not connect to host
 versfin.net: could not connect to host
 veryyounglesbians.com: could not connect to host
 vgatest.nl: could not connect to host
 vgropp.de: could not connect to host
 vicenage.com: could not connect to host
 videorullen.se: could not connect to host
 vidister.de: could not connect to host
+vigrey.com: could not connect to host
 vikasbabyworld.de: could not connect to host
 vimeosucks.nyc: could not connect to host
 vinetalk.net: could not connect to host
+visionless.me: could not connect to host
 visionthroughknowledge.com: could not connect to host
 visiontree.eu: could not connect to host
 vkino.com: could not connect to host
 vlogge.com: could not connect to host
 voeux.io: could not connect to host
 vogt.tech: could not connect to host
 volcain.io: could not connect to host
 volker-gropp.de: could not connect to host
 volkergropp.de: could not connect to host
 vorlif.org: could not connect to host
 votresiteweb.ch: could not connect to host
 vrtouring.org: could not connect to host
 vsx.ch: could not connect to host
-vumetric.com: could not connect to host
 vxapps.com: could not connect to host
 w4.no: could not connect to host
 w4nvu.org: could not connect to host
 wabifoggynuts.com: could not connect to host
 waixingrenfuli.vip: could not connect to host
 wanashi.com: could not connect to host
 wanda76.com: could not connect to host
 wanda78.com: could not connect to host
 wanda79.com: could not connect to host
 wanda96.com: could not connect to host
 wanda97.com: could not connect to host
 wanda98.com: could not connect to host
 warlions.info: could not connect to host
+warmservers.com: could not connect to host
 warp-radio.com: could not connect to host
 warp-radio.tv: could not connect to host
 watchweasel.com: could not connect to host
 waxdramatic.com: could not connect to host
 we.serveftp.net: could not connect to host
 weareincognito.org: could not connect to host
 webart-factory.de: could not connect to host
 webbson.net: could not connect to host
@@ -1613,17 +1638,16 @@ webhackspro.com: could not connect to ho
 webproject.rocks: could not connect to host
 webspotter.nl: could not connect to host
 webtar.info: could not connect to host
 webtech.com.br: could not connect to host
 webthings.com.br: could not connect to host
 wecanvisit.com: could not connect to host
 weebsr.us: could not connect to host
 weed.ren: could not connect to host
-week.report: could not connect to host
 weiler.xyz: could not connect to host
 wejumall.com: could not connect to host
 wekibe.de: could not connect to host
 welby.cat: could not connect to host
 wereldplanner.nl: could not connect to host
 werhatunsverraten.eu: could not connect to host
 wespeakgeek.co.za: could not connect to host
 wetthost.com: could not connect to host
@@ -1646,16 +1670,18 @@ wizznab.tk: could not connect to host
 wmawri.com: could not connect to host
 wolfemg.com: could not connect to host
 wolfenland.net: could not connect to host
 wonderbooks.club: could not connect to host
 woomu.me: could not connect to host
 workemy.com: could not connect to host
 worldfree4.org: could not connect to host
 worldpeacetechnology.com: could not connect to host
+wormholevpn.net: could not connect to host
+wow-foederation.de: could not connect to host
 wp-fastsearch.de: could not connect to host
 wp-stack.pro: could not connect to host
 wp6.pw: could not connect to host
 wsdcap.com: could not connect to host
 wuchipc.com: could not connect to host
 wuerfel.wf: could not connect to host
 www-68277.com: could not connect to host
 www-8887999.com: could not connect to host
@@ -1663,33 +1689,35 @@ www.re: could not connect to host
 www.sb: could not connect to host
 www.simbolo.co.uk: could not connect to host
 xbc.nz: could not connect to host
 xeonlab.com: could not connect to host
 xeonlab.de: could not connect to host
 xia100.xyz: could not connect to host
 xianguocy.com: could not connect to host
 xing.ml: could not connect to host
+xiqi.us: could not connect to host
 xn--8mr166hf6s.xn--fiqs8s: could not connect to host
 xn--erklderbarenben-slbh.dk: could not connect to host
+xn--jbs-tna.de: could not connect to host
+xn--mllers-wxa.info: could not connect to host
 xn--srenpind-54a.dk: could not connect to host
 xn--t8j2a3042d.xyz: could not connect to host
 xn--yj8h0m.ws: could not connect to host
 xn--ykrp42k.com: could not connect to host
 xoda.pw: could not connect to host
 xpwn.cz: could not connect to host
 xqin.net: could not connect to host
 xuntaosms.com: could not connect to host
 xwaretech.info: could not connect to host
 y3451.com: could not connect to host
 yabrt.cn: could not connect to host
 yahoo.ax: could not connect to host
 yarchives.jp: could not connect to host
 yaucy.win: could not connect to host
-ybresson.com: could not connect to host
 yd.io: could not connect to host
 yellowcar.website: could not connect to host
 yemekbaz.az: could not connect to host
 yesfone.com.br: could not connect to host
 yffengshi.ml: could not connect to host
 yggdar.ga: could not connect to host
 yhori.xyz: could not connect to host
 yibin0831.com: could not connect to host
@@ -1699,31 +1727,30 @@ ylk.io: could not connect to host
 yobst.tk: could not connect to host
 yoga.is-an-engineer.com: could not connect to host
 yotilabs.com: could not connect to host
 yourznc.com: could not connect to host
 yousite.by: could not connect to host
 yude.ml: could not connect to host
 yugege.cf: could not connect to host
 yum.beer: could not connect to host
+yum0.cn: could not connect to host
 yux.fr: could not connect to host
 zachbolinger.com: could not connect to host
-zajazd.biz: could not connect to host
 zaoext.com: could not connect to host
 zbchen.com: could not connect to host
 zby.io: could not connect to host
 zeitzer-turngala.de: could not connect to host
 zenghx.tk: could not connect to host
 zero-x-baadf00d.com: could not connect to host
 zerosource.net: could not connect to host
 zhangfangzhou.com: could not connect to host
 zhangsir.net: could not connect to host
 zhaochen.xyz: could not connect to host
 zhenmeish.com: could not connect to host
-zhiin.net: could not connect to host
 zhikin.com: could not connect to host
 zhoujiashu.com: could not connect to host
 zikirakhirzaman.com: could not connect to host
 zobraz.cz: could not connect to host
 zokster.net: could not connect to host
 zudomc.me: could not connect to host
 zuefle.net: could not connect to host
 zuehlcke.de: could not connect to host
@@ -1734,17 +1761,17 @@ zxtcode.com: could not connect to host
 zyx.im: could not connect to host
 zzw.ca: could not connect to host
 00001.am: did not receive HSTS header
 00002.am: did not receive HSTS header
 0005.com: could not connect to host
 0005aa.com: could not connect to host
 007sascha.de: did not receive HSTS header
 020wifi.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 119"  data: no]
-0222aa.com: did not receive HSTS header
+0222aa.com: could not connect to host
 040fit.nl: did not receive HSTS header
 048.ag: could not connect to host
 050508.com: could not connect to host
 0f.io: could not connect to host
 0fl.com: did not receive HSTS header
 0g.org.uk: could not connect to host
 0o0.ooo: could not connect to host
 0p.no: did not receive HSTS header
@@ -1778,17 +1805,17 @@ 12vpnchina.com: could not connect to hos
 1391kj.com: did not receive HSTS header
 1396.cc: did not receive HSTS header
 1536.cf: could not connect to host
 163pwd.com: could not connect to host
 16deza.com: did not receive HSTS header
 16packets.com: could not connect to host
 173vpn.cn: could not connect to host
 173vpns.com: did not receive HSTS header
-173vpnv.com: did not receive HSTS header
+173vpnv.com: could not connect to host
 188betwarriors.co.uk: could not connect to host
 188trafalgar.ca: did not receive HSTS header
 195gm.com: could not connect to host
 1a-jva.de: could not connect to host
 1atic.com: could not connect to host
 1co-jp.net: did not receive HSTS header
 1cover.com: could not connect to host
 1k8b.com: could not connect to host
@@ -1810,17 +1837,17 @@ 25daysof.io: could not connect to host
 2859cc.com: could not connect to host
 2acbi-asso.fr: did not receive HSTS header
 2bizi.ru: could not connect to host
 2brokegirls.org: could not connect to host
 2carpros.com: did not receive HSTS header
 2intermediate.co.uk: did not receive HSTS header
 2or3.tk: could not connect to host
 2smart4food.com: did not receive HSTS header
-2ss.jp: did not receive HSTS header
+2ss.jp: could not connect to host
 300651.ru: did not receive HSTS header
 300mbmovie24.com: could not connect to host
 300mbmovies4u.cc: could not connect to host
 301.website: could not connect to host
 302.nyc: could not connect to host
 314166.com: could not connect to host
 32ph.com: could not connect to host
 33836.com: did not receive HSTS header
@@ -2014,16 +2041,17 @@ aether.pw: could not connect to host
 aevpn.net: could not connect to host
 aeyoun.com: did not receive HSTS header
 af-fotografie.net: did not receive HSTS header
 afdkompakt.de: max-age too low: 86400
 aficotroceni.ro: did not receive HSTS header
 afiru.net: could not connect to host
 afmchandler.com: did not receive HSTS header
 afp548.tk: could not connect to host
+africantourer.com: did not receive HSTS header
 after.im: did not receive HSTS header
 afvallendoeje.nu: could not connect to host
 afyou.co.kr: could not connect to host
 afzco.asia: did not receive HSTS header
 agalaxyfarfaraway.co.uk: could not connect to host
 agatheetraphael.fr: could not connect to host
 agbremen.de: did not receive HSTS header
 agentseeker.ca: could not connect to host
@@ -2060,27 +2088,25 @@ ajouin.com: could not connect to host
 aka.my: did not receive HSTS header
 akboy.pw: could not connect to host
 akclinics.org: did not receive HSTS header
 akerek.hu: could not connect to host
 akgundemirbas.com: could not connect to host
 akkadia.cc: could not connect to host
 akombakom.net: could not connect to host
 akselimedia.fi: did not receive HSTS header
-akstudentsfirst.org: could not connect to host
 aktivist.in: did not receive HSTS header
 al-shami.net: could not connect to host
 aladdin.ie: did not receive HSTS header
 alanlee.net: could not connect to host
 alanrickmanflipstable.com: could not connect to host
 alariel.de: did not receive HSTS header
 alarme-gps.ch: could not connect to host
 alarmegps.ch: could not connect to host
 alarmsystemreviews.com: did not receive HSTS header
-alaundeil.xyz: could not connect to host
 albanien.guide: could not connect to host
 alberguecimballa.es: could not connect to host
 albertbogdanowicz.pl: did not receive HSTS header
 albertopimienta.com: did not receive HSTS header
 alcantarafleuriste.com: did not receive HSTS header
 alcazaar.com: could not connect to host
 alecvannoten.be: did not receive HSTS header
 alenan.org: could not connect to host
@@ -2102,16 +2128,17 @@ all.tf: could not connect to host
 all4os.com: did not receive HSTS header
 alldaymonitoring.com: could not connect to host
 allegro-inc.com: did not receive HSTS header
 allinnote.com: could not connect to host
 allmbw.com: could not connect to host
 allmystery.de: did not receive HSTS header
 allo-symo.fr: did not receive HSTS header
 allods-zone.ru: could not connect to host
+alloffice.com.ua: did not receive HSTS header
 alloinformatique.net: could not connect to host
 allrealty.co.za: could not connect to host
 allsortscastles.co.uk: did not receive HSTS header
 allstarswithus.com: could not connect to host
 aloalabs.com: did not receive HSTS header
 alpha.irccloud.com: could not connect to host
 alphabit-secure.com: could not connect to host
 alphabuild.io: could not connect to host
@@ -2133,17 +2160,16 @@ amandaonishi.com: could not connect to h
 amavis.org: did not receive HSTS header
 amazing-gaming.fr: did not receive HSTS header
 amcvega.com: did not receive HSTS header
 amerhd.com: could not connect to host
 american-truck-simulator.de: could not connect to host
 american-truck-simulator.net: could not connect to host
 americansportsinstitute.org: did not receive HSTS header
 americanworkwear.nl: did not receive HSTS header
-amerimarkdirect.com: did not receive HSTS header
 amigogeek.net: could not connect to host
 amilx.com: could not connect to host
 amilx.org: could not connect to host
 amimoto-ami.com: max-age too low: 3153600
 amishsecurity.com: could not connect to host
 amitse.com: did not receive HSTS header
 amitube.com: did not receive HSTS header
 amlvfs.net: could not connect to host
@@ -2310,17 +2336,17 @@ arthan.me: could not connect to host
 artifex21.com: could not connect to host
 artifex21.fr: could not connect to host
 artiming.com: could not connect to host
 artisavotins.com: could not connect to host
 artisphere.ch: did not receive HSTS header
 artistnetwork.nl: did not receive HSTS header
 arto.bg: did not receive HSTS header
 arturkohut.com: could not connect to host
-artyland.ru: did not receive HSTS header
+artyland.ru: could not connect to host
 arvamus.eu: could not connect to host
 arzaroth.com: did not receive HSTS header
 as.se: could not connect to host
 as9178.net: could not connect to host
 asahikoji.net: could not connect to host
 asasuou.pw: could not connect to host
 asc16.com: could not connect to host
 ascamso.com: could not connect to host
@@ -2342,17 +2368,17 @@ atavio.at: could not connect to host
 atavio.ch: could not connect to host
 atavio.de: did not receive HSTS header
 atbeckett.com: did not receive HSTS header
 atcreform.gov: did not receive HSTS header
 atelier-rk.com: did not receive HSTS header
 atencionbimbo.com: max-age too low: 86400
 athaliasoft.com: could not connect to host
 athenelive.com: could not connect to host
-athensbusinessresources.us: could not connect to host
+athensbusinessresources.us: did not receive HSTS header
 athul.xyz: could not connect to host
 atlex.nl: did not receive HSTS header
 atlseccon.com: did not receive HSTS header
 atomic.menu: could not connect to host
 atomik.pro: could not connect to host
 atop.io: could not connect to host
 attic118.com: could not connect to host
 attimidesigns.com: did not receive HSTS header
@@ -2379,17 +2405,16 @@ aussiecable.org: did not receive HSTS he
 auth.mail.ru: did not receive HSTS header
 authentication.io: could not connect to host
 author24.ru: did not receive HSTS header
 authoritynutrition.com: did not receive HSTS header
 auto-serwis.zgorzelec.pl: did not receive HSTS header
 auto3d.cn: could not connect to host
 auto4trade.nl: could not connect to host
 autobedarf.net: did not receive HSTS header
-autobedrijfschalkoort.nl: did not receive HSTS header
 autodeploy.it: could not connect to host
 autoecolebudget.ch: did not receive HSTS header
 autoeet.cz: did not receive HSTS header
 autoepc.ro: did not receive HSTS header
 autojuhos.sk: could not connect to host
 autokovrik-diskont.ru: did not receive HSTS header
 automobiles5.com: could not connect to host
 autotsum.com: could not connect to host
@@ -2402,21 +2427,18 @@ av.de: did not receive HSTS header
 avadatravel.com: did not receive HSTS header
 avantmfg.com: did not receive HSTS header
 avec-ou-sans-ordonnance.fr: could not connect to host
 aveling-adventure.co.uk: did not receive HSTS header
 avepol.cz: did not receive HSTS header
 avepol.eu: did not receive HSTS header
 aviacao.pt: did not receive HSTS header
 aviodeals.com: could not connect to host
-avmo.pw: did not receive HSTS header
 avqueen.cn: could not connect to host
-avso.pw: did not receive HSTS header
 avus-automobile.com: did not receive HSTS header
-avxo.pw: did not receive HSTS header
 awanderlustadventure.com: did not receive HSTS header
 awg-mode.de: did not receive HSTS header
 aww.moe: did not receive HSTS header
 axado.com.br: did not receive HSTS header
 axelchv.fr: did not receive HSTS header
 axeny.com: did not receive HSTS header
 axg.io: did not receive HSTS header
 axolsoft.com: max-age too low: 10540800
@@ -2630,16 +2652,17 @@ billin.net: did not receive HSTS header
 billkiss.com: could not connect to host
 billninja.com: did not receive HSTS header
 billrusling.com: could not connect to host
 bimbo.com: did not receive HSTS header
 bimbo.com.ar: max-age too low: 86400
 bimbobakeriesusa.com: max-age too low: 86400
 binaryfigments.com: max-age too low: 86400
 binderapp.net: could not connect to host
+bing.com: did not receive HSTS header
 bioespuna.eu: did not receive HSTS header
 biofam.ru: did not receive HSTS header
 bioknowme.com: did not receive HSTS header
 bionicspirit.com: could not connect to host
 biophysik-ssl.de: did not receive HSTS header
 birkman.com: did not receive HSTS header
 bismarck.moe: did not receive HSTS header
 bisterfeldt.com: could not connect to host
@@ -2723,16 +2746,17 @@ bm-trading.nl: did not receive HSTS head
 bnhlibrary.com: did not receive HSTS header
 board-buy.ru: could not connect to host
 bodo-wolff.de: could not connect to host
 bodyblog.nl: did not receive HSTS header
 bodybuilding-legends.com: could not connect to host
 bodyweightsolution.com: could not connect to host
 boensou.com: did not receive HSTS header
 bogosity.se: could not connect to host
+bohaishibei.com: did not receive HSTS header
 bohan.life: could not connect to host
 bohramt.de: did not receive HSTS header
 boiadeirodeberna.com: could not connect to host
 boltdata.io: could not connect to host
 bonapp.restaurant: could not connect to host
 boneko.de: could not connect to host
 bonitabrazilian.co.nz: did not receive HSTS header
 bonop.com: did not receive HSTS header
@@ -2809,19 +2833,18 @@ brunohenc.from.hr: could not connect to 
 brunoonline.co.uk: could not connect to host
 bryn.xyz: could not connect to host
 bs12v.ru: did not receive HSTS header
 bsdtips.com: could not connect to host
 bsklabels.com: did not receive HSTS header
 btc-e.com: did not receive HSTS header
 btcdlc.com: could not connect to host
 btcpot.ltd: did not receive HSTS header
-btio.pw: did not receive HSTS header
 btxiaobai.com: did not receive HSTS header
-buben.tech: could not connect to host
+buben.tech: did not receive HSTS header
 bubulazi.com: did not receive HSTS header
 bubulazy.com: did not receive HSTS header
 buch-cuber.de: max-age too low: 0
 buchheld.at: did not receive HSTS header
 bucket.tk: could not connect to host
 budgetthostels.nl: did not receive HSTS header
 budskap.eu: could not connect to host
 buenosairesestetica.com.ar: could not connect to host
@@ -2845,16 +2868,17 @@ bulkbuy.tech: could not connect to host
 bullbits.com: max-age too low: 0
 bulletpoint.cz: could not connect to host
 bullterrier.me: could not connect to host
 bulmafox.com: could not connect to host
 bumarkamoda.com: did not receive HSTS header
 bunaken.asia: did not receive HSTS header
 bunbomenu.de: could not connect to host
 bunsenlabs.org: max-age too low: 2592000
+bupu.ml: did not receive HSTS header
 bureaubolster.nl: did not receive HSTS header
 bureaugravity.com: did not receive HSTS header
 burian-server.cz: could not connect to host
 burlesquemakeup.com: did not receive HSTS header
 burningcrash.de: max-age too low: 600000
 burpsuite.site: could not connect to host
 burrow.ovh: could not connect to host
 burrowingsec.com: could not connect to host
@@ -2892,19 +2916,19 @@ bypassed.me: could not connect to host
 bypassed.online: could not connect to host
 bypassed.org: did not receive HSTS header
 bypassed.party: could not connect to host
 bypassed.press: could not connect to host
 bypassed.pw: could not connect to host
 bypassed.rocks: did not receive HSTS header
 bypassed.site: could not connect to host
 bypassed.st: did not receive HSTS header
-bypassed.today: did not receive HSTS header
-bypassed.works: did not receive HSTS header
-bypassed.world: did not receive HSTS header
+bypassed.today: could not connect to host
+bypassed.works: could not connect to host
+bypassed.world: could not connect to host
 bypro.xyz: could not connect to host
 bysymphony.com: max-age too low: 0
 byte.chat: did not receive HSTS header
 byte.wtf: did not receive HSTS header
 bytepark.de: did not receive HSTS header
 bytesatwork.eu: could not connect to host
 bytesund.biz: could not connect to host
 byurudraw.pics: could not connect to host
@@ -3103,30 +3127,32 @@ chotu.net: could not connect to host
 chris-web.info: could not connect to host
 chrisandsarahinasia.com: did not receive HSTS header
 chrisbrakebill.com: could not connect to host
 chrisbrown.id.au: could not connect to host
 chrisfaber.com: could not connect to host
 chriskirchner.de: did not receive HSTS header
 chriskyrouac.com: could not connect to host
 chrisopperwall.com: did not receive HSTS header
+chrispstreet.com: did not receive HSTS header
 chrisself.xyz: did not receive HSTS header
 christiaandruif.nl: could not connect to host
 christianbro.gq: could not connect to host
 christina-quast.de: did not receive HSTS header
 christophercolumbusfoundation.gov: could not connect to host
 christophheich.me: did not receive HSTS header
 chrisupjohn.com: could not connect to host
 chrisvicmall.com: did not receive HSTS header
 chrome: could not connect to host
 chrome-devtools-frontend.appspot.com: did not receive HSTS header (error ignored - included regardless)
 chrome.google.com: did not receive HSTS header (error ignored - included regardless)
 chrst.ph: could not connect to host
 chs.us: did not receive HSTS header
 chua.cf: could not connect to host
+chuckame.fr: did not receive HSTS header
 chulado.com: did not receive HSTS header
 churchux.co: did not receive HSTS header
 churrasqueirafacil.com.br: could not connect to host
 ci-labo.com.tw: max-age too low: 7889238
 cidr.ml: could not connect to host
 cienbeaute-lidl.fr: did not receive HSTS header
 cigarblogs.net: could not connect to host
 cigi.site: could not connect to host
@@ -3354,17 +3380,16 @@ couponcodeq.com: could not connect to ho
 couragewhispers.ca: could not connect to host
 coursdeprogrammation.com: could not connect to host
 coursella.com: did not receive HSTS header
 covenantbank.net: could not connect to host
 coverdat.com: did not receive HSTS header
 coverduck.ru: could not connect to host
 cpuvinf.eu.org: could not connect to host
 cracking.org: did not receive HSTS header
-crackingking.com: did not receive HSTS header
 craftbeerbarn.co.uk: could not connect to host
 craftedge.xyz: could not connect to host
 craftmain.eu: could not connect to host
 cranems.com.ua: did not receive HSTS header
 cranioschule.com: did not receive HSTS header
 crate.io: did not receive HSTS header
 cravelyrics.com: could not connect to host
 crazifyngers.com: could not connect to host
@@ -3372,16 +3397,17 @@ crazy-crawler.de: did not receive HSTS h
 crazycen.com: did not receive HSTS header
 crazycraftland.de: could not connect to host
 crazycraftland.net: did not receive HSTS header
 crazyhotseeds.com: did not receive HSTS header
 crazyker.com: did not receive HSTS header
 crbug.com: did not receive HSTS header (error ignored - included regardless)
 creaescola.com: did not receive HSTS header
 create-test-publish.co.uk: could not connect to host
+creative-coder.de: did not receive HSTS header
 creativeapple.ltd: did not receive HSTS header
 creativeartifice.com: did not receive HSTS header
 creativephysics.ml: could not connect to host
 creativeplayuk.com: did not receive HSTS header
 crecket.me: could not connect to host
 creditclear.com.au: did not receive HSTS header
 crendontech.com: could not connect to host
 crestoncottage.com: could not connect to host
@@ -3528,17 +3554,16 @@ darkanzali.pl: max-age too low: 0
 darkfriday.ddns.net: could not connect to host
 darkhole.cn: did not receive HSTS header
 darkkeepers.dk: max-age too low: 172800
 darknebula.space: could not connect to host
 darkpony.ru: could not connect to host
 darksideof.it: could not connect to host
 darkstance.org: could not connect to host
 darktree.in: could not connect to host
-darlastudio66.com: could not connect to host
 darrenellis.xyz: did not receive HSTS header
 dash-board.jp: did not receive HSTS header
 dash.rocks: did not receive HSTS header
 dashburst.com: did not receive HSTS header
 dashnimorad.com: did not receive HSTS header
 data-abundance.com: could not connect to host
 data.haus: could not connect to host
 data.qld.gov.au: did not receive HSTS header
@@ -3673,17 +3698,16 @@ diagnosia.com: did not receive HSTS head
 diagonale-deco.fr: did not receive HSTS header
 diamondcare.com.br: could not connect to host
 dianlujitao.com: did not receive HSTS header
 diannaobos.com: did not receive HSTS header
 dicando.com: could not connect to host
 dicelab.co.uk: could not connect to host
 dicionariofinanceiro.com: did not receive HSTS header
 dicionariopopular.com: did not receive HSTS header
-dicoding.com: did not receive HSTS header
 dieb.photo: could not connect to host
 diejanssens.net: did not receive HSTS header
 dierenkruiden.nl: could not connect to host
 diewebstube.de: could not connect to host
 diezel.com: could not connect to host
 diferenca.com: did not receive HSTS header
 diggable.co: did not receive HSTS header
 digired.xyz: could not connect to host
@@ -3856,30 +3880,30 @@ drostschocolates.com: did not receive HS
 drtroyhendrickson.com: could not connect to host
 drumbandesperanto.nl: did not receive HSTS header
 drupal123.com: could not connect to host
 dryan.com: did not receive HSTS header
 drycreekapiary.com: could not connect to host
 ds-christiansen.de: could not connect to host
 dshiv.io: could not connect to host
 dtub.co: could not connect to host
-dualias.xyz: did not receive HSTS header
 dubik.su: did not receive HSTS header
 ducohosting.com: max-age too low: 2592000
 dudesunderwear.com.br: could not connect to host
 duelysthub.com: could not connect to host
 duerls.de: did not receive HSTS header
 dukec.me: did not receive HSTS header
 dullsir.com: could not connect to host
 dune.io: did not receive HSTS header
 dunea.nl: did not receive HSTS header
 dungi.org: could not connect to host
 duole30.com: did not receive HSTS header
 duongpho.com: did not receive HSTS header
 duskopy.top: could not connect to host
+dutchessuganda.com: did not receive HSTS header
 dutchrank.com: did not receive HSTS header
 duuu.ch: could not connect to host
 dycem-ns.com: did not receive HSTS header
 dycoa.com: did not receive HSTS header
 dycontrol.de: could not connect to host
 dylanscott.com.au: did not receive HSTS header
 dymersion.com: did not receive HSTS header
 dynamic-innovations.net: could not connect to host
@@ -4239,16 +4263,17 @@ fairlyoddtreasures.com: did not receive 
 faizan.xyz: did not receive HSTS header
 fakeletters.org: did not receive HSTS header
 faktura.pl: did not receive HSTS header
 falconfrag.com: could not connect to host
 falconwiz.com: did not receive HSTS header
 falkhusemann.de: did not receive HSTS header
 falkp.no: did not receive HSTS header
 fallenangelspirits.uk: could not connect to host
+fallofthecitadel.com: did not receive HSTS header
 faluninfo.ba: did not receive HSTS header
 fam-weyer.de: could not connect to host
 fame-agency.net: could not connect to host
 famep.gov: could not connect to host
 familie-sprink.de: could not connect to host
 familie-zimmermann.at: could not connect to host
 famio.cn: could not connect to host
 fanflow.com: did not receive HSTS header
@@ -4618,17 +4643,16 @@ george-brighton.co.uk: could not connect
 georgebrighton.co.uk: could not connect to host
 georgesonarthurs.com.au: did not receive HSTS header
 gereja.ga: could not connect to host
 gerencianet.com.br: did not receive HSTS header
 gereon.ch: could not connect to host
 gesiwista.net: could not connect to host
 gesunde-smoothies.de: did not receive HSTS header
 get-cctv.com: could not connect to host
-get-refer.com: did not receive HSTS header
 get.zenpayroll.com: did not receive HSTS header
 getable.com: did not receive HSTS header
 getblys.com.au: did not receive HSTS header
 getbooks.co.il: did not receive HSTS header
 getcarefirst.com: could not connect to host
 getcarina.com: could not connect to host
 getcleartouch.com: did not receive HSTS header
 getcolor.com: did not receive HSTS header
@@ -4655,16 +4679,17 @@ gfhgiro.nl: max-age too low: 0
 gfm.tech: could not connect to host
 gfwsb.ml: could not connect to host
 ggss.ml: could not connect to host
 gheorghe-sarcov.ga: could not connect to host
 gheorghesarcov.ga: could not connect to host
 gheorghesarcov.tk: could not connect to host
 ghi.gov: could not connect to host
 ghkim.net: could not connect to host
+ghuntley.com: max-age too low: 0
 giakki.eu: could not connect to host
 gianlucapartengo.photography: did not receive HSTS header
 gibraltar-firma.com: did not receive HSTS header
 gidea.nu: could not connect to host
 gietvloergarant.nl: did not receive HSTS header
 giftgofers.com: did not receive HSTS header
 giftservices.nl: could not connect to host
 gigacloud.org: max-age too low: 0
@@ -4727,16 +4752,17 @@ gogetssl.com: did not receive HSTS heade
 goggs.eu: could not connect to host
 gogold-g.com: could not connect to host
 gold24.in: did not receive HSTS header
 goldegg-training.com: did not receive HSTS header
 goldendata.io: could not connect to host
 goldminer.ga: could not connect to host
 goldpros.com: did not receive HSTS header
 golocal-media.de: could not connect to host
+gomiblog.com: did not receive HSTS header
 gong8.win: could not connect to host
 gonzalosanchez.mx: did not receive HSTS header
 goodfurday.ca: did not receive HSTS header
 goodtech.com.br: could not connect to host
 goodwin43.ru: could not connect to host
 google: could not connect to host (error ignored - included regardless)
 googlemail.com: did not receive HSTS header (error ignored - included regardless)
 googleplex.com: did not receive HSTS header (error ignored - included regardless)
@@ -5083,18 +5109,18 @@ hodne.io: could not connect to host
 hoekwoningverkopen.nl: could not connect to host
 hoerbuecher-und-hoerspiele.de: could not connect to host
 hofiprojekt.cz: did not receive HSTS header
 hogar123.es: could not connect to host
 hoiku-map.tokyo: could not connect to host
 hoiku-navi.com: did not receive HSTS header
 holgerlehner.com: could not connect to host
 holifestival-freyung.de: could not connect to host
+holygrail.games: did not receive HSTS header
 holymoly.lu: could not connect to host
-holz.nu: did not receive HSTS header
 homa.website: could not connect to host
 homads.com: did not receive HSTS header
 homeandyarddetailing.com: could not connect to host
 homeclouding.de: could not connect to host
 homedna.com: did not receive HSTS header
 homeexx.com: did not receive HSTS header
 homeownersassociationmanagementla.com: did not receive HSTS header
 homeseller.co.uk: could not connect to host
@@ -5246,17 +5272,17 @@ igi.codes: did not receive HSTS header
 igiftcards.nl: did not receive HSTS header
 ignatisd.gr: did not receive HSTS header
 igule.net: could not connect to host
 ihotel.io: did not receive HSTS header
 ihrlotto.de: could not connect to host
 ihrnationalrat.ch: could not connect to host
 ihsbsd.me: could not connect to host
 ihsbsd.tk: could not connect to host
-iideaz.org: could not connect to host
+iideaz.org: did not receive HSTS header
 iispeed.com: did not receive HSTS header
 ijn-dd.nl: could not connect to host
 ijoda.com: could not connect to host
 ikocik.sk: did not receive HSTS header
 ikon.name: did not receive HSTS header
 ikwilguidobellen.nl: could not connect to host
 ikzoekjeugdhulp.nl: did not receive HSTS header
 ilbuongiorno.it: did not receive HSTS header
@@ -5284,21 +5310,21 @@ immunicity.cc: could not connect to host
 immunicity.date: did not receive HSTS header
 immunicity.eu: did not receive HSTS header
 immunicity.host: could not connect to host
 immunicity.info: could not connect to host
 immunicity.online: could not connect to host
 immunicity.press: could not connect to host
 immunicity.rocks: could not connect to host
 immunicity.st: did not receive HSTS header
-immunicity.today: did not receive HSTS header
+immunicity.today: could not connect to host
 immunicity.top: could not connect to host
 immunicity.win: could not connect to host
-immunicity.works: did not receive HSTS header
-immunicity.world: did not receive HSTS header
+immunicity.works: could not connect to host
+immunicity.world: could not connect to host
 imolug.org: did not receive HSTS header
 imoni-blog.net: could not connect to host
 imoto.me: could not connect to host
 imouto.my: max-age too low: 5184000
 imperialwebsolutions.com: did not receive HSTS header
 imu.li: did not receive HSTS header
 imusic.dk: did not receive HSTS header
 inb4.us: could not connect to host
@@ -5354,16 +5380,17 @@ inmyarea.com: max-age too low: 0
 innophate-security.nl: could not connect to host
 inplacers.ru: did not receive HSTS header
 inquisitive.io: could not connect to host
 insane-bullets.com: could not connect to host
 insite-feedback.com: could not connect to host
 inspire-av.com: did not receive HSTS header
 inspiroinc.com: could not connect to host
 instacart.com: did not receive HSTS header
+installgentoo.net: did not receive HSTS header
 instant-hack.com: did not receive HSTS header
 instantdev.io: could not connect to host
 institutoflordelavida.com: could not connect to host
 institutolancaster.com: did not receive HSTS header
 instruktor.io: could not connect to host
 intel.gov: did not receive HSTS header
 intel.li: could not connect to host
 interboursegeneva.ch: did not receive HSTS header
@@ -5638,16 +5665,17 @@ jm22.com: did not receive HSTS header
 jmbelloteau.com: did not receive HSTS header
 jmdekker.it: could not connect to host
 jn1.me: did not receive HSTS header
 joakimalgroy.com: could not connect to host
 jobflyapp.com: could not connect to host
 jobshq.com: did not receive HSTS header
 jobss.co.uk: did not receive HSTS header
 joelgonewild.com: did not receive HSTS header
+johannes-bauer.com: did not receive HSTS header
 johannes-sprink.de: could not connect to host
 johnbrownphotography.ch: did not receive HSTS header
 johncardell.com: did not receive HSTS header
 johners.me: could not connect to host
 johngaltgroup.com: did not receive HSTS header
 johnhgaunt.com: did not receive HSTS header
 johnmcgovern.com: max-age too low: 43200
 johnrom.com: did not receive HSTS header
@@ -5778,22 +5806,21 @@ kdbx.online: could not connect to host
 kdm-online.de: did not receive HSTS header
 keeley.gq: could not connect to host
 keeley.ml: could not connect to host
 keeleysam.me: could not connect to host
 keepaa.com: could not connect to host
 keepassa.co: could not connect to host
 keepclean.me: could not connect to host
 keepcoalintheground.org: could not connect to host
-keepflow.io: did not receive HSTS header
 kefaloniatoday.com: did not receive HSTS header
 kenkoelectric.com: did not receive HSTS header
 kentacademiestrust.org.uk: did not receive HSTS header
 kenvix.com: could not connect to host
-kepkonyvtar.hu: did not receive HSTS header
+kepkonyvtar.hu: could not connect to host
 kerangalam.com: did not receive HSTS header
 kerksanders.nl: did not receive HSTS header
 kermadec.blog: could not connect to host
 kermadec.net: did not receive HSTS header
 kernl.us: did not receive HSTS header
 keskeces.com: did not receive HSTS header
 keymaster.lookout.com: did not receive HSTS header
 kfbrussels.be: could not connect to host
@@ -5828,17 +5855,17 @@ kintrip.com: did not receive HSTS header
 kionetworks.com: did not receive HSTS header
 kipin.fr: did not receive HSTS header
 kipira.com: could not connect to host
 kirara.eu: could not connect to host
 kirkforcongress.com: could not connect to host
 kirkforsenate.com: could not connect to host
 kirkpatrickdavis.com: could not connect to host
 kisa.io: could not connect to host
-kisalt.im: could not connect to host
+kisalt.im: did not receive HSTS header
 kiss-register.org: did not receive HSTS header
 kissart.net: could not connect to host
 kisstyle.ru: did not receive HSTS header
 kita.id: did not receive HSTS header
 kitabgaul.com: did not receive HSTS header
 kitakemon.com: could not connect to host
 kitashop.com.br: did not receive HSTS header
 kitatec.com.br: could not connect to host
@@ -5863,17 +5890,17 @@ kleertjesvoordelig.nl: could not connect
 kleinerarchitekturfuehrer.de: could not connect to host
 klempnershop.eu: did not receive HSTS header
 kleppe.co: could not connect to host
 kletterkater.com: did not receive HSTS header
 klicktojob.de: could not connect to host
 kloentrup.de: did not receive HSTS header
 klunkergarten.org: could not connect to host
 knapen.io: max-age too low: 604800
-knccloud.com: did not receive HSTS header
+knccloud.com: could not connect to host
 knigadel.com: did not receive HSTS header
 knightsbridgegroup.org: could not connect to host
 knowdebt.org: did not receive HSTS header
 knowledgesnap.com: could not connect to host
 knowledgesnapsites.com: could not connect to host
 kodakit.com: max-age too low: 0
 koddsson.com: did not receive HSTS header
 kode-it.de: could not connect to host
@@ -5974,16 +6001,17 @@ labrasaq8.com: did not receive HSTS head
 labs.directory: could not connect to host
 labs.moscow: did not receive HSTS header
 lacarpesaintaubinoise.fr: did not receive HSTS header
 lacaverne.nl: could not connect to host
 lacentral.com: did not receive HSTS header
 lachlankidson.net: did not receive HSTS header
 lacledeslan.ninja: could not connect to host
 lacocinadelila.com: did not receive HSTS header
+lacuevadechauvet.com: did not receive HSTS header
 ladylucks.co.uk: did not receive HSTS header
 laemen.com: did not receive HSTS header
 laemen.nl: could not connect to host
 laf.in.net: could not connect to host
 lagalerievirtuelle.fr: did not receive HSTS header
 lagier.xyz: could not connect to host
 lagoza.name: could not connect to host
 lainchan.org: did not receive HSTS header
@@ -5997,17 +6025,16 @@ lanauzedesigns.com: did not receive HSTS
 lanboll.com: could not connect to host
 lancehoteis.com: did not receive HSTS header
 lancehoteis.com.br: did not receive HSTS header
 land-links.org: did not receive HSTS header
 landgoedverkopen.nl: could not connect to host
 landhuisverkopen.nl: could not connect to host
 landscape.canonical.com: max-age too low: 2592000
 landscapingmedic.com: did not receive HSTS header
-landyparts.nl: did not receive HSTS header
 langenbach.rocks: could not connect to host
 langendries.eu: could not connect to host
 langhun.me: did not receive HSTS header
 laniakean.com: could not connect to host
 lanseyujie.com: max-age too low: 2592000
 lansinoh.co.uk: did not receive HSTS header
 lanzainc.xyz: did not receive HSTS header
 laobox.fr: could not connect to host
@@ -6168,17 +6195,16 @@ listafirmelor.com: could not connect to 
 listage.ovh: did not receive HSTS header
 litespeed.io: could not connect to host
 little.pw: did not receive HSTS header
 littlefreelibrary.org: did not receive HSTS header
 littleqiu.net: could not connect to host
 liujunyang.com: did not receive HSTS header
 livedemo.io: could not connect to host
 livej.am: could not connect to host
-liveperformersmeeting.net: did not receive HSTS header
 liverewrite.com: could not connect to host
 liviababynet.com.br: could not connect to host
 livrariahugodesaovitor.com.br: did not receive HSTS header
 lixiang.one: could not connect to host
 lixingcong.com: could not connect to host
 lkp111138.me: could not connect to host
 llamasweet.tech: could not connect to host
 lmkts.com: max-age too low: 0
@@ -6196,16 +6222,17 @@ locktheirphone.com: could not connect to
 lockyourcomputer.pw: did not receive HSTS header
 locomotive.ca: did not receive HSTS header
 locvis.ru: did not receive HSTS header
 loftboard.eu: could not connect to host
 log2n.uk: could not connect to host
 logario.com.br: could not connect to host
 logicaladvertising.com: could not connect to host
 login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless)
+login.gov: did not receive HSTS header
 login.persona.org: could not connect to host
 loginseite.com: could not connect to host
 logistify.com.mx: did not receive HSTS header
 lognot.net: could not connect to host
 logymedia.com: could not connect to host
 loisircreatif.net: did not receive HSTS header
 lojadocristaozinho.com.br: did not receive HSTS header
 lojashowdecozinha.com.br: could not connect to host
@@ -6245,17 +6272,16 @@ lovelyfriends.org: did not receive HSTS 
 loveto.at: could not connect to host
 lovingearth.net: max-age too low: 0
 lowhangingfruitgrabber.com: could not connect to host
 loxis.be: did not receive HSTS header
 lpak.nl: could not connect to host
 lpgram.ga: could not connect to host
 lrhsclubs.com: could not connect to host
 lrhstsa.com: could not connect to host
-lrssystems.com: did not receive HSTS header
 ls-a.org: did not receive HSTS header
 ls-reallife.de: did not receive HSTS header
 lsky.cn: could not connect to host
 lsp-sports.de: did not receive HSTS header
 ltbytes.com: could not connect to host
 ltechnologygroup.com: did not receive HSTS header
 ltu.social: could not connect to host
 lucas-garte.com: did not receive HSTS header
@@ -6324,16 +6350,17 @@ mademoiselle-emma.be: did not receive HS
 mademoiselle-emma.fr: did not receive HSTS header
 maderwin.com: did not receive HSTS header
 madesoftware.com.br: did not receive HSTS header
 mafamane.com: could not connect to host
 mafiareturns.com: max-age too low: 2592000
 magenx.com: did not receive HSTS header
 magia360.com: did not receive HSTS header
 magneticanvil.com: did not receive HSTS header
+magyarokegyhelyen.hu: did not receive HSTS header
 mahamed91.pw: could not connect to host
 mahfouzadedimeji.com: did not receive HSTS header
 maidofhonorcleaning.net: max-age too low: 200
 mail-settings.google.com: did not receive HSTS header (error ignored - included regardless)
 mail.google.com: did not receive HSTS header (error ignored - included regardless)
 mailchuck.com: could not connect to host
 maildragon.com: could not connect to host
 mailgarant.nl: could not connect to host
@@ -6376,17 +6403,17 @@ manageall.de: could not connect to host
 manageforall.com: could not connect to host
 manageforall.de: could not connect to host
 managemynetsuite.com: did not receive HSTS header
 manantial.mx: did not receive HSTS header
 mandpress.com: did not receive HSTS header
 mangazuki.co: did not receive HSTS header
 maniadeprazer.com.br: could not connect to host
 manifestbin.com: did not receive HSTS header
-manipulatedtme.com: did not receive HSTS header
+manipulatedtme.com: could not connect to host
 manitasicily.com: did not receive HSTS header
 manningbrothers.com: did not receive HSTS header
 manns-solutions.com: did not receive HSTS header
 manns-solutions.ru: did not receive HSTS header
 mannsolutions.co.uk: did not receive HSTS header
 mansfieldplacevt.com: did not receive HSTS header
 manshop24.com: could not connect to host
 mansion-note.com: did not receive HSTS header
@@ -6506,17 +6533,16 @@ mcdonalds.ru: did not receive HSTS heade
 mcga.media: could not connect to host
 mclab.su: could not connect to host
 mclist.it: could not connect to host
 mclyr.com: did not receive HSTS header
 mcmillansedationdentistry.com: did not receive HSTS header
 mcooperlaw.com: did not receive HSTS header
 mcuexchange.com: did not receive HSTS header
 mdfnet.se: did not receive HSTS header
-mdkr.nl: did not receive HSTS header
 mdscomp.net: did not receive HSTS header
 meadowfenfarm.com: could not connect to host
 meamod.com: max-age too low: 0
 meat-education.com: could not connect to host
 mebio.us: could not connect to host
 mecenat-cassous.com: did not receive HSTS header
 mechmk1.me: did not receive HSTS header
 medallia.io: could not connect to host
@@ -6688,17 +6714,17 @@ mintea-noua.ro: did not receive HSTS hea
 miragrow.com: could not connect to host
 mirindadomo.ru: did not receive HSTS header
 mironized.com: did not receive HSTS header
 mirrorx.com: did not receive HSTS header
 misgluteosperfectos.com: did not receive HSTS header
 misiondelosangeles-mailing.com: did not receive HSTS header
 missrain.tw: could not connect to host
 mist.ink: could not connect to host
-mister.hosting: could not connect to host
+mister.hosting: did not receive HSTS header
 misterl.net: did not receive HSTS header
 mitarbeiter-pc.de: did not receive HSTS header
 mitchellrenouf.ca: could not connect to host
 mitm-software.badssl.com: could not connect to host
 mittenhacks.com: could not connect to host
 mivcon.net: could not connect to host
 miweb.cr: did not receive HSTS header
 mizd.at: could not connect to host
@@ -6770,17 +6796,16 @@ monautoneuve.fr: did not receive HSTS he
 mondar.io: could not connect to host
 mondopoint.com: did not receive HSTS header
 mondwandler.de: could not connect to host
 moneromerchant.com: could not connect to host
 moneycrownmedia.com: could not connect to host
 monika-sokol.de: did not receive HSTS header
 monitaure.io: could not connect to host
 monitman.com: did not receive HSTS header
-monoseis-monotica.gr: max-age too low: 300
 monsieurbureau.com: did not receive HSTS header
 montanacures.org: could not connect to host
 montanwerk.de: did not receive HSTS header
 montonicms.com: could not connect to host
 moon.lc: could not connect to host
 moonless.net: could not connect to host
 moonloupe.com: could not connect to host
 moonysbouncycastles.co.uk: did not receive HSTS header
@@ -6904,16 +6929,17 @@ mygov.scot: did not receive HSTS header
 myhair.asia: did not receive HSTS header
 myiocc.org: could not connect to host
 myip.tech: max-age too low: 2592000
 myjumpsuit.de: did not receive HSTS header
 mykolab.com: did not receive HSTS header
 mykreuzfahrt.de: could not connect to host
 mymp3singer.site: did not receive HSTS header
 mynetblog.com: did not receive HSTS header
+mynewleaf.co: did not receive HSTS header
 mynewselfbariatrics.com: did not receive HSTS header
 myni.io: could not connect to host
 mynigma.org: did not receive HSTS header
 mypagella.com: could not connect to host
 mypagella.eu: could not connect to host
 mypagella.it: could not connect to host
 mypension.ca: could not connect to host
 myphonebox.de: could not connect to host
@@ -7022,31 +7048,32 @@ net4it.de: did not receive HSTS header
 netbox.cc: could not connect to host
 netbrief.ml: did not receive HSTS header
 netherwind.eu: did not receive HSTS header
 netlilo.com: could not connect to host
 netloanusa.com: could not connect to host
 netmagik.com: did not receive HSTS header
 netprofile.com.au: could not connect to host
 netresourcedesign.com: could not connect to host
+netsparkercloud.com: did not receive HSTS header
 nettefoundation.com: could not connect to host
 networx-online.de: could not connect to host
 netzbit.de: could not connect to host
 netzpolitik.org: max-age too low: 2592000
 netztest.at: did not receive HSTS header
 netzvieh.de: did not receive HSTS header
 netzzwerg4u.de: could not connect to host
 neueonlinecasino2016.com: could not connect to host
 neuralgic.net: could not connect to host
 neuro-plus-100.com: could not connect to host
 neuronfactor.com: max-age too low: 1000
 never-afk.de: did not receive HSTS header
 never.pet: did not receive HSTS header
 neveta.com: could not connect to host
-newbieboss.com: could not connect to host
+newbieboss.com: did not receive HSTS header
 newedivideo.it: could not connect to host
 newgenerationplus.org: could not connect to host
 newhdmovies.io: could not connect to host
 newkaliningrad.ru: did not receive HSTS header
 newlooknow.com: did not receive HSTS header
 newmelalife.com: did not receive HSTS header
 newparadigmventures.net: did not receive HSTS header
 newportpropertygroup.com: could not connect to host
@@ -7489,17 +7516,17 @@ pastdream.xyz: could not connect to host
 paste.linode.com: could not connect to host
 pastebin.linode.com: could not connect to host
 pastenib.com: could not connect to host
 paster.li: did not receive HSTS header
 pataua.kiwi: did not receive HSTS header
 paternitydnatest.com: could not connect to host
 patfs.com: did not receive HSTS header
 patientinsight.net: did not receive HSTS header
-patt.us: did not receive HSTS header
+patt.us: could not connect to host
 patterson.mp: could not connect to host
 paul-kerebel.pro: could not connect to host
 paulbunyanmls.com: did not receive HSTS header
 paulproell.at: could not connect to host
 paulyang.cn: did not receive HSTS header
 pavelfojt.cz: did not receive HSTS header
 pavelkahouseforcisco.com: did not receive HSTS header
 paxdei.com.br: could not connect to host
@@ -7591,16 +7618,17 @@ phdsupply.com: could not connect to host
 philadelphiacandies.com: did not receive HSTS header
 phillmoore.com: did not receive HSTS header
 philpropertygroup.com: could not connect to host
 phoebe.co.nz: did not receive HSTS header
 phoenicis.com.ua: did not receive HSTS header
 phonenumberinfo.co.uk: could not connect to host
 phongmay24h.com: could not connect to host
 photoblogverona.com: could not connect to host
+photoboothpartyhire.co.uk: did not receive HSTS header
 phototag.org: did not receive HSTS header
 php-bach.org: could not connect to host
 phperformances.fr: did not receive HSTS header
 phrasing.me: could not connect to host
 physicaltherapist.com: did not receive HSTS header
 pi-eng.fr: did not receive HSTS header
 pianetaottica.net: could not connect to host
 pianetaottica.org: could not connect to host
@@ -7768,24 +7796,23 @@ prefontaine.name: could not connect to h
 prego-shop.de: did not receive HSTS header
 preissler.co.uk: could not connect to host
 prelist.org: did not receive HSTS header
 prelogica.com.br: did not receive HSTS header
 prepandgo-euro.com: could not connect to host
 preppertactics.com: did not receive HSTS header
 presidentials2016.com: could not connect to host
 press-anime-nenkan.com: did not receive HSTS header
-press-presse.ca: did not receive HSTS header
 pressenews.net: did not receive HSTS header
 pressfreedomfoundation.org: did not receive HSTS header
 prettygrouse.com: did not receive HSTS header
 prettyphotoart.de: did not receive HSTS header
 pretzlaff.info: did not receive HSTS header
 preworkout.me: could not connect to host
-prezola.com: did not receive HSTS header
+prezola.com: max-age too low: 0
 prgslab.net: could not connect to host
 pridoc.se: did not receive HSTS header
 prilock.com: did not receive HSTS header
 prinbanat.ngo: did not receive HSTS header
 printerest.io: could not connect to host
 printersonline.be: did not receive HSTS header
 printery.be: did not receive HSTS header
 printfn.com: could not connect to host
@@ -7813,16 +7840,17 @@ prohostonline.fi: could not connect to h
 proitconsulting.com.au: could not connect to host
 project-sparks.eu: did not receive HSTS header
 projectascension.io: could not connect to host
 projectdp.net: could not connect to host
 projectmercury.space: could not connect to host
 projectvault.ovh: did not receive HSTS header
 projektik.cz: did not receive HSTS header
 projetoresecia.com: could not connect to host
+prolan.pw: did not receive HSTS header
 promarketer.net: did not receive HSTS header
 promecon-gmbh.de: did not receive HSTS header
 prontocleaners.co.uk: did not receive HSTS header
 prontolight.com: did not receive HSTS header
 prontomovers.co.uk: could not connect to host
 propactrading.com: could not connect to host
 prosoft.sk: did not receive HSTS header
 prosperident.com: did not receive HSTS header
@@ -7874,16 +7902,17 @@ pwd.ovh: could not connect to host
 pwm.jp: could not connect to host
 pwnsdx.pw: could not connect to host
 pyol.org: could not connect to host
 pypi-mirrors.org: could not connect to host
 pypi-status.org: could not connect to host
 pyplo.org: did not receive HSTS header
 pypt.lt: did not receive HSTS header
 pyrrhonism.org: could not connect to host
+pysays.net: did not receive HSTS header
 pythonic.guru: could not connect to host
 pythonic.training: could not connect to host
 pzgreni.ch: did not receive HSTS header
 pzme.me: could not connect to host
 q-rickroll-u.pw: could not connect to host
 q2.si: did not receive HSTS header
 q8mp3.me: did not receive HSTS header
 qbik.de: did not receive HSTS header
@@ -7921,17 +7950,16 @@ quebecmailbox.com: could not connect to 
 queenbrownie.com.br: could not connect to host
 quelmandataire.fr: did not receive HSTS header
 queryplayground.com: could not connect to host
 questsandrewards.com: could not connect to host
 quickandroid.tools: could not connect to host
 quickpayservice.com: could not connect to host
 quizionic.com: could not connect to host
 quizmemes.org: could not connect to host
-quli.nl: could not connect to host
 quotehex.com: could not connect to host
 quotemaster.co.za: could not connect to host
 quranserver.net: could not connect to host
 qvi.st: could not connect to host
 qwilink.me: did not receive HSTS header
 r-ay.cn: could not connect to host
 r-core.ru: could not connect to host
 r-rickroll-u.pw: could not connect to host
@@ -8013,17 +8041,16 @@ readydok.com: did not receive HSTS heade
 reagir43.fr: did not receive HSTS header
 realmic.net: could not connect to host
 realmofespionage.com: could not connect to host
 reapdrive.net: did not receive HSTS header
 reaper.rip: could not connect to host
 reardenporn.com: could not connect to host
 rebekaesgabor.online: could not connect to host
 rebootmc.com: did not receive HSTS header
-recyclingpromotions.us: did not receive HSTS header
 redable.nl: did not receive HSTS header
 redair.es: did not receive HSTS header
 redar.xyz: could not connect to host
 reddit.com: did not receive HSTS header
 rede.ca: did not receive HSTS header
 redhorsemountainranch.com: did not receive HSTS header
 redicabo.de: could not connect to host
 redirectman.com: did not receive HSTS header
@@ -8184,16 +8211,17 @@ romaimperator.com: did not receive HSTS 
 romainmuller.xyz: did not receive HSTS header
 romans-place.me.uk: could not connect to host
 romeoferraris.com: did not receive HSTS header
 romulusapp.com: could not connect to host
 ron2k.za.net: could not connect to host
 rondoniatec.com.br: did not receive HSTS header
 ronvandordt.info: could not connect to host
 ronwo.de: max-age too low: 1
+room208.org: did not receive HSTS header
 rootforum.org: did not receive HSTS header
 rootservice.org: did not receive HSTS header
 rootwpn.com: could not connect to host
 rop.io: could not connect to host
 roquecenter.org: did not receive HSTS header
 rorymcdaniel.com: did not receive HSTS header
 rossen.be: did not receive HSTS header
 rotex1840.de: did not receive HSTS header
@@ -8252,16 +8280,17 @@ ryansmithphotography.com: did not receiv
 ryanteck.uk: did not receive HSTS header
 rylin.net: did not receive HSTS header
 ryssland.guide: could not connect to host
 s-d-v.ch: could not connect to host
 s-rickroll-p.pw: could not connect to host
 s.how: could not connect to host
 s1mplescripts.de: did not receive HSTS header
 saabwa.org: did not receive HSTS header
+sadsu.com: did not receive HSTS header
 safeex.com: did not receive HSTS header
 safelist.eu: did not receive HSTS header
 safematix.com: could not connect to host
 safemovescheme.co.uk: could not connect to host
 safersurfing.eu: did not receive HSTS header
 safetyrisk.net: did not receive HSTS header
 safewings-nh.nl: could not connect to host
 safing.me: did not receive HSTS header
@@ -8330,17 +8359,16 @@ save.gov: could not connect to host
 saveaward.gov: could not connect to host
 saveyour.biz: could not connect to host
 savingrecipe.com: did not receive HSTS header
 savvysuit.com: did not receive HSTS header
 sawamura-rental.com: did not receive HSTS header
 say-hanabi.com: could not connect to host
 sayhanabi.com: could not connect to host
 sazima.ru: did not receive HSTS header
-sbanken.no: did not receive HSTS header
 sbobetfun.com: did not receive HSTS header
 sbox-archives.com: could not connect to host
 sby.de: did not receive HSTS header
 sc4le.com: could not connect to host
 scala.click: did not receive HSTS header
 scannabi.com: could not connect to host
 schachburg.de: did not receive HSTS header
 schadegarant.net: could not connect to host
@@ -8382,17 +8410,17 @@ scrambler.in: could not connect to host
 scrapings.net: could not connect to host
 screencaster.io: did not receive HSTS header
 screenresolution.space: could not connect to host
 screensaversplanet.com: did not receive HSTS header
 scribbleserver.com: could not connect to host
 scribe.systems: could not connect to host
 scrion.com: could not connect to host
 script.google.com: did not receive HSTS header (error ignored - included regardless)
-scriptenforcer.net: could not connect to host
+scriptenforcer.net: did not receive HSTS header
 scriptict.nl: could not connect to host
 scrollstory.com: did not receive HSTS header
 sdhmanagementgroup.com: could not connect to host
 sdia.ru: could not connect to host
 sdmoscow.ru: could not connect to host
 sdrobs.com: did not receive HSTS header
 sdsl-speedtest.de: could not connect to host
 se7ensins.com: did not receive HSTS header
@@ -8483,16 +8511,17 @@ serenitycreams.com: did not receive HSTS
 serfdom.io: did not receive HSTS header
 serized.pw: could not connect to host
 serverangels.co.uk: did not receive HSTS header
 servercode.ca: did not receive HSTS header
 serverdensity.io: did not receive HSTS header
 servergno.me: did not receive HSTS header
 servermonkey.nl: could not connect to host
 servicevie.com: did not receive HSTS header
+servpanel.de: did not receive HSTS header
 servu.de: did not receive HSTS header
 seryo.moe: could not connect to host
 seryo.net: could not connect to host
 sessionslogning.dk: could not connect to host
 setphaserstostun.org: could not connect to host
 setuid.de: could not connect to host
 setuid.io: did not receive HSTS header
 seyahatsagliksigortalari.com: could not connect to host
@@ -8527,16 +8556,17 @@ shanesage.com: could not connect to host
 shaobin.wang: could not connect to host
 shapesedinburgh.co.uk: did not receive HSTS header
 shardsoft.com: could not connect to host
 shareimg.xyz: could not connect to host
 sharejoy.cn: did not receive HSTS header
 sharekey.com: did not receive HSTS header
 sharepass.pw: could not connect to host
 sharepic.xyz: could not connect to host
+sharevari.com: did not receive HSTS header
 sharezen.de: could not connect to host
 sharingcode.com: did not receive HSTS header
 shauncrowley.co.uk: could not connect to host
 shaunwheelhou.se: could not connect to host
 shavegazette.com: did not receive HSTS header
 shawnbsmith.me: did not receive HSTS header
 shawnh.net: could not connect to host
 shellsec.pw: did not receive HSTS header
@@ -8767,16 +8797,17 @@ sorensen-online.com: could not connect t
 sosaka.ml: could not connect to host
 sosiolog.com: did not receive HSTS header
 sotor.de: did not receive HSTS header
 soucorneteiro.com.br: could not connect to host
 soulfulglamour.uk: could not connect to host
 soundforsound.co.uk: did not receive HSTS header
 sourcelair.com: did not receive HSTS header
 sourcitec.com: did not receive HSTS header
+southcoastkitesurf.co.uk: did not receive HSTS header
 southcoastswords.com: did not receive HSTS header
 southernjamusa.com: did not receive HSTS header
 southgale.condos: could not connect to host
 southside-crew.club: could not connect to host
 southworcestershiregpservices.co.uk: could not connect to host
 souvik.me: did not receive HSTS header
 souyar.de: could not connect to host
 souyar.net: could not connect to host
@@ -8899,16 +8930,17 @@ steelbea.ms: could not connect to host
 steem.io: did not receive HSTS header
 stefanweiser.de: did not receive HSTS header
 stepbystep3d.com: did not receive HSTS header
 steph-autoecole.ch: did not receive HSTS header
 stephanierxo.com: did not receive HSTS header
 stephanos.me: could not connect to host
 stephenandburns.com: did not receive HSTS header
 stevechekblain.win: could not connect to host
+stevensheffey.me: did not receive HSTS header
 stevensononthe.net: did not receive HSTS header
 stevenz.net: did not receive HSTS header
 stewartremodelingadvantage.com: could not connect to host
 sticklerjs.org: could not connect to host
 stig.io: did not receive HSTS header
 stigroom.com: could not connect to host
 stillblackhat.id: could not connect to host
 stinkytrashhound.com: could not connect to host
@@ -8921,16 +8953,17 @@ stmbgr.com: could not connect to host
 stn.me.uk: did not receive HSTS header
 stockseyeserum.com: could not connect to host
 stocktrade.de: could not connect to host
 stoffe-monster.de: did not receive HSTS header
 stoick.me: could not connect to host
 stole-my.bike: could not connect to host
 stole-my.tv: could not connect to host
 stonecutterscommunity.com: could not connect to host
+stopbreakupnow.org: did not receive HSTS header
 stopwoodfin.org: could not connect to host
 storbritannien.guide: could not connect to host
 storecove.com: did not receive HSTS header
 storeden.com: did not receive HSTS header
 storefrontify.com: did not receive HSTS header
 storiesofhealth.org: did not receive HSTS header
 storillo.com: did not receive HSTS header
 stormhub.org: could not connect to host
@@ -8968,26 +9001,27 @@ stylenda.com: could not connect to host
 subbing.work: could not connect to host
 subdimension.org: did not receive HSTS header
 subeesu.com: could not connect to host
 subhacker.net: did not receive HSTS header
 subsys.no: did not receive HSTS header
 subtitle.rip: could not connect to host
 subwayz.de: did not receive HSTS header
 sudo.li: did not receive HSTS header
-sudokian.io: did not receive HSTS header
+sudokian.io: could not connect to host
 sugarsweetorsour.com: did not receive HSTS header
 suian.or.jp: max-age too low: 86400
 suite73.org: could not connect to host
 summitbankofkc.com: did not receive HSTS header
 sumoatm.com: did not receive HSTS header
 sumoscout.de: could not connect to host
 sun-wellness-online.com.vn: did not receive HSTS header
 sunboxstore.jp: did not receive HSTS header
 suncountrymarine.com: did not receive HSTS header
+sunflyer.cn: did not receive HSTS header
 sungo.wtf: did not receive HSTS header
 sunlandsg.vn: did not receive HSTS header
 sunnyfruit.ru: could not connect to host
 sunshinepress.org: could not connect to host
 sunyanzi.tk: could not connect to host
 suos.io: could not connect to host
 supcro.com: could not connect to host
 super-erotica.ru: could not connect to host
@@ -9012,16 +9046,17 @@ superwally.org: could not connect to hos
 supes.io: did not receive HSTS header
 support4server.de: did not receive HSTS header
 suprlink.net: could not connect to host
 supweb.ovh: did not receive HSTS header
 surasak.xyz: could not connect to host
 surfeasy.com: did not receive HSTS header
 surfone-leucate.com: did not receive HSTS header
 survivalistplanet.com: could not connect to host
+sushi101tempe.com: did not receive HSTS header
 sussexwebdesigns.info: could not connect to host
 sustainability.gov: did not receive HSTS header
 suzukikenichi.com: did not receive HSTS header
 svatba-frantovi.cz: could not connect to host
 svenluijten.com: did not receive HSTS header
 svenskacasino.com: did not receive HSTS header
 svenskaservern.se: could not connect to host
 svetjakonadlani.cz: did not receive HSTS header
@@ -9157,22 +9192,23 @@ techfactslive.com: did not receive HSTS 
 techhipster.net: could not connect to host
 techhub.ml: could not connect to host
 techllage.com: could not connect to host
 techloaner.com: could not connect to host
 techmasters.andover.edu: could not connect to host
 techmatehq.com: could not connect to host
 technogroup.cz: did not receive HSTS header
 technosavvyport.com: did not receive HSTS header
-technotonic.com.au: could not connect to host
+technotonic.com.au: did not receive HSTS header
 techpointed.com: could not connect to host
 techproud.com: did not receive HSTS header
 techreview.link: could not connect to host
 techtoy.store: did not receive HSTS header
 techtraveller.com.au: did not receive HSTS header
+techview.link: did not receive HSTS header
 tecnimotos.com: did not receive HSTS header
 tecnogaming.com: did not receive HSTS header
 tecture.de: did not receive HSTS header
 tedovo.com: did not receive HSTS header
 tedxkmitl.com: could not connect to host
 tefl.io: could not connect to host
 tegelsensanitaironline.nl: did not receive HSTS header
 tehotuotanto.net: did not receive HSTS header
@@ -9232,16 +9268,17 @@ the-construct.com: could not connect to 
 the-delta.net.eu.org: could not connect to host
 the-sky-of-valkyries.com: could not connect to host
 the.ie: could not connect to host
 theamateurs.net: did not receive HSTS header
 theamp.com: did not receive HSTS header
 theater.cf: could not connect to host
 theavenuegallery.com: did not receive HSTS header
 thebasementguys.com: could not connect to host
+thebeautifulmusic.net: did not receive HSTS header
 thebeginningisnye.com: could not connect to host
 theberkshirescompany.com: could not connect to host
 thebigfail.net: could not connect to host
 thebrightons.co.uk: did not receive HSTS header
 thebrightons.uk: could not connect to host
 thebrotherswarde.com: could not connect to host
 thecapitalbank.com: did not receive HSTS header
 thecharlestonwaldorf.com: did not receive HSTS header
@@ -9360,17 +9397,17 @@ tightlineproductions.com: did not receiv
 tikutiku.pl: could not connect to host
 tildebot.com: could not connect to host
 tilient.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 119"  data: no]
 tilikum.io: did not receive HSTS header
 tilkah.com.au: did not receive HSTS header
 tillcraft.com: could not connect to host
 timbeilby.com: could not connect to host
 timbuktutimber.com: did not receive HSTS header
-timcamara.com: did not receive HSTS header
+timcamara.com: could not connect to host
 time-river.xyz: could not connect to host
 timeatlas.com: did not