Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 25 Nov 2016 16:14:48 +0100
changeset 324316 40fd20c7aed22abc0a700dee63682fc1a41f0c6b
parent 324315 a7966a6adb3d61a2c2b495391f08f49ae035a645 (current diff)
parent 324295 b982373cb0e953976fd45f342910d1d1ea123fbb (diff)
child 324317 8144961dead7492bdbfc6e7dde081e555d13ac98
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
milestone53.0a1
Merge mozilla-central to mozilla-inbound
testing/marionette/harness/marionette/runner/httpd.py
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,6 +1,16 @@
 # Checks run by clang-tidy over Mozilla code.
 
 # The following checks are currently enabled:
-# * misc-use-override
-Checks:          '-*,misc-use-override'
+# * modernize-raw-string-literal -
+#     Replace string literals containing escaped characters with raw string literals
+# * modernize-use-bool-literals
+#     Replace integer literals which are cast to bool
+# * modernize-loop-convert
+#     Converts for(...; ...; ...) loops to use the new range-based loops in C++11
+# * modernize-use-default
+#     Replace default bodies of special member functions with = default;
+# * modernize-use-override
+#     Use C++11's override and remove virtual where applicable
 
+Checks:          '-*, modernize-raw-string-literal, modernize-use-bool-literals, modernize-loop-convert, modernize-use-default, modernize-use-override'
+
--- a/.eslintignore
+++ b/.eslintignore
@@ -113,18 +113,22 @@ devtools/server/actors/**
 !devtools/server/actors/inspector.js
 !devtools/server/actors/highlighters/css-grid.js
 !devtools/server/actors/highlighters/eye-dropper.js
 !devtools/server/actors/layout.js
 !devtools/server/actors/string.js
 !devtools/server/actors/styles.js
 !devtools/server/actors/webbrowser.js
 !devtools/server/actors/webextension.js
+!devtools/server/actors/webextension-inspected-window.js
 devtools/server/performance/**
-devtools/server/tests/**
+devtools/server/tests/browser/**
+!devtools/server/tests/browser/browser_webextension_inspected_window.js
+devtools/server/tests/mochitest/**
+devtools/server/tests/unit/**
 devtools/shared/*.js
 !devtools/shared/async-storage.js
 !devtools/shared/async-utils.js
 !devtools/shared/defer.js
 !devtools/shared/event-emitter.js
 !devtools/shared/indentation.js
 !devtools/shared/loader-plugin-raw.jsm
 !devtools/shared/task.js
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<blocklist lastupdate="1479994717581" xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist lastupdate="1480081945919" xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
     <emItem blockID="i545" id="superlrcs@svenyor.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i167" id="{b64982b1-d112-42b5-b1e4-d3867c4533f8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5626,17 +5626,17 @@ function middleMousePaste(event) {
   });
 
   event.stopPropagation();
 }
 
 function stripUnsafeProtocolOnPaste(pasteData) {
   // Don't allow pasting javascript URIs since we don't support
   // LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL for those.
-  return pasteData.replace(/^(?:\s*javascript:)+/i, "");
+  return pasteData.replace(/\r?\n/g, "").replace(/^(?:\s*javascript:)+/i, "");
 }
 
 // handleDroppedLink has the following 2 overloads:
 //   handleDroppedLink(event, url, name)
 //   handleDroppedLink(event, links)
 function handleDroppedLink(event, urlOrLinks, name)
 {
   let links;
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -696,48 +696,61 @@ file, You can obtain one at http://mozil
       </method>
 
       <method name="_hideURLTooltip">
         <body><![CDATA[
           this.inputField.removeAttribute("tooltiptext");
         ]]></body>
       </method>
 
+      <method name="_getDroppableLink">
+        <parameter name="aEvent"/>
+        <body><![CDATA[
+          let links = browserDragAndDrop.dropLinks(aEvent);
+          // The URL bar automatically handles inputs with newline characters,
+          // so we can get away with treating text/x-moz-url flavours as text/plain.
+          if (links.length > 0 && links[0].url) {
+            aEvent.preventDefault();
+            let url = links[0].url;
+            let strippedURL = stripUnsafeProtocolOnPaste(url);
+            if (strippedURL != url) {
+              aEvent.stopImmediatePropagation();
+              return null;
+            }
+            try {
+              urlSecurityCheck(url,
+                               gBrowser.contentPrincipal,
+                               Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
+            } catch (ex) {
+              return null;
+            }
+            return url;
+          }
+          return null;
+        ]]></body>
+      </method>
+
       <method name="onDragOver">
         <parameter name="aEvent"/>
-        <body>
-          var types = aEvent.dataTransfer.types;
-          if (types.includes("application/x-moz-file") ||
-              types.includes("text/x-moz-url") ||
-              types.includes("text/uri-list") ||
-              types.includes("text/unicode"))
-            aEvent.preventDefault();
-        </body>
+        <body><![CDATA[
+          // We don't need the link here, so we ignore the return value.
+          if (!this._getDroppableLink(aEvent)) {
+            aEvent.dataTransfer.dropEffect = "none";
+          }
+        ]]></body>
       </method>
 
       <method name="onDrop">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          let links = browserDragAndDrop.dropLinks(aEvent);
-
-          // The URL bar automatically handles inputs with newline characters,
-          // so we can get away with treating text/x-moz-url flavours as text/plain.
-          if (links.length > 0 && links[0].url) {
-            let url = links[0].url;
-            aEvent.preventDefault();
+          let url = this._getDroppableLink(aEvent);
+          if (url) {
             this.value = url;
             SetPageProxyState("invalid");
             this.focus();
-            try {
-              urlSecurityCheck(url,
-                               gBrowser.contentPrincipal,
-                               Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
-            } catch (ex) {
-              return;
-            }
             this.handleCommand();
           }
         ]]></body>
       </method>
 
       <method name="_getSelectedValueForClipboard">
         <body><![CDATA[
           // Grab the actual input field's value, not our value, which could include moz-action:
@@ -919,17 +932,17 @@ file, You can obtain one at http://mozil
               }
               let oldEnd = oldValue.substring(this.inputField.selectionEnd);
 
               let pasteData = stripUnsafeProtocolOnPaste(originalPasteData);
               if (originalPasteData != pasteData) {
                 // Unfortunately we're not allowed to set the bits being pasted
                 // so cancel this event:
                 aEvent.preventDefault();
-                aEvent.stopPropagation();
+                aEvent.stopImmediatePropagation();
 
                 this.inputField.value = oldStart + pasteData + oldEnd;
                 // Fix up cursor/selection:
                 let newCursorPos = oldStart.length + pasteData.length;
                 this.inputField.selectionStart = newCursorPos;
                 this.inputField.selectionEnd = newCursorPos;
               }
               break;
--- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js
+++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js
@@ -47,19 +47,23 @@ stubPreparedMessages.set("asdf()", new C
 	"timeStamp": 1479159921377,
 	"type": "result",
 	"level": "error",
 	"messageText": "ReferenceError: asdf is not defined",
 	"parameters": {
 		"type": "undefined"
 	},
 	"repeat": 1,
-	"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1479159921377,\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null}",
+	"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1479159921377,\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":1},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null}",
 	"stacktrace": null,
-	"frame": null,
+	"frame": {
+		"source": "debugger eval code",
+		"line": 1,
+		"column": 1
+	},
 	"groupId": null,
 	"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
 	"userProvidedStyles": null
 }));
 
 stubPreparedMessages.set("1 + @", new ConsoleMessage({
 	"id": "1",
 	"allowRepeating": true,
@@ -67,19 +71,23 @@ stubPreparedMessages.set("1 + @", new Co
 	"timeStamp": 1479159921399,
 	"type": "result",
 	"level": "error",
 	"messageText": "SyntaxError: illegal character",
 	"parameters": {
 		"type": "undefined"
 	},
 	"repeat": 1,
-	"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1479159921399,\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"userProvidedStyles\":null}",
+	"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"timeStamp\":1479159921399,\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":4},\"groupId\":null,\"userProvidedStyles\":null}",
 	"stacktrace": null,
-	"frame": null,
+	"frame": {
+		"source": "debugger eval code",
+		"line": 1,
+		"column": 4
+	},
 	"groupId": null,
 	"userProvidedStyles": null
 }));
 
 
 stubPackets.set("new Date(0)", {
 	"from": "server1.conn0.child1/consoleActor2",
 	"input": "new Date(0)",
@@ -123,17 +131,21 @@ stubPackets.set("asdf()", {
 			"stack": "@debugger eval code:1:1\n",
 			"fileName": "debugger eval code",
 			"lineNumber": 1,
 			"columnNumber": 1
 		}
 	},
 	"exceptionMessage": "ReferenceError: asdf is not defined",
 	"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
-	"frame": null,
+	"frame": {
+		"source": "debugger eval code",
+		"line": 1,
+		"column": 1
+	},
 	"helperResult": null
 });
 
 stubPackets.set("1 + @", {
 	"from": "server1.conn0.child1/consoleActor2",
 	"input": "1 + @",
 	"result": {
 		"type": "undefined"
@@ -153,17 +165,21 @@ stubPackets.set("1 + @", {
 			"message": "illegal character",
 			"stack": "",
 			"fileName": "debugger eval code",
 			"lineNumber": 1,
 			"columnNumber": 4
 		}
 	},
 	"exceptionMessage": "SyntaxError: illegal character",
-	"frame": null,
+	"frame": {
+		"source": "debugger eval code",
+		"line": 1,
+		"column": 4
+	},
 	"helperResult": null
 });
 
 
 module.exports = {
   stubPreparedMessages,
   stubPackets,
 }
\ No newline at end of file
--- a/devtools/client/webconsole/test/browser_console_netlogging.js
+++ b/devtools/client/webconsole/test/browser_console_netlogging.js
@@ -18,19 +18,18 @@ add_task(function* () {
 
   const hud = yield loadPageAndGetHud(TEST_NETWORK_REQUEST_URI,
                                       "browserConsole");
   let request = yield finishedRequest;
 
   ok(request, "Page load was logged");
 
   let client = hud.ui.webConsoleClient;
-  let args = [request.actor];
-  const postData = yield getPacket(client, "getRequestPostData", args);
-  const responseContent = yield getPacket(client, "getResponseContent", args);
+  const postData = yield client.getRequestPostData(request.actor);
+  const responseContent = yield client.getResponseContent(request.actor);
 
   is(request.request.url, TEST_NETWORK_REQUEST_URI,
     "Logged network entry is page load");
   is(request.request.method, "GET", "Method is correct");
   ok(!postData.postData.text, "No request body was stored");
   ok(postData.postDataDiscarded, "Request body was discarded");
   ok(!responseContent.content.text, "No response body was stored");
   ok(responseContent.contentDiscarded || request.fromCache,
--- a/devtools/client/webconsole/test/browser_webconsole_netlogging.js
+++ b/devtools/client/webconsole/test/browser_webconsole_netlogging.js
@@ -34,19 +34,18 @@ add_task(function* testPageLoad() {
 
   let finishedRequest = waitForFinishedRequest(PAGE_REQUEST_PREDICATE);
   let hud = yield loadPageAndGetHud(TEST_NETWORK_REQUEST_URI);
   let request = yield finishedRequest;
 
   ok(request, "Page load was logged");
 
   let client = hud.ui.webConsoleClient;
-  let args = [request.actor];
-  const postData = yield getPacket(client, "getRequestPostData", args);
-  const responseContent = yield getPacket(client, "getResponseContent", args);
+  const postData = yield client.getRequestPostData(request.actor);
+  const responseContent = yield client.getResponseContent(request.actor);
 
   is(request.request.url, TEST_NETWORK_REQUEST_URI,
     "Logged network entry is page load");
   is(request.request.method, "GET", "Method is correct");
   ok(!postData.postData.text, "No request body was stored");
   ok(!postData.postDataDiscarded,
     "Request body was not discarded");
   is(responseContent.content.text.indexOf("<!DOCTYPE HTML>"), 0,
@@ -60,19 +59,18 @@ add_task(function* testXhrGet() {
 
   let finishedRequest = waitForFinishedRequest(TEST_DATA_REQUEST_PREDICATE);
   content.wrappedJSObject.testXhrGet();
   let request = yield finishedRequest;
 
   ok(request, "testXhrGet() was logged");
 
   let client = hud.ui.webConsoleClient;
-  let args = [request.actor];
-  const postData = yield getPacket(client, "getRequestPostData", args);
-  const responseContent = yield getPacket(client, "getResponseContent", args);
+  const postData = yield client.getRequestPostData(request.actor);
+  const responseContent = yield client.getResponseContent(request.actor);
 
   is(request.request.method, "GET", "Method is correct");
   ok(!postData.postData.text, "No request body was sent");
   ok(!postData.postDataDiscarded,
     "Request body was not discarded");
   is(responseContent.content.text, TEST_DATA_JSON_CONTENT,
     "Response is correct");
 
@@ -84,19 +82,18 @@ add_task(function* testXhrPost() {
 
   let finishedRequest = waitForFinishedRequest(TEST_DATA_REQUEST_PREDICATE);
   content.wrappedJSObject.testXhrPost();
   let request = yield finishedRequest;
 
   ok(request, "testXhrPost() was logged");
 
   let client = hud.ui.webConsoleClient;
-  let args = [request.actor];
-  const postData = yield getPacket(client, "getRequestPostData", args);
-  const responseContent = yield getPacket(client, "getResponseContent", args);
+  const postData = yield client.getRequestPostData(request.actor);
+  const responseContent = yield client.getResponseContent(request.actor);
 
   is(request.request.method, "POST", "Method is correct");
   is(postData.postData.text, "Hello world!", "Request body was logged");
   is(responseContent.content.text, TEST_DATA_JSON_CONTENT,
     "Response is correct");
 
   yield closeTabAndToolbox();
 });
@@ -115,19 +112,18 @@ add_task(function* testFormSubmission() 
     let form = content.document.querySelector("form");
     form.submit();
   }`);
   let request = yield finishedRequest;
 
   ok(request, "testFormSubmission() was logged");
 
   let client = hud.ui.webConsoleClient;
-  let args = [request.actor];
-  const postData = yield getPacket(client, "getRequestPostData", args);
-  const responseContent = yield getPacket(client, "getResponseContent", args);
+  const postData = yield client.getRequestPostData(request.actor);
+  const responseContent = yield client.getResponseContent(request.actor);
 
   is(request.request.method, "POST", "Method is correct");
   isnot(postData.postData.text
     .indexOf("Content-Type: application/x-www-form-urlencoded"), -1,
     "Content-Type is correct");
   isnot(postData.postData.text
     .indexOf("Content-Length: 20"), -1, "Content-length is correct");
   isnot(postData.postData.text
--- a/devtools/client/webconsole/test/head.js
+++ b/devtools/client/webconsole/test/head.js
@@ -1786,31 +1786,16 @@ function checkLinkToInspector(hasLinkToI
 }
 
 function getSourceActor(sources, URL) {
   let item = sources.getItemForAttachment(a => a.source.url === URL);
   return item && item.value;
 }
 
 /**
- * Make a request against an actor and resolve with the packet.
- * @param object client
- *   The client to use when making the request.
- * @param function requestType
- *   The client request function to run.
- * @param array args
- *   The arguments to pass into the function.
- */
-function getPacket(client, requestType, args) {
-  return new Promise(resolve => {
-    client[requestType](...args, packet => resolve(packet));
-  });
-}
-
-/**
  * Verify that clicking on a link from a popup notification message tries to
  * open the expected URL.
  */
 function simulateMessageLinkClick(element, expectedLink) {
   let deferred = promise.defer();
 
   // Invoke the click event and check if a new tab would
   // open to the correct page.
--- a/devtools/server/actors/moz.build
+++ b/devtools/server/actors/moz.build
@@ -58,12 +58,13 @@ DevToolsModules(
     'string.js',
     'styleeditor.js',
     'styles.js',
     'stylesheets.js',
     'timeline.js',
     'webaudio.js',
     'webbrowser.js',
     'webconsole.js',
+    'webextension-inspected-window.js',
     'webextension.js',
     'webgl.js',
     'worker.js',
 )
new file mode 100644
--- /dev/null
+++ b/devtools/server/actors/webextension-inspected-window.js
@@ -0,0 +1,469 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const protocol = require("devtools/shared/protocol");
+
+const {Ci, Cu, Cr} = require("chrome");
+
+const Services = require("Services");
+
+const {
+  XPCOMUtils,
+} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
+
+const {
+  webExtensionInspectedWindowSpec,
+} = require("devtools/shared/specs/webextension-inspected-window");
+
+function CustomizedReload(params) {
+  this.docShell = params.tabActor.window
+                        .QueryInterface(Ci.nsIInterfaceRequestor)
+                        .getInterface(Ci.nsIDocShell);
+  this.docShell.QueryInterface(Ci.nsIWebProgress);
+
+  this.inspectedWindowEval = params.inspectedWindowEval;
+  this.callerInfo = params.callerInfo;
+
+  this.ignoreCache = params.ignoreCache;
+  this.injectedScript = params.injectedScript;
+  this.userAgent = params.userAgent;
+
+  this.customizedReloadWindows = new WeakSet();
+}
+
+CustomizedReload.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+                                         Ci.nsISupportsWeakReference,
+                                         Ci.nsISupports]),
+  get window() {
+    return this.docShell.DOMWindow;
+  },
+
+  get webNavigation() {
+    return this.docShell
+               .QueryInterface(Ci.nsIInterfaceRequestor)
+               .getInterface(Ci.nsIWebNavigation);
+  },
+
+  start() {
+    if (!this.waitForReloadCompleted) {
+      this.waitForReloadCompleted = new Promise((resolve, reject) => {
+        this.resolveReloadCompleted = resolve;
+        this.rejectReloadCompleted = reject;
+
+        if (this.userAgent) {
+          this.docShell.customUserAgent = this.userAgent;
+        }
+
+        let reloadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
+
+        if (this.ignoreCache) {
+          reloadFlags |= Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
+        }
+
+        try {
+          if (this.injectedScript) {
+            // Listen to the newly created document elements only if there is an
+            // injectedScript to evaluate.
+            Services.obs.addObserver(this, "document-element-inserted", false);
+          }
+
+          // Watch the loading progress and clear the current CustomizedReload once the
+          // page has been reloaded (or if its reloading has been interrupted).
+          this.docShell.addProgressListener(this,
+                                            Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
+
+          this.webNavigation.reload(reloadFlags);
+        } catch (err) {
+          // Cancel the injected script listener if the reload fails
+          // (which will also report the error by rejecting the promise).
+          this.stop(err);
+        }
+      });
+    }
+
+    return this.waitForReloadCompleted;
+  },
+
+  observe(subject, topic, data) {
+    if (topic !== "document-element-inserted") {
+      return;
+    }
+
+    const document = subject;
+    const window = document && document.defaultView;
+
+    // Filter out non interesting documents.
+    if (!document || !document.location || !window) {
+      return;
+    }
+
+    let subjectDocShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIWebNavigation)
+                                .QueryInterface(Ci.nsIDocShell);
+
+    // Keep track of the set of window objects where we are going to inject
+    // the injectedScript: the top level window and all its descendant
+    // that are still of type content (filtering out loaded XUL pages, if any).
+    if (window == this.window) {
+      this.customizedReloadWindows.add(window);
+    } else if (subjectDocShell.sameTypeParent) {
+      let parentWindow = subjectDocShell.sameTypeParent
+                                        .QueryInterface(Ci.nsIInterfaceRequestor)
+                                        .getInterface(Ci.nsIDOMWindow);
+      if (parentWindow && this.customizedReloadWindows.has(parentWindow)) {
+        this.customizedReloadWindows.add(window);
+      }
+    }
+
+    if (this.customizedReloadWindows.has(window)) {
+      const {
+        apiErrorResult
+      } = this.inspectedWindowEval(this.callerInfo, this.injectedScript, {}, window);
+
+      // Log only apiErrorResult, because no one is waiting for the
+      // injectedScript result, and any exception is going to be logged
+      // in the inspectedWindow webconsole.
+      if (apiErrorResult) {
+        console.error(
+          "Unexpected Error in injectedScript during inspectedWindow.reload for",
+          `${this.callerInfo.url}:${this.callerInfo.lineNumber}`,
+          apiErrorResult
+        );
+      }
+    }
+  },
+
+  onStateChange(webProgress, request, state, status) {
+    if (webProgress.DOMWindow !== this.window) {
+      return;
+    }
+
+    if (state & Ci.nsIWebProgressListener.STATE_STOP) {
+      if (status == Cr.NS_BINDING_ABORTED) {
+        // The customized reload has been interrupted and we can clear
+        // the CustomizedReload and reject the promise.
+        const url = this.window.location.href;
+        this.stop(new Error(
+          `devtools.inspectedWindow.reload on ${url} has been interrupted`
+        ));
+      } else {
+        // Once the top level frame has been loaded, we can clear the customized reload
+        // and resolve the promise.
+        this.stop();
+      }
+    }
+  },
+
+  stop(error) {
+    if (this.stopped) {
+      return;
+    }
+
+    this.docShell.removeProgressListener(this);
+
+    if (this.injectedScript) {
+      Services.obs.removeObserver(this, "document-element-inserted", false);
+    }
+
+    // Reset the customized user agent.
+    if (this.userAgent && this.docShell.customUserAgent == this.userAgent) {
+      this.docShell.customUserAgent = null;
+    }
+
+    if (error) {
+      this.rejectReloadCompleted(error);
+    } else {
+      this.resolveReloadCompleted();
+    }
+
+    this.stopped = true;
+  }
+};
+
+var WebExtensionInspectedWindowActor = protocol.ActorClassWithSpec(
+  webExtensionInspectedWindowSpec,
+  {
+    /**
+     * Created the WebExtension InspectedWindow actor
+     */
+    initialize(conn, tabActor) {
+      protocol.Actor.prototype.initialize.call(this, conn);
+      this.tabActor = tabActor;
+    },
+
+    destroy(conn) {
+      protocol.Actor.prototype.destroy.call(this, conn);
+      if (this.customizedReload) {
+        this.customizedReload.stop(
+          new Error("WebExtensionInspectedWindowActor destroyed")
+        );
+        delete this.customizedReload;
+      }
+
+      if (this._dbg) {
+        this._dbg.enabled = false;
+        delete this._dbg;
+      }
+    },
+
+    isSystemPrincipal(window) {
+      const principal = window.document.nodePrincipal;
+      return Services.scriptSecurityManager.isSystemPrincipal(principal);
+    },
+
+    get dbg() {
+      if (this._dbg) {
+        return this._dbg;
+      }
+
+      this._dbg = this.tabActor.makeDebugger();
+      return this._dbg;
+    },
+
+    get window() {
+      return this.tabActor.window;
+    },
+
+    get webNavigation() {
+      return this.tabActor.webNavigation;
+    },
+
+    /**
+     * Reload the target tab, optionally bypass cache, customize the userAgent and/or
+     * inject a script in targeted document or any of its sub-frame.
+     *
+     * @param {webExtensionCallerInfo} callerInfo
+     *   the addonId and the url (the addon base url or the url of the actual caller
+     *   filename and lineNumber) used to log useful debugging information in the
+     *   produced error logs and eval stack trace.
+     *
+     * @param {webExtensionReloadOptions} options
+     *   used to optionally enable the reload customizations.
+     * @param {boolean|undefined}       options.ignoreCache
+     *   enable/disable the cache bypass headers.
+     * @param {string|undefined}        options.userAgent
+     *   customize the userAgent during the page reload.
+     * @param {string|undefined}        options.injectedScript
+     *   evaluate the provided javascript code in the top level and every sub-frame
+     *   created during the page reload, before any other script in the page has been
+     *   executed.
+     */
+    reload(callerInfo, {ignoreCache, userAgent, injectedScript}) {
+      if (this.isSystemPrincipal(this.window)) {
+        console.error("Ignored inspectedWindow.reload on system principal target for " +
+                      `${callerInfo.url}:${callerInfo.lineNumber}`);
+        return {};
+      }
+
+      const delayedReload = () => {
+        // This won't work while the browser is shutting down and we don't really
+        // care.
+        if (Services.startup.shuttingDown) {
+          return;
+        }
+
+        if (injectedScript || userAgent) {
+          if (this.customizedReload) {
+            // TODO(rpl): check what chrome does, and evaluate if queue the new reload
+            // after the current one has been completed.
+            console.error(
+              "Reload already in progress. Ignored inspectedWindow.reload for " +
+              `${callerInfo.url}:${callerInfo.lineNumber}`
+            );
+            return;
+          }
+
+          try {
+            this.customizedReload = new CustomizedReload({
+              tabActor: this.tabActor,
+              inspectedWindowEval: this.eval.bind(this),
+              callerInfo, injectedScript, userAgent, ignoreCache,
+            });
+
+            this.customizedReload.start()
+                .then(() => {
+                  delete this.customizedReload;
+                })
+                .catch(err => {
+                  delete this.customizedReload;
+                  throw err;
+                });
+          } catch (err) {
+            // Cancel the customized reload (if any) on exception during the
+            // reload setup.
+            if (this.customizedReload) {
+              this.customizedReload.stop(err);
+            }
+
+            throw err;
+          }
+        } else {
+          // If there is no custom user agent and/or injected script, then
+          // we can reload the target without subscribing any observer/listener.
+          let reloadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
+          if (ignoreCache) {
+            reloadFlags |= Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
+          }
+          this.webNavigation.reload(reloadFlags);
+        }
+      };
+
+      // Execute the reload in a dispatched runnable, so that we can
+      // return the reply to the caller before the reload is actually
+      // started.
+      Services.tm.currentThread.dispatch(delayedReload, 0);
+
+      return {};
+    },
+
+    /**
+     * Evaluate the provided javascript code in a target window (that is always the
+     * tabActor window when called through RDP protocol, or the passed customTargetWindow
+     * when called directly from the CustomizedReload instances).
+     *
+     * @param {webExtensionCallerInfo} callerInfo
+     *   the addonId and the url (the addon base url or the url of the actual caller
+     *   filename and lineNumber) used to log useful debugging information in the
+     *   produced error logs and eval stack trace.
+     *
+     * @param {string} expression
+     *   the javascript code to be evaluated in the target window
+     *
+     * @param {webExtensionEvalOptions} evalOptions
+     *   used to optionally enable the eval customizations.
+     *   NOTE: none of the eval options is currently implemented, they will be already
+     *   reported as unsupported by the WebExtensions schema validation wrappers, but
+     *   an additional level of error reporting is going to be applied here, so that
+     *   if the server and the client have different ideas of which option is supported
+     *   the eval call result will contain detailed informations (in the format usually
+     *   expected for errors not raised in the evaluated javascript code).
+     *
+     * @param {DOMWindow|undefined} customTargetWindow
+     *   Used in the CustomizedReload instances to evaluate the `injectedScript`
+     *   javascript code in every sub-frame of the target window during the tab reload.
+     *   NOTE: this parameter is not part of the RDP protocol exposed by this actor, when
+     *   it is called over the remote debugging protocol the target window is always
+     *   `tabActor.window`.
+     */
+    eval(callerInfo, expression, options, customTargetWindow) {
+      const window = customTargetWindow || this.window;
+
+      if (Object.keys(options).length > 0) {
+        return {
+          exceptionInfo: {
+            isError: true,
+            code: "E_PROTOCOLERROR",
+            description: "Inspector protocol error: %s",
+            details: [
+              "The inspectedWindow.eval options are currently not supported",
+            ],
+          },
+        };
+      }
+
+      if (!window) {
+        return {
+          exceptionInfo: {
+            isError: true,
+            code: "E_PROTOCOLERROR",
+            description: "Inspector protocol error: %s",
+            details: [
+              "The target window is not defined. inspectedWindow.eval not executed.",
+            ],
+          },
+        };
+      }
+
+      if (this.isSystemPrincipal(window)) {
+        // On denied JS evaluation, report it using the same data format
+        // used in the corresponding chrome API method to report issues that are
+        // not exceptions raised in the evaluated javascript code.
+        return {
+          exceptionInfo: {
+            isError: true,
+            code: "E_PROTOCOLERROR",
+            description: "Inspector protocol error: %s",
+            details: [
+              "This target has a system principal. inspectedWindow.eval denied.",
+            ],
+          },
+        };
+      }
+
+      const dbgWindow = this.dbg.makeGlobalObjectReference(window);
+
+      let evalCalledFrom = callerInfo.url;
+      if (callerInfo.lineNumber) {
+        evalCalledFrom += `:${callerInfo.lineNumber}`;
+      }
+      // TODO(rpl): add $0 and inspect(...) bindings (Bug 1300590)
+      const result = dbgWindow.executeInGlobalWithBindings(expression, {}, {
+        url: `debugger eval called from ${evalCalledFrom} - eval code`,
+      });
+
+      let evalResult;
+
+      if (result) {
+        if ("return" in result) {
+          evalResult = result.return;
+        } else if ("yield" in result) {
+          evalResult = result.yield;
+        } else if ("throw" in result) {
+          const throwErr = result.throw;
+
+          // XXXworkers: Calling unsafeDereference() returns an object with no
+          // toString method in workers. See Bug 1215120.
+          const unsafeDereference = throwErr && (typeof throwErr === "object") &&
+            throwErr.unsafeDereference();
+          const message = unsafeDereference && unsafeDereference.toString ?
+            unsafeDereference.toString() : String(throwErr);
+          const stack = unsafeDereference && unsafeDereference.stack ?
+            unsafeDereference.stack : null;
+
+          return {
+            exceptionInfo: {
+              isException: true,
+              value: `${message}\n\t${stack}`,
+            },
+          };
+        }
+      } else {
+        // TODO(rpl): can the result of executeInGlobalWithBinding be null or
+        // undefined? (which means that it is not a return, a yield or a throw).
+        console.error("Unexpected empty inspectedWindow.eval result for",
+                      `${callerInfo.url}:${callerInfo.lineNumber}`);
+      }
+
+      if (evalResult) {
+        try {
+          if (evalResult && typeof evalResult === "object") {
+            evalResult = evalResult.unsafeDereference();
+          }
+          evalResult = JSON.parse(JSON.stringify(evalResult));
+        } catch (err) {
+          // The evaluation result cannot be sent over the RDP Protocol,
+          // report it as with the same data format used in the corresponding
+          // chrome API method.
+          return {
+            exceptionInfo: {
+              isError: true,
+              code: "E_PROTOCOLERROR",
+              description: "Inspector protocol error: %s",
+              details: [
+                String(err),
+              ],
+            },
+          };
+        }
+      }
+
+      return {value: evalResult};
+    }
+  }
+);
+
+exports.WebExtensionInspectedWindowActor = WebExtensionInspectedWindowActor;
--- a/devtools/server/main.js
+++ b/devtools/server/main.js
@@ -564,16 +564,21 @@ var DebuggerServer = {
       constructor: "PerformanceEntriesActor",
       type: { tab: true }
     });
     this.registerModule("devtools/server/actors/emulation", {
       prefix: "emulation",
       constructor: "EmulationActor",
       type: { tab: true }
     });
+    this.registerModule("devtools/server/actors/webextension-inspected-window", {
+      prefix: "webExtensionInspectedWindow",
+      constructor: "WebExtensionInspectedWindowActor",
+      type: { tab: true }
+    });
   },
 
   /**
    * Passes a set of options to the BrowserAddonActors for the given ID.
    *
    * @param id string
    *        The ID of the add-on to pass the options to
    * @param options object
--- a/devtools/server/tests/browser/browser.ini
+++ b/devtools/server/tests/browser/browser.ini
@@ -4,16 +4,17 @@ subsuite = devtools
 support-files =
   head.js
   animation.html
   doc_allocations.html
   doc_force_cc.html
   doc_force_gc.html
   doc_innerHTML.html
   doc_perf.html
+  inspectedwindow-reload-target.sjs
   navigate-first.html
   navigate-second.html
   storage-cookies-same-name.html
   storage-dynamic-windows.html
   storage-listings.html
   storage-unsecured-iframe.html
   storage-updates.html
   storage-secured-iframe.html
@@ -92,8 +93,9 @@ skip-if = e10s # Bug 1183605 - devtools/
 [browser_timeline_iframes.js]
 [browser_directorscript_actors_exports.js]
 skip-if = e10s # Bug 1183605 - devtools/server/tests/browser/ tests are still disabled in E10S
 [browser_directorscript_actors_error_events.js]
 skip-if = e10s # Bug 1183605 - devtools/server/tests/browser/ tests are still disabled in E10S
 [browser_directorscript_actors.js]
 skip-if = e10s # Bug 1183605 - devtools/server/tests/browser/ tests are still disabled in E10S
 [browser_register_actor.js]
+[browser_webextension_inspected_window.js]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/browser/browser_webextension_inspected_window.js
@@ -0,0 +1,364 @@
+/* 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/ */
+
+"use strict";
+
+const {
+  WebExtensionInspectedWindowFront
+} = require("devtools/shared/fronts/webextension-inspected-window");
+
+const TEST_RELOAD_URL = `${MAIN_DOMAIN}/inspectedwindow-reload-target.sjs`;
+
+const FAKE_CALLER_INFO = {
+  url: "moz-extension://fake-webextension-uuid/fake-caller-script.js",
+  lineNumber: 1,
+  addonId: "fake-webextension-uuid",
+};
+
+function* setup(pageUrl) {
+  yield addTab(pageUrl);
+  initDebuggerServer();
+
+  const client = new DebuggerClient(DebuggerServer.connectPipe());
+  const form = yield connectDebuggerClient(client);
+
+  const [, tabClient] = yield client.attachTab(form.actor);
+
+  const [, consoleClient] = yield client.attachConsole(form.consoleActor, []);
+
+  const inspectedWindowFront = new WebExtensionInspectedWindowFront(client, form);
+
+  return {
+    client, form,
+    tabClient, consoleClient,
+    inspectedWindowFront,
+  };
+}
+
+function* teardown({client}) {
+  yield client.close();
+  DebuggerServer.destroy();
+  gBrowser.removeCurrentTab();
+}
+
+function waitForNextTabNavigated(client) {
+  return new Promise(resolve => {
+    client.addListener("tabNavigated", function tabNavigatedListener(evt, pkt) {
+      if (pkt.state == "stop" && pkt.isFrameSwitching == false) {
+        client.removeListener("tabNavigated", tabNavigatedListener);
+        resolve();
+      }
+    });
+  });
+}
+
+function consoleEvalJS(consoleClient, jsCode) {
+  return new Promise(resolve => {
+    consoleClient.evaluateJS(jsCode, resolve);
+  });
+}
+
+// Script used as the injectedScript option in the inspectedWindow.reload tests.
+function injectedScript() {
+  if (!window.pageScriptExecutedFirst) {
+    window.addEventListener("DOMContentLoaded", function listener() {
+      window.removeEventListener("DOMContentLoaded", listener);
+      if (document.querySelector("pre")) {
+        document.querySelector("pre").textContent = "injected script executed first";
+      }
+    });
+  }
+}
+
+// Script evaluated in the target tab, to collect the results of injectedScript
+// evaluation in the inspectedWindow.reload tests.
+function collectEvalResults() {
+  let results = [];
+  let iframeDoc = document;
+
+  while (iframeDoc) {
+    if (iframeDoc.querySelector("pre")) {
+      results.push(iframeDoc.querySelector("pre").textContent);
+    }
+    const iframe = iframeDoc.querySelector("iframe");
+    iframeDoc = iframe ? iframe.contentDocument : null;
+  }
+  return JSON.stringify(results);
+}
+
+add_task(function* test_successfull_inspectedWindowEval_result() {
+  const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
+  const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window.location", {});
+
+  ok(result.value, "Got a result from inspectedWindow eval");
+  is(result.value.href, MAIN_DOMAIN,
+     "Got the expected window.location.href property value");
+  is(result.value.protocol, "http:",
+     "Got the expected window.location.protocol property value");
+
+  yield teardown({client});
+});
+
+add_task(function* test_error_inspectedWindowEval_result() {
+  const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
+  const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
+
+  ok(!result.value, "Got a null result from inspectedWindow eval");
+  ok(result.exceptionInfo.isError, "Got an API Error result from inspectedWindow eval");
+  ok(!result.exceptionInfo.isException, "An error isException is false as expected");
+  is(result.exceptionInfo.code, "E_PROTOCOLERROR",
+     "Got the expected 'code' property in the error result");
+  is(result.exceptionInfo.description, "Inspector protocol error: %s",
+     "Got the expected 'description' property in the error result");
+  is(result.exceptionInfo.details.length, 1,
+     "The 'details' array property should contains 1 element");
+  ok(result.exceptionInfo.details[0].includes("cyclic object value"),
+     "Got the expected content in the error results's details");
+
+  yield teardown({client});
+});
+
+add_task(function* test_system_principal_denied_error_inspectedWindowEval_result() {
+  const {client, inspectedWindowFront} = yield setup("about:addons");
+  const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
+
+  ok(!result.value, "Got a null result from inspectedWindow eval");
+  ok(result.exceptionInfo.isError,
+     "Got an API Error result from inspectedWindow eval on a system principal page");
+  is(result.exceptionInfo.code, "E_PROTOCOLERROR",
+     "Got the expected 'code' property in the error result");
+  is(result.exceptionInfo.description, "Inspector protocol error: %s",
+     "Got the expected 'description' property in the error result");
+  is(result.exceptionInfo.details.length, 1,
+     "The 'details' array property should contains 1 element");
+  is(result.exceptionInfo.details[0],
+     "This target has a system principal. inspectedWindow.eval denied.",
+     "Got the expected content in the error results's details");
+
+  yield teardown({client});
+});
+
+add_task(function* test_exception_inspectedWindowEval_result() {
+  const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
+  const result = yield inspectedWindowFront.eval(
+    FAKE_CALLER_INFO, "throw Error('fake eval error');", {});
+
+  ok(result.exceptionInfo.isException, "Got an exception as expected");
+  ok(!result.value, "Got an undefined eval value");
+  ok(!result.exceptionInfo.isError, "An exception should not be isError=true");
+  ok(result.exceptionInfo.value.includes("Error: fake eval error"),
+     "Got the expected exception message");
+
+  const expectedCallerInfo =
+    `called from ${FAKE_CALLER_INFO.url}:${FAKE_CALLER_INFO.lineNumber}`;
+  ok(result.exceptionInfo.value.includes(expectedCallerInfo),
+     "Got the expected caller info in the exception message");
+
+  const expectedStack = `eval code:1:7`;
+  ok(result.exceptionInfo.value.includes(expectedStack),
+     "Got the expected stack trace in the exception message");
+
+  yield teardown({client});
+});
+
+add_task(function* test_exception_inspectedWindowReload() {
+  const {
+    client, consoleClient, inspectedWindowFront,
+  } = yield setup(`${TEST_RELOAD_URL}?test=cache`);
+
+  // Test reload with bypassCache=false.
+
+  const waitForNoBypassCacheReload = waitForNextTabNavigated(client);
+  const reloadResult = yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                                         {ignoreCache: false});
+
+  ok(!reloadResult, "Got the expected undefined result from inspectedWindow reload");
+
+  yield waitForNoBypassCacheReload;
+
+  const noBypassCacheEval = yield consoleEvalJS(consoleClient,
+                                                "document.body.textContent");
+
+  is(noBypassCacheEval.result, "empty cache headers",
+     "Got the expected result with reload forceBypassCache=false");
+
+  // Test reload with bypassCache=true.
+
+  const waitForForceBypassCacheReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {ignoreCache: true});
+
+  yield waitForForceBypassCacheReload;
+
+  const forceBypassCacheEval = yield consoleEvalJS(consoleClient,
+                                                   "document.body.textContent");
+
+  is(forceBypassCacheEval.result, "no-cache:no-cache",
+     "Got the expected result with reload forceBypassCache=true");
+
+  yield teardown({client});
+});
+
+add_task(function* test_exception_inspectedWindowReload_customUserAgent() {
+  const {
+    client, consoleClient, inspectedWindowFront,
+  } = yield setup(`${TEST_RELOAD_URL}?test=user-agent`);
+
+  // Test reload with custom userAgent.
+
+  const waitForCustomUserAgentReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                    {userAgent: "Customized User Agent"});
+
+  yield waitForCustomUserAgentReload;
+
+  const customUserAgentEval = yield consoleEvalJS(consoleClient,
+                                                  "document.body.textContent");
+
+  is(customUserAgentEval.result, "Customized User Agent",
+     "Got the expected result on reload with a customized userAgent");
+
+  // Test reload with no custom userAgent.
+
+  const waitForNoCustomUserAgentReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+
+  yield waitForNoCustomUserAgentReload;
+
+  const noCustomUserAgentEval = yield consoleEvalJS(consoleClient,
+                                                    "document.body.textContent");
+
+  is(noCustomUserAgentEval.result, window.navigator.userAgent,
+     "Got the expected result with reload without a customized userAgent");
+
+  yield teardown({client});
+});
+
+add_task(function* test_exception_inspectedWindowReload_injectedScript() {
+  const {
+    client, consoleClient, inspectedWindowFront,
+  } = yield setup(`${TEST_RELOAD_URL}?test=injected-script&frames=3`);
+
+  // Test reload with an injectedScript.
+
+  const waitForInjectedScriptReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                    {injectedScript: `new ${injectedScript}`});
+  yield waitForInjectedScriptReload;
+
+  const injectedScriptEval = yield consoleEvalJS(consoleClient,
+                                                 `(${collectEvalResults})()`);
+
+  const expectedResult = (new Array(4)).fill("injected script executed first");
+
+  SimpleTest.isDeeply(JSON.parse(injectedScriptEval.result), expectedResult,
+     "Got the expected result on reload with an injected script");
+
+  // Test reload without an injectedScript.
+
+  const waitForNoInjectedScriptReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+  yield waitForNoInjectedScriptReload;
+
+  const noInjectedScriptEval = yield consoleEvalJS(consoleClient,
+                                                   `(${collectEvalResults})()`);
+
+  const newExpectedResult = (new Array(4)).fill("injected script NOT executed");
+
+  SimpleTest.isDeeply(JSON.parse(noInjectedScriptEval.result), newExpectedResult,
+                      "Got the expected result on reload with no injected script");
+
+  yield teardown({client});
+});
+
+add_task(function* test_exception_inspectedWindowReload_multiple_calls() {
+  const {
+    client, consoleClient, inspectedWindowFront,
+  } = yield setup(`${TEST_RELOAD_URL}?test=user-agent`);
+
+  // Test reload with custom userAgent three times (and then
+  // check that only the first one has affected the page reload.
+
+  const waitForCustomUserAgentReload = waitForNextTabNavigated(client);
+
+  inspectedWindowFront.reload(FAKE_CALLER_INFO, {userAgent: "Customized User Agent 1"});
+  inspectedWindowFront.reload(FAKE_CALLER_INFO, {userAgent: "Customized User Agent 2"});
+
+  yield waitForCustomUserAgentReload;
+
+  const customUserAgentEval = yield consoleEvalJS(consoleClient,
+                                                  "document.body.textContent");
+
+  is(customUserAgentEval.result, "Customized User Agent 1",
+     "Got the expected result on reload with a customized userAgent");
+
+  // Test reload with no custom userAgent.
+
+  const waitForNoCustomUserAgentReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+
+  yield waitForNoCustomUserAgentReload;
+
+  const noCustomUserAgentEval = yield consoleEvalJS(consoleClient,
+                                                    "document.body.textContent");
+
+  is(noCustomUserAgentEval.result, window.navigator.userAgent,
+     "Got the expected result with reload without a customized userAgent");
+
+  yield teardown({client});
+});
+
+add_task(function* test_exception_inspectedWindowReload_stopped() {
+  const {
+    client, consoleClient, inspectedWindowFront,
+  } = yield setup(`${TEST_RELOAD_URL}?test=injected-script&frames=3`);
+
+  // Test reload on a page that calls window.stop() immediately during the page loading
+
+  const waitForPageLoad = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.eval(FAKE_CALLER_INFO,
+                                  "window.location += '&stop=windowStop'");
+
+  info("Load a webpage that calls 'window.stop()' while is still loading");
+  yield waitForPageLoad;
+
+  info("Starting a reload with an injectedScript");
+  const waitForInjectedScriptReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO,
+                                    {injectedScript: `new ${injectedScript}`});
+  yield waitForInjectedScriptReload;
+
+  const injectedScriptEval = yield consoleEvalJS(consoleClient,
+                                                 `(${collectEvalResults})()`);
+
+  // The page should have stopped during the reload and only one injected script
+  // is expected.
+  const expectedResult = (new Array(1)).fill("injected script executed first");
+
+  SimpleTest.isDeeply(JSON.parse(injectedScriptEval.result), expectedResult,
+     "The injected script has been executed on the 'stopped' page reload");
+
+  // Reload again with no options.
+
+  info("Reload the tab again without any reload options");
+  const waitForNoInjectedScriptReload = waitForNextTabNavigated(client);
+  yield inspectedWindowFront.reload(FAKE_CALLER_INFO, {});
+  yield waitForNoInjectedScriptReload;
+
+  const noInjectedScriptEval = yield consoleEvalJS(consoleClient,
+                                                   `(${collectEvalResults})()`);
+
+  // The page should have stopped during the reload and no injected script should
+  // have been executed during this second reload (or it would mean that the previous
+  // customized reload was still pending and has wrongly affected the second reload)
+  const newExpectedResult = (new Array(1)).fill("injected script NOT executed");
+
+  SimpleTest.isDeeply(
+    JSON.parse(noInjectedScriptEval.result), newExpectedResult,
+    "No injectedScript should have been evaluated during the second reload"
+  );
+
+  yield teardown({client});
+});
+
+// TODO: check eval with $0 binding once implemented (Bug 1300590)
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/browser/inspectedwindow-reload-target.sjs
@@ -0,0 +1,75 @@
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+
+function handleRequest(request, response) {
+  let params = new URLSearchParams(request.queryString);
+
+  switch(params.get("test")) {
+    case "cache":
+      handleCacheTestRequest(request, response);
+      break;
+
+    case "user-agent":
+      handleUserAgentTestRequest(request, response);
+      break;
+
+    case "injected-script":
+      handleInjectedScriptTestRequest(request, response, params);
+      break;
+  }
+}
+
+function handleCacheTestRequest(request, response) {
+  response.setHeader("Content-Type", "text/plain; charset=UTF-8", false);
+
+  if (request.hasHeader("pragma") && request.hasHeader("cache-control")) {
+    response.write(`${request.getHeader("pragma")}:${request.getHeader("cache-control")}`);
+  } else {
+    response.write("empty cache headers");
+  }
+}
+
+function handleUserAgentTestRequest(request, response) {
+  response.setHeader("Content-Type", "text/plain; charset=UTF-8", false);
+
+  if (request.hasHeader("user-agent")) {
+    response.write(request.getHeader("user-agent"));
+  } else {
+    response.write("no user agent header");
+  }
+}
+
+function handleInjectedScriptTestRequest(request, response, params) {
+  response.setHeader("Content-Type", "text/html; charset=UTF-8", false);
+
+  const frames = parseInt(params.get("frames"));
+  let content = "";
+
+  if (frames > 0) {
+    // Output an iframe in seamless mode, so that there is an higher chance that in case
+    // of test failures we get a screenshot where the nested iframes are all visible.
+    content = `<iframe seamless src="?test=injected-script&frames=${frames - 1}"></iframe>`;
+  }
+
+  if (params.get("stop") == "windowStop") {
+    content = "<script>window.stop();</script>" + content;
+  }
+
+  response.write(`<!DOCTYPE html>
+    <html>
+      <head>
+       <meta charset="utf-8">
+       <style>
+         iframe { width: 100%; height: ${frames * 150}px; }
+       </style>
+      </head>
+      <body>
+       <h1>IFRAME ${frames}</h1>
+       <pre>injected script NOT executed</pre>
+       <script>
+         window.pageScriptExecutedFirst = true;
+       </script>
+       ${content}
+      </body>
+    </html>
+  `);
+}
\ No newline at end of file
--- a/devtools/shared/fronts/moz.build
+++ b/devtools/shared/fronts/moz.build
@@ -32,10 +32,11 @@ DevToolsModules(
     'reflow.js',
     'settings.js',
     'storage.js',
     'string.js',
     'styles.js',
     'stylesheets.js',
     'timeline.js',
     'webaudio.js',
+    'webextension-inspected-window.js',
     'webgl.js'
 )
new file mode 100644
--- /dev/null
+++ b/devtools/shared/fronts/webextension-inspected-window.js
@@ -0,0 +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/. */
+"use strict";
+
+const {
+  webExtensionInspectedWindowSpec,
+} = require("devtools/shared/specs/webextension-inspected-window");
+
+const protocol = require("devtools/shared/protocol");
+
+/**
+ * The corresponding Front object for the WebExtensionInspectedWindowActor.
+ */
+const WebExtensionInspectedWindowFront = protocol.FrontClassWithSpec(
+  webExtensionInspectedWindowSpec,
+  {
+    initialize: function (client, { webExtensionInspectedWindowActor }) {
+      protocol.Front.prototype.initialize.call(this, client, {
+        actor: webExtensionInspectedWindowActor
+      });
+      this.manage(this);
+    }
+  }
+);
+
+exports.WebExtensionInspectedWindowFront = WebExtensionInspectedWindowFront;
--- a/devtools/shared/specs/moz.build
+++ b/devtools/shared/specs/moz.build
@@ -40,11 +40,12 @@ DevToolsModules(
     'source.js',
     'storage.js',
     'string.js',
     'styleeditor.js',
     'styles.js',
     'stylesheets.js',
     'timeline.js',
     'webaudio.js',
+    'webextension-inspected-window.js',
     'webgl.js',
     'worker.js'
 )
new file mode 100644
--- /dev/null
+++ b/devtools/shared/specs/webextension-inspected-window.js
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+  Arg,
+  RetVal,
+  generateActorSpec,
+  types,
+} = require("devtools/shared/protocol");
+
+/**
+ * Sent with the eval and reload requests, used to inform the
+ * webExtensionInspectedWindowActor about the caller information
+ * to be able to evaluate code as being executed from the caller
+ * WebExtension sources, or log errors with information that can
+ * help the addon developer to more easily identify the affected
+ * lines in his own addon code.
+ */
+types.addDictType("webExtensionCallerInfo", {
+  // Information related to the line of code that has originated
+  // the request.
+  url: "string",
+  lineNumber: "nullable:number",
+
+  // The called addonId.
+  addonId: "string",
+});
+
+/**
+ * RDP type related to the inspectedWindow.eval method request.
+ */
+types.addDictType("webExtensionEvalOptions", {
+  frameURL: "nullable:string",
+  contextSecurityOrigin: "nullable:string",
+  useContentScriptContext: "nullable:boolean",
+});
+
+/**
+ * RDP type related to the inspectedWindow.eval method result errors.
+ *
+ * This type has been modelled on the same data format
+ * used in the corresponding chrome API method.
+ */
+types.addDictType("webExtensionEvalExceptionInfo", {
+  // The following properties are set if the error has not occurred
+  // in the evaluated JS code.
+  isError: "nullable:boolean",
+  code: "nullable:string",
+  description: "nullable:string",
+  details: "nullable:array:json",
+
+  // The following properties are set if the error has occurred
+  // in the evaluated JS code.
+  isException: "nullable:string",
+  value: "nullable:string",
+});
+
+/**
+ * RDP type related to the inspectedWindow.eval method result.
+ */
+types.addDictType("webExtensionEvalResult", {
+  // The following properties are set if the evaluation has been
+  // completed successfully.
+  value: "nullable:json",
+  // The following properties are set if the evalutation has been
+  // completed with errors.
+  exceptionInfo: "nullable:webExtensionEvalExceptionInfo",
+});
+
+/**
+ * RDP type related to the inspectedWindow.reload method request.
+ */
+types.addDictType("webExtensionReloadOptions", {
+  ignoreCache: "nullable:boolean",
+  userAgent: "nullable:string",
+  injectedScript: "nullable:string",
+});
+
+const webExtensionInspectedWindowSpec = generateActorSpec({
+  typeName: "webExtensionInspectedWindow",
+
+  methods: {
+    reload: {
+      request: {
+        webExtensionCallerInfo: Arg(0, "webExtensionCallerInfo"),
+        options: Arg(1, "webExtensionReloadOptions"),
+      },
+    },
+    eval: {
+      request: {
+        webExtensionCallerInfo: Arg(0, "webExtensionCallerInfo"),
+        expression: Arg(1, "string"),
+        options: Arg(2, "webExtensionEvalOptions"),
+      },
+
+      response: {
+        evalResult: RetVal("webExtensionEvalResult"),
+      },
+    },
+  },
+});
+
+exports.webExtensionInspectedWindowSpec = webExtensionInspectedWindowSpec;
--- a/devtools/shared/webconsole/client.js
+++ b/devtools/shared/webconsole/client.js
@@ -177,40 +177,44 @@ WebConsoleClient.prototype = {
    * Retrieve the cached messages from the server.
    *
    * @see this.CACHED_MESSAGES
    * @param array types
    *        The array of message types you want from the server. See
    *        this.CACHED_MESSAGES for known types.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getCachedMessages: function (types, onResponse) {
     let packet = {
       to: this._actor,
       type: "getCachedMessages",
       messageTypes: types,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Inspect the properties of an object.
    *
    * @param string actor
    *        The WebConsoleObjectActor ID to send the request to.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   inspectObjectProperties: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "inspectProperties",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Evaluate a JavaScript expression.
    *
    * @param string string
    *        The code you want to evaluate.
    * @param function onResponse
@@ -239,59 +243,71 @@ WebConsoleClient.prototype = {
    *        - url: the url to evaluate the script as. Defaults to
    *        "debugger eval code".
    *
    *        - selectedNodeActor: the NodeActor ID of the current
    *        selection in the Inspector, if such a selection
    *        exists. This is used by helper functions that can
    *        reference the currently selected node in the Inspector,
    *        like $0.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   evaluateJS: function (string, onResponse, options = {}) {
     let packet = {
       to: this._actor,
       type: "evaluateJS",
       text: string,
       bindObjectActor: options.bindObjectActor,
       frameActor: options.frameActor,
       url: options.url,
       selectedNodeActor: options.selectedNodeActor,
       selectedObjectActor: options.selectedObjectActor,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Evaluate a JavaScript expression asynchronously.
    * See evaluateJS for parameter and response information.
    */
   evaluateJSAsync: function (string, onResponse, options = {}) {
     // Pre-37 servers don't support async evaluation.
     if (!this.traits.evaluateJSAsync) {
-      this.evaluateJS(string, onResponse, options);
-      return;
+      return this.evaluateJS(string, onResponse, options);
     }
 
     let packet = {
       to: this._actor,
       type: "evaluateJSAsync",
       text: string,
       bindObjectActor: options.bindObjectActor,
       frameActor: options.frameActor,
       url: options.url,
       selectedNodeActor: options.selectedNodeActor,
       selectedObjectActor: options.selectedObjectActor,
     };
 
-    this._client.request(packet, response => {
-      // Null check this in case the client has been detached while waiting
-      // for a response.
-      if (this.pendingEvaluationResults) {
-        this.pendingEvaluationResults.set(response.resultID, onResponse);
-      }
+    return new Promise((resolve, reject) => {
+      this._client.request(packet, response => {
+        // Null check this in case the client has been detached while waiting
+        // for a response.
+        if (this.pendingEvaluationResults) {
+          this.pendingEvaluationResults.set(response.resultID, resp => {
+            if (onResponse) {
+              onResponse(resp);
+            }
+            if (resp.error) {
+              reject(resp);
+            } else {
+              resolve(resp);
+            }
+          });
+        }
+      });
     });
   },
 
   /**
    * Handler for the actors's unsolicited evaluationResult packet.
    */
   onEvaluationResult: function (notification, packet) {
     // The client on the main thread can receive notification packets from
@@ -321,254 +337,285 @@ WebConsoleClient.prototype = {
    * @param string string
    *        The code you want to autocomplete.
    * @param number cursor
    *        Cursor location inside the string. Index starts from 0.
    * @param function onResponse
    *        The function invoked when the response is received.
    * @param string frameActor
    *        The id of the frame actor that made the call.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   autocomplete: function (string, cursor, onResponse, frameActor) {
     let packet = {
       to: this._actor,
       type: "autocomplete",
       text: string,
       cursor: cursor,
       frameActor: frameActor,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Clear the cache of messages (page errors and console API calls).
+   *
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   clearMessagesCache: function () {
     let packet = {
       to: this._actor,
       type: "clearMessagesCache",
     };
-    this._client.request(packet);
+    return this._client.request(packet);
   },
 
   /**
    * Get Web Console-related preferences on the server.
    *
    * @param array preferences
    *        An array with the preferences you want to retrieve.
    * @param function [onResponse]
    *        Optional function to invoke when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getPreferences: function (preferences, onResponse) {
     let packet = {
       to: this._actor,
       type: "getPreferences",
       preferences: preferences,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Set Web Console-related preferences on the server.
    *
    * @param object preferences
    *        An object with the preferences you want to change.
    * @param function [onResponse]
    *        Optional function to invoke when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   setPreferences: function (preferences, onResponse) {
     let packet = {
       to: this._actor,
       type: "setPreferences",
       preferences: preferences,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the request headers from the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getRequestHeaders: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getRequestHeaders",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the request cookies from the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getRequestCookies: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getRequestCookies",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the request post data from the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getRequestPostData: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getRequestPostData",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the response headers from the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getResponseHeaders: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getResponseHeaders",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the response cookies from the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getResponseCookies: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getResponseCookies",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the response content from the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getResponseContent: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getResponseContent",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the timing information for the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getEventTimings: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getEventTimings",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Retrieve the security information for the given NetworkEventActor.
    *
    * @param string actor
    *        The NetworkEventActor ID.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   getSecurityInfo: function (actor, onResponse) {
     let packet = {
       to: actor,
       type: "getSecurityInfo",
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Send a HTTP request with the given data.
    *
    * @param string data
    *        The details of the HTTP request.
    * @param function onResponse
    *        The function invoked when the response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   sendHTTPRequest: function (data, onResponse) {
     let packet = {
       to: this._actor,
       type: "sendHTTPRequest",
       request: data
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Start the given Web Console listeners.
    *
    * @see this.LISTENERS
    * @param array listeners
    *        Array of listeners you want to start. See this.LISTENERS for
    *        known listeners.
    * @param function onResponse
    *        Function to invoke when the server response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   startListeners: function (listeners, onResponse) {
     let packet = {
       to: this._actor,
       type: "startListeners",
       listeners: listeners,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Stop the given Web Console listeners.
    *
    * @see this.LISTENERS
    * @param array listeners
    *        Array of listeners you want to stop. See this.LISTENERS for
    *        known listeners.
    * @param function onResponse
    *        Function to invoke when the server response is received.
+   * @return request
+   *         Request object that implements both Promise and EventEmitter interfaces
    */
   stopListeners: function (listeners, onResponse) {
     let packet = {
       to: this._actor,
       type: "stopListeners",
       listeners: listeners,
     };
-    this._client.request(packet, onResponse);
+    return this._client.request(packet, onResponse);
   },
 
   /**
    * Return an instance of LongStringClient for the given long string grip.
    *
    * @param object grip
    *        The long string grip returned by the protocol.
    * @return object
--- a/devtools/shared/webconsole/test/test_jsterm.html
+++ b/devtools/shared/webconsole/test/test_jsterm.html
@@ -19,23 +19,21 @@ SimpleTest.waitForExplicitFinish();
 let gState;
 
 let {MAX_AUTOCOMPLETE_ATTEMPTS,MAX_AUTOCOMPLETIONS} = require("devtools/shared/webconsole/js-property-provider");
 
 // This test runs all of its assertions twice - once with
 // evaluateJS and once with evaluateJSAsync.
 let evaluatingSync = true;
 function evaluateJS(input, options = {}) {
-  return new Promise((resolve, reject) => {
-    if (evaluatingSync) {
-      gState.client.evaluateJS(input, resolve, options);
-    } else {
-      gState.client.evaluateJSAsync(input, resolve, options);
-    }
-  });
+  if (evaluatingSync) {
+    return gState.client.evaluateJS(input, null, options);
+  } else {
+    return gState.client.evaluateJSAsync(input, null, options);
+  }
 }
 
 function startTest()
 {
   removeEventListener("load", startTest);
 
   attachConsoleToTab(["PageError"], onAttach);
 }
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -131,16 +131,21 @@ TextTrack::GetId(nsAString& aId) const
   if (mTrackElement) {
     mTrackElement->GetAttribute(NS_LITERAL_STRING("id"), aId);
   }
 }
 
 void
 TextTrack::AddCue(TextTrackCue& aCue)
 {
+  TextTrack* oldTextTrack = aCue.GetTrack();
+  if (oldTextTrack) {
+    ErrorResult dummy;
+    oldTextTrack->RemoveCue(aCue, dummy);
+  }
   mCueList->AddCue(aCue);
   aCue.SetTrack(this);
   if (mTextTrackList) {
     HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
     if (mediaElement && (mMode != TextTrackMode::Disabled)) {
       mediaElement->NotifyCueAdded(aCue);
     }
   }
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -807,16 +807,17 @@ skip-if = appname == "seamonkey"
 [test_playback_reactivate.html]
 [test_played.html]
 [test_preload_actions.html]
 [test_preload_attribute.html]
 [test_preload_suspend.html]
 [test_preserve_playbackrate_after_ui_play.html]
 [test_progress.html]
 [test_reactivate.html]
+skip-if = true # see bug 1319725
 [test_readyState.html]
 [test_referer.html]
 [test_replay_metadata.html]
 [test_reset_events_async.html]
 [test_reset_src.html]
 [test_video_dimensions.html]
 [test_resolution_change.html]
 tags=capturestream
--- a/media/libstagefright/binding/DecoderData.cpp
+++ b/media/libstagefright/binding/DecoderData.cpp
@@ -199,16 +199,19 @@ MP4VideoInfo::Update(const mp4parse_trac
   }
   mTrackId = track->track_id;
   mDuration = track->duration;
   mMediaTime = track->media_time;
   mDisplay.width = video->display_width;
   mDisplay.height = video->display_height;
   mImage.width = video->image_width;
   mImage.height = video->image_height;
+  if (video->extra_data.data) {
+    mExtraData->AppendElements(video->extra_data.data, video->extra_data.length);
+  }
 }
 #endif
 
 bool
 MP4VideoInfo::IsValid() const
 {
   return (mDisplay.width > 0 && mDisplay.height > 0) ||
     (mImage.width > 0 && mImage.height > 0);
--- a/media/libstagefright/binding/MP4Metadata.cpp
+++ b/media/libstagefright/binding/MP4Metadata.cpp
@@ -304,16 +304,20 @@ MP4Metadata::GetTrackInfo(mozilla::Track
       //MOZ_DIAGNOSTIC_ASSERT(audioRust->mProfile != audio->mProfile);
       //MOZ_DIAGNOSTIC_ASSERT(audioRust->mExtendedProfile != audio->mExtendedProfile);
       break;
     }
     case mozilla::TrackInfo::kVideoTrack: {
       VideoInfo *videoRust = infoRust->GetAsVideoInfo(), *video = info->GetAsVideoInfo();
       MOZ_DIAGNOSTIC_ASSERT(videoRust->mDisplay == video->mDisplay);
       MOZ_DIAGNOSTIC_ASSERT(videoRust->mImage == video->mImage);
+      MOZ_DIAGNOSTIC_ASSERT(*videoRust->mExtraData == *video->mExtraData);
+      // mCodecSpecificConfig is for video/mp4-es, not video/avc. Since video/mp4-es
+      // is supported on b2g only, it could be removed from TrackInfo.
+      MOZ_DIAGNOSTIC_ASSERT(*videoRust->mCodecSpecificConfig == *video->mCodecSpecificConfig);
       break;
     }
     default:
       break;
     }
   }
 #endif
 
--- a/media/libstagefright/binding/include/mp4parse.h
+++ b/media/libstagefright/binding/include/mp4parse.h
@@ -64,16 +64,17 @@ typedef struct mp4parse_track_audio_info
 	mp4parse_byte_data codec_specific_config;
 } mp4parse_track_audio_info;
 
 typedef struct mp4parse_track_video_info {
 	uint32_t display_width;
 	uint32_t display_height;
 	uint16_t image_width;
 	uint16_t image_height;
+	mp4parse_byte_data extra_data;
 } mp4parse_track_video_info;
 
 typedef struct mp4parse_fragment_info {
 	uint64_t fragment_duration;
 } mp4parse_fragment_info;
 
 typedef struct mp4parse_parser mp4parse_parser;
 
--- a/media/libstagefright/binding/mp4parse/src/lib.rs
+++ b/media/libstagefright/binding/mp4parse/src/lib.rs
@@ -200,22 +200,22 @@ struct SampleDescriptionBox {
 #[derive(Debug, Clone)]
 pub enum SampleEntry {
     Audio(AudioSampleEntry),
     Video(VideoSampleEntry),
     Unknown,
 }
 
 #[allow(non_camel_case_types)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Default)]
 pub struct ES_Descriptor {
     pub audio_codec: CodecType,
     pub audio_sample_rate: Option<u32>,
     pub audio_channel_count: Option<u16>,
-    pub codec_specific_config: Vec<u8>,
+    pub codec_esds: Vec<u8>,
 }
 
 #[allow(non_camel_case_types)]
 #[derive(Debug, Clone)]
 pub enum AudioCodecSpecific {
     ES_Descriptor(ES_Descriptor),
     FLACSpecificBox(FLACSpecificBox),
     OpusSpecificBox(OpusSpecificBox),
@@ -454,23 +454,23 @@ impl<'a, T: Read> BMFFBox<'a, T> {
 
 /// Read and parse a box header.
 ///
 /// Call this first to determine the type of a particular mp4 box
 /// and its length. Used internally for dispatching to specific
 /// parsers for the internal content, or to get the length to
 /// skip unknown or uninteresting boxes.
 fn read_box_header<T: ReadBytesExt>(src: &mut T) -> Result<BoxHeader> {
-    let size32 = try!(be_u32(src));
-    let name = BoxType::from(try!(be_u32(src)));
+    let size32 = be_u32(src)?;
+    let name = BoxType::from(be_u32(src)?);
     let size = match size32 {
         // valid only for top-level box and indicates it's the last box in the file.  usually mdat.
         0 => return Err(Error::Unsupported("unknown sized box")),
         1 => {
-            let size64 = try!(be_u64(src));
+            let size64 = be_u64(src)?;
             if size64 < 16 {
                 return Err(Error::InvalidData("malformed wide size"));
             }
             size64
         }
         2...7 => return Err(Error::InvalidData("malformed size")),
         _ => size32 as u64,
     };
@@ -483,33 +483,33 @@ fn read_box_header<T: ReadBytesExt>(src:
         name: name,
         size: size,
         offset: offset,
     })
 }
 
 /// Parse the extra header fields for a full box.
 fn read_fullbox_extra<T: ReadBytesExt>(src: &mut T) -> Result<(u8, u32)> {
-    let version = try!(src.read_u8());
-    let flags_a = try!(src.read_u8());
-    let flags_b = try!(src.read_u8());
-    let flags_c = try!(src.read_u8());
+    let version = src.read_u8()?;
+    let flags_a = src.read_u8()?;
+    let flags_b = src.read_u8()?;
+    let flags_c = src.read_u8()?;
     Ok((version,
         (flags_a as u32) << 16 | (flags_b as u32) << 8 | (flags_c as u32)))
 }
 
 /// Skip over the entire contents of a box.
 fn skip_box_content<T: Read>(src: &mut BMFFBox<T>) -> Result<()> {
     // Skip the contents of unknown chunks.
     let to_skip = {
         let header = src.get_header();
         log!("{:?} (skipped)", header);
         (header.size - header.offset) as usize
     };
-    assert!(to_skip == src.bytes_left());
+    assert_eq!(to_skip, src.bytes_left());
     skip(src, to_skip)
 }
 
 /// Skip over the remain data of a box.
 fn skip_box_remain<T: Read>(src: &mut BMFFBox<T>) -> Result<()> {
     let remain = {
         let header = src.get_header();
         let len = src.bytes_left();
@@ -533,17 +533,17 @@ macro_rules! check_parser_state {
 /// Metadata is accumulated in the passed-through `MediaContext` struct,
 /// which can be examined later.
 pub fn read_mp4<T: Read>(f: &mut T, context: &mut MediaContext) -> Result<()> {
     let mut found_ftyp = false;
     let mut found_moov = false;
     // TODO(kinetik): Top-level parsing should handle zero-sized boxes
     // rather than throwing an error.
     let mut iter = BoxIter::new(f);
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         // box ordering: ftyp before any variable length box (inc. moov),
         // but may not be first box in file if file signatures etc. present
         // fragmented mp4 order: ftyp, moov, pairs of moof/mdat (1-multiple), mfra
 
         // "special": uuid, wide (= 8 bytes)
         // isom: moov, mdat, free, skip, udta, ftyp, moof, mfra
         // iso2: pdin, meta
         // iso3: meco
@@ -551,25 +551,25 @@ pub fn read_mp4<T: Read>(f: &mut T, cont
         // unknown, maybe: id32
 
         // qt: pnot
 
         // possibly allow anything where all printable and/or all lowercase printable
         // "four printable characters from the ISO 8859-1 character set"
         match b.head.name {
             BoxType::FileTypeBox => {
-                let ftyp = try!(read_ftyp(&mut b));
+                let ftyp = read_ftyp(&mut b)?;
                 found_ftyp = true;
                 log!("{:?}", ftyp);
             }
             BoxType::MovieBox => {
-                try!(read_moov(&mut b, context));
+                read_moov(&mut b, context)?;
                 found_moov = true;
             }
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
         if found_moov {
             log!("found moov {}, could stop pure 'moov' parser now", if found_ftyp {
                 "and ftyp"
             } else {
                 "but no ftyp"
             });
@@ -582,146 +582,146 @@ pub fn read_mp4<T: Read>(f: &mut T, cont
     if found_moov {
         Ok(())
     } else {
         Err(Error::NoMoov)
     }
 }
 
 fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<(MovieHeaderBox, Option<MediaTimeScale>)> {
-    let mvhd = try!(read_mvhd(f));
+    let mvhd = read_mvhd(f)?;
     if mvhd.timescale == 0 {
         return Err(Error::InvalidData("zero timescale in mdhd"));
     }
     let timescale = Some(MediaTimeScale(mvhd.timescale as u64));
     Ok((mvhd, timescale))
 }
 
 fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: &mut MediaContext) -> Result<()> {
     let mut iter = f.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::MovieHeaderBox => {
-                let (mvhd, timescale) = try!(parse_mvhd(&mut b));
+                let (mvhd, timescale) = parse_mvhd(&mut b)?;
                 context.timescale = timescale;
                 log!("{:?}", mvhd);
             }
             BoxType::TrackBox => {
                 let mut track = Track::new(context.tracks.len());
-                try!(read_trak(&mut b, &mut track));
+                read_trak(&mut b, &mut track)?;
                 context.tracks.push(track);
             }
             BoxType::MovieExtendsBox => {
-                let mvex = try!(read_mvex(&mut b));
+                let mvex = read_mvex(&mut b)?;
                 log!("{:?}", mvex);
                 context.mvex = Some(mvex);
             }
             BoxType::ProtectionSystemSpecificHeaderBox => {
-                let pssh = try!(read_pssh(&mut b));
+                let pssh = read_pssh(&mut b)?;
                 log!("{:?}", pssh);
                 context.psshs.push(pssh);
             }
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
     }
     Ok(())
 }
 
 fn read_pssh<T: Read>(src: &mut BMFFBox<T>) -> Result<ProtectionSystemSpecificHeaderBox> {
     let mut box_content = Vec::with_capacity(src.head.size as usize);
-    try!(src.read_to_end(&mut box_content));
+    src.read_to_end(&mut box_content)?;
 
     let (system_id, kid, data) = {
         let pssh = &mut Cursor::new(box_content.as_slice());
 
-        let (version, _) = try!(read_fullbox_extra(pssh));
+        let (version, _) = read_fullbox_extra(pssh)?;
 
-        let system_id = try!(read_buf(pssh, 16));
+        let system_id = read_buf(pssh, 16)?;
 
         let mut kid: Vec<ByteData> = Vec::new();
         if version > 0 {
-            let count = try!(be_i32(pssh));
+            let count = be_i32(pssh)?;
             for _ in 0..count {
-                let item = try!(read_buf(pssh, 16));
+                let item = read_buf(pssh, 16)?;
                 kid.push(item);
             }
         }
 
-        let data_size = try!(be_i32(pssh)) as usize;
-        let data = try!(read_buf(pssh, data_size));
+        let data_size = be_i32(pssh)? as usize;
+        let data = read_buf(pssh, data_size)?;
 
         (system_id, kid, data)
     };
 
     let mut pssh_box = Vec::new();
-    try!(write_be_u32(&mut pssh_box, src.head.size as u32));
+    write_be_u32(&mut pssh_box, src.head.size as u32)?;
     pssh_box.append(&mut b"pssh".to_vec());
     pssh_box.append(&mut box_content);
 
     Ok(ProtectionSystemSpecificHeaderBox {
         system_id: system_id,
         kid: kid,
         data: data,
         box_content: pssh_box,
     })
 }
 
 fn read_mvex<T: Read>(src: &mut BMFFBox<T>) -> Result<MovieExtendsBox> {
     let mut iter = src.box_iter();
     let mut fragment_duration = None;
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::MovieExtendsHeaderBox => {
-                let duration = try!(read_mehd(&mut b));
+                let duration = read_mehd(&mut b)?;
                 fragment_duration = Some(duration);
             },
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         }
     }
     Ok(MovieExtendsBox {
         fragment_duration: fragment_duration,
     })
 }
 
 fn read_mehd<T: Read>(src: &mut BMFFBox<T>) -> Result<MediaScaledTime> {
-    let (version, _) = try!(read_fullbox_extra(src));
+    let (version, _) = read_fullbox_extra(src)?;
     let fragment_duration = match version {
-        1 => try!(be_u64(src)),
-        0 => try!(be_u32(src)) as u64,
+        1 => be_u64(src)?,
+        0 => be_u32(src)? as u64,
         _ => return Err(Error::InvalidData("unhandled mehd version")),
     };
     Ok(MediaScaledTime(fragment_duration))
 }
 
 fn read_trak<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
     let mut iter = f.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::TrackHeaderBox => {
-                let tkhd = try!(read_tkhd(&mut b));
+                let tkhd = read_tkhd(&mut b)?;
                 track.track_id = Some(tkhd.track_id);
                 track.tkhd = Some(tkhd.clone());
                 log!("{:?}", tkhd);
             }
-            BoxType::EditBox => try!(read_edts(&mut b, track)),
-            BoxType::MediaBox => try!(read_mdia(&mut b, track)),
-            _ => try!(skip_box_content(&mut b)),
+            BoxType::EditBox => read_edts(&mut b, track)?,
+            BoxType::MediaBox => read_mdia(&mut b, track)?,
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
     }
     Ok(())
 }
 
 fn read_edts<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
     let mut iter = f.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::EditListBox => {
-                let elst = try!(read_elst(&mut b));
+                let elst = read_elst(&mut b)?;
                 let mut empty_duration = 0;
                 let mut idx = 0;
                 if elst.edits.len() > 2 {
                     return Err(Error::Unsupported("more than two edits"));
                 }
                 if elst.edits[idx].media_time == -1 {
                     empty_duration = elst.edits[idx].segment_duration;
                     if elst.edits.len() < 2 {
@@ -732,589 +732,601 @@ fn read_edts<T: Read>(f: &mut BMFFBox<T>
                 track.empty_duration = Some(MediaScaledTime(empty_duration));
                 if elst.edits[idx].media_time < 0 {
                     return Err(Error::InvalidData("unexpected negative media time in edit"));
                 }
                 track.media_time = Some(TrackScaledTime(elst.edits[idx].media_time as u64,
                                                         track.id));
                 log!("{:?}", elst);
             }
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
     }
     Ok(())
 }
 
 fn parse_mdhd<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<(MediaHeaderBox, Option<TrackScaledTime>, Option<TrackTimeScale>)> {
-    let mdhd = try!(read_mdhd(f));
+    let mdhd = read_mdhd(f)?;
     let duration = match mdhd.duration {
         std::u64::MAX => None,
         duration => Some(TrackScaledTime(duration, track.id)),
     };
     if mdhd.timescale == 0 {
         return Err(Error::InvalidData("zero timescale in mdhd"));
     }
     let timescale = Some(TrackTimeScale(mdhd.timescale as u64, track.id));
     Ok((mdhd, duration, timescale))
 }
 
 fn read_mdia<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
     let mut iter = f.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::MediaHeaderBox => {
-                let (mdhd, duration, timescale) = try!(parse_mdhd(&mut b, track));
+                let (mdhd, duration, timescale) = parse_mdhd(&mut b, track)?;
                 track.duration = duration;
                 track.timescale = timescale;
                 log!("{:?}", mdhd);
             }
             BoxType::HandlerBox => {
-                let hdlr = try!(read_hdlr(&mut b));
+                let hdlr = read_hdlr(&mut b)?;
                 match hdlr.handler_type {
                     0x76696465 /* 'vide' */ => track.track_type = TrackType::Video,
                     0x736f756e /* 'soun' */ => track.track_type = TrackType::Audio,
                     _ => (),
                 }
                 log!("{:?}", hdlr);
             }
-            BoxType::MediaInformationBox => try!(read_minf(&mut b, track)),
-            _ => try!(skip_box_content(&mut b)),
+            BoxType::MediaInformationBox => read_minf(&mut b, track)?,
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
     }
     Ok(())
 }
 
 fn read_minf<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
     let mut iter = f.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
-            BoxType::SampleTableBox => try!(read_stbl(&mut b, track)),
-            _ => try!(skip_box_content(&mut b)),
+            BoxType::SampleTableBox => read_stbl(&mut b, track)?,
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
     }
     Ok(())
 }
 
 fn read_stbl<T: Read>(f: &mut BMFFBox<T>, track: &mut Track) -> Result<()> {
     let mut iter = f.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::SampleDescriptionBox => {
-                let stsd = try!(read_stsd(&mut b, track));
+                let stsd = read_stsd(&mut b, track)?;
                 log!("{:?}", stsd);
             }
             BoxType::TimeToSampleBox => {
-                let stts = try!(read_stts(&mut b));
+                let stts = read_stts(&mut b)?;
                 track.empty_sample_boxes.empty_stts = stts.samples.is_empty();
                 log!("{:?}", stts);
             }
             BoxType::SampleToChunkBox => {
-                let stsc = try!(read_stsc(&mut b));
+                let stsc = read_stsc(&mut b)?;
                 track.empty_sample_boxes.empty_stsc = stsc.samples.is_empty();
                 log!("{:?}", stsc);
             }
             BoxType::SampleSizeBox => {
-                let stsz = try!(read_stsz(&mut b));
+                let stsz = read_stsz(&mut b)?;
                 log!("{:?}", stsz);
             }
             BoxType::ChunkOffsetBox => {
-                let stco = try!(read_stco(&mut b));
+                let stco = read_stco(&mut b)?;
                 track.empty_sample_boxes.empty_stco = stco.offsets.is_empty();
                 log!("{:?}", stco);
             }
             BoxType::ChunkLargeOffsetBox => {
-                let co64 = try!(read_co64(&mut b));
+                let co64 = read_co64(&mut b)?;
                 log!("{:?}", co64);
             }
             BoxType::SyncSampleBox => {
-                let stss = try!(read_stss(&mut b));
+                let stss = read_stss(&mut b)?;
                 log!("{:?}", stss);
             }
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
     }
     Ok(())
 }
 
 /// Parse an ftyp box.
 fn read_ftyp<T: Read>(src: &mut BMFFBox<T>) -> Result<FileTypeBox> {
-    let major = try!(be_u32(src));
-    let minor = try!(be_u32(src));
+    let major = be_u32(src)?;
+    let minor = be_u32(src)?;
     let bytes_left = src.bytes_left();
     if bytes_left % 4 != 0 {
         return Err(Error::InvalidData("invalid ftyp size"));
     }
     // Is a brand_count of zero valid?
     let brand_count = bytes_left / 4;
     let mut brands = Vec::new();
     for _ in 0..brand_count {
-        brands.push(try!(be_u32(src)));
+        brands.push(be_u32(src)?);
     }
     Ok(FileTypeBox {
         major_brand: major,
         minor_version: minor,
         compatible_brands: brands,
     })
 }
 
 /// Parse an mvhd box.
 fn read_mvhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MovieHeaderBox> {
-    let (version, _) = try!(read_fullbox_extra(src));
+    let (version, _) = read_fullbox_extra(src)?;
     match version {
         // 64 bit creation and modification times.
         1 => {
-            try!(skip(src, 16));
+            skip(src, 16)?;
         }
         // 32 bit creation and modification times.
         0 => {
-            try!(skip(src, 8));
+            skip(src, 8)?;
         }
         _ => return Err(Error::InvalidData("unhandled mvhd version")),
     }
-    let timescale = try!(be_u32(src));
+    let timescale = be_u32(src)?;
     let duration = match version {
-        1 => try!(be_u64(src)),
+        1 => be_u64(src)?,
         0 => {
-            let d = try!(be_u32(src));
+            let d = be_u32(src)?;
             if d == std::u32::MAX {
                 std::u64::MAX
             } else {
                 d as u64
             }
         }
         _ => return Err(Error::InvalidData("unhandled mvhd version")),
     };
     // Skip remaining fields.
-    try!(skip(src, 80));
+    skip(src, 80)?;
     Ok(MovieHeaderBox {
         timescale: timescale,
         duration: duration,
     })
 }
 
 /// Parse a tkhd box.
 fn read_tkhd<T: Read>(src: &mut BMFFBox<T>) -> Result<TrackHeaderBox> {
-    let (version, flags) = try!(read_fullbox_extra(src));
+    let (version, flags) = read_fullbox_extra(src)?;
     let disabled = flags & 0x1u32 == 0 || flags & 0x2u32 == 0;
     match version {
         // 64 bit creation and modification times.
         1 => {
-            try!(skip(src, 16));
+            skip(src, 16)?;
         }
         // 32 bit creation and modification times.
         0 => {
-            try!(skip(src, 8));
+            skip(src, 8)?;
         }
         _ => return Err(Error::InvalidData("unhandled tkhd version")),
     }
-    let track_id = try!(be_u32(src));
-    try!(skip(src, 4));
+    let track_id = be_u32(src)?;
+    skip(src, 4)?;
     let duration = match version {
-        1 => try!(be_u64(src)),
-        0 => try!(be_u32(src)) as u64,
+        1 => be_u64(src)?,
+        0 => be_u32(src)? as u64,
         _ => return Err(Error::InvalidData("unhandled tkhd version")),
     };
     // Skip uninteresting fields.
-    try!(skip(src, 52));
-    let width = try!(be_u32(src));
-    let height = try!(be_u32(src));
+    skip(src, 52)?;
+    let width = be_u32(src)?;
+    let height = be_u32(src)?;
     Ok(TrackHeaderBox {
         track_id: track_id,
         disabled: disabled,
         duration: duration,
         width: width,
         height: height,
     })
 }
 
 /// Parse a elst box.
 fn read_elst<T: Read>(src: &mut BMFFBox<T>) -> Result<EditListBox> {
-    let (version, _) = try!(read_fullbox_extra(src));
-    let edit_count = try!(be_u32(src));
+    let (version, _) = read_fullbox_extra(src)?;
+    let edit_count = be_u32(src)?;
     if edit_count == 0 {
         return Err(Error::InvalidData("invalid edit count"));
     }
     let mut edits = Vec::new();
     for _ in 0..edit_count {
         let (segment_duration, media_time) = match version {
             1 => {
                 // 64 bit segment duration and media times.
-                (try!(be_u64(src)), try!(be_i64(src)))
+                (be_u64(src)?, be_i64(src)?)
             }
             0 => {
                 // 32 bit segment duration and media times.
-                (try!(be_u32(src)) as u64, try!(be_i32(src)) as i64)
+                (be_u32(src)? as u64, be_i32(src)? as i64)
             }
             _ => return Err(Error::InvalidData("unhandled elst version")),
         };
-        let media_rate_integer = try!(be_i16(src));
-        let media_rate_fraction = try!(be_i16(src));
+        let media_rate_integer = be_i16(src)?;
+        let media_rate_fraction = be_i16(src)?;
         edits.push(Edit {
             segment_duration: segment_duration,
             media_time: media_time,
             media_rate_integer: media_rate_integer,
             media_rate_fraction: media_rate_fraction,
         })
     }
 
     Ok(EditListBox {
         edits: edits,
     })
 }
 
 /// Parse a mdhd box.
 fn read_mdhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MediaHeaderBox> {
-    let (version, _) = try!(read_fullbox_extra(src));
+    let (version, _) = read_fullbox_extra(src)?;
     let (timescale, duration) = match version {
         1 => {
             // Skip 64-bit creation and modification times.
-            try!(skip(src, 16));
+            skip(src, 16)?;
 
             // 64 bit duration.
-            (try!(be_u32(src)), try!(be_u64(src)))
+            (be_u32(src)?, be_u64(src)?)
         }
         0 => {
             // Skip 32-bit creation and modification times.
-            try!(skip(src, 8));
+            skip(src, 8)?;
 
             // 32 bit duration.
-            let timescale = try!(be_u32(src));
+            let timescale = be_u32(src)?;
             let duration = {
                 // Since we convert the 32-bit duration to 64-bit by
                 // upcasting, we need to preserve the special all-1s
                 // ("unknown") case by hand.
-                let d = try!(be_u32(src));
+                let d = be_u32(src)?;
                 if d == std::u32::MAX {
                     std::u64::MAX
                 } else {
                     d as u64
                 }
             };
             (timescale, duration)
         }
         _ => return Err(Error::InvalidData("unhandled mdhd version")),
     };
 
     // Skip uninteresting fields.
-    try!(skip(src, 4));
+    skip(src, 4)?;
 
     Ok(MediaHeaderBox {
         timescale: timescale,
         duration: duration,
     })
 }
 
 /// Parse a stco box.
 fn read_stco<T: Read>(src: &mut BMFFBox<T>) -> Result<ChunkOffsetBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
-    let offset_count = try!(be_u32(src));
+    let (_, _) = read_fullbox_extra(src)?;
+    let offset_count = be_u32(src)?;
     let mut offsets = Vec::new();
     for _ in 0..offset_count {
-        offsets.push(try!(be_u32(src)) as u64);
+        offsets.push(be_u32(src)? as u64);
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(ChunkOffsetBox {
         offsets: offsets,
     })
 }
 
 /// Parse a co64 box.
 fn read_co64<T: Read>(src: &mut BMFFBox<T>) -> Result<ChunkOffsetBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
-    let offset_count = try!(be_u32(src));
+    let (_, _) = read_fullbox_extra(src)?;
+    let offset_count = be_u32(src)?;
     let mut offsets = Vec::new();
     for _ in 0..offset_count {
-        offsets.push(try!(be_u64(src)));
+        offsets.push(be_u64(src)?);
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(ChunkOffsetBox {
         offsets: offsets,
     })
 }
 
 /// Parse a stss box.
 fn read_stss<T: Read>(src: &mut BMFFBox<T>) -> Result<SyncSampleBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
-    let sample_count = try!(be_u32(src));
+    let (_, _) = read_fullbox_extra(src)?;
+    let sample_count = be_u32(src)?;
     let mut samples = Vec::new();
     for _ in 0..sample_count {
-        samples.push(try!(be_u32(src)));
+        samples.push(be_u32(src)?);
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(SyncSampleBox {
         samples: samples,
     })
 }
 
 /// Parse a stsc box.
 fn read_stsc<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleToChunkBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
-    let sample_count = try!(be_u32(src));
+    let (_, _) = read_fullbox_extra(src)?;
+    let sample_count = be_u32(src)?;
     let mut samples = Vec::new();
     for _ in 0..sample_count {
-        let first_chunk = try!(be_u32(src));
-        let samples_per_chunk = try!(be_u32(src));
-        let sample_description_index = try!(be_u32(src));
+        let first_chunk = be_u32(src)?;
+        let samples_per_chunk = be_u32(src)?;
+        let sample_description_index = be_u32(src)?;
         samples.push(SampleToChunk {
             first_chunk: first_chunk,
             samples_per_chunk: samples_per_chunk,
             sample_description_index: sample_description_index,
         });
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(SampleToChunkBox {
         samples: samples,
     })
 }
 
 /// Parse a stsz box.
 fn read_stsz<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleSizeBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
-    let sample_size = try!(be_u32(src));
-    let sample_count = try!(be_u32(src));
+    let (_, _) = read_fullbox_extra(src)?;
+    let sample_size = be_u32(src)?;
+    let sample_count = be_u32(src)?;
     let mut sample_sizes = Vec::new();
     if sample_size == 0 {
         for _ in 0..sample_count {
-            sample_sizes.push(try!(be_u32(src)));
+            sample_sizes.push(be_u32(src)?);
         }
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(SampleSizeBox {
         sample_size: sample_size,
         sample_sizes: sample_sizes,
     })
 }
 
 /// Parse a stts box.
 fn read_stts<T: Read>(src: &mut BMFFBox<T>) -> Result<TimeToSampleBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
-    let sample_count = try!(be_u32(src));
+    let (_, _) = read_fullbox_extra(src)?;
+    let sample_count = be_u32(src)?;
     let mut samples = Vec::new();
     for _ in 0..sample_count {
-        let sample_count = try!(be_u32(src));
-        let sample_delta = try!(be_u32(src));
+        let sample_count = be_u32(src)?;
+        let sample_delta = be_u32(src)?;
         samples.push(Sample {
             sample_count: sample_count,
             sample_delta: sample_delta,
         });
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(TimeToSampleBox {
         samples: samples,
     })
 }
 
 /// Parse a VPx Config Box.
 fn read_vpcc<T: Read>(src: &mut BMFFBox<T>) -> Result<VPxConfigBox> {
-    let (version, _) = try!(read_fullbox_extra(src));
+    let (version, _) = read_fullbox_extra(src)?;
     if version != 0 {
         return Err(Error::Unsupported("unknown vpcC version"));
     }
 
-    let profile = try!(src.read_u8());
-    let level = try!(src.read_u8());
+    let profile = src.read_u8()?;
+    let level = src.read_u8()?;
     let (bit_depth, color_space) = {
-        let byte = try!(src.read_u8());
+        let byte = src.read_u8()?;
         ((byte >> 4) & 0x0f, byte & 0x0f)
     };
     let (chroma_subsampling, transfer_function, video_full_range) = {
-        let byte = try!(src.read_u8());
+        let byte = src.read_u8()?;
         ((byte >> 4) & 0x0f, (byte >> 1) & 0x07, (byte & 1) == 1)
     };
 
-    let codec_init_size = try!(be_u16(src));
-    let codec_init = try!(read_buf(src, codec_init_size as usize));
+    let codec_init_size = be_u16(src)?;
+    let codec_init = read_buf(src, codec_init_size as usize)?;
 
     // TODO(rillian): validate field value ranges.
     Ok(VPxConfigBox {
         profile: profile,
         level: level,
         bit_depth: bit_depth,
         color_space: color_space,
         chroma_subsampling: chroma_subsampling,
         transfer_function: transfer_function,
         video_full_range: video_full_range,
         codec_init: codec_init,
     })
 }
 
 fn read_flac_metadata<T: Read>(src: &mut BMFFBox<T>) -> Result<FLACMetadataBlock> {
-    let temp = try!(src.read_u8());
+    let temp = src.read_u8()?;
     let block_type = temp & 0x7f;
-    let length = try!(be_u24(src));
+    let length = be_u24(src)?;
     if length as usize > src.bytes_left() {
         return Err(Error::InvalidData(
                 "FLACMetadataBlock larger than parent box"));
     }
-    let data = try!(read_buf(src, length as usize));
+    let data = read_buf(src, length as usize)?;
     Ok(FLACMetadataBlock {
         block_type: block_type,
         data: data,
     })
 }
 
-fn read_esds<T: Read>(src: &mut BMFFBox<T>) -> Result<ES_Descriptor> {
+fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
     // Tags for elementary stream description
     const ESDESCR_TAG: u8          = 0x03;
     const DECODER_CONFIG_TAG: u8   = 0x04;
     const DECODER_SPECIFIC_TAG: u8 = 0x05;
 
+    let mut remains = data;
+
+    while !remains.is_empty() {
+        let des = &mut Cursor::new(remains);
+        let tag = des.read_u8()?;
+
+        let extend_or_len = des.read_u8()?;
+        // extension tag start from 0x80.
+        let end = if extend_or_len >= 0x80 {
+            // Extension found, skip remaining extension.
+            skip(des, 2)?;
+            des.read_u8()? as u64 + des.position()
+        } else {
+            extend_or_len as u64 + des.position()
+        };
+
+        if end as usize > remains.len() {
+            return Err(Error::InvalidData("Invalid descriptor."));
+        }
+
+        let descriptor = &remains[des.position() as usize .. end as usize];
+
+        match tag {
+            ESDESCR_TAG => {
+                read_es_descriptor(descriptor, esds)?;
+            },
+            DECODER_CONFIG_TAG => {
+                read_dc_descriptor(descriptor, esds)?;
+            },
+            DECODER_SPECIFIC_TAG => {
+                read_ds_descriptor(descriptor, esds)?;
+            },
+            _ => {
+                log!("Unsupported descriptor, tag {}", tag);
+            },
+        }
+
+        remains = &remains[end as usize .. remains.len()];
+    }
+
+    Ok(())
+}
+
+fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
     let frequency_table =
         vec![(0x1, 96000), (0x1, 88200), (0x2, 64000), (0x3, 48000),
              (0x4, 44100), (0x5, 32000), (0x6, 24000), (0x7, 22050),
              (0x8, 16000), (0x9, 12000), (0xa, 11025), (0xb, 8000),
              (0xc, 7350)];
 
-    let (_, _) = try!(read_fullbox_extra(src));
+    let des = &mut Cursor::new(data);
+
+    let audio_specific_config = be_u16(des)?;
+
+    let sample_index = (audio_specific_config & 0x07FF) >> 7;
+
+    let channel_counts = (audio_specific_config & 0x007F) >> 3;
+
+    let sample_frequency =
+        frequency_table.iter().find(|item| item.0 == sample_index).map(|x| x.1);
+
+    esds.audio_sample_rate = sample_frequency;
+    esds.audio_channel_count = Some(channel_counts);
+
+    Ok(())
+}
+
+fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
+    let des = &mut Cursor::new(data);
+    let object_profile = des.read_u8()?;
+
+    // Skip uninteresting fields.
+    skip(des, 12)?;
+
+    if data.len() > des.position() as usize {
+        find_descriptor(&data[des.position() as usize .. data.len()], esds)?;
+    }
+
+    esds.audio_codec = match object_profile {
+        0x40 | 0x41 => CodecType::AAC,
+        0x6B => CodecType::MP3,
+        _ => CodecType::Unknown,
+    };
+
+    Ok(())
+}
+
+fn read_es_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
+    let des = &mut Cursor::new(data);
+
+    skip(des, 2)?;
+
+    let esds_flags = des.read_u8()?;
+
+    // Stream dependency flag, first bit from left most.
+    if esds_flags & 0x80 > 0 {
+        // Skip uninteresting fields.
+        skip(des, 2)?;
+    }
+
+    // Url flag, second bit from left most.
+    if esds_flags & 0x40 > 0 {
+        // Skip uninteresting fields.
+        let skip_es_len: usize = des.read_u8()? as usize + 2;
+        skip(des, skip_es_len)?;
+    }
+
+    if data.len() > des.position() as usize {
+        find_descriptor(&data[des.position() as usize .. data.len()], esds)?;
+    }
+
+    Ok(())
+}
+
+fn read_esds<T: Read>(src: &mut BMFFBox<T>) -> Result<ES_Descriptor> {
+    let (_, _) = read_fullbox_extra(src)?;
 
     let esds_size = src.head.size - src.head.offset - 4;
     if esds_size > BUF_SIZE_LIMIT {
         return Err(Error::InvalidData("esds box exceeds BUF_SIZE_LIMIT"));
     }
-    let esds_array = try!(read_buf(src, esds_size as usize));
-
-    // Parsing DecoderConfig descriptor to get the object_profile_indicator
-    // for correct codec type, audio sample rate and channel counts.
-    let (object_profile_indicator, sample_frequency, channels) = {
-        let mut object_profile: u8 = 0;
-        let mut sample_frequency = None;
-        let mut channels = None;
-
-        // clone a esds cursor for parsing.
-        let esds = &mut Cursor::new(&esds_array);
-        let next_tag = try!(esds.read_u8());
-
-        if next_tag != ESDESCR_TAG {
-            return Err(Error::Unsupported("fail to parse ES descriptor"));
-        }
-
-        let esds_extend = try!(esds.read_u8());
-        // extension tag start from 0x80.
-        let esds_end = if esds_extend >= 0x80 {
-            // skip remaining extension.
-            try!(skip(esds, 2));
-            esds.position() + try!(esds.read_u8()) as u64
-        } else {
-            esds.position() + esds_extend as u64
-        };
-        try!(skip(esds, 2));
-
-        let esds_flags = try!(esds.read_u8());
-
-        // Stream dependency flag, first bit from left most.
-        if esds_flags & 0x80 > 0 {
-            // Skip uninteresting fields.
-            try!(skip(esds, 2));
-        }
-
-        // Url flag, second bit from left most.
-        if esds_flags & 0x40 > 0 {
-            // Skip uninteresting fields.
-            let skip_es_len: usize = try!(esds.read_u8()) as usize + 2;
-            try!(skip(esds, skip_es_len));
-        }
+    let esds_array = read_buf(src, esds_size as usize)?;
 
-        // find DecoderConfig descriptor (tag = DECODER_CONFIG_TAG)
-        if esds_end > esds.position() {
-            let next_tag = try!(esds.read_u8());
-            if next_tag == DECODER_CONFIG_TAG {
-                let dcds_extend = try!(esds.read_u8());
-                // extension tag start from 0x80.
-                if dcds_extend >= 0x80 {
-                    // skip remains extension and length.
-                    try!(skip(esds, 3));
-                }
-
-                object_profile = try!(esds.read_u8());
-
-                // Skip uninteresting fields.
-                try!(skip(esds, 12));
-            }
-        }
-
-
-        // find DecoderSpecific descriptor (tag = DECODER_SPECIFIC_TAG)
-        if esds_end > esds.position() {
-            let next_tag = try!(esds.read_u8());
-            if next_tag == DECODER_SPECIFIC_TAG {
-                let dsds_extend = try!(esds.read_u8());
-                // extension tag start from 0x80.
-                if dsds_extend >= 0x80 {
-                    // skip remains extension and length.
-                    try!(skip(esds, 3));
-                }
+    let mut es_data = ES_Descriptor::default();
+    find_descriptor(&esds_array, &mut es_data)?;
 
-                let audio_specific_config = try!(be_u16(esds));
-
-                let sample_index = (audio_specific_config & 0x07FF) >> 7;
-
-                let channel_counts = (audio_specific_config & 0x007F) >> 3;
-
-                sample_frequency =
-                    frequency_table.iter().find(|item| item.0 == sample_index).map(|x| x.1);
-
-                channels = Some(channel_counts);
-            }
-        }
-
-        (object_profile, sample_frequency, channels)
-    };
+    es_data.codec_esds = esds_array;
 
-    let codec = match object_profile_indicator {
-        0x40 | 0x41 => CodecType::AAC,
-        0x6B => CodecType::MP3,
-        _ => CodecType::Unknown,
-    };
-
-    if codec == CodecType::Unknown {
-        return Err(Error::Unsupported("unknown audio codec"));
-    }
-
-    Ok(ES_Descriptor {
-        audio_codec: codec,
-        audio_sample_rate: sample_frequency,
-        audio_channel_count: channels,
-        codec_specific_config: esds_array,
-    })
+    Ok(es_data)
 }
 
 /// Parse `FLACSpecificBox`.
 fn read_dfla<T: Read>(src: &mut BMFFBox<T>) -> Result<FLACSpecificBox> {
-    let (version, flags) = try!(read_fullbox_extra(src));
+    let (version, flags) = read_fullbox_extra(src)?;
     if version != 0 {
         return Err(Error::Unsupported("unknown dfLa (FLAC) version"));
     }
     if flags != 0 {
         return Err(Error::InvalidData("no-zero dfLa (FLAC) flags"));
     }
     let mut blocks = Vec::new();
     while src.bytes_left() > 0 {
-        let block = try!(read_flac_metadata(src));
+        let block = read_flac_metadata(src)?;
         blocks.push(block);
     }
     // The box must have at least one meta block, and the first block
     // must be the METADATA_BLOCK_STREAMINFO
     if blocks.is_empty() {
         return Err(Error::InvalidData("FLACSpecificBox missing metadata"));
     } else if blocks[0].block_type != 0 {
         println!("flac metadata block:\n  {:?}", blocks[0]);
@@ -1327,33 +1339,33 @@ fn read_dfla<T: Read>(src: &mut BMFFBox<
     Ok(FLACSpecificBox {
         version: version,
         blocks: blocks,
     })
 }
 
 /// Parse `OpusSpecificBox`.
 fn read_dops<T: Read>(src: &mut BMFFBox<T>) -> Result<OpusSpecificBox> {
-    let version = try!(src.read_u8());
+    let version = src.read_u8()?;
     if version != 0 {
         return Err(Error::Unsupported("unknown dOps (Opus) version"));
     }
 
-    let output_channel_count = try!(src.read_u8());
-    let pre_skip = try!(be_u16(src));
-    let input_sample_rate = try!(be_u32(src));
-    let output_gain = try!(be_i16(src));
-    let channel_mapping_family = try!(src.read_u8());
+    let output_channel_count = src.read_u8()?;
+    let pre_skip = be_u16(src)?;
+    let input_sample_rate = be_u32(src)?;
+    let output_gain = be_i16(src)?;
+    let channel_mapping_family = src.read_u8()?;
 
     let channel_mapping_table = if channel_mapping_family == 0 {
         None
     } else {
-        let stream_count = try!(src.read_u8());
-        let coupled_count = try!(src.read_u8());
-        let channel_mapping = try!(read_buf(src, output_channel_count as usize));
+        let stream_count = src.read_u8()?;
+        let coupled_count = src.read_u8()?;
+        let channel_mapping = read_buf(src, output_channel_count as usize)?;
 
         Some(ChannelMappingTable {
             stream_count: stream_count,
             coupled_count: coupled_count,
             channel_mapping: channel_mapping,
         })
     };
 
@@ -1383,54 +1395,54 @@ pub fn serialize_opus_header<W: byteorde
                 return Err(Error::InvalidData("Couldn't write OpusHead tag."));
             }
         }
     }
     // In mp4 encapsulation, the version field is 0, but in ogg
     // it is 1. While decoders generally accept zero as well, write
     // out the version of the header we're supporting rather than
     // whatever we parsed out of mp4.
-    try!(dst.write_u8(1));
-    try!(dst.write_u8(opus.output_channel_count));
-    try!(dst.write_u16::<byteorder::LittleEndian>(opus.pre_skip));
-    try!(dst.write_u32::<byteorder::LittleEndian>(opus.input_sample_rate));
-    try!(dst.write_i16::<byteorder::LittleEndian>(opus.output_gain));
-    try!(dst.write_u8(opus.channel_mapping_family));
+    dst.write_u8(1)?;
+    dst.write_u8(opus.output_channel_count)?;
+    dst.write_u16::<byteorder::LittleEndian>(opus.pre_skip)?;
+    dst.write_u32::<byteorder::LittleEndian>(opus.input_sample_rate)?;
+    dst.write_i16::<byteorder::LittleEndian>(opus.output_gain)?;
+    dst.write_u8(opus.channel_mapping_family)?;
     match opus.channel_mapping_table {
         None => {}
         Some(ref table) => {
-            try!(dst.write_u8(table.stream_count));
-            try!(dst.write_u8(table.coupled_count));
+            dst.write_u8(table.stream_count)?;
+            dst.write_u8(table.coupled_count)?;
             match dst.write(&table.channel_mapping) {
                 Err(e) => return Err(Error::from(e)),
                 Ok(bytes) => {
                     if bytes != table.channel_mapping.len() {
                         return Err(Error::InvalidData("Couldn't write channel mapping table data."));
                     }
                 }
             }
         }
     };
     Ok(())
 }
 
 /// Parse a hdlr box.
 fn read_hdlr<T: Read>(src: &mut BMFFBox<T>) -> Result<HandlerBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
+    let (_, _) = read_fullbox_extra(src)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 4));
+    skip(src, 4)?;
 
-    let handler_type = try!(be_u32(src));
+    let handler_type = be_u32(src)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 12));
+    skip(src, 12)?;
 
     let bytes_left = src.bytes_left();
-    let _name = try!(read_null_terminated_string(src, bytes_left));
+    let _name = read_null_terminated_string(src, bytes_left)?;
 
     Ok(HandlerBox {
         handler_type: handler_type,
     })
 }
 
 /// Parse an video description inside an stsd box.
 fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) -> Result<SampleEntry> {
@@ -1439,64 +1451,64 @@ fn read_video_sample_entry<T: Read>(src:
         BoxType::AVCSampleEntry | BoxType::AVC3SampleEntry => CodecType::H264,
         BoxType::VP8SampleEntry => CodecType::VP8,
         BoxType::VP9SampleEntry => CodecType::VP9,
         BoxType::ProtectedVisualSampleEntry => CodecType::EncryptedVideo,
         _ => CodecType::Unknown,
     };
 
     // Skip uninteresting fields.
-    try!(skip(src, 6));
+    skip(src, 6)?;
 
-    let data_reference_index = try!(be_u16(src));
+    let data_reference_index = be_u16(src)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 16));
+    skip(src, 16)?;
 
-    let width = try!(be_u16(src));
-    let height = try!(be_u16(src));
+    let width = be_u16(src)?;
+    let height = be_u16(src)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 14));
+    skip(src, 14)?;
 
-    let _compressorname = try!(read_fixed_length_pascal_string(src, 32));
+    let _compressorname = read_fixed_length_pascal_string(src, 32)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 4));
+    skip(src, 4)?;
 
     // Skip clap/pasp/etc. for now.
     let mut codec_specific = None;
     let mut iter = src.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::AVCConfigurationBox => {
                 if (name != BoxType::AVCSampleEntry &&
                     name != BoxType::AVC3SampleEntry &&
                     name != BoxType::ProtectedVisualSampleEntry) ||
                     codec_specific.is_some() {
                         return Err(Error::InvalidData("malformed video sample entry"));
                     }
                 let avcc_size = b.head.size - b.head.offset;
                 if avcc_size > BUF_SIZE_LIMIT {
                     return Err(Error::InvalidData("avcC box exceeds BUF_SIZE_LIMIT"));
                 }
-                let avcc = try!(read_buf(&mut b.content, avcc_size as usize));
+                let avcc = read_buf(&mut b.content, avcc_size as usize)?;
                 // TODO(kinetik): Parse avcC box?  For now we just stash the data.
                 codec_specific = Some(VideoCodecSpecific::AVCConfig(avcc));
             }
             BoxType::VPCodecConfigurationBox => { // vpcC
                 if (name != BoxType::VP8SampleEntry &&
                     name != BoxType::VP9SampleEntry) ||
                     codec_specific.is_some() {
                         return Err(Error::InvalidData("malformed video sample entry"));
                     }
-                let vpcc = try!(read_vpcc(&mut b));
+                let vpcc = read_vpcc(&mut b)?;
                 codec_specific = Some(VideoCodecSpecific::VPxConfig(vpcc));
             }
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         }
         check_parser_state!(b.content);
     }
 
     codec_specific
         .map(|codec_specific| SampleEntry::Video(VideoSampleEntry {
             data_reference_index: data_reference_index,
             width: width,
@@ -1504,23 +1516,23 @@ fn read_video_sample_entry<T: Read>(src:
             codec_specific: codec_specific,
         }))
         .ok_or_else(|| Error::InvalidData("malformed video sample entry"))
 }
 
 fn read_qt_wave_atom<T: Read>(src: &mut BMFFBox<T>) -> Result<ES_Descriptor> {
     let mut codec_specific = None;
     let mut iter = src.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::ESDBox => {
-                let esds = try!(read_esds(&mut b));
+                let esds = read_esds(&mut b)?;
                 codec_specific = Some(esds);
             },
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         }
     }
 
     codec_specific.ok_or_else(|| Error::InvalidData("malformed audio sample entry"))
 }
 
 /// Parse an audio description inside an stsd box.
 fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) -> Result<SampleEntry> {
@@ -1530,87 +1542,87 @@ fn read_audio_sample_entry<T: Read>(src:
         BoxType::MP4AudioSampleEntry => CodecType::AAC,
         BoxType::FLACSampleEntry => CodecType::FLAC,
         BoxType::OpusSampleEntry => CodecType::Opus,
         BoxType::ProtectedAudioSampleEntry => CodecType::EncryptedAudio,
         _ => CodecType::Unknown,
     };
 
     // Skip uninteresting fields.
-    try!(skip(src, 6));
+    skip(src, 6)?;
 
-    let data_reference_index = try!(be_u16(src));
+    let data_reference_index = be_u16(src)?;
 
     // XXX(kinetik): This is "reserved" in BMFF, but some old QT MOV variant
     // uses it, need to work out if we have to support it.  Without checking
     // here and reading extra fields after samplerate (or bailing with an
     // error), the parser loses sync completely.
-    let version = try!(be_u16(src));
+    let version = be_u16(src)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 6));
+    skip(src, 6)?;
 
-    let channelcount = try!(be_u16(src));
-    let samplesize = try!(be_u16(src));
+    let channelcount = be_u16(src)?;
+    let samplesize = be_u16(src)?;
 
     // Skip uninteresting fields.
-    try!(skip(src, 4));
+    skip(src, 4)?;
 
-    let samplerate = try!(be_u32(src));
+    let samplerate = be_u32(src)?;
 
     match version {
         0 => (),
         1 => {
             // Quicktime sound sample description version 1.
             // Skip uninteresting fields.
-            try!(skip(src, 16));
+            skip(src, 16)?;
         },
         _ => return Err(Error::Unsupported("unsupported non-isom audio sample entry")),
     }
 
     // Skip chan/etc. for now.
     let mut codec_specific = None;
     let mut iter = src.box_iter();
-    while let Some(mut b) = try!(iter.next_box()) {
+    while let Some(mut b) = iter.next_box()? {
         match b.head.name {
             BoxType::ESDBox => {
                 if (name != BoxType::MP4AudioSampleEntry &&
                     name != BoxType::ProtectedAudioSampleEntry) ||
                     codec_specific.is_some() {
                         return Err(Error::InvalidData("malformed audio sample entry"));
                 }
 
-                let esds = try!(read_esds(&mut b));
+                let esds = read_esds(&mut b)?;
                 track.codec_type = esds.audio_codec;
                 codec_specific = Some(AudioCodecSpecific::ES_Descriptor(esds));
             }
             BoxType::FLACSpecificBox => {
                 if name != BoxType::FLACSampleEntry ||
                     codec_specific.is_some() {
                     return Err(Error::InvalidData("malformed audio sample entry"));
                 }
-                let dfla = try!(read_dfla(&mut b));
+                let dfla = read_dfla(&mut b)?;
                 track.codec_type = CodecType::FLAC;
                 codec_specific = Some(AudioCodecSpecific::FLACSpecificBox(dfla));
             }
             BoxType::OpusSpecificBox => {
                 if name != BoxType::OpusSampleEntry ||
                     codec_specific.is_some() {
                     return Err(Error::InvalidData("malformed audio sample entry"));
                 }
-                let dops = try!(read_dops(&mut b));
+                let dops = read_dops(&mut b)?;
                 track.codec_type = CodecType::Opus;
                 codec_specific = Some(AudioCodecSpecific::OpusSpecificBox(dops));
             }
             BoxType::QTWaveAtom => {
-                let qt_esds = try!(read_qt_wave_atom(&mut b));
+                let qt_esds = read_qt_wave_atom(&mut b)?;
                 track.codec_type = qt_esds.audio_codec;
                 codec_specific = Some(AudioCodecSpecific::ES_Descriptor(qt_esds));
             }
-            _ => try!(skip_box_content(&mut b)),
+            _ => skip_box_content(&mut b)?,
         }
         check_parser_state!(b.content);
     }
 
     codec_specific
         .map(|codec_specific| SampleEntry::Audio(AudioSampleEntry {
             data_reference_index: data_reference_index,
             channelcount: channelcount,
@@ -1618,38 +1630,38 @@ fn read_audio_sample_entry<T: Read>(src:
             samplerate: samplerate,
             codec_specific: codec_specific,
         }))
         .ok_or_else(|| Error::InvalidData("malformed audio sample entry"))
 }
 
 /// Parse a stsd box.
 fn read_stsd<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) -> Result<SampleDescriptionBox> {
-    let (_, _) = try!(read_fullbox_extra(src));
+    let (_, _) = read_fullbox_extra(src)?;
 
-    let description_count = try!(be_u32(src));
+    let description_count = be_u32(src)?;
     let mut descriptions = Vec::new();
 
     {
         // TODO(kinetik): check if/when more than one desc per track? do we need to support?
         let mut iter = src.box_iter();
-        while let Some(mut b) = try!(iter.next_box()) {
+        while let Some(mut b) = iter.next_box()? {
             let description = match track.track_type {
                 TrackType::Video => read_video_sample_entry(&mut b, track),
                 TrackType::Audio => read_audio_sample_entry(&mut b, track),
                 TrackType::Unknown => Err(Error::Unsupported("unknown track type")),
             };
             let description = match description {
                 Ok(desc) => desc,
                 Err(Error::Unsupported(_)) => {
                     // read_{audio,video}_desc may have returned Unsupported
                     // after partially reading the box content, so we can't
                     // simply use skip_box_content here.
                     let to_skip = b.bytes_left();
-                    try!(skip(&mut b, to_skip));
+                    skip(&mut b, to_skip)?;
                     SampleEntry::Unknown
                 }
                 Err(e) => return Err(e),
             };
             if track.data.is_none() {
                 track.data = Some(description.clone());
             } else {
                 log!("** don't know how to handle multiple descriptions **");
@@ -1658,80 +1670,80 @@ fn read_stsd<T: Read>(src: &mut BMFFBox<
             check_parser_state!(b.content);
             if descriptions.len() == description_count as usize {
                 break;
             }
         }
     }
 
     // Padding could be added in some contents.
-    try!(skip_box_remain(src));
+    skip_box_remain(src)?;
 
     Ok(SampleDescriptionBox {
         descriptions: descriptions,
     })
 }
 
 /// Skip a number of bytes that we don't care to parse.
 fn skip<T: Read>(src: &mut T, mut bytes: usize) -> Result<()> {
     const BUF_SIZE: usize = 64 * 1024;
     let mut buf = vec![0; BUF_SIZE];
     while bytes > 0 {
         let buf_size = cmp::min(bytes, BUF_SIZE);
-        let len = try!(src.take(buf_size as u64).read(&mut buf));
+        let len = src.take(buf_size as u64).read(&mut buf)?;
         if len == 0 {
             return Err(Error::UnexpectedEOF);
         }
         bytes -= len;
     }
     Ok(())
 }
 
 /// Read size bytes into a Vector or return error.
 fn read_buf<T: ReadBytesExt>(src: &mut T, size: usize) -> Result<Vec<u8>> {
     let mut buf = vec![0; size];
-    let r = try!(src.read(&mut buf));
+    let r = src.read(&mut buf)?;
     if r != size {
         return Err(Error::InvalidData("failed buffer read"));
     }
     Ok(buf)
 }
 
 // TODO(kinetik): Find a copy of ISO/IEC 14496-1 to confirm various string encodings.
 // XXX(kinetik): definition of "null-terminated" string is fuzzy, we have:
 // - zero or more byte strings, with a single null terminating the string.
 // - zero byte strings with no null terminator (i.e. zero space in the box for the string)
 // - length-prefixed strings with no null terminator (e.g. bear_rotate_0.mp4)
 fn read_null_terminated_string<T: ReadBytesExt>(src: &mut T, mut size: usize) -> Result<String> {
     let mut buf = Vec::new();
     while size > 0 {
-        let c = try!(src.read_u8());
+        let c = src.read_u8()?;
         if c == 0 {
             break;
         }
         buf.push(c);
         size -= 1;
     }
     String::from_utf8(buf).map_err(From::from)
 }
 
 #[allow(dead_code)]
 fn read_pascal_string<T: ReadBytesExt>(src: &mut T) -> Result<String> {
-    let len = try!(src.read_u8());
-    let buf = try!(read_buf(src, len as usize));
+    let len = src.read_u8()?;
+    let buf = read_buf(src, len as usize)?;
     String::from_utf8(buf).map_err(From::from)
 }
 
 // Weird string encoding with a length prefix and a fixed sized buffer which
 // contains padding if the string doesn't fill the buffer.
 fn read_fixed_length_pascal_string<T: Read>(src: &mut T, size: usize) -> Result<String> {
     assert!(size > 0);
-    let len = cmp::min(try!(src.read_u8()) as usize, size - 1);
-    let buf = try!(read_buf(src, len));
-    try!(skip(src, size - 1 - buf.len()));
+    let len = cmp::min(src.read_u8()? as usize, size - 1);
+    let buf = read_buf(src, len)?;
+    skip(src, size - 1 - buf.len())?;
     String::from_utf8(buf).map_err(From::from)
 }
 
 fn be_i16<T: ReadBytesExt>(src: &mut T) -> Result<i16> {
     src.read_i16::<byteorder::BigEndian>().map_err(From::from)
 }
 
 fn be_i32<T: ReadBytesExt>(src: &mut T) -> Result<i32> {
--- a/media/libstagefright/binding/mp4parse/src/tests.rs
+++ b/media/libstagefright/binding/mp4parse/src/tests.rs
@@ -143,18 +143,18 @@ fn read_truncated_ftyp() {
     let mut stream = make_box(BoxSize::UncheckedShort(24), b"ftyp", |s| {
         s.append_bytes(b"mp42")
             .B32(0) // minor version
             .append_bytes(b"isom")
     });
     let mut context = MediaContext::new();
     match read_mp4(&mut stream, &mut context) {
         Err(Error::UnexpectedEOF) => (),
-        Ok(_) => assert!(false, "expected an error result"),
-        _ => assert!(false, "expected a different error result"),
+        Ok(_) => panic!("expected an error result"),
+        _ => panic!("expected a different error result"),
     }
 }
 
 #[test]
 fn read_ftyp_case() {
     // Brands in BMFF are represented as a u32, so it would seem clear that
     // 0x6d703432 ("mp42") is not equal to 0x4d503432 ("MP42"), but some
     // demuxers treat these as case-insensitive strings, e.g. street.mp4's
@@ -588,18 +588,18 @@ fn serialize_opus_header() {
         pre_skip: 342,
         input_sample_rate: 24000,
         output_gain: 0,
         channel_mapping_family: 0,
         channel_mapping_table: None,
     };
     let mut v = Vec::<u8>::new();
     super::serialize_opus_header(&opus, &mut v).unwrap();
-    assert!(v.len() == 19);
-    assert!(v == vec![
+    assert_eq!(v.len(), 19);
+    assert_eq!(v, vec![
             0x4f, 0x70, 0x75, 0x73, 0x48,0x65, 0x61, 0x64,
             0x01, 0x01, 0x56, 0x01,
             0xc0, 0x5d, 0x00, 0x00,
             0x00, 0x00, 0x00,
     ]);
     let opus = super::OpusSpecificBox {
         version: 0,
         output_channel_count: 6,
@@ -610,18 +610,18 @@ fn serialize_opus_header() {
         channel_mapping_table: Some(super::ChannelMappingTable {
             stream_count: 4,
             coupled_count: 2,
             channel_mapping: vec![0, 4, 1, 2, 3, 5],
         }),
     };
     let mut v = Vec::<u8>::new();
     super::serialize_opus_header(&opus, &mut v).unwrap();
-    assert!(v.len() == 27);
-    assert!(v == vec![
+    assert_eq!(v.len(), 27);
+    assert_eq!(v, vec![
             0x4f, 0x70, 0x75, 0x73, 0x48,0x65, 0x61, 0x64,
             0x01, 0x06, 0x98, 0x00,
             0x80, 0xbb, 0x00, 0x00,
             0x00, 0x00, 0x01, 0x04, 0x02,
             0x00, 0x04, 0x01, 0x02, 0x03, 0x05,
     ]);
 }
 
@@ -640,18 +640,18 @@ fn avcc_limit() {
          .append_bytes(b"avcC")
          .append_repeated(0, 100)
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     let mut track = super::Track::new(0);
     match super::read_video_sample_entry(&mut stream, &mut track) {
         Err(Error::InvalidData(s)) => assert_eq!(s, "avcC box exceeds BUF_SIZE_LIMIT"),
-        Ok(_) => assert!(false, "expected an error result"),
-        _ => assert!(false, "expected a different error result"),
+        Ok(_) => panic!("expected an error result"),
+        _ => panic!("expected a different error result"),
     }
 }
 
 #[test]
 fn esds_limit() {
     let mut stream = make_box(BoxSize::Auto, b"mp4a", |s| {
         s.append_repeated(0, 6)
          .B16(1)
@@ -666,18 +666,18 @@ fn esds_limit() {
          .append_bytes(b"esds")
          .append_repeated(0, 100)
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     let mut track = super::Track::new(0);
     match super::read_audio_sample_entry(&mut stream, &mut track) {
         Err(Error::InvalidData(s)) => assert_eq!(s, "esds box exceeds BUF_SIZE_LIMIT"),
-        Ok(_) => assert!(false, "expected an error result"),
-        _ => assert!(false, "expected a different error result"),
+        Ok(_) => panic!("expected an error result"),
+        _ => panic!("expected a different error result"),
     }
 }
 
 #[test]
 fn esds_limit_2() {
     let mut stream = make_box(BoxSize::Auto, b"mp4a", |s| {
         s.append_repeated(0, 6)
          .B16(1)
@@ -692,34 +692,34 @@ fn esds_limit_2() {
          .append_bytes(b"esds")
          .append_repeated(0, 4)
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     let mut track = super::Track::new(0);
     match super::read_audio_sample_entry(&mut stream, &mut track) {
         Err(Error::UnexpectedEOF) => (),
-        Ok(_) => assert!(false, "expected an error result"),
-        _ => assert!(false, "expected a different error result"),
+        Ok(_) => panic!("expected an error result"),
+        _ => panic!("expected a different error result"),
     }
 }
 
 #[test]
 fn read_elst_zero_entries() {
     let mut stream = make_fullbox(BoxSize::Auto, b"elst", 0, |s| {
         s.B32(0)
          .B16(12)
          .B16(34)
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     match super::read_elst(&mut stream) {
         Err(Error::InvalidData(s)) => assert_eq!(s, "invalid edit count"),
-        Ok(_) => assert!(false, "expected an error result"),
-        _ => assert!(false, "expected a different error result"),
+        Ok(_) => panic!("expected an error result"),
+        _ => panic!("expected a different error result"),
     }
 }
 
 fn make_elst() -> Cursor<Vec<u8>> {
     make_fullbox(BoxSize::Auto, b"elst", 1, |s| {
         s.B32(1)
         // first entry
          .B64(1234) // duration
@@ -736,18 +736,18 @@ fn read_edts_bogus() {
     let mut stream = make_box(BoxSize::Auto, b"edts", |s| {
         s.append_bytes(&make_elst().into_inner())
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     let mut track = super::Track::new(0);
     match super::read_edts(&mut stream, &mut track) {
         Err(Error::InvalidData(s)) => assert_eq!(s, "expected additional edit"),
-        Ok(_) => assert!(false, "expected an error result"),
-        _ => assert!(false, "expected a different error result"),
+        Ok(_) => panic!("expected an error result"),
+        _ => panic!("expected a different error result"),
     }
 }
 
 #[test]
 fn invalid_pascal_string() {
     // String claims to be 32 bytes long (we provide 33 bytes to account for
     // the 1 byte length prefix).
     let pstr = "\x20xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
@@ -822,17 +822,17 @@ fn skip_padding_in_stsd() {
     super::read_stsd(&mut stream, &mut super::Track::new(0))
           .expect("fail to skip padding: stsd");
 }
 
 #[test]
 fn read_qt_wave_atom() {
     let esds = make_fullbox(BoxSize::Auto, b"esds", 0, |s| {
         s.B8(0x03)  // elementary stream descriptor tag
-         .B8(0x0b)  // esds length
+         .B8(0x12)  // esds length
          .append_repeated(0, 2)
          .B8(0x00)  // flags
          .B8(0x04)  // decoder config descriptor tag
          .B8(0x0d)  // dcds length
          .B8(0x6b)  // mp3
          .append_repeated(0, 12)
     }).into_inner();
     let wave = make_box(BoxSize::Auto, b"wave", |s| {
--- a/media/libstagefright/binding/mp4parse/tests/public.rs
+++ b/media/libstagefright/binding/mp4parse/tests/public.rs
@@ -73,18 +73,18 @@ fn public_api() {
                     mp4::AudioCodecSpecific::ES_Descriptor(esds) => {
                         assert_eq!(esds.audio_codec, mp4::CodecType::AAC);
                         assert_eq!(esds.audio_sample_rate.unwrap(), 48000);
                         "ES"
                     }
                     mp4::AudioCodecSpecific::FLACSpecificBox(flac) => {
                         // STREAMINFO block must be present and first.
                         assert!(flac.blocks.len() > 0);
-                        assert!(flac.blocks[0].block_type == 0);
-                        assert!(flac.blocks[0].data.len() == 34);
+                        assert_eq!(flac.blocks[0].block_type, 0);
+                        assert_eq!(flac.blocks[0].data.len(), 34);
                         "FLAC"
                     }
                     mp4::AudioCodecSpecific::OpusSpecificBox(opus) => {
                         // We don't enter in here, we just check if fields are public.
                         assert!(opus.version > 0);
                         "Opus"
                     }
                 }, "ES");
--- a/media/libstagefright/binding/mp4parse_capi/src/lib.rs
+++ b/media/libstagefright/binding/mp4parse_capi/src/lib.rs
@@ -136,28 +136,26 @@ pub struct mp4parse_pssh_info {
 #[repr(C)]
 pub struct mp4parse_track_audio_info {
     pub channels: u16,
     pub bit_depth: u16,
     pub sample_rate: u32,
     // TODO(kinetik):
     // int32_t profile;
     // int32_t extended_profile; // check types
-    codec_specific_config: mp4parse_byte_data,
+    pub codec_specific_config: mp4parse_byte_data,
 }
 
 #[repr(C)]
 pub struct mp4parse_track_video_info {
     pub display_width: u32,
     pub display_height: u32,
     pub image_width: u16,
     pub image_height: u16,
-    // TODO(kinetik):
-    // extra_data
-    // codec_specific_config
+    pub extra_data: mp4parse_byte_data,
 }
 
 #[repr(C)]
 pub struct mp4parse_fragment_info {
     pub fragment_duration: u64,
     // TODO:
     // info in trex box.
 }
@@ -331,17 +329,17 @@ fn rational_scale(numerator: u64, denomi
 }
 
 fn media_time_to_us(time: MediaScaledTime, scale: MediaTimeScale) -> Option<u64> {
     let microseconds_per_second = 1000000;
     rational_scale(time.0, scale.0, microseconds_per_second)
 }
 
 fn track_time_to_us(time: TrackScaledTime, scale: TrackTimeScale) -> Option<u64> {
-    assert!(time.1 == scale.1);
+    assert_eq!(time.1, scale.1);
     let microseconds_per_second = 1000000;
     rational_scale(time.0, scale.0, microseconds_per_second)
 }
 
 /// Fill the supplied `mp4parse_track_info` with metadata for `track`.
 #[no_mangle]
 pub unsafe extern fn mp4parse_get_track_info(parser: *mut mp4parse_parser, track_index: u32, info: *mut mp4parse_track_info) -> mp4parse_error {
     if parser.is_null() || info.is_null() || (*parser).poisoned() {
@@ -455,21 +453,21 @@ pub unsafe extern fn mp4parse_get_track_
     };
 
     (*info).channels = audio.channelcount;
     (*info).bit_depth = audio.samplesize;
     (*info).sample_rate = audio.samplerate >> 16; // 16.16 fixed point
 
     match audio.codec_specific {
         AudioCodecSpecific::ES_Descriptor(ref v) => {
-            if v.codec_specific_config.len() > std::u32::MAX as usize {
+            if v.codec_esds.len() > std::u32::MAX as usize {
                 return MP4PARSE_ERROR_INVALID;
             }
-            (*info).codec_specific_config.length = v.codec_specific_config.len() as u32;
-            (*info).codec_specific_config.data = v.codec_specific_config.as_ptr();
+            (*info).codec_specific_config.length = v.codec_esds.len() as u32;
+            (*info).codec_specific_config.data = v.codec_esds.as_ptr();
             if let Some(rate) = v.audio_sample_rate {
                 (*info).sample_rate = rate;
             }
             if let Some(channels) = v.audio_channel_count {
                 (*info).channels = channels;
             }
         }
         AudioCodecSpecific::FLACSpecificBox(ref flac) => {
@@ -542,16 +540,23 @@ pub unsafe extern fn mp4parse_get_track_
         (*info).display_width = tkhd.width >> 16; // 16.16 fixed point
         (*info).display_height = tkhd.height >> 16; // 16.16 fixed point
     } else {
         return MP4PARSE_ERROR_INVALID;
     }
     (*info).image_width = video.width;
     (*info).image_height = video.height;
 
+    match video.codec_specific {
+        VideoCodecSpecific::AVCConfig(ref avc) => {
+            (*info).extra_data.set_data(avc);
+        },
+        _ => {},
+    }
+
     MP4PARSE_OK
 }
 
 /// Fill the supplied `mp4parse_fragment_info` with metadata from fragmented file.
 #[no_mangle]
 pub unsafe extern fn mp4parse_get_fragment_info(parser: *mut mp4parse_parser, info: *mut mp4parse_fragment_info) -> mp4parse_error {
     if parser.is_null() || info.is_null() || (*parser).poisoned() {
         return MP4PARSE_ERROR_BADARG;
@@ -681,19 +686,19 @@ fn free_null_parser() {
     }
 }
 
 #[test]
 fn get_track_count_null_parser() {
     unsafe {
         let mut count: u32 = 0;
         let rv = mp4parse_get_track_count(std::ptr::null(), std::ptr::null_mut());
-        assert!(rv == MP4PARSE_ERROR_BADARG);
+        assert_eq!(rv, MP4PARSE_ERROR_BADARG);
         let rv = mp4parse_get_track_count(std::ptr::null(), &mut count);
-        assert!(rv == MP4PARSE_ERROR_BADARG);
+        assert_eq!(rv, MP4PARSE_ERROR_BADARG);
     }
 }
 
 #[test]
 fn arg_validation() {
     unsafe {
         // Passing a null mp4parse_io is an error.
         let parser = mp4parse_new(std::ptr::null());
@@ -732,16 +737,17 @@ fn arg_validation() {
         };
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_info(std::ptr::null_mut(), 0, &mut dummy_info));
 
         let mut dummy_video = mp4parse_track_video_info {
             display_width: 0,
             display_height: 0,
             image_width: 0,
             image_height: 0,
+            extra_data: mp4parse_byte_data::default(),
         };
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_video_info(std::ptr::null_mut(), 0, &mut dummy_video));
 
         let mut dummy_audio = Default::default();
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_audio_info(std::ptr::null_mut(), 0, &mut dummy_audio));
     }
 }
 
@@ -776,16 +782,17 @@ fn arg_validation_with_parser() {
         };
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_info(parser, 0, &mut dummy_info));
 
         let mut dummy_video = mp4parse_track_video_info {
             display_width: 0,
             display_height: 0,
             image_width: 0,
             image_height: 0,
+            extra_data: mp4parse_byte_data::default(),
         };
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_video_info(parser, 0, &mut dummy_video));
 
         let mut dummy_audio = Default::default();
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_audio_info(parser, 0, &mut dummy_audio));
 
         mp4parse_free(parser);
     }
@@ -802,17 +809,17 @@ fn get_track_count_poisoned_parser() {
         let parser = mp4parse_new(&io);
         assert!(!parser.is_null());
 
         // Our mp4parse_io read should simply fail with an error.
         assert_eq!(MP4PARSE_ERROR_IO, mp4parse_read(parser));
 
         let mut count: u32 = 0;
         let rv = mp4parse_get_track_count(parser, &mut count);
-        assert!(rv == MP4PARSE_ERROR_BADARG);
+        assert_eq!(rv, MP4PARSE_ERROR_BADARG);
     }
 }
 
 #[test]
 fn arg_validation_with_data() {
     unsafe {
         let mut file = std::fs::File::open("../mp4parse/tests/minimal.mp4").unwrap();
         let io = mp4parse_io { read: valid_read,
@@ -847,16 +854,17 @@ fn arg_validation_with_data() {
         assert_eq!(info.duration, 61333);
         assert_eq!(info.media_time, 21333);
 
         let mut video = mp4parse_track_video_info {
             display_width: 0,
             display_height: 0,
             image_width: 0,
             image_height: 0,
+            extra_data: mp4parse_byte_data::default(),
         };
         assert_eq!(MP4PARSE_OK, mp4parse_get_track_video_info(parser, 0, &mut video));
         assert_eq!(video.display_width, 320);
         assert_eq!(video.display_height, 240);
         assert_eq!(video.image_width, 320);
         assert_eq!(video.image_height, 240);
 
         let mut audio = Default::default();
@@ -878,17 +886,18 @@ fn arg_validation_with_data() {
         assert_eq!(info.codec, mp4parse_codec::MP4PARSE_CODEC_UNKNOWN);
         assert_eq!(info.track_id, 0);
         assert_eq!(info.duration, 0);
         assert_eq!(info.media_time, 0);
 
         let mut video = mp4parse_track_video_info { display_width: 0,
                                                     display_height: 0,
                                                     image_width: 0,
-                                                    image_height: 0 };
+                                                    image_height: 0,
+                                                    extra_data: mp4parse_byte_data::default(),};
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_video_info(parser, 3, &mut video));
         assert_eq!(video.display_width, 0);
         assert_eq!(video.display_height, 0);
         assert_eq!(video.image_width, 0);
         assert_eq!(video.image_height, 0);
 
         let mut audio = Default::default();
         assert_eq!(MP4PARSE_ERROR_BADARG, mp4parse_get_track_audio_info(parser, 3, &mut audio));
--- a/mfbt/Variant.h
+++ b/mfbt/Variant.h
@@ -19,16 +19,44 @@
 
 namespace mozilla {
 
 template<typename... Ts>
 class Variant;
 
 namespace detail {
 
+template <typename...>
+struct FirstTypeIsInRest;
+
+template <typename First>
+struct FirstTypeIsInRest<First> : FalseType {};
+
+template <typename First, typename Second, typename... Rest>
+struct FirstTypeIsInRest<First, Second, Rest...>
+{
+  static constexpr bool value =
+    IsSame<First, Second>::value ||
+    FirstTypeIsInRest<First, Rest...>::value;
+};
+
+template <typename...>
+struct TypesAreDistinct;
+
+template <>
+struct TypesAreDistinct<> : TrueType { };
+
+template<typename First, typename... Rest>
+struct TypesAreDistinct<First, Rest...>
+{
+  static constexpr bool value =
+    !FirstTypeIsInRest<First, Rest...>::value &&
+    TypesAreDistinct<Rest...>::value;
+};
+
 // MaxSizeOf computes the maximum sizeof(T) for each T in Ts.
 
 template<typename T, typename... Ts>
 struct MaxSizeOf
 {
   static const size_t size = sizeof(T) > MaxSizeOf<Ts...>::size
     ? sizeof(T)
     : MaxSizeOf<Ts...>::size;
@@ -423,16 +451,17 @@ struct AsVariantTemporary
  *       Variant<const char*, UniquePtr<char[]>> string;
  *
  *       ...
  *     };
  */
 template<typename... Ts>
 class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Variant
 {
+  static_assert(detail::TypesAreDistinct<Ts...>::value, "Variant with duplicate types is not supported");
   using Tag = typename detail::VariantTag<Ts...>::Type;
   using Impl = detail::VariantImplementation<Tag, 0, Ts...>;
   using RawData = AlignedStorage<detail::MaxSizeOf<Ts...>::size>;
 
   // Raw storage for the contained variant value.
   RawData raw;
 
   // Each type is given a unique tag value that lets us keep track of the
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -1926,16 +1926,19 @@ public abstract class GeckoApp
         intent.putExtra("duplicate", false);
 
         intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
         getApplicationContext().sendBroadcast(intent);
 
         // Remember interaction
         final UrlAnnotations urlAnnotations = BrowserDB.from(getApplicationContext()).getUrlAnnotations();
         urlAnnotations.insertHomeScreenShortcut(getContentResolver(), aURI, true);
+
+        // After shortcut is created, show the mobile desktop.
+        ActivityUtils.goToHomeScreen(this);
     }
 
     private Bitmap getLauncherIcon(Bitmap aSource, int size) {
         final float[] DEFAULT_LAUNCHER_ICON_HSV = { 32.0f, 1.0f, 1.0f };
         final int kOffset = 6;
         final int kRadius = 5;
 
         int insetSize = aSource != null ? size * 2 / 3 : size;
--- a/mobile/android/base/java/org/mozilla/gecko/SiteIdentity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/SiteIdentity.java
@@ -11,16 +11,17 @@ import android.text.TextUtils;
 
 public class SiteIdentity {
     private final String LOGTAG = "GeckoSiteIdentity";
     private SecurityMode mSecurityMode;
     private boolean mSecure;
     private MixedMode mMixedModeActive;
     private MixedMode mMixedModeDisplay;
     private TrackingMode mTrackingMode;
+    private boolean mSecurityException;
     private String mHost;
     private String mOwner;
     private String mSupplemental;
     private String mCountry;
     private String mVerifier;
     private String mOrigin;
 
     // The order of the items here relate to image levels in
@@ -124,30 +125,32 @@ public class SiteIdentity {
     }
 
     public SiteIdentity() {
         reset();
     }
 
     public void resetIdentity() {
         mSecurityMode = SecurityMode.UNKNOWN;
+        mSecurityException = false;
         mOrigin = null;
         mHost = null;
         mOwner = null;
         mSupplemental = null;
         mCountry = null;
         mVerifier = null;
         mSecure = false;
     }
 
     public void reset() {
         resetIdentity();
         mMixedModeActive = MixedMode.UNKNOWN;
         mMixedModeDisplay = MixedMode.UNKNOWN;
         mTrackingMode = TrackingMode.UNKNOWN;
+        mSecurityException = false;
     }
 
     void update(JSONObject identityData) {
         if (identityData == null) {
             reset();
             return;
         }
 
@@ -182,16 +185,18 @@ public class SiteIdentity {
             try {
                 mOrigin = identityData.getString("origin");
                 mHost = identityData.optString("host", null);
                 mOwner = identityData.optString("owner", null);
                 mSupplemental = identityData.optString("supplemental", null);
                 mCountry = identityData.optString("country", null);
                 mVerifier = identityData.optString("verifier", null);
                 mSecure = identityData.optBoolean("secure", false);
+                mSecurityException = identityData.optBoolean("securityException", false);
+
             } catch (Exception e) {
                 resetIdentity();
             }
         } catch (Exception e) {
             reset();
         }
     }
 
@@ -238,12 +243,16 @@ public class SiteIdentity {
     public MixedMode getMixedModeActive() {
         return mMixedModeActive;
     }
 
     public MixedMode getMixedModeDisplay() {
         return mMixedModeDisplay;
     }
 
+    public boolean isSecurityException() {
+        return mSecurityException;
+    }
+
     public TrackingMode getTrackingMode() {
         return mTrackingMode;
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/media/JellyBeanAsyncCodec.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/JellyBeanAsyncCodec.java
@@ -209,34 +209,32 @@ final class JellyBeanAsyncCodec implemen
 
             return true;
         }
 
         private void pollInputBuffer() {
             int result = mCodec.dequeueInputBuffer(DEQUEUE_TIMEOUT_US);
             if (result >= 0) {
                 mCallbackSender.notifyInputBuffer(result);
-                schedulePollingIfNotCanceled(BufferPoller.MSG_POLL_INPUT_BUFFERS);
-            } else if (result != MediaCodec.INFO_TRY_AGAIN_LATER) {
+            } else if (result == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                mBufferPoller.schedulePollingIfNotCanceled(BufferPoller.MSG_POLL_INPUT_BUFFERS);
+            } else {
                 mCallbackSender.notifyError(result);
             }
         }
 
         private void pollOutputBuffer() {
             boolean dequeueMoreBuffer = true;
             MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
             int result = mCodec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT_US);
             if (result >= 0) {
                 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                     mOutputEnded = true;
                 }
                 mCallbackSender.notifyOutputBuffer(result, info);
-                if (!hasMessages(MSG_POLL_INPUT_BUFFERS)) {
-                    schedulePollingIfNotCanceled(MSG_POLL_INPUT_BUFFERS);
-                }
             } else if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                 mOutputBuffers = mCodec.getOutputBuffers();
             } else if (result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                 mCallbackSender.notifyOutputFormat(mCodec.getOutputFormat());
             } else if (result == MediaCodec.INFO_TRY_AGAIN_LATER) {
                 // When input ended, keep polling remaining output buffer until EOS.
                 dequeueMoreBuffer = mInputEnded;
             } else {
@@ -321,36 +319,38 @@ final class JellyBeanAsyncCodec implemen
     @Override
     public void start() {
         assertCallbacks();
 
         mCodec.start();
         mInputEnded = false;
         mOutputEnded = false;
         mInputBuffers = mCodec.getInputBuffers();
+        for (int i = 0; i < mInputBuffers.length; i++) {
+            mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_INPUT_BUFFERS);
+        }
         mOutputBuffers = mCodec.getOutputBuffers();
-        mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_INPUT_BUFFERS);
     }
 
     @Override
     public final void queueInputBuffer(int index, int offset, int size, long presentationTimeUs, int flags) {
         assertCallbacks();
 
         mInputEnded = (flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
 
         try {
             mCodec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
         } catch (IllegalStateException e) {
             e.printStackTrace();
             mCallbackSender.notifyError(ERROR_CODEC);
             return;
         }
 
+        mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_OUTPUT_BUFFERS);
         mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_INPUT_BUFFERS);
-        mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_OUTPUT_BUFFERS);
     }
 
     @Override
     public final void queueSecureInputBuffer(int index,
                                              int offset,
                                              MediaCodec.CryptoInfo cryptoInfo,
                                              long presentationTimeUs,
                                              int flags) {
@@ -394,17 +394,19 @@ final class JellyBeanAsyncCodec implemen
     @Override
     public void flush() {
         assertCallbacks();
 
         mInputEnded = false;
         mOutputEnded = false;
         cancelPendingTasks();
         mCodec.flush();
-        mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_INPUT_BUFFERS);
+        for (int i = 0; i < mInputBuffers.length; i++) {
+            mBufferPoller.schedulePolling(BufferPoller.MSG_POLL_INPUT_BUFFERS);
+        }
     }
 
     private void cancelPendingTasks() {
         mBufferPoller.cancel();
         mCallbackSender.cancel();
     }
 
     @Override
--- a/mobile/android/base/java/org/mozilla/gecko/promotion/HomeScreenPrompt.java
+++ b/mobile/android/base/java/org/mozilla/gecko/promotion/HomeScreenPrompt.java
@@ -25,16 +25,17 @@ import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.db.UrlAnnotations;
 import org.mozilla.gecko.icons.IconCallback;
 import org.mozilla.gecko.icons.IconResponse;
 import org.mozilla.gecko.icons.Icons;
 import org.mozilla.gecko.Experiments;
+import org.mozilla.gecko.util.ActivityUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
 /**
  * Prompt to promote adding the current website to the home screen.
  */
 public class HomeScreenPrompt extends Locales.LocaleAwareActivity implements IconCallback {
     private static final String EXTRA_TITLE = "title";
     private static final String EXTRA_URL = "url";
@@ -118,33 +119,24 @@ public class HomeScreenPrompt extends Lo
     private void addToHomeScreen() {
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
                 GeckoAppShell.createShortcut(title, url);
 
                 Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, TELEMETRY_EXTRA);
 
-                goToHomeScreen();
+                ActivityUtils.goToHomeScreen(HomeScreenPrompt.this);
+
+                finish();
             }
         });
     }
 
-    /**
-     * Finish this activity and launch the default home screen activity.
-     */
-    private void goToHomeScreen() {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
 
-        intent.addCategory(Intent.CATEGORY_HOME);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        startActivity(intent);
-
-        finish();
-    }
 
     private void loadShortcutIcon() {
         Icons.with(this)
                 .pageUrl(url)
                 .skipNetwork()
                 .skipMemory()
                 .forLauncherIcon()
                 .build()
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
@@ -358,16 +358,24 @@ public class SiteIdentityPopup extends A
                 clearSecurityStateIcon();
 
                 mMixedContentActivity.setVisibility(View.GONE);
                 mLink.setVisibility(View.GONE);
             }
 
             mSecurityState.setText(R.string.identity_connection_insecure);
             mSecurityState.setTextColor(ContextCompat.getColor(mContext, R.color.placeholder_active_grey));
+
+        } else if (siteIdentity.isSecurityException()) {
+
+            mIcon.setImageResource(R.drawable.lock_inactive);
+            setSecurityStateIcon(R.drawable.warning_major, 1);
+            mSecurityState.setText(R.string.identity_connection_insecure);
+            mSecurityState.setTextColor(ContextCompat.getColor(mContext, R.color.placeholder_active_grey));
+
         } else {
             // Connection is secure.
             mIcon.setImageResource(R.drawable.lock_secure);
 
             setSecurityStateIcon(R.drawable.img_check, 2);
             mSecurityState.setTextColor(ContextCompat.getColor(mContext, R.color.affirmative_green));
             mSecurityState.setText(R.string.identity_connection_secure);
 
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java
@@ -354,26 +354,30 @@ public class ToolbarDisplayLayout extend
         final SiteIdentity siteIdentity = tab.getSiteIdentity();
 
         mSiteIdentityPopup.setSiteIdentity(siteIdentity);
 
         final SecurityMode securityMode;
         final MixedMode activeMixedMode;
         final MixedMode displayMixedMode;
         final TrackingMode trackingMode;
+        final boolean securityException;
+
         if (siteIdentity == null) {
             securityMode = SecurityMode.UNKNOWN;
             activeMixedMode = MixedMode.UNKNOWN;
             displayMixedMode = MixedMode.UNKNOWN;
             trackingMode = TrackingMode.UNKNOWN;
+            securityException = false;
         } else {
             securityMode = siteIdentity.getSecurityMode();
             activeMixedMode = siteIdentity.getMixedModeActive();
             displayMixedMode = siteIdentity.getMixedModeDisplay();
             trackingMode = siteIdentity.getTrackingMode();
+            securityException = siteIdentity.isSecurityException();
         }
 
         // This is a bit tricky, but we have one icon and three potential indicators.
         // Default to the identity level
         int imageLevel = securityMode.ordinal();
 
         // about: pages should default to having no icon too (the same as SecurityMode.UNKNOWN), however
         // SecurityMode.CHROMEUI has a different ordinal - hence we need to manually reset it here.
@@ -382,16 +386,18 @@ public class ToolbarDisplayLayout extend
         if (securityMode == SecurityMode.CHROMEUI) {
             imageLevel = LEVEL_DEFAULT_GLOBE; // == SecurityMode.UNKNOWN.ordinal()
         }
 
         // Check to see if any protection was overridden first
         if (AboutPages.isTitlelessAboutPage(tab.getURL())) {
             // We always want to just show a search icon on about:home
             imageLevel = LEVEL_SEARCH_ICON;
+        } else if (securityException) {
+            imageLevel = LEVEL_WARNING_MINOR;
         } else if (trackingMode == TrackingMode.TRACKING_CONTENT_LOADED) {
             imageLevel = LEVEL_SHIELD_DISABLED;
         } else if (trackingMode == TrackingMode.TRACKING_CONTENT_BLOCKED) {
             imageLevel = LEVEL_SHIELD_ENABLED;
         } else if (activeMixedMode == MixedMode.MIXED_CONTENT_LOADED) {
             imageLevel = LEVEL_LOCK_DISABLED;
         } else if (displayMixedMode == MixedMode.MIXED_CONTENT_LOADED) {
             imageLevel = LEVEL_WARNING_MINOR;
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -5913,19 +5913,20 @@ var IdentityHandler = {
     // something in the default case (bug 432241).
     // .hostname can return an empty string in some exceptional cases -
     // hasMatchingOverride does not handle that, so avoid calling it.
     // Updating the tooltip value in those cases isn't critical.
     // FIXME: Fixing bug 646690 would probably makes this check unnecessary
     if (this._lastLocation.hostname &&
         this._overrideService.hasMatchingOverride(this._lastLocation.hostname,
                                                   (this._lastLocation.port || 443),
-                                                  iData.cert, {}, {}))
+                                                  iData.cert, {}, {})) {
       result.verifier = Strings.browser.GetStringFromName("identity.identified.verified_by_you");
-
+      result.securityException = true;
+    }
     return result;
   },
 
   /**
    * Attempt to provide proper IDN treatment for host names
    */
   getEffectiveHost: function getEffectiveHost() {
     if (!this._IDNService)
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/ActivityUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/ActivityUtils.java
@@ -1,16 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * 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/. */
 
 package org.mozilla.gecko.util;
 
 import android.app.Activity;
+import android.content.Intent;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
 import org.mozilla.gecko.AppConstants.Versions;
 
 public class ActivityUtils {
     private ActivityUtils() {
@@ -51,9 +52,21 @@ public class ActivityUtils {
         if (Versions.feature16Plus) {
             final int vis = window.getDecorView().getSystemUiVisibility();
             return (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
         }
 
         final int flags = window.getAttributes().flags;
         return ((flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0);
     }
+
+    /**
+     * Finish this activity and launch the default home screen activity.
+     */
+    public static void goToHomeScreen(Activity activity) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+
+        intent.addCategory(Intent.CATEGORY_HOME);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        activity.startActivity(intent);
+
+    }
 }
--- a/python/compare-locales/compare_locales/__init__.py
+++ b/python/compare-locales/compare_locales/__init__.py
@@ -1,1 +1,1 @@
-version = "1.1"
+version = "1.2.1"
--- a/python/compare-locales/compare_locales/commands.py
+++ b/python/compare-locales/compare_locales/commands.py
@@ -1,154 +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/.
 
 'Commands exposed to commandlines'
 
 import logging
-from optparse import OptionParser, make_option
+from argparse import ArgumentParser
 
+from compare_locales import version
 from compare_locales.paths import EnumerateApp
 from compare_locales.compare import compareApp, compareDirs
 from compare_locales.webapps import compare_web_app
 
 
 class BaseCommand(object):
     """Base class for compare-locales commands.
     This handles command line parsing, and general sugar for setuptools
     entry_points.
     """
-    options = [
-        make_option('-v', '--verbose', action='count', dest='v', default=0,
-                    help='Make more noise'),
-        make_option('-q', '--quiet', action='count', dest='q', default=0,
-                    help='Make less noise'),
-        make_option('-m', '--merge',
-                    help='''Use this directory to stage merged files,
-use {ab_CD} to specify a different directory for each locale'''),
-    ]
-    data_option = make_option('--data', choices=['text', 'exhibit', 'json'],
-                              default='text',
-                              help='''Choose data and format (one of text,
+
+    def __init__(self):
+        self.parser = None
+
+    def get_parser(self):
+        """Get an ArgumentParser, with class docstring as description.
+        """
+        parser = ArgumentParser(description=self.__doc__)
+        parser.add_argument('--version', action='version',
+                            version='%(prog)s ' + version)
+        parser.add_argument('-v', '--verbose', action='count', dest='v',
+                            default=0, help='Make more noise')
+        parser.add_argument('-q', '--quiet', action='count', dest='q',
+                            default=0, help='Make less noise')
+        parser.add_argument('-m', '--merge',
+                            help='''Use this directory to stage merged files,
+use {ab_CD} to specify a different directory for each locale''')
+        return parser
+
+    def add_data_argument(self, parser):
+        parser.add_argument('--data', choices=['text', 'exhibit', 'json'],
+                            default='text',
+                            help='''Choose data and format (one of text,
 exhibit, json); text: (default) Show which files miss which strings, together
 with warnings and errors. Also prints a summary; json: Serialize the internal
 tree, useful for tools. Also always succeeds; exhibit: Serialize the summary
 data in a json useful for Exhibit
 ''')
 
-    def __init__(self):
-        self.parser = None
-
-    def get_parser(self):
-        """Get an OptionParser, with class docstring as usage, and
-        self.options.
-        """
-        parser = OptionParser()
-        parser.set_usage(self.__doc__)
-        for option in self.options:
-            parser.add_option(option)
-        return parser
-
     @classmethod
     def call(cls):
         """Entry_point for setuptools.
         The actual command handling is done in the handle() method of the
         subclasses.
         """
         cmd = cls()
         cmd.handle_()
 
     def handle_(self):
         """The instance part of the classmethod call."""
         self.parser = self.get_parser()
-        (options, args) = self.parser.parse_args()
+        args = self.parser.parse_args()
         # log as verbose or quiet as we want, warn by default
         logging.basicConfig()
         logging.getLogger().setLevel(logging.WARNING -
-                                     (options.v - options.q)*10)
-        observer = self.handle(args, options)
-        print observer.serialize(type=options.data).encode('utf-8', 'replace')
+                                     (args.v - args.q) * 10)
+        observer = self.handle(args)
+        print observer.serialize(type=args.data).encode('utf-8', 'replace')
 
-    def handle(self, args, options):
+    def handle(self, args):
         """Subclasses need to implement this method for the actual
         command handling.
         """
         raise NotImplementedError
 
 
 class CompareLocales(BaseCommand):
-    """usage: %prog [options] l10n.ini l10n_base_dir [locale ...]
-
-Check the localization status of a gecko application.
+    """Check the localization status of a gecko application.
 The first argument is a path to the l10n.ini file for the application,
 followed by the base directory of the localization repositories.
 Then you pass in the list of locale codes you want to compare. If there are
 not locales given, the list of locales will be taken from the all-locales file
 of the application\'s l10n.ini."""
 
-    options = BaseCommand.options + [
-        make_option('--clobber-merge', action="store_true", default=False,
-                    dest='clobber',
-                    help="""WARNING: DATALOSS.
+    def get_parser(self):
+        parser = super(CompareLocales, self).get_parser()
+        parser.add_argument('ini_file', metavar='l10n.ini',
+                            help='INI file for the project')
+        parser.add_argument('l10n_base_dir', metavar='l10n-base-dir',
+                            help='Parent directory of localizations')
+        parser.add_argument('locales', nargs='*', metavar='locale-code',
+                            help='Locale code and top-level directory of '
+                                 'each localization')
+        parser.add_argument('--clobber-merge', action="store_true",
+                            default=False, dest='clobber',
+                            help="""WARNING: DATALOSS.
 Use this option with care. If specified, the merge directory will
 be clobbered for each module. That means, the subdirectory will
 be completely removed, any files that were there are lost.
-Be careful to specify the right merge directory when using this option."""),
-        make_option('-r', '--reference', default='en-US', dest='reference',
-                    help='Explicitly set the reference '
-                    'localization. [default: en-US]'),
-        BaseCommand.data_option
-    ]
+Be careful to specify the right merge directory when using this option.""")
+        parser.add_argument('-r', '--reference', default='en-US',
+                            dest='reference',
+                            help='Explicitly set the reference '
+                            'localization. [default: en-US]')
+        self.add_data_argument(parser)
+        return parser
 
-    def handle(self, args, options):
-        if len(args) < 2:
-            self.parser.error('Need to pass in list of languages')
-        inipath, l10nbase = args[:2]
-        locales = args[2:]
-        app = EnumerateApp(inipath, l10nbase, locales)
-        app.reference = options.reference
+    def handle(self, args):
+        app = EnumerateApp(args.ini_file, args.l10n_base_dir, args.locales)
+        app.reference = args.reference
         try:
-            observer = compareApp(app, merge_stage=options.merge,
-                                  clobber=options.clobber)
+            observer = compareApp(app, merge_stage=args.merge,
+                                  clobber=args.clobber)
         except (OSError, IOError), exc:
             print "FAIL: " + str(exc)
             self.parser.exit(2)
         return observer
 
 
 class CompareDirs(BaseCommand):
-    """usage: %prog [options] reference localization
-
-Check the localization status of a directory tree.
+    """Check the localization status of a directory tree.
 The first argument is a path to the reference data,the second is the
 localization to be tested."""
 
-    options = BaseCommand.options + [
-        BaseCommand.data_option
-    ]
+    def get_parser(self):
+        parser = super(CompareDirs, self).get_parser()
+        parser.add_argument('reference')
+        parser.add_argument('localization')
+        self.add_data_argument(parser)
+        return parser
 
-    def handle(self, args, options):
-        if len(args) != 2:
-            self.parser.error('Reference and localizatino required')
-        reference, locale = args
-        observer = compareDirs(reference, locale, merge_stage=options.merge)
+    def handle(self, args):
+        observer = compareDirs(args.reference, args.localization,
+                               merge_stage=args.merge)
         return observer
 
 
 class CompareWebApp(BaseCommand):
-    """usage: %prog [options] webapp [locale locale]
-
-Check the localization status of a gaia-style web app.
+    """Check the localization status of a gaia-style web app.
 The first argument is the directory of the web app.
 Following arguments explicitly state the locales to test.
 If none are given, test all locales in manifest.webapp or files."""
 
-    options = BaseCommand.options[:-1] + [
-        BaseCommand.data_option]
+    def get_parser(self):
+        parser = super(CompareWebApp, self).get_parser()
+        parser.add_argument('webapp')
+        parser.add_argument('locales', nargs='*', metavar='locale-code',
+                            help='Locale code and top-level directory of '
+                                 'each localization')
+        self.add_data_argument(parser)
+        return parser
 
-    def handle(self, args, options):
-        if len(args) < 1:
-            self.parser.error('Webapp directory required')
-        basedir = args[0]
-        locales = args[1:]
-        observer = compare_web_app(basedir, locales)
+    def handle(self, args):
+        observer = compare_web_app(args.webapp, args.locales)
         return observer
--- a/python/compare-locales/compare_locales/compare.py
+++ b/python/compare-locales/compare_locales/compare.py
@@ -378,45 +378,45 @@ class ContentComparer:
         Results from the notify calls are ignored.
         '''
         self.other_observers.append(obs)
 
     def set_merge_stage(self, merge_stage):
         self.merge_stage = merge_stage
 
     def merge(self, ref_entities, ref_map, ref_file, l10n_file, missing,
-              skips, p):
+              skips, ctx, canMerge, encoding):
         outfile = os.path.join(self.merge_stage, l10n_file.module,
                                l10n_file.file)
         outdir = os.path.dirname(outfile)
         if not os.path.isdir(outdir):
             os.makedirs(outdir)
-        if not p.canMerge:
+        if not canMerge:
             shutil.copyfile(ref_file.fullpath, outfile)
             print "copied reference to " + outfile
             return
         if skips:
             # skips come in ordered by key name, we need them in file order
             skips.sort(key=lambda s: s.span[0])
         trailing = (['\n'] +
                     [ref_entities[ref_map[key]].all for key in missing] +
                     [ref_entities[ref_map[skip.key]].all for skip in skips
                      if not isinstance(skip, parser.Junk)])
         if skips:
             # we need to skip a few errornous blocks in the input, copy by hand
-            f = codecs.open(outfile, 'wb', p.encoding)
+            f = codecs.open(outfile, 'wb', encoding)
             offset = 0
             for skip in skips:
                 chunk = skip.span
-                f.write(p.contents[offset:chunk[0]])
+                f.write(ctx.contents[offset:chunk[0]])
                 offset = chunk[1]
-            f.write(p.contents[offset:])
+            f.write(ctx.contents[offset:])
         else:
             shutil.copyfile(l10n_file.fullpath, outfile)
-            f = codecs.open(outfile, 'ab', p.encoding)
+            f = codecs.open(outfile, 'ab', encoding)
         print "adding to " + outfile
 
         def ensureNewline(s):
             if not s.endswith('\n'):
                 return s + '\n'
             return s
 
         f.write(''.join(map(ensureNewline, trailing)))
@@ -453,30 +453,20 @@ class ContentComparer:
                 return
             self.reference[ref_file] = p.parse()
         ref = self.reference[ref_file]
         ref_list = ref[1].keys()
         ref_list.sort()
         try:
             p.readContents(l10n.getContents())
             l10n_entities, l10n_map = p.parse()
+            l10n_ctx = p.ctx
         except Exception, e:
             self.notify('error', l10n, str(e))
             return
-        lines = []
-
-        def _getLine(offset):
-            if not lines:
-                lines.append(0)
-                for m in self.nl.finditer(p.contents):
-                    lines.append(m.end())
-            for i in xrange(len(lines), 0, -1):
-                if offset >= lines[i - 1]:
-                    return (i, offset - lines[i - 1])
-            return (1, offset)
 
         l10n_list = l10n_map.keys()
         l10n_list.sort()
         ar = AddRemove()
         ar.set_left(ref_list)
         ar.set_right(l10n_list)
         report = missing = obsolete = changed = unchanged = keys = 0
         missings = []
@@ -496,19 +486,20 @@ class ContentComparer:
                 else:
                     # just report
                     report += 1
             elif action == 'add':
                 # obsolete entity or junk
                 if isinstance(l10n_entities[l10n_map[item_or_pair]],
                               parser.Junk):
                     junk = l10n_entities[l10n_map[item_or_pair]]
-                    params = (junk.val,) + junk.span
+                    params = (junk.val,) + junk.position() + junk.position(-1)
                     self.notify('error', l10n,
-                                'Unparsed content "%s" at %d-%d' % params)
+                                'Unparsed content "%s" from line %d colum %d'
+                                ' to line %d column %d' % params)
                     if self.merge_stage is not None:
                         skips.append(junk)
                 elif self.notify('obsoleteEntity', l10n,
                                  item_or_pair) != 'ignore':
                     obsolete += 1
             else:
                 # entity found in both ref and l10n, check for changed
                 entity = item_or_pair[0]
@@ -523,37 +514,40 @@ class ContentComparer:
                     else:
                         self.doChanged(ref_file, refent, l10nent)
                         changed += 1
                         # run checks:
                 if checker:
                     for tp, pos, msg, cat in checker.check(refent, l10nent):
                         # compute real src position, if first line,
                         # col needs adjustment
-                        _l, _offset = _getLine(l10nent.val_span[0])
                         if isinstance(pos, tuple):
+                            _l, col = l10nent.value_position()
                             # line, column
                             if pos[0] == 1:
-                                col = pos[1] + _offset
+                                col = col + pos[1]
                             else:
                                 col = pos[1]
-                            _l += pos[0] - 1
+                                _l += pos[0] - 1
                         else:
-                            _l, col = _getLine(l10nent.val_span[0] + pos)
-                            # skip error entities when merging
+                            _l, col = l10nent.value_position(pos)
+                        # skip error entities when merging
                         if tp == 'error' and self.merge_stage is not None:
                             skips.append(l10nent)
                         self.notify(tp, l10n,
                                     u"%s at line %d, column %d for %s" %
                                     (msg, _l, col, refent.key))
                 pass
         if missing:
             self.notify('missing', l10n, missing)
         if self.merge_stage is not None and (missings or skips):
-            self.merge(ref[0], ref[1], ref_file, l10n, missings, skips, p)
+            self.merge(
+                ref[0], ref[1], ref_file,
+                l10n, missings, skips, l10n_ctx,
+                p.canMerge, p.encoding)
         if report:
             self.notify('report', l10n, report)
         if obsolete:
             self.notify('obsolete', l10n, obsolete)
         if changed:
             self.notify('changed', l10n, changed)
         if unchanged:
             self.notify('unchanged', l10n, unchanged)
--- a/python/compare-locales/compare_locales/parser.py
+++ b/python/compare-locales/compare_locales/parser.py
@@ -1,199 +1,298 @@
 # 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/.
 
 import re
+import bisect
 import codecs
 import logging
-from HTMLParser import HTMLParser
 
 __constructors = []
 
 
-class Entity(object):
+class EntityBase(object):
     '''
     Abstraction layer for a localizable entity.
     Currently supported are grammars of the form:
 
     1: pre white space
-    2: pre comments
-    3: entity definition
-    4: entity key (name)
-    5: entity value
-    6: post comment (and white space) in the same line (dtd only)
+    2: entity definition
+    3: entity key (name)
+    4: entity value
+    5: post white space
                                                  <--[1]
-    <!-- pre comments -->                        <--[2]
-    <!ENTITY key "value"> <!-- comment -->
+    <!ENTITY key "value">
 
-    <-------[3]---------><------[6]------>
+    <-------[2]--------->
     '''
-    def __init__(self, contents, pp,
-                 span, pre_ws_span, pre_comment_span, def_span,
+    def __init__(self, ctx, pp, pre_comment,
+                 span, pre_ws_span, def_span,
                  key_span, val_span, post_span):
-        self.contents = contents
+        self.ctx = ctx
         self.span = span
         self.pre_ws_span = pre_ws_span
-        self.pre_comment_span = pre_comment_span
         self.def_span = def_span
         self.key_span = key_span
         self.val_span = val_span
         self.post_span = post_span
         self.pp = pp
+        self.pre_comment = pre_comment
         pass
 
+    def position(self, offset=0):
+        """Get the 1-based line and column of the character
+        with given offset into the Entity.
+
+        If offset is negative, return the end of the Entity.
+        """
+        if offset < 0:
+            pos = self.span[1]
+        else:
+            pos = self.span[0] + offset
+        return self.ctx.lines(pos)[0]
+
+    def value_position(self, offset=0):
+        """Get the 1-based line and column of the character
+        with given offset into the value.
+
+        If offset is negative, return the end of the value.
+        """
+        if offset < 0:
+            pos = self.val_span[1]
+        else:
+            pos = self.val_span[0] + offset
+        return self.ctx.lines(pos)[0]
+
     # getter helpers
 
     def get_all(self):
-        return self.contents[self.span[0]:self.span[1]]
+        return self.ctx.contents[self.span[0]:self.span[1]]
 
     def get_pre_ws(self):
-        return self.contents[self.pre_ws_span[0]:self.pre_ws_span[1]]
-
-    def get_pre_comment(self):
-        return self.contents[self.pre_comment_span[0]:
-                             self.pre_comment_span[1]]
+        return self.ctx.contents[self.pre_ws_span[0]:self.pre_ws_span[1]]
 
     def get_def(self):
-        return self.contents[self.def_span[0]:self.def_span[1]]
+        return self.ctx.contents[self.def_span[0]:self.def_span[1]]
 
     def get_key(self):
-        return self.contents[self.key_span[0]:self.key_span[1]]
+        return self.ctx.contents[self.key_span[0]:self.key_span[1]]
 
     def get_val(self):
-        return self.pp(self.contents[self.val_span[0]:self.val_span[1]])
+        return self.pp(self.ctx.contents[self.val_span[0]:self.val_span[1]])
 
     def get_raw_val(self):
-        return self.contents[self.val_span[0]:self.val_span[1]]
+        return self.ctx.contents[self.val_span[0]:self.val_span[1]]
 
     def get_post(self):
-        return self.contents[self.post_span[0]:self.post_span[1]]
+        return self.ctx.contents[self.post_span[0]:self.post_span[1]]
 
     # getters
 
     all = property(get_all)
     pre_ws = property(get_pre_ws)
-    pre_comment = property(get_pre_comment)
     definition = property(get_def)
     key = property(get_key)
     val = property(get_val)
     raw_val = property(get_raw_val)
     post = property(get_post)
 
     def __repr__(self):
         return self.key
 
 
+class Entity(EntityBase):
+    pass
+
+
+class Comment(EntityBase):
+    def __init__(self, ctx, span, pre_ws_span, def_span,
+                 post_span):
+        self.ctx = ctx
+        self.span = span
+        self.pre_ws_span = pre_ws_span
+        self.def_span = def_span
+        self.post_span = post_span
+        self.pp = lambda v: v
+
+    @property
+    def key(self):
+        return None
+
+    @property
+    def val(self):
+        return None
+
+    def __repr__(self):
+        return self.all
+
+
 class Junk(object):
     '''
     An almost-Entity, representing junk data that we didn't parse.
     This way, we can signal bad content as stuff we don't understand.
     And the either fix that, or report real bugs in localizations.
     '''
     junkid = 0
 
-    def __init__(self, contents, span):
-        self.contents = contents
+    def __init__(self, ctx, span):
+        self.ctx = ctx
         self.span = span
-        self.pre_ws = self.pre_comment = self.definition = self.post = ''
+        self.pre_ws = self.definition = self.post = ''
         self.__class__.junkid += 1
         self.key = '_junk_%d_%d-%d' % (self.__class__.junkid, span[0], span[1])
 
+    def position(self, offset=0):
+        """Get the 1-based line and column of the character
+        with given offset into the Entity.
+
+        If offset is negative, return the end of the Entity.
+        """
+        if offset < 0:
+            pos = self.span[1]
+        else:
+            pos = self.span[0] + offset
+        return self.ctx.lines(pos)[0]
+
     # getter helpers
     def get_all(self):
-        return self.contents[self.span[0]:self.span[1]]
+        return self.ctx.contents[self.span[0]:self.span[1]]
 
     # getters
     all = property(get_all)
     val = property(get_all)
 
     def __repr__(self):
         return self.key
 
 
+class Whitespace(EntityBase):
+    '''Entity-like object representing an empty file with whitespace,
+    if allowed
+    '''
+    def __init__(self, ctx, span):
+        self.ctx = ctx
+        self.key_span = self.val_span = self.span = span
+        self.def_span = self.pre_ws_span = (span[0], span[0])
+        self.post_span = (span[1], span[1])
+        self.pp = lambda v: v
+
+    def __repr__(self):
+        return self.raw_val
+
+
 class Parser:
     canMerge = True
+    tail = re.compile('\s+\Z')
+
+    class Context(object):
+        "Fixture for content and line numbers"
+        def __init__(self, contents):
+            self.contents = contents
+            self._lines = None
+
+        def lines(self, *positions):
+            # return line and column tuples, 1-based
+            if self._lines is None:
+                nl = re.compile('\n', re.M)
+                self._lines = [m.end()
+                               for m in nl.finditer(self.contents)]
+            line_nrs = [bisect.bisect(self._lines, p) for p in positions]
+            # compute columns
+            pos_ = [
+                (1 + line, 1 + p - (self._lines[line-1] if line else 0))
+                for line, p in zip(line_nrs, positions)]
+            return pos_
 
     def __init__(self):
         if not hasattr(self, 'encoding'):
             self.encoding = 'utf-8'
-        pass
+        self.ctx = None
+        self.last_comment = None
 
     def readFile(self, file):
-        f = codecs.open(file, 'r', self.encoding)
-        try:
-            self.contents = f.read()
-        except UnicodeDecodeError, e:
-            (logging.getLogger('locales')
-                    .error("Can't read file: " + file + '; ' + str(e)))
-            self.contents = u''
-        f.close()
+        with open(file, 'rU') as f:
+            try:
+                self.readContents(f.read())
+            except UnicodeDecodeError, e:
+                (logging.getLogger('locales')
+                        .error("Can't read file: " + file + '; ' + str(e)))
 
     def readContents(self, contents):
-        (self.contents, length) = codecs.getdecoder(self.encoding)(contents)
+        '''Read contents and create parsing context.
+
+        contents are in native encoding, but with normalized line endings.
+        '''
+        (contents, length) = codecs.getdecoder(self.encoding)(contents)
+        self.ctx = Parser.Context(contents)
 
     def parse(self):
         l = []
         m = {}
         for e in self:
             m[e.key] = len(l)
             l.append(e)
         return (l, m)
 
     def postProcessValue(self, val):
         return val
 
     def __iter__(self):
-        contents = self.contents
+        return self.walk(onlyEntities=True)
+
+    def walk(self, onlyEntities=False):
+        if not self.ctx:
+            # loading file failed, or we just didn't load anything
+            return
+        ctx = self.ctx
+        contents = ctx.contents
         offset = 0
-        self.header, offset = self.getHeader(contents, offset)
-        self.footer = ''
-        entity, offset = self.getEntity(contents, offset)
+        entity, offset = self.getEntity(ctx, offset)
         while entity:
-            yield entity
-            entity, offset = self.getEntity(contents, offset)
-        f = self.reFooter.match(contents, offset)
-        if f:
-            self.footer = f.group()
-            offset = f.end()
+            if (not onlyEntities or
+                    type(entity) is Entity or
+                    type(entity) is Junk):
+                yield entity
+            entity, offset = self.getEntity(ctx, offset)
         if len(contents) > offset:
-            yield Junk(contents, (offset, len(contents)))
-        pass
+            yield Junk(ctx, (offset, len(contents)))
 
-    def getHeader(self, contents, offset):
-        header = ''
-        h = self.reHeader.match(contents)
-        if h:
-            header = h.group()
-            offset = h.end()
-        return (header, offset)
-
-    def getEntity(self, contents, offset):
-        m = self.reKey.match(contents, offset)
+    def getEntity(self, ctx, offset):
+        m = self.reKey.match(ctx.contents, offset)
         if m:
             offset = m.end()
-            entity = self.createEntity(contents, m)
+            entity = self.createEntity(ctx, m)
             return (entity, offset)
-        # first check if footer has a non-empty match,
-        # 'cause then we don't find junk
-        m = self.reFooter.match(contents, offset)
-        if m and m.end() > offset:
-            return (None, offset)
-        m = self.reKey.search(contents, offset)
+        m = self.reComment.match(ctx.contents, offset)
         if m:
-            # we didn't match, but search, so there's junk between offset
-            # and start. We'll match() on the next turn
-            junkend = m.start()
-            return (Junk(contents, (offset, junkend)), junkend)
-        return (None, offset)
+            offset = m.end()
+            self.last_comment = Comment(ctx, *[m.span(i) for i in xrange(4)])
+            return (self.last_comment, offset)
+        return self.getTrailing(ctx, offset, self.reKey, self.reComment)
 
-    def createEntity(self, contents, m):
-        return Entity(contents, self.postProcessValue,
-                      *[m.span(i) for i in xrange(7)])
+    def getTrailing(self, ctx, offset, *expressions):
+        junkend = None
+        for exp in expressions:
+            m = exp.search(ctx.contents, offset)
+            if m:
+                junkend = min(junkend, m.start()) if junkend else m.start()
+        if junkend is None:
+            if self.tail.match(ctx.contents, offset):
+                white_end = len(ctx.contents)
+                return (Whitespace(ctx, (offset, white_end)), white_end)
+            else:
+                return (None, offset)
+        return (Junk(ctx, (offset, junkend)), junkend)
+
+    def createEntity(self, ctx, m):
+        pre_comment = unicode(self.last_comment) if self.last_comment else ''
+        self.last_comment = ''
+        return Entity(ctx, self.postProcessValue, pre_comment,
+                      *[m.span(i) for i in xrange(6)])
 
 
 def getParser(path):
     for item in __constructors:
         if re.search(item[0], path):
             return item[1]
     raise UserWarning("Cannot find Parser")
 
@@ -225,297 +324,249 @@ class DTDParser(Parser):
         u'\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F' + \
         u'\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD'
     # + \U00010000-\U000EFFFF seems to be unsupported in python
 
     # NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 |
     #     [#x0300-#x036F] | [#x203F-#x2040]
     NameChar = NameStartChar + ur'\-\.0-9' + u'\xB7\u0300-\u036F\u203F-\u2040'
     Name = '[' + NameStartChar + '][' + NameChar + ']*'
-    reKey = re.compile('(?:(?P<pre>\s*)(?P<precomment>(?:' + XmlComment +
-                       '\s*)*)(?P<entity><!ENTITY\s+(?P<key>' + Name +
+    reKey = re.compile('(?:(?P<pre>\s*)(?P<entity><!ENTITY\s+(?P<key>' + Name +
                        ')\s+(?P<val>\"[^\"]*\"|\'[^\']*\'?)\s*>)'
-                       '(?P<post>[ \t]*(?:' + XmlComment + '\s*)*\n?)?)',
-                       re.DOTALL)
+                       '(?P<post>\s*)?)',
+                       re.DOTALL | re.M)
     # add BOM to DTDs, details in bug 435002
-    reHeader = re.compile(u'^\ufeff?'
-                          u'(\s*<!--.*(http://mozilla.org/MPL/2.0/|'
-                          u'LICENSE BLOCK)([^-]+-)*[^-]+-->)?', re.S)
-    reFooter = re.compile('\s*(<!--([^-]+-)*[^-]+-->\s*)*$')
-    rePE = re.compile('(?:(\s*)((?:' + XmlComment + '\s*)*)'
-                      '(<!ENTITY\s+%\s+(' + Name +
-                      ')\s+SYSTEM\s+(\"[^\"]*\"|\'[^\']*\')\s*>\s*%' + Name +
-                      ';)([ \t]*(?:' + XmlComment + '\s*)*\n?)?)')
+    reHeader = re.compile(u'^\ufeff')
+    reComment = re.compile('(\s*)(<!--(-?[%s])*?-->)(\s*)' % CharMinusDash,
+                           re.S)
+    rePE = re.compile(u'(?:(\s*)'
+                      u'(<!ENTITY\s+%\s+(' + Name +
+                      u')\s+SYSTEM\s+(\"[^\"]*\"|\'[^\']*\')\s*>\s*%' + Name +
+                      u';)([ \t]*(?:' + XmlComment + u'\s*)*\n?)?)')
 
-    def getEntity(self, contents, offset):
+    def getEntity(self, ctx, offset):
         '''
         Overload Parser.getEntity to special-case ParsedEntities.
         Just check for a parsed entity if that method claims junk.
 
         <!ENTITY % foo SYSTEM "url">
         %foo;
         '''
-        entity, inneroffset = Parser.getEntity(self, contents, offset)
+        if offset is 0 and self.reHeader.match(ctx.contents):
+            offset += 1
+        entity, inneroffset = Parser.getEntity(self, ctx, offset)
         if (entity and isinstance(entity, Junk)) or entity is None:
-            m = self.rePE.match(contents, offset)
+            m = self.rePE.match(ctx.contents, offset)
             if m:
                 inneroffset = m.end()
-                entity = Entity(contents, self.postProcessValue,
-                                *[m.span(i) for i in xrange(7)])
+                self.last_comment = ''
+                entity = Entity(ctx, self.postProcessValue, '',
+                                *[m.span(i) for i in xrange(6)])
         return (entity, inneroffset)
 
-    def createEntity(self, contents, m):
+    def createEntity(self, ctx, m):
         valspan = m.span('val')
         valspan = (valspan[0]+1, valspan[1]-1)
-        return Entity(contents, self.postProcessValue, m.span(),
-                      m.span('pre'), m.span('precomment'),
+        pre_comment = unicode(self.last_comment) if self.last_comment else ''
+        self.last_comment = ''
+        return Entity(ctx, self.postProcessValue, pre_comment,
+                      m.span(),
+                      m.span('pre'),
                       m.span('entity'), m.span('key'), valspan,
                       m.span('post'))
 
 
 class PropertiesParser(Parser):
     escape = re.compile(r'\\((?P<uni>u[0-9a-fA-F]{1,4})|'
                         '(?P<nl>\n\s*)|(?P<single>.))', re.M)
     known_escapes = {'n': '\n', 'r': '\r', 't': '\t', '\\': '\\'}
 
     def __init__(self):
         self.reKey = re.compile('^(\s*)'
-                                '((?:[#!].*?\n\s*)*)'
                                 '([^#!\s\n][^=:\n]*?)\s*[:=][ \t]*', re.M)
-        self.reHeader = re.compile('^\s*([#!].*\s*)+')
-        self.reFooter = re.compile('\s*([#!].*\s*)*$')
+        self.reComment = re.compile('(\s*)(((?:[#!][^\n]*\n?)+))', re.M)
         self._escapedEnd = re.compile(r'\\+$')
-        self._trailingWS = re.compile(r'[ \t]*$')
+        self._trailingWS = re.compile(r'\s*(?:\n|\Z)', re.M)
         Parser.__init__(self)
 
-    def getHeader(self, contents, offset):
-        header = ''
-        h = self.reHeader.match(contents, offset)
-        if h:
-            candidate = h.group()
-            if 'http://mozilla.org/MPL/2.0/' in candidate or \
-                    'LICENSE BLOCK' in candidate:
-                header = candidate
-                offset = h.end()
-        return (header, offset)
-
-    def getEntity(self, contents, offset):
+    def getEntity(self, ctx, offset):
         # overwritten to parse values line by line
+        contents = ctx.contents
+        m = self.reComment.match(contents, offset)
+        if m:
+            spans = [m.span(i) for i in xrange(3)]
+            start_trailing = offset = m.end()
+            while offset < len(contents):
+                m = self._trailingWS.match(contents, offset)
+                if not m:
+                    break
+                offset = m.end()
+            spans.append((start_trailing, offset))
+            self.last_comment = Comment(ctx, *spans)
+            return (self.last_comment, offset)
         m = self.reKey.match(contents, offset)
         if m:
-            offset = m.end()
+            startline = offset = m.end()
             while True:
                 endval = nextline = contents.find('\n', offset)
                 if nextline == -1:
                     endval = offset = len(contents)
                     break
                 # is newline escaped?
                 _e = self._escapedEnd.search(contents, offset, nextline)
                 offset = nextline + 1
                 if _e is None:
                     break
                 # backslashes at end of line, if 2*n, not escaped
                 if len(_e.group()) % 2 == 0:
                     break
+                startline = offset
             # strip trailing whitespace
-            ws = self._trailingWS.search(contents, m.end(), offset)
+            ws = self._trailingWS.search(contents, startline)
             if ws:
-                endval -= ws.end() - ws.start()
-            entity = Entity(contents, self.postProcessValue,
+                endval = ws.start()
+                offset = ws.end()
+            pre_comment = (unicode(self.last_comment) if self.last_comment
+                           else '')
+            self.last_comment = ''
+            entity = Entity(ctx, self.postProcessValue, pre_comment,
                             (m.start(), offset),   # full span
                             m.span(1),  # leading whitespan
-                            m.span(2),  # leading comment span
-                            (m.start(3), offset),   # entity def span
-                            m.span(3),   # key span
+                            (m.start(2), offset),   # entity def span
+                            m.span(2),   # key span
                             (m.end(), endval),   # value span
                             (offset, offset))  # post comment span, empty
             return (entity, offset)
-        m = self.reKey.search(contents, offset)
-        if m:
-            # we didn't match, but search, so there's junk between offset
-            # and start. We'll match() on the next turn
-            junkend = m.start()
-            return (Junk(contents, (offset, junkend)), junkend)
-        return (None, offset)
+        return self.getTrailing(ctx, offset, self.reKey, self.reComment)
 
     def postProcessValue(self, val):
 
         def unescape(m):
             found = m.groupdict()
             if found['uni']:
                 return unichr(int(found['uni'][1:], 16))
             if found['nl']:
                 return ''
             return self.known_escapes.get(found['single'], found['single'])
         val = self.escape.sub(unescape, val)
         return val
 
 
+class DefinesInstruction(EntityBase):
+    '''Entity-like object representing processing instructions in inc files
+    '''
+    def __init__(self, ctx, span, pre_ws_span, def_span, val_span, post_span):
+        self.ctx = ctx
+        self.span = span
+        self.pre_ws_span = pre_ws_span
+        self.def_span = def_span
+        self.key_span = self.val_span = val_span
+        self.post_span = post_span
+        self.pp = lambda v: v
+
+    def __repr__(self):
+        return self.raw_val
+
+
 class DefinesParser(Parser):
     # can't merge, #unfilter needs to be the last item, which we don't support
     canMerge = False
+    tail = re.compile(r'(?!)')  # never match
 
     def __init__(self):
-        self.reKey = re.compile('^(\s*)((?:^#(?!define\s).*\s*)*)'
-                                '(#define[ \t]+(\w+)[ \t]+(.*?))([ \t]*$\n?)',
+        self.reComment = re.compile(
+            '((?:[ \t]*\n)*)'
+            '((?:^# .*?(?:\n|\Z))+)'
+            '((?:[ \t]*(?:\n|\Z))*)', re.M)
+        self.reKey = re.compile('((?:[ \t]*\n)*)'
+                                '(#define[ \t]+(\w+)(?:[ \t](.*?))?(?:\n|\Z))'
+                                '((?:[ \t]*(?:\n|\Z))*)',
                                 re.M)
-        self.reHeader = re.compile('^\s*(#(?!define\s).*\s*)*')
-        self.reFooter = re.compile('\s*(#(?!define\s).*\s*)*$', re.M)
+        self.rePI = re.compile('((?:[ \t]*\n)*)'
+                               '(#(\w+)[ \t]+(.*?)(?:\n|\Z))'
+                               '((?:[ \t]*(?:\n|\Z))*)',
+                               re.M)
         Parser.__init__(self)
 
+    def getEntity(self, ctx, offset):
+        contents = ctx.contents
+        m = self.reComment.match(contents, offset)
+        if m:
+            offset = m.end()
+            self.last_comment = Comment(ctx, *[m.span(i) for i in xrange(4)])
+            return (self.last_comment, offset)
+        m = self.reKey.match(contents, offset)
+        if m:
+            offset = m.end()
+            return (self.createEntity(ctx, m), offset)
+        m = self.rePI.match(contents, offset)
+        if m:
+            offset = m.end()
+            return (DefinesInstruction(ctx, *[m.span(i) for i in xrange(5)]),
+                    offset)
+        return self.getTrailing(ctx, offset,
+                                self.reComment, self.reKey, self.rePI)
+
+
+class IniSection(EntityBase):
+    '''Entity-like object representing sections in ini files
+    '''
+    def __init__(self, ctx, span, pre_ws_span, def_span, val_span, post_span):
+        self.ctx = ctx
+        self.span = span
+        self.pre_ws_span = pre_ws_span
+        self.def_span = def_span
+        self.key_span = self.val_span = val_span
+        self.post_span = post_span
+        self.pp = lambda v: v
+
+    def __repr__(self):
+        return self.raw_val
+
 
 class IniParser(Parser):
     '''
     Parse files of the form:
     # initial comment
     [cat]
     whitespace*
     #comment
     string=value
     ...
     '''
     def __init__(self):
-        self.reHeader = re.compile('^((?:\s*|[;#].*)\n)*\[.+?\]\n', re.M)
-        self.reKey = re.compile('(\s*)((?:[;#].*\n\s*)*)((.+?)=(.*))(\n?)')
-        self.reFooter = re.compile('\s*([;#].*\s*)*$')
+        self.reComment = re.compile(
+            '((?:[ \t]*\n)*)'
+            '((?:^[;#].*?(?:\n|\Z))+)'
+            '((?:[ \t]*(?:\n|\Z))*)', re.M)
+        self.reSection = re.compile(
+            '((?:[ \t]*\n)*)'
+            '(\[(.*?)\])'
+            '((?:[ \t]*(?:\n|\Z))*)', re.M)
+        self.reKey = re.compile(
+            '((?:[ \t]*\n)*)'
+            '((.+?)=(.*))'
+            '((?:[ \t]*(?:\n|\Z))*)', re.M)
         Parser.__init__(self)
 
-
-DECL, COMMENT, START, END, CONTENT = range(5)
-
-
-class BookmarksParserInner(HTMLParser):
-
-    class Token(object):
-        _type = None
-        content = ''
-
-        def __str__(self):
-            return self.content
-
-    class DeclToken(Token):
-        _type = DECL
-
-        def __init__(self, decl):
-            self.content = decl
-            pass
-
-        def __str__(self):
-            return '<!%s>' % self.content
-        pass
-
-    class CommentToken(Token):
-        _type = COMMENT
-
-        def __init__(self, comment):
-            self.content = comment
-            pass
-
-        def __str__(self):
-            return '<!--%s-->' % self.content
-        pass
-
-    class StartToken(Token):
-        _type = START
-
-        def __init__(self, tag, attrs, content):
-            self.tag = tag
-            self.attrs = dict(attrs)
-            self.content = content
-            pass
-        pass
-
-    class EndToken(Token):
-        _type = END
-
-        def __init__(self, tag):
-            self.tag = tag
-            pass
-
-        def __str__(self):
-            return '</%s>' % self.tag.upper()
-        pass
-
-    class ContentToken(Token):
-        _type = CONTENT
-
-        def __init__(self, content):
-            self.content = content
-            pass
-        pass
-
-    def __init__(self):
-        HTMLParser.__init__(self)
-        self.tokens = []
-
-    def parse(self, contents):
-        self.tokens = []
-        self.feed(contents)
-        self.close()
-        return self.tokens
-
-    # Called when we hit an end DL tag to reset the folder selections
-    def handle_decl(self, decl):
-        self.tokens.append(self.DeclToken(decl))
-
-    # Called when we hit an end DL tag to reset the folder selections
-    def handle_comment(self, comment):
-        self.tokens.append(self.CommentToken(comment))
-
-    def handle_starttag(self, tag, attrs):
-        self.tokens.append(self.StartToken(tag, attrs,
-                                           self.get_starttag_text()))
-
-    # Called when text data is encountered
-    def handle_data(self, data):
-        if self.tokens[-1]._type == CONTENT:
-            self.tokens[-1].content += data
-        else:
-            self.tokens.append(self.ContentToken(data))
-
-    def handle_charref(self, data):
-        self.handle_data('&#%s;' % data)
-
-    def handle_entityref(self, data):
-        self.handle_data('&%s;' % data)
-
-    # Called when we hit an end DL tag to reset the folder selections
-    def handle_endtag(self, tag):
-        self.tokens.append(self.EndToken(tag))
-
-
-class BookmarksParser(Parser):
-    canMerge = False
-
-    class BMEntity(object):
-        def __init__(self, key, val):
-            self.key = key
-            self.val = val
-
-    def __iter__(self):
-        p = BookmarksParserInner()
-        tks = p.parse(self.contents)
-        i = 0
-        k = []
-        for i in xrange(len(tks)):
-            t = tks[i]
-            if t._type == START:
-                k.append(t.tag)
-                keys = t.attrs.keys()
-                keys.sort()
-                for attrname in keys:
-                    yield self.BMEntity('.'.join(k) + '.@' + attrname,
-                                        t.attrs[attrname])
-                if i + 1 < len(tks) and tks[i+1]._type == CONTENT:
-                    i += 1
-                    t = tks[i]
-                    v = t.content.strip()
-                    if v:
-                        yield self.BMEntity('.'.join(k), v)
-            elif t._type == END:
-                k.pop()
+    def getEntity(self, ctx, offset):
+        contents = ctx.contents
+        m = self.reComment.match(contents, offset)
+        if m:
+            offset = m.end()
+            self.last_comment = Comment(ctx, *[m.span(i) for i in xrange(4)])
+            return (self.last_comment, offset)
+        m = self.reSection.match(contents, offset)
+        if m:
+            offset = m.end()
+            return (IniSection(ctx, *[m.span(i) for i in xrange(5)]), offset)
+        m = self.reKey.match(contents, offset)
+        if m:
+            offset = m.end()
+            return (self.createEntity(ctx, m), offset)
+        return self.getTrailing(ctx, offset,
+                                self.reComment, self.reSection, self.reKey)
 
 
 __constructors = [('\\.dtd$', DTDParser()),
                   ('\\.properties$', PropertiesParser()),
                   ('\\.ini$', IniParser()),
-                  ('\\.inc$', DefinesParser()),
-                  ('bookmarks\\.html$', BookmarksParser())]
+                  ('\\.inc$', DefinesParser())]
--- a/python/compare-locales/compare_locales/tests/__init__.py
+++ b/python/compare-locales/compare_locales/tests/__init__.py
@@ -4,28 +4,28 @@
 
 '''Mixins for parser tests.
 '''
 
 from itertools import izip_longest
 from pkg_resources import resource_string
 import re
 
-from compare_locales.parser import getParser
+from compare_locales import parser
 
 
 class ParserTestMixin():
     '''Utility methods used by the parser tests.
     '''
     filename = None
 
     def setUp(self):
         '''Create a parser for this test.
         '''
-        self.parser = getParser(self.filename)
+        self.parser = parser.getParser(self.filename)
 
     def tearDown(self):
         'tear down this test'
         del self.parser
 
     def resource(self, name):
         testcontent = resource_string(__name__, 'data/' + name)
         # fake universal line endings
@@ -33,17 +33,18 @@ class ParserTestMixin():
         return testcontent
 
     def _test(self, content, refs):
         '''Helper to test the parser.
         Compares the result of parsing content with the given list
         of reference keys and values.
         '''
         self.parser.readContents(content)
-        entities = [entity for entity in self.parser]
+        entities = list(self.parser.walk())
         for entity, ref in izip_longest(entities, refs):
-            self.assertTrue(entity, 'excess reference entity')
-            self.assertTrue(ref, 'excess parsed entity')
-            self.assertEqual(entity.val, ref[1])
-            if ref[0].startswith('_junk'):
-                self.assertTrue(re.match(ref[0], entity.key))
+            self.assertTrue(entity, 'excess reference entity ' + unicode(ref))
+            self.assertTrue(ref, 'excess parsed entity ' + unicode(entity))
+            if isinstance(entity, parser.Entity):
+                self.assertEqual(entity.key, ref[0])
+                self.assertEqual(entity.val, ref[1])
             else:
-                self.assertEqual(entity.key, ref[0])
+                self.assertEqual(type(entity).__name__, ref[0])
+                self.assertIn(ref[1], entity.all)
--- a/python/compare-locales/compare_locales/tests/test_checks.py
+++ b/python/compare-locales/compare_locales/tests/test_checks.py
@@ -1,17 +1,17 @@
 # -*- coding: 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/.
 
 import unittest
 
 from compare_locales.checks import getChecker
-from compare_locales.parser import getParser, Entity
+from compare_locales.parser import getParser, Parser, Entity
 from compare_locales.paths import File
 
 
 class BaseHelper(unittest.TestCase):
     file = None
     refContent = None
 
     def setUp(self):
@@ -234,24 +234,26 @@ class TestAndroid(unittest.TestCase):
     we're passing in a DTD file in the embedding/android module.
     """
     apos_msg = u"Apostrophes in Android DTDs need escaping with \\' or " + \
                u"\\u0027, or use \u2019, or put string in quotes."
     quot_msg = u"Quotes in Android DTDs need escaping with \\\" or " + \
                u"\\u0022, or put string in apostrophes."
 
     def getEntity(self, v):
-        return Entity(v, lambda s: s, (0, len(v)), (), (0, 0), (), (),
+        ctx = Parser.Context(v)
+        return Entity(ctx, lambda s: s, '', (0, len(v)), (), (), (),
                       (0, len(v)), ())
 
     def getDTDEntity(self, v):
         v = v.replace('"', '&quot;')
-        return Entity('<!ENTITY foo "%s">' % v,
-                      lambda s: s,
-                      (0, len(v) + 16), (), (0, 0), (), (9, 12),
+        ctx = Parser.Context('<!ENTITY foo "%s">' % v)
+        return Entity(ctx,
+                      lambda s: s, '',
+                      (0, len(v) + 16), (), (), (9, 12),
                       (14, len(v) + 14), ())
 
     def test_android_dtd(self):
         """Testing the actual android checks. The logic is involved,
         so this is a lot of nitty gritty detail tests.
         """
         f = File("embedding/android/strings.dtd", "strings.dtd",
                  "embedding/android")
new file mode 100644
--- /dev/null
+++ b/python/compare-locales/compare_locales/tests/test_defines.py
@@ -0,0 +1,95 @@
+# -*- coding: 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/.
+
+import unittest
+
+from compare_locales.tests import ParserTestMixin
+
+
+mpl2 = '''\
+# 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/.
+'''
+
+
+class TestDefinesParser(ParserTestMixin, unittest.TestCase):
+
+    filename = 'defines.inc'
+
+    def testBrowser(self):
+        self._test(mpl2 + '''#filter emptyLines
+
+#define MOZ_LANGPACK_CREATOR mozilla.org
+
+# If non-English locales wish to credit multiple contributors, uncomment this
+# variable definition and use the format specified.
+# #define MOZ_LANGPACK_CONTRIBUTORS <em:contributor>Joe Solon</em:contributor>
+
+#unfilter emptyLines
+
+''', (
+            ('Comment', mpl2),
+            ('DefinesInstruction', 'filter emptyLines'),
+            ('MOZ_LANGPACK_CREATOR', 'mozilla.org'),
+            ('Comment', '#define'),
+            ('DefinesInstruction', 'unfilter emptyLines')))
+
+    def testBrowserWithContributors(self):
+        self._test(mpl2 + '''#filter emptyLines
+
+#define MOZ_LANGPACK_CREATOR mozilla.org
+
+# If non-English locales wish to credit multiple contributors, uncomment this
+# variable definition and use the format specified.
+#define MOZ_LANGPACK_CONTRIBUTORS <em:contributor>Joe Solon</em:contributor>
+
+#unfilter emptyLines
+
+''', (
+            ('Comment', mpl2),
+            ('DefinesInstruction', 'filter emptyLines'),
+            ('MOZ_LANGPACK_CREATOR', 'mozilla.org'),
+            ('Comment', 'non-English'),
+            ('MOZ_LANGPACK_CONTRIBUTORS',
+             '<em:contributor>Joe Solon</em:contributor>'),
+            ('DefinesInstruction', 'unfilter emptyLines')))
+
+    def testCommentWithNonAsciiCharacters(self):
+        self._test(mpl2 + '''#filter emptyLines
+
+# e.g. #define seamonkey_l10n <DT><A HREF="http://www.mozilla.cz/produkty/seamonkey/">SeaMonkey v češtině</a>
+#define seamonkey_l10n_long
+
+#unfilter emptyLines
+
+''', (
+            ('Comment', mpl2),
+            ('DefinesInstruction', 'filter emptyLines'),
+            ('Comment', u'češtině'),
+            ('seamonkey_l10n_long', ''),
+            ('DefinesInstruction', 'unfilter emptyLines')))
+
+    def testToolkit(self):
+        self._test('''#define MOZ_LANG_TITLE English (US)
+''', (
+            ('MOZ_LANG_TITLE', 'English (US)'),))
+
+    def testToolkitEmpty(self):
+        self._test('', tuple())
+
+    def test_empty_file(self):
+        '''Test that empty files generate errors
+
+        defines.inc are interesting that way, as their
+        content is added to the generated file.
+        '''
+        self._test('\n', (('Junk', '\n'),))
+        self._test('\n\n', (('Junk', '\n\n'),))
+        self._test(' \n\n', (('Junk', ' \n\n'),))
+
+
+if __name__ == '__main__':
+    unittest.main()
--- a/python/compare-locales/compare_locales/tests/test_dtd.py
+++ b/python/compare-locales/compare_locales/tests/test_dtd.py
@@ -3,17 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 '''Tests for the DTD parser.
 '''
 
 import unittest
 import re
 
-from compare_locales.parser import getParser
+from compare_locales import parser
 from compare_locales.tests import ParserTestMixin
 
 
 class TestDTD(ParserTestMixin, unittest.TestCase):
     '''Tests for the DTD Parser.'''
     filename = 'foo.dtd'
 
     def test_one_entity(self):
@@ -25,19 +25,19 @@ class TestDTD(ParserTestMixin, unittest.
 <!ENTITY good.two "two">
 <!ENTITY bad.two "bad "quoted" word">
 <!ENTITY good.three "three">
 <!ENTITY good.four "good ' quote">
 <!ENTITY good.five "good 'quoted' word">
 '''
     quoteRef = (
         ('good.one', 'one'),
-        ('_junk_\\d_25-56$', '<!ENTITY bad.one "bad " quote">'),
+        ('Junk', '<!ENTITY bad.one "bad " quote">'),
         ('good.two', 'two'),
-        ('_junk_\\d_82-119$', '<!ENTITY bad.two "bad "quoted" word">'),
+        ('Junk', '<!ENTITY bad.two "bad "quoted" word">'),
         ('good.three', 'three'),
         ('good.four', 'good \' quote'),
         ('good.five', 'good \'quoted\' word'),)
 
     def test_quotes(self):
         self._test(self.quoteContent, self.quoteRef)
 
     def test_apos(self):
@@ -57,30 +57,73 @@ class TestDTD(ParserTestMixin, unittest.
 
     def test_trailing_comment(self):
         self._test('''<!ENTITY first "string">
 <!ENTITY second "string">
 <!--
 <!ENTITY commented "out">
 -->
 ''',
-                   (('first', 'string'), ('second', 'string')))
+                   (('first', 'string'), ('second', 'string'),
+                    ('Comment', 'out')))
 
     def test_license_header(self):
-        p = getParser('foo.dtd')
+        p = parser.getParser('foo.dtd')
         p.readContents(self.resource('triple-license.dtd'))
-        for e in p:
-            self.assertEqual(e.key, 'foo')
-            self.assertEqual(e.val, 'value')
-        self.assert_('MPL' in p.header)
+        entities = list(p.walk())
+        self.assert_(isinstance(entities[0], parser.Comment))
+        self.assertIn('MPL', entities[0].all)
+        e = entities[1]
+        self.assert_(isinstance(e, parser.Entity))
+        self.assertEqual(e.key, 'foo')
+        self.assertEqual(e.val, 'value')
+        self.assertEqual(len(entities), 2)
         p.readContents('''\
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this file,
    - You can obtain one at http://mozilla.org/MPL/2.0/.  -->
 <!ENTITY foo "value">
 ''')
-        for e in p:
-            self.assertEqual(e.key, 'foo')
-            self.assertEqual(e.val, 'value')
-        self.assert_('MPL' in p.header)
+        entities = list(p.walk())
+        self.assert_(isinstance(entities[0], parser.Comment))
+        self.assertIn('MPL', entities[0].all)
+        e = entities[1]
+        self.assert_(isinstance(e, parser.Entity))
+        self.assertEqual(e.key, 'foo')
+        self.assertEqual(e.val, 'value')
+        self.assertEqual(len(entities), 2)
+
+    def testBOM(self):
+        self._test(u'\ufeff<!ENTITY foo.label "stuff">'.encode('utf-8'),
+                   (('foo.label', 'stuff'),))
+
+    def test_trailing_whitespace(self):
+        self._test('<!ENTITY foo.label "stuff">\n  \n',
+                   (('foo.label', 'stuff'),))
+
+    def test_unicode_comment(self):
+        self._test('<!-- \xe5\x8f\x96 -->',
+                   (('Comment', u'\u53d6'),))
+
+    def test_empty_file(self):
+        self._test('', tuple())
+        self._test('\n', (('Whitespace', '\n'),))
+        self._test('\n\n', (('Whitespace', '\n\n'),))
+        self._test(' \n\n', (('Whitespace', ' \n\n'),))
+
+    def test_positions(self):
+        self.parser.readContents('''\
+<!ENTITY one  "value">
+<!ENTITY  two "other
+escaped value">
+''')
+        one, two = list(self.parser)
+        self.assertEqual(one.position(), (1, 1))
+        self.assertEqual(one.value_position(), (1, 16))
+        self.assertEqual(one.position(-1), (2, 1))
+        self.assertEqual(two.position(), (2, 1))
+        self.assertEqual(two.value_position(), (2, 16))
+        self.assertEqual(two.value_position(-1), (3, 14))
+        self.assertEqual(two.value_position(10), (3, 5))
+
 
 if __name__ == '__main__':
     unittest.main()
--- a/python/compare-locales/compare_locales/tests/test_ini.py
+++ b/python/compare-locales/compare_locales/tests/test_ini.py
@@ -18,98 +18,122 @@ mpl2 = '''\
 class TestIniParser(ParserTestMixin, unittest.TestCase):
 
     filename = 'foo.ini'
 
     def testSimpleHeader(self):
         self._test('''; This file is in the UTF-8 encoding
 [Strings]
 TitleText=Some Title
-''', (('TitleText', 'Some Title'),))
-        self.assert_('UTF-8' in self.parser.header)
+''', (
+            ('Comment', 'UTF-8 encoding'),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),))
 
     def testMPL2_Space_UTF(self):
         self._test(mpl2 + '''
 ; This file is in the UTF-8 encoding
 [Strings]
 TitleText=Some Title
-''', (('TitleText', 'Some Title'),))
-        self.assert_('MPL' in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('Comment', 'UTF-8'),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),))
 
     def testMPL2_Space(self):
         self._test(mpl2 + '''
 [Strings]
 TitleText=Some Title
-''', (('TitleText', 'Some Title'),))
-        self.assert_('MPL' in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),))
 
     def testMPL2_MultiSpace(self):
         self._test(mpl2 + '''\
 
 ; more comments
 
 [Strings]
 TitleText=Some Title
-''', (('TitleText', 'Some Title'),))
-        self.assert_('MPL' in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('Comment', 'more comments'),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),))
 
     def testMPL2_JunkBeforeCategory(self):
         self._test(mpl2 + '''\
 Junk
 [Strings]
 TitleText=Some Title
-''', (('_junk_\\d+_0-213$', mpl2 + '''\
-Junk
-[Strings]'''), ('TitleText', 'Some Title')))
-        self.assert_('MPL' not in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('Junk', 'Junk'),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title')))
 
     def test_TrailingComment(self):
         self._test(mpl2 + '''
 [Strings]
 TitleText=Some Title
 ;Stray trailing comment
-''', (('TitleText', 'Some Title'),))
-        self.assert_('MPL' in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),
+            ('Comment', 'Stray trailing')))
 
     def test_SpacedTrailingComments(self):
         self._test(mpl2 + '''
 [Strings]
 TitleText=Some Title
 
 ;Stray trailing comment
 ;Second stray comment
 
-''', (('TitleText', 'Some Title'),))
-        self.assert_('MPL' in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),
+            ('Comment', 'Second stray comment')))
 
     def test_TrailingCommentsAndJunk(self):
         self._test(mpl2 + '''
 [Strings]
 TitleText=Some Title
 
 ;Stray trailing comment
 Junk
 ;Second stray comment
 
-''', (('TitleText', 'Some Title'), ('_junk_\\d+_231-284$', '''\
-
-;Stray trailing comment
-Junk
-;Second stray comment
-
-''')))
-        self.assert_('MPL' in self.parser.header)
+''', (
+            ('Comment', mpl2),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),
+            ('Comment', 'Stray trailing'),
+            ('Junk', 'Junk'),
+            ('Comment', 'Second stray comment')))
 
     def test_JunkInbetweenEntries(self):
         self._test(mpl2 + '''
 [Strings]
 TitleText=Some Title
 
 Junk
 
 Good=other string
-''', (('TitleText', 'Some Title'), ('_junk_\\d+_231-236$', '''\
+''', (
+            ('Comment', mpl2),
+            ('IniSection', 'Strings'),
+            ('TitleText', 'Some Title'),
+            ('Junk', 'Junk'),
+            ('Good', 'other string')))
 
-Junk'''), ('Good', 'other string')))
-        self.assert_('MPL' in self.parser.header)
+    def test_empty_file(self):
+        self._test('', tuple())
+        self._test('\n', (('Whitespace', '\n'),))
+        self._test('\n\n', (('Whitespace', '\n\n'),))
+        self._test(' \n\n', (('Whitespace', ' \n\n'),))
 
 if __name__ == '__main__':
     unittest.main()
--- a/python/compare-locales/compare_locales/tests/test_merge.py
+++ b/python/compare-locales/compare_locales/tests/test_merge.py
@@ -8,32 +8,32 @@ from tempfile import mkdtemp
 import shutil
 
 from compare_locales.parser import getParser
 from compare_locales.paths import File
 from compare_locales.compare import ContentComparer
 
 
 class ContentMixin(object):
-    maxDiff = None  # we got big dictionaries to compare
     extension = None  # OVERLOAD
 
     def reference(self, content):
         self.ref = os.path.join(self.tmp, "en-reference" + self.extension)
         open(self.ref, "w").write(content)
 
     def localized(self, content):
         self.l10n = os.path.join(self.tmp, "l10n" + self.extension)
         open(self.l10n, "w").write(content)
 
 
 class TestProperties(unittest.TestCase, ContentMixin):
     extension = '.properties'
 
     def setUp(self):
+        self.maxDiff = None
         self.tmp = mkdtemp()
         os.mkdir(os.path.join(self.tmp, "merge"))
 
     def tearDown(self):
         shutil.rmtree(self.tmp)
         del self.tmp
 
     def testGood(self):
@@ -93,17 +93,18 @@ eff = effVal""")
         [m, n] = p.parse()
         self.assertEqual(map(lambda e: e.key,  m), ["bar", "eff", "foo"])
 
     def testError(self):
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""foo = fooVal
 bar = %d barVal
 eff = effVal""")
-        self.localized("""bar = %S lBar
+        self.localized("""\
+bar = %S lBar
 eff = leffVal
 """)
         cc = ContentComparer()
         cc.set_merge_stage(os.path.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.properties", ""),
                    File(self.l10n, "l10n.properties", ""))
         self.assertDictEqual(
             cc.observer.toJSON(),
@@ -111,17 +112,17 @@ eff = leffVal
                 {None: {
                     'changed': 2, 'errors': 1, 'missing': 1
                 }},
              'details': {
                  'children': [
                      ('l10n.properties',
                          {'value': {
                           'error': [u'argument 1 `S` should be `d` '
-                                    u'at line 1, column 6 for bar'],
+                                    u'at line 1, column 7 for bar'],
                           'missingEntity': [u'foo']}}
                       )
                  ]}
              }
         )
         mergefile = os.path.join(self.tmp, "merge", "l10n.properties")
         self.assertTrue(os.path.isfile(mergefile))
         p = getParser(mergefile)
@@ -155,16 +156,17 @@ eff = leffVal
              }
         )
 
 
 class TestDTD(unittest.TestCase, ContentMixin):
     extension = '.dtd'
 
     def setUp(self):
+        self.maxDiff = None
         self.tmp = mkdtemp()
         os.mkdir(os.path.join(self.tmp, "merge"))
 
     def tearDown(self):
         shutil.rmtree(self.tmp)
         del self.tmp
 
     def testGood(self):
@@ -243,17 +245,19 @@ class TestDTD(unittest.TestCase, Content
                 {None: {
                     'errors': 1, 'missing': 1, 'unchanged': 2
                 }},
              'details': {
                  'children': [
                      ('l10n.dtd',
                          {'value': {
                              'error': [u'Unparsed content "<!ENTY bar '
-                                       u'\'gimmick\'>" at 23-44'],
+                                       u'\'gimmick\'>" '
+                                       u'from line 2 colum 1 to '
+                                       u'line 2 column 22'],
                              'missingEntity': [u'bar']}}
                       )
                  ]}
              }
         )
         mergefile = os.path.join(self.tmp, "merge", "l10n.dtd")
         self.assertTrue(os.path.isfile(mergefile))
         p = getParser(mergefile)
new file mode 100644
--- /dev/null
+++ b/python/compare-locales/compare_locales/tests/test_parser.py
@@ -0,0 +1,44 @@
+# 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/.
+
+import unittest
+
+from compare_locales import parser
+
+
+class TestParserContext(unittest.TestCase):
+    def test_lines(self):
+        "Test that Parser.Context.lines returns 1-based tuples"
+        ctx = parser.Parser.Context('''first line
+second line
+third line
+''')
+        self.assertEqual(
+            ctx.lines(0, 1),
+            [(1, 1), (1, 2)]
+        )
+        self.assertEqual(
+            ctx.lines(len('first line')),
+            [(1, len('first line') + 1)]
+        )
+        self.assertEqual(
+            ctx.lines(len('first line') + 1),
+            [(2, 1)]
+        )
+        self.assertEqual(
+            ctx.lines(len(ctx.contents)),
+            [(4, 1)]
+        )
+
+    def test_empty_parser(self):
+        p = parser.Parser()
+        entities, _map = p.parse()
+        self.assertListEqual(
+            entities,
+            []
+        )
+        self.assertDictEqual(
+            _map,
+            {}
+        )
--- a/python/compare-locales/compare_locales/tests/test_properties.py
+++ b/python/compare-locales/compare_locales/tests/test_properties.py
@@ -19,17 +19,17 @@ of two lines
 one_line_trailing = This line ends in \\
 and has junk
 two_lines_triple = This line is one of two and ends in \\\
 and still has another line coming
 ''', (
             ('one_line', 'This is one line'),
             ('two_line', u'This is the first of two lines'),
             ('one_line_trailing', u'This line ends in \\'),
-            ('_junk_\\d+_113-126$', 'and has junk\n'),
+            ('Junk', 'and has junk\n'),
             ('two_lines_triple', 'This line is one of two and ends in \\'
              'and still has another line coming')))
 
     def testProperties(self):
         # port of netwerk/test/PropertiesTest.cpp
         self.parser.readContents(self.resource('test.properties'))
         ref = ['1', '2', '3', '4', '5', '6', '7', '8',
                'this is the first part of a continued line '
@@ -58,18 +58,17 @@ and an end''', (('bar', 'one line with a
 
     def test_license_header(self):
         self._test('''\
 # 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/.
 
 foo=value
-''', (('foo', 'value'),))
-        self.assert_('MPL' in self.parser.header)
+''', (('Comment', 'MPL'), ('foo', 'value')))
 
     def test_escapes(self):
         self.parser.readContents(r'''
 # unicode escapes
 zero = some \unicode
 one = \u0
 two = \u41
 three = \u042
@@ -83,13 +82,69 @@ seven = \n\r\t\\
             self.assertEqual(e.val, r)
 
     def test_trailing_comment(self):
         self._test('''first = string
 second = string
 
 #
 #commented out
-''', (('first', 'string'), ('second', 'string')))
+''', (('first', 'string'), ('second', 'string'),
+            ('Comment', 'commented out')))
+
+    def test_trailing_newlines(self):
+        self._test('''\
+foo = bar
+
+\x20\x20
+  ''', (('foo', 'bar'),))
+
+    def test_just_comments(self):
+        self._test('''\
+# 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/.
+
+# LOCALIZATION NOTE These strings are used inside the Promise debugger
+# which is available as a panel in the Debugger.
+''', (('Comment', 'MPL'), ('Comment', 'LOCALIZATION NOTE')))
+
+    def test_just_comments_without_trailing_newline(self):
+        self._test('''\
+# 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/.
 
+# LOCALIZATION NOTE These strings are used inside the Promise debugger
+# which is available as a panel in the Debugger.''', (
+            ('Comment', 'MPL'), ('Comment', 'LOCALIZATION NOTE')))
+
+    def test_trailing_comment_and_newlines(self):
+        self._test('''\
+# LOCALIZATION NOTE These strings are used inside the Promise debugger
+# which is available as a panel in the Debugger.
+
+
+
+''',  (('Comment', 'LOCALIZATION NOTE'),))
+
+    def test_empty_file(self):
+        self._test('', tuple())
+        self._test('\n', (('Whitespace', '\n'),))
+        self._test('\n\n', (('Whitespace', '\n\n'),))
+        self._test(' \n\n', (('Whitespace', ' \n\n'),))
+
+    def test_positions(self):
+        self.parser.readContents('''\
+one = value
+two = other \\
+escaped value
+''')
+        one, two = list(self.parser)
+        self.assertEqual(one.position(), (1, 1))
+        self.assertEqual(one.value_position(), (1, 7))
+        self.assertEqual(two.position(), (2, 1))
+        self.assertEqual(two.value_position(), (2, 7))
+        self.assertEqual(two.value_position(-1), (3, 14))
+        self.assertEqual(two.value_position(10), (3, 3))
 
 if __name__ == '__main__':
     unittest.main()
--- a/python/compare-locales/compare_locales/webapps.py
+++ b/python/compare-locales/compare_locales/webapps.py
@@ -78,17 +78,17 @@ class Manifest(object):
         return self._strings
 
     def load_and_parse(self):
         try:
             manifest = json.load(open(self.file.fullpath))
         except (ValueError, IOError), e:
             if self.watcher:
                 self.watcher.notify('error', self.file, str(e))
-            return False
+            return {}
         return self.extract_manifest_strings(manifest)
 
     def extract_manifest_strings(self, manifest_fragment):
         '''Extract localizable strings from a manifest dict.
         This method is recursive, and returns a two-level dict,
         first level being locale codes, second level being generated
         key and localized value. Keys are generated by concatenating
         each level in the json with a ".".
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1160,9 +1160,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 = 464;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1488464530999000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1488551716626000);
--- a/security/manager/ssl/moz.build
+++ b/security/manager/ssl/moz.build
@@ -179,16 +179,17 @@ if CONFIG['NSS_DISABLE_DBM']:
 
 DEFINES['SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES'] = 'True'
 DEFINES['NSS_ENABLE_ECC'] = 'True'
 for var in ('DLL_PREFIX', 'DLL_SUFFIX'):
     DEFINES[var] = '"%s"' % CONFIG[var]
 
 DEFINES['CERT_AddTempCertToPerm'] = '__CERT_AddTempCertToPerm'
 
-USE_LIBS += [
-    'crmf',
-]
+if not CONFIG['MOZ_SYSTEM_NSS']:
+    USE_LIBS += [
+        'crmf',
+    ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -11,27 +11,27 @@ 10seos.com: did not receive HSTS header
 123plons.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 121"  data: no]
 12vpnchina.com: could not connect to host
 18f.gsa.gov: did not receive HSTS header
 1a-jva.de: did not receive HSTS header
 1p.ro: could not connect to host
 1password.com: did not receive HSTS header
 1whw.co.uk: could not connect to host
 206rc.net: max-age too low: 2592000
-20hs.cn: did not receive HSTS header
 24hourpaint.com: did not receive HSTS header
 25daysof.io: could not connect to host
 2859cc.com: could not connect to host
 2or3.tk: could not connect to host
 300651.ru: did not receive HSTS header
 302.nyc: could not connect to host
 360ds.co.in: could not connect to host
 360gradus.com: did not receive HSTS header
 365.or.jp: did not receive HSTS header
 3chit.cf: could not connect to host
+404.sh: could not connect to host
 420dongstorm.com: could not connect to host
 42ms.org: could not connect to host
 4455software.com: did not receive HSTS header
 4679.space: could not connect to host
 47ronin.com: did not receive HSTS header
 491mhz.net: could not connect to host
 4elements.com: did not receive HSTS header
 4eyes.ch: did not receive HSTS header
@@ -111,17 +111,16 @@ afrodigital.uk: could not connect to hos
 agbremen.de: did not receive HSTS header
 agevio.com: could not connect to host
 agilebits.net: could not connect to host
 agrimap.com: did not receive HSTS header
 agrios.de: did not receive HSTS header
 agro-id.gov.ua: could not connect to host
 ahabingo.com: did not receive HSTS header
 ahri.ovh: could not connect to host
-aidanmontare.net: could not connect to host
 aidanwoods.com: did not receive HSTS header
 airbnb.com: did not receive HSTS header
 aircomms.com: did not receive HSTS header
 airproto.com: did not receive HSTS header
 aishnair.com: could not connect to host
 aiticon.de: did not receive HSTS header
 aiw-thkoeln.online: could not connect to host
 ajmahal.com: did not receive HSTS header
@@ -136,19 +135,19 @@ aladdin.ie: did not receive HSTS header
 alainwolf.net: could not connect to host
 alanlee.net: could not connect to host
 alanrickmanflipstable.com: could not connect to host
 alariel.de: did not receive HSTS header
 alarmsystemreviews.com: did not receive HSTS header
 albertopimienta.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
 alessandro.pw: did not receive HSTS header
 alethearose.com: did not receive HSTS header
-alexandra-schulze.de: could not connect to host
 alexandre.sh: did not receive HSTS header
 alexhaydock.co.uk: [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 121"  data: no]
 alexisabarca.com: did not receive HSTS header
 alexismeza.com: could not connect to host
 alexismeza.com.mx: could not connect to host
 alexismeza.dk: could not connect to host
 alfredxing.com: did not receive HSTS header
 alittlebitcheeky.com: did not receive HSTS header
@@ -158,16 +157,17 @@ all.tf: could not connect to host
 allforyou.at: could not connect to host
 allinnote.com: could not connect to host
 allstarswithus.com: could not connect to host
 allthingssquared.com: could not connect to host
 alpha.irccloud.com: could not connect to host
 alphabit-secure.com: could not connect to host
 alphabuild.io: did not receive HSTS header
 alphalabs.xyz: could not connect to host
+alterbaum.net: did not receive HSTS header
 altfire.ca: could not connect to host
 altmv.com: max-age too low: 7776000
 amaforums.org: could not connect to host
 american-truck-simulator.de: could not connect to host
 american-truck-simulator.net: could not connect to host
 americanworkwear.nl: did not receive HSTS header
 ameza.co.uk: could not connect to host
 amigogeek.net: could not connect to host
@@ -188,16 +188,17 @@ andreasolsson.se: could not connect to h
 andreigec.net: did not receive HSTS header
 andrewmichaud.beer: could not connect to host
 andreypopp.com: could not connect to host
 androoz.se: did not receive HSTS header
 andymartin.cc: did not receive HSTS header
 anfsanchezo.co: could not connect to host
 anfsanchezo.me: could not connect to host
 anghami.com: did not receive HSTS header
+anime.my: could not connect to host
 animeday.ml: could not connect to host
 animesfusion.com.br: could not connect to host
 animesharp.com: could not connect to host
 animurecs.com: could not connect to host
 aniplus.cf: could not connect to host
 aniplus.gq: could not connect to host
 aniplus.ml: could not connect to host
 ankakaak.com: could not connect to host
@@ -236,71 +237,75 @@ appreciationkards.com: could not connect
 approlys.fr: did not receive HSTS header
 apps-for-fishing.com: could not connect to host
 appseccalifornia.org: did not receive HSTS header
 arabdigitalexpression.org: did not receive HSTS header
 aradulconteaza.ro: could not connect to host
 aran.me.uk: did not receive HSTS header
 arboineuropa.nl: did not receive HSTS header
 arbu.eu: max-age too low: 2419200
+argh.io: could not connect to host
 arlen.se: could not connect to host
 armory.consulting: could not connect to host
 armory.supplies: could not connect to host
 armytricka.cz: did not receive HSTS header
 arnetdigital.eu: did not receive HSTS header
 arrayify.com: could not connect to host
 ars-design.net: could not connect to host
 ars.toscana.it: max-age too low: 0
 artistnetwork.nl: did not receive HSTS header
 arturkohut.com: could not connect to host
 as.se: could not connect to host
 asasuou.pw: could not connect to host
 asc16.com: could not connect to host
 asdpress.cn: could not connect to host
 aserver.co: could not connect to host
 asmui.ga: could not connect to host
-asrob.eu: did not receive HSTS header
+asrob.eu: could not connect to host
 ass.org.au: did not receive HSTS header
 assdecoeur.org: could not connect to host
 asset-alive.com: did not receive HSTS header
 asset-alive.net: did not receive HSTS header
 astrolpost.com: could not connect to host
+astromelody.com: could not connect to host
 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
 athaliasoft.com: did not receive HSTS header
 athenelive.com: could not connect to host
 athul.xyz: did not receive HSTS header
 atlex.nl: did not receive HSTS header
 atomik.pro: could not connect to host
 atop.io: could not connect to host
+attilagyorffy.com: could not connect to host
 attimidesigns.com: did not receive HSTS header
 au.search.yahoo.com: max-age too low: 172800
 aubiosales.com: did not receive HSTS header
+aufmerksamkeitsstudie.com: could not connect to host
 aujapan.ru: could not connect to host
 aurainfosec.com.au: could not connect to host
 ausnah.me: could not connect to host
 ausoptic.com.au: max-age too low: 2592000
 auszeit.bio: did not receive HSTS header
 auth.mail.ru: did not receive HSTS header
 authentication.io: could not connect to host
 auto-serwis.zgorzelec.pl: did not receive HSTS header
 auto4trade.nl: could not connect to host
 autojuhos.sk: did not receive HSTS header
 autokovrik-diskont.ru: did not receive HSTS header
-automacity.com: could not connect to host
 autotsum.com: could not connect to host
 autumnwindsagility.com: could not connect to host
 auverbox.ovh: did not receive HSTS header
 auxiliumincrementum.co.uk: could not connect to host
 av.de: did not receive HSTS header
 avec-ou-sans-ordonnance.fr: could not connect to host
 avinet.com: max-age too low: 0
 awg-mode.de: did not receive HSTS header
+awxg.com: could not connect to host
 axado.com.br: did not receive HSTS header
 axeny.com: did not receive HSTS header
 az.search.yahoo.com: did not receive HSTS header
 azprep.us: could not connect to host
 b3orion.com: max-age too low: 0
 babak.de: did not receive HSTS header
 baby-click.de: did not receive HSTS header
 babybic.hu: did not receive HSTS header
@@ -316,25 +321,25 @@ balcan-underground.net: could not connec
 baldwinkoo.com: could not connect to host
 bandb.xyz: could not connect to host
 bannisbierblog.de: could not connect to host
 banqingdiao.com: could not connect to host
 barely.sexy: did not receive HSTS header
 bashcode.ninja: could not connect to host
 basicsolutionsus.com: did not receive HSTS header
 bassh.net: did not receive HSTS header
+baum.ga: did not receive HSTS header
 baumstark.ca: did not receive HSTS header
 bazarstupava.sk: did not receive HSTS header
 bcbsmagentprofile.com: could not connect to host
 bccx.com: could not connect to host
 bckp.de: could not connect to host
 bcm.com.au: max-age too low: 0
 bcnx.de: max-age too low: 0
 bcsytv.com: could not connect to host
-bdikaros-network.net: could not connect to host
 be.search.yahoo.com: did not receive HSTS header
 beach-inspector.com: did not receive HSTS header
 beachi.es: could not connect to host
 beaglewatch.com: did not receive HSTS header
 beardydave.com: did not receive HSTS header
 beastowner.com: did not receive HSTS header
 beavers.io: could not connect to host
 bebesurdoue.com: could not connect to host
@@ -351,19 +356,21 @@ belltower.io: could not connect to host
 beneffy.com: did not receive HSTS header
 benk.press: could not connect to host
 benny003.de: did not receive HSTS header
 benzkosmetik.de: could not connect to host
 bermytraq.bm: [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 121"  data: no]
 berrymark.be: max-age too low: 0
 besixdouze.world: could not connect to host
 betafive.net: could not connect to host
+betlander.com: did not receive HSTS header
 betnet.fr: could not connect to host
 betplanning.it: did not receive HSTS header
 bets.de: did not receive HSTS header
+bettercrypto.org: could not connect to host
 bettween.com: could not connect to host
 betz.ro: did not receive HSTS header
 beulahtabernacle.com: could not connect to host
 bevapehappy.com: did not receive HSTS header
 bezorg.ninja: could not connect to host
 bf.am: max-age too low: 0
 bgcparkstad.nl: did not receive HSTS header
 bgmn.net: could not connect to host
@@ -429,17 +436,17 @@ bluetenmeer.com: did not receive HSTS he
 bm-trading.nl: did not receive HSTS header
 bngsecure.com: [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 121"  data: no]
 bobiji.com: did not receive HSTS header
 bodyblog.nl: did not receive HSTS header
 bodybuilding-legends.com: could not connect to host
 bodyweightsolution.com: did not receive HSTS header
 boensou.com: did not receive HSTS header
 bogosity.se: could not connect to host
-bohan.life: could not connect to host
+bohan.life: did not receive HSTS header
 boltdata.io: did not receive HSTS header
 bonapp.restaurant: could not connect to host
 bonfi.net: did not receive HSTS header
 bonigo.de: [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 121"  data: no]
 bonitabrazilian.co.nz: did not receive HSTS header
 bookcelerator.com: did not receive HSTS header
 booked.holiday: did not receive HSTS header
 boomerang.com: could not connect to host
@@ -481,17 +488,16 @@ buch-cuber.de: could not connect to host
 buchheld.at: did not receive HSTS header
 budgetthostels.nl: did not receive HSTS header
 budskap.eu: could not connect to host
 bugtrack.io: did not receive HSTS header
 buhler.pro: did not receive HSTS header
 buildsaver.co.za: did not receive HSTS header
 built.by: did not receive HSTS header
 bulletpoint.cz: did not receive HSTS header
-bulmafox.com: could not connect to host
 bumarkamoda.com: could not connect to host
 bunaken.asia: could not connect to host
 burian-server.cz: could not connect to host
 burrow.ovh: could not connect to host
 burtrum.me: could not connect to host
 business.lookout.com: could not connect to host
 businesshosting.nl: did not receive HSTS header
 busold.ws: could not connect to host
@@ -509,31 +515,28 @@ bypro.xyz: could not connect to host
 bysymphony.com: max-age too low: 0
 bytepark.de: did not receive HSTS header
 c1yd3i.me: could not connect to host
 c3b.info: could not connect to host
 cabarave.com: could not connect to host
 cabusar.fr: could not connect to host
 caconnect.org: could not connect to host
 cadao.me: did not receive HSTS header
-cadmail.nl: could not connect to host
 cadusilva.com: did not receive HSTS header
 cafe-scientifique.org.ec: could not connect to host
 caim.cz: did not receive HSTS header
 cajapopcorn.com: did not receive HSTS header
 cake.care: could not connect to host
 calgaryconstructionjobs.com: could not connect to host
 calix.com: max-age too low: 0
-call.me: did not receive HSTS header
 calltrackingreports.com: could not connect to host
 calvin.me: max-age too low: 2592000
 calvinallen.net: could not connect to host
 calyxinstitute.org: [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 121"  data: no]
 camolist.com: could not connect to host
-campbellsoftware.co.uk: could not connect to host
 canadiangamblingchoice.com: did not receive HSTS header
 cancelmyprofile.com: did not receive HSTS header
 candicontrols.com: did not receive HSTS header
 candratech.com: could not connect to host
 candylion.rocks: could not connect to host
 cannyfoxx.me: could not connect to host
 canyonshoa.com: did not receive HSTS header
 capecycles.co.za: did not receive HSTS header
@@ -609,23 +612,22 @@ childcaresolutionscny.org: did not recei
 chirgui.eu: could not connect to host
 chm.vn: did not receive HSTS header
 chontalpa.pw: could not connect to host
 chotu.net: could not connect to host
 chris-web.info: could not connect to host
 chriskyrouac.com: could not connect to host
 christiaandruif.nl: could not connect to host
 christianbro.gq: could not connect to host
-christophheich.me: could not connect to host
+christophheich.me: did not receive HSTS header
 chrisupjohn.com: 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)
 chroniclesofgeorge.com: did not receive HSTS header
 chua.cf: could not connect to host
-chxdf.net: did not receive HSTS header
 cidr.ml: could not connect to host
 cigarblogs.net: could not connect to host
 cigi.site: could not connect to host
 cip.md: did not receive HSTS header
 ciplanutrition.com: did not receive HSTS header
 citiagent.cz: could not connect to host
 cityoflaurel.org: did not receive HSTS header
 clara-baumert.de: could not connect to host
@@ -690,17 +692,16 @@ colognegaming.net: could not connect to 
 coloradocomputernetworking.net: could not connect to host
 colorbrush.ru: did not receive HSTS header
 comfortticket.de: did not receive HSTS header
 comicspines.com: could not connect to host
 compalytics.com: could not connect to host
 comparejewelleryprices.co.uk: could not connect to host
 completionist.audio: could not connect to host
 computeremergency.com.au: did not receive HSTS header
-computersystems.guru: could not connect to host
 concord-group.co.jp: did not receive HSTS header
 condesaelectronics.com: max-age too low: 0
 confirm365.com: could not connect to host
 conformal.com: could not connect to host
 conrad-kostecki.de: did not receive HSTS header
 consciousandglamorous.com: could not connect to host
 console.python.org: did not receive HSTS header
 constructionjobs.com: did not receive HSTS header
@@ -716,18 +717,18 @@ core4system.de: did not receive HSTS hea
 corenetworking.de: could not connect to host
 cormactagging.ie: could not connect to host
 cormilu.com.br: did not receive HSTS header
 cornodo.com: could not connect to host
 correctpaardbatterijnietje.nl: did not receive HSTS header
 corruption-mc.net: could not connect to host
 corruption-rsps.net: could not connect to host
 corruption-server.net: could not connect to host
+corzntin.fr: could not connect to host
 count.sh: could not connect to host
-couragefound.org: could not connect to host
 couragewhispers.ca: did not receive HSTS header
 coursdeprogrammation.com: could not connect to host
 coursella.com: did not receive HSTS header
 covenantbank.net: could not connect to host
 coverduck.ru: could not connect to host
 cr.search.yahoo.com: did not receive HSTS header
 cracking.org: did not receive HSTS header
 craftbeerbarn.co.uk: could not connect to host
@@ -736,86 +737,84 @@ craftmine.cz: could not connect to host
 crate.io: did not receive HSTS header
 cravelyrics.com: did not receive HSTS header
 crazifyngers.com: could not connect to host
 crazycen.com: did not receive HSTS header
 crazyhotseeds.com: did not receive HSTS header
 creativephysics.ml: could not connect to host
 creativeplayuk.com: did not receive HSTS header
 crendontech.com: could not connect to host
-crestasantos.com: could not connect to host
 crestoncottage.com: could not connect to host
 criena.net: could not connect to host
 critical.today: could not connect to host
 criticalaim.com: could not connect to host
 crizk.com: could not connect to host
 crosssec.com: did not receive HSTS header
 crowd.supply: could not connect to host
 crowdcurity.com: did not receive HSTS header
 crowdjuris.com: could not connect to host
 crtvmgmt.com: could not connect to host
 crudysql.com: could not connect to host
 cruzr.xyz: could not connect to host
 crypt.guru: could not connect to host
-cryptearth.de: could not connect to host
 cryptify.eu: did not receive HSTS header
 cryptobells.com: could not connect to host
 cryptobin.org: could not connect to host
 cryptojar.io: did not receive HSTS header
 cryptoki.fr: max-age too low: 7776000
 cryptopush.com: did not receive HSTS header
 crysadm.com: max-age too low: 1
-crystalchandelierservices.com: could not connect to host
 crystalclassics.co.uk: did not receive HSTS header
 csapak.com: max-age too low: 0
 csawctf.poly.edu: could not connect to host
 csfs.org.uk: could not connect to host
 csgodicegame.com: did not receive HSTS header
 csgoelemental.com: could not connect to host
 csgokings.eu: could not connect to host
 csohack.tk: could not connect to host
 cspbuilder.info: could not connect to host
 ct.search.yahoo.com: did not receive HSTS header
 cthulhuden.com: could not connect to host
 cubeserver.eu: could not connect to host
 cubewano.com: could not connect to host
 cujanovic.com: did not receive HSTS header
 cumshots-video.ru: could not connect to host
+cupi.co: did not receive HSTS header
 cupidmentor.com: did not receive HSTS header
 curroapp.com: could not connect to host
 custe.rs: could not connect to host
 cuvva.insure: did not receive HSTS header
 cyanogenmod.xxx: could not connect to host
 cybershambles.com: could not connect to host
 cycleluxembourg.lu: did not receive HSTS header
 cydia-search.io: could not connect to host
 cyphertite.com: could not connect to host
+cysec.biz: could not connect to host
 dad256.tk: could not connect to host
 dah5.com: did not receive HSTS header
 dailystormerpodcasts.com: did not receive HSTS header
-daimadi.com: could not connect to host
 dakrib.net: could not connect to host
 dalingk.co: could not connect to host
 dango.in: did not receive HSTS header
 daniel-steuer.de: did not receive HSTS header
 danieldk.eu: did not receive HSTS header
 danielworthy.com: did not receive HSTS header
 danijobs.com: could not connect to host
-dannyrohde.de: could not connect to host
 danpiel.net: could not connect to host
 danrl.de: did not receive HSTS header
 daolerp.xyz: could not connect to host
 dargasia.is: could not connect to host
 dario.im: could not connect to host
 dark-x.cf: could not connect to host
 darkag.ovh: could not connect to host
 darkengine.io: could not connect to host
 darkhole.cn: could not connect to host
 darknebula.space: could not connect to host
 darkpony.ru: could not connect to host
+darrenellis.xyz: 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
 databionix.com: could not connect to host
 databutlr.com: could not connect to host
 databutlr.net: could not connect to host
 datahove.no: did not receive HSTS header
 datarank.com: max-age too low: 0
@@ -869,39 +868,38 @@ derevtsov.com: did not receive HSTS head
 derwolfe.net: did not receive HSTS header
 desiccantpackets.com: did not receive HSTS header
 destinationbijoux.fr: could not connect to host
 detector.exposed: could not connect to host
 deux.solutions: could not connect to host
 deuxsol.com: could not connect to host
 deuxsolutions.com: could not connect to host
 devcu.net: did not receive HSTS header
-devdesco.com: could not connect to host
 devh.de: did not receive HSTS header
 devincrow.me: could not connect to host
 devinfo.net: did not receive HSTS header
 devmsg.com: did not receive HSTS header
 devtub.com: did not receive HSTS header
 devuan.org: did not receive HSTS header
 diablotine.rocks: could not connect to host
 diarbag.us: did not receive HSTS header
 diasp.cz: [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 121"  data: no]
 diasp.org: did not receive HSTS header
 diedrich.co: could not connect to host
 digitaldaddy.net: could not connect to host
 digitalriver.tk: could not connect to host
 digitalskillswap.com: could not connect to host
 dinamoelektrik.com: max-age too low: 0
+dinkum.online: could not connect to host
 dirk-weise.de: could not connect to host
 discoveringdocker.com: did not receive HSTS header
 discovery.lookout.com: did not receive HSTS header
 dislocated.de: did not receive HSTS header
 dissimulo.me: could not connect to host
 dittvertshus.no: could not connect to host
-diycc.org: could not connect to host
 dizihocasi.com: did not receive HSTS header
 dizorg.net: could not connect to host
 dj4et.de: did not receive HSTS header
 dl.google.com: did not receive HSTS header (error ignored - included regardless)
 dlouwrink.nl: could not connect to host
 dmxledlights.com: could not connect to host
 dn42.eu: could not connect to host
 dns.google.com: did not receive HSTS header (error ignored - included regardless)
@@ -909,22 +907,20 @@ do-do.tk: could not connect to host
 do.search.yahoo.com: did not receive HSTS header
 dobet.in: could not connect to host
 docket.news: could not connect to host
 docs.google.com: did not receive HSTS header (error ignored - included regardless)
 doeswindowssuckforeveryoneorjustme.com: could not connect to host
 dogbox.se: did not receive HSTS header
 dohosting.ru: could not connect to host
 dokan.online: could not connect to host
-doku-gilde.de: could not connect to host
 dollarstore24.com: could not connect to host
 dollywiki.co.uk: could not connect to host
 dolphin-cloud.com: could not connect to host
 dolphincorp.co.uk: could not connect to host
-domadillo.com: could not connect to host
 domaris.de: did not receive HSTS header
 dominique-mueller.de: did not receive HSTS header
 donttrustrobots.nl: could not connect to host
 donzelot.co.uk: max-age too low: 3600
 doomleika.com: could not connect to host
 dopost.it: could not connect to host
 doridian.com: could not connect to host
 doridian.de: could not connect to host
@@ -956,16 +952,17 @@ drtroyhendrickson.com: could not connect
 drumbandesperanto.nl: could not connect to host
 dshiv.io: 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
 duesee.org: could not connect to host
 duria.de: max-age too low: 3600
 dwhd.org: [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 121"  data: no]
+dworzak.ch: could not connect to host
 dycontrol.de: could not connect to host
 dylanscott.com.au: did not receive HSTS header
 dymersion.com: did not receive HSTS header
 dynamize.solutions: could not connect to host
 dzimejl.sk: did not receive HSTS header
 dzlibs.io: could not connect to host
 e-aut.net: could not connect to host
 e-deca2.org: did not receive HSTS header
@@ -991,27 +988,30 @@ edelsteincosmetic.com: max-age too low: 
 edissecurity.sk: did not receive HSTS header
 edix.ru: could not connect to host
 edk.com.tr: did not receive HSTS header
 edmodo.com: did not receive HSTS header
 edp-collaborative.com: max-age too low: 2500
 eduvance.in: did not receive HSTS header
 eeqj.com: could not connect to host
 efficienthealth.com: did not receive HSTS header
+effortlesshr.com: did not receive HSTS header
 egg-ortho.ch: did not receive HSTS header
 egit.co: could not connect to host
 ego-world.org: could not connect to host
 ehrenamt-skpfcw.de: could not connect to host
 eicfood.com: could not connect to host
 eidolonhost.com: could not connect to host
 ekbanden.nl: could not connect to host
 ekostecki.de: did not receive HSTS header
 el-soul.com: did not receive HSTS header
 elaintehtaat.fi: did not receive HSTS header
 elanguest.pl: could not connect to host
+elbetech.net: could not connect to host
+eldinhadzic.com: could not connect to host
 electricianforum.co.uk: could not connect to host
 electromc.com: could not connect to host
 elemprendedor.com.ve: could not connect to host
 elenag.ga: could not connect to host
 elenoon.ir: did not receive HSTS header
 elgacien.de: could not connect to host
 elimdengelen.com: did not receive HSTS header
 elisabeth-kostecki.de: did not receive HSTS header
@@ -1027,20 +1027,16 @@ emeldi-commerce.com: max-age too low: 0
 emjainteractive.com: did not receive HSTS header
 emmable.com: could not connect to host
 emnitech.com: could not connect to host
 empleostampico.com: did not receive HSTS header
 enargia.jp: max-age too low: 0
 encode.space: did not receive HSTS header
 encoder.pw: could not connect to host
 encrypted.google.com: did not receive HSTS header (error ignored - included regardless)
-endohaus.ca: could not connect to host
-endohaus.com: could not connect to host
-endohaus.eu: could not connect to host
-endohaus.us: could not connect to host
 endzeit-architekten.com: did not receive HSTS header
 engelwerbung.com: [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 121"  data: no]
 englishforums.com: could not connect to host
 enigmacpt.com: did not receive HSTS header
 enigmail.net: did not receive HSTS header
 enteente.club: could not connect to host
 enteente.space: could not connect to host
 enteente.xyz: could not connect to host
@@ -1058,45 +1054,47 @@ epoxate.com: did not receive HSTS header
 eq8.net.au: could not connect to host
 equate.net.au: max-age too low: 3600
 equatetechnologies.com.au: max-age too low: 3600
 equilibre-yoga-jennifer-will.com: could not connect to host
 erawanarifnugroho.com: did not receive HSTS header
 eressea.xyz: did not receive HSTS header
 ericbond.net: could not connect to host
 ericyl.com: did not receive HSTS header
+ernesto.at: could not connect to host
 eromixx.com: did not receive HSTS header
 erotalia.es: could not connect to host
 eroticen.com: did not receive HSTS header
 erotische-aanbiedingen.nl: could not connect to host
 errlytics.com: [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 121"  data: no]
 errolz.com: could not connect to host
 errors.zenpayroll.com: could not connect to host
 ersindemirtas.com: did not receive HSTS header
 esclear.de: did not receive HSTS header
 escotour.com: did not receive HSTS header
 esec.rs: did not receive HSTS header
 espra.com: could not connect to host
+esquonic.com: could not connect to host
 essexcosmeticdentists.co.uk: did not receive HSTS header
 essexghosthunters.co.uk: did not receive HSTS header
 estilosapeca.com: could not connect to host
 etdonline.co.uk: could not connect to host
 eternitylove.us: could not connect to host
 ethack.org: [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 121"  data: no]
 ethicalexploiting.com: could not connect to host
 etsysecure.com: could not connect to host
 etula.ga: could not connect to host
 etula.me: did not receive HSTS header
 euanbaines.com: did not receive HSTS header
 eucl3d.com: did not receive HSTS header
 euph.eu: could not connect to host
 euren.se: could not connect to host
 euroshop24.net: could not connect to host
 evantage.org: could not connect to host
-evdenevenakliyatankara.pw: could not connect to host
+evdenevenakliyatankara.pw: did not receive HSTS header
 everybooks.com: max-age too low: 60
 everylab.org: could not connect to host
 evi.be: did not receive HSTS header
 evin.ml: could not connect to host
 evomon.com: could not connect to host
 evossd.tk: could not connect to host
 exceltobarcode.com: did not receive HSTS header
 exfiles.cz: did not receive HSTS header
@@ -1133,16 +1131,17 @@ falkena.net: max-age too low: 5184000
 falkp.no: did not receive HSTS header
 familie-zimmermann.at: could not connect to host
 fanyl.cn: did not receive HSTS header
 fashioncare.cz: did not receive HSTS header
 fasset.jp: could not connect to host
 fastopen.ml: could not connect to host
 fatgeekflix.net: could not connect to host
 fatherhood.gov: did not receive HSTS header
+fatlossguide.xyz: could not connect to host
 fatox.de: could not connect to host
 fatwin.pw: could not connect to host
 fayolle.info: [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 121"  data: no]
 fbox.li: could not connect to host
 fdj.im: could not connect to host
 feard.space: could not connect to host
 fedux.com.ar: could not connect to host
 feezmodo.com: max-age too low: 0
@@ -1239,31 +1238,33 @@ frezbo.com: could not connect to host
 frforms.com: did not receive HSTS header
 friendica.ch: could not connect to host
 frizo.com: did not receive HSTS header
 froggstack.de: could not connect to host
 frontmin.com: did not receive HSTS header
 frost-ci.xyz: could not connect to host
 fruitusers.com: could not connect to host
 frusky.net: could not connect to host
+fsf.moe: could not connect to host
 ftctele.com: did not receive HSTS header
 fuckgfw233.org: could not connect to host
 fugle.de: could not connect to host
 fukushima-web.com: did not receive HSTS header
 funkyweddingideas.com.au: could not connect to host
 funrun.com: did not receive HSTS header
 furiffic.com: did not receive HSTS header
 furry.be: max-age too low: 86400
 fusionmate.com: could not connect to host
 futbol11.com: did not receive HSTS header
 futuretechnologi.es: could not connect to host
 futureyouhealth.com: did not receive HSTS header
 fx-rk.com: did not receive HSTS header
 fysiohaenraets.nl: did not receive HSTS header
 fzn.io: could not connect to host
+g01.in.ua: could not connect to host
 g2a.co: did not receive HSTS header
 g2g.com: did not receive HSTS header
 g4w.co: did not receive HSTS header (error ignored - included regardless)
 gabber.scot: could not connect to host
 gaelleetarnaud.com: did not receive HSTS header
 gaestehaus-monika.com: could not connect to host
 gafachi.com: could not connect to host
 gakkainavi4.com: could not connect to host
@@ -1284,17 +1285,17 @@ gamesdepartment.co.uk: max-age too low: 
 gamingmedia.eu: did not receive HSTS header
 gampenhof.de: did not receive HSTS header
 gaptek.id: did not receive HSTS header
 garciamartin.me: could not connect to host
 gatilagata.com.br: did not receive HSTS header
 gdpventure.com: max-age too low: 0
 gedankenbude.info: did not receive HSTS header
 geekbundle.org: did not receive HSTS header
-geekcast.co.uk: could not connect to host
+geekcast.co.uk: did not receive HSTS header
 geli-graphics.com: did not receive HSTS header
 gem-indonesia.net: could not connect to host
 genuu.com: could not connect to host
 genuxation.com: could not connect to host
 genyaa.com: could not connect to host
 gerencianet.com.br: did not receive HSTS header
 get.zenpayroll.com: did not receive HSTS header
 getable.com: did not receive HSTS header
@@ -1353,38 +1354,40 @@ goben.ch: could not connect to host
 goerner.me: did not receive HSTS header
 goge.site: could not connect to host
 gogenenglish.com: could not connect to host
 gogetssl.com: did not receive HSTS header
 gogold-g.com: could not connect to host
 gold24.in: 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: did not receive HSTS header
 gonzalosanchez.mx: did not receive HSTS header
 goodenough.nz: did not receive HSTS header
 goodwin43.ru: did not receive HSTS header
 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)
-goolok.com: did not receive HSTS header
 gorilla-gym.site: could not connect to host
 goto.google.com: did not receive HSTS header (error ignored - included regardless)
 gottcode.org: did not receive HSTS header
 govillemo.ca: did not receive HSTS header
 gowe.wang: could not connect to host
 gparent.org: did not receive HSTS header
 gpsfix.cz: could not connect to host
 gpstuner.com: did not receive HSTS header
 gracesofgrief.com: max-age too low: 86400
 grandmascookieblog.com: did not receive HSTS header
 graph.no: did not receive HSTS header
 gravity-net.de: could not connect to host
 graycell.net: could not connect to host
 grazetech.com: could not connect to host
+greboid.co.uk: could not connect to host
+greboid.com: could not connect to host
 greenhillantiques.co.uk: did not receive HSTS header
 greenvines.com.tw: did not receive HSTS header
 gregorytlee.me: did not receive HSTS header
 gremots.com: did not receive HSTS header
 greplin.com: could not connect to host
 gribani.com: could not connect to host
 grigalanzsoftware.com: could not connect to host
 grossmann.gr: could not connect to host
@@ -1429,16 +1432,17 @@ haitschi.de: could not connect to host
 haitschi.net: could not connect to host
 haitschi.org: could not connect to host
 haktec.de: could not connect to host
 haku.moe: could not connect to host
 hakugin.org: could not connect to host
 halo.red: could not connect to host
 hancc.net: did not receive HSTS header
 hanfu.la: could not connect to host
+hang333.pw: could not connect to host
 hannover-banditen.de: did not receive HSTS header
 hao2taiwan.com: max-age too low: 0
 haozi.me: could not connect to host
 happyfabric.me: did not receive HSTS header
 happygadget.me: could not connect to host
 harabuhouse.com: did not receive HSTS header
 harbor-light.net: did not receive HSTS header
 harmonycosmetic.com: max-age too low: 300
@@ -1471,16 +1475,17 @@ heftkaufen.de: did not receive HSTS head
 hellenicaward.com: did not receive HSTS header
 helloworldhost.com: did not receive HSTS header
 helpadmin.net: could not connect to host
 helpium.de: [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 121"  data: no]
 helpmebuild.com: did not receive HSTS header
 hemdal.se: could not connect to host
 hencagon.com: could not connect to host
 henriknoerr.com: could not connect to host
+hepteract.us: did not receive HSTS header
 hermes-net.de: did not receive HSTS header
 herpaderp.net: did not receive HSTS header
 herzbotschaft.de: did not receive HSTS header
 hibilog.com: could not connect to host
 hicn.gq: could not connect to host
 hiddendepth.ie: max-age too low: 0
 hiddenmail.xyz: could not connect to host
 highseer.com: did not receive HSTS header
@@ -1504,17 +1509,16 @@ homa.website: could not connect to host
 honeytracks.com: [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 121"  data: no]
 hongzhaxiaofendui.com: could not connect to host
 honoo.com: could not connect to host
 hookandloom.com: did not receive HSTS header
 horosho.in: could not connect to host
 horseboners.xxx: did not receive HSTS header
 hortifarm.ro: did not receive HSTS header
 hosted-service.com: did not receive HSTS header
-hostedbgp.net: could not connect to host
 hostedtalkgadget.google.com: did not receive HSTS header (error ignored - included regardless)
 hostgarou.com: did not receive HSTS header
 hostinaus.com.au: could not connect to host
 hostisan.com: did not receive HSTS header
 hotchillibox.com: max-age too low: 0
 hotchoc.io: did not receive HSTS header
 hotting.nl: could not connect to host
 houkago-step.com: did not receive HSTS header
@@ -1524,21 +1528,21 @@ howbigismybuilding.com: [Exception... "C
 howrandom.org: could not connect to host
 hr-intranet.com: did not receive HSTS header
 hsir.me: could not connect to host
 hsts.date: could not connect to host
 http418.xyz: could not connect to host
 httpstatuscode418.xyz: could not connect to host
 hu.search.yahoo.com: did not receive HSTS header
 huarongdao.com: did not receive HSTS header
-hugofs.com: could not connect to host
 hugosleep.com.au: did not receive HSTS header
 humblefinances.com: could not connect to host
 humeurs.net: could not connect to host
 humpteedumptee.in: did not receive HSTS header
+huntshomeinspections.com: [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 121"  data: no]
 hurricanelabs.com: did not receive HSTS header
 hydra.ws: could not connect to host
 hyper69.com: did not receive HSTS header
 hzsh.xyz: max-age too low: 0
 i-jp.net: could not connect to host
 i-partners.sk: did not receive HSTS header
 iamokay.nl: did not receive HSTS header
 iamveto.com: could not connect to host
@@ -1695,16 +1699,17 @@ jakenbake.com: did not receive HSTS head
 jakubtopic.cz: could not connect to host
 jamesbradach.com: did not receive HSTS header
 jamesburton.london: could not connect to host
 jamesbywater.me: could not connect to host
 jamesbywater.me.uk: could not connect to host
 jamesconroyfinn.com: did not receive HSTS header
 jamesdoell.com: could not connect to host
 jamesdoylephoto.com: did not receive HSTS header
+jamesf.xyz: could not connect to host
 jamesmorrison.me: did not receive HSTS header
 jamourtney.com: could not connect to host
 jan27.org: did not receive HSTS header
 janario.me: could not connect to host
 janbrodda.de: max-age too low: 2592000
 jannyrijneveld.nl: did not receive HSTS header
 janus-engineering.de: did not receive HSTS header
 japlex.com: could not connect to host
@@ -1725,17 +1730,16 @@ jayshao.com: did not receive HSTS header
 jazzinutrecht.info: [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 121"  data: no]
 jbbd.fr: could not connect to host
 jbfp.dk: could not connect to host
 jbn.mx: could not connect to host
 jbradaric.me: could not connect to host
 jcch.de: could not connect to host
 jcor.me: did not receive HSTS header
 jctf.io: could not connect to host
-jdh8.org: could not connect to host
 jeff393.com: could not connect to host
 jefftickle.com: could not connect to host
 jenjoit.de: could not connect to host
 jensenbanden.no: could not connect to host
 jeremye77.com: could not connect to host
 jesorsenville.com: did not receive HSTS header
 jessicabenedictus.nl: could not connect to host
 jetaprices.com: max-age too low: 0
@@ -1753,17 +1757,16 @@ jhejderup.me: could not connect to host
 jia1hao.com: could not connect to host
 jikken.de: could not connect to host
 jimas.eu: did not receive HSTS header
 jimmycai.org: max-age too low: 10368000
 jinbo123.com: did not receive HSTS header
 jkb.pics: could not connect to host
 jkbuster.com: could not connect to host
 jmdekker.it: could not connect to host
-jmk.hu: did not receive HSTS header
 joakimalgroy.com: could not connect to host
 jobmedic.com: did not receive HSTS header
 joedavison.me: could not connect to host
 johnbrownphotography.ch: did not receive HSTS header
 johners.me: could not connect to host
 johners.tech: did not receive HSTS header
 johnhgaunt.com: did not receive HSTS header
 johnrom.com: did not receive HSTS header
@@ -1784,42 +1787,41 @@ jrc9.ca: did not receive HSTS header
 jrgold.me: could not connect to host
 jrvar.com: did not receive HSTS header
 jsanders.us: did not receive HSTS header
 jslay.net: could not connect to host
 jualautoclave.com: did not receive HSTS header
 jualssh.com: could not connect to host
 juliamweber.de: [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 121"  data: no]
 julian-kipka.de: did not receive HSTS header
-julibear.com: could not connect to host
 jumbox.xyz: could not connect to host
 junaos.xyz: did not receive HSTS header
 junge-selbsthilfe.info: could not connect to host
 junqtion.com: could not connect to host
 jupp0r.de: did not receive HSTS header
 justlikethat.hosting: did not receive HSTS header
 justnaw.co.uk: could not connect to host
 justudin.com: did not receive HSTS header
 juwairen.cn: could not connect to host
 jvoice.net: could not connect to host
 jwilsson.me: could not connect to host
 jxm.in: could not connect to host
-jznet.org: did not receive HSTS header
 k-dev.de: could not connect to host
 ka-clan.com: could not connect to host
 kabuabc.com: did not receive HSTS header
 kabus.org: could not connect to host
 kadioglumakina.com.tr: did not receive HSTS header
 kahopoon.net: could not connect to host
 kaisers.de: did not receive HSTS header
 kalami.nl: did not receive HSTS header
 kamikano.com: could not connect to host
 kaplatz.is: could not connect to host
 kapucini.si: max-age too low: 0
 karaoketonight.com: could not connect to host
+kasilag.me: did not receive HSTS header
 katiaetdavid.fr: could not connect to host
 katproxy.online: could not connect to host
 katproxy.site: could not connect to host
 katproxy.tech: could not connect to host
 kaufkraftkiel.de: could not connect to host
 kausch.at: could not connect to host
 kawaii.io: could not connect to host
 kawaiiku.com: could not connect to host
@@ -1837,28 +1839,27 @@ kermadec.net: could not connect to host
 kernl.us: did not receive HSTS header
 kevinapease.com: could not connect to host
 keymaster.lookout.com: did not receive HSTS header
 kg-rating.com: did not receive HSTS header
 kgxtech.com: max-age too low: 2592000
 kickass.al: could not connect to host
 kid-dachau.de: did not receive HSTS header
 kiel-media.de: did not receive HSTS header
-kilianvalkhof.com: did not receive HSTS header
 kimpost.org: could not connect to host
 kinderwagen-test24.de: could not connect to host
 kingmanhall.org: could not connect to host
 kinnon.enterprises: could not connect to host
 kinogb.net: max-age too low: 0
 kionetworks.com: did not receive HSTS header
 kipira.com: could not connect to host
-kirbear.com: could not connect to host
 kirkforcongress.com: could not connect to host
 kirkforsenate.com: did not receive HSTS header
 kirkpatrickdavis.com: could not connect to host
+kisa.io: could not connect to host
 kisalt.im: did not receive HSTS header
 kissart.net: could not connect to host
 kissflow.com: did not receive HSTS header
 kitakemon.com: could not connect to host
 kitchenpunx.com: [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 121"  data: no]
 kitk.at: could not connect to host
 kitsta.com: could not connect to host
 kiwiirc.com: max-age too low: 5256000
@@ -1886,17 +1887,16 @@ koordinate.net: could not connect to hos
 korni22.org: did not receive HSTS header
 korsanparti.org: could not connect to host
 kotonehoko.net: could not connect to host
 kotovstyle.ru: could not connect to host
 kr.search.yahoo.com: did not receive HSTS header
 kraynik.com: could not connect to host
 kredite.sale: could not connect to host
 kriegt.es: could not connect to host
-krislamoureux.com: could not connect to host
 krmela.com: could not connect to host
 kroetenfuchs.de: could not connect to host
 kropkait.pl: could not connect to host
 krouzkyliduska.cz: [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 121"  data: no]
 krunut.com: did not receive HSTS header
 krypteia.org: could not connect to host
 ksfh-mail.de: could not connect to host
 kstan.me: could not connect to host
@@ -1957,17 +1957,16 @@ lemp.io: did not receive HSTS header
 lenovogaming.com: did not receive HSTS header
 lentri.com: did not receive HSTS header
 leolana.com: could not connect to host
 leon-jaekel.com: could not connect to host
 leopold.email: could not connect to host
 leopoldina.net: did not receive HSTS header
 leopotamgroup.com: could not connect to host
 leovanna.co.uk: [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 121"  data: no]
-leppis-it.de: could not connect to host
 lerasenglish.com: did not receive HSTS header
 lerner.moscow: did not receive HSTS header
 les-corsaires.net: could not connect to host
 lesdouceursdeliyana.com: could not connect to host
 letras.mus.br: did not receive HSTS header
 letsmultiplayerplay.com: did not receive HSTS header
 letustravel.tk: could not connect to host
 lfullerdesign.com: did not receive HSTS header
@@ -1991,42 +1990,42 @@ librechan.net: could not connect to host
 liduan.com: could not connect to host
 liduan.net: could not connect to host
 lifeguard.aecom.com: did not receive HSTS header
 lifeinitsownway.com: did not receive HSTS header
 lifestylehunter.co.uk: did not receive HSTS header
 lifetimemoneymachine.com: did not receive HSTS header
 lightarmory.com: could not connect to host
 lightpaste.com: could not connect to host
-likeaross.com: could not connect to host
 lillpopp.eu: max-age too low: 10
 lilpwny.com: could not connect to host
 limalama.eu: max-age too low: 1
 limiteddata.co.uk: could not connect to host
 limpido.it: could not connect to host
 lindberg.io: did not receive HSTS header
 lingros-test.tk: could not connect to host
 linguaquote.com: did not receive HSTS header
-linkenheil.org: could not connect to host
+linkages.org: could not connect to host
 linmi.cc: did not receive HSTS header
 linorman1997.me: could not connect to host
 linuxeyecandy.com: could not connect to host
 linuxfixed.it: could not connect to host
 linuxgeek.ro: could not connect to host
 liquorsanthe.in: could not connect to host
 listafirmelor.com: could not connect to host
 litespeed.io: could not connect to host
 livedemo.io: could not connect to host
 livej.am: could not connect to host
 livi.co: did not receive HSTS header
 lmerza.com: could not connect to host
 loafbox.com: could not connect to host
 locktheirphone.com: could not connect to host
 locomotive.ca: did not receive HSTS header
 login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless)
+login.gov: could not connect to host
 loginseite.com: could not connect to host
 loli.bz: could not connect to host
 lolicore.ch: could not connect to host
 lonal.com: could not connect to host
 lookastic.co.uk: [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 121"  data: no]
 lookastic.com: [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 121"  data: no]
 lookastic.de: [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 121"  data: no]
 lookastic.es: [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 121"  data: no]
@@ -2070,26 +2069,26 @@ luoxiao.im: could not connect to host
 lusis.fr: did not receive HSTS header
 lusis.net: did not receive HSTS header
 lustrumxi.nl: did not receive HSTS header
 luxus-russen.de: did not receive HSTS header
 luxwatch.com: could not connect to host
 lv.search.yahoo.com: did not receive HSTS header
 lzkill.com: could not connect to host
 m-ali.xyz: did not receive HSTS header
-m-plan.com: did not receive HSTS header
 m.gparent.org: could not connect to host
 m.nu: did not receive HSTS header
 m3-gmbh.de: did not receive HSTS header
 m82labs.com: did not receive HSTS header
 maarten.nyc: did not receive HSTS header
 maartenvandekamp.nl: did not receive HSTS header
 macbolo.com: could not connect to host
 macchaberrycream.com: could not connect to host
 macchedil.com: did not receive HSTS header
+macgeneral.de: did not receive HSTS header
 madars.org: did not receive HSTS header
 maddin.ga: could not connect to host
 madebymagnitude.com: did not receive HSTS header
 maderwin.com: did not receive HSTS header
 madusecurity.com: could not connect to host
 mafamane.com: could not connect to host
 mafiareturns.com: max-age too low: 2592000
 magenx.com: did not receive HSTS header
@@ -2206,21 +2205,20 @@ midwestwomenworkers.org: did not receive
 mightydicks.io: could not connect to host
 mightydicks.tech: could not connect to host
 mightysounds.cz: max-age too low: 0
 mijcorijneveld.nl: did not receive HSTS header
 mijn-email.org: could not connect to host
 mikaelemilsson.net: did not receive HSTS header
 mikeburns.com: could not connect to host
 mikeg.de: did not receive HSTS header
-mikek.work: did not receive HSTS header
 mikeology.org: could not connect to host
 mikonmaa.fi: could not connect to host
 miku.be: could not connect to host
-miku.hatsune.my: could not connect to host
+miku.hatsune.my: max-age too low: 5184000
 milesgeek.com: did not receive HSTS header
 mindoktor.se: did not receive HSTS header
 minecraftserverz.com: could not connect to host
 minecraftvoter.com: could not connect to host
 minikneet.nl: did not receive HSTS header
 minnesotadata.com: could not connect to host
 mirindadomo.ru: did not receive HSTS header
 mironized.com: did not receive HSTS header
@@ -2259,16 +2257,17 @@ mondopoint.com: could not connect to hos
 monitman.com: could not connect to host
 moon.lc: could not connect to host
 moparisthebest.biz: could not connect to host
 moparisthebest.info: could not connect to host
 moparscape.org: did not receive HSTS header
 mor.gl: could not connect to host
 morbitzer.de: did not receive HSTS header
 morethanadream.lv: could not connect to host
+morganino.eu: could not connect to host
 moriz.net: could not connect to host
 morningcalculation.com: could not connect to host
 morotech.com.br: max-age too low: 2592000
 morpork.xyz: could not connect to host
 mortgagecentersmo.com: did not receive HSTS header
 mostwuat.com: could not connect to host
 motherbase.io: could not connect to host
 motionpicturesolutions.com: could not connect to host
@@ -2324,17 +2323,16 @@ mypagella.eu: could not connect to host
 mypagella.it: could not connect to host
 myplaceonline.com: did not receive HSTS header
 mysecretrewards.com: did not receive HSTS header
 mysmelly.com: could not connect to host
 mystudy.me: [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 121"  data: no]
 myvirtualserver.com: max-age too low: 2592000
 myzone.com: did not receive HSTS header
 mziulu.me: could not connect to host
-n-soft.info: could not connect to host
 n0psled.nl: could not connect to host
 n2x.in: could not connect to host
 n4l.pw: could not connect to host
 nagoya-kyuyo.com: could not connect to host
 naiharngym.com: did not receive HSTS header
 najedlo.sk: did not receive HSTS header
 nakliyatsirketi.biz: could not connect to host
 nalifornia.com: did not receive HSTS header
@@ -2353,18 +2351,16 @@ naval.tf: could not connect to host
 navigate-it-services.de: max-age too low: 0
 navjobs.com: did not receive HSTS header
 nbb.io: could not connect to host
 nbg-ha.de: could not connect to host
 ncc60205.info: could not connect to host
 ncpc.gov: could not connect to host
 nct.org.uk: max-age too low: 1
 nctx.co.uk: did not receive HSTS header
-ndtblog.com: could not connect to host
-ndtmarket.place: could not connect to host
 near.st: did not receive HSTS header
 neel.ch: could not connect to host
 neftaly.com: did not receive HSTS header
 negai.moe: could not connect to host
 neilgreen.net: did not receive HSTS header
 neko-life.com: did not receive HSTS header
 neko-system.com: did not receive HSTS header
 nella-project.org: could not connect to host
@@ -2402,34 +2398,33 @@ ng-security.com: could not connect to ho
 ngine.ch: did not receive HSTS header
 nginxnudes.com: could not connect to host
 ni.search.yahoo.com: did not receive HSTS header
 nibiisclaim.com: could not connect to host
 nicestresser.fr: could not connect to host
 nicky.io: did not receive HSTS header
 nicolasbettag.me: could not connect to host
 niconiconi.xyz: could not connect to host
-niconode.com: could not connect to host
+niconode.com: did not receive HSTS header
 nien.chat: could not connect to host
 nightx.uk: could not connect to host
 niho.jp: [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 121"  data: no]
 nikomo.fi: could not connect to host
 nilrem.org: could not connect to host
 ninchisho-online.com: did not receive HSTS header
 ninhs.org: could not connect to host
 nippler.org: did not receive HSTS header
 nippombashi.net: did not receive HSTS header
 nipponcareers.com: did not receive HSTS header
 nixien.fr: could not connect to host
 nkinka.de: did not receive HSTS header
 nmctest.net: could not connect to host
 nnya.cat: did not receive HSTS header
 no17sifangjie.cc: could not connect to host
 nocallaghan.com: could not connect to host
-nocit.dk: could not connect to host
 nocs.cn: did not receive HSTS header
 noctinus.tk: could not connect to host
 nodari.com.ar: did not receive HSTS header
 nodebrewery.com: could not connect to host
 nodetemple.com: could not connect to host
 noexpect.org: could not connect to host
 noima.com: did not receive HSTS header
 nojestorget.se: could not connect to host
@@ -2477,28 +2472,28 @@ nuos.org: could not connect to host
 nutleyeducationalfoundation.org: did not receive HSTS header
 nutleyef.org: did not receive HSTS header
 nutrienti.eu: did not receive HSTS header
 nutritionculture.com: could not connect to host
 nutsandboltsmedia.com: did not receive HSTS header
 nwgh.org: max-age too low: 86400
 nyantec.com: did not receive HSTS header
 nysepho.pw: could not connect to host
-nystart.no: did not receive HSTS header
+nystart.no: could not connect to host
 nz.search.yahoo.com: max-age too low: 172800
 nzb.cat: max-age too low: 7776000
 o0o.one: did not receive HSTS header
 oasis.mobi: did not receive HSTS header
 oasisim.net: [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 121"  data: no]
 obsydian.org: could not connect to host
 occentus.net: did not receive HSTS header
 ochaken.cf: could not connect to host
 octothorpe.club: could not connect to host
 odifi.com: could not connect to host
-odin.xxx: could not connect to host
+odin.xxx: did not receive HSTS header
 oe8.bet: could not connect to host
 ofcourselanguages.com: could not connect to host
 offshore-firma.org: could not connect to host
 oishioffice.com: did not receive HSTS header
 okane.love: could not connect to host
 okok.rent: could not connect to host
 okutama.in.th: could not connect to host
 oliver-pietsch.de: did not receive HSTS header
@@ -2614,30 +2609,31 @@ passwordbox.com: did not receive HSTS he
 passwordrevelator.net: did not receive HSTS header
 passwords.google.com: did not receive HSTS header (error ignored - included regardless)
 pastaf.com: could not connect to host
 paste.fedoraproject.org: did not receive HSTS header
 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
-pastie.se: did not receive HSTS header
 patientinsight.net: could not connect to host
 patrz.eu: could not connect to host
 patt.us: did not receive HSTS header
 patterson.mp: could not connect to host
 paulchen.at: did not receive HSTS header
 paulyang.cn: did not receive HSTS header
 paxwinkel.nl: did not receive HSTS header
 pay.gigahost.dk: did not receive HSTS header
 payments.google.com: did not receive HSTS header (error ignored - included regardless)
 payroll.ch: did not receive HSTS header
 pbapp.net: did not receive HSTS header
 pbprint.ru: max-age too low: 0
 pc-nf.de: could not connect to host
+pcfeuerwehr.de: did not receive HSTS header
+pcfun.net: did not receive HSTS header
 pchax.net: did not receive HSTS header
 peissen.com: [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 121"  data: no]
 pekkapikkarainen.fi: could not connect to host
 pekkarik.ru: could not connect to host
 penguinclientsystem.com: did not receive HSTS header
 pensacolawinterfest.org: could not connect to host
 pentagram.me: could not connect to host
 pepperhead.com: could not connect to host
@@ -2668,17 +2664,17 @@ picotronic.biz: could not connect to hos
 picscare.co.uk: did not receive HSTS header
 pijuice.com: could not connect to host
 piligrimname.com: could not connect to host
 pinesandneedles.com: did not receive HSTS header
 pippen.io: could not connect to host
 pir9.com: max-age too low: 2592000
 piratedb.com: could not connect to host
 piratedot.com: could not connect to host
-piratelist.online: did not receive HSTS header
+piratelist.online: could not connect to host
 piratenlogin.de: could not connect to host
 pirati.cz: max-age too low: 604800
 pirlitu.com: did not receive HSTS header
 pisexy.me: did not receive HSTS header
 pisidia.de: could not connect to host
 pittonpreschool.com: did not receive HSTS header
 piwko.co: could not connect to host
 pixel.google.com: did not receive HSTS header (error ignored - included regardless)
@@ -2704,28 +2700,30 @@ pmnts.io: could not connect to host
 po.gl: did not receive HSTS header
 poiema.com.sg: did not receive HSTS header
 pol.in.th: could not connect to host
 pole.net.nz: did not receive HSTS header
 poleartschool.com: could not connect to host
 polimat.org: could not connect to host
 politically-incorrect.xyz: could not connect to host
 politologos.org: could not connect to host
+polymathematician.com: could not connect to host
 polypho.nyc: could not connect to host
 pompompoes.com: could not connect to host
 pontokay.com.br: did not receive HSTS header
 pontualcomp.com: max-age too low: 2592000
 poolsandstuff.com: did not receive HSTS header
 poon.tech: could not connect to host
 poris.web.id: did not receive HSTS header
 portalplatform.net: did not receive HSTS header
 postcodewise.co.uk: did not receive HSTS header
 posterspy.com: did not receive HSTS header
 postscheduler.org: could not connect to host
 posylka.de: did not receive HSTS header
+potatofrom.space: could not connect to host
 poussinooz.fr: could not connect to host
 povitria.net: could not connect to host
 power-of-interest.com: did not receive HSTS header
 power99press.com: did not receive HSTS header
 powerplannerapp.com: did not receive HSTS header
 powerxequality.com: could not connect to host
 ppr-truby.ru: could not connect to host
 pr.search.yahoo.com: did not receive HSTS header
@@ -2739,33 +2737,33 @@ prezola.com: did not receive HSTS header
 printfn.com: could not connect to host
 priolkar.com: did not receive HSTS header
 priva.si: could not connect to host
 privacylabs.io: did not receive HSTS header
 privacyrup.net: could not connect to host
 prnt.li: did not receive HSTS header
 pro-zone.com: could not connect to host
 prodpad.com: did not receive HSTS header
-production.vn: did not receive HSTS header
+production.vn: could not connect to host
 professionalboundaries.com: did not receive HSTS header
 profi-durchgangsmelder.de: did not receive HSTS header
 profundr.com: could not connect to host
 progg.no: could not connect to host
 prohostonline.fi: could not connect to host
+proj.org.cn: could not connect to host
 promecon-gmbh.de: did not receive HSTS header
 prontolight.com: did not receive HSTS header
 prosocialmachines.com: could not connect to host
 prosoft.sk: max-age too low: 0
 prosperident.com: did not receive HSTS header
 prowhisky.de: did not receive HSTS header
 proximato.com: could not connect to host
 proxybay.al: could not connect to host
 proxybay.club: could not connect to host
 proxybay.info: did not receive HSTS header
-prxio.date: could not connect to host
 prxio.site: could not connect to host
 prytkov.com: did not receive HSTS header
 psw.academy: did not receive HSTS header
 psw.consulting: did not receive HSTS header
 ptn.moscow: could not connect to host
 ptonet.com: did not receive HSTS header
 pubkey.is: could not connect to host
 puiterwijk.org: could not connect to host
@@ -2777,31 +2775,31 @@ purplestar.mobi: did not receive HSTS he
 pushapp.org: did not receive HSTS header
 pwd.ovh: could not connect to host
 pwnies.dk: could not connect to host
 py.search.yahoo.com: did not receive HSTS header
 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
+pzme.me: did not receive HSTS header
 q2.si: did not receive HSTS header
 qingxuan.info: max-age too low: 864000
 qinxi1992.com: did not receive HSTS header
 qiwi.be: did not receive HSTS header
 qorm.co.uk: did not receive HSTS header
 qrara.net: did not receive HSTS header
 qrlending.com: did not receive HSTS header
 quail.solutions: could not connect to host
 quantacloud.ch: could not connect to host
 quantenteranik.eu: could not connect to host
 quantumcourse.org: did not receive HSTS header
 queercoders.com: did not receive HSTS header
 quemmeliga.com: could not connect to host
 questsandrewards.com: could not connect to host
-quotehex.com: did not receive HSTS header
 quranserver.net: could not connect to host
 qvi.st: did not receive HSTS header
 qwaser.fr: could not connect to host
 qwilink.me: did not receive HSTS header
 r10n.com: did not receive HSTS header
 r15.me: could not connect to host
 r3bl.me: did not receive HSTS header
 raajheshkannaa.com: could not connect to host
@@ -2809,17 +2807,17 @@ radicaleducation.net: could not connect 
 radiormi.com: did not receive HSTS header
 rafaelcz.de: could not connect to host
 rainbowbarracuda.com: could not connect to host
 ramonj.nl: could not connect to host
 randomcage.com: did not receive HSTS header
 rankthespot.com: did not receive HSTS header
 rapidresearch.me: could not connect to host
 rapidthunder.io: could not connect to host
-rasing.me: did not receive HSTS header
+rasing.me: could not connect to host
 ratajczak.fr: could not connect to host
 raulfraile.net: could not connect to host
 rawet.se: did not receive HSTS header
 rawstorieslondon.com: could not connect to host
 raydobe.me: could not connect to host
 rc4.io: did not receive HSTS header
 rcafox.com: could not connect to host
 rcpcbd.com: did not receive HSTS header
@@ -2843,22 +2841,22 @@ regenerescence.com: did not receive HSTS
 reggae-cdmx.com: did not receive HSTS header
 reic.me: could not connect to host
 reisyukaku.org: did not receive HSTS header
 rejo.in: could not connect to host
 relisten.nl: did not receive HSTS header
 remitatm.com: could not connect to host
 remodela.com.ve: could not connect to host
 renem.net: did not receive HSTS header
-renideo.fr: did not receive HSTS header
 renlong.org: could not connect to host
 renrenss.com: did not receive HSTS header
 rent-a-coder.de: did not receive HSTS header
 rentcarassist.com: could not connect to host
 renteater.com: could not connect to host
+repaxan.com: could not connect to host
 replacemychina.com: did not receive HSTS header
 reprolife.co.uk: max-age too low: 0
 res-rheingau.de: did not receive HSTS header
 res42.com: could not connect to host
 reserve-online.net: did not receive HSTS header
 respice.xyz: could not connect to host
 respostas.com.br: did not receive HSTS header
 restchart.com: did not receive HSTS header
@@ -2885,21 +2883,19 @@ ring0.xyz: did not receive HSTS header
 ringh.am: could not connect to host
 rippleunion.com: could not connect to host
 riskmgt.com.au: could not connect to host
 rj.gg: could not connect to host
 rk6.cz: could not connect to host
 rkmantpur.org: did not receive HSTS header
 rme.li: did not receive HSTS header
 roan24.pl: did not receive HSTS header
-robandjanine.com: could not connect to host
 robertglastra.com: could not connect to host
 robigalia.org: did not receive HSTS header
 robin.info: could not connect to host
-robspc.repair: could not connect to host
 robtex.org: did not receive HSTS header
 rochman.id: could not connect to host
 rocksberg.net: did not receive HSTS header
 roddis.net: did not receive HSTS header
 rodney.id.au: did not receive HSTS header
 rodosto.com: did not receive HSTS header
 roeper.party: could not connect to host
 romans-place.me.uk: did not receive HSTS header
@@ -2972,20 +2968,18 @@ satsukii.moe: did not receive HSTS heade
 saturngames.co.uk: did not receive HSTS header
 saunasandstuff.ca: did not receive HSTS header
 saunasandstuff.com: did not receive HSTS header
 save.gov: could not connect to host
 saveaward.gov: could not connect to host
 saveyour.biz: did not receive HSTS header
 sawamura-rental.com: did not receive HSTS header
 sb-group.dk: did not receive HSTS header
-sbiewald.de: could not connect to host
 sby.de: did not receive HSTS header
 sc4le.com: could not connect to host
-scannabi.com: could not connect to host
 schmitz.link: could not connect to host
 schnell-gold.com: could not connect to host
 schoop.me: [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 121"  data: no]
 schrauger.run: could not connect to host
 schreiber-netzwerk.eu: did not receive HSTS header
 schrodinger.io: could not connect to host
 scienceathome.org: did not receive HSTS header
 scooshonline.co.uk: did not receive HSTS header
@@ -2996,17 +2990,16 @@ scrapings.net: could not connect to host
 screencaster.io: did not receive HSTS header
 screenresolution.space: could not connect to host
 scribe.systems: could not connect to host
 script.google.com: did not receive HSTS header (error ignored - included regardless)
 scriptict.nl: 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
-sealbaker.com: could not connect to host
 search-one.de: did not receive HSTS header
 sebastian-lutsch.de: could not connect to host
 sebster.com: did not receive HSTS header
 secandtech.com: could not connect to host
 sectia22.ro: could not connect to host
 sectun.com: did not receive HSTS header
 secure-games.us: could not connect to host
 secureradio.net: could not connect to host
@@ -3042,16 +3035,17 @@ seon.me: did not receive HSTS header
 seowarp.net: did not receive HSTS header
 seq.tf: did not receive HSTS header
 serfdom.io: did not receive HSTS header
 serized.pw: could not connect to host
 servercode.ca: did not receive HSTS header
 serverdensity.io: did not receive HSTS header
 servergno.me: did not receive HSTS header
 seryo.moe: could not connect to host
+sesha.co.za: 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
 sgcaccounts.co.uk: could not connect to host
 shadoom.com: did not receive HSTS header
 shadowmorph.info: did not receive HSTS header
 shadowsocks.net: could not connect to host
@@ -3151,34 +3145,36 @@ sobotkama.eu: did not receive HSTS heade
 soccergif.com: could not connect to host
 soci.ml: did not receive HSTS header
 socialbillboard.com: could not connect to host
 socialdevelop.biz: did not receive HSTS header
 socialhams.net: did not receive HSTS header
 socialhead.io: could not connect to host
 socialspirit.com.br: did not receive HSTS header
 sockeye.cc: could not connect to host
-socomponents.co.uk: could not connect to host
+socomponents.co.uk: did not receive HSTS header
 sodiao.cc: could not connect to host
 sogeek.me: did not receive HSTS header
 solidfuelappliancespares.co.uk: did not receive HSTS header
 solinter.com.br: did not receive HSTS header
 soll-i.ch: did not receive HSTS header
 solsystems.ru: could not connect to host
 someshit.xyz: could not connect to host
 somethingnew.xyz: did not receive HSTS header
 songzhuolun.com: did not receive HSTS header
 sonic.sk: max-age too low: 0
 sonicrainboom.rocks: did not receive HSTS header
+sorenstudios.com: could not connect to host
 sotar.us: [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 121"  data: no]
 sotor.de: did not receive HSTS header
 soulboy.io: did not receive HSTS header
 soulema.com: [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 121"  data: no]
 soulfulglamour.uk: could not connect to host
 sourcelair.com: did not receive HSTS header
+sourceway.de: could not connect to host
 southside-crew.club: could not connect to host
 southworcestershiregpservices.co.uk: could not connect to host
 souyar.de: could not connect to host
 souyar.net: could not connect to host
 souyar.us: could not connect to host
 sovereignshare.com: could not connect to host
 sown.dyndns.org: could not connect to host
 spacecafe.org: could not connect to host
@@ -3207,17 +3203,17 @@ sportwette.eu: did not receive HSTS head
 spot-events.com: could not connect to host
 spotlightsrule.ddns.net: could not connect to host
 spreadsheets.google.com: did not receive HSTS header (error ignored - included regardless)
 spreed.me: did not receive HSTS header
 sproutconnections.com: did not receive HSTS header
 sprybear.com: did not receive HSTS header
 square.gs: could not connect to host
 squatldf.org: [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 121"  data: no]
-sqzryang.com: max-age too low: 604800
+sqzryang.com: did not receive HSTS header
 srevilak.net: did not receive HSTS header
 srna.sk: could not connect to host
 srrr.ca: could not connect to host
 ss.wtf: did not receive HSTS header
 ssersay.com: max-age too low: 0
 ssl.panoramio.com: did not receive HSTS header
 ssl.rip: could not connect to host
 ssmato.me: could not connect to host
@@ -3270,16 +3266,17 @@ studybay.com: did not receive HSTS heade
 studydrive.net: did not receive HSTS header
 stugb.de: did not receive HSTS header
 stupendous.net: could not connect to host
 stw-group.at: could not connect to host
 subbing.work: could not connect to host
 subdimension.org: did not receive HSTS header
 subrosa.io: could not connect to host
 subtitle.rip: could not connect to host
+succ.in: could not connect to host
 sudo.li: did not receive HSTS header
 suite73.org: could not connect to host
 suitocracy.com: did not receive HSTS header
 suksit.com: could not connect to host
 sumoatm.com: did not receive HSTS header
 sumoscout.de: did not receive HSTS header
 suncountrymarine.com: did not receive HSTS header
 sunflyer.cn: did not receive HSTS header
@@ -3310,17 +3307,17 @@ syncserve.net: did not receive HSTS head
 syneic.com: did not receive HSTS header
 syno.gq: could not connect to host
 sysadmin.xyz: could not connect to host
 syso.name: could not connect to host
 szaszm.tk: max-age too low: 0
 t.facebook.com: did not receive HSTS header
 taabe.xyz: did not receive HSTS header
 tablet.facebook.com: did not receive HSTS header
-tacomafia.net: did not receive HSTS header
+tacomafia.net: could not connect to host
 tadigitalstore.com: could not connect to host
 tafoma.com: did not receive HSTS header
 tageau.com: could not connect to host
 taglondon.org: did not receive HSTS header
 tails.com.ar: could not connect to host
 talk.google.com: did not receive HSTS header (error ignored - included regardless)
 talktwincities.com: could not connect to host
 tallr.se: could not connect to host
@@ -3411,17 +3408,16 @@ therewill.be: could not connect to host
 thestack.xyz: could not connect to host
 thestagchorleywood.co.uk: did not receive HSTS header
 thetomharling.com: max-age too low: 86400
 thetradinghall.com: could not connect to host
 theurbanyoga.com: did not receive HSTS header
 thevintagenews.com: [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 121"  data: no]
 thezonders.com: did not receive HSTS header
 thierfreund.de: could not connect to host
-thingies.site: could not connect to host
 thinkcoding.de: could not connect to host
 thinlyveiledcontempt.com: could not connect to host
 thirdpartytrade.com: did not receive HSTS header
 thirty5.net: did not receive HSTS header
 thiswebhost.com: did not receive HSTS header
 thomaswoo.com: could not connect to host
 thorncreek.net: did not receive HSTS header
 thriveapproach.co.uk: did not receive HSTS header
@@ -3454,23 +3450,23 @@ tmitchell.io: could not connect to host
 tmprod.com: did not receive HSTS header
 tncnanet.com.br: could not connect to host
 tnrsca.jp: did not receive HSTS header
 tobiasmathes.com: could not connect to host
 tobiasmathes.name: could not connect to host
 tobiasofficial.at: could not connect to host
 todo.is: did not receive HSTS header
 todobazar.es: could not connect to host
+tokage.me: could not connect to host
 tokyopopline.com: did not receive HSTS header
 tollmanz.com: did not receive HSTS header
 tomberek.info: could not connect to host
 tomeara.net: could not connect to host
 tomharling.co.uk: max-age too low: 86400
 tomharling.uk: max-age too low: 86400
-tomharris.tech: could not connect to host
 tomlankhorst.nl: did not receive HSTS header
 tommsy.com: did not receive HSTS header
 tonburi.jp: [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 121"  data: no]
 tonyfantjr.com: could not connect to host
 toomanypillows.com: could not connect to host
 topbargains.com.au: did not receive HSTS header
 topdevbox.net: could not connect to host
 topmarine.se: could not connect to host
@@ -3531,17 +3527,16 @@ tx041cap.org: did not receive HSTS heade
 txclimbers.com: could not connect to host
 txf.pw: could not connect to host
 ty2u.com: did not receive HSTS header
 tylian.net: max-age too low: 0
 tyrelius.com: did not receive HSTS header
 tyroproducts.eu: did not receive HSTS header
 tzappa.net: could not connect to host
 u-blox.com: did not receive HSTS header
-u03.fr: could not connect to host
 ua.search.yahoo.com: did not receive HSTS header
 ubicloud.de: could not connect to host
 ublox.com: did not receive HSTS header
 ubuntuhot.com: did not receive HSTS header
 uega.net: did not receive HSTS header
 ufgaming.com: did not receive HSTS header
 ufotable.uk: could not connect to host
 ui8.net: max-age too low: 86400
@@ -3587,16 +3582,17 @@ urphp.com: could not connect to host
 us-immigration.com: did not receive HSTS header
 usaa.com: did not receive HSTS header
 uscitizenship.info: did not receive HSTS header
 used-in.jp: did not receive HSTS header
 usercare.com: did not receive HSTS header
 userify.com: did not receive HSTS header
 ustr.gov: max-age too low: 86400
 utumno.ch: could not connect to host
+uvarov.pw: could not connect to host
 uy.search.yahoo.com: did not receive HSTS header
 uz.search.yahoo.com: did not receive HSTS header
 uzmandroid.com: could not connect to host
 uzmandroid.net: could not connect to host
 uzmandroid.top: could not connect to host
 v4veedu.com: could not connect to host
 vaddder.com: could not connect to host
 valethound.com: could not connect to host
@@ -3613,39 +3609,41 @@ vansieleghem.com: could not connect to h
 vasanth.org: could not connect to host
 vbh2o.com: did not receive HSTS header
 vbulletin-russia.com: could not connect to host
 vbulletinrussia.com: could not connect to host
 vcdove.com: did not receive HSTS header
 vcr.re: could not connect to host
 veblen.com: could not connect to host
 vechkasov.ru: did not receive HSTS header
-vemokin.net: did not receive HSTS header
+vemokin.net: could not connect to host
 venixplays-stream.ml: could not connect to host
 verifikatorindonesia.com: could not connect to host
 vermontcareergateway.org: could not connect to host
 versia.ru: did not receive HSTS header
 veryhax.de: could not connect to host
 vestacp.top: could not connect to host
 vetmgmt.com: could not connect to host
 vfree.org: could not connect to host
 vglimg.com: could not connect to host
 vhost.co.id: could not connect to host
 viadeux.com: could not connect to host
 videnskabsklubben.dk: did not receive HSTS header
 videomuz.com: did not receive HSTS header
 vidz.ga: could not connect to host
 vieaw.com: could not connect to host
 viktorsvantesson.net: did not receive HSTS header
+villenvinkit.com: could not connect to host
 vincentkooijman.at: did not receive HSTS header
 vincentkooijman.nl: did not receive HSTS header
 vintageheartcoffee.com: did not receive HSTS header
 vio.no: did not receive HSTS header
 viperdns.com: could not connect to host
 vipmusic.ga: could not connect to host
+vipnettikasinoklubi.com: could not connect to host
 visitbroadstairs.com: could not connect to host
 vissanum.com: did not receive HSTS header
 vistarait.com: did not receive HSTS header
 vitalorange.com: could not connect to host
 viva-french.com: did not receive HSTS header
 vlastimilburian.cz: did not receive HSTS header
 vlora.city: could not connect to host
 vm0.eu: did not receive HSTS header
@@ -3743,17 +3741,16 @@ whoclicks.net: could not connect to host
 whoisapi.online: could not connect to host
 wholebites.com: did not receive HSTS header
 whoshotya.de: did not receive HSTS header
 whysuck.com: could not connect to host
 whyworldhot.com: could not connect to host
 wienholding.at: max-age too low: 0
 wieninternational.at: could not connect to host
 wiire.me: could not connect to host
-wikileaks.com: could not connect to host
 wilf1rst.com: could not connect to host
 william.si: did not receive HSTS header
 willosagiede.com: did not receive HSTS header
 winclient.cn: could not connect to host
 winecodeavocado.com: could not connect to host
 wingumd.net: could not connect to host
 winhistory-forum.net: did not receive HSTS header
 winpack.cf: could not connect to host
@@ -3900,17 +3897,16 @@ yourstrongbox.com: could not connect to 
 yout.com: max-age too low: 60000
 yu.gg: did not receive HSTS header
 yuan.ga: did not receive HSTS header
 yuhen.ru: did not receive HSTS header
 yuko.moe: could not connect to host
 yukontec.com: [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 121"  data: no]
 yunzhu.li: did not receive HSTS header
 yunzhu.org: could not connect to host
-yutabon.com: could not connect to host
 yux.io: did not receive HSTS header
 yzal.io: could not connect to host
 z33.ch: did not receive HSTS header
 z3liff.com: could not connect to host
 z3liff.net: could not connect to host
 za.search.yahoo.com: did not receive HSTS header
 zadieheimlich.com: did not receive HSTS header
 zamorano.edu: could not connect to host
@@ -3930,17 +3926,17 @@ zelfstandigemakelaars.net: did not recei
 zenlogic.com: could not connect to host
 zenpayroll.com: did not receive HSTS header
 zentraler-kreditausschuss.de: did not receive HSTS header
 zentralwolke.de: did not receive HSTS header
 zera.com.au: could not connect to host
 zett4.me: could not connect to host
 zeytin.pro: could not connect to host
 zh.search.yahoo.com: did not receive HSTS header
-zhaojin97.cn: max-age too low: 604800
+zhaojin97.cn: did not receive HSTS header
 zhendingresources.com: max-age too low: 0
 zigcore.com.br: could not connect to host
 zirtue.io: could not connect to host
 zking.ga: could not connect to host
 zocken.com: could not connect to host
 zomerschoen.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 121"  data: no]
 zoneminder.com: did not receive HSTS header
 zoo24.de: did not receive HSTS header
--- a/security/manager/ssl/nsSTSPreloadList.inc
+++ b/security/manager/ssl/nsSTSPreloadList.inc
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*****************************************************************************/
 /* This is an automatically generated file. If you're not                    */
 /* nsSiteSecurityService.cpp, you shouldn't be #including it.     */
 /*****************************************************************************/
 
 #include <stdint.h>
-const PRTime gPreloadListExpirationTime = INT64_C(1490883721216000);
+const PRTime gPreloadListExpirationTime = INT64_C(1490970907144000);
 
 static const char kSTSHostTable[] = {
   /* "007-preisvergleich.de", true */ '0', '0', '7', '-', 'p', 'r', 'e', 'i', 's', 'v', 'e', 'r', 'g', 'l', 'e', 'i', 'c', 'h', '.', 'd', 'e', '\0',
   /* "007sascha.de", true */ '0', '0', '7', 's', 'a', 's', 'c', 'h', 'a', '.', 'd', 'e', '\0',
   /* "00f.net", true */ '0', '0', 'f', '.', 'n', 'e', 't', '\0',
   /* "01electronica.com.ar", true */ '0', '1', 'e', 'l', 'e', 'c', 't', 'r', 'o', 'n', 'i', 'c', 'a', '.', 'c', 'o', 'm', '.', 'a', 'r', '\0',
   /* "01seguridad.com.ar", true */ '0', '1', 's', 'e', 'g', 'u', 'r', 'i', 'd', 'a', 'd', '.', 'c', 'o', 'm', '.', 'a', 'r', '\0',
   /* "050media.nl", true */ '0', '5', '0', 'm', 'e', 'd', 'i', 'a', '.', 'n', 'l', '\0',
@@ -80,32 +80,33 @@ static const char kSTSHostTable[] = {
   /* "1co-jp.net", true */ '1', 'c', 'o', '-', 'j', 'p', '.', 'n', 'e', 't', '\0',
   /* "1cover.com", true */ '1', 'c', 'o', 'v', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "1cover.com.au", true */ '1', 'c', 'o', 'v', 'e', 'r', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "1hourproofreading.com", true */ '1', 'h', 'o', 'u', 'r', 'p', 'r', 'o', 'o', 'f', 'r', 'e', 'a', 'd', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "1item.co.il", true */ '1', 'i', 't', 'e', 'm', '.', 'c', 'o', '.', 'i', 'l', '\0',
   /* "1js.de", true */ '1', 'j', 's', '.', 'd', 'e', '\0',
   /* "1k8b.com", true */ '1', 'k', '8', 'b', '.', 'c', 'o', 'm', '\0',
   /* "1km.ro", true */ '1', 'k', 'm', '.', 'r', 'o', '\0',
-  /* "1on1on1.de", true */ '1', 'o', 'n', '1', 'o', 'n', '1', '.', 'd', 'e', '\0',
-  /* "1on1on1.tv", true */ '1', 'o', 'n', '1', 'o', 'n', '1', '.', 't', 'v', '\0',
+  /* "1on1on1.de", false */ '1', 'o', 'n', '1', 'o', 'n', '1', '.', 'd', 'e', '\0',
+  /* "1on1on1.tv", false */ '1', 'o', 'n', '1', 'o', 'n', '1', '.', 't', 'v', '\0',
   /* "1pw.ca", true */ '1', 'p', 'w', '.', 'c', 'a', '\0',
   /* "1px.tv", true */ '1', 'p', 'x', '.', 't', 'v', '\0',
   /* "1q365a.com", true */ '1', 'q', '3', '6', '5', 'a', '.', 'c', 'o', 'm', '\0',
   /* "1rs.nl", true */ '1', 'r', 's', '.', 'n', 'l', '\0',
   /* "1se2or3.com", true */ '1', 's', 'e', '2', 'o', 'r', '3', '.', 'c', 'o', 'm', '\0',
   /* "1st-community.de", true */ '1', 's', 't', '-', 'c', 'o', 'm', 'm', 'u', 'n', 'i', 't', 'y', '.', 'd', 'e', '\0',
   /* "1stcapital.com.sg", true */ '1', 's', 't', 'c', 'a', 'p', 'i', 't', 'a', 'l', '.', 'c', 'o', 'm', '.', 's', 'g', '\0',
   /* "1ststop.co.uk", true */ '1', 's', 't', 's', 't', 'o', 'p', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "1three1.net", true */ '1', 't', 'h', 'r', 'e', 'e', '1', '.', 'n', 'e', 't', '\0',
   /* "1xcess.com", true */ '1', 'x', 'c', 'e', 's', 's', '.', 'c', 'o', 'm', '\0',
   /* "1years.cc", true */ '1', 'y', 'e', 'a', 'r', 's', '.', 'c', 'c', '\0',
   /* "2-cpu.de", true */ '2', '-', 'c', 'p', 'u', '.', 'd', 'e', '\0',
   /* "2.wtf", true */ '2', '.', 'w', 't', 'f', '\0',
   /* "2048game.co.uk", true */ '2', '0', '4', '8', 'g', 'a', 'm', 'e', '.', 'c', 'o', '.', 'u', 'k', '\0',
+  /* "20hs.cn", true */ '2', '0', 'h', 's', '.', 'c', 'n', '\0',
   /* "21.co.uk", true */ '2', '1', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "247healthshop.com", true */ '2', '4', '7', 'h', 'e', 'a', 'l', 't', 'h', 's', 'h', 'o', 'p', '.', 'c', 'o', 'm', '\0',
   /* "247loan.com", true */ '2', '4', '7', 'l', 'o', 'a', 'n', '.', 'c', 'o', 'm', '\0',
   /* "24ip.com", true */ '2', '4', 'i', 'p', '.', 'c', 'o', 'm', '\0',
   /* "24ip.de", true */ '2', '4', 'i', 'p', '.', 'd', 'e', '\0',
   /* "24ip.fr", true */ '2', '4', 'i', 'p', '.', 'f', 'r', '\0',
   /* "2600hq.com", true */ '2', '6', '0', '0', 'h', 'q', '.', 'c', 'o', 'm', '\0',
   /* "263.info", true */ '2', '6', '3', '.', 'i', 'n', 'f', 'o', '\0',
@@ -150,17 +151,16 @@ static const char kSTSHostTable[] = {
   /* "3r.org.uk", true */ '3', 'r', '.', 'o', 'r', 'g', '.', 'u', 'k', '\0',
   /* "3s-hosting.de", true */ '3', 's', '-', 'h', 'o', 's', 't', 'i', 'n', 'g', '.', 'd', 'e', '\0',
   /* "3sreporting.com", true */ '3', 's', 'r', 'e', 'p', 'o', 'r', 't', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "3timegear.com", true */ '3', 't', 'i', 'm', 'e', 'g', 'e', 'a', 'r', '.', 'c', 'o', 'm', '\0',
   /* "3yearloans.com", true */ '3', 'y', 'e', 'a', 'r', 'l', 'o', 'a', 'n', 's', '.', 'c', 'o', 'm', '\0',
   /* "4-1-where.com", true */ '4', '-', '1', '-', 'w', 'h', 'e', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "4-it.de", true */ '4', '-', 'i', 't', '.', 'd', 'e', '\0',
   /* "403.ch", true */ '4', '0', '3', '.', 'c', 'h', '\0',
-  /* "404.sh", true */ '4', '0', '4', '.', 's', 'h', '\0',
   /* "404404.info", true */ '4', '0', '4', '4', '0', '4', '.', 'i', 'n', 'f', 'o', '\0',
   /* "4096bit.de", true */ '4', '0', '9', '6', 'b', 'i', 't', '.', 'd', 'e', '\0',
   /* "41-where.com", true */ '4', '1', '-', 'w', 'h', 'e', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "41844.de", true */ '4', '1', '8', '4', '4', '.', 'd', 'e', '\0',
   /* "41where.com", true */ '4', '1', 'w', 'h', 'e', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "4500.co.il", true */ '4', '5', '0', '0', '.', 'c', 'o', '.', 'i', 'l', '\0',
   /* "4azino777.ru", true */ '4', 'a', 'z', 'i', 'n', 'o', '7', '7', '7', '.', 'r', 'u', '\0',
   /* "4cclothing.com", true */ '4', 'c', 'c', 'l', 'o', 't', 'h', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
@@ -314,19 +314,19 @@ static const char kSTSHostTable[] = {
   /* "adamdixon.co.uk", true */ 'a', 'd', 'a', 'm', 'd', 'i', 'x', 'o', 'n', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "adamgold.net", true */ 'a', 'd', 'a', 'm', 'g', 'o', 'l', 'd', '.', 'n', 'e', 't', '\0',
   /* "adamkaminski.com", true */ 'a', 'd', 'a', 'm', 'k', 'a', 'm', 'i', 'n', 's', 'k', 'i', '.', 'c', 'o', 'm', '\0',
   /* "adamoutler.com", true */ 'a', 'd', 'a', 'm', 'o', 'u', 't', 'l', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "adamradocz.com", true */ 'a', 'd', 'a', 'm', 'r', 'a', 'd', 'o', 'c', 'z', '.', 'c', 'o', 'm', '\0',
   /* "adamricheimer.com", true */ 'a', 'd', 'a', 'm', 'r', 'i', 'c', 'h', 'e', 'i', 'm', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "adams.dk", true */ 'a', 'd', 'a', 'm', 's', '.', 'd', 'k', '\0',
   /* "adamstas.com", true */ 'a', 'd', 'a', 'm', 's', 't', 'a', 's', '.', 'c', 'o', 'm', '\0',
-  /* "adapt-elektronik.com", true */ 'a', 'd', 'a', 'p', 't', '-', 'e', 'l', 'e', 'k', 't', 'r', 'o', 'n', 'i', 'k', '.', 'c', 'o', 'm', '\0',
-  /* "adapt.de", true */ 'a', 'd', 'a', 'p', 't', '.', 'd', 'e', '\0',
-  /* "adapti.de", true */ 'a', 'd', 'a', 'p', 't', 'i', '.', 'd', 'e', '\0',
+  /* "adapt-elektronik.com", false */ 'a', 'd', 'a', 'p', 't', '-', 'e', 'l', 'e', 'k', 't', 'r', 'o', 'n', 'i', 'k', '.', 'c', 'o', 'm', '\0',
+  /* "adapt.de", false */ 'a', 'd', 'a', 'p', 't', '.', 'd', 'e', '\0',
+  /* "adapti.de", false */ 'a', 'd', 'a', 'p', 't', 'i', '.', 'd', 'e', '\0',
   /* "adaptivemechanics.edu.au", true */ 'a', 'd', 'a', 'p', 't', 'i', 'v', 'e', 'm', 'e', 'c', 'h', 'a', 'n', 'i', 'c', 's', '.', 'e', 'd', 'u', '.', 'a', 'u', '\0',
   /* "adastra.re", true */ 'a', 'd', 'a', 's', 't', 'r', 'a', '.', 'r', 'e', '\0',
   /* "adayinthelifeof.nl", true */ 'a', 'd', 'a', 'y', 'i', 'n', 't', 'h', 'e', 'l', 'i', 'f', 'e', 'o', 'f', '.', 'n', 'l', '\0',
   /* "adblock.ovh", true */ 'a', 'd', 'b', 'l', 'o', 'c', 'k', '.', 'o', 'v', 'h', '\0',
   /* "adblockextreme.com", true */ 'a', 'd', 'b', 'l', 'o', 'c', 'k', 'e', 'x', 't', 'r', 'e', 'm', 'e', '.', 'c', 'o', 'm', '\0',
   /* "adblockextreme.net", true */ 'a', 'd', 'b', 'l', 'o', 'c', 'k', 'e', 'x', 't', 'r', 'e', 'm', 'e', '.', 'n', 'e', 't', '\0',
   /* "adblockextreme.org", true */ 'a', 'd', 'b', 'l', 'o', 'c', 'k', 'e', 'x', 't', 'r', 'e', 'm', 'e', '.', 'o', 'r', 'g', '\0',
   /* "addaxpetroleum.com", true */ 'a', 'd', 'd', 'a', 'x', 'p', 'e', 't', 'r', 'o', 'l', 'e', 'u', 'm', '.', 'c', 'o', 'm', '\0',
@@ -364,17 +364,17 @@ static const char kSTSHostTable[] = {
   /* "advanced.info", true */ 'a', 'd', 'v', 'a', 'n', 'c', 'e', 'd', '.', 'i', 'n', 'f', 'o', '\0',
   /* "advancedseotool.it", true */ 'a', 'd', 'v', 'a', 'n', 'c', 'e', 'd', 's', 'e', 'o', 't', 'o', 'o', 'l', '.', 'i', 't', '\0',
   /* "advancis.net", true */ 'a', 'd', 'v', 'a', 'n', 'c', 'i', 's', '.', 'n', 'e', 't', '\0',
   /* "advelty.cz", true */ 'a', 'd', 'v', 'e', 'l', 't', 'y', '.', 'c', 'z', '\0',
   /* "adventistdeploy.org", true */ 'a', 'd', 'v', 'e', 'n', 't', 'i', 's', 't', 'd', 'e', 'p', 'l', 'o', 'y', '.', 'o', 'r', 'g', '\0',
   /* "adventure-inn.com", true */ 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', '-', 'i', 'n', 'n', '.', 'c', 'o', 'm', '\0',
   /* "adventureally.com", true */ 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 'a', 'l', 'l', 'y', '.', 'c', 'o', 'm', '\0',
   /* "adventureforest.de", false */ 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 'f', 'o', 'r', 'e', 's', 't', '.', 'd', 'e', '\0',
-  /* "adventures.de", true */ 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 's', '.', 'd', 'e', '\0',
+  /* "adventures.de", false */ 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', 's', '.', 'd', 'e', '\0',
   /* "advocatenalkmaar.org", true */ 'a', 'd', 'v', 'o', 'c', 'a', 't', 'e', 'n', 'a', 'l', 'k', 'm', 'a', 'a', 'r', '.', 'o', 'r', 'g', '\0',
   /* "adxperience.com", true */ 'a', 'd', 'x', 'p', 'e', 'r', 'i', 'e', 'n', 'c', 'e', '.', 'c', 'o', 'm', '\0',
   /* "adzuna.ca", true */ 'a', 'd', 'z', 'u', 'n', 'a', '.', 'c', 'a', '\0',
   /* "adzuna.co.uk", true */ 'a', 'd', 'z', 'u', 'n', 'a', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "adzuna.co.za", true */ 'a', 'd', 'z', 'u', 'n', 'a', '.', 'c', 'o', '.', 'z', 'a', '\0',
   /* "adzuna.com.au", true */ 'a', 'd', 'z', 'u', 'n', 'a', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "adzuna.com.br", true */ 'a', 'd', 'z', 'u', 'n', 'a', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "adzuna.de", true */ 'a', 'd', 'z', 'u', 'n', 'a', '.', 'd', 'e', '\0',
@@ -423,16 +423,17 @@ static const char kSTSHostTable[] = {
   /* "ahmad.works", true */ 'a', 'h', 'm', 'a', 'd', '.', 'w', 'o', 'r', 'k', 's', '\0',
   /* "ahmerjamilkhan.org", true */ 'a', 'h', 'm', 'e', 'r', 'j', 'a', 'm', 'i', 'l', 'k', 'h', 'a', 'n', '.', 'o', 'r', 'g', '\0',
   /* "ahoyconference.com", true */ 'a', 'h', 'o', 'y', 'c', 'o', 'n', 'f', 'e', 'r', 'e', 'n', 'c', 'e', '.', 'c', 'o', 'm', '\0',
   /* "ahoynetwork.com", true */ 'a', 'h', 'o', 'y', 'n', 'e', 't', 'w', 'o', 'r', 'k', '.', 'c', 'o', 'm', '\0',
   /* "ahwatukeefoothillsmontessori.com", true */ 'a', 'h', 'w', 'a', 't', 'u', 'k', 'e', 'e', 'f', 'o', 'o', 't', 'h', 'i', 'l', 'l', 's', 'm', 'o', 'n', 't', 'e', 's', 's', 'o', 'r', 'i', '.', 'c', 'o', 'm', '\0',
   /* "ahxxm.com", true */ 'a', 'h', 'x', 'x', 'm', '.', 'c', 'o', 'm', '\0',
   /* "ai-english.jp", true */ 'a', 'i', '-', 'e', 'n', 'g', 'l', 'i', 's', 'h', '.', 'j', 'p', '\0',
   /* "aia.de", true */ 'a', 'i', 'a', '.', 'd', 'e', '\0',
+  /* "aidanmontare.net", true */ 'a', 'i', 'd', 'a', 'n', 'm', 'o', 'n', 't', 'a', 'r', 'e', '.', 'n', 'e', 't', '\0',
   /* "aids.gov", true */ 'a', 'i', 'd', 's', '.', 'g', 'o', 'v', '\0',
   /* "aie.de", true */ 'a', 'i', 'e', '.', 'd', 'e', '\0',
   /* "aiesecarad.ro", true */ 'a', 'i', 'e', 's', 'e', 'c', 'a', 'r', 'a', 'd', '.', 'r', 'o', '\0',
   /* "aify.eu", true */ 'a', 'i', 'f', 'y', '.', 'e', 'u', '\0',
   /* "aigcev.org", true */ 'a', 'i', 'g', 'c', 'e', 'v', '.', 'o', 'r', 'g', '\0',
   /* "aikido-linz.at", true */ 'a', 'i', 'k', 'i', 'd', 'o', '-', 'l', 'i', 'n', 'z', '.', 'a', 't', '\0',
   /* "aikido-wels.at", true */ 'a', 'i', 'k', 'i', 'd', 'o', '-', 'w', 'e', 'l', 's', '.', 'a', 't', '\0',
   /* "aimeeandalec.com", true */ 'a', 'i', 'm', 'e', 'e', 'a', 'n', 'd', 'a', 'l', 'e', 'c', '.', 'c', 'o', 'm', '\0',
@@ -488,22 +489,22 @@ static const char kSTSHostTable[] = {
   /* "alcorao.org", true */ 'a', 'l', 'c', 'o', 'r', 'a', 'o', '.', 'o', 'r', 'g', '\0',
   /* "aldes.co.za", true */ 'a', 'l', 'd', 'e', 's', '.', 'c', 'o', '.', 'z', 'a', '\0',
   /* "aleax.me", true */ 'a', 'l', 'e', 'a', 'x', '.', 'm', 'e', '\0',
   /* "alecpap.com", true */ 'a', 'l', 'e', 'c', 'p', 'a', 'p', '.', 'c', 'o', 'm', '\0',
   /* "alecpapierniak.com", true */ 'a', 'l', 'e', 'c', 'p', 'a', 'p', 'i', 'e', 'r', 'n', 'i', 'a', 'k', '.', 'c', 'o', 'm', '\0',
   /* "alecrust.com", true */ 'a', 'l', 'e', 'c', 'r', 'u', 's', 't', '.', 'c', 'o', 'm', '\0',
   /* "aleksib.fi", true */ 'a', 'l', 'e', 'k', 's', 'i', 'b', '.', 'f', 'i', '\0',
   /* "alela.fr", true */ 'a', 'l', 'e', 'l', 'a', '.', 'f', 'r', '\0',
-  /* "alenan.org", true */ 'a', 'l', 'e', 'n', 'a', 'n', '.', 'o', 'r', 'g', '\0',
   /* "alertboxx.com", true */ 'a', 'l', 'e', 'r', 't', 'b', 'o', 'x', 'x', '.', 'c', 'o', 'm', '\0',
   /* "alertwire.com", true */ 'a', 'l', 'e', 'r', 't', 'w', 'i', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "alessandroz.pro", true */ 'a', 'l', 'e', 's', 's', 'a', 'n', 'd', 'r', 'o', 'z', '.', 'p', 'r', 'o', '\0',
   /* "alex-ross.co.uk", true */ 'a', 'l', 'e', 'x', '-', 'r', 'o', 's', 's', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "alexanderschimpf.de", true */ 'a', 'l', 'e', 'x', 'a', 'n', 'd', 'e', 'r', 's', 'c', 'h', 'i', 'm', 'p', 'f', '.', 'd', 'e', '\0',
+  /* "alexandra-schulze.de", true */ 'a', 'l', 'e', 'x', 'a', 'n', 'd', 'r', 'a', '-', 's', 'c', 'h', 'u', 'l', 'z', 'e', '.', 'd', 'e', '\0',
   /* "alexbaker.org", true */ 'a', 'l', 'e', 'x', 'b', 'a', 'k', 'e', 'r', '.', 'o', 'r', 'g', '\0',
   /* "alexberts.ch", true */ 'a', 'l', 'e', 'x', 'b', 'e', 'r', 't', 's', '.', 'c', 'h', '\0',
   /* "alexei.su", true */ 'a', 'l', 'e', 'x', 'e', 'i', '.', 's', 'u', '\0',
   /* "alexgaynor.net", true */ 'a', 'l', 'e', 'x', 'g', 'a', 'y', 'n', 'o', 'r', '.', 'n', 'e', 't', '\0',
   /* "alexhd.de", true */ 'a', 'l', 'e', 'x', 'h', 'd', '.', 'd', 'e', '\0',
   /* "alexmak.net", true */ 'a', 'l', 'e', 'x', 'm', 'a', 'k', '.', 'n', 'e', 't', '\0',
   /* "alexmerkel.com", true */ 'a', 'l', 'e', 'x', 'm', 'e', 'r', 'k', 'e', 'l', '.', 'c', 'o', 'm', '\0',
   /* "alexmerkel.me", true */ 'a', 'l', 'e', 'x', 'm', 'e', 'r', 'k', 'e', 'l', '.', 'm', 'e', '\0',
@@ -557,17 +558,16 @@ static const char kSTSHostTable[] = {
   /* "alphagamers.net", true */ 'a', 'l', 'p', 'h', 'a', 'g', 'a', 'm', 'e', 'r', 's', '.', 'n', 'e', 't', '\0',
   /* "alphassl.de", true */ 'a', 'l', 'p', 'h', 'a', 's', 's', 'l', '.', 'd', 'e', '\0',
   /* "alphatrash.de", true */ 'a', 'l', 'p', 'h', 'a', 't', 'r', 'a', 's', 'h', '.', 'd', 'e', '\0',
   /* "alspolska.pl", true */ 'a', 'l', 's', 'p', 'o', 'l', 's', 'k', 'a', '.', 'p', 'l', '\0',
   /* "alt-three.com", true */ 'a', 'l', 't', '-', 't', 'h', 'r', 'e', 'e', '.', 'c', 'o', 'm', '\0',
   /* "alt.org", true */ 'a', 'l', 't', '.', 'o', 'r', 'g', '\0',
   /* "altahrim.net", true */ 'a', 'l', 't', 'a', 'h', 'r', 'i', 'm', '.', 'n', 'e', 't', '\0',
   /* "altedirect.com", true */ 'a', 'l', 't', 'e', 'd', 'i', 'r', 'e', 'c', 't', '.', 'c', 'o', 'm', '\0',
-  /* "alterbaum.net", true */ 'a', 'l', 't', 'e', 'r', 'b', 'a', 'u', 'm', '.', 'n', 'e', 't', '\0',
   /* "alternativet.party", true */ 'a', 'l', 't', 'e', 'r', 'n', 'a', 't', 'i', 'v', 'e', 't', '.', 'p', 'a', 'r', 't', 'y', '\0',
   /* "altesses.eu", true */ 'a', 'l', 't', 'e', 's', 's', 'e', 's', '.', 'e', 'u', '\0',
   /* "altestore.com", true */ 'a', 'l', 't', 'e', 's', 't', 'o', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "altonblom.com", true */ 'a', 'l', 't', 'o', 'n', 'b', 'l', 'o', 'm', '.', 'c', 'o', 'm', '\0',
   /* "altopia.com", true */ 'a', 'l', 't', 'o', 'p', 'i', 'a', '.', 'c', 'o', 'm', '\0',
   /* "alumni-kusa.jp", true */ 'a', 'l', 'u', 'm', 'n', 'i', '-', 'k', 'u', 's', 'a', '.', 'j', 'p', '\0',
   /* "aluroof.eu", true */ 'a', 'l', 'u', 'r', 'o', 'o', 'f', '.', 'e', 'u', '\0',
   /* "alvicom.hu", true */ 'a', 'l', 'v', 'i', 'c', 'o', 'm', '.', 'h', 'u', '\0',
@@ -673,17 +673,16 @@ static const char kSTSHostTable[] = {
   /* "anedot.xyz", true */ 'a', 'n', 'e', 'd', 'o', 't', '.', 'x', 'y', 'z', '\0',
   /* "anetaben.nl", true */ 'a', 'n', 'e', 't', 'a', 'b', 'e', 'n', '.', 'n', 'l', '\0',
   /* "anglesya.win", true */ 'a', 'n', 'g', 'l', 'e', 's', 'y', 'a', '.', 'w', 'i', 'n', '\0',
   /* "anglictinatabor.cz", true */ 'a', 'n', 'g', 'l', 'i', 'c', 't', 'i', 'n', 'a', 't', 'a', 'b', 'o', 'r', '.', 'c', 'z', '\0',
   /* "angrapa.ru", true */ 'a', 'n', 'g', 'r', 'a', 'p', 'a', '.', 'r', 'u', '\0',
   /* "angristan.fr", true */ 'a', 'n', 'g', 'r', 'i', 's', 't', 'a', 'n', '.', 'f', 'r', '\0',
   /* "angularjs.org", true */ 'a', 'n', 'g', 'u', 'l', 'a', 'r', 'j', 's', '.', 'o', 'r', 'g', '\0',
   /* "animalnet.de", false */ 'a', 'n', 'i', 'm', 'a', 'l', 'n', 'e', 't', '.', 'd', 'e', '\0',
-  /* "anime.my", false */ 'a', 'n', 'i', 'm', 'e', '.', 'm', 'y', '\0',
   /* "anitaalbersen.nl", true */ 'a', 'n', 'i', 't', 'a', 'a', 'l', 'b', 'e', 'r', 's', 'e', 'n', '.', 'n', 'l', '\0',
   /* "anitube-nocookie.ch", true */ 'a', 'n', 'i', 't', 'u', 'b', 'e', '-', 'n', 'o', 'c', 'o', 'o', 'k', 'i', 'e', '.', 'c', 'h', '\0',
   /* "anitube.ch", true */ 'a', 'n', 'i', 't', 'u', 'b', 'e', '.', 'c', 'h', '\0',
   /* "ankarakart.com.tr", true */ 'a', 'n', 'k', 'a', 'r', 'a', 'k', 'a', 'r', 't', '.', 'c', 'o', 'm', '.', 't', 'r', '\0',
   /* "ankaraprofesyonelnakliyat.com.tr", false */ 'a', 'n', 'k', 'a', 'r', 'a', 'p', 'r', 'o', 'f', 'e', 's', 'y', 'o', 'n', 'e', 'l', 'n', 'a', 'k', 'l', 'i', 'y', 'a', 't', '.', 'c', 'o', 'm', '.', 't', 'r', '\0',
   /* "ankaraprofesyonelwebtasarim.com", true */ 'a', 'n', 'k', 'a', 'r', 'a', 'p', 'r', 'o', 'f', 'e', 's', 'y', 'o', 'n', 'e', 'l', 'w', 'e', 'b', 't', 'a', 's', 'a', 'r', 'i', 'm', '.', 'c', 'o', 'm', '\0',
   /* "ankarauzmanlarnakliyat.com", true */ 'a', 'n', 'k', 'a', 'r', 'a', 'u', 'z', 'm', 'a', 'n', 'l', 'a', 'r', 'n', 'a', 'k', 'l', 'i', 'y', 'a', 't', '.', 'c', 'o', 'm', '\0',
   /* "anna.info", true */ 'a', 'n', 'n', 'a', '.', 'i', 'n', 'f', 'o', '\0',
@@ -810,17 +809,16 @@ static const char kSTSHostTable[] = {
   /* "archlinux.de", true */ 'a', 'r', 'c', 'h', 'l', 'i', 'n', 'u', 'x', '.', 'd', 'e', '\0',
   /* "arctic.gov", true */ 'a', 'r', 'c', 't', 'i', 'c', '.', 'g', 'o', 'v', '\0',
   /* "ardao.me", true */ 'a', 'r', 'd', 'a', 'o', '.', 'm', 'e', '\0',
   /* "ardtrade.ru", true */ 'a', 'r', 'd', 't', 'r', 'a', 'd', 'e', '.', 'r', 'u', '\0',
   /* "areafiftylan.nl", true */ 'a', 'r', 'e', 'a', 'f', 'i', 'f', 't', 'y', 'l', 'a', 'n', '.', 'n', 'l', '\0',
   /* "areatrend.com", true */ 'a', 'r', 'e', 'a', 't', 'r', 'e', 'n', 'd', '.', 'c', 'o', 'm', '\0',
   /* "arendburgers.nl", true */ 'a', 'r', 'e', 'n', 'd', 'b', 'u', 'r', 'g', 'e', 'r', 's', '.', 'n', 'l', '\0',
   /* "argekultur.at", true */ 'a', 'r', 'g', 'e', 'k', 'u', 'l', 't', 'u', 'r', '.', 'a', 't', '\0',
-  /* "argh.io", true */ 'a', 'r', 'g', 'h', '.', 'i', 'o', '\0',
   /* "arguggi.co.uk", true */ 'a', 'r', 'g', 'u', 'g', 'g', 'i', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "ariege-pyrenees.net", true */ 'a', 'r', 'i', 'e', 'g', 'e', '-', 'p', 'y', 'r', 'e', 'n', 'e', 'e', 's', '.', 'n', 'e', 't', '\0',
   /* "arima.co.ke", true */ 'a', 'r', 'i', 'm', 'a', '.', 'c', 'o', '.', 'k', 'e', '\0',
   /* "aristocrates.co", true */ 'a', 'r', 'i', 's', 't', 'o', 'c', 'r', 'a', 't', 'e', 's', '.', 'c', 'o', '\0',
   /* "aritec-la.com", true */ 'a', 'r', 'i', 't', 'e', 'c', '-', 'l', 'a', '.', 'c', 'o', 'm', '\0',
   /* "arivo.com.br", false */ 'a', 'r', 'i', 'v', 'o', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "arjandejong.eu", true */ 'a', 'r', 'j', 'a', 'n', 'd', 'e', 'j', 'o', 'n', 'g', '.', 'e', 'u', '\0',
   /* "arksan.com.tr", true */ 'a', 'r', 'k', 's', 'a', 'n', '.', 'c', 'o', 'm', '.', 't', 'r', '\0',
@@ -911,17 +909,16 @@ static const char kSTSHostTable[] = {
   /* "asr.li", true */ 'a', 's', 'r', '.', 'l', 'i', '\0',
   /* "asr.rocks", true */ 'a', 's', 'r', '.', 'r', 'o', 'c', 'k', 's', '\0',
   /* "assekuranzjobs.de", true */ 'a', 's', 's', 'e', 'k', 'u', 'r', 'a', 'n', 'z', 'j', 'o', 'b', 's', '.', 'd', 'e', '\0',
   /* "assemble-together.org", true */ 'a', 's', 's', 'e', 'm', 'b', 'l', 'e', '-', 't', 'o', 'g', 'e', 't', 'h', 'e', 'r', '.', 'o', 'r', 'g', '\0',
   /* "assindia.nl", true */ 'a', 's', 's', 'i', 'n', 'd', 'i', 'a', '.', 'n', 'l', '\0',
   /* "asta-bar.de", true */ 'a', 's', 't', 'a', '-', 'b', 'a', 'r', '.', 'd', 'e', '\0',
   /* "astengox.com", true */ 'a', 's', 't', 'e', 'n', 'g', 'o', 'x', '.', 'c', 'o', 'm', '\0',
   /* "astrath.net", true */ 'a', 's', 't', 'r', 'a', 't', 'h', '.', 'n', 'e', 't', '\0',
-  /* "astromelody.com", true */ 'a', 's', 't', 'r', 'o', 'm', 'e', 'l', 'o', 'd', 'y', '.', 'c', 'o', 'm', '\0',
   /* "asuhe.cc", true */ 'a', 's', 'u', 'h', 'e', '.', 'c', 'c', '\0',
   /* "asun.co", true */ 'a', 's', 'u', 'n', '.', 'c', 'o', '\0',
   /* "asurepay.cc", true */ 'a', 's', 'u', 'r', 'e', 'p', 'a', 'y', '.', 'c', 'c', '\0',
   /* "at.search.yahoo.com", false */ 'a', 't', '.', 's', 'e', 'a', 'r', 'c', 'h', '.', 'y', 'a', 'h', 'o', 'o', '.', 'c', 'o', 'm', '\0',
   /* "atc.io", true */ 'a', 't', 'c', '.', 'i', 'o', '\0',
   /* "atchleyjazz.com", true */ 'a', 't', 'c', 'h', 'l', 'e', 'y', 'j', 'a', 'z', 'z', '.', 'c', 'o', 'm', '\0',
   /* "atchleyjazz.org", true */ 'a', 't', 'c', 'h', 'l', 'e', 'y', 'j', 'a', 'z', 'z', '.', 'o', 'r', 'g', '\0',
   /* "atchleylab.org", true */ 'a', 't', 'c', 'h', 'l', 'e', 'y', 'l', 'a', 'b', '.', 'o', 'r', 'g', '\0',
@@ -950,30 +947,28 @@ static const char kSTSHostTable[] = {
   /* "atnis.com", true */ 'a', 't', 'n', 'i', 's', '.', 'c', 'o', 'm', '\0',
   /* "atolm.net", true */ 'a', 't', 'o', 'l', 'm', '.', 'n', 'e', 't', '\0',
   /* "atom-china.org", true */ 'a', 't', 'o', 'm', '-', 'c', 'h', 'i', 'n', 'a', '.', 'o', 'r', 'g', '\0',
   /* "atom.solutions", true */ 'a', 't', 'o', 'm', '.', 's', 'o', 'l', 'u', 't', 'i', 'o', 'n', 's', '\0',
   /* "atombase.org", true */ 'a', 't', 'o', 'm', 'b', 'a', 's', 'e', '.', 'o', 'r', 'g', '\0',
   /* "atrinik.org", true */ 'a', 't', 'r', 'i', 'n', 'i', 'k', '.', 'o', 'r', 'g', '\0',
   /* "atte.fi", true */ 'a', 't', 't', 'e', '.', 'f', 'i', '\0',
   /* "attic118.com", true */ 'a', 't', 't', 'i', 'c', '1', '1', '8', '.', 'c', 'o', 'm', '\0',
-  /* "attilagyorffy.com", true */ 'a', 't', 't', 'i', 'l', 'a', 'g', 'y', 'o', 'r', 'f', 'f', 'y', '.', 'c', 'o', 'm', '\0',
   /* "attogproductions.com", true */ 'a', 't', 't', 'o', 'g', 'p', 'r', 'o', 'd', 'u', 'c', 't', 'i', 'o', 'n', 's', '.', 'c', 'o', 'm', '\0',
   /* "attogtech.com", true */ 'a', 't', 't', 'o', 'g', 't', 'e', 'c', 'h', '.', 'c', 'o', 'm', '\0',
   /* "attorney.org.il", true */ 'a', 't', 't', 'o', 'r', 'n', 'e', 'y', '.', 'o', 'r', 'g', '.', 'i', 'l', '\0',
   /* "au2pb.net", true */ 'a', 'u', '2', 'p', 'b', '.', 'n', 'e', 't', '\0',
   /* "aucubin.moe", true */ 'a', 'u', 'c', 'u', 'b', 'i', 'n', '.', 'm', 'o', 'e', '\0',
   /* "audiense.com", true */ 'a', 'u', 'd', 'i', 'e', 'n', 's', 'e', '.', 'c', 'o', 'm', '\0',
   /* "audio-detector.com", true */ 'a', 'u', 'd', 'i', 'o', '-', 'd', 'e', 't', 'e', 'c', 't', 'o', 'r', '.', 'c', 'o', 'm', '\0',
   /* "audiovisualdevices.com.au", true */ 'a', 'u', 'd', 'i', 'o', 'v', 'i', 's', 'u', 'a', 'l', 'd', 'e', 'v', 'i', 'c', 'e', 's', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "audisto.com", true */ 'a', 'u', 'd', 'i', 's', 't', 'o', '.', 'c', 'o', 'm', '\0',
   /* "auditmatrix.com", true */ 'a', 'u', 'd', 'i', 't', 'm', 'a', 't', 'r', 'i', 'x', '.', 'c', 'o', 'm', '\0',
   /* "auditos.com", true */ 'a', 'u', 'd', 'i', 't', 'o', 's', '.', 'c', 'o', 'm', '\0',
   /* "auf-feindgebiet.de", true */ 'a', 'u', 'f', '-', 'f', 'e', 'i', 'n', 'd', 'g', 'e', 'b', 'i', 'e', 't', '.', 'd', 'e', '\0',
-  /* "aufmerksamkeitsstudie.com", true */ 'a', 'u', 'f', 'm', 'e', 'r', 'k', 's', 'a', 'm', 'k', 'e', 'i', 't', 's', 's', 't', 'u', 'd', 'i', 'e', '.', 'c', 'o', 'm', '\0',
   /* "augaware.org", true */ 'a', 'u', 'g', 'a', 'w', 'a', 'r', 'e', '.', 'o', 'r', 'g', '\0',
   /* "augias.org", true */ 'a', 'u', 'g', 'i', 'a', 's', '.', 'o', 'r', 'g', '\0',
   /* "augiero.it", true */ 'a', 'u', 'g', 'i', 'e', 'r', 'o', '.', 'i', 't', '\0',
   /* "augustian-life.cz", true */ 'a', 'u', 'g', 'u', 's', 't', 'i', 'a', 'n', '-', 'l', 'i', 'f', 'e', '.', 'c', 'z', '\0',
   /* "augustiner-kantorei-erfurt.de", true */ 'a', 'u', 'g', 'u', 's', 't', 'i', 'n', 'e', 'r', '-', 'k', 'a', 'n', 't', 'o', 'r', 'e', 'i', '-', 'e', 'r', 'f', 'u', 'r', 't', '.', 'd', 'e', '\0',
   /* "augustiner-kantorei.de", true */ 'a', 'u', 'g', 'u', 's', 't', 'i', 'n', 'e', 'r', '-', 'k', 'a', 'n', 't', 'o', 'r', 'e', 'i', '.', 'd', 'e', '\0',
   /* "aukaraoke.su", true */ 'a', 'u', 'k', 'a', 'r', 'a', 'o', 'k', 'e', '.', 's', 'u', '\0',
   /* "aulo.in", false */ 'a', 'u', 'l', 'o', '.', 'i', 'n', '\0',
@@ -993,16 +988,17 @@ static const char kSTSHostTable[] = {
   /* "author24.ru", true */ 'a', 'u', 't', 'h', 'o', 'r', '2', '4', '.', 'r', 'u', '\0',
   /* "authoritynutrition.com", true */ 'a', 'u', 't', 'h', 'o', 'r', 'i', 't', 'y', 'n', 'u', 't', 'r', 'i', 't', 'i', 'o', 'n', '.', 'c', 'o', 'm', '\0',
   /* "autimatisering.nl", true */ 'a', 'u', 't', 'i', 'm', 'a', 't', 'i', 's', 'e', 'r', 'i', 'n', 'g', '.', 'n', 'l', '\0',
   /* "auto-anleitung.de", true */ 'a', 'u', 't', 'o', '-', 'a', 'n', 'l', 'e', 'i', 't', 'u', 'n', 'g', '.', 'd', 'e', '\0',
   /* "autoauctionsohio.com", true */ 'a', 'u', 't', 'o', 'a', 'u', 'c', 't', 'i', 'o', 'n', 's', 'o', 'h', 'i', 'o', '.', 'c', 'o', 'm', '\0',
   /* "autoauctionsvirginia.com", true */ 'a', 'u', 't', 'o', 'a', 'u', 'c', 't', 'i', 'o', 'n', 's', 'v', 'i', 'r', 'g', 'i', 'n', 'i', 'a', '.', 'c', 'o', 'm', '\0',
   /* "autodeploy.it", true */ 'a', 'u', 't', 'o', 'd', 'e', 'p', 'l', 'o', 'y', '.', 'i', 't', '\0',
   /* "autoledky.sk", true */ 'a', 'u', 't', 'o', 'l', 'e', 'd', 'k', 'y', '.', 's', 'k', '\0',
+  /* "automacity.com", true */ 'a', 'u', 't', 'o', 'm', 'a', 'c', 'i', 't', 'y', '.', 'c', 'o', 'm', '\0',
   /* "autoskola.hr", true */ 'a', 'u', 't', 'o', 's', 'k', 'o', 'l', 'a', '.', 'h', 'r', '\0',
   /* "autoskole.hr", true */ 'a', 'u', 't', 'o', 's', 'k', 'o', 'l', 'e', '.', 'h', 'r', '\0',
   /* "auxetek.se", true */ 'a', 'u', 'x', 'e', 't', 'e', 'k', '.', 's', 'e', '\0',
   /* "ava-creative.de", true */ 'a', 'v', 'a', '-', 'c', 'r', 'e', 'a', 't', 'i', 'v', 'e', '.', 'd', 'e', '\0',
   /* "avaaz.org", true */ 'a', 'v', 'a', 'a', 'z', '.', 'o', 'r', 'g', '\0',
   /* "avacariu.me", true */ 'a', 'v', 'a', 'c', 'a', 'r', 'i', 'u', '.', 'm', 'e', '\0',
   /* "avalon-island.ru", true */ 'a', 'v', 'a', 'l', 'o', 'n', '-', 'i', 's', 'l', 'a', 'n', 'd', '.', 'r', 'u', '\0',
   /* "avanovum.de", true */ 'a', 'v', 'a', 'n', 'o', 'v', 'u', 'm', '.', 'd', 'e', '\0',
@@ -1024,17 +1020,16 @@ static const char kSTSHostTable[] = {
   /* "avsox.com", true */ 'a', 'v', 's', 'o', 'x', '.', 'c', 'o', 'm', '\0',
   /* "avtovokzaly.ru", true */ 'a', 'v', 't', 'o', 'v', 'o', 'k', 'z', 'a', 'l', 'y', '.', 'r', 'u', '\0',
   /* "avus-automobile.com", true */ 'a', 'v', 'u', 's', '-', 'a', 'u', 't', 'o', 'm', 'o', 'b', 'i', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "avxo.pw", true */ 'a', 'v', 'x', 'o', '.', 'p', 'w', '\0',
   /* "awanderlustadventure.com", true */ 'a', 'w', 'a', 'n', 'd', 'e', 'r', 'l', 'u', 's', 't', 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "awaremi-tai.com", true */ 'a', 'w', 'a', 'r', 'e', 'm', 'i', '-', 't', 'a', 'i', '.', 'c', 'o', 'm', '\0',
   /* "awk.tw", true */ 'a', 'w', 'k', '.', 't', 'w', '\0',
   /* "aww.moe", true */ 'a', 'w', 'w', '.', 'm', 'o', 'e', '\0',
-  /* "awxg.com", true */ 'a', 'w', 'x', 'g', '.', 'c', 'o', 'm', '\0',
   /* "axka.com", false */ 'a', 'x', 'k', 'a', '.', 'c', 'o', 'm', '\0',
   /* "axolotlfarm.org", true */ 'a', 'x', 'o', 'l', 'o', 't', 'l', 'f', 'a', 'r', 'm', '.', 'o', 'r', 'g', '\0',
   /* "axolsoft.com", true */ 'a', 'x', 'o', 'l', 's', 'o', 'f', 't', '.', 'c', 'o', 'm', '\0',
   /* "axrec.de", true */ 'a', 'x', 'r', 'e', 'c', '.', 'd', 'e', '\0',
   /* "ayesh.me", true */ 'a', 'y', 'e', 's', 'h', '.', 'm', 'e', '\0',
   /* "aykutcevik.com", true */ 'a', 'y', 'k', 'u', 't', 'c', 'e', 'v', 'i', 'k', '.', 'c', 'o', 'm', '\0',
   /* "aylak.com", true */ 'a', 'y', 'l', 'a', 'k', '.', 'c', 'o', 'm', '\0',
   /* "aymerick.fr", true */ 'a', 'y', 'm', 'e', 'r', 'i', 'c', 'k', '.', 'f', 'r', '\0',
@@ -1165,17 +1160,16 @@ static const char kSTSHostTable[] = {
   /* "basnoslovno.com.ua", true */ 'b', 'a', 's', 'n', 'o', 's', 'l', 'o', 'v', 'n', 'o', '.', 'c', 'o', 'm', '.', 'u', 'a', '\0',
   /* "basnoslovno.ru", true */ 'b', 'a', 's', 'n', 'o', 's', 'l', 'o', 'v', 'n', 'o', '.', 'r', 'u', '\0',
   /* "bastianstalder.ch", true */ 'b', 'a', 's', 't', 'i', 'a', 'n', 's', 't', 'a', 'l', 'd', 'e', 'r', '.', 'c', 'h', '\0',
   /* "basyspro.net", true */ 'b', 'a', 's', 'y', 's', 'p', 'r', 'o', '.', 'n', 'e', 't', '\0',
   /* "batfoundry.com", true */ 'b', 'a', 't', 'f', 'o', 'u', 'n', 'd', 'r', 'y', '.', 'c', 'o', 'm', '\0',
   /* "batschu.de", true */ 'b', 'a', 't', 's', 'c', 'h', 'u', '.', 'd', 'e', '\0',
   /* "batten.eu.org", true */ 'b', 'a', 't', 't', 'e', 'n', '.', 'e', 'u', '.', 'o', 'r', 'g', '\0',
   /* "baud.ninja", true */ 'b', 'a', 'u', 'd', '.', 'n', 'i', 'n', 'j', 'a', '\0',
-  /* "baum.ga", true */ 'b', 'a', 'u', 'm', '.', 'g', 'a', '\0',
   /* "bausep.de", true */ 'b', 'a', 'u', 's', 'e', 'p', '.', 'd', 'e', '\0',
   /* "bautied.de", true */ 'b', 'a', 'u', 't', 'i', 'e', 'd', '.', 'd', 'e', '\0',
   /* "bayden.com", true */ 'b', 'a', 'y', 'd', 'e', 'n', '.', 'c', 'o', 'm', '\0',
   /* "bayrisch-fuer-anfaenger.de", true */ 'b', 'a', 'y', 'r', 'i', 's', 'c', 'h', '-', 'f', 'u', 'e', 'r', '-', 'a', 'n', 'f', 'a', 'e', 'n', 'g', 'e', 'r', '.', 'd', 'e', '\0',
   /* "baysse.eu", true */ 'b', 'a', 'y', 's', 's', 'e', '.', 'e', 'u', '\0',
   /* "baywatch.io", true */ 'b', 'a', 'y', 'w', 'a', 't', 'c', 'h', '.', 'i', 'o', '\0',
   /* "bazdell.com", true */ 'b', 'a', 'z', 'd', 'e', 'l', 'l', '.', 'c', 'o', 'm', '\0',
   /* "bazos.at", true */ 'b', 'a', 'z', 'o', 's', '.', 'a', 't', '\0',
@@ -1195,16 +1189,17 @@ static const char kSTSHostTable[] = {
   /* "bchep.com", true */ 'b', 'c', 'h', 'e', 'p', '.', 'c', 'o', 'm', '\0',
   /* "bcmlu.org", true */ 'b', 'c', 'm', 'l', 'u', '.', 'o', 'r', 'g', '\0',
   /* "bcrook.com", false */ 'b', 'c', 'r', 'o', 'o', 'k', '.', 'c', 'o', 'm', '\0',
   /* "bcswampcabins.com", true */ 'b', 'c', 's', 'w', 'a', 'm', 'p', 'c', 'a', 'b', 'i', 'n', 's', '.', 'c', 'o', 'm', '\0',
   /* "bcvps.com", true */ 'b', 'c', 'v', 'p', 's', '.', 'c', 'o', 'm', '\0',
   /* "bcweightlifting.ca", true */ 'b', 'c', 'w', 'e', 'i', 'g', 'h', 't', 'l', 'i', 'f', 't', 'i', 'n', 'g', '.', 'c', 'a', '\0',
   /* "bddemir.com", true */ 'b', 'd', 'd', 'e', 'm', 'i', 'r', '.', 'c', 'o', 'm', '\0',
   /* "bde-epitech.fr", true */ 'b', 'd', 'e', '-', 'e', 'p', 'i', 't', 'e', 'c', 'h', '.', 'f', 'r', '\0',
+  /* "bdikaros-network.net", true */ 'b', 'd', 'i', 'k', 'a', 'r', 'o', 's', '-', 'n', 'e', 't', 'w', 'o', 'r', 'k', '.', 'n', 'e', 't', '\0',
   /* "be-ka-tec.de", true */ 'b', 'e', '-', 'k', 'a', '-', 't', 'e', 'c', '.', 'd', 'e', '\0',
   /* "be-real.life", true */ 'b', 'e', '-', 'r', 'e', 'a', 'l', '.', 'l', 'i', 'f', 'e', '\0',
   /* "beamitapp.com", true */ 'b', 'e', 'a', 'm', 'i', 't', 'a', 'p', 'p', '.', 'c', 'o', 'm', '\0',
   /* "beanjuice.me", true */ 'b', 'e', 'a', 'n', 'j', 'u', 'i', 'c', 'e', '.', 'm', 'e', '\0',
   /* "beans-one.com", false */ 'b', 'e', 'a', 'n', 's', '-', 'o', 'n', 'e', '.', 'c', 'o', 'm', '\0',
   /* "beastlog.tk", true */ 'b', 'e', 'a', 's', 't', 'l', 'o', 'g', '.', 't', 'k', '\0',
   /* "beastowner.li", true */ 'b', 'e', 'a', 's', 't', 'o', 'w', 'n', 'e', 'r', '.', 'l', 'i', '\0',
   /* "beatnikbreaks.com", true */ 'b', 'e', 'a', 't', 'n', 'i', 'k', 'b', 'r', 'e', 'a', 'k', 's', '.', 'c', 'o', 'm', '\0',
@@ -1307,21 +1302,19 @@ static const char kSTSHostTable[] = {
   /* "bestmotherfucking.website", true */ 'b', 'e', 's', 't', 'm', 'o', 't', 'h', 'e', 'r', 'f', 'u', 'c', 'k', 'i', 'n', 'g', '.', 'w', 'e', 'b', 's', 'i', 't', 'e', '\0',
   /* "bestorangeseo.com", true */ 'b', 'e', 's', 't', 'o', 'r', 'a', 'n', 'g', 'e', 's', 'e', 'o', '.', 'c', 'o', 'm', '\0',
   /* "bestperfumebrands.com", true */ 'b', 'e', 's', 't', 'p', 'e', 'r', 'f', 'u', 'm', 'e', 'b', 'r', 'a', 'n', 'd', 's', '.', 'c', 'o', 'm', '\0',
   /* "bestseries.tv", true */ 'b', 'e', 's', 't', 's', 'e', 'r', 'i', 'e', 's', '.', 't', 'v', '\0',
   /* "betaclean.fr", true */ 'b', 'e', 't', 'a', 'c', 'l', 'e', 'a', 'n', '.', 'f', 'r', '\0',
   /* "betaworx.de", true */ 'b', 'e', 't', 'a', 'w', 'o', 'r', 'x', '.', 'd', 'e', '\0',
   /* "betaworx.eu", true */ 'b', 'e', 't', 'a', 'w', 'o', 'r', 'x', '.', 'e', 'u', '\0',
   /* "betcafearena.ro", false */ 'b', 'e', 't', 'c', 'a', 'f', 'e', 'a', 'r', 'e', 'n', 'a', '.', 'r', 'o', '\0',
-  /* "betlander.com", true */ 'b', 'e', 't', 'l', 'a', 'n', 'd', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "betonmoney.com", true */ 'b', 'e', 't', 'o', 'n', 'm', 'o', 'n', 'e', 'y', '.', 'c', 'o', 'm', '\0',
   /* "betpamm.com", true */ 'b', 'e', 't', 'p', 'a', 'm', 'm', '.', 'c', 'o', 'm', '\0',
   /* "betterbabyshop.com.au", true */ 'b', 'e', 't', 't', 'e', 'r', 'b', 'a', 'b', 'y', 's', 'h', 'o', 'p', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
-  /* "bettercrypto.org", true */ 'b', 'e', 't', 't', 'e', 'r', 'c', 'r', 'y', 'p', 't', 'o', '.', 'o', 'r', 'g', '\0',
   /* "betterhelp.com", true */ 'b', 'e', 't', 't', 'e', 'r', 'h', 'e', 'l', 'p', '.', 'c', 'o', 'm', '\0',
   /* "betterlifemakers.com", true */ 'b', 'e', 't', 't', 'e', 'r', 'l', 'i', 'f', 'e', 'm', 'a', 'k', 'e', 'r', 's', '.', 'c', 'o', 'm', '\0',
   /* "bettertest.it", true */ 'b', 'e', 't', 't', 'e', 'r', 't', 'e', 's', 't', '.', 'i', 't', '\0',
   /* "bettingbusiness.ru", true */ 'b', 'e', 't', 't', 'i', 'n', 'g', 'b', 'u', 's', 'i', 'n', 'e', 's', 's', '.', 'r', 'u', '\0',
   /* "bettrlifeapp.com", true */ 'b', 'e', 't', 't', 'r', 'l', 'i', 'f', 'e', 'a', 'p', 'p', '.', 'c', 'o', 'm', '\0',
   /* "betulashop.ch", true */ 'b', 'e', 't', 'u', 'l', 'a', 's', 'h', 'o', 'p', '.', 'c', 'h', '\0',
   /* "beulen.email", true */ 'b', 'e', 'u', 'l', 'e', 'n', '.', 'e', 'm', 'a', 'i', 'l', '\0',
   /* "bevinco2020.com", true */ 'b', 'e', 'v', 'i', 'n', 'c', 'o', '2', '0', '2', '0', '.', 'c', 'o', 'm', '\0',
@@ -1794,16 +1787,17 @@ static const char kSTSHostTable[] = {
   /* "bul3seas.eu", true */ 'b', 'u', 'l', '3', 's', 'e', 'a', 's', '.', 'e', 'u', '\0',
   /* "bulario.com", true */ 'b', 'u', 'l', 'a', 'r', 'i', 'o', '.', 'c', 'o', 'm', '\0',
   /* "bulbcompare.com", true */ 'b', 'u', 'l', 'b', 'c', 'o', 'm', 'p', 'a', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "bulbgenie.com", true */ 'b', 'u', 'l', 'b', 'g', 'e', 'n', 'i', 'e', '.', 'c', 'o', 'm', '\0',
   /* "bulkcandystore.com", true */ 'b', 'u', 'l', 'k', 'c', 'a', 'n', 'd', 'y', 's', 't', 'o', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "bulktrade.de", true */ 'b', 'u', 'l', 'k', 't', 'r', 'a', 'd', 'e', '.', 'd', 'e', '\0',
   /* "bullbits.com", true */ 'b', 'u', 'l', 'l', 'b', 'i', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "bulldog-hosting.de", true */ 'b', 'u', 'l', 'l', 'd', 'o', 'g', '-', 'h', 'o', 's', 't', 'i', 'n', 'g', '.', 'd', 'e', '\0',
+  /* "bulmafox.com", true */ 'b', 'u', 'l', 'm', 'a', 'f', 'o', 'x', '.', 'c', 'o', 'm', '\0',
   /* "bunbun.be", false */ 'b', 'u', 'n', 'b', 'u', 'n', '.', 'b', 'e', '\0',
   /* "bund-von-theramore.de", true */ 'b', 'u', 'n', 'd', '-', 'v', 'o', 'n', '-', 't', 'h', 'e', 'r', 'a', 'm', 'o', 'r', 'e', '.', 'd', 'e', '\0',
   /* "bundaberg.com", true */ 'b', 'u', 'n', 'd', 'a', 'b', 'e', 'r', 'g', '.', 'c', 'o', 'm', '\0',
   /* "bunkyo-life.com", true */ 'b', 'u', 'n', 'k', 'y', 'o', '-', 'l', 'i', 'f', 'e', '.', 'c', 'o', 'm', '\0',
   /* "bunsenlabs.org", true */ 'b', 'u', 'n', 's', 'e', 'n', 'l', 'a', 'b', 's', '.', 'o', 'r', 'g', '\0',
   /* "buonventosbt.eu", true */ 'b', 'u', 'o', 'n', 'v', 'e', 'n', 't', 'o', 's', 'b', 't', '.', 'e', 'u', '\0',
   /* "bureaubolster.nl", true */ 'b', 'u', 'r', 'e', 'a', 'u', 'b', 'o', 'l', 's', 't', 'e', 'r', '.', 'n', 'l', '\0',
   /* "burgers.io", true */ 'b', 'u', 'r', 'g', 'e', 'r', 's', '.', 'i', 'o', '\0',
@@ -1892,16 +1886,17 @@ static const char kSTSHostTable[] = {
   /* "caasd.org", true */ 'c', 'a', 'a', 's', 'd', '.', 'o', 'r', 'g', '\0',
   /* "cablemod.com", true */ 'c', 'a', 'b', 'l', 'e', 'm', 'o', 'd', '.', 'c', 'o', 'm', '\0',
   /* "cablesandkits.com", true */ 'c', 'a', 'b', 'l', 'e', 's', 'a', 'n', 'd', 'k', 'i', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "cabsites.com", true */ 'c', 'a', 'b', 's', 'i', 't', 'e', 's', '.', 'c', 'o', 'm', '\0',
   /* "cacaolalina.com", true */ 'c', 'a', 'c', 'a', 'o', 'l', 'a', 'l', 'i', 'n', 'a', '.', 'c', 'o', 'm', '\0',
   /* "caceis.bank", true */ 'c', 'a', 'c', 'e', 'i', 's', '.', 'b', 'a', 'n', 'k', '\0',
   /* "cachethq.io", true */ 'c', 'a', 'c', 'h', 'e', 't', 'h', 'q', '.', 'i', 'o', '\0',
   /* "cackette.com", true */ 'c', 'a', 'c', 'k', 'e', 't', 't', 'e', '.', 'c', 'o', 'm', '\0',
+  /* "cadmail.nl", true */ 'c', 'a', 'd', 'm', 'a', 'i', 'l', '.', 'n', 'l', '\0',
   /* "cadoth.net", true */ 'c', 'a', 'd', 'o', 't', 'h', '.', 'n', 'e', 't', '\0',
   /* "caesarkabalan.com", true */ 'c', 'a', 'e', 's', 'a', 'r', 'k', 'a', 'b', 'a', 'l', 'a', 'n', '.', 'c', 'o', 'm', '\0',
   /* "caesreon.com", true */ 'c', 'a', 'e', 's', 'r', 'e', 'o', 'n', '.', 'c', 'o', 'm', '\0',
   /* "cafe-murr.de", true */ 'c', 'a', 'f', 'e', '-', 'm', 'u', 'r', 'r', '.', 'd', 'e', '\0',
   /* "cafe-service.ru", true */ 'c', 'a', 'f', 'e', '-', 's', 'e', 'r', 'v', 'i', 'c', 'e', '.', 'r', 'u', '\0',
   /* "caffeinatedcode.com", true */ 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'a', 't', 'e', 'd', 'c', 'o', 'd', 'e', '.', 'c', 'o', 'm', '\0',
   /* "cainhosting.com", true */ 'c', 'a', 'i', 'n', 'h', 'o', 's', 't', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "cais.de", true */ 'c', 'a', 'i', 's', '.', 'd', 'e', '\0',
@@ -1914,16 +1909,17 @@ static const char kSTSHostTable[] = {
   /* "calcularpagerank.com.br", true */ 'c', 'a', 'l', 'c', 'u', 'l', 'a', 'r', 'p', 'a', 'g', 'e', 'r', 'a', 'n', 'k', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "calculator-imt.com", true */ 'c', 'a', 'l', 'c', 'u', 'l', 'a', 't', 'o', 'r', '-', 'i', 'm', 't', '.', 'c', 'o', 'm', '\0',
   /* "calculator.tf", true */ 'c', 'a', 'l', 'c', 'u', 'l', 'a', 't', 'o', 'r', '.', 't', 'f', '\0',
   /* "calebmorris.com", false */ 'c', 'a', 'l', 'e', 'b', 'm', 'o', 'r', 'r', 'i', 's', '.', 'c', 'o', 'm', '\0',
   /* "calendarr.com", true */ 'c', 'a', 'l', 'e', 'n', 'd', 'a', 'r', 'r', '.', 'c', 'o', 'm', '\0',
   /* "calgoty.com", true */ 'c', 'a', 'l', 'g', 'o', 't', 'y', '.', 'c', 'o', 'm', '\0',
   /* "calibreapp.com", false */ 'c', 'a', 'l', 'i', 'b', 'r', 'e', 'a', 'p', 'p', '.', 'c', 'o', 'm', '\0',
   /* "calibso.net", true */ 'c', 'a', 'l', 'i', 'b', 's', 'o', '.', 'n', 'e', 't', '\0',
+  /* "call.me", false */ 'c', 'a', 'l', 'l', '.', 'm', 'e', '\0',
   /* "callabs.net", true */ 'c', 'a', 'l', 'l', 'a', 'b', 's', '.', 'n', 'e', 't', '\0',
   /* "callaction.co", true */ 'c', 'a', 'l', 'l', 'a', 'c', 't', 'i', 'o', 'n', '.', 'c', 'o', '\0',
   /* "callcap.com", false */ 'c', 'a', 'l', 'l', 'c', 'a', 'p', '.', 'c', 'o', 'm', '\0',
   /* "callear.org", true */ 'c', 'a', 'l', 'l', 'e', 'a', 'r', '.', 'o', 'r', 'g', '\0',
   /* "callhub.io", true */ 'c', 'a', 'l', 'l', 'h', 'u', 'b', '.', 'i', 'o', '\0',
   /* "callision.com", true */ 'c', 'a', 'l', 'l', 'i', 's', 'i', 'o', 'n', '.', 'c', 'o', 'm', '\0',
   /* "callsigns.ca", true */ 'c', 'a', 'l', 'l', 's', 'i', 'g', 'n', 's', '.', 'c', 'a', '\0',
   /* "calomel.org", true */ 'c', 'a', 'l', 'o', 'm', 'e', 'l', '.', 'o', 'r', 'g', '\0',
@@ -1936,16 +1932,17 @@ static const char kSTSHostTable[] = {
   /* "cambier.org", true */ 'c', 'a', 'm', 'b', 'i', 'e', 'r', '.', 'o', 'r', 'g', '\0',
   /* "cambridgeanalytica.net", true */ 'c', 'a', 'm', 'b', 'r', 'i', 'd', 'g', 'e', 'a', 'n', 'a', 'l', 'y', 't', 'i', 'c', 'a', '.', 'n', 'e', 't', '\0',
   /* "cambridgeanalytica.org", true */ 'c', 'a', 'm', 'b', 'r', 'i', 'd', 'g', 'e', 'a', 'n', 'a', 'l', 'y', 't', 'i', 'c', 'a', '.', 'o', 'r', 'g', '\0',
   /* "camconn.cc", true */ 'c', 'a', 'm', 'c', 'o', 'n', 'n', '.', 'c', 'c', '\0',
   /* "camjackson.net", true */ 'c', 'a', 'm', 'j', 'a', 'c', 'k', 's', 'o', 'n', '.', 'n', 'e', 't', '\0',
   /* "campaign-ad.com", true */ 'c', 'a', 'm', 'p', 'a', 'i', 'g', 'n', '-', 'a', 'd', '.', 'c', 'o', 'm', '\0',
   /* "campaign.gov.uk", true */ 'c', 'a', 'm', 'p', 'a', 'i', 'g', 'n', '.', 'g', 'o', 'v', '.', 'u', 'k', '\0',
   /* "campaignelves.com", true */ 'c', 'a', 'm', 'p', 'a', 'i', 'g', 'n', 'e', 'l', 'v', 'e', 's', '.', 'c', 'o', 'm', '\0',
+  /* "campbellsoftware.co.uk", false */ 'c', 'a', 'm', 'p', 'b', 'e', 'l', 'l', 's', 'o', 'f', 't', 'w', 'a', 'r', 'e', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "campbrainybunch.com", true */ 'c', 'a', 'm', 'p', 'b', 'r', 'a', 'i', 'n', 'y', 'b', 'u', 'n', 'c', 'h', '.', 'c', 'o', 'm', '\0',
   /* "camperdays.de", true */ 'c', 'a', 'm', 'p', 'e', 'r', 'd', 'a', 'y', 's', '.', 'd', 'e', '\0',
   /* "campermanaustralia.com", true */ 'c', 'a', 'm', 'p', 'e', 'r', 'm', 'a', 'n', 'a', 'u', 's', 't', 'r', 'a', 'l', 'i', 'a', '.', 'c', 'o', 'm', '\0',
   /* "camperverzekerd.nl", true */ 'c', 'a', 'm', 'p', 'e', 'r', 'v', 'e', 'r', 'z', 'e', 'k', 'e', 'r', 'd', '.', 'n', 'l', '\0',
   /* "campfiretails.org", true */ 'c', 'a', 'm', 'p', 'f', 'i', 'r', 'e', 't', 'a', 'i', 'l', 's', '.', 'o', 'r', 'g', '\0',
   /* "campfourpaws.com", true */ 'c', 'a', 'm', 'p', 'f', 'o', 'u', 'r', 'p', 'a', 'w', 's', '.', 'c', 'o', 'm', '\0',
   /* "campus-cybersecurity.team", true */ 'c', 'a', 'm', 'p', 'u', 's', '-', 'c', 'y', 'b', 'e', 'r', 's', 'e', 'c', 'u', 'r', 'i', 't', 'y', '.', 't', 'e', 'a', 'm', '\0',
   /* "campus-finance.com", true */ 'c', 'a', 'm', 'p', 'u', 's', '-', 'f', 'i', 'n', 'a', 'n', 'c', 'e', '.', 'c', 'o', 'm', '\0',
@@ -2249,16 +2246,17 @@ static const char kSTSHostTable[] = {
   /* "chronoshop.cz", true */ 'c', 'h', 'r', 'o', 'n', 'o', 's', 'h', 'o', 'p', '.', 'c', 'z', '\0',
   /* "chrst.ph", true */ 'c', 'h', 'r', 's', 't', '.', 'p', 'h', '\0',
   /* "chsterz.de", true */ 'c', 'h', 's', 't', 'e', 'r', 'z', '.', 'd', 'e', '\0',
   /* "chuckame.fr", true */ 'c', 'h', 'u', 'c', 'k', 'a', 'm', 'e', '.', 'f', 'r', '\0',
   /* "chulado.com", true */ 'c', 'h', 'u', 'l', 'a', 'd', 'o', '.', 'c', 'o', 'm', '\0',
   /* "chun.pro", true */ 'c', 'h', 'u', 'n', '.', 'p', 'r', 'o', '\0',
   /* "chunche.net", true */ 'c', 'h', 'u', 'n', 'c', 'h', 'e', '.', 'n', 'e', 't', '\0',
   /* "churchthemes.com", true */ 'c', 'h', 'u', 'r', 'c', 'h', 't', 'h', 'e', 'm', 'e', 's', '.', 'c', 'o', 'm', '\0',
+  /* "chxdf.net", true */ 'c', 'h', 'x', 'd', 'f', '.', 'n', 'e', 't', '\0',
   /* "cianmawhinney.xyz", true */ 'c', 'i', 'a', 'n', 'm', 'a', 'w', 'h', 'i', 'n', 'n', 'e', 'y', '.', 'x', 'y', 'z', '\0',
   /* "ciat.no", false */ 'c', 'i', 'a', 't', '.', 'n', 'o', '\0',
   /* "cidbot.com", true */ 'c', 'i', 'd', 'b', 'o', 't', '.', 'c', 'o', 'm', '\0',
   /* "cienbeaute-lidl.fr", true */ 'c', 'i', 'e', 'n', 'b', 'e', 'a', 'u', 't', 'e', '-', 'l', 'i', 'd', 'l', '.', 'f', 'r', '\0',
   /* "cig-dem.com", true */ 'c', 'i', 'g', '-', 'd', 'e', 'm', '.', 'c', 'o', 'm', '\0',
   /* "cigarterminal.com", false */ 'c', 'i', 'g', 'a', 'r', 't', 'e', 'r', 'm', 'i', 'n', 'a', 'l', '.', 'c', 'o', 'm', '\0',
   /* "cigoteket.se", true */ 'c', 'i', 'g', 'o', 't', 'e', 'k', 'e', 't', '.', 's', 'e', '\0',
   /* "cim2b.de", true */ 'c', 'i', 'm', '2', 'b', '.', 'd', 'e', '\0',
@@ -2519,25 +2517,26 @@ static const char kSTSHostTable[] = {
   /* "complexart.ro", true */ 'c', 'o', 'm', 'p', 'l', 'e', 'x', 'a', 'r', 't', '.', 'r', 'o', '\0',
   /* "compliance-systeme.de", true */ 'c', 'o', 'm', 'p', 'l', 'i', 'a', 'n', 'c', 'e', '-', 's', 'y', 's', 't', 'e', 'm', 'e', '.', 'd', 'e', '\0',
   /* "compliancedictionary.com", true */ 'c', 'o', 'm', 'p', 'l', 'i', 'a', 'n', 'c', 'e', 'd', 'i', 'c', 't', 'i', 'o', 'n', 'a', 'r', 'y', '.', 'c', 'o', 'm', '\0',
   /* "complymd.com", true */ 'c', 'o', 'm', 'p', 'l', 'y', 'm', 'd', '.', 'c', 'o', 'm', '\0',
   /* "compraneta.com", true */ 'c', 'o', 'm', 'p', 'r', 'a', 'n', 'e', 't', 'a', '.', 'c', 'o', 'm', '\0',
   /* "compucorner.com.mx", true */ 'c', 'o', 'm', 'p', 'u', 'c', 'o', 'r', 'n', 'e', 'r', '.', 'c', 'o', 'm', '.', 'm', 'x', '\0',
   /* "compucorner.mx", true */ 'c', 'o', 'm', 'p', 'u', 'c', 'o', 'r', 'n', 'e', 'r', '.', 'm', 'x', '\0',
   /* "computerhilfe-feucht.de", true */ 'c', 'o', 'm', 'p', 'u', 't', 'e', 'r', 'h', 'i', 'l', 'f', 'e', '-', 'f', 'e', 'u', 'c', 'h', 't', '.', 'd', 'e', '\0',
+  /* "computersystems.guru", true */ 'c', 'o', 'm', 'p', 'u', 't', 'e', 'r', 's', 'y', 's', 't', 'e', 'm', 's', '.', 'g', 'u', 'r', 'u', '\0',
   /* "comssa.org.au", true */ 'c', 'o', 'm', 's', 's', 'a', '.', 'o', 'r', 'g', '.', 'a', 'u', '\0',
   /* "concentrade.de", true */ 'c', 'o', 'n', 'c', 'e', 'n', 't', 'r', 'a', 'd', 'e', '.', 'd', 'e', '\0',
   /* "conclave.global", true */ 'c', 'o', 'n', 'c', 'l', 'a', 'v', 'e', '.', 'g', 'l', 'o', 'b', 'a', 'l', '\0',
   /* "concretehermit.com", true */ 'c', 'o', 'n', 'c', 'r', 'e', 't', 'e', 'h', 'e', 'r', 'm', 'i', 't', '.', 'c', 'o', 'm', '\0',
   /* "condepenalba.com", true */ 'c', 'o', 'n', 'd', 'e', 'p', 'e', 'n', 'a', 'l', 'b', 'a', '.', 'c', 'o', 'm', '\0',
   /* "condosforcash.com", true */ 'c', 'o', 'n', 'd', 'o', 's', 'f', 'o', 'r', 'c', 'a', 's', 'h', '.', 'c', 'o', 'm', '\0',
   /* "confiancefoundation.org", true */ 'c', 'o', 'n', 'f', 'i', 'a', 'n', 'c', 'e', 'f', 'o', 'u', 'n', 'd', 'a', 't', 'i', 'o', 'n', '.', 'o', 'r', 'g', '\0',
   /* "config.schokokeks.org", false */ 'c', 'o', 'n', 'f', 'i', 'g', '.', 's', 'c', 'h', 'o', 'k', 'o', 'k', 'e', 'k', 's', '.', 'o', 'r', 'g', '\0',
-  /* "confiwall.de", true */ 'c', 'o', 'n', 'f', 'i', 'w', 'a', 'l', 'l', '.', 'd', 'e', '\0',
+  /* "confiwall.de", false */ 'c', 'o', 'n', 'f', 'i', 'w', 'a', 'l', 'l', '.', 'd', 'e', '\0',
   /* "conflux.tw", true */ 'c', 'o', 'n', 'f', 'l', 'u', 'x', '.', 't', 'w', '\0',
   /* "confucio.cl", true */ 'c', 'o', 'n', 'f', 'u', 'c', 'i', 'o', '.', 'c', 'l', '\0',
   /* "conjugacao.com.br", true */ 'c', 'o', 'n', 'j', 'u', 'g', 'a', 'c', 'a', 'o', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "connect-ed.network", true */ 'c', 'o', 'n', 'n', 'e', 'c', 't', '-', 'e', 'd', '.', 'n', 'e', 't', 'w', 'o', 'r', 'k', '\0',
   /* "connect.dating", true */ 'c', 'o', 'n', 'n', 'e', 'c', 't', '.', 'd', 'a', 't', 'i', 'n', 'g', '\0',
   /* "connect.ua", false */ 'c', 'o', 'n', 'n', 'e', 'c', 't', '.', 'u', 'a', '\0',
   /* "connected-verhuurservice.nl", true */ 'c', 'o', 'n', 'n', 'e', 'c', 't', 'e', 'd', '-', 'v', 'e', 'r', 'h', 'u', 'u', 'r', 's', 'e', 'r', 'v', 'i', 'c', 'e', '.', 'n', 'l', '\0',
   /* "connectfss.com", true */ 'c', 'o', 'n', 'n', 'e', 'c', 't', 'f', 's', 's', '.', 'c', 'o', 'm', '\0',
@@ -2604,28 +2603,28 @@ static const char kSTSHostTable[] = {
   /* "coronelpicanha.com.br", true */ 'c', 'o', 'r', 'o', 'n', 'e', 'l', 'p', 'i', 'c', 'a', 'n', 'h', 'a', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "corpfin.net", true */ 'c', 'o', 'r', 'p', 'f', 'i', 'n', '.', 'n', 'e', 't', '\0',
   /* "corporatesubscriptions.com.au", true */ 'c', 'o', 'r', 'p', 'o', 'r', 'a', 't', 'e', 's', 'u', 'b', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 's', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "correct.horse", true */ 'c', 'o', 'r', 'r', 'e', 'c', 't', '.', 'h', 'o', 'r', 's', 'e', '\0',
   /* "cortexitrecruitment.com", true */ 'c', 'o', 'r', 't', 'e', 'x', 'i', 't', 'r', 'e', 'c', 'r', 'u', 'i', 't', 'm', 'e', 'n', 't', '.', 'c', 'o', 'm', '\0',
   /* "cortisolsupplement.com", true */ 'c', 'o', 'r', 't', 'i', 's', 'o', 'l', 's', 'u', 'p', 'p', 'l', 'e', 'm', 'e', 'n', 't', '.', 'c', 'o', 'm', '\0',
   /* "corvus.eu.org", true */ 'c', 'o', 'r', 'v', 'u', 's', '.', 'e', 'u', '.', 'o', 'r', 'g', '\0',
   /* "coryadum.com", true */ 'c', 'o', 'r', 'y', 'a', 'd', 'u', 'm', '.', 'c', 'o', 'm', '\0',
-  /* "corzntin.fr", true */ 'c', 'o', 'r', 'z', 'n', 't', 'i', 'n', '.', 'f', 'r', '\0',
   /* "cosmeticasimple.com", true */ 'c', 'o', 's', 'm', 'e', 't', 'i', 'c', 'a', 's', 'i', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "cosmundi.de", true */ 'c', 'o', 's', 'm', 'u', 'n', 'd', 'i', '.', 'd', 'e', '\0',
   /* "costablancavoorjou.com", true */ 'c', 'o', 's', 't', 'a', 'b', 'l', 'a', 'n', 'c', 'a', 'v', 'o', 'o', 'r', 'j', 'o', 'u', '.', 'c', 'o', 'm', '\0',
   /* "costreportdata.com", true */ 'c', 'o', 's', 't', 'r', 'e', 'p', 'o', 'r', 't', 'd', 'a', 't', 'a', '.', 'c', 'o', 'm', '\0',
   /* "cotonea.de", true */ 'c', 'o', 't', 'o', 'n', 'e', 'a', '.', 'd', 'e', '\0',
   /* "cougar.dating", true */ 'c', 'o', 'u', 'g', 'a', 'r', '.', 'd', 'a', 't', 'i', 'n', 'g', '\0',
   /* "coughlan.de", true */ 'c', 'o', 'u', 'g', 'h', 'l', 'a', 'n', '.', 'd', 'e', '\0',
   /* "counterglobal.com", true */ 'c', 'o', 'u', 'n', 't', 'e', 'r', 'g', 'l', 'o', 'b', 'a', 'l', '.', 'c', 'o', 'm', '\0',
   /* "countermail.com", true */ 'c', 'o', 'u', 'n', 't', 'e', 'r', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm', '\0',
   /* "countybankdel.com", true */ 'c', 'o', 'u', 'n', 't', 'y', 'b', 'a', 'n', 'k', 'd', 'e', 'l', '.', 'c', 'o', 'm', '\0',
   /* "couponcodeq.com", true */ 'c', 'o', 'u', 'p', 'o', 'n', 'c', 'o', 'd', 'e', 'q', '.', 'c', 'o', 'm', '\0',
+  /* "couragefound.org", true */ 'c', 'o', 'u', 'r', 'a', 'g', 'e', 'f', 'o', 'u', 'n', 'd', '.', 'o', 'r', 'g', '\0',
   /* "coursera.org", true */ 'c', 'o', 'u', 'r', 's', 'e', 'r', 'a', '.', 'o', 'r', 'g', '\0',
   /* "courses.nl", true */ 'c', 'o', 'u', 'r', 's', 'e', 's', '.', 'n', 'l', '\0',
   /* "courtlistener.com", true */ 'c', 'o', 'u', 'r', 't', 'l', 'i', 's', 't', 'e', 'n', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "cousincouples.com", true */ 'c', 'o', 'u', 's', 'i', 'n', 'c', 'o', 'u', 'p', 'l', 'e', 's', '.', 'c', 'o', 'm', '\0',
   /* "covenantoftheriver.org", true */ 'c', 'o', 'v', 'e', 'n', 'a', 'n', 't', 'o', 'f', 't', 'h', 'e', 'r', 'i', 'v', 'e', 'r', '.', 'o', 'r', 'g', '\0',
   /* "covershousing.nl", true */ 'c', 'o', 'v', 'e', 'r', 's', 'h', 'o', 'u', 's', 'i', 'n', 'g', '.', 'n', 'l', '\0',
   /* "covoiturage.fr", false */ 'c', 'o', 'v', 'o', 'i', 't', 'u', 'r', 'a', 'g', 'e', '.', 'f', 'r', '\0',
   /* "covybrat.cz", true */ 'c', 'o', 'v', 'y', 'b', 'r', 'a', 't', '.', 'c', 'z', '\0',
@@ -2668,16 +2667,17 @@ static const char kSTSHostTable[] = {
   /* "credential.eu", true */ 'c', 'r', 'e', 'd', 'e', 'n', 't', 'i', 'a', 'l', '.', 'e', 'u', '\0',
   /* "creditclear.com.au", true */ 'c', 'r', 'e', 'd', 'i', 't', 'c', 'l', 'e', 'a', 'r', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "crediteo.pl", true */ 'c', 'r', 'e', 'd', 'i', 't', 'e', 'o', '.', 'p', 'l', '\0',
   /* "creditkarma.com", true */ 'c', 'r', 'e', 'd', 'i', 't', 'k', 'a', 'r', 'm', 'a', '.', 'c', 'o', 'm', '\0',
   /* "creditproautos.com", false */ 'c', 'r', 'e', 'd', 'i', 't', 'p', 'r', 'o', 'a', 'u', 't', 'o', 's', '.', 'c', 'o', 'm', '\0',
   /* "creep.im", true */ 'c', 'r', 'e', 'e', 'p', '.', 'i', 'm', '\0',
   /* "crefelder.com", true */ 'c', 'r', 'e', 'f', 'e', 'l', 'd', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "crepererum.net", true */ 'c', 'r', 'e', 'p', 'e', 'r', 'e', 'r', 'u', 'm', '.', 'n', 'e', 't', '\0',
+  /* "crestasantos.com", true */ 'c', 'r', 'e', 's', 't', 'a', 's', 'a', 'n', 't', 'o', 's', '.', 'c', 'o', 'm', '\0',
   /* "crimson.no", true */ 'c', 'r', 'i', 'm', 's', 'o', 'n', '.', 'n', 'o', '\0',
   /* "cristiandeluxe.com", true */ 'c', 'r', 'i', 's', 't', 'i', 'a', 'n', 'd', 'e', 'l', 'u', 'x', 'e', '.', 'c', 'o', 'm', '\0',
   /* "critcola.com", true */ 'c', 'r', 'i', 't', 'c', 'o', 'l', 'a', '.', 'c', 'o', 'm', '\0',
   /* "criticalsurveys.co.uk", true */ 'c', 'r', 'i', 't', 'i', 'c', 'a', 'l', 's', 'u', 'r', 'v', 'e', 'y', 's', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "crl-autos.com", true */ 'c', 'r', 'l', '-', 'a', 'u', 't', 'o', 's', '.', 'c', 'o', 'm', '\0',
   /* "crm.onlime.ch", false */ 'c', 'r', 'm', '.', 'o', 'n', 'l', 'i', 'm', 'e', '.', 'c', 'h', '\0',
   /* "crmdemo.website", true */ 'c', 'r', 'm', 'd', 'e', 'm', 'o', '.', 'w', 'e', 'b', 's', 'i', 't', 'e', '\0',
   /* "cross-view.com", true */ 'c', 'r', 'o', 's', 's', '-', 'v', 'i', 'e', 'w', '.', 'c', 'o', 'm', '\0',
@@ -2691,16 +2691,17 @@ static const char kSTSHostTable[] = {
   /* "crownruler.com", true */ 'c', 'r', 'o', 'w', 'n', 'r', 'u', 'l', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "crstat.ru", true */ 'c', 'r', 's', 't', 'a', 't', '.', 'r', 'u', '\0',
   /* "crt.sh", true */ 'c', 'r', 't', '.', 's', 'h', '\0',
   /* "crufad.org", true */ 'c', 'r', 'u', 'f', 'a', 'd', '.', 'o', 'r', 'g', '\0',
   /* "crumbcontrol.com", true */ 'c', 'r', 'u', 'm', 'b', 'c', 'o', 'n', 't', 'r', 'o', 'l', '.', 'c', 'o', 'm', '\0',
   /* "crushroom.com", true */ 'c', 'r', 'u', 's', 'h', 'r', 'o', 'o', 'm', '.', 'c', 'o', 'm', '\0',
   /* "crute.me", true */ 'c', 'r', 'u', 't', 'e', '.', 'm', 'e', '\0',
   /* "crvv.me", true */ 'c', 'r', 'v', 'v', '.', 'm', 'e', '\0',
+  /* "cryptearth.de", true */ 'c', 'r', 'y', 'p', 't', 'e', 'a', 'r', 't', 'h', '.', 'd', 'e', '\0',
   /* "crypticshell.co.uk", true */ 'c', 'r', 'y', 'p', 't', 'i', 'c', 's', 'h', 'e', 'l', 'l', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "crypto.cat", false */ 'c', 'r', 'y', 'p', 't', 'o', '.', 'c', 'a', 't', '\0',
   /* "crypto.graphics", true */ 'c', 'r', 'y', 'p', 't', 'o', '.', 'g', 'r', 'a', 'p', 'h', 'i', 'c', 's', '\0',
   /* "crypto.is", false */ 'c', 'r', 'y', 'p', 't', 'o', '.', 'i', 's', '\0',
   /* "cryptobin.co", true */ 'c', 'r', 'y', 'p', 't', 'o', 'b', 'i', 'n', '.', 'c', 'o', '\0',
   /* "cryptocon.org", true */ 'c', 'r', 'y', 'p', 't', 'o', 'c', 'o', 'n', '.', 'o', 'r', 'g', '\0',
   /* "cryptodash.net", true */ 'c', 'r', 'y', 'p', 't', 'o', 'd', 'a', 's', 'h', '.', 'n', 'e', 't', '\0',
   /* "cryptography.io", true */ 'c', 'r', 'y', 'p', 't', 'o', 'g', 'r', 'a', 'p', 'h', 'y', '.', 'i', 'o', '\0',
@@ -2712,16 +2713,17 @@ static const char kSTSHostTable[] = {
   /* "cryptoparty.at", true */ 'c', 'r', 'y', 'p', 't', 'o', 'p', 'a', 'r', 't', 'y', '.', 'a', 't', '\0',
   /* "cryptoparty.dk", true */ 'c', 'r', 'y', 'p', 't', 'o', 'p', 'a', 'r', 't', 'y', '.', 'd', 'k', '\0',
   /* "cryptopartyatx.org", true */ 'c', 'r', 'y', 'p', 't', 'o', 'p', 'a', 'r', 't', 'y', 'a', 't', 'x', '.', 'o', 'r', 'g', '\0',
   /* "cryptopartynewcastle.org", true */ 'c', 'r', 'y', 'p', 't', 'o', 'p', 'a', 'r', 't', 'y', 'n', 'e', 'w', 'c', 'a', 's', 't', 'l', 'e', '.', 'o', 'r', 'g', '\0',
   /* "cryptopartyutah.org", true */ 'c', 'r', 'y', 'p', 't', 'o', 'p', 'a', 'r', 't', 'y', 'u', 't', 'a', 'h', '.', 'o', 'r', 'g', '\0',
   /* "cryptophobia.nl", true */ 'c', 'r', 'y', 'p', 't', 'o', 'p', 'h', 'o', 'b', 'i', 'a', '.', 'n', 'l', '\0',
   /* "cryptoseb.pw", true */ 'c', 'r', 'y', 'p', 't', 'o', 's', 'e', 'b', '.', 'p', 'w', '\0',
   /* "cryptract.co", true */ 'c', 'r', 'y', 'p', 't', 'r', 'a', 'c', 't', '.', 'c', 'o', '\0',
+  /* "crystalchandelierservices.com", true */ 'c', 'r', 'y', 's', 't', 'a', 'l', 'c', 'h', 'a', 'n', 'd', 'e', 'l', 'i', 'e', 'r', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '.', 'c', 'o', 'm', '\0',
   /* "crystone.me", true */ 'c', 'r', 'y', 's', 't', 'o', 'n', 'e', '.', 'm', 'e', '\0',
   /* "cs-ubladego.pl", true */ 'c', 's', '-', 'u', 'b', 'l', 'a', 'd', 'e', 'g', 'o', '.', 'p', 'l', '\0',
   /* "csabg.org", true */ 'c', 's', 'a', 'b', 'g', '.', 'o', 'r', 'g', '\0',
   /* "csacongress.org", true */ 'c', 's', 'a', 'c', 'o', 'n', 'g', 'r', 'e', 's', 's', '.', 'o', 'r', 'g', '\0',
   /* "csbs.fr", true */ 'c', 's', 'b', 's', '.', 'f', 'r', '\0',
   /* "cselzer.com", false */ 'c', 's', 'e', 'l', 'z', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "csengle.de", true */ 'c', 's', 'e', 'n', 'g', 'l', 'e', '.', 'd', 'e', '\0',
   /* "csfm.com", true */ 'c', 's', 'f', 'm', '.', 'c', 'o', 'm', '\0',
@@ -2761,17 +2763,16 @@ static const char kSTSHostTable[] = {
   /* "cultiv.nl", true */ 'c', 'u', 'l', 't', 'i', 'v', '.', 'n', 'l', '\0',
   /* "culturedcode.com", true */ 'c', 'u', 'l', 't', 'u', 'r', 'e', 'd', 'c', 'o', 'd', 'e', '.', 'c', 'o', 'm', '\0',
   /* "cultureroll.com", true */ 'c', 'u', 'l', 't', 'u', 'r', 'e', 'r', 'o', 'l', 'l', '.', 'c', 'o', 'm', '\0',
   /* "cuongquach.com", true */ 'c', 'u', 'o', 'n', 'g', 'q', 'u', 'a', 'c', 'h', '.', 'c', 'o', 'm', '\0',
   /* "cuonic.com", true */ 'c', 'u', 'o', 'n', 'i', 'c', '.', 'c', 'o', 'm', '\0',
   /* "cup.al", true */ 'c', 'u', 'p', '.', 'a', 'l', '\0',
   /* "cupcake.io", true */ 'c', 'u', 'p', 'c', 'a', 'k', 'e', '.', 'i', 'o', '\0',
   /* "cupcake.is", true */ 'c', 'u', 'p', 'c', 'a', 'k', 'e', '.', 'i', 's', '\0',
-  /* "cupi.co", true */ 'c', 'u', 'p', 'i', '.', 'c', 'o', '\0',
   /* "curacao-license.com", true */ 'c', 'u', 'r', 'a', 'c', 'a', 'o', '-', 'l', 'i', 'c', 'e', 'n', 's', 'e', '.', 'c', 'o', 'm', '\0',
   /* "curiosity-driven.org", true */ 'c', 'u', 'r', 'i', 'o', 's', 'i', 't', 'y', '-', 'd', 'r', 'i', 'v', 'e', 'n', '.', 'o', 'r', 'g', '\0',
   /* "curlybracket.co.uk", true */ 'c', 'u', 'r', 'l', 'y', 'b', 'r', 'a', 'c', 'k', 'e', 't', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "curlyroots.com", true */ 'c', 'u', 'r', 'l', 'y', 'r', 'o', 'o', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "currency-strength.com", true */ 'c', 'u', 'r', 'r', 'e', 'n', 'c', 'y', '-', 's', 't', 'r', 'e', 'n', 'g', 't', 'h', '.', 'c', 'o', 'm', '\0',
   /* "current.com", true */ 'c', 'u', 'r', 'r', 'e', 'n', 't', '.', 'c', 'o', 'm', '\0',
   /* "curtacircuitos.com.br", false */ 'c', 'u', 'r', 't', 'a', 'c', 'i', 'r', 'c', 'u', 'i', 't', 'o', 's', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "curtis-smith.me.uk", true */ 'c', 'u', 'r', 't', 'i', 's', '-', 's', 'm', 'i', 't', 'h', '.', 'm', 'e', '.', 'u', 'k', '\0',
@@ -2834,17 +2835,16 @@ static const char kSTSHostTable[] = {
   /* "cygnius.net", true */ 'c', 'y', 'g', 'n', 'i', 'u', 's', '.', 'n', 'e', 't', '\0',
   /* "cymtech.net", true */ 'c', 'y', 'm', 't', 'e', 'c', 'h', '.', 'n', 'e', 't', '\0',
   /* "cyon.ch", true */ 'c', 'y', 'o', 'n', '.', 'c', 'h', '\0',
   /* "cyph.audio", true */ 'c', 'y', 'p', 'h', '.', 'a', 'u', 'd', 'i', 'o', '\0',
   /* "cyph.com", true */ 'c', 'y', 'p', 'h', '.', 'c', 'o', 'm', '\0',
   /* "cyph.im", true */ 'c', 'y', 'p', 'h', '.', 'i', 'm', '\0',
   /* "cyph.video", true */ 'c', 'y', 'p', 'h', '.', 'v', 'i', 'd', 'e', 'o', '\0',
   /* "cyprus-company-service.com", true */ 'c', 'y', 'p', 'r', 'u', 's', '-', 'c', 'o', 'm', 'p', 'a', 'n', 'y', '-', 's', 'e', 'r', 'v', 'i', 'c', 'e', '.', 'c', 'o', 'm', '\0',
-  /* "cysec.biz", true */ 'c', 'y', 's', 'e', 'c', '.', 'b', 'i', 'z', '\0',
   /* "cytadel.fr", true */ 'c', 'y', 't', 'a', 'd', 'e', 'l', '.', 'f', 'r', '\0',
   /* "czakey.net", true */ 'c', 'z', 'a', 'k', 'e', 'y', '.', 'n', 'e', 't', '\0',
   /* "czbix.com", true */ 'c', 'z', 'b', 'i', 'x', '.', 'c', 'o', 'm', '\0',
   /* "czechamlp.com", true */ 'c', 'z', 'e', 'c', 'h', 'a', 'm', 'l', 'p', '.', 'c', 'o', 'm', '\0',
   /* "czechvirus.cz", true */ 'c', 'z', 'e', 'c', 'h', 'v', 'i', 'r', 'u', 's', '.', 'c', 'z', '\0',
   /* "czerno.com", true */ 'c', 'z', 'e', 'r', 'n', 'o', '.', 'c', 'o', 'm', '\0',
   /* "czk.mk", true */ 'c', 'z', 'k', '.', 'm', 'k', '\0',
   /* "czlx.co", true */ 'c', 'z', 'l', 'x', '.', 'c', 'o', '\0',
@@ -2865,16 +2865,17 @@ static const char kSTSHostTable[] = {
   /* "daduke.org", true */ 'd', 'a', 'd', 'u', 'k', 'e', '.', 'o', 'r', 'g', '\0',
   /* "daemen.org", true */ 'd', 'a', 'e', 'm', 'e', 'n', '.', 'o', 'r', 'g', '\0',
   /* "daemon.xin", true */ 'd', 'a', 'e', 'm', 'o', 'n', '.', 'x', 'i', 'n', '\0',
   /* "dag-konsult.com", true */ 'd', 'a', 'g', '-', 'k', 'o', 'n', 's', 'u', 'l', 't', '.', 'c', 'o', 'm', '\0',
   /* "dahlberg.cologne", true */ 'd', 'a', 'h', 'l', 'b', 'e', 'r', 'g', '.', 'c', 'o', 'l', 'o', 'g', 'n', 'e', '\0',
   /* "dailybits.be", true */ 'd', 'a', 'i', 'l', 'y', 'b', 'i', 't', 's', '.', 'b', 'e', '\0',
   /* "dailyenglishchallenge.com", true */ 'd', 'a', 'i', 'l', 'y', 'e', 'n', 'g', 'l', 'i', 's', 'h', 'c', 'h', 'a', 'l', 'l', 'e', 'n', 'g', 'e', '.', 'c', 'o', 'm', '\0',
   /* "dailylifefinancial.com", false */ 'd', 'a', 'i', 'l', 'y', 'l', 'i', 'f', 'e', 'f', 'i', 'n', 'a', 'n', 'c', 'i', 'a', 'l', '.', 'c', 'o', 'm', '\0',
+  /* "daimadi.com", true */ 'd', 'a', 'i', 'm', 'a', 'd', 'i', '.', 'c', 'o', 'm', '\0',
   /* "dairyshrine.org", true */ 'd', 'a', 'i', 'r', 'y', 's', 'h', 'r', 'i', 'n', 'e', '.', 'o', 'r', 'g', '\0',
   /* "daiwai.de", true */ 'd', 'a', 'i', 'w', 'a', 'i', '.', 'd', 'e', '\0',
   /* "daiweihu.com", true */ 'd', 'a', 'i', 'w', 'e', 'i', 'h', 'u', '.', 'c', 'o', 'm', '\0',
   /* "daknob.net", true */ 'd', 'a', 'k', 'n', 'o', 'b', '.', 'n', 'e', 't', '\0',
   /* "daladubbeln.se", true */ 'd', 'a', 'l', 'a', 'd', 'u', 'b', 'b', 'e', 'l', 'n', '.', 's', 'e', '\0',
   /* "dale-electric.com", true */ 'd', 'a', 'l', 'e', '-', 'e', 'l', 'e', 'c', 't', 'r', 'i', 'c', '.', 'c', 'o', 'm', '\0',
   /* "dalek.co.nz", true */ 'd', 'a', 'l', 'e', 'k', '.', 'c', 'o', '.', 'n', 'z', '\0',
   /* "dalfiume.it", false */ 'd', 'a', 'l', 'f', 'i', 'u', 'm', 'e', '.', 'i', 't', '\0',
@@ -2910,16 +2911,17 @@ static const char kSTSHostTable[] = {
   /* "danielvoogsgerd.nl", true */ 'd', 'a', 'n', 'i', 'e', 'l', 'v', 'o', 'o', 'g', 's', 'g', 'e', 'r', 'd', '.', 'n', 'l', '\0',
   /* "danilapisarev.com", true */ 'd', 'a', 'n', 'i', 'l', 'a', 'p', 'i', 's', 'a', 'r', 'e', 'v', '.', 'c', 'o', 'm', '\0',
   /* "danishenanigans.com", true */ 'd', 'a', 'n', 'i', 's', 'h', 'e', 'n', 'a', 'n', 'i', 'g', 'a', 'n', 's', '.', 'c', 'o', 'm', '\0',
   /* "danjesensky.com", true */ 'd', 'a', 'n', 'j', 'e', 's', 'e', 'n', 's', 'k', 'y', '.', 'c', 'o', 'm', '\0',
   /* "dank.ninja", true */ 'd', 'a', 'n', 'k', '.', 'n', 'i', 'n', 'j', 'a', '\0',
   /* "dankim.de", false */ 'd', 'a', 'n', 'k', 'i', 'm', '.', 'd', 'e', '\0',
   /* "danny.fm", true */ 'd', 'a', 'n', 'n', 'y', '.', 'f', 'm', '\0',
   /* "dannycrichton.com", true */ 'd', 'a', 'n', 'n', 'y', 'c', 'r', 'i', 'c', 'h', 't', 'o', 'n', '.', 'c', 'o', 'm', '\0',
+  /* "dannyrohde.de", true */ 'd', 'a', 'n', 'n', 'y', 'r', 'o', 'h', 'd', 'e', '.', 'd', 'e', '\0',
   /* "danonsecurity.com", true */ 'd', 'a', 'n', 'o', 'n', 's', 'e', 'c', 'u', 'r', 'i', 't', 'y', '.', 'c', 'o', 'm', '\0',
   /* "danscomp.com", true */ 'd', 'a', 'n', 's', 'c', 'o', 'm', 'p', '.', 'c', 'o', 'm', '\0',
   /* "danseressen.nl", true */ 'd', 'a', 'n', 's', 'e', 'r', 'e', 's', 's', 'e', 'n', '.', 'n', 'l', '\0',
   /* "danskoferie.dk", true */ 'd', 'a', 'n', 's', 'k', 'o', 'f', 'e', 'r', 'i', 'e', '.', 'd', 'k', '\0',
   /* "danw.io", true */ 'd', 'a', 'n', 'w', '.', 'i', 'o', '\0',
   /* "daphne.informatik.uni-freiburg.de", true */ 'd', 'a', 'p', 'h', 'n', 'e', '.', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'k', '.', 'u', 'n', 'i', '-', 'f', 'r', 'e', 'i', 'b', 'u', 'r', 'g', '.', 'd', 'e', '\0',
   /* "daplie.com", true */ 'd', 'a', 'p', 'l', 'i', 'e', '.', 'c', 'o', 'm', '\0',
   /* "darchoods.net", false */ 'd', 'a', 'r', 'c', 'h', 'o', 'o', 'd', 's', '.', 'n', 'e', 't', '\0',
@@ -2937,22 +2939,21 @@ static const char kSTSHostTable[] = {
   /* "darkside.re", true */ 'd', 'a', 'r', 'k', 's', 'i', 'd', 'e', '.', 'r', 'e', '\0',
   /* "darksideof.it", true */ 'd', 'a', 'r', 'k', 's', 'i', 'd', 'e', 'o', 'f', '.', 'i', 't', '\0',
   /* "darkspacelab.com", true */ 'd', 'a', 'r', 'k', 's', 'p', 'a', 'c', 'e', 'l', 'a', 'b', '.', 'c', 'o', 'm', '\0',
   /* "darktime.ru", true */ 'd', 'a', 'r', 'k', 't', 'i', 'm', 'e', '.', 'r', 'u', '\0',
   /* "darktree.in", true */ 'd', 'a', 'r', 'k', 't', 'r', 'e', 'e', '.', 'i', 'n', '\0',
   /* "darkwater.info", true */ 'd', 'a', 'r', 'k', 'w', 'a', 't', 'e', 'r', '.', 'i', 'n', 'f', 'o', '\0',
   /* "darlo.co.uk", false */ 'd', 'a', 'r', 'l', 'o', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "darom.jp", true */ 'd', 'a', 'r', 'o', 'm', '.', 'j', 'p', '\0',
-  /* "darrenellis.xyz", true */ 'd', 'a', 'r', 'r', 'e', 'n', 'e', 'l', 'l', 'i', 's', '.', 'x', 'y', 'z', '\0',
   /* "darrenm.net", true */ 'd', 'a', 'r', 'r', 'e', 'n', 'm', '.', 'n', 'e', 't', '\0',
   /* "darrienworth.com", true */ 'd', 'a', 'r', 'r', 'i', 'e', 'n', 'w', 'o', 'r', 't', 'h', '.', 'c', 'o', 'm', '\0',
   /* "darth-sonic.de", true */ 'd', 'a', 'r', 't', 'h', '-', 's', 'o', 'n', 'i', 'c', '.', 'd', 'e', '\0',
   /* "darwinkel.net", false */ 'd', 'a', 'r', 'w', 'i', 'n', 'k', 'e', 'l', '.', 'n', 'e', 't', '\0',
-  /* "das-mediale-haus.de", true */ 'd', 'a', 's', '-', 'm', 'e', 'd', 'i', 'a', 'l', 'e', '-', 'h', 'a', 'u', 's', '.', 'd', 'e', '\0',
+  /* "das-mediale-haus.de", false */ 'd', 'a', 's', '-', 'm', 'e', 'd', 'i', 'a', 'l', 'e', '-', 'h', 'a', 'u', 's', '.', 'd', 'e', '\0',
   /* "dash-board.jp", false */ 'd', 'a', 's', 'h', '-', 'b', 'o', 'a', 'r', 'd', '.', 'j', 'p', '\0',
   /* "dash.rocks", true */ 'd', 'a', 's', 'h', '.', 'r', 'o', 'c', 'k', 's', '\0',
   /* "dashboard.yt", true */ 'd', 'a', 's', 'h', 'b', 'o', 'a', 'r', 'd', '.', 'y', 't', '\0',
   /* "data.haus", true */ 'd', 'a', 't', 'a', '.', 'h', 'a', 'u', 's', '\0',
   /* "data.qld.gov.au", false */ 'd', 'a', 't', 'a', '.', 'q', 'l', 'd', '.', 'g', 'o', 'v', '.', 'a', 'u', '\0',
   /* "datacalle.com", true */ 'd', 'a', 't', 'a', 'c', 'a', 'l', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "datacandy.com", true */ 'd', 'a', 't', 'a', 'c', 'a', 'n', 'd', 'y', '.', 'c', 'o', 'm', '\0',
   /* "datadit.hu", true */ 'd', 'a', 't', 'a', 'd', 'i', 't', '.', 'h', 'u', '\0',
@@ -3119,34 +3120,34 @@ static const char kSTSHostTable[] = {
   /* "dentallaborgeraeteservice.de", true */ 'd', 'e', 'n', 't', 'a', 'l', 'l', 'a', 'b', 'o', 'r', 'g', 'e', 'r', 'a', 'e', 't', 'e', 's', 'e', 'r', 'v', 'i', 'c', 'e', '.', 'd', 'e', '\0',
   /* "dentistglasgow.com", true */ 'd', 'e', 'n', 't', 'i', 's', 't', 'g', 'l', 'a', 's', 'g', 'o', 'w', '.', 'c', 'o', 'm', '\0',
   /* "dentrassi.de", true */ 'd', 'e', 'n', 't', 'r', 'a', 's', 's', 'i', '.', 'd', 'e', '\0',
   /* "dentystabirmingham.co.uk", true */ 'd', 'e', 'n', 't', 'y', 's', 't', 'a', 'b', 'i', 'r', 'm', 'i', 'n', 'g', 'h', 'a', 'm', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "denverprophit.us", true */ 'd', 'e', 'n', 'v', 'e', 'r', 'p', 'r', 'o', 'p', 'h', 'i', 't', '.', 'u', 's', '\0',
   /* "depeche-mode.moscow", true */ 'd', 'e', 'p', 'e', 'c', 'h', 'e', '-', 'm', 'o', 'd', 'e', '.', 'm', 'o', 's', 'c', 'o', 'w', '\0',
   /* "depechemode-live.com", true */ 'd', 'e', 'p', 'e', 'c', 'h', 'e', 'm', 'o', 'd', 'e', '-', 'l', 'i', 'v', 'e', '.', 'c', 'o', 'm', '\0',
   /* "depicus.com", true */ 'd', 'e', 'p', 'i', 'c', 'u', 's', '.', 'c', 'o', 'm', '\0',
-  /* "der-stein-fluesterer.de", true */ 'd', 'e', 'r', '-', 's', 't', 'e', 'i', 'n', '-', 'f', 'l', 'u', 'e', 's', 't', 'e', 'r', 'e', 'r', '.', 'd', 'e', '\0',
+  /* "der-stein-fluesterer.de", false */ 'd', 'e', 'r', '-', 's', 't', 'e', 'i', 'n', '-', 'f', 'l', 'u', 'e', 's', 't', 'e', 'r', 'e', 'r', '.', 'd', 'e', '\0',
   /* "derbyshire-language-scheme.co.uk", true */ 'd', 'e', 'r', 'b', 'y', 's', 'h', 'i', 'r', 'e', '-', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', '-', 's', 'c', 'h', 'e', 'm', 'e', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "derchris.me", true */ 'd', 'e', 'r', 'c', 'h', 'r', 'i', 's', '.', 'm', 'e', '\0',
   /* "derechosdigitales.org", true */ 'd', 'e', 'r', 'e', 'c', 'h', 'o', 's', 'd', 'i', 'g', 'i', 't', 'a', 'l', 'e', 's', '.', 'o', 'r', 'g', '\0',
   /* "dereferenced.net", true */ 'd', 'e', 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e', 'd', '.', 'n', 'e', 't', '\0',
   /* "deregowski.net", true */ 'd', 'e', 'r', 'e', 'g', 'o', 'w', 's', 'k', 'i', '.', 'n', 'e', 't', '\0',
   /* "derekkent.com", true */ 'd', 'e', 'r', 'e', 'k', 'k', 'e', 'n', 't', '.', 'c', 'o', 'm', '\0',
   /* "dergeilstestammderwelt.de", true */ 'd', 'e', 'r', 'g', 'e', 'i', 'l', 's', 't', 'e', 's', 't', 'a', 'm', 'm', 'd', 'e', 'r', 'w', 'e', 'l', 't', '.', 'd', 'e', '\0',
   /* "derhil.de", true */ 'd', 'e', 'r', 'h', 'i', 'l', '.', 'd', 'e', '\0',
   /* "derivativeshub.pro", true */ 'd', 'e', 'r', 'i', 'v', 'a', 't', 'i', 'v', 'e', 's', 'h', 'u', 'b', '.', 'p', 'r', 'o', '\0',
   /* "dermapuur.nl", true */ 'd', 'e', 'r', 'm', 'a', 'p', 'u', 'u', 'r', '.', 'n', 'l', '\0',
   /* "deroo.org", true */ 'd', 'e', 'r', 'o', 'o', '.', 'o', 'r', 'g', '\0',
   /* "derp.army", true */ 'd', 'e', 'r', 'p', '.', 'a', 'r', 'm', 'y', '\0',
   /* "derreichesack.com", true */ 'd', 'e', 'r', 'r', 'e', 'i', 'c', 'h', 'e', 's', 'a', 'c', 'k', '.', 'c', 'o', 'm', '\0',
   /* "dersoundhunter.de", true */ 'd', 'e', 'r', 's', 'o', 'u', 'n', 'd', 'h', 'u', 'n', 't', 'e', 'r', '.', 'd', 'e', '\0',
   /* "designed-cybersecurity.com", true */ 'd', 'e', 's', 'i', 'g', 'n', 'e', 'd', '-', 'c', 'y', 'b', 'e', 'r', 's', 'e', 'c', 'u', 'r', 'i', 't', 'y', '.', 'c', 'o', 'm', '\0',
   /* "designgears.com", true */ 'd', 'e', 's', 'i', 'g', 'n', 'g', 'e', 'a', 'r', 's', '.', 'c', 'o', 'm', '\0',
-  /* "designhotel-kronjuwel.de", true */ 'd', 'e', 's', 'i', 'g', 'n', 'h', 'o', 't', 'e', 'l', '-', 'k', 'r', 'o', 'n', 'j', 'u', 'w', 'e', 'l', '.', 'd', 'e', '\0',
+  /* "designhotel-kronjuwel.de", false */ 'd', 'e', 's', 'i', 'g', 'n', 'h', 'o', 't', 'e', 'l', '-', 'k', 'r', 'o', 'n', 'j', 'u', 'w', 'e', 'l', '.', 'd', 'e', '\0',
   /* "designpilot.ch", true */ 'd', 'e', 's', 'i', 'g', 'n', 'p', 'i', 'l', 'o', 't', '.', 'c', 'h', '\0',
   /* "designsbyjanith.com", true */ 'd', 'e', 's', 'i', 'g', 'n', 's', 'b', 'y', 'j', 'a', 'n', 'i', 't', 'h', '.', 'c', 'o', 'm', '\0',
   /* "designthinking.or.jp", false */ 'd', 'e', 's', 'i', 'g', 'n', 't', 'h', 'i', 'n', 'k', 'i', 'n', 'g', '.', 'o', 'r', '.', 'j', 'p', '\0',
   /* "designville.cz", true */ 'd', 'e', 's', 'i', 'g', 'n', 'v', 'i', 'l', 'l', 'e', '.', 'c', 'z', '\0',
   /* "designville.sk", true */ 'd', 'e', 's', 'i', 'g', 'n', 'v', 'i', 'l', 'l', 'e', '.', 's', 'k', '\0',
   /* "desmaakvanplanten.be", true */ 'd', 'e', 's', 'm', 'a', 'a', 'k', 'v', 'a', 'n', 'p', 'l', 'a', 'n', 't', 'e', 'n', '.', 'b', 'e', '\0',
   /* "despora.de", true */ 'd', 'e', 's', 'p', 'o', 'r', 'a', '.', 'd', 'e', '\0',
   /* "desserteagleselvenar.tk", true */ 'd', 'e', 's', 's', 'e', 'r', 't', 'e', 'a', 'g', 'l', 'e', 's', 'e', 'l', 'v', 'e', 'n', 'a', 'r', '.', 't', 'k', '\0',
@@ -3160,16 +3161,17 @@ static const char kSTSHostTable[] = {
   /* "detutorial.com", true */ 'd', 'e', 't', 'u', 't', 'o', 'r', 'i', 'a', 'l', '.', 'c', 'o', 'm', '\0',
   /* "deusu.de", true */ 'd', 'e', 'u', 's', 'u', '.', 'd', 'e', '\0',
   /* "deusu.org", true */ 'd', 'e', 'u', 's', 'u', '.', 'o', 'r', 'g', '\0',
   /* "dev-tek.de", true */ 'd', 'e', 'v', '-', 't', 'e', 'k', '.', 'd', 'e', '\0',
   /* "devafterdark.com", true */ 'd', 'e', 'v', 'a', 'f', 't', 'e', 'r', 'd', 'a', 'r', 'k', '.', 'c', 'o', 'm', '\0',
   /* "devb.nl", true */ 'd', 'e', 'v', 'b', '.', 'n', 'l', '\0',
   /* "devct.cz", true */ 'd', 'e', 'v', 'c', 't', '.', 'c', 'z', '\0',
   /* "devcu.com", true */ 'd', 'e', 'v', 'c', 'u', '.', 'c', 'o', 'm', '\0',
+  /* "devdesco.com", true */ 'd', 'e', 'v', 'd', 'e', 's', 'c', 'o', '.', 'c', 'o', 'm', '\0',
   /* "devdom.io", true */ 'd', 'e', 'v', 'd', 'o', 'm', '.', 'i', 'o', '\0',
   /* "devdoodle.net", true */ 'd', 'e', 'v', 'd', 'o', 'o', 'd', 'l', 'e', '.', 'n', 'e', 't', '\0',
   /* "developer.mydigipass.com", false */ 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'e', 'r', '.', 'm', 'y', 'd', 'i', 'g', 'i', 'p', 'a', 's', 's', '.', 'c', 'o', 'm', '\0',
   /* "developerfair.com", true */ 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'e', 'r', 'f', 'a', 'i', 'r', '.', 'c', 'o', 'm', '\0',
   /* "developers.facebook.com", false */ 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'e', 'r', 's', '.', 'f', 'a', 'c', 'e', 'b', 'o', 'o', 'k', '.', 'c', 'o', 'm', '\0',
   /* "developfx.com", true */ 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'f', 'x', '.', 'c', 'o', 'm', '\0',
   /* "developmentaid.org", true */ 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'm', 'e', 'n', 't', 'a', 'i', 'd', '.', 'o', 'r', 'g', '\0',
   /* "developmentsites.melbourne", true */ 'd', 'e', 'v', 'e', 'l', 'o', 'p', 'm', 'e', 'n', 't', 's', 'i', 't', 'e', 's', '.', 'm', 'e', 'l', 'b', 'o', 'u', 'r', 'n', 'e', '\0',
@@ -3244,17 +3246,17 @@ static const char kSTSHostTable[] = {
   /* "diezel.com", true */ 'd', 'i', 'e', 'z', 'e', 'l', '.', 'c', 'o', 'm', '\0',
   /* "diff2html.xyz", true */ 'd', 'i', 'f', 'f', '2', 'h', 't', 'm', 'l', '.', 'x', 'y', 'z', '\0',
   /* "different.cz", true */ 'd', 'i', 'f', 'f', 'e', 'r', 'e', 'n', 't', '.', 'c', 'z', '\0',
   /* "diffnow.com", true */ 'd', 'i', 'f', 'f', 'n', 'o', 'w', '.', 'c', 'o', 'm', '\0',
   /* "dighans.com", true */ 'd', 'i', 'g', 'h', 'a', 'n', 's', '.', 'c', 'o', 'm', '\0',
   /* "digidroom.be", true */ 'd', 'i', 'g', 'i', 'd', 'r', 'o', 'o', 'm', '.', 'b', 'e', '\0',
   /* "digihyp.ch", true */ 'd', 'i', 'g', 'i', 'h', 'y', 'p', '.', 'c', 'h', '\0',
   /* "digimagical.com", true */ 'd', 'i', 'g', 'i', 'm', 'a', 'g', 'i', 'c', 'a', 'l', '.', 'c', 'o', 'm', '\0',
-  /* "digimedia.cd", true */ 'd', 'i', 'g', 'i', 'm', 'e', 'd', 'i', 'a', '.', 'c', 'd', '\0',
+  /* "digimedia.cd", false */ 'd', 'i', 'g', 'i', 'm', 'e', 'd', 'i', 'a', '.', 'c', 'd', '\0',
   /* "digired.xyz", true */ 'd', 'i', 'g', 'i', 'r', 'e', 'd', '.', 'x', 'y', 'z', '\0',
   /* "digital-coach.it", false */ 'd', 'i', 'g', 'i', 't', 'a', 'l', '-', 'c', 'o', 'a', 'c', 'h', '.', 'i', 't', '\0',
   /* "digital-eastside.de", true */ 'd', 'i', 'g', 'i', 't', 'a', 'l', '-', 'e', 'a', 's', 't', 's', 'i', 'd', 'e', '.', 'd', 'e', '\0',
   /* "digital1st.co.uk", true */ 'd', 'i', 'g', 'i', 't', 'a', 'l', '1', 's', 't', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "digitalbank.kz", true */ 'd', 'i', 'g', 'i', 't', 'a', 'l', 'b', 'a', 'n', 'k', '.', 'k', 'z', '\0',
   /* "digitaldeli.org", true */ 'd', 'i', 'g', 'i', 't', 'a', 'l', 'd', 'e', 'l', 'i', '.', 'o', 'r', 'g', '\0',
   /* "digitaldeli.tv", true */ 'd', 'i', 'g', 'i', 't', 'a', 'l', 'd', 'e', 'l', 'i', '.', 't', 'v', '\0',
   /* "digitaldeli.us", true */ 'd', 'i', 'g', 'i', 't', 'a', 'l', 'd', 'e', 'l', 'i', '.', 'u', 's', '\0',
@@ -3273,17 +3275,16 @@ static const char kSTSHostTable[] = {
   /* "dillonkorman.com", true */ 'd', 'i', 'l', 'l', 'o', 'n', 'k', 'o', 'r', 'm', 'a', 'n', '.', 'c', 'o', 'm', '\0',
   /* "dim.lighting", true */ 'd', 'i', 'm', '.', 'l', 'i', 'g', 'h', 't', 'i', 'n', 'g', '\0',
   /* "dimanss47.net", true */ 'd', 'i', 'm', 'a', 'n', 's', 's', '4', '7', '.', 'n', 'e', 't', '\0',
   /* "dime-staging.com", true */ 'd', 'i', 'm', 'e', '-', 's', 't', 'a', 'g', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "dime.io", true */ 'd', 'i', 'm', 'e', '.', 'i', 'o', '\0',
   /* "dinepont.fr", true */ 'd', 'i', 'n', 'e', 'p', 'o', 'n', 't', '.', 'f', 'r', '\0',
   /* "dinge.xyz", true */ 'd', 'i', 'n', 'g', 'e', '.', 'x', 'y', 'z', '\0',
   /* "dingss.com", true */ 'd', 'i', 'n', 'g', 's', 's', '.', 'c', 'o', 'm', '\0',
-  /* "dinkum.online", true */ 'd', 'i', 'n', 'k', 'u', 'm', '.', 'o', 'n', 'l', 'i', 'n', 'e', '\0',
   /* "dinmtb.dk", true */ 'd', 'i', 'n', 'm', 't', 'b', '.', 'd', 'k', '\0',
   /* "dintillat.fr", true */ 'd', 'i', 'n', 't', 'i', 'l', 'l', 'a', 't', '.', 'f', 'r', '\0',
   /* "dintrafic.net", true */ 'd', 'i', 'n', 't', 'r', 'a', 'f', 'i', 'c', '.', 'n', 'e', 't', '\0',
   /* "dinube.com", true */ 'd', 'i', 'n', 'u', 'b', 'e', '.', 'c', 'o', 'm', '\0',
   /* "diodeled.com", true */ 'd', 'i', 'o', 'd', 'e', 'l', 'e', 'd', '.', 'c', 'o', 'm', '\0',
   /* "dipconsultants.com", true */ 'd', 'i', 'p', 'c', 'o', 'n', 's', 'u', 'l', 't', 'a', 'n', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "dipl.io", false */ 'd', 'i', 'p', 'l', '.', 'i', 'o', '\0',
   /* "dipulse.it", true */ 'd', 'i', 'p', 'u', 'l', 's', 'e', '.', 'i', 't', '\0',
@@ -3315,16 +3316,17 @@ static const char kSTSHostTable[] = {
   /* "diva-ey.com", true */ 'd', 'i', 'v', 'a', '-', 'e', 'y', '.', 'c', 'o', 'm', '\0',
   /* "divegearexpress.com", true */ 'd', 'i', 'v', 'e', 'g', 'e', 'a', 'r', 'e', 'x', 'p', 'r', 'e', 's', 's', '.', 'c', 'o', 'm', '\0',
   /* "divergenz.org", true */ 'd', 'i', 'v', 'e', 'r', 'g', 'e', 'n', 'z', '.', 'o', 'r', 'g', '\0',
   /* "diversityflags.com", true */ 'd', 'i', 'v', 'e', 'r', 's', 'i', 't', 'y', 'f', 'l', 'a', 'g', 's', '.', 'c', 'o', 'm', '\0',
   /* "divingwithnic.com", true */ 'd', 'i', 'v', 'i', 'n', 'g', 'w', 'i', 't', 'h', 'n', 'i', 'c', '.', 'c', 'o', 'm', '\0',
   /* "dixiediner.com", true */ 'd', 'i', 'x', 'i', 'e', 'd', 'i', 'n', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "dixmag.com", true */ 'd', 'i', 'x', 'm', 'a', 'g', '.', 'c', 'o', 'm', '\0',
   /* "diybook.at", true */ 'd', 'i', 'y', 'b', 'o', 'o', 'k', '.', 'a', 't', '\0',
+  /* "diycc.org", true */ 'd', 'i', 'y', 'c', 'c', '.', 'o', 'r', 'g', '\0',
   /* "djangoproject.com", true */ 'd', 'j', 'a', 'n', 'g', 'o', 'p', 'r', 'o', 'j', 'e', 'c', 't', '.', 'c', 'o', 'm', '\0',
   /* "djangosnippets.org", true */ 'd', 'j', 'a', 'n', 'g', 'o', 's', 'n', 'i', 'p', 'p', 'e', 't', 's', '.', 'o', 'r', 'g', '\0',
   /* "djlive.pl", true */ 'd', 'j', 'l', 'i', 'v', 'e', '.', 'p', 'l', '\0',
   /* "djlnetworks.co.uk", true */ 'd', 'j', 'l', 'n', 'e', 't', 'w', 'o', 'r', 'k', 's', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "djul.net", true */ 'd', 'j', 'u', 'l', '.', 'n', 'e', 't', '\0',
   /* "djxmmx.net", false */ 'd', 'j', 'x', 'm', 'm', 'x', '.', 'n', 'e', 't', '\0',
   /* "djz4music.com", false */ 'd', 'j', 'z', '4', 'm', 'u', 's', 'i', 'c', '.', 'c', 'o', 'm', '\0',
   /* "dk.search.yahoo.com", false */ 'd', 'k', '.', 's', 'e', 'a', 'r', 'c', 'h', '.', 'y', 'a', 'h', 'o', 'o', '.', 'c', 'o', 'm', '\0',
@@ -3384,26 +3386,28 @@ static const char kSTSHostTable[] = {
   /* "doculus.io", true */ 'd', 'o', 'c', 'u', 'l', 'u', 's', '.', 'i', 'o', '\0',
   /* "docupet.com", true */ 'd', 'o', 'c', 'u', 'p', 'e', 't', '.', 'c', 'o', 'm', '\0',
   /* "doesmycodehavebugs.today", true */ 'd', 'o', 'e', 's', 'm', 'y', 'c', 'o', 'd', 'e', 'h', 'a', 'v', 'e', 'b', 'u', 'g', 's', '.', 't', 'o', 'd', 'a', 'y', '\0',
   /* "dogan.ch", false */ 'd', 'o', 'g', 'a', 'n', '.', 'c', 'h', '\0',
   /* "dogespeed.ga", true */ 'd', 'o', 'g', 'e', 's', 'p', 'e', 'e', 'd', '.', 'g', 'a', '\0',
   /* "dogfi.sh", true */ 'd', 'o', 'g', 'f', 'i', '.', 's', 'h', '\0',
   /* "doggieholic.net", true */ 'd', 'o', 'g', 'g', 'i', 'e', 'h', 'o', 'l', 'i', 'c', '.', 'n', 'e', 't', '\0',
   /* "dogoodbehappyllc.com", true */ 'd', 'o', 'g', 'o', 'o', 'd', 'b', 'e', 'h', 'a', 'p', 'p', 'y', 'l', 'l', 'c', '.', 'c', 'o', 'm', '\0',
+  /* "doku-gilde.de", true */ 'd', 'o', 'k', 'u', '-', 'g', 'i', 'l', 'd', 'e', '.', 'd', 'e', '\0',
   /* "dokuboard.com", true */ 'd', 'o', 'k', 'u', 'b', 'o', 'a', 'r', 'd', '.', 'c', 'o', 'm', '\0',
   /* "dokuraum.de", true */ 'd', 'o', 'k', 'u', 'r', 'a', 'u', 'm', '.', 'd', 'e', '\0',
   /* "dolarcanadense.com.br", true */ 'd', 'o', 'l', 'a', 'r', 'c', 'a', 'n', 'a', 'd', 'e', 'n', 's', 'e', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "doleta.gov", false */ 'd', 'o', 'l', 'e', 't', 'a', '.', 'g', 'o', 'v', '\0',
   /* "dolevik.com", true */ 'd', 'o', 'l', 'e', 'v', 'i', 'k', '.', 'c', 'o', 'm', '\0',
   /* "dolice.net", true */ 'd', 'o', 'l', 'i', 'c', 'e', '.', 'n', 'e', 't', '\0',
   /* "dollemore.com", true */ 'd', 'o', 'l', 'l', 'e', 'm', 'o', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "dolphin-hosting.com", true */ 'd', 'o', 'l', 'p', 'h', 'i', 'n', '-', 'h', 'o', 's', 't', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "dolphin-it.de", true */ 'd', 'o', 'l', 'p', 'h', 'i', 'n', '-', 'i', 't', '.', 'd', 'e', '\0',
   /* "dolphinswithlasers.com", true */ 'd', 'o', 'l', 'p', 'h', 'i', 'n', 's', 'w', 'i', 't', 'h', 'l', 'a', 's', 'e', 'r', 's', '.', 'c', 'o', 'm', '\0',
+  /* "domadillo.com", true */ 'd', 'o', 'm', 'a', 'd', 'i', 'l', 'l', 'o', '.', 'c', 'o', 'm', '\0',
   /* "domain001.info", true */ 'd', 'o', 'm', 'a', 'i', 'n', '0', '0', '1', '.', 'i', 'n', 'f', 'o', '\0',
   /* "domainexpress.de", true */ 'd', 'o', 'm', 'a', 'i', 'n', 'e', 'x', 'p', 'r', 'e', 's', 's', '.', 'd', 'e', '\0',
   /* "domainkauf.de", true */ 'd', 'o', 'm', 'a', 'i', 'n', 'k', 'a', 'u', 'f', '.', 'd', 'e', '\0',
   /* "domains.google.com", true */ 'd', 'o', 'm', 'a', 'i', 'n', 's', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "domainstaff.com", true */ 'd', 'o', 'm', 'a', 'i', 'n', 's', 't', 'a', 'f', 'f', '.', 'c', 'o', 'm', '\0',
   /* "domenic.me", true */ 'd', 'o', 'm', 'e', 'n', 'i', 'c', '.', 'm', 'e', '\0',
   /* "domfee.com", true */ 'd', 'o', 'm', 'f', 'e', 'e', '.', 'c', 'o', 'm', '\0',
   /* "domhaase.me", true */ 'd', 'o', 'm', 'h', 'a', 'a', 's', 'e', '.', 'm', 'e', '\0',
@@ -3511,17 +3515,17 @@ static const char kSTSHostTable[] = {
   /* "droomhuis-in-friesland-kopen.nl", true */ 'd', 'r', 'o', 'o', 'm', 'h', 'u', 'i', 's', '-', 'i', 'n', '-', 'f', 'r', 'i', 'e', 's', 'l', 'a', 'n', 'd', '-', 'k', 'o', 'p', 'e', 'n', '.', 'n', 'l', '\0',
   /* "droomhuis-in-laren-kopen.nl", true */ 'd', 'r', 'o', 'o', 'm', 'h', 'u', 'i', 's', '-', 'i', 'n', '-', 'l', 'a', 'r', 'e', 'n', '-', 'k', 'o', 'p', 'e', 'n', '.', 'n', 'l', '\0',
   /* "droomhuis-in-veendam-kopen.nl", true */ 'd', 'r', 'o', 'o', 'm', 'h', 'u', 'i', 's', '-', 'i', 'n', '-', 'v', 'e', 'e', 'n', 'd', 'a', 'm', '-', 'k', 'o', 'p', 'e', 'n', '.', 'n', 'l', '\0',
   /* "dropbox.com", true */ 'd', 'r', 'o', 'p', 'b', 'o', 'x', '.', 'c', 'o', 'm', '\0',
   /* "dropboxer.net", true */ 'd', 'r', 'o', 'p', 'b', 'o', 'x', 'e', 'r', '.', 'n', 'e', 't', '\0',
   /* "drpetervoigt.de", true */ 'd', 'r', 'p', 'e', 't', 'e', 'r', 'v', 'o', 'i', 'g', 't', '.', 'd', 'e', '\0',
   /* "drrr.chat", true */ 'd', 'r', 'r', 'r', '.', 'c', 'h', 'a', 't', '\0',
   /* "drrr.wiki", true */ 'd', 'r', 'r', 'r', '.', 'w', 'i', 'k', 'i', '\0',
-  /* "drschruefer.de", true */ 'd', 'r', 's', 'c', 'h', 'r', 'u', 'e', 'f', 'e', 'r', '.', 'd', 'e', '\0',
+  /* "drschruefer.de", false */ 'd', 'r', 's', 'c', 'h', 'r', 'u', 'e', 'f', 'e', 'r', '.', 'd', 'e', '\0',
   /* "drsturgeonfreitas.com", true */ 'd', 'r', 's', 't', 'u', 'r', 'g', 'e', 'o', 'n', 'f', 'r', 'e', 'i', 't', 'a', 's', '.', 'c', 'o', 'm', '\0',
   /* "drugagodba.si", true */ 'd', 'r', 'u', 'g', 'a', 'g', 'o', 'd', 'b', 'a', '.', 's', 'i', '\0',
   /* "drumbe.at", true */ 'd', 'r', 'u', 'm', 'b', 'e', '.', 'a', 't', '\0',
   /* "drupal.org", true */ 'd', 'r', 'u', 'p', 'a', 'l', '.', 'o', 'r', 'g', '\0',
   /* "drweissbrot.net", true */ 'd', 'r', 'w', 'e', 'i', 's', 's', 'b', 'r', 'o', 't', '.', 'n', 'e', 't', '\0',
   /* "drycreekphoto.com", true */ 'd', 'r', 'y', 'c', 'r', 'e', 'e', 'k', 'p', 'h', 'o', 't', 'o', '.', 'c', 'o', 'm', '\0',
   /* "ds-christiansen.de", true */ 'd', 's', '-', 'c', 'h', 'r', 'i', 's', 't', 'i', 'a', 'n', 's', 'e', 'n', '.', 'd', 'e', '\0',
   /* "ds67.de", true */ 'd', 's', '6', '7', '.', 'd', 'e', '\0',
@@ -3562,17 +3566,16 @@ static const char kSTSHostTable[] = {
   /* "dutyfreeonboard.com", true */ 'd', 'u', 't', 'y', 'f', 'r', 'e', 'e', 'o', 'n', 'b', 'o', 'a', 'r', 'd', '.', 'c', 'o', 'm', '\0',
   /* "duuu.ch", true */ 'd', 'u', 'u', 'u', '.', 'c', 'h', '\0',
   /* "dvbris.co.uk", true */ 'd', 'v', 'b', 'r', 'i', 's', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "dvbris.com", true */ 'd', 'v', 'b', 'r', 'i', 's', '.', 'c', 'o', 'm', '\0',
   /* "dvorupotocnych.sk", true */ 'd', 'v', 'o', 'r', 'u', 'p', 'o', 't', 'o', 'c', 'n', 'y', 'c', 'h', '.', 's', 'k', '\0',
   /* "dvotx.org", true */ 'd', 'v', 'o', 't', 'x', '.', 'o', 'r', 'g', '\0',
   /* "dvwc.org", true */ 'd', 'v', 'w', 'c', '.', 'o', 'r', 'g', '\0',
   /* "dwnld.me", true */ 'd', 'w', 'n', 'l', 'd', '.', 'm', 'e', '\0',
-  /* "dworzak.ch", true */ 'd', 'w', 'o', 'r', 'z', 'a', 'k', '.', 'c', 'h', '\0',
   /* "dwtm.ch", true */ 'd', 'w', 't', 'm', '.', 'c', 'h', '\0',
   /* "dxa.io", true */ 'd', 'x', 'a', '.', 'i', 'o', '\0',
   /* "dxgl.info", true */ 'd', 'x', 'g', 'l', '.', 'i', 'n', 'f', 'o', '\0',
   /* "dyeager.org", true */ 'd', 'y', 'e', 'a', 'g', 'e', 'r', '.', 'o', 'r', 'g', '\0',
   /* "dyktig.as", true */ 'd', 'y', 'k', 't', 'i', 'g', '.', 'a', 's', '\0',
   /* "dyn-nserve.net", true */ 'd', 'y', 'n', '-', 'n', 's', 'e', 'r', 'v', 'e', '.', 'n', 'e', 't', '\0',
   /* "dyn.im", true */ 'd', 'y', 'n', '.', 'i', 'm', '\0',
   /* "dynaloop.net", true */ 'd', 'y', 'n', 'a', 'l', 'o', 'o', 'p', '.', 'n', 'e', 't', '\0',
@@ -3703,33 +3706,32 @@ static const char kSTSHostTable[] = {
   /* "eelzak.nl", true */ 'e', 'e', 'l', 'z', 'a', 'k', '.', 'n', 'l', '\0',
   /* "eenhoorn.ga", true */ 'e', 'e', 'n', 'h', 'o', 'o', 'r', 'n', '.', 'g', 'a', '\0',
   /* "eery.de", true */ 'e', 'e', 'r', 'y', '.', 'd', 'e', '\0',
   /* "eewna.org", true */ 'e', 'e', 'w', 'n', 'a', '.', 'o', 'r', 'g', '\0',
   /* "ef.gy", true */ 'e', 'f', '.', 'g', 'y', '\0',
   /* "eff.org", true */ 'e', 'f', 'f', '.', 'o', 'r', 'g', '\0',
   /* "effectiveosgi.com", true */ 'e', 'f', 'f', 'e', 'c', 't', 'i', 'v', 'e', 'o', 's', 'g', 'i', '.', 'c', 'o', 'm', '\0',
   /* "effex.ru", true */ 'e', 'f', 'f', 'e', 'x', '.', 'r', 'u', '\0',
-  /* "effortlesshr.com", true */ 'e', 'f', 'f', 'o', 'r', 't', 'l', 'e', 's', 's', 'h', 'r', '.', 'c', 'o', 'm', '\0',
   /* "egfl.org.uk", true */ 'e', 'g', 'f', 'l', '.', 'o', 'r', 'g', '.', 'u', 'k', '\0',
   /* "egge.com", true */ 'e', 'g', 'g', 'e', '.', 'c', 'o', 'm', '\0',
   /* "eggplant.today", true */ 'e', 'g', 'g', 'p', 'l', 'a', 'n', 't', '.', 't', 'o', 'd', 'a', 'y', '\0',
   /* "eglek.com", true */ 'e', 'g', 'l', 'e', 'k', '.', 'c', 'o', 'm', '\0',
   /* "ego4u.com", true */ 'e', 'g', 'o', '4', 'u', '.', 'c', 'o', 'm', '\0',
   /* "ego4u.de", true */ 'e', 'g', 'o', '4', 'u', '.', 'd', 'e', '\0',
   /* "egretail.no", true */ 'e', 'g', 'r', 'e', 't', 'a', 'i', 'l', '.', 'n', 'o', '\0',
   /* "ehealthcounselor.com", true */ 'e', 'h', 'e', 'a', 'l', 't', 'h', 'c', 'o', 'u', 'n', 's', 'e', 'l', 'o', 'r', '.', 'c', 'o', 'm', '\0',
   /* "ehipaa.com", true */ 'e', 'h', 'i', 'p', 'a', 'a', '.', 'c', 'o', 'm', '\0',
   /* "ehipaadev.com", true */ 'e', 'h', 'i', 'p', 'a', 'a', 'd', 'e', 'v', '.', 'c', 'o', 'm', '\0',
   /* "ehito.ovh", true */ 'e', 'h', 'i', 't', 'o', '.', 'o', 'v', 'h', '\0',
   /* "ehrlichesbier.de", true */ 'e', 'h', 'r', 'l', 'i', 'c', 'h', 'e', 's', 'b', 'i', 'e', 'r', '.', 'd', 'e', '\0',
   /* "ehuber.info", true */ 'e', 'h', 'u', 'b', 'e', 'r', '.', 'i', 'n', 'f', 'o', '\0',
   /* "eichornenterprises.com", true */ 'e', 'i', 'c', 'h', 'o', 'r', 'n', 'e', 'n', 't', 'e', 'r', 'p', 'r', 'i', 's', 'e', 's', '.', 'c', 'o', 'm', '\0',
   /* "eickemeyer.nl", true */ 'e', 'i', 'c', 'k', 'e', 'm', 'e', 'y', 'e', 'r', '.', 'n', 'l', '\0',
-  /* "eighty-aid.com", true */ 'e', 'i', 'g', 'h', 't', 'y', '-', 'a', 'i', 'd', '.', 'c', 'o', 'm', '\0',
+  /* "eighty-aid.com", false */ 'e', 'i', 'g', 'h', 't', 'y', '-', 'a', 'i', 'd', '.', 'c', 'o', 'm', '\0',
   /* "eimacs.com", true */ 'e', 'i', 'm', 'a', 'c', 's', '.', 'c', 'o', 'm', '\0',
   /* "eimanavicius.lt", true */ 'e', 'i', 'm', 'a', 'n', 'a', 'v', 'i', 'c', 'i', 'u', 's', '.', 'l', 't', '\0',
   /* "einaros.is", true */ 'e', 'i', 'n', 'a', 'r', 'o', 's', '.', 'i', 's', '\0',
   /* "einheizpreis.de", true */ 'e', 'i', 'n', 'h', 'e', 'i', 'z', 'p', 'r', 'e', 'i', 's', '.', 'd', 'e', '\0',
   /* "einsatzstellenverwaltung.de", true */ 'e', 'i', 'n', 's', 'a', 't', 'z', 's', 't', 'e', 'l', 'l', 'e', 'n', 'v', 'e', 'r', 'w', 'a', 'l', 't', 'u', 'n', 'g', '.', 'd', 'e', '\0',
   /* "eintageinzug.de", true */ 'e', 'i', 'n', 't', 'a', 'g', 'e', 'i', 'n', 'z', 'u', 'g', '.', 'd', 'e', '\0',
   /* "eipione.com", true */ 'e', 'i', 'p', 'i', 'o', 'n', 'e', '.', 'c', 'o', 'm', '\0',
   /* "eirastudios.co.uk", false */ 'e', 'i', 'r', 'a', 's', 't', 'u', 'd', 'i', 'o', 's', '.', 'c', 'o', '.', 'u', 'k', '\0',
@@ -3745,19 +3747,17 @@ static const char kSTSHostTable[] = {
   /* "el-cell.com", true */ 'e', 'l', '-', 'c', 'e', 'l', 'l', '.', 'c', 'o', 'm', '\0',
   /* "elan-organics.com", true */ 'e', 'l', 'a', 'n', '-', 'o', 'r', 'g', 'a', 'n', 'i', 'c', 's', '.', 'c', 'o', 'm', '\0',
   /* "elanguest.ro", true */ 'e', 'l', 'a', 'n', 'g', 'u', 'e', 's', 't', '.', 'r', 'o', '\0',
   /* "elanguest.ru", true */ 'e', 'l', 'a', 'n', 'g', 'u', 'e', 's', 't', '.', 'r', 'u', '\0',
   /* "elaon.de", true */ 'e', 'l', 'a', 'o', 'n', '.', 'd', 'e', '\0',
   /* "elars.de", true */ 'e', 'l', 'a', 'r', 's', '.', 'd', 'e', '\0',
   /* "elastic7.uk", true */ 'e', 'l', 'a', 's', 't', 'i', 'c', '7', '.', 'u', 'k', '\0',
   /* "elaxy-online.de", true */ 'e', 'l', 'a', 'x', 'y', '-', 'o', 'n', 'l', 'i', 'n', 'e', '.', 'd', 'e', '\0',
-  /* "elbetech.net", true */ 'e', 'l', 'b', 'e', 't', 'e', 'c', 'h', '.', 'n', 'e', 't', '\0',
   /* "elblein.de", true */ 'e', 'l', 'b', 'l', 'e', 'i', 'n', '.', 'd', 'e', '\0',
-  /* "eldinhadzic.com", true */ 'e', 'l', 'd', 'i', 'n', 'h', 'a', 'd', 'z', 'i', 'c', '.', 'c', 'o', 'm', '\0',
   /* "elearningpilot.com", true */ 'e', 'l', 'e', 'a', 'r', 'n', 'i', 'n', 'g', 'p', 'i', 'l', 'o', 't', '.', 'c', 'o', 'm', '\0',
   /* "electricant.com", true */ 'e', 'l', 'e', 'c', 't', 'r', 'i', 'c', 'a', 'n', 't', '.', 'c', 'o', 'm', '\0',
   /* "electricant.nl", true */ 'e', 'l', 'e', 'c', 't', 'r', 'i', 'c', 'a', 'n', 't', '.', 'n', 'l', '\0',
   /* "electronic-ignition-system.com", true */ 'e', 'l', 'e', 'c', 't', 'r', 'o', 'n', 'i', 'c', '-', 'i', 'g', 'n', 'i', 't', 'i', 'o', 'n', '-', 's', 'y', 's', 't', 'e', 'm', '.', 'c', 'o', 'm', '\0',
   /* "electronicfasteners.com", true */ 'e', 'l', 'e', 'c', 't', 'r', 'o', 'n', 'i', 'c', 'f', 'a', 's', 't', 'e', 'n', 'e', 'r', 's', '.', 'c', 'o', 'm', '\0',
   /* "elefantevoador.com", true */ 'e', 'l', 'e', 'f', 'a', 'n', 't', 'e', 'v', 'o', 'a', 'd', 'o', 'r', '.', 'c', 'o', 'm', '\0',
   /* "eleicoes2016.com.br", true */ 'e', 'l', 'e', 'i', 'c', 'o', 'e', 's', '2', '0', '1', '6', '.', 'c', 'o', 'm', '.', 'b', 'r', '\0',
   /* "elektronring.com", true */ 'e', 'l', 'e', 'k', 't', 'r', 'o', 'n', 'r', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
@@ -3851,16 +3851,20 @@ static const char kSTSHostTable[] = {
   /* "end.pp.ua", true */ 'e', 'n', 'd', '.', 'p', 'p', '.', 'u', 'a', '\0',
   /* "endeal.nl", true */ 'e', 'n', 'd', 'e', 'a', 'l', '.', 'n', 'l', '\0',
   /* "ender.co.at", true */ 'e', 'n', 'd', 'e', 'r', '.', 'c', 'o', '.', 'a', 't', '\0',
   /* "endlessdark.net", true */ 'e', 'n', 'd', 'l', 'e', 's', 's', 'd', 'a', 'r', 'k', '.', 'n', 'e', 't', '\0',
   /* "endlessdiy.ca", true */ 'e', 'n', 'd', 'l', 'e', 's', 's', 'd', 'i', 'y', '.', 'c', 'a', '\0',
   /* "endlesshorizon.net", true */ 'e', 'n', 'd', 'l', 'e', 's', 's', 'h', 'o', 'r', 'i', 'z', 'o', 'n', '.', 'n', 'e', 't', '\0',
   /* "endlesstone.com", true */ 'e', 'n', 'd', 'l', 'e', 's', 's', 't', 'o', 'n', 'e', '.', 'c', 'o', 'm', '\0',
   /* "endofnet.org", true */ 'e', 'n', 'd', 'o', 'f', 'n', 'e', 't', '.', 'o', 'r', 'g', '\0',
+  /* "endohaus.ca", true */ 'e', 'n', 'd', 'o', 'h', 'a', 'u', 's', '.', 'c', 'a', '\0',
+  /* "endohaus.com", true */ 'e', 'n', 'd', 'o', 'h', 'a', 'u', 's', '.', 'c', 'o', 'm', '\0',
+  /* "endohaus.eu", true */ 'e', 'n', 'd', 'o', 'h', 'a', 'u', 's', '.', 'e', 'u', '\0',
+  /* "endohaus.us", true */ 'e', 'n', 'd', 'o', 'h', 'a', 'u', 's', '.', 'u', 's', '\0',
   /* "enecoshop.nl", true */ 'e', 'n', 'e', 'c', 'o', 's', 'h', 'o', 'p', '.', 'n', 'l', '\0',
   /* "enefan.jp", true */ 'e', 'n', 'e', 'f', 'a', 'n', '.', 'j', 'p', '\0',
   /* "energiekeurplus.nl", true */ 'e', 'n', 'e', 'r', 'g', 'i', 'e', 'k', 'e', 'u', 'r', 'p', 'l', 'u', 's', '.', 'n', 'l', '\0',
   /* "energy-drink-magazin.de", true */ 'e', 'n', 'e', 'r', 'g', 'y', '-', 'd', 'r', 'i', 'n', 'k', '-', 'm', 'a', 'g', 'a', 'z', 'i', 'n', '.', 'd', 'e', '\0',
   /* "energy-infra.nl", true */ 'e', 'n', 'e', 'r', 'g', 'y', '-', 'i', 'n', 'f', 'r', 'a', '.', 'n', 'l', '\0',
   /* "energy.eu", true */ 'e', 'n', 'e', 'r', 'g', 'y', '.', 'e', 'u', '\0',
   /* "energyatlas.com", true */ 'e', 'n', 'e', 'r', 'g', 'y', 'a', 't', 'l', 'a', 's', '.', 'c', 'o', 'm', '\0',
   /* "energydrinkblog.de", true */ 'e', 'n', 'e', 'r', 'g', 'y', 'd', 'r', 'i', 'n', 'k', 'b', 'l', 'o', 'g', '.', 'd', 'e', '\0',
@@ -3940,17 +3944,16 @@ static const char kSTSHostTable[] = {
   /* "eriix.org", true */ 'e', 'r', 'i', 'i', 'x', '.', 'o', 'r', 'g', '\0',
   /* "erikhubers.nl", true */ 'e', 'r', 'i', 'k', 'h', 'u', 'b', 'e', 'r', 's', '.', 'n', 'l', '\0',
   /* "erikseth.de", true */ 'e', 'r', 'i', 'k', 's', 'e', 't', 'h', '.', 'd', 'e', '\0',
   /* "eriner.me", true */ 'e', 'r', 'i', 'n', 'e', 'r', '.', 'm', 'e', '\0',
   /* "erisrenee.com", true */ 'e', 'r', 'i', 's', 'r', 'e', 'n', 'e', 'e', '.', 'c', 'o', 'm', '\0',
   /* "ernaehrungsberatung-rapperswil.ch", true */ 'e', 'r', 'n', 'a', 'e', 'h', 'r', 'u', 'n', 'g', 's', 'b', 'e', 'r', 'a', 't', 'u', 'n', 'g', '-', 'r', 'a', 'p', 'p', 'e', 'r', 's', 'w', 'i', 'l', '.', 'c', 'h', '\0',
   /* "ernaehrungsberatung-zurich.ch", true */ 'e', 'r', 'n', 'a', 'e', 'h', 'r', 'u', 'n', 'g', 's', 'b', 'e', 'r', 'a', 't', 'u', 'n', 'g', '-', 'z', 'u', 'r', 'i', 'c', 'h', '.', 'c', 'h', '\0',
   /* "ernest.ly", true */ 'e', 'r', 'n', 'e', 's', 't', '.', 'l', 'y', '\0',
-  /* "ernesto.at", true */ 'e', 'r', 'n', 'e', 's', 't', 'o', '.', 'a', 't', '\0',
   /* "erp-band.ru", true */ 'e', 'r', 'p', '-', 'b', 'a', 'n', 'd', '.', 'r', 'u', '\0',
   /* "erp.band", true */ 'e', 'r', 'p', '.', 'b', 'a', 'n', 'd', '\0',
   /* "erpband.ru", true */ 'e', 'r', 'p', 'b', 'a', 'n', 'd', '.', 'r', 'u', '\0',
   /* "erpcargo.com", false */ 'e', 'r', 'p', 'c', 'a', 'r', 'g', 'o', '.', 'c', 'o', 'm', '\0',
   /* "eru.me", true */ 'e', 'r', 'u', '.', 'm', 'e', '\0',
   /* "erudikum.cz", true */ 'e', 'r', 'u', 'd', 'i', 'k', 'u', 'm', '.', 'c', 'z', '\0',
   /* "erwanlepape.com", true */ 'e', 'r', 'w', 'a', 'n', 'l', 'e', 'p', 'a', 'p', 'e', '.', 'c', 'o', 'm', '\0',
   /* "erwinwensveen.nl", true */ 'e', 'r', 'w', 'i', 'n', 'w', 'e', 'n', 's', 'v', 'e', 'e', 'n', '.', 'n', 'l', '\0',
@@ -3978,17 +3981,16 @@ static const char kSTSHostTable[] = {
   /* "esp8285.store", true */ 'e', 's', 'p', '8', '2', '8', '5', '.', 's', 't', 'o', 'r', 'e', '\0',
   /* "espace-gestion.fr", true */ 'e', 's', 'p', 'a', 'c', 'e', '-', 'g', 'e', 's', 't', 'i', 'o', 'n', '.', 'f', 'r', '\0',
   /* "espacemontmorency.com", true */ 'e', 's', 'p', 'a', 'c', 'e', 'm', 'o', 'n', 't', 'm', 'o', 'r', 'e', 'n', 'c', 'y', '.', 'c', 'o', 'm', '\0',
   /* "espanol.search.yahoo.com", false */ 'e', 's', 'p', 'a', 'n', 'o', 'l', '.', 's', 'e', 'a', 'r', 'c', 'h', '.', 'y', 'a', 'h', 'o', 'o', '.', 'c', 'o', 'm', '\0',
   /* "espanova.com", true */ 'e', 's', 'p', 'a', 'n', 'o', 'v', 'a', '.', 'c', 'o', 'm', '\0',
   /* "espci.fr", true */ 'e', 's', 'p', 'c', 'i', '.', 'f', 'r', '\0',
   /* "especificosba.com.ar", true */ 'e', 's', 'p', 'e', 'c', 'i', 'f', 'i', 'c', 'o', 's', 'b', 'a', '.', 'c', 'o', 'm', '.', 'a', 'r', '\0',
   /* "espgg.org", true */ 'e', 's', 'p', 'g', 'g', '.', 'o', 'r', 'g', '\0',
-  /* "esquonic.com", true */ 'e', 's', 'q', 'u', 'o', 'n', 'i', 'c', '.', 'c', 'o', 'm', '\0',
   /* "ess-cert.ru", true */ 'e', 's', 's', '-', 'c', 'e', 'r', 't', '.', 'r', 'u', '\0',
   /* "essentialoilsimports.com", true */ 'e', 's', 's', 'e', 'n', 't', 'i', 'a', 'l', 'o', 'i', 'l', 's', 'i', 'm', 'p', 'o', 'r', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "esseriumani.com", true */ 'e', 's', 's', 'e', 'r', 'i', 'u', 'm', 'a', 'n', 'i', '.', 'c', 'o', 'm', '\0',
   /* "essoduke.org", true */ 'e', 's', 's', 'o', 'd', 'u', 'k', 'e', '.', 'o', 'r', 'g', '\0',
   /* "estaciona.guru", true */ 'e', 's', 't', 'a', 'c', 'i', 'o', 'n', 'a', '.', 'g', 'u', 'r', 'u', '\0',
   /* "estaleiro.org", true */ 'e', 's', 't', 'a', 'l', 'e', 'i', 'r', 'o', '.', 'o', 'r', 'g', '\0',
   /* "estan.cn", true */ 'e', 's', 't', 'a', 'n', '.', 'c', 'n', '\0',
   /* "estateczech-eu.ru", true */ 'e', 's', 't', 'a', 't', 'e', 'c', 'z', 'e', 'c', 'h', '-', 'e', 'u', '.', 'r', 'u', '\0',
@@ -4225,17 +4227,16 @@ static const char kSTSHostTable[] = {
   /* "faspirits.com", true */ 'f', 'a', 's', 'p', 'i', 'r', 'i', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "fassadenverkleidung24.de", true */ 'f', 'a', 's', 's', 'a', 'd', 'e', 'n', 'v', 'e', 'r', 'k', 'l', 'e', 'i', 'd', 'u', 'n', 'g', '2', '4', '.', 'd', 'e', '\0',
   /* "fastaim.de", true */ 'f', 'a', 's', 't', 'a', 'i', 'm', '.', 'd', 'e', '\0',
   /* "fastcomcorp.com", true */ 'f', 'a', 's', 't', 'c', 'o', 'm', 'c', 'o', 'r', 'p', '.', 'c', 'o', 'm', '\0',
   /* "fastcomcorp.net", true */ 'f', 'a', 's', 't', 'c', 'o', 'm', 'c', 'o', 'r', 'p', '.', 'n', 'e', 't', '\0',
   /* "fastconfirm.com", true */ 'f', 'a', 's', 't', 'c', 'o', 'n', 'f', 'i', 'r', 'm', '.', 'c', 'o', 'm', '\0',
   /* "fastmail.com", false */ 'f', 'a', 's', 't', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm', '\0',
   /* "fastograph.com", true */ 'f', 'a', 's', 't', 'o', 'g', 'r', 'a', 'p', 'h', '.', 'c', 'o', 'm', '\0',
-  /* "fatlossguide.xyz", true */ 'f', 'a', 't', 'l', 'o', 's', 's', 'g', 'u', 'i', 'd', 'e', '.', 'x', 'y', 'z', '\0',
   /* "fatzebra.com.au", false */ 'f', 'a', 't', 'z', 'e', 'b', 'r', 'a', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "faucetbox.com", true */ 'f', 'a', 'u', 'c', 'e', 't', 'b', 'o', 'x', '.', 'c', 'o', 'm', '\0',
   /* "favorit.club", true */ 'f', 'a', 'v', 'o', 'r', 'i', 't', '.', 'c', 'l', 'u', 'b', '\0',
   /* "fawkex.me", true */ 'f', 'a', 'w', 'k', 'e', 'x', '.', 'm', 'e', '\0',
   /* "fawong.com", true */ 'f', 'a', 'w', 'o', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "faxreader.net", true */ 'f', 'a', 'x', 'r', 'e', 'a', 'd', 'e', 'r', '.', 'n', 'e', 't', '\0',
   /* "fca-tools.com", true */ 'f', 'c', 'a', '-', 't', 'o', 'o', 'l', 's', '.', 'c', 'o', 'm', '\0',
   /* "fcburk.de", true */ 'f', 'c', 'b', 'u', 'r', 'k', '.', 'd', 'e', '\0',
@@ -4525,17 +4526,17 @@ static const char kSTSHostTable[] = {
   /* "fraho.eu", true */ 'f', 'r', 'a', 'h', 'o', '.', 'e', 'u', '\0',
   /* "fralef.me", false */ 'f', 'r', 'a', 'l', 'e', 'f', '.', 'm', 'e', '\0',
   /* "fran.cr", true */ 'f', 'r', 'a', 'n', '.', 'c', 'r', '\0',
   /* "francescopalazzo.com", true */ 'f', 'r', 'a', 'n', 'c', 'e', 's', 'c', 'o', 'p', 'a', 'l', 'a', 'z', 'z', 'o', '.', 'c', 'o', 'm', '\0',
   /* "franckgirard.net", true */ 'f', 'r', 'a', 'n', 'c', 'k', 'g', 'i', 'r', 'a', 'r', 'd', '.', 'n', 'e', 't', '\0',
   /* "francoz.me", true */ 'f', 'r', 'a', 'n', 'c', 'o', 'z', '.', 'm', 'e', '\0',
   /* "frank.fyi", true */ 'f', 'r', 'a', 'n', 'k', '.', 'f', 'y', 'i', '\0',
   /* "franke-chemie.de", true */ 'f', 'r', 'a', 'n', 'k', 'e', '-', 'c', 'h', 'e', 'm', 'i', 'e', '.', 'd', 'e', '\0',
-  /* "franken-lehrmittel.de", true */ 'f', 'r', 'a', 'n', 'k', 'e', 'n', '-', 'l', 'e', 'h', 'r', 'm', 'i', 't', 't', 'e', 'l', '.', 'd', 'e', '\0',
+  /* "franken-lehrmittel.de", false */ 'f', 'r', 'a', 'n', 'k', 'e', 'n', '-', 'l', 'e', 'h', 'r', 'm', 'i', 't', 't', 'e', 'l', '.', 'd', 'e', '\0',
   /* "frankhaala.com", true */ 'f', 'r', 'a', 'n', 'k', 'h', 'a', 'a', 'l', 'a', '.', 'c', 'o', 'm', '\0',
   /* "frankierprofi.de", true */ 'f', 'r', 'a', 'n', 'k', 'i', 'e', 'r', 'p', 'r', 'o', 'f', 'i', '.', 'd', 'e', '\0',
   /* "frankl.in", true */ 'f', 'r', 'a', 'n', 'k', 'l', '.', 'i', 'n', '\0',
   /* "frankwei.xyz", true */ 'f', 'r', 'a', 'n', 'k', 'w', 'e', 'i', '.', 'x', 'y', 'z', '\0',
   /* "fransallen.com", true */ 'f', 'r', 'a', 'n', 's', 'a', 'l', 'l', 'e', 'n', '.', 'c', 'o', 'm', '\0',
   /* "frantic1048.com", true */ 'f', 'r', 'a', 'n', 't', 'i', 'c', '1', '0', '4', '8', '.', 'c', 'o', 'm', '\0',
   /* "franzt.ovh", true */ 'f', 'r', 'a', 'n', 'z', 't', '.', 'o', 'v', 'h', '\0',
   /* "frappant.cc", true */ 'f', 'r', 'a', 'p', 'p', 'a', 'n', 't', '.', 'c', 'c', '\0',
@@ -4611,17 +4612,16 @@ static const char kSTSHostTable[] = {
   /* "frtr.gov", true */ 'f', 'r', 't', 'r', '.', 'g', 'o', 'v', '\0',
   /* "fruchthof24.de", true */ 'f', 'r', 'u', 'c', 'h', 't', 'h', 'o', 'f', '2', '4', '.', 'd', 'e', '\0',
   /* "frugro.be", true */ 'f', 'r', 'u', 'g', 'r', 'o', '.', 'b', 'e', '\0',
   /* "frusky.de", true */ 'f', 'r', 'u', 's', 'k', 'y', '.', 'd', 'e', '\0',
   /* "fs-gamenet.de", true */ 'f', 's', '-', 'g', 'a', 'm', 'e', 'n', 'e', 't', '.', 'd', 'e', '\0',
   /* "fsapubs.gov", true */ 'f', 's', 'a', 'p', 'u', 'b', 's', '.', 'g', 'o', 'v', '\0',
   /* "fsbpaintrock.com", true */ 'f', 's', 'b', 'p', 'a', 'i', 'n', 't', 'r', 'o', 'c', 'k', '.', 'c', 'o', 'm', '\0',
   /* "fsbturton.com", true */ 'f', 's', 'b', 't', 'u', 'r', 't', 'o', 'n', '.', 'c', 'o', 'm', '\0',
-  /* "fsf.moe", true */ 'f', 's', 'f', '.', 'm', 'o', 'e', '\0',
   /* "fsfi.is", true */ 'f', 's', 'f', 'i', '.', 'i', 's', '\0',
   /* "fsinf.at", true */ 'f', 's', 'i', 'n', 'f', '.', 'a', 't', '\0',
   /* "fsm2016.org", true */ 'f', 's', 'm', '2', '0', '1', '6', '.', 'o', 'r', 'g', '\0',
   /* "fspphoto.com", true */ 'f', 's', 'p', 'p', 'h', 'o', 't', 'o', '.', 'c', 'o', 'm', '\0',
   /* "ftc.gov", false */ 'f', 't', 'c', '.', 'g', 'o', 'v', '\0',
   /* "ftccomplaintassistant.gov", true */ 'f', 't', 'c', 'c', 'o', 'm', 'p', 'l', 'a', 'i', 'n', 't', 'a', 's', 's', 'i', 's', 't', 'a', 'n', 't', '.', 'g', 'o', 'v', '\0',
   /* "fteproxy.org", true */ 'f', 't', 'e', 'p', 'r', 'o', 'x', 'y', '.', 'o', 'r', 'g', '\0',
   /* "ftrsecure.com", true */ 'f', 't', 'r', 's', 'e', 'c', 'u', 'r', 'e', '.', 'c', 'o', 'm', '\0',
@@ -4674,17 +4674,16 @@ static const char kSTSHostTable[] = {
   /* "fxp.co.il", true */ 'f', 'x', 'p', '.', 'c', 'o', '.', 'i', 'l', '\0',
   /* "fxtalk.cn", true */ 'f', 'x', 't', 'a', 'l', 'k', '.', 'c', 'n', '\0',
   /* "fyfywka.com", true */ 'f', 'y', 'f', 'y', 'w', 'k', 'a', '.', 'c', 'o', 'm', '\0',
   /* "fyn.nl", true */ 'f', 'y', 'n', '.', 'n', 'l', '\0',
   /* "fyrkat.no", true */ 'f', 'y', 'r', 'k', 'a', 't', '.', 'n', 'o', '\0',
   /* "g-m-w.eu", true */ 'g', '-', 'm', '-', 'w', '.', 'e', 'u', '\0',
   /* "g-marketing.ro", true */ 'g', '-', 'm', 'a', 'r', 'k', 'e', 't', 'i', 'n', 'g', '.', 'r', 'o', '\0',
   /* "g-o.pl", true */ 'g', '-', 'o', '.', 'p', 'l', '\0',
-  /* "g01.in.ua", true */ 'g', '0', '1', '.', 'i', 'n', '.', 'u', 'a', '\0',
   /* "g2links.com", true */ 'g', '2', 'l', 'i', 'n', 'k', 's', '.', 'c', 'o', 'm', '\0',
   /* "g2pla.net", true */ 'g', '2', 'p', 'l', 'a', '.', 'n', 'e', 't', '\0',
   /* "g2soft.net", true */ 'g', '2', 's', 'o', 'f', 't', '.', 'n', 'e', 't', '\0',
   /* "g4w.co", true */ 'g', '4', 'w', '.', 'c', 'o', '\0',
   /* "g5led.nl", true */ 'g', '5', 'l', 'e', 'd', '.', 'n', 'l', '\0',
   /* "gabi.com.es", true */ 'g', 'a', 'b', 'i', '.', 'c', 'o', 'm', '.', 'e', 's', '\0',
   /* "gabi.uno", true */ 'g', 'a', 'b', 'i', '.', 'u', 'n', 'o', '\0',
   /* "gablaxian.com", true */ 'g', 'a', 'b', 'l', 'a', 'x', 'i', 'a', 'n', '.', 'c', 'o', 'm', '\0',
@@ -4994,30 +4993,30 @@ static const char kSTSHostTable[] = {
   /* "gohon.org", true */ 'g', 'o', 'h', 'o', 'n', '.', 'o', 'r', 'g', '\0',
   /* "gokhankesici.com", true */ 'g', 'o', 'k', 'h', 'a', 'n', 'k', 'e', 's', 'i', 'c', 'i', '.', 'c', 'o', 'm', '\0',
   /* "gokmenguresci.com", true */ 'g', 'o', 'k', 'm', 'e', 'n', 'g', 'u', 'r', 'e', 's', 'c', 'i', '.', 'c', 'o', 'm', '\0',
   /* "gold24.ru", true */ 'g', 'o', 'l', 'd', '2', '4', '.', 'r', 'u', '\0',
   /* "goldenhillsoftware.com", true */ 'g', 'o', 'l', 'd', 'e', 'n', 'h', 'i', 'l', 'l', 's', 'o', 'f', 't', 'w', 'a', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "goldenhost.ca", true */ 'g', 'o', 'l', 'd', 'e', 'n', 'h', 'o', 's', 't', '.', 'c', 'a', '\0',
   /* "goldmark.com.au", true */ 'g', 'o', 'l', 'd', 'm', 'a', 'r', 'k', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "goldpreisfinder.at", true */ 'g', 'o', 'l', 'd', 'p', 'r', 'e', 'i', 's', 'f', 'i', 'n', 'd', 'e', 'r', '.', 'a', 't', '\0',
-  /* "goldpros.com", true */ 'g', 'o', 'l', 'd', 'p', 'r', 'o', 's', '.', 'c', 'o', 'm', '\0',
   /* "goldsecurity.com", true */ 'g', 'o', 'l', 'd', 's', 'e', 'c', 'u', 'r', 'i', 't', 'y', '.', 'c', 'o', 'm', '\0',
   /* "golf18network.com", true */ 'g', 'o', 'l', 'f', '1', '8', 'n', 'e', 't', 'w', 'o', 'r', 'k', '.', 'c', 'o', 'm', '\0',
   /* "golfburn.com", true */ 'g', 'o', 'l', 'f', 'b', 'u', 'r', 'n', '.', 'c', 'o', 'm', '\0',
   /* "golfscape.com", true */ 'g', 'o', 'l', 'f', 's', 'c', 'a', 'p', 'e', '.', 'c', 'o', 'm', '\0',
   /* "gong8.win", true */ 'g', 'o', 'n', 'g', '8', '.', 'w', 'i', 'n', '\0',
   /* "gonkar.com", true */ 'g', 'o', 'n', 'k', 'a', 'r', '.', 'c', 'o', 'm', '\0',
   /* "gooby.co", true */ 'g', 'o', 'o', 'b', 'y', '.', 'c', 'o', '\0',
   /* "goodmengroup.de", true */ 'g', 'o', 'o', 'd', 'm', 'e', 'n', 'g', 'r', 'o', 'u', 'p', '.', 'd', 'e', '\0',
   /* "google", true */ 'g', 'o', 'o', 'g', 'l', 'e', '\0',
   /* "google-analytics.com", true */ 'g', 'o', 'o', 'g', 'l', 'e', '-', 'a', 'n', 'a', 'l', 'y', 't', 'i', 'c', 's', '.', 'c', 'o', 'm', '\0',
   /* "googlemail.com", false */ 'g', 'o', 'o', 'g', 'l', 'e', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm', '\0',
   /* "googleplex.com", true */ 'g', 'o', 'o', 'g', 'l', 'e', 'p', 'l', 'e', 'x', '.', 'c', 'o', 'm', '\0',
   /* "googlesource.com", true */ 'g', 'o', 'o', 'g', 'l', 'e', 's', 'o', 'u', 'r', 'c', 'e', '.', 'c', 'o', 'm', '\0',
+  /* "goolok.com", true */ 'g', 'o', 'o', 'l', 'o', 'k', '.', 'c', 'o', 'm', '\0',
   /* "goozz.nl", true */ 'g', 'o', 'o', 'z', 'z', '.', 'n', 'l', '\0',
   /* "gopay.cz", true */ 'g', 'o', 'p', 'a', 'y', '.', 'c', 'z', '\0',
   /* "gopokego.cz", true */ 'g', 'o', 'p', 'o', 'k', 'e', 'g', 'o', '.', 'c', 'z', '\0',
   /* "gordonobrecht.com", true */ 'g', 'o', 'r', 'd', 'o', 'n', 'o', 'b', 'r', 'e', 'c', 'h', 't', '.', 'c', 'o', 'm', '\0',
   /* "gorf.chat", true */ 'g', 'o', 'r', 'f', '.', 'c', 'h', 'a', 't', '\0',
   /* "gorgiaxx.com", true */ 'g', 'o', 'r', 'g', 'i', 'a', 'x', 'x', '.', 'c', 'o', 'm', '\0',
   /* "gorod74.ru", true */ 'g', 'o', 'r', 'o', 'd', '7', '4', '.', 'r', 'u', '\0',
   /* "gorschenin.com", true */ 'g', 'o', 'r', 's', 'c', 'h', 'e', 'n', 'i', 'n', '.', 'c', 'o', 'm', '\0',
@@ -5090,18 +5089,16 @@ static const char kSTSHostTable[] = {
   /* "gravitechthai.com", true */ 'g', 'r', 'a', 'v', 'i', 't', 'e', 'c', 'h', 't', 'h', 'a', 'i', '.', 'c', 'o', 'm', '\0',
   /* "gravito.nl", true */ 'g', 'r', 'a', 'v', 'i', 't', 'o', '.', 'n', 'l', '\0',
   /* "gravity-dev.de", true */ 'g', 'r', 'a', 'v', 'i', 't', 'y', '-', 'd', 'e', 'v', '.', 'd', 'e', '\0',
   /* "graymalk.in", true */ 'g', 'r', 'a', 'y', 'm', 'a', 'l', 'k', '.', 'i', 'n', '\0',
   /* "grc.com", false */ 'g', 'r', 'c', '.', 'c', 'o', 'm', '\0',
   /* "grcnode.co.uk", true */ 'g', 'r', 'c', 'n', 'o', 'd', 'e', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "greatfire.org", true */ 'g', 'r', 'e', 'a', 't', 'f', 'i', 'r', 'e', '.', 'o', 'r', 'g', '\0',
   /* "greatnet.de", true */ 'g', 'r', 'e', 'a', 't', 'n', 'e', 't', '.', 'd', 'e', '\0',
-  /* "greboid.co.uk", true */ 'g', 'r', 'e', 'b', 'o', 'i', 'd', '.', 'c', 'o', '.', 'u', 'k', '\0',
-  /* "greboid.com", true */ 'g', 'r', 'e', 'b', 'o', 'i', 'd', '.', 'c', 'o', 'm', '\0',
   /* "greedbutt.com", true */ 'g', 'r', 'e', 'e', 'd', 'b', 'u', 't', 't', '.', 'c', 'o', 'm', '\0',
   /* "greek.dating", true */ 'g', 'r', 'e', 'e', 'k', '.', 'd', 'a', 't', 'i', 'n', 'g', '\0',
   /* "green-attitude.be", true */ 'g', 'r', 'e', 'e', 'n', '-', 'a', 't', 't', 'i', 't', 'u', 'd', 'e', '.', 'b', 'e', '\0',
   /* "greenaddress.it", true */ 'g', 'r', 'e', 'e', 'n', 'a', 'd', 'd', 'r', 'e', 's', 's', '.', 'i', 't', '\0',
   /* "greencardtalent.com", true */ 'g', 'r', 'e', 'e', 'n', 'c', 'a', 'r', 'd', 't', 'a', 'l', 'e', 'n', 't', '.', 'c', 'o', 'm', '\0',
   /* "greencircleplantnursery.com.au", true */ 'g', 'r', 'e', 'e', 'n', 'c', 'i', 'r', 'c', 'l', 'e', 'p', 'l', 'a', 'n', 't', 'n', 'u', 'r', 's', 'e', 'r', 'y', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "greencircleplantnursery.net.au", true */ 'g', 'r', 'e', 'e', 'n', 'c', 'i', 'r', 'c', 'l', 'e', 'p', 'l', 'a', 'n', 't', 'n', 'u', 'r', 's', 'e', 'r', 'y', '.', 'n', 'e', 't', '.', 'a', 'u', '\0',
   /* "greenpeace-magazin.de", true */ 'g', 'r', 'e', 'e', 'n', 'p', 'e', 'a', 'c', 'e', '-', 'm', 'a', 'g', 'a', 'z', 'i', 'n', '.', 'd', 'e', '\0',
@@ -5284,17 +5281,16 @@ static const char kSTSHostTable[] = {
   /* "halo.fr", true */ 'h', 'a', 'l', 'o', '.', 'f', 'r', '\0',
   /* "hamali.bg", true */ 'h', 'a', 'm', 'a', 'l', 'i', '.', 'b', 'g', '\0',
   /* "haman.nl", true */ 'h', 'a', 'm', 'a', 'n', '.', 'n', 'l', '\0',
   /* "hana.ondemand.com", true */ 'h', 'a', 'n', 'a', '.', 'o', 'n', 'd', 'e', 'm', 'a', 'n', 'd', '.', 'c', 'o', 'm', '\0',
   /* "handenafvanhetmedischdossier.nl", true */ 'h', 'a', 'n', 'd', 'e', 'n', 'a', 'f', 'v', 'a', 'n', 'h', 'e', 't', 'm', 'e', 'd', 'i', 's', 'c', 'h', 'd', 'o', 's', 's', 'i', 'e', 'r', '.', 'n', 'l', '\0',
   /* "handiworker.com", true */ 'h', 'a', 'n', 'd', 'i', 'w', 'o', 'r', 'k', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "handmadetutorials.ro", true */ 'h', 'a', 'n', 'd', 'm', 'a', 'd', 'e', 't', 'u', 't', 'o', 'r', 'i', 'a', 'l', 's', '.', 'r', 'o', '\0',
   /* "handycommerce.co", true */ 'h', 'a', 'n', 'd', 'y', 'c', 'o', 'm', 'm', 'e', 'r', 'c', 'e', '.', 'c', 'o', '\0',
-  /* "hang333.pw", true */ 'h', 'a', 'n', 'g', '3', '3', '3', '.', 'p', 'w', '\0',
   /* "hangouts.google.com", true */ 'h', 'a', 'n', 'g', 'o', 'u', 't', 's', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "hanimalis.fr", true */ 'h', 'a', 'n', 'i', 'm', 'a', 'l', 'i', 's', '.', 'f', 'r', '\0',
   /* "hans-natur.de", true */ 'h', 'a', 'n', 's', '-', 'n', 'a', 't', 'u', 'r', '.', 'd', 'e', '\0',
   /* "hansen.hn", true */ 'h', 'a', 'n', 's', 'e', 'n', '.', 'h', 'n', '\0',
   /* "hansvaneijsden.com", true */ 'h', 'a', 'n', 's', 'v', 'a', 'n', 'e', 'i', 'j', 's', 'd', 'e', 'n', '.', 'c', 'o', 'm', '\0',
   /* "hansvaneijsden.nl", true */ 'h', 'a', 'n', 's', 'v', 'a', 'n', 'e', 'i', 'j', 's', 'd', 'e', 'n', '.', 'n', 'l', '\0',
   /* "hantse.com", true */ 'h', 'a', 'n', 't', 's', 'e', '.', 'c', 'o', 'm', '\0',
   /* "hanu.la", true */ 'h', 'a', 'n', 'u', '.', 'l', 'a', '\0',
@@ -5457,17 +5453,16 @@ static const char kSTSHostTable[] = {
   /* "henok.eu", true */ 'h', 'e', 'n', 'o', 'k', '.', 'e', 'u', '\0',
   /* "henriksen.is", true */ 'h', 'e', 'n', 'r', 'i', 'k', 's', 'e', 'n', '.', 'i', 's', '\0',
   /* "henrock.net", true */ 'h', 'e', 'n', 'r', 'o', 'c', 'k', '.', 'n', 'e', 't', '\0',
   /* "henryphan.com", false */ 'h', 'e', 'n', 'r', 'y', 'p', 'h', 'a', 'n', '.', 'c', 'o', 'm', '\0',
   /* "hentschke-bau.de", true */ 'h', 'e', 'n', 't', 's', 'c', 'h', 'k', 'e', '-', 'b', 'a', 'u', '.', 'd', 'e', '\0',
   /* "hentschke-betonfertigteilwerk.de", true */ 'h', 'e', 'n', 't', 's', 'c', 'h', 'k', 'e', '-', 'b', 'e', 't', 'o', 'n', 'f', 'e', 'r', 't', 'i', 'g', 't', 'e', 'i', 'l', 'w', 'e', 'r', 'k', '.', 'd', 'e', '\0',
   /* "hentschke-invest.de", true */ 'h', 'e', 'n', 't', 's', 'c', 'h', 'k', 'e', '-', 'i', 'n', 'v', 'e', 's', 't', '.', 'd', 'e', '\0',
   /* "heppler.net", true */ 'h', 'e', 'p', 'p', 'l', 'e', 'r', '.', 'n', 'e', 't', '\0',
-  /* "hepteract.us", true */ 'h', 'e', 'p', 't', 'e', 'r', 'a', 'c', 't', '.', 'u', 's', '\0',
   /* "herbandpat.org", true */ 'h', 'e', 'r', 'b', 'a', 'n', 'd', 'p', 'a', 't', '.', 'o', 'r', 'g', '\0',
   /* "herbert.io", true */ 'h', 'e', 'r', 'b', 'e', 'r', 't', '.', 'i', 'o', '\0',
   /* "herbertmouwen.nl", true */ 'h', 'e', 'r', 'b', 'e', 'r', 't', 'm', 'o', 'u', 'w', 'e', 'n', '.', 'n', 'l', '\0',
   /* "herbweb.net", true */ 'h', 'e', 'r', 'b', 'w', 'e', 'b', '.', 'n', 'e', 't', '\0',
   /* "herbweb.org", true */ 'h', 'e', 'r', 'b', 'w', 'e', 'b', '.', 'o', 'r', 'g', '\0',
   /* "herds.eu", true */ 'h', 'e', 'r', 'd', 's', '.', 'e', 'u', '\0',
   /* "herebedragons.io", true */ 'h', 'e', 'r', 'e', 'b', 'e', 'd', 'r', 'a', 'g', 'o', 'n', 's', '.', 'i', 'o', '\0',
   /* "heritagedentistry.ca", true */ 'h', 'e', 'r', 'i', 't', 'a', 'g', 'e', 'd', 'e', 'n', 't', 'i', 's', 't', 'r', 'y', '.', 'c', 'a', '\0',
@@ -5613,30 +5608,31 @@ static const char kSTSHostTable[] = {
   /* "hosiet.me", true */ 'h', 'o', 's', 'i', 'e', 't', '.', 'm', 'e', '\0',
   /* "hosmussynergie.nl", true */ 'h', 'o', 's', 'm', 'u', 's', 's', 'y', 'n', 'e', 'r', 'g', 'i', 'e', '.', 'n', 'l', '\0',
   /* "hospitalhomelottery.org", true */ 'h', 'o', 's', 'p', 'i', 't', 'a', 'l', 'h', 'o', 'm', 'e', 'l', 'o', 't', 't', 'e', 'r', 'y', '.', 'o', 'r', 'g', '\0',
   /* "hostam.link", true */ 'h', 'o', 's', 't', 'a', 'm', '.', 'l', 'i', 'n', 'k', '\0',
   /* "hostanalyticsconsulting.com", true */ 'h', 'o', 's', 't', 'a', 'n', 'a', 'l', 'y', 't', 'i', 'c', 's', 'c', 'o', 'n', 's', 'u', 'l', 't', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "hosteasy.nl", true */ 'h', 'o', 's', 't', 'e', 'a', 's', 'y', '.', 'n', 'l', '\0',
   /* "hosted-oswa.org", true */ 'h', 'o', 's', 't', 'e', 'd', '-', 'o', 's', 'w', 'a', '.', 'o', 'r', 'g', '\0',
   /* "hosted4u.de", true */ 'h', 'o', 's', 't', 'e', 'd', '4', 'u', '.', 'd', 'e', '\0',
+  /* "hostedbgp.net", true */ 'h', 'o', 's', 't', 'e', 'd', 'b', 'g', 'p', '.', 'n', 'e', 't', '\0',
   /* "hostedtalkgadget.google.com", true */ 'h', 'o', 's', 't', 'e', 'd', 't', 'a', 'l', 'k', 'g', 'a', 'd', 'g', 'e', 't', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "hostelite.com", true */ 'h', 'o', 's', 't', 'e', 'l', 'i', 't', 'e', '.', 'c', 'o', 'm', '\0',
   /* "hostfission.com", true */ 'h', 'o', 's', 't', 'f', 'i', 's', 's', 'i', 'o', 'n', '.', 'c', 'o', 'm', '\0',
   /* "hostingactive.it", true */ 'h', 'o', 's', 't', 'i', 'n', 'g', 'a', 'c', 't', 'i', 'v', 'e', '.', 'i', 't', '\0',
   /* "hostingfj.com", true */ 'h', 'o', 's', 't', 'i', 'n', 'g', 'f', 'j', '.', 'c', 'o', 'm', '\0',
   /* "hostinghelp.guru", true */ 'h', 'o', 's', 't', 'i', 'n', 'g', 'h', 'e', 'l', 'p', '.', 'g', 'u', 'r', 'u', '\0',
   /* "hostinginnederland.nl", true */ 'h', 'o', 's', 't', 'i', 'n', 'g', 'i', 'n', 'n', 'e', 'd', 'e', 'r', 'l', 'a', 'n', 'd', '.', 'n', 'l', '\0',
   /* "hostix.de", true */ 'h', 'o', 's', 't', 'i', 'x', '.', 'd', 'e', '\0',
   /* "hostmijnpagina.nl", true */ 'h', 'o', 's', 't', 'm', 'i', 'j', 'n', 'p', 'a', 'g', 'i', 'n', 'a', '.', 'n', 'l', '\0',
   /* "hotchillibox.co.za", true */ 'h', 'o', 't', 'c', 'h', 'i', 'l', 'l', 'i', 'b', 'o', 'x', '.', 'c', 'o', '.', 'z', 'a', '\0',
-  /* "hotel-kronjuwel.de", true */ 'h', 'o', 't', 'e', 'l', '-', 'k', 'r', 'o', 'n', 'j', 'u', 'w', 'e', 'l', '.', 'd', 'e', '\0',
+  /* "hotel-kronjuwel.de", false */ 'h', 'o', 't', 'e', 'l', '-', 'k', 'r', 'o', 'n', 'j', 'u', 'w', 'e', 'l', '.', 'd', 'e', '\0',
   /* "hotel-pension-sonnalp.eu", true */ 'h', 'o', 't', 'e', 'l', '-', 'p', 'e', 'n', 's', 'i', 'o', 'n', '-', 's', 'o', 'n', 'n', 'a', 'l', 'p', '.', 'e', 'u', '\0',
   /* "hotel-tongruben.de", true */ 'h', 'o', 't', 'e', 'l', '-', 't', 'o', 'n', 'g', 'r', 'u', 'b', 'e', 'n', '.', 'd', 'e', '\0',
-  /* "hotelident.de", true */ 'h', 'o', 't', 'e', 'l', 'i', 'd', 'e', 'n', 't', '.', 'd', 'e', '\0',
+  /* "hotelident.de", false */ 'h', 'o', 't', 'e', 'l', 'i', 'd', 'e', 'n', 't', '.', 'd', 'e', '\0',
   /* "hotelmap.com", true */ 'h', 'o', 't', 'e', 'l', 'm', 'a', 'p', '.', 'c', 'o', 'm', '\0',
   /* "hotelvictoriaoax-mailing.com", true */ 'h', 'o', 't', 'e', 'l', 'v', 'i', 'c', 't', 'o', 'r', 'i', 'a', 'o', 'a', 'x', '-', 'm', 'a', 'i', 'l', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "hotelvillahermosa-mailing.com", true */ 'h', 'o', 't', 'e', 'l', 'v', 'i', 'l', 'l', 'a', 'h', 'e', 'r', 'm', 'o', 's', 'a', '-', 'm', 'a', 'i', 'l', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "hotelvue.nl", true */ 'h', 'o', 't', 'e', 'l', 'v', 'u', 'e', '.', 'n', 'l', '\0',
   /* "hoton.in", true */ 'h', 'o', 't', 'o', 'n', '.', 'i', 'n', '\0',
   /* "hotornot.com", true */ 'h', 'o', 't', 'o', 'r', 'n', 'o', 't', '.', 'c', 'o', 'm', '\0',
   /* "hotplug.gr", true */ 'h', 'o', 't', 'p', 'l', 'u', 'g', '.', 'g', 'r', '\0',
   /* "houser.lu", true */ 'h', 'o', 'u', 's', 'e', 'r', '.', 'l', 'u', '\0',
@@ -5686,23 +5682,23 @@ static const char kSTSHostTable[] = {
   /* "huagati.com", true */ 'h', 'u', 'a', 'g', 'a', 't', 'i', '.', 'c', 'o', 'm', '\0',
   /* "huang.nu", true */ 'h', 'u', 'a', 'n', 'g', '.', 'n', 'u', '\0',
   /* "huaxueba.com", true */ 'h', 'u', 'a', 'x', 'u', 'e', 'b', 'a', '.', 'c', 'o', 'm', '\0',
   /* "hubert.systems", true */ 'h', 'u', 'b', 'e', 'r', 't', '.', 's', 'y', 's', 't', 'e', 'm', 's', '\0',
   /* "hudingyuan.cn", true */ 'h', 'u', 'd', 'i', 'n', 'g', 'y', 'u', 'a', 'n', '.', 'c', 'n', '\0',
   /* "huersch.com", true */ 'h', 'u', 'e', 'r', 's', 'c', 'h', '.', 'c', 'o', 'm', '\0',
   /* "huffduffer.com", true */ 'h', 'u', 'f', 'f', 'd', 'u', 'f', 'f', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "hugocollignon.fr", false */ 'h', 'u', 'g', 'o', 'c', 'o', 'l', 'l', 'i', 'g', 'n', 'o', 'n', '.', 'f', 'r', '\0',
+  /* "hugofs.com", true */ 'h', 'u', 'g', 'o', 'f', 's', '.', 'c', 'o', 'm', '\0',
   /* "huihui.moe", true */ 'h', 'u', 'i', 'h', 'u', 'i', '.', 'm', 'o', 'e', '\0',
   /* "huiser.nl", true */ 'h', 'u', 'i', 's', 'e', 'r', '.', 'n', 'l', '\0',
   /* "humankode.com", true */ 'h', 'u', 'm', 'a', 'n', 'k', 'o', 'd', 'e', '.', 'c', 'o', 'm', '\0',
   /* "humpi.at", true */ 'h', 'u', 'm', 'p', 'i', '.', 'a', 't', '\0',
   /* "hund.io", true */ 'h', 'u', 'n', 'd', '.', 'i', 'o', '\0',
   /* "hunter.io", true */ 'h', 'u', 'n', 't', 'e', 'r', '.', 'i', 'o', '\0',
-  /* "huntshomeinspections.com", true */ 'h', 'u', 'n', 't', 's', 'h', 'o', 'm', 'e', 'i', 'n', 's', 'p', 'e', 'c', 't', 'i', 'o', 'n', 's', '.', 'c', 'o', 'm', '\0',
   /* "hup.blue", true */ 'h', 'u', 'p', '.', 'b', 'l', 'u', 'e', '\0',
   /* "hupp.se", true */ 'h', 'u', 'p', 'p', '.', 's', 'e', '\0',
   /* "hurd.is", true */ 'h', 'u', 'r', 'd', '.', 'i', 's', '\0',
   /* "huren.nl", true */ 'h', 'u', 'r', 'e', 'n', '.', 'n', 'l', '\0',
   /* "husakbau.at", true */ 'h', 'u', 's', 'a', 'k', 'b', 'a', 'u', '.', 'a', 't', '\0',
   /* "hushfile.it", true */ 'h', 'u', 's', 'h', 'f', 'i', 'l', 'e', '.', 'i', 't', '\0',
   /* "husic.net", true */ 'h', 'u', 's', 'i', 'c', '.', 'n', 'e', 't', '\0',
   /* "husky.xyz", true */ 'h', 'u', 's', 'k', 'y', '.', 'x', 'y', 'z', '\0',
@@ -5901,17 +5897,17 @@ static const char kSTSHostTable[] = {
   /* "inabox.ro", true */ 'i', 'n', 'a', 'b', 'o', 'x', '.', 'r', 'o', '\0',
   /* "inbitcoin.it", true */ 'i', 'n', 'b', 'i', 't', 'c', 'o', 'i', 'n', '.', 'i', 't', '\0',
   /* "inbounder.io", true */ 'i', 'n', 'b', 'o', 'u', 'n', 'd', 'e', 'r', '.', 'i', 'o', '\0',
   /* "inbox-group.com", true */ 'i', 'n', 'b', 'o', 'x', '-', 'g', 'r', 'o', 'u', 'p', '.', 'c', 'o', 'm', '\0',
   /* "inbox.google.com", true */ 'i', 'n', 'b', 'o', 'x', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', '\0',
   /* "inboxen.org", true */ 'i', 'n', 'b', 'o', 'x', 'e', 'n', '.', 'o', 'r', 'g', '\0',
   /* "incendiary-arts.com", true */ 'i', 'n', 'c', 'e', 'n', 'd', 'i', 'a', 'r', 'y', '-', 'a', 'r', 't', 's', '.', 'c', 'o', 'm', '\0',
   /* "inche-ali.com", true */ 'i', 'n', 'c', 'h', 'e', '-', 'a', 'l', 'i', '.', 'c', 'o', 'm', '\0',
-  /* "inconcerts.de", true */ 'i', 'n', 'c', 'o', 'n', 'c', 'e', 'r', 't', 's', '.', 'd', 'e', '\0',
+  /* "inconcerts.de", false */ 'i', 'n', 'c', 'o', 'n', 'c', 'e', 'r', 't', 's', '.', 'd', 'e', '\0',
   /* "incparadise.net", true */ 'i', 'n', 'c', 'p', 'a', 'r', 'a', 'd', 'i', 's', 'e', '.', 'n', 'e', 't', '\0',
   /* "incubos.org", true */ 'i', 'n', 'c', 'u', 'b', 'o', 's', '.', 'o', 'r', 'g', '\0',
   /* "indicateurs-flash.fr", true */ 'i', 'n', 'd', 'i', 'c', 'a', 't', 'e', 'u', 'r', 's', '-', 'f', 'l', 'a', 's', 'h', '.', 'f', 'r', '\0',
   /* "indiecert.net", false */ 'i', 'n', 'd', 'i', 'e', 'c', 'e', 'r', 't', '.', 'n', 'e', 't', '\0',
   /* "indievelopment.nl", true */ 'i', 'n', 'd', 'i', 'e', 'v', 'e', 'l', 'o', 'p', 'm', 'e', 'n', 't', '.', 'n', 'l', '\0',
   /* "indigosakura.com", true */ 'i', 'n', 'd', 'i', 'g', 'o', 's', 'a', 'k', 'u', 'r', 'a', '.', 'c', 'o', 'm', '\0',
   /* "inditip.com", true */ 'i', 'n', 'd', 'i', 't', 'i', 'p', '.', 'c', 'o', 'm', '\0',
   /* "indovinabank.com.vn", true */ 'i', 'n', 'd', 'o', 'v', 'i', 'n', 'a', 'b', 'a', 'n', 'k', '.', 'c', 'o', 'm', '.', 'v', 'n', '\0',
@@ -6008,17 +6004,17 @@ static const char kSTSHostTable[] = {
   /* "internetofdon.gs", true */ 'i', 'n', 't', 'e', 'r', 'n', 'e', 't', 'o', 'f', 'd', 'o', 'n', '.', 'g', 's', '\0',
   /* "internetpro.me", true */ 'i', 'n', 't', 'e', 'r', 'n', 'e', 't', 'p', 'r', 'o', '.', 'm', 'e', '\0',
   /* "internetstaff.com", true */ 'i', 'n', 't', 'e', 'r', 'n', 'e', 't', 's', 't', 'a', 'f', 'f', '.', 'c', 'o', 'm', '\0',
   /* "internetzentrale.net", true */ 'i', 'n', 't', 'e', 'r', 'n', 'e', 't', 'z', 'e', 'n', 't', 'r', 'a', 'l', 'e', '.', 'n', 'e', 't', '\0',
   /* "interociter-enterprises.com", true */ 'i', 'n', 't', 'e', 'r', 'o', 'c', 'i', 't', 'e', 'r', '-', 'e', 'n', 't', 'e', 'r', 'p', 'r', 'i', 's', 'e', 's', '.', 'c', 'o', 'm', '\0',
   /* "interviewpipeline.co.uk", true */ 'i', 'n', 't', 'e', 'r', 'v', 'i', 'e', 'w', 'p', 'i', 'p', 'e', 'l', 'i', 'n', 'e', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "intervisteperstrada.com", true */ 'i', 'n', 't', 'e', 'r', 'v', 'i', 's', 't', 'e', 'p', 'e', 'r', 's', 't', 'r', 'a', 'd', 'a', '.', 'c', 'o', 'm', '\0',
   /* "interways.de", true */ 'i', 'n', 't', 'e', 'r', 'w', 'a', 'y', 's', '.', 'd', 'e', '\0',
-  /* "intheater.de", true */ 'i', 'n', 't', 'h', 'e', 'a', 't', 'e', 'r', '.', 'd', 'e', '\0',
+  /* "intheater.de", false */ 'i', 'n', 't', 'h', 'e', 'a', 't', 'e', 'r', '.', 'd', 'e', '\0',
   /* "inthepicture.com", true */ 'i', 'n', 't', 'h', 'e', 'p', 'i', 'c', 't', 'u', 'r', 'e', '.', 'c', 'o', 'm', '\0',
   /* "inthouse.cloud", true */ 'i', 'n', 't', 'h', 'o', 'u', 's', 'e', '.', 'c', 'l', 'o', 'u', 'd', '\0',
   /* "intimateperrierjouet.com", true */ 'i', 'n', 't', 'i', 'm', 'a', 't', 'e', 'p', 'e', 'r', 'r', 'i', 'e', 'r', 'j', 'o', 'u', 'e', 't', '.', 'c', 'o', 'm', '\0',
   /* "intocities.de", false */ 'i', 'n', 't', 'o', 'c', 'i', 't', 'i', 'e', 's', '.', 'd', 'e', '\0',
   /* "inton.biz", true */ 'i', 'n', 't', 'o', 'n', '.', 'b', 'i', 'z', '\0',
   /* "intramanager.co.uk", true */ 'i', 'n', 't', 'r', 'a', 'm', 'a', 'n', 'a', 'g', 'e', 'r', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "intramanager.dk", true */ 'i', 'n', 't', 'r', 'a', 'm', 'a', 'n', 'a', 'g', 'e', 'r', '.', 'd', 'k', '\0',
   /* "intranetsec-regionra.fr", true */ 'i', 'n', 't', 'r', 'a', 'n', 'e', 't', 's', 'e', 'c', '-', 'r', 'e', 'g', 'i', 'o', 'n', 'r', 'a', '.', 'f', 'r', '\0',
@@ -6253,17 +6249,16 @@ static const char kSTSHostTable[] = {
   /* "jakub-boucek.cz", true */ 'j', 'a', 'k', 'u', 'b', '-', 'b', 'o', 'u', 'c', 'e', 'k', '.', 'c', 'z', '\0',
   /* "jakubboucek.cz", true */ 'j', 'a', 'k', 'u', 'b', 'b', 'o', 'u', 'c', 'e', 'k', '.', 'c', 'z', '\0',
   /* "james.je", true */ 'j', 'a', 'm', 'e', 's', '.', 'j', 'e', '\0',
   /* "jamesandpame.la", true */ 'j', 'a', 'm', 'e', 's', 'a', 'n', 'd', 'p', 'a', 'm', 'e', '.', 'l', 'a', '\0',
   /* "jamesbillingham.com", true */ 'j', 'a', 'm', 'e', 's', 'b', 'i', 'l', 'l', 'i', 'n', 'g', 'h', 'a', 'm', '.', 'c', 'o', 'm', '\0',
   /* "jamesbywater.co.uk", true */ 'j', 'a', 'm', 'e', 's', 'b', 'y', 'w', 'a', 't', 'e', 'r', '.', 'c', 'o', '.', 'u', 'k', '\0',
   /* "jamesbywater.com", true */ 'j', 'a', 'm', 'e', 's', 'b', 'y', 'w', 'a', 't', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "jamesbywater.uk", false */ 'j', 'a', 'm', 'e', 's', 'b', 'y', 'w', 'a', 't', 'e', 'r', '.', 'u', 'k', '\0',
-  /* "jamesf.xyz", true */ 'j', 'a', 'm', 'e', 's', 'f', '.', 'x', 'y', 'z', '\0',
   /* "jamesgreenfield.com", true */ 'j', 'a', 'm', 'e', 's', 'g', 'r', 'e', 'e', 'n', 'f', 'i', 'e', 'l', 'd', '.', 'c', 'o', 'm', '\0',
   /* "jameshale.me", true */ 'j', 'a', 'm', 'e', 's', 'h', 'a', 'l', 'e', '.', 'm', 'e', '\0',
   /* "jameshost.net", true */ 'j', 'a', 'm', 'e', 's', 'h', 'o', 's', 't', '.', 'n', 'e', 't', '\0',
   /* "jameshunt.us", false */ 'j', 'a', 'm', 'e', 's', 'h', 'u', 'n', 't', '.', 'u', 's', '\0',
   /* "jamesj.me", true */ 'j', 'a', 'm', 'e', 's', 'j', '.', 'm', 'e', '\0',
   /* "jamesmaurer.com", true */ 'j', 'a', 'm', 'e', 's', 'm', 'a', 'u', 'r', 'e', 'r', '.', 'c', 'o', 'm', '\0',
   /* "jamesmilazzo.com", true */ 'j', 'a', 'm', 'e', 's', 'm', 'i', 'l', 'a', 'z', 'z', 'o', '.', 'c', 'o', 'm', '\0',
   /* "jamesrains.com", true */ 'j', 'a', 'm', 'e', 's', 'r', 'a', 'i', 'n', 's', '.', 'c', 'o', 'm', '\0',
@@ -6317,16 +6312,17 @@ static const char kSTSHostTable[] = {
   /* "jazzncheese.com", true */ 'j', 'a', 'z', 'z', 'n', 'c', 'h', 'e', 'e', 's', 'e', '.', 'c', 'o', 'm', '\0',
   /* "jcaicedo.tk", true */ 'j', 'c', 'a', 'i', 'c', 'e', 'd', 'o', '.', 't', 'k', '\0',
   /* "jccrew.org", true */ 'j', 'c', 'c', 'r', 'e', 'w', '.', 'o', 'r', 'g', '\0',
   /* "jcoscia.com", true */ 'j', 'c', 'o', 's', 'c', 'i', 'a', '.', 'c', 'o', 'm', '\0',
   /* "jcraft.us", true */ 'j', 'c', 'r', 'a', 'f', 't', '.', 'u', 's', '\0',
   /* "jcyz.cf", true */ 'j', 'c', 'y', 'z', '.', 'c', 'f', '\0',
   /* "jdav-leipzig.de", true */ 'j', 'd', 'a', 'v', '-', 'l', 'e', 'i', 'p', 'z', 'i', 'g', '.', 'd', 'e', '\0',
   /* "jdcgroup.com.ph", true */ 'j', 'd', 'c', 'g', 'r', 'o', 'u', 'p', '.', 'c', 'o', 'm', '.', 'p', 'h', '\0',
+  /* "jdh8.org", true */ 'j', 'd', 'h', '8', '.', 'o', 'r', 'g', '\0',
   /* "jdubya.info", true */ 'j', 'd', 'u', 'b', 'y', 'a', '.', 'i', 'n', 'f', 'o', '\0',
   /* "jean-remy.ch", true */ 'j', 'e', 'a', 'n', '-', 'r', 'e', 'm', 'y', '.', 'c', 'h', '\0',
   /* "jedipedia.net", true */ 'j', 'e', 'd', 'i', 'p', 'e', 'd', 'i', 'a', '.', 'n', 'e', 't', '\0',
   /* "jedwarddurrett.com", true */ 'j', 'e', 'd', 'w', 'a', 'r', 'd', 'd', 'u', 'r', 'r', 'e', 't', 't', '.', 'c', 'o', 'm', '\0',
   /* "jeepmafia.com", true */ 'j', 'e', 'e', 'p', 'm', 'a', 'f', 'i', 'a', '.', 'c', 'o', 'm', '\0',
   /* "jeff.forsale", true */ 'j', 'e', 'f', 'f', '.', 'f', 'o', 'r', 's', 'a', 'l', 'e', '\0',
   /* "jeffanderson.me", true */ 'j', 'e', 'f', 'f', 'a', 'n', 'd', 'e', 'r', 's', 'o', 'n', '.', 'm', 'e', '\0',
   /* "jeffcasavant.com", false */ 'j', 'e', 'f', 'f', 'c', 'a', 's', 'a', 'v', 'a', 'n', 't', '.', 'c', 'o', 'm', '\0',
@@ -6387,16 +6383,17 @@ static const char kSTSHostTable[] = {
   /* "jiyuu-ni.net", true */ 'j', 'i', 'y', 'u', 'u', '-', 'n', 'i', '.', 'n', 'e', 't', '\0',
   /* "jka.io", true */ 'j', 'k', 'a', '.', 'i', 'o', '\0',
   /* "jkchocolate.com", true */ 'j', 'k', 'c', 'h', 'o', 'c', 'o', 'l', 'a', 't', 'e', '.', 'c', 'o', 'm', '\0',
   /* "jkirsche.com", true */ 'j', 'k', 'i', 'r', 's', 'c', 'h', 'e', '.', 'c', 'o', 'm', '\0',
   /* "jkrippen.com", true */ 'j', 'k', 'r', 'i', 'p', 'p', 'e', 'n', '.', 'c', 'o', 'm', '\0',
   /* "jlhmedia.com", true */ 'j', 'l', 'h', 'm', 'e', 'd', 'i', 'a', '.', 'c', 'o', 'm', '\0',
   /* "jlkhosting.com", true */ 'j', 'l', 'k', 'h', 'o', 's', 't', 'i', 'n', 'g', '.', 'c', 'o', 'm', '\0',
   /* "jmedved.com", true */ 'j', 'm', 'e', 'd', 'v', 'e', 'd', '.', 'c', 'o', 'm', '\0',
+  /* "jmk.hu", true */ 'j', 'm', 'k', '.', 'h', 'u', '\0',
   /* "jn1.me", true */ 'j', 'n', '1', '.', 'm', 'e', '\0',
   /* "jncde.de", true */ 'j', 'n', 'c', 'd', 'e', '.', 'd', 'e', '\0',
   /* "jncie.eu", true */ 'j', 'n', 'c', 'i', 'e', '.', 'e', 'u', '\0',
   /* "jncip.de", true */ 'j', 'n', 'c', 'i', 'p', '.', 'd', 'e', '\0',
   /* "jobbkk.com", true */ 'j', 'o', 'b', 'b', 'k', 'k', '.', 'c', 'o', 'm', '\0',
   /* "jobflyapp.com", true */ 'j', 'o', 'b', 'f', 'l', 'y', 'a', 'p', 'p', '.', 'c', 'o', 'm', '\0',
   /* "jobmob.co.il", true */ 'j', 'o', 'b', 'm', 'o', 'b', '.', 'c', 'o', '.', 'i', 'l', '\0',
   /* "jobs.at", true */ 'j', 'o', 'b', 's', '.', 'a', 't', '\0',
@@ -6493,16 +6490,17 @@ static const char kSTSHostTable[] = {
   /* "juchit.at", true */ 'j', 'u', 'c', 'h', 'i', 't', '.', 'a', 't', '\0',
   /* "judoprodeti.cz", true */ 'j', 'u', 'd', 'o', 'p', 'r', 'o', 'd', 'e', 't', 'i', '.', 'c', 'z', '\0',
   /* "juergenhecht.de", true */ 'j', 'u', 'e', 'r', 'g', 'e', 'n', 'h', 'e', 'c', 'h', 't', '.', 'd', 'e', '\0',
   /* "jugendsuenden.info", true */ 'j', 'u', 'g', 'e', 'n', 'd', 's', 'u', 'e', 'n', 'd', 'e', 'n', '.', 'i', 'n', 'f', 'o', '\0',
   /* "juhakoho.com", true */ 'j', 'u', 'h', 'a', 'k', 'o', 'h', 'o', '.', 'c', 'o', 'm', '\0',
   /* "juliangonggrijp.com", true */ 'j', 'u', 'l', 'i', 'a', 'n', 'g', 'o', 'n', 'g', 'g', 'r', 'i', 'j', 'p', '.', 'c', 'o', 'm', '\0',
   /* "julianmeyer.de", true */ 'j', 'u', 'l', 'i', 'a', 'n', 'm', 'e', 'y', 'e', 'r', '.', 'd', 'e', '\0',
   /* "juliansimioni.com", true */ 'j', 'u', 'l', 'i', 'a', 'n', 's', 'i', 'm', 'i', 'o', 'n', 'i', '.', 'c', 'o', 'm', '\0',
+  /* "julibear.com", true */ 'j', 'u', 'l', 'i', 'b', 'e', 'a', 'r', '.', 'c', 'o', 'm', '\0',
   /* "julido.de", true */ 'j', 'u', 'l', 'i', 'd', 'o', '.', 'd', 'e', '\0',
   /* "juliekoubova.net", true */ 'j', 'u', 'l', 'i', 'e', 'k', 'o', 'u', 'b', 'o', 'v', 'a', '.', 'n', 'e', 't', '\0',
   /* "juliemaurel.fr", true */ 'j', 'u', 'l', 'i', 'e', 'm', 'a', 'u', 'r', 'e', 'l', '.', 'f', 'r', '\0',
   /* "julienc.io", true */ 'j', 'u', 'l', 'i', 'e', 'n', 'c', '.', 'i', 'o', '\0',
   /* "jultube.de", true */ 'j', 'u', 'l', 't', 'u', 'b', 'e', '.', 'd', 'e', '\0',
   /* "jumba.com.au", true */ 'j', 'u', 'm', 'b', 'a', '.', 'c', 'o', 'm', '.', 'a', 'u', '\0',
   /* "jump.bg", true */ 'j', 'u', 'm', 'p', '.', 'b', 'g', '\0',
   /* "jump.wtf", true */ 'j', 'u', 'm', 'p', '.', 'w', 't', 'f', '\0',
@@ -6528,16 +6526,17 @@ static const char kSTSHostTable[] = {
   /* "juxstempel.de", true */ 'j', 'u', 'x', 's', 't', 'e', 'm', 'p', 'e', 'l', '.', 'd', 'e', '\0',
   /* "juzgalo.com", true */ 'j', 'u', 'z', 'g', 'a', 'l', 'o', '.', 'c', 'o', 'm', '\0',
   /* "jva-wuerzburg.de", true */ 'j', 'v', 'a', '-', 'w', 'u', 'e', 'r', 'z', 'b', 'u', 'r', 'g', '.', 'd', 'e', '\0',
   /* "jwilsson.com", true */ 'j', 'w', 'i', 'l', 's', 's', 'o', 'n', '.', 'c', 'o', 'm', '\0',
   /* "jwnotifier.org", true */ 'j', 'w', 'n', 'o', 't', 'i', 'f', 'i', 'e', 'r', '.', 'o', 'r', 'g', '\0',
   /* "jym.fit", true */ 'j', 'y', 'm', '.',