Merge mozilla-central to autoland
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 27 Jul 2016 16:42:20 +0200
changeset 331908 6b54e59980fb1cad35f72c88a729f4199b8402b8
parent 331907 33f7d8838b3305f9c044b91418a615c935214f7a (current diff)
parent 331905 fef429fba4c64c5b9c0c823a6ab713edbbcd4220 (diff)
child 331909 0869818632bbf42863677a0d411edd4cc0cf05c8
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone50.0a1
Merge mozilla-central to autoland
build/autoconf/mozcommonheader.m4
--- a/.eslintignore
+++ b/.eslintignore
@@ -82,17 +82,20 @@ devtools/client/canvasdebugger/**
 devtools/client/commandline/**
 devtools/client/debugger/**
 devtools/client/eyedropper/**
 devtools/client/framework/**
 devtools/client/jsonview/lib/**
 devtools/client/memory/**
 devtools/client/netmonitor/test/**
 devtools/client/netmonitor/har/test/**
-devtools/client/performance/**
+devtools/client/performance/components/**
+devtools/client/performance/legacy/**
+devtools/client/performance/modules/**
+devtools/client/performance/test/**
 devtools/client/projecteditor/**
 devtools/client/promisedebugger/**
 devtools/client/responsivedesign/**
 devtools/client/scratchpad/**
 devtools/client/shadereditor/**
 devtools/client/shared/*.jsm
 devtools/client/shared/webgl-utils.js
 devtools/client/shared/developer-toolbar.js
--- a/accessible/interfaces/nsIAccessible.idl
+++ b/accessible/interfaces/nsIAccessible.idl
@@ -25,17 +25,17 @@ class Accessible;
  * accessibility APIs like MSAA and ATK. Contains the sum of what's needed
  * to support IAccessible as well as ATK's generic accessibility objects.
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
  * nodes in the DOM tree -- such as documents, focusable elements and text.
  * Mozilla creates the implementations of nsIAccessible on demand.
  * See http://www.mozilla.org/projects/ui/accessibility for more information.
  */
-[scriptable, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
+[scriptable, builtinclass, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
 interface nsIAccessible : nsISupports
 {
   /**
    * Parent node in accessible tree.
    */
   readonly attribute nsIAccessible parent;
 
   /**
--- a/accessible/interfaces/nsIAccessibleApplication.idl
+++ b/accessible/interfaces/nsIAccessibleApplication.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * This interface is implemented by top level accessible object in hierarchy and
  * provides information about application.
  */
-[scriptable, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
+[scriptable, builtinclass, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
 interface nsIAccessibleApplication : nsISupports
 {
   /**
    * Returns the application name.
    */
   readonly attribute DOMString appName;
 
   /**
--- a/accessible/interfaces/nsIAccessibleDocument.idl
+++ b/accessible/interfaces/nsIAccessibleDocument.idl
@@ -14,17 +14,17 @@ interface mozIDOMWindowProxy;
  * that wish to retrieve information about a document.
  * When accessibility is turned on in Gecko,
  * there is an nsIAccessibleDocument for each document
  * whether it is XUL, HTML or whatever.
  * You can QueryInterface to nsIAccessibleDocument from the nsIAccessible for
  * the root node of a document or you can get one from
  * nsIAccessible::GetDocument().
  */
-[scriptable, uuid(5cad5f91-fcce-40e7-913e-4671701d19b4)]
+[scriptable, builtinclass, uuid(5cad5f91-fcce-40e7-913e-4671701d19b4)]
 interface nsIAccessibleDocument : nsISupports
 {
   /**
    * The URL of the document
    */
   readonly attribute AString URL;
 
   /**
--- a/accessible/interfaces/nsIAccessibleEditableText.idl
+++ b/accessible/interfaces/nsIAccessibleEditableText.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(28915cca-3366-4034-ba1d-b7afb9b37639)]
+[scriptable, builtinclass, uuid(28915cca-3366-4034-ba1d-b7afb9b37639)]
 interface nsIAccessibleEditableText : nsISupports
 {
   /**
    * Replaces the text represented by this object by the given text.
    */
   void setTextContents (in AString text);
 
   /**
--- a/accessible/interfaces/nsIAccessibleHyperLink.idl
+++ b/accessible/interfaces/nsIAccessibleHyperLink.idl
@@ -8,17 +8,17 @@
 
 interface nsIURI;
 interface nsIAccessible;
 
 /**
  * A cross-platform interface that supports hyperlink-specific properties and
  * methods.  Anchors, image maps, xul:labels with class="text-link" implement this interface.
  */
-[scriptable, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
+[scriptable, builtinclass, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
 interface nsIAccessibleHyperLink : nsISupports
 {
   /**
    * Returns the offset of the link within the parent accessible.
    */
   readonly attribute long startIndex;
 
   /**
--- a/accessible/interfaces/nsIAccessibleHyperText.idl
+++ b/accessible/interfaces/nsIAccessibleHyperText.idl
@@ -10,17 +10,17 @@
 /**
  * A cross-platform interface that deals with text which contains hyperlinks.
  * Each link is an embedded object representing exactly 1 character within
  * the hypertext.
  *
  * Current implementation assumes every embedded object is a link.
  */
 
-[scriptable, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
+[scriptable, builtinclass, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
 interface nsIAccessibleHyperText : nsISupports
 {
   /**
    * Return the number of links contained within this hypertext object.
    */
   readonly attribute long linkCount;
 
   /**
--- a/accessible/interfaces/nsIAccessibleImage.idl
+++ b/accessible/interfaces/nsIAccessibleImage.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
+[scriptable, builtinclass, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
 interface nsIAccessibleImage : nsISupports
 {
   /**
    * Returns the coordinates of the image.
    *
    * @param coordType  specifies coordinates origin (for available constants
    *                   refer to nsIAccessibleCoordinateType)
    * @param x          the x coordinate
--- a/accessible/interfaces/nsIAccessibleRelation.idl
+++ b/accessible/interfaces/nsIAccessibleRelation.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 #include "nsIArray.idl"
 
 interface nsIAccessible;
 
 /**
  * This interface gives access to an accessible's set of relations.
  */
-[scriptable, uuid(55b308c4-2ae4-46bc-b4cd-4d4370e0a660)]
+[scriptable, builtinclass, uuid(55b308c4-2ae4-46bc-b4cd-4d4370e0a660)]
 interface nsIAccessibleRelation : nsISupports
 {
   /**
    * This object is labelled by a target object.
    */
   const unsigned long RELATION_LABELLED_BY = 0x00;
 
   /**
--- a/accessible/interfaces/nsIAccessibleRetrieval.idl
+++ b/accessible/interfaces/nsIAccessibleRetrieval.idl
@@ -11,17 +11,17 @@ interface nsIWeakReference;
 interface nsIPresShell;
 interface nsIAccessiblePivot;
 
 /**
  * An interface for in-process accessibility clients wishing to get an
  * nsIAccessible for a given DOM node.  More documentation at:
  *   http://www.mozilla.org/projects/ui/accessibility
  */
-[scriptable, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
+[scriptable, builtinclass, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
 interface nsIAccessibleRetrieval : nsISupports
 {
   /**
    * Return application accessible.
    */
   nsIAccessible getApplicationAccessible();
 
   /**
--- a/accessible/interfaces/nsIAccessibleRole.idl
+++ b/accessible/interfaces/nsIAccessibleRole.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * Defines cross platform (Gecko) roles.
  */
-[scriptable, uuid(05a9f33f-dcfd-4e7b-b825-138ba784c1f5)]
+[scriptable, builtinclass, uuid(05a9f33f-dcfd-4e7b-b825-138ba784c1f5)]
 interface nsIAccessibleRole : nsISupports
 {
   /**
    * Used when accessible hans't strong defined role.
    */
   const unsigned long ROLE_NOTHING = 0;
 
   /**
--- a/accessible/interfaces/nsIAccessibleSelectable.idl
+++ b/accessible/interfaces/nsIAccessibleSelectable.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 
 interface nsIAccessible;
 interface nsIArray;
 
 /**
  * An accessibility interface for selectable widgets.
  */
-[scriptable, uuid(8efb03d4-1354-4875-94cf-261336057626)]
+[scriptable, builtinclass, uuid(8efb03d4-1354-4875-94cf-261336057626)]
 interface nsIAccessibleSelectable : nsISupports
 {
   /**
    * Return an nsIArray of selected items within the widget.
    */
   readonly attribute nsIArray selectedItems;
 
   /**
--- a/accessible/interfaces/nsIAccessibleTable.idl
+++ b/accessible/interfaces/nsIAccessibleTable.idl
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIAccessible;
 interface nsIArray;
 
-[scriptable, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
+[scriptable, builtinclass, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
 interface nsIAccessibleTable : nsISupports
 {
   /**
    * Return the caption accessible for the table. For example, html:caption
    * element of html:table element.
    */
   readonly attribute nsIAccessible caption;
 
@@ -216,17 +216,17 @@ interface nsIAccessibleTable : nsISuppor
 
   /**
    * Use heuristics to determine if table is most likely used for layout.
    */
   boolean isProbablyForLayout();
 };
 
 
-[scriptable, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
+[scriptable, builtinclass, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
 interface nsIAccessibleTableCell : nsISupports
 {
   /**
    * Return host table accessible.
    */
   readonly attribute nsIAccessibleTable table;
 
   /**
--- a/accessible/interfaces/nsIAccessibleText.idl
+++ b/accessible/interfaces/nsIAccessibleText.idl
@@ -8,17 +8,17 @@
 
 typedef long AccessibleTextBoundary;
 
 interface nsIAccessible;
 interface nsIArray;
 interface nsIPersistentProperties;
 interface nsIAccessibleTextRange;
 
-[scriptable, uuid(93ad2ca1-f12b-4ab9-a793-95d9fa9d1774)]
+[scriptable, builtinclass, uuid(93ad2ca1-f12b-4ab9-a793-95d9fa9d1774)]
 interface nsIAccessibleText : nsISupports
 {
   // In parameters for character offsets:
   //  -1 will be treated as the equal to the end of the text
   //  -2 will be treated as the caret position
   const int32_t TEXT_OFFSET_END_OF_TEXT = -1;
   const int32_t TEXT_OFFSET_CARET       = -2;
 
--- a/accessible/interfaces/nsIAccessibleTextRange.idl
+++ b/accessible/interfaces/nsIAccessibleTextRange.idl
@@ -8,17 +8,17 @@
 interface nsIAccessible;
 interface nsIAccessibleText;
 interface nsIArray;
 interface nsIVariant;
 
 /**
  * A range representing a piece of text in the document.
  */
-[scriptable, uuid(c4515623-55f9-4543-a3d5-c1e9afa588f4)]
+[scriptable, builtinclass, uuid(c4515623-55f9-4543-a3d5-c1e9afa588f4)]
 interface nsIAccessibleTextRange : nsISupports
 {
   readonly attribute nsIAccessibleText startContainer;
   readonly attribute long startOffset;
   readonly attribute nsIAccessibleText endContainer;
   readonly attribute long endOffset;
 
   /**
--- a/accessible/interfaces/nsIAccessibleTypes.idl
+++ b/accessible/interfaces/nsIAccessibleTypes.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * These constants control the scrolling of an object or substring into a
  * window. Note, keep them synchronized with IA2ScrollType.
  */
-[scriptable, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
+[scriptable, builtinclass, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
 interface nsIAccessibleScrollType : nsISupports
 {
   /**
    * Scroll the top left of the object or substring to the top left of the
    * window (or as close as possible).
    */
   const unsigned long SCROLL_TYPE_TOP_LEFT =0x00;
 
@@ -54,17 +54,17 @@ interface nsIAccessibleScrollType : nsIS
    */
   const unsigned long SCROLL_TYPE_ANYWHERE = 0x06;
 };
 
 
 /**
  * These constants define which coordinate system a point is located in.
  */
-[scriptable, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
+[scriptable, builtinclass, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
 interface nsIAccessibleCoordinateType : nsISupports
 {
   /**
    * The coordinates are relative to the screen.
    */
   const unsigned long COORDTYPE_SCREEN_RELATIVE = 0x00;
 
   /**
--- a/accessible/interfaces/nsIAccessibleValue.idl
+++ b/accessible/interfaces/nsIAccessibleValue.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
+[scriptable, builtinclass, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
 interface nsIAccessibleValue : nsISupports
 {
   readonly attribute double maximumValue;
   readonly attribute double minimumValue;
   attribute double currentValue;
   readonly attribute double minimumIncrement;
 };
 
--- a/accessible/interfaces/nsIXBLAccessible.idl
+++ b/accessible/interfaces/nsIXBLAccessible.idl
@@ -5,16 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 /**
  * XBL controls can implement this interface to provide own implementation of
  * accessible properties.
  */
-[scriptable, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
+[scriptable, builtinclass, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
 interface nsIXBLAccessible : nsISupports
 {
   /**
    * Return accessible name.
    */
   readonly attribute DOMString accessibleName;
 };
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -11,17 +11,16 @@ builtin(include, build/autoconf/toolchai
 builtin(include, build/autoconf/nspr.m4)dnl
 builtin(include, build/autoconf/nspr-build.m4)dnl
 builtin(include, build/autoconf/nss.m4)dnl
 builtin(include, build/autoconf/pkg.m4)dnl
 builtin(include, build/autoconf/codeset.m4)dnl
 builtin(include, build/autoconf/altoptions.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
-builtin(include, build/autoconf/mozcommonheader.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
 builtin(include, build/autoconf/compiler-opts.m4)dnl
 builtin(include, build/autoconf/expandlibs.m4)dnl
 builtin(include, build/autoconf/arch.m4)dnl
 builtin(include, build/autoconf/android.m4)dnl
 builtin(include, build/autoconf/zlib.m4)dnl
 builtin(include, build/autoconf/linux.m4)dnl
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1455,17 +1455,17 @@ pref("toolkit.pageThumbs.minHeight", 190
 
 // Enable speech synthesis
 pref("media.webspeech.synth.enabled", true);
 
 pref("browser.esedbreader.loglevel", "Error");
 
 pref("browser.laterrun.enabled", false);
 
-pref("browser.migration.automigrate", false);
+pref("browser.migrate.automigrate.enabled", false);
 
 // Enable browser frames for use on desktop.  Only exposed to chrome callers.
 pref("dom.mozBrowserFramesEnabled", true);
 
 pref("extensions.pocket.enabled", true);
 
 pref("signon.schemeUpgrades", true);
 
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -14,20 +14,16 @@ var gEMEHandler = {
   },
   ensureEMEEnabled: function(browser, keySystem) {
     Services.prefs.setBoolPref("media.eme.enabled", true);
     if (keySystem) {
       if (keySystem.startsWith("com.adobe") &&
           Services.prefs.getPrefType("media.gmp-eme-adobe.enabled") &&
           !Services.prefs.getBoolPref("media.gmp-eme-adobe.enabled")) {
         Services.prefs.setBoolPref("media.gmp-eme-adobe.enabled", true);
-      } else if (keySystem == "org.w3.clearkey" &&
-                 Services.prefs.getPrefType("media.eme.clearkey.enabled") &&
-                 !Services.prefs.getBoolPref("media.eme.clearkey.enabled")) {
-        Services.prefs.setBoolPref("media.eme.clearkey.enabled", true);
       } else if (keySystem == "com.widevine.alpha" &&
                  Services.prefs.getPrefType("media.gmp-widevinecdm.enabled") &&
                  !Services.prefs.getBoolPref("media.gmp-widevinecdm.enabled")) {
         Services.prefs.setBoolPref("media.gmp-widevinecdm.enabled", true);
       }
     }
     browser.reload();
   },
--- a/browser/components/migration/AutoMigrate.jsm
+++ b/browser/components/migration/AutoMigrate.jsm
@@ -3,83 +3,129 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["AutoMigrate"];
 
 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
-const kAutoMigrateStartedPref = "browser.migrate.automigrate-started";
-const kAutoMigrateFinishedPref = "browser.migrate.automigrate-finished";
+const kAutoMigrateEnabledPref = "browser.migrate.automigrate.enabled";
+
+const kAutoMigrateStartedPref = "browser.migrate.automigrate.started";
+const kAutoMigrateFinishedPref = "browser.migrate.automigrate.finished";
+const kAutoMigrateBrowserPref = "browser.migrate.automigrate.browser";
+
+const kPasswordManagerTopic = "passwordmgr-storage-changed";
+const kPasswordManagerTopicTypes = new Set([
+  "addLogin",
+  "modifyLogin",
+]);
 
 Cu.import("resource:///modules/MigrationUtils.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const AutoMigrate = {
   get resourceTypesToUse() {
     let {BOOKMARKS, HISTORY, PASSWORDS} = Ci.nsIBrowserProfileMigrator;
     return BOOKMARKS | HISTORY | PASSWORDS;
   },
 
+  init() {
+    this.enabled = Preferences.get(kAutoMigrateEnabledPref, false);
+    if (this.enabled) {
+      this.maybeInitUndoObserver();
+    }
+  },
+
+  maybeInitUndoObserver() {
+    // Check synchronously (NB: canUndo is async) if we really need
+    // to do this:
+    if (!this.getUndoRange()) {
+      return;
+    }
+    // Now register places and password observers:
+    this.onItemAdded = this.onItemMoved = this.onItemChanged =
+      this.removeUndoOption;
+    PlacesUtils.addLazyBookmarkObserver(this, true);
+    Services.obs.addObserver(this, kPasswordManagerTopic, true);
+  },
+
+  observe(subject, topic, data) {
+    // As soon as any login gets added or modified, disable undo:
+    // (Note that this ignores logins being removed as that doesn't
+    //  impair the 'undo' functionality of the import.)
+    if (kPasswordManagerTopicTypes.has(data)) {
+      this.removeUndoOption();
+    }
+  },
+
   /**
    * Automatically pick a migrator and resources to migrate,
    * then migrate those and start up.
    *
    * @throws if automatically deciding on migrators/data
    *         failed for some reason.
    */
   migrate(profileStartup, migratorKey, profileToMigrate) {
-    let histogram = Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_AUTOMATED_IMPORT_PROCESS_SUCCESS");
+    let histogram = Services.telemetry.getHistogramById(
+      "FX_STARTUP_MIGRATION_AUTOMATED_IMPORT_PROCESS_SUCCESS");
     histogram.add(0);
-    let migrator = this.pickMigrator(migratorKey);
+    let {migrator, pickedKey} = this.pickMigrator(migratorKey);
     histogram.add(5);
 
     profileToMigrate = this.pickProfile(migrator, profileToMigrate);
     histogram.add(10);
 
     let resourceTypes = migrator.getMigrateData(profileToMigrate, profileStartup);
     if (!(resourceTypes & this.resourceTypesToUse)) {
       throw new Error("No usable resources were found for the selected browser!");
     }
     histogram.add(15);
 
     let sawErrors = false;
-    let migrationObserver = function(subject, topic, data) {
+    let migrationObserver = (subject, topic, data) => {
       if (topic == "Migration:ItemError") {
         sawErrors = true;
       } else if (topic == "Migration:Ended") {
         histogram.add(25);
         if (sawErrors) {
           histogram.add(26);
         }
         Services.obs.removeObserver(migrationObserver, "Migration:Ended");
         Services.obs.removeObserver(migrationObserver, "Migration:ItemError");
         Services.prefs.setCharPref(kAutoMigrateStartedPref, startTime.toString());
         Services.prefs.setCharPref(kAutoMigrateFinishedPref, Date.now().toString());
+        Services.prefs.setCharPref(kAutoMigrateBrowserPref, pickedKey);
+        // Need to manually start listening to new bookmarks/logins being created,
+        // because, when we were initialized, there wasn't the possibility to
+        // 'undo' anything.
+        this.maybeInitUndoObserver();
       }
     };
 
     Services.obs.addObserver(migrationObserver, "Migration:Ended", false);
     Services.obs.addObserver(migrationObserver, "Migration:ItemError", false);
     // We'll save this when the migration has finished, at which point the pref
     // service will be available.
     let startTime = Date.now();
     migrator.migrate(this.resourceTypesToUse, profileStartup, profileToMigrate);
     histogram.add(20);
   },
 
   /**
    * Pick and return a migrator to use for automatically migrating.
    *
    * @param {String} migratorKey   optional, a migrator key to prefer/pick.
-   * @returns                      the migrator to use for migrating.
+   * @returns {Object}             an object with the migrator to use for migrating, as
+   *                               well as the key we eventually ended up using to obtain it.
    */
   pickMigrator(migratorKey) {
     if (!migratorKey) {
       let defaultKey = MigrationUtils.getMigratorKeyForDefaultBrowser();
       if (!defaultKey) {
         throw new Error("Could not determine default browser key to migrate from");
       }
       migratorKey = defaultKey;
@@ -87,17 +133,17 @@ const AutoMigrate = {
     if (migratorKey == "firefox") {
       throw new Error("Can't automatically migrate from Firefox.");
     }
 
     let migrator = MigrationUtils.getMigrator(migratorKey);
     if (!migrator) {
       throw new Error("Migrator specified or a default was found, but the migrator object is not available.");
     }
-    return migrator;
+    return {migrator, pickedKey: migratorKey};
   },
 
   /**
    * Pick a source profile (from the original browser) to use.
    *
    * @param {Migrator} migrator     the migrator object to use
    * @param {String}   suggestedId  the id of the profile to migrate, if pre-specified, or null
    * @returns                       the profile to migrate, or null if migrating
@@ -122,18 +168,18 @@ const AutoMigrate = {
       throw new Error("Don't know how to pick a profile when more than 1 profile is present.");
     }
     return profiles ? profiles[0] : null;
   },
 
   getUndoRange() {
     let start, finish;
     try {
-      start = parseInt(Services.prefs.getCharPref(kAutoMigrateStartedPref), 10);
-      finish = parseInt(Services.prefs.getCharPref(kAutoMigrateFinishedPref), 10);
+      start = parseInt(Preferences.get(kAutoMigrateStartedPref, "0"), 10);
+      finish = parseInt(Preferences.get(kAutoMigrateFinishedPref, "0"), 10);
     } catch (ex) {
       Cu.reportError(ex);
     }
     if (!finish || !start) {
       return null;
     }
     return [new Date(start), new Date(finish)];
   },
@@ -182,14 +228,32 @@ const AutoMigrate = {
     histogram.add(20);
 
     try {
       Services.logins.removeAllLogins();
     } catch (ex) {
       // ignore failure.
     }
     histogram.add(25);
-    Services.prefs.clearUserPref("browser.migrate.automigrate-started");
-    Services.prefs.clearUserPref("browser.migrate.automigrate-finished");
+    this.removeUndoOption();
     histogram.add(30);
   }),
+
+  removeUndoOption() {
+    // Remove observers, and ensure that exceptions doing so don't break
+    // removing the pref.
+    try {
+      Services.obs.removeObserver(this, kPasswordManagerTopic);
+    } catch (ex) {}
+    try {
+      PlacesUtils.removeLazyBookmarkObserver(this);
+    } catch (ex) {}
+    Services.prefs.clearUserPref(kAutoMigrateStartedPref);
+    Services.prefs.clearUserPref(kAutoMigrateFinishedPref);
+    Services.prefs.clearUserPref(kAutoMigrateBrowserPref);
+  },
+
+  QueryInterface: XPCOMUtils.generateQI(
+    [Ci.nsIObserver, Ci.nsINavBookmarkObserver, Ci.nsISupportsWeakReference]
+  ),
 };
 
+AutoMigrate.init();
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -447,16 +447,46 @@ this.MigrationUtils = Object.freeze({
     aKey = OVERRIDES[aKey] || aKey;
 
     if (aReplacements === undefined)
       return getMigrationBundle().GetStringFromName(aKey);
     return getMigrationBundle().formatStringFromName(
       aKey, aReplacements, aReplacements.length);
   },
 
+  _getLocalePropertyForBrowser(browserId) {
+    switch (browserId) {
+      case "edge":
+        return "sourceNameEdge";
+      case "ie":
+        return "sourceNameIE";
+      case "safari":
+        return "sourceNameSafari";
+      case "canary":
+        return "sourceNameCanary";
+      case "chrome":
+        return "sourceNameChrome";
+      case "chromium":
+        return "sourceNameChromium";
+      case "firefox":
+        return "sourceNameFirefox";
+      case "360se":
+        return "sourceName360se";
+    }
+    return null;
+  },
+
+  getBrowserName(browserId) {
+    let prop = this._getLocalePropertyForBrowser(browserId);
+    if (prop) {
+      return this.getLocalizedString(prop);
+    }
+    return null;
+  },
+
   /**
    * Helper for creating a folder for imported bookmarks from a particular
    * migration source.  The folder is created at the end of the given folder.
    *
    * @param sourceNameStr
    *        the source name (first letter capitalized).  This is used
    *        for reading the localized source name from the migration
    *        bundle (e.g. if aSourceNameStr is Mosaic, this will try to read
@@ -711,18 +741,17 @@ this.MigrationUtils = Object.freeze({
         this.finishMigration();
         return;
       }
     }
 
     let isRefresh = migrator && skipSourcePage &&
                     migratorKey == AppConstants.MOZ_APP_NAME;
 
-    if (!isRefresh &&
-        Services.prefs.getBoolPref("browser.migration.automigrate")) {
+    if (!isRefresh && AutoMigrate.enabled) {
       try {
         AutoMigrate.migrate(aProfileStartup, aMigratorKey, aProfileToMigrate);
         return;
       } catch (ex) {
         // If automigration failed, continue and show the dialog.
         Cu.reportError(ex);
       }
     }
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -309,48 +309,24 @@ var MigrationWizard = {
     document.getElementById("homePageImportDesc").setAttribute("value", pageDesc);
 
     this._wiz._adjustWizardHeader();
 
     var singleStart = document.getElementById("homePageSingleStart");
     singleStart.setAttribute("label", mainStr);
     singleStart.setAttribute("value", "DEFAULT");
 
-    var source = null;
-    switch (this._source) {
-      case "ie":
-        source = "sourceNameIE";
-        break;
-      case "safari":
-        source = "sourceNameSafari";
-        break;
-      case "canary":
-        source = "sourceNameCanary";
-        break;
-      case "chrome":
-        source = "sourceNameChrome";
-        break;
-      case "chromium":
-        source = "sourceNameChromium";
-        break;
-      case "firefox":
-        source = "sourceNameFirefox";
-        break;
-      case "360se":
-        source = "sourceName360se";
-        break;
-    }
+    var appName = MigrationUtils.getBrowserName(this._source);
 
     // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places
     this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
 
     var oldHomePageURL = this._migrator.sourceHomePageURL;
 
-    if (oldHomePageURL && source) {
-      var appName = MigrationUtils.getLocalizedString(source);
+    if (oldHomePageURL && appName) {
       var oldHomePageLabel =
         brandBundle.getFormattedString("homePageImport", [appName]);
       var oldHomePage = document.getElementById("oldHomePage");
       oldHomePage.setAttribute("label", oldHomePageLabel);
       oldHomePage.setAttribute("value", oldHomePageURL);
       oldHomePage.removeAttribute("hidden");
     }
     else {
--- a/browser/components/migration/tests/unit/test_automigration.js
+++ b/browser/components/migration/tests/unit/test_automigration.js
@@ -1,10 +1,11 @@
 Cu.import("resource:///modules/MigrationUtils.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://testing-common/TestUtils.jsm");
 Cu.import("resource://testing-common/PlacesTestUtils.jsm");
 let AutoMigrateBackstage = Cu.import("resource:///modules/AutoMigrate.jsm");
 
 let gShimmedMigratorKeyPicker = null;
 let gShimmedMigrator = null;
 
 const kUsecPerMin = 60 * 1000000;
@@ -155,19 +156,19 @@ add_task(function* checkUndoPrecondition
                      "getMigrateData called with 'null' as a profile");
 
   let {BOOKMARKS, HISTORY, PASSWORDS} = Ci.nsIBrowserProfileMigrator;
   let expectedTypes = BOOKMARKS | HISTORY | PASSWORDS;
   Assert.deepEqual(gShimmedMigrator._migrateArgs, [expectedTypes, "startup", null],
                    "migrate called with 'null' as a profile");
 
   yield migrationFinishedPromise;
-  Assert.ok(Services.prefs.getPrefType("browser.migrate.automigrate-started"),
+  Assert.ok(Preferences.has("browser.migrate.automigrate.started"),
             "Should have set start time pref");
-  Assert.ok(Services.prefs.getPrefType("browser.migrate.automigrate-finished"),
+  Assert.ok(Preferences.has("browser.migrate.automigrate.finished"),
             "Should have set finish time pref");
   Assert.ok((yield AutoMigrate.canUndo()), "Should be able to undo migration");
 
   let [beginRange, endRange] = AutoMigrate.getUndoRange();
   let stringRange = `beginRange: ${beginRange}; endRange: ${endRange}`;
   Assert.ok(beginRange <= endRange,
             "Migration should have started before or when it ended " + stringRange);
 
@@ -175,17 +176,16 @@ add_task(function* checkUndoPrecondition
   Assert.ok(true, "Should be able to finish an undo cycle.");
 });
 
 /**
  * Fake a migration and then try to undo it to verify all data gets removed.
  */
 add_task(function* checkUndoRemoval() {
   let startTime = "" + Date.now();
-  Services.prefs.setCharPref("browser.migrate.automigrate-started", startTime);
 
   // Insert a login and check that that worked.
   let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
   login.init("www.mozilla.org", "http://www.mozilla.org", null, "user", "pass", "userEl", "passEl");
   Services.logins.addLogin(login);
   let storedLogins = Services.logins.findLogins({}, "www.mozilla.org",
                                                 "http://www.mozilla.org", null);
   Assert.equal(storedLogins.length, 1, "Should have 1 login");
@@ -217,17 +217,18 @@ add_task(function* checkUndoRemoval() {
   let visits = PlacesUtils.history.executeQuery(query, opts);
   visits.root.containerOpen = true;
   Assert.equal(visits.root.childCount, 2, "Should have 2 visits");
   // Clean up:
   visits.root.containerOpen = false;
 
   // Now set finished pref:
   let endTime = "" + Date.now();
-  Services.prefs.setCharPref("browser.migrate.automigrate-finished", endTime);
+  Preferences.set("browser.migrate.automigrate.started", startTime);
+  Preferences.set("browser.migrate.automigrate.finished", endTime);
 
   // Verify that we can undo, then undo:
   Assert.ok(yield AutoMigrate.canUndo(), "Should be possible to undo migration");
   yield AutoMigrate.undo();
 
   // Check that the undo removed the history visits:
   visits = PlacesUtils.history.executeQuery(query, opts);
   visits.root.containerOpen = true;
@@ -239,13 +240,49 @@ add_task(function* checkUndoRemoval() {
   Assert.ok(!bookmark, "Should have no bookmarks after undo");
 
   // Check that the undo removed the passwords:
   storedLogins = Services.logins.findLogins({}, "www.mozilla.org",
                                             "http://www.mozilla.org", null);
   Assert.equal(storedLogins.length, 0, "Should have no logins");
 
   // Finally check prefs got cleared:
-  Assert.ok(!Services.prefs.getPrefType("browser.migrate.automigrate-started"),
+  Assert.ok(!Preferences.has("browser.migrate.automigrate.started"),
             "Should no longer have pref for migration start time.");
-  Assert.ok(!Services.prefs.getPrefType("browser.migrate.automigrate-finished"),
+  Assert.ok(!Preferences.has("browser.migrate.automigrate.finished"),
             "Should no longer have pref for migration finish time.");
 });
+
+add_task(function* checkUndoDisablingByBookmarksAndPasswords() {
+  let startTime = "" + Date.now();
+  Services.prefs.setCharPref("browser.migrate.automigrate.started", startTime);
+  // Now set finished pref:
+  let endTime = "" + (Date.now() + 1000);
+  Services.prefs.setCharPref("browser.migrate.automigrate.finished", endTime);
+  AutoMigrate.maybeInitUndoObserver();
+
+  ok((yield AutoMigrate.canUndo()), "Should be able to undo.");
+
+  // Insert a login and check that that disabled undo.
+  let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
+  login.init("www.mozilla.org", "http://www.mozilla.org", null, "user", "pass", "userEl", "passEl");
+  Services.logins.addLogin(login);
+
+  ok(!(yield AutoMigrate.canUndo()), "Should no longer be able to undo.");
+  Services.prefs.setCharPref("browser.migrate.automigrate.started", startTime);
+  Services.prefs.setCharPref("browser.migrate.automigrate.finished", endTime);
+  ok((yield AutoMigrate.canUndo()), "Should be able to undo.");
+  AutoMigrate.maybeInitUndoObserver();
+
+  // Insert a bookmark and check that that disabled undo.
+  yield PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    url: "http://www.example.org/",
+    title: "Some example bookmark",
+  });
+  ok(!(yield AutoMigrate.canUndo()), "Should no longer be able to undo.");
+
+  try {
+    Services.logins.removeAllLogins();
+  } catch (ex) {}
+  yield PlacesUtils.bookmarks.eraseEverything();
+});
+
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -793,16 +793,19 @@ BrowserGlue.prototype = {
     Feeds.init();
     ContentPrefServiceParent.init();
 
     LoginManagerParent.init();
     ReaderParent.init();
 
     SelfSupportBackend.init();
 
+    // Ensure we keep track of places/pw-mananager undo by init'ing this early.
+    Cu.import("resource:///modules/AutoMigrate.jsm");
+
     if (!AppConstants.RELEASE_BUILD) {
       let themeName = gBrowserBundle.GetStringFromName("deveditionTheme.name");
       let vendorShortName = gBrandBundle.GetStringFromName("vendorShortName");
 
       LightweightThemeManager.addBuiltInTheme({
         id: "firefox-devedition@mozilla.org",
         name: themeName,
         headerURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.header.png",
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -74,21 +74,34 @@ var gCookiesWindow = {
   _cookieEquals: function (aCookieA, aCookieB, aStrippedHost) {
     return aCookieA.rawHost == aStrippedHost &&
            aCookieA.name == aCookieB.name &&
            aCookieA.path == aCookieB.path &&
            ChromeUtils.isOriginAttributesEqual(aCookieA.originAttributes,
                                                aCookieB.originAttributes);
   },
 
+  _isPrivateCookie: function (aCookie) {
+      let { userContextId } = aCookie.originAttributes;
+      if (!userContextId) {
+        // Default identity is public.
+        return false;
+      }
+      return !ContextualIdentityService.getIdentityFromId(userContextId).public;
+  },
+
   observe: function (aCookie, aTopic, aData) {
     if (aTopic != "cookie-changed")
       return;
 
     if (aCookie instanceof Components.interfaces.nsICookie) {
+      if (this._isPrivateCookie(aCookie)) {
+        return;
+      }
+
       var strippedHost = this._makeStrippedHost(aCookie.host);
       if (aData == "changed")
         this._handleCookieChanged(aCookie, strippedHost);
       else if (aData == "added")
         this._handleCookieAdded(aCookie, strippedHost);
     }
     else if (aData == "cleared") {
       this._hosts = {};
@@ -485,16 +498,20 @@ var gCookiesWindow = {
   _loadCookies: function () {
     var e = this._cm.enumerator;
     var hostCount = { value: 0 };
     this._hosts = {};
     this._hostOrder = [];
     while (e.hasMoreElements()) {
       var cookie = e.getNext();
       if (cookie && cookie instanceof Components.interfaces.nsICookie) {
+        if (this._isPrivateCookie(cookie)) {
+          continue;
+        }
+
         var strippedHost = this._makeStrippedHost(cookie.host);
         this._addCookie(strippedHost, cookie, hostCount);
       }
       else
         break;
     }
     this._view._rowCount = hostCount.value;
   },
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -392,19 +392,19 @@ PluginContent.prototype = {
       // <embed> element), this call is for a window-global plugin.
       this.onPluginCrashed(event.target, event);
       return;
     }
 
     if (eventType == "HiddenPlugin") {
       let pluginTag = event.tag.QueryInterface(Ci.nsIPluginTag);
       if (event.target.defaultView.top.document != this.content.document) {
-	return;
+        return;
       }
-      this._showClickToPlayNotification(pluginTag, true);
+      this._showClickToPlayNotification(pluginTag, false);
     }
 
     let plugin = event.target;
     let doc = plugin.ownerDocument;
 
     if (!(plugin instanceof Ci.nsIObjectLoadingContent))
       return;
 
--- a/build/autoconf/alloc.m4
+++ b/build/autoconf/alloc.m4
@@ -17,26 +17,26 @@ for file in $MALLOC_HEADERS; do
 done
 
 MOZ_CHECK_HEADERS(alloca.h)
 
 AC_CHECK_FUNCS(strndup posix_memalign memalign)
 
 AC_CHECK_FUNCS(malloc_usable_size)
 MALLOC_USABLE_SIZE_CONST_PTR=const
-MOZ_CHECK_HEADERS([malloc.h], [
+if test -n "$HAVE_MALLOC_H"; then
   AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
   AC_TRY_COMPILE([#include <malloc.h>
                   #include <stddef.h>
                   size_t malloc_usable_size(const void *ptr);],
                   [return malloc_usable_size(0);],
                   AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   MALLOC_USABLE_SIZE_CONST_PTR=)
-])
+fi
 AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
 
 
 dnl In newer bionic headers, valloc is built but not defined,
 dnl so we check more carefully here.
 AC_MSG_CHECKING([for valloc in malloc.h])
 AC_EGREP_HEADER(valloc, malloc.h,
                 AC_DEFINE(HAVE_VALLOC)
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -6,69 +6,19 @@ AC_DEFUN([MOZ_ANDROID_NDK],
 [
 
 MOZ_ARG_WITH_STRING(android-cxx-stl,
 [  --with-android-cxx-stl=VALUE
                           use the specified C++ STL (stlport, libstdc++, libc++)],
     android_cxx_stl=$withval,
     android_cxx_stl=libc++)
 
-define([MIN_ANDROID_VERSION], [9])
-android_version=MIN_ANDROID_VERSION
-
-MOZ_ARG_WITH_STRING(android-version,
-[  --with-android-version=VER
-                          android platform version, default] MIN_ANDROID_VERSION,
-    android_version=$withval)
-
-if test $android_version -lt MIN_ANDROID_VERSION ; then
-    AC_MSG_ERROR([--with-android-version must be at least MIN_ANDROID_VERSION.])
-fi
-
 case "$target" in
 *-android*|*-linuxandroid*)
-    AC_MSG_CHECKING([for android platform directory])
-
-    case "$target_cpu" in
-    arm)
-        target_name=arm
-        ;;
-    i?86)
-        target_name=x86
-        ;;
-    mipsel)
-        target_name=mips
-        ;;
-    esac
-
-    dnl Not all Android releases have their own platform release. We use
-    dnl the next lower platform version in these cases.
-    case $android_version in
-    11|10)
-        android_platform_version=9
-        ;;
-    20)
-        android_platform_version=19
-        ;;
-    22)
-        android_platform_version=21
-        ;;
-    *)
-        android_platform_version=$android_version
-        ;;
-    esac
-
-    android_platform="$android_ndk"/platforms/android-"$android_platform_version"/arch-"$target_name"
-
-    if test -d "$android_platform" ; then
-        AC_MSG_RESULT([$android_platform])
-    else
-        AC_MSG_ERROR([not found. Please check your NDK. With the current configuration, it should be in $android_platform])
-    fi
-
+    dnl $android_platform will be set for us by Python configure.
     CPPFLAGS="-idirafter $android_platform/usr/include $CPPFLAGS"
     CFLAGS="-fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-fno-short-enums -fno-exceptions $CXXFLAGS"
     ASFLAGS="-idirafter $android_platform/usr/include -DANDROID $ASFLAGS"
 
     dnl Add --allow-shlib-undefined, because libGLESv2 links to an
     dnl undefined symbol (present on the hardware, just not in the
     dnl NDK.)
deleted file mode 100644
--- a/build/autoconf/mozcommonheader.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-dnl This Source Code Form is subject to the terms of the Mozilla Public
-dnl License, v. 2.0. If a copy of the MPL was not distributed with this
-dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-AC_DEFUN(MOZ_CHECK_COMMON_HEADERS,
-	MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h sys/bitypes.h \
-        memory.h unistd.h gnu/libc-version.h nl_types.h malloc.h \
-        X11/XKBlib.h io.h cpuid.h)
-)
--- a/build/moz.configure/android-ndk.configure
+++ b/build/moz.configure/android-ndk.configure
@@ -9,27 +9,96 @@ js_option('--with-android-ndk', nargs=1,
           help='location where the Android NDK can be found')
 
 js_option('--with-android-toolchain', nargs=1,
           help='location of the Android toolchain')
 
 js_option('--with-android-gnu-compiler-version', nargs=1,
           help='GNU compiler version to use')
 
+@depends('--help')
+def min_android_version(_):
+    return '9'
+
+js_option('--with-android-version',
+          nargs=1,
+          help='android platform version',
+          default=min_android_version)
+
+@depends('--with-android-version', min_android_version)
+@imports(_from='__builtin__', _import='ValueError')
+def android_version(value, min_version):
+    if not value:
+        # Someone has passed --without-android-version.
+        die('--with-android-version cannot be disabled.')
+
+    try:
+        version = int(value[0])
+    except ValueError:
+        die('--with-android-version expects an integer value')
+
+    if version < int(min_version):
+        die('--with-android-version must be at least %s (got %s)',
+            min_version, value[0])
+
+    return version
+
+add_old_configure_assignment('android_version', android_version)
+
 @depends('--with-android-ndk', build_project)
 def ndk(value, build_project):
     if build_project == 'mobile/android' and not value:
         die('You must specify --with-android-ndk=/path/to/ndk when '
             'building mobile/android')
     if value:
         return value[0]
 
 set_config('ANDROID_NDK', ndk)
 add_old_configure_assignment('android_ndk', ndk)
 
+@depends(target, android_version, ndk)
+@checking('for android platform directory')
+def android_platform(target, android_version, ndk):
+    if target.os != 'Android':
+        return
+
+    if 'mips' in target.cpu:
+        target_dir_name = 'mips'
+    else:
+        target_dir_name = target.cpu
+
+    # Not all Android releases have their own platform release. We use
+    # the next lower platform version in these cases.
+    if android_version in (11, 10):
+        platform_version = 9
+    elif android_version in (20, 22):
+        platform_version = android_version - 1
+    else:
+        platform_version = android_version
+
+    platform_dir = os.path.join(ndk,
+                                'platforms',
+                                'android-%s' % platform_version,
+                                'arch-%s' % target_dir_name)
+
+    if not os.path.isdir(platform_dir):
+        die("Android platform directory not found. With the current "
+            "configuration, it should be in %s" % platform_dir)
+
+    return platform_dir
+
+add_old_configure_assignment('android_platform', android_platform)
+
+@depends(android_platform)
+def extra_toolchain_flags(platform_dir):
+    if not platform_dir:
+        return []
+    return ['-idirafter',
+            os.path.join(platform_dir, 'usr', 'include')]
+
 @depends(target, host, ndk, '--with-android-toolchain',
          '--with-android-gnu-compiler-version')
 @checking('for the Android toolchain directory', lambda x: x or 'not found')
 @imports(_from='mozbuild.shellutil', _import='quote')
 def android_toolchain(target, host, ndk, toolchain, gnu_compiler_version):
     if not ndk:
         return
     if toolchain:
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/compilechecks.configure
@@ -0,0 +1,110 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+# Generates a test program and attempts to compile it. In case of failure, the
+# resulting check will return None. If the test program succeeds, it will return
+# the output of the test program.
+# - `includes` are the includes (as file names) that will appear at the top of
+#   the generated test program.
+# - `body` is the code that will appear in the main function of the generated
+#   test program. `return 0;` is appended to the function body automatically.
+# - `language` is the language selection, so that the appropriate compiler is
+#   used.
+# - `flags` are the flags to be passed to the compiler, in addition to `-c`.
+# - `check_msg` is the message to be printed to accompany compiling the test
+#   program.
+@template
+@imports('textwrap')
+def try_compile(includes=None, body='', language='C++', flags=None, check_msg=None):
+    includes = includes or []
+    source_lines = ['#include <%s>' % f for f in includes]
+    source = '\n'.join(source_lines) + '\n'
+    source += textwrap.dedent('''\
+        int
+        main(void)
+        {
+        %s
+          ;
+          return 0;
+        }
+    ''' % body)
+
+    if check_msg:
+        def checking_fn(fn):
+            return checking(check_msg, callback=lambda r: r is not None)(fn)
+    else:
+        def checking_fn(fn):
+            return fn
+
+    def get_flags():
+        if flags:
+            return flags[:]
+
+    @depends(cxx_compiler, c_compiler, extra_toolchain_flags)
+    @checking_fn
+    def check(cxx_info, c_info, extra_flags):
+        flags = get_flags() or []
+        flags += extra_flags
+        flags.append('-c')
+
+        info = {
+            'C': c_info,
+            'C++': cxx_info,
+        }[language]
+        return try_invoke_compiler(info.wrapper + [info.compiler] + info.flags,
+                                   language, source, flags,
+                                   onerror=lambda: None)
+    return check
+
+# Checks for the presence of the given header on the target system by compiling
+# a test program including that header. The return value of the template is a
+# check function returning True if the header is present, and None if it is not.
+# The value of this check function is also used to set a variable (with set_define)
+# corresponding to the checked header. For instance, HAVE_MALLOC_H will be set in
+# defines if check_header if called with 'malloc.h' as input and malloc.h is
+# present on the target.
+# - `header` is the header, as a file name, to check for.
+# - `language` is the language selection, so that the appropriate compiler is
+#   used.
+# - `flags` are the flags to be passed to the compiler, in addition to `-c`.
+# - `includes` are additional includes, as file names, to appear before the
+#   header checked for.
+# - `when` is a depends function that if present will make performing the check
+#   conditional on the value of that function.
+@template
+def check_header(header, language='C++', flags=None, includes=None, when=None):
+    when = when or depends('--help')(lambda _: True)
+
+    if includes:
+        includes = includes[:]
+    else:
+        includes = []
+    includes.append(header)
+
+    @depends_when(try_compile(includes=includes, language=language, flags=flags,
+                              check_msg='for %s' % header), when=when)
+    def have_header(value):
+        if value is not None:
+            return True
+    header_var = 'HAVE_%s' % (header.upper()
+                                    .replace('-', '_')
+                                    .replace('/', '_')
+                                    .replace('.', '_'))
+    set_define(header_var, have_header)
+    return have_header
+
+# A convenience wrapper for check_header for checking multiple headers.
+# returns an array of the resulting checks in order corresponding to the
+# provided headers.
+# - `headers` are the headers to be checked.
+# - `kwargs` are keyword arguments passed verbatim to check_header.
+@template
+def check_headers(*headers, **kwargs):
+    checks = []
+    for header in headers:
+        checks.append(check_header(header, **kwargs))
+    return checks
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/headers.configure
@@ -0,0 +1,63 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Check for headers defining standard int types.
+check_header('stdint.h')
+have_inttypes = check_header('inttypes.h')
+
+set_config('HAVE_INTTYPES_H', have_inttypes)
+
+# Checks for headers relevant to non-windows systems.
+non_msvc_compiler = depends(c_compiler)(lambda info: info.type != 'msvc')
+
+building_linux = depends(target)(lambda target: target.kernel == 'Linux')
+
+have_malloc = check_header('malloc.h')
+
+add_old_configure_assignment('HAVE_MALLOC_H', have_malloc)
+
+check_headers(
+    'sys/byteorder.h',
+    'getopt.h',
+    'unistd.h',
+    'nl_types.h',
+    'cpuid.h',
+    when=non_msvc_compiler,
+)
+
+# These are all the places some variant of statfs can be hiding.
+check_headers(
+    'sys/statvfs.h',
+    'sys/statfs.h',
+    'sys/vfs.h',
+    'sys/mount.h',
+    when=non_msvc_compiler,
+)
+
+# Quota support
+check_header('sys/quota.h',
+             when=non_msvc_compiler)
+check_header('linux/quota.h',
+             includes=['sys/socket.h'],
+             when=building_linux)
+
+# SCTP support - needs various network include headers
+check_headers(
+    'linux/if_addr.h',
+    'linux/rtnetlink.h',
+    includes=['sys/socket.h'],
+    when=building_linux,
+)
+
+check_header('sys/queue.h',
+             when=non_msvc_compiler)
+
+check_headers(
+    'sys/types.h',
+    'netinet/in.h',
+    'byteswap.h',
+    when=non_msvc_compiler,
+)
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -267,17 +267,16 @@ def old_configure_options(*options):
     '--no-create',
     '--prefix',
     '--with-adjust-sdk-keyfile',
     '--with-android-cxx-stl',
     '--with-android-distribution-directory',
     '--with-android-max-sdk',
     '--with-android-min-sdk',
     '--with-android-sdk',
-    '--with-android-version',
     '--with-app-basename',
     '--with-app-name',
     '--with-arch',
     '--with-bing-api-keyfile',
     '--with-branding',
     '--with-crashreporter-enable-percent',
     '--with-cross-lib',
     '--with-debug-label',
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -50,27 +50,30 @@ set_config('YASM_ASFLAGS', yasm_asflags)
 def have_yasm(value):
     if value:
         return True
 
 set_config('HAVE_YASM', have_yasm)
 # Until the YASM variable is not necessary in old-configure.
 add_old_configure_assignment('YASM', have_yasm)
 
+@depends('--help')
+def extra_toolchain_flags(_):
+    # This value will be overriden for android builds, where
+    # extra flags are required to do basic checks.
+    return []
 
 # Android NDK
 # ==============================================================
 
 @depends('--disable-compile-environment', build_project, gonkdir, '--help')
-def android_ndk_include(compile_env, build_project, gonkdir, _):
-    if compile_env and (gonkdir or build_project in ('mobile/android', 'js')):
-        return 'android-ndk.configure'
+def compiling_android(compile_env, build_project, gonkdir, _):
+    return compile_env and (gonkdir or build_project in ('mobile/android', 'js'))
 
-include(android_ndk_include)
-
+include_when('android-ndk.configure', when=compiling_android)
 
 # MacOS deployment target version
 # ==============================================================
 # This needs to happen before any compilation test is done.
 
 option('--enable-macos-target', env='MACOSX_DEPLOYMENT_TARGET', nargs=1,
        default='10.7', help='Set the minimum MacOS version needed at runtime')
 
@@ -163,41 +166,18 @@ def toolchain_prefix(value, target, host
         return '%s-' % target.toolchain
 
 set_config('TOOLCHAIN_PREFIX', toolchain_prefix)
 add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
 
 
 # Compilers
 # ==============================================================
-@imports('os')
-@imports('subprocess')
-@imports(_from='mozbuild.configure.util', _import='LineIO')
-@imports(_from='tempfile', _import='mkstemp')
 def try_preprocess(compiler, language, source):
-    suffix = {
-        'C': '.c',
-        'C++': '.cpp',
-    }[language]
-
-    fd, path = mkstemp(prefix='conftest.', suffix=suffix)
-    try:
-        source = source.encode('ascii', 'replace')
-
-        log.debug('Creating `%s` with content:', path)
-        with LineIO(lambda l: log.debug('| %s', l)) as out:
-            out.write(source)
-
-        os.write(fd, source)
-        os.close(fd)
-        cmd = compiler + ['-E', path]
-        return check_cmd_output(*cmd)
-    finally:
-        os.remove(path)
-
+    return try_invoke_compiler(compiler, language, source, ['-E'])
 
 @imports(_from='mozbuild.configure.constants', _import='CompilerType')
 @imports(_from='mozbuild.configure.constants',
          _import='CPU_preprocessor_checks')
 @imports(_from='mozbuild.configure.constants',
          _import='kernel_preprocessor_checks')
 @imports(_from='textwrap', _import='dedent')
 def get_compiler_info(compiler, language):
@@ -760,16 +740,18 @@ def compiler(language, host_or_target, c
 
 c_compiler = compiler('C', target)
 cxx_compiler = compiler('C++', target, c_compiler=c_compiler)
 host_c_compiler = compiler('C', host, other_compiler=c_compiler)
 host_cxx_compiler = compiler('C++', host, c_compiler=host_c_compiler,
                              other_compiler=cxx_compiler,
                              other_c_compiler=c_compiler)
 
+include('compilechecks.configure')
+
 @depends(c_compiler)
 def default_debug_flags(compiler_info):
     # Debug info is ON by default.
     if compiler_info.type == 'msvc':
         return '-Zi'
     return '-g'
 
 option(env='MOZ_DEBUG_FLAGS',
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -80,16 +80,49 @@ def find_program(file, paths=None):
                     "not %r", paths)
             paths = list(itertools.chain(
                 *(p.split(pathsep) for p in paths if p)))
         return normsep(which(file, path=paths))
     except WhichError:
         return None
 
 
+@imports('os')
+@imports('subprocess')
+@imports(_from='mozbuild.configure.util', _import='LineIO')
+@imports(_from='tempfile', _import='mkstemp')
+def try_invoke_compiler(compiler, language, source, flags=None, onerror=None):
+    flags = flags or []
+
+    if not isinstance(flags, (list, tuple)):
+        die("Flags provided to try_compile must be a list of strings, "
+            "not %r", paths)
+
+    suffix = {
+        'C': '.c',
+        'C++': '.cpp',
+    }[language]
+
+    fd, path = mkstemp(prefix='conftest.', suffix=suffix)
+    try:
+        source = source.encode('ascii', 'replace')
+
+        log.debug('Creating `%s` with content:', path)
+        with LineIO(lambda l: log.debug('| %s', l)) as out:
+            out.write(source)
+
+        os.write(fd, source)
+        os.close(fd)
+        cmd = compiler + list(flags) + [path]
+        kwargs = {'onerror': onerror}
+        return check_cmd_output(*cmd, **kwargs)
+    finally:
+        os.remove(path)
+
+
 def unique_list(l):
     result = []
     for i in l:
         if l not in result:
             result.append(i)
     return result
 
 
@@ -275,8 +308,18 @@ def depends_when(*args, **kwargs):
     when = kwargs['when']
     def decorator(fn):
         @depends(when, *args)
         def wrapper(val, *args):
             if val:
                 return fn(*args)
         return wrapper
     return decorator
+
+# Includes a file when the given condition evaluates to a truthy value.
+@template
+def include_when(filename, when):
+    # Assume, for now, our condition already depends on --help.
+    @depends(when, '--help')
+    def conditional_include(value, _):
+        if value:
+            return filename
+    include(conditional_include)
--- a/build/subconfigure.py
+++ b/build/subconfigure.py
@@ -201,26 +201,29 @@ def prepare(srcdir, objdir, shell, args)
     if os.path.exists(data_file):
         with open(data_file, 'rb') as f:
             data = pickle.load(f)
             previous_args = data['args']
 
     # Msys likes to break environment variables and command line arguments,
     # so read those from stdin, as they are passed from the configure script
     # when necessary (on windows).
-    # However, for some reason, $PATH is not handled like other environment
-    # variables, and msys remangles it even when giving it is already a msys
-    # $PATH. Fortunately, the mangling/demangling is just find for $PATH, so
-    # we can just take the value from the environment. Msys will convert it
-    # back properly when calling subconfigure.
     input = sys.stdin.read()
     if input:
         data = {a: b for [a, b] in eval(input)}
         environ = {a: b for a, b in data['env']}
-        environ['PATH'] = os.environ['PATH']
+        # These environment variables as passed from old-configure may contain
+        # posix-style paths, which will not be meaningful to the js
+        # subconfigure, which runs as a native python process, so use their
+        # values from the environment. In the case of autoconf implemented
+        # subconfigures, Msys will re-convert them properly.
+        for var in ('HOME', 'TERM', 'PATH', 'TMPDIR', 'TMP',
+                    'TEMP', 'INCLUDE'):
+            if var in environ and var in os.environ:
+                environ[var] = os.environ[var]
         args = data['args']
     else:
         environ = os.environ
 
     args, others = parser.parse_known_args(args)
 
     data = {
         'target': args.target,
--- a/caps/nsNullPrincipalURI.cpp
+++ b/caps/nsNullPrincipalURI.cpp
@@ -266,16 +266,24 @@ NS_IMETHODIMP
 nsNullPrincipalURI::CloneIgnoringRef(nsIURI **_newURI)
 {
   // GetRef/SetRef not supported by nsNullPrincipalURI, so
   // CloneIgnoringRef() is the same as Clone().
   return Clone(_newURI);
 }
 
 NS_IMETHODIMP
+nsNullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI **_newURI)
+{
+  // GetRef/SetRef not supported by nsNullPrincipalURI, so
+  // CloneWithNewRef() is the same as Clone().
+  return Clone(_newURI);
+}
+
+NS_IMETHODIMP
 nsNullPrincipalURI::Equals(nsIURI *aOther, bool *_equals)
 {
   *_equals = false;
   RefPtr<nsNullPrincipalURI> otherURI;
   nsresult rv = aOther->QueryInterface(kNullPrincipalURIImplementationCID,
                                        getter_AddRefs(otherURI));
   if (NS_SUCCEEDED(rv)) {
     *_equals = mPath == otherURI->mPath;
--- a/devtools/client/inspector/breadcrumbs.js
+++ b/devtools/client/inspector/breadcrumbs.js
@@ -346,17 +346,17 @@ HTMLBreadcrumbs.prototype = {
     this.separators.innerHTML =
                       "<div id='breadcrumb-separator-before'></div>" +
                       "<div id='breadcrumb-separator-after'></div>" +
                       "<div id='breadcrumb-separator-normal'></div>";
     this.container.parentNode.appendChild(this.separators);
 
     this.outer.addEventListener("click", this, true);
     this.outer.addEventListener("mouseover", this, true);
-    this.outer.addEventListener("mouseleave", this, true);
+    this.outer.addEventListener("mouseout", this, true);
     this.outer.addEventListener("focus", this, true);
 
     this.shortcuts = new KeyShortcuts({ window: this.chromeWin, target: this.outer });
     this.handleShortcut = this.handleShortcut.bind(this);
 
     this.shortcuts.on("Right", this.handleShortcut);
     this.shortcuts.on("Left", this.handleShortcut);
     this.shortcuts.on("Tab", this.handleShortcut);
@@ -477,17 +477,17 @@ HTMLBreadcrumbs.prototype = {
    * Generic event handler.
    * @param {DOMEvent} event.
    */
   handleEvent: function (event) {
     if (event.type == "click" && event.button == 0) {
       this.handleClick(event);
     } else if (event.type == "mouseover") {
       this.handleMouseOver(event);
-    } else if (event.type == "mouseleave") {
+    } else if (event.type == "mouseout") {
       this.handleMouseLeave(event);
     } else if (event.type == "focus") {
       this.handleFocus(event);
     }
   },
 
   /**
    * Focus event handler. When breadcrumbs container gets focus, if there is an
@@ -528,20 +528,20 @@ HTMLBreadcrumbs.prototype = {
   handleMouseOver: function (event) {
     let target = event.originalTarget;
     if (target.tagName == "button") {
       target.onBreadcrumbsHover();
     }
   },
 
   /**
-   * On mouse leave, make sure to unhighlight.
+   * On mouse out, make sure to unhighlight.
    * @param {DOMEvent} event.
    */
-  handleMouseLeave: function (event) {
+  handleMouseOut: function (event) {
     this.inspector.toolbox.highlighterUtils.unhighlight();
   },
 
   /**
    * Handle a keyboard shortcut supported by the breadcrumbs widget.
    *
    * @param {String} name
    *        Name of the keyboard shortcut received.
@@ -588,17 +588,17 @@ HTMLBreadcrumbs.prototype = {
   destroy: function () {
     this.selection.off("new-node-front", this.update);
     this.selection.off("pseudoclass", this.updateSelectors);
     this.selection.off("attribute-changed", this.updateSelectors);
     this.inspector.off("markupmutation", this.update);
 
     this.container.removeEventListener("click", this, true);
     this.container.removeEventListener("mouseover", this, true);
-    this.container.removeEventListener("mouseleave", this, true);
+    this.container.removeEventListener("mouseout", this, true);
     this.container.removeEventListener("focus", this, true);
     this.shortcuts.destroy();
 
     this.empty();
     this.separators.remove();
 
     this.arrowScrollBox.off("overflow", this.scroll);
     this.arrowScrollBox.destroy();
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -127,29 +127,29 @@ function MarkupView(inspector, frame, co
   this._mutationObserver = this._mutationObserver.bind(this);
   this._onDisplayChange = this._onDisplayChange.bind(this);
   this._onMouseClick = this._onMouseClick.bind(this);
   this._onMouseUp = this._onMouseUp.bind(this);
   this._onNewSelection = this._onNewSelection.bind(this);
   this._onCopy = this._onCopy.bind(this);
   this._onFocus = this._onFocus.bind(this);
   this._onMouseMove = this._onMouseMove.bind(this);
-  this._onMouseLeave = this._onMouseLeave.bind(this);
+  this._onMouseOut = this._onMouseOut.bind(this);
   this._onToolboxPickerHover = this._onToolboxPickerHover.bind(this);
   this._onCollapseAttributesPrefChange =
     this._onCollapseAttributesPrefChange.bind(this);
   this._isImagePreviewTarget = this._isImagePreviewTarget.bind(this);
   this._onBlur = this._onBlur.bind(this);
 
   EventEmitter.decorate(this);
 
   // Listening to various events.
   this._elt.addEventListener("click", this._onMouseClick, false);
   this._elt.addEventListener("mousemove", this._onMouseMove, false);
-  this._elt.addEventListener("mouseleave", this._onMouseLeave, false);
+  this._elt.addEventListener("mouseout", this._onMouseOut, false);
   this._elt.addEventListener("blur", this._onBlur, true);
   this.win.addEventListener("mouseup", this._onMouseUp);
   this.win.addEventListener("copy", this._onCopy);
   this._frame.addEventListener("focus", this._onFocus, false);
   this.walker.on("mutations", this._mutationObserver);
   this.walker.on("display-change", this._onDisplayChange);
   this._inspector.selection.on("new-node-front", this._onNewSelection);
   this._inspector.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
@@ -396,17 +396,22 @@ MarkupView.prototype = {
     if (this._hoveredNode) {
       this.getContainer(this._hoveredNode).hovered = false;
     }
 
     this.getContainer(nodeFront).hovered = true;
     this._hoveredNode = nodeFront;
   },
 
-  _onMouseLeave: function () {
+  _onMouseOut: function (event) {
+    // Emulate mouseleave by skipping any relatedTarget inside the markup-view.
+    if (this._elt.contains(event.relatedTarget)) {
+      return;
+    }
+
     if (this._autoScrollAnimationFrame) {
       this.win.cancelAnimationFrame(this._autoScrollAnimationFrame);
     }
     if (this.isDragging) {
       return;
     }
 
     this._hideBoxModel(true);
@@ -1736,17 +1741,17 @@ MarkupView.prototype = {
     this.undo.destroy();
     this.undo = null;
 
     this.popup.destroy();
     this.popup = null;
 
     this._elt.removeEventListener("click", this._onMouseClick, false);
     this._elt.removeEventListener("mousemove", this._onMouseMove, false);
-    this._elt.removeEventListener("mouseleave", this._onMouseLeave, false);
+    this._elt.removeEventListener("mouseout", this._onMouseOut, false);
     this._elt.removeEventListener("blur", this._onBlur, true);
     this.win.removeEventListener("mouseup", this._onMouseUp);
     this.win.removeEventListener("copy", this._onCopy);
     this._frame.removeEventListener("focus", this._onFocus, false);
     this.walker.off("mutations", this._mutationObserver);
     this.walker.off("display-change", this._onDisplayChange);
     this._inspector.selection.off("new-node-front", this._onNewSelection);
     this._inspector.toolbox.off("picker-node-hovered",
--- a/devtools/client/inspector/shared/style-inspector-overlays.js
+++ b/devtools/client/inspector/shared/style-inspector-overlays.js
@@ -60,17 +60,17 @@ function HighlightersOverlay(view) {
   this.view = view;
 
   let {CssRuleView} = require("devtools/client/inspector/rules/rules");
   this.isRuleView = view instanceof CssRuleView;
 
   this.highlighterUtils = this.view.inspector.toolbox.highlighterUtils;
 
   this._onMouseMove = this._onMouseMove.bind(this);
-  this._onMouseLeave = this._onMouseLeave.bind(this);
+  this._onMouseOut = this._onMouseOut.bind(this);
 
   this.highlighters = {};
 
   // Only initialize the overlay if at least one of the highlighter types is
   // supported
   this.supportsHighlighters =
     this.highlighterUtils.supportsCustomHighlighters();
 
@@ -86,17 +86,18 @@ HighlightersOverlay.prototype = {
    */
   addToView: function () {
     if (!this.supportsHighlighters || this._isStarted || this._isDestroyed) {
       return;
     }
 
     let el = this.view.element;
     el.addEventListener("mousemove", this._onMouseMove, false);
-    el.addEventListener("mouseleave", this._onMouseLeave, false);
+    el.addEventListener("mouseout", this._onMouseOut, false);
+    el.ownerDocument.defaultView.addEventListener("mouseout", this._onMouseOut, false);
 
     this._isStarted = true;
   },
 
   /**
    * Remove the overlay from the current view. This will stop tracking mouse
    * movement and showing highlighters
    */
@@ -104,17 +105,17 @@ HighlightersOverlay.prototype = {
     if (!this.supportsHighlighters || !this._isStarted || this._isDestroyed) {
       return;
     }
 
     this._hideCurrent();
 
     let el = this.view.element;
     el.removeEventListener("mousemove", this._onMouseMove, false);
-    el.removeEventListener("mouseleave", this._onMouseLeave, false);
+    el.removeEventListener("mouseout", this._onMouseOut, false);
 
     this._isStarted = false;
   },
 
   _onMouseMove: function (event) {
     // Bail out if the target is the same as for the last mousemove
     if (event.target === this._lastHovered) {
       return;
@@ -145,17 +146,24 @@ HighlightersOverlay.prototype = {
           .then(shown => {
             if (shown) {
               this.emit("highlighter-shown");
             }
           });
     }
   },
 
-  _onMouseLeave: function () {
+  _onMouseOut: function (event) {
+    // Only hide the highlighter if the mouse leaves the currently hovered node.
+    if (!this._lastHovered ||
+        (event && this._lastHovered.contains(event.relatedTarget))) {
+      return;
+    }
+
+    // Otherwise, hide the highlighter.
     this._lastHovered = null;
     this._hideCurrent();
   },
 
   /**
    * Is the current hovered node a css transform property value in the rule-view
    *
    * @param {Object} nodeInfo
--- a/devtools/client/inspector/shared/test/browser_styleinspector_transform-highlighter-03.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_transform-highlighter-03.js
@@ -55,17 +55,17 @@ add_task(function* () {
   let {valueSpan} = getRuleViewProperty(view, "body", "transform");
 
   info("Checking that the HighlighterFront's show/hide methods are called");
   let onHighlighterShown = hs.once("highlighter-shown");
   hs._onMouseMove({target: valueSpan});
   yield onHighlighterShown;
   ok(HighlighterFront.isShown, "The highlighter is shown");
   let onHighlighterHidden = hs.once("highlighter-hidden");
-  hs._onMouseLeave();
+  hs._onMouseOut();
   yield onHighlighterHidden;
   ok(!HighlighterFront.isShown, "The highlighter is hidden");
 
   info("Checking that hovering several times over the same property doesn't" +
     " show the highlighter several times");
   let nb = HighlighterFront.nbOfTimesShown;
   onHighlighterShown = hs.once("highlighter-shown");
   hs._onMouseMove({target: valueSpan});
--- a/devtools/client/performance/panel.js
+++ b/devtools/client/performance/panel.js
@@ -1,16 +1,15 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const { Cc, Ci, Cu, Cr } = require("chrome");
 const { Task } = require("devtools/shared/task");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter",
   "devtools/shared/event-emitter");
 
 function PerformancePanel(iframeWindow, toolbox) {
   this.panelWin = iframeWindow;
--- a/devtools/client/performance/performance-controller.js
+++ b/devtools/client/performance/performance-controller.js
@@ -1,43 +1,51 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
+/* globals document, PerformanceView, ToolbarView, RecordingsView, DetailsView */
+
+/* exported Cc, Ci, Cu, Cr, loader */
 var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 var BrowserLoaderModule = {};
 Cu.import("resource://devtools/client/shared/browser-loader.js", BrowserLoaderModule);
 var { loader, require } = BrowserLoaderModule.BrowserLoader({
   baseURI: "resource://devtools/client/performance/",
   window: this
 });
 var { Task } = require("devtools/shared/task");
+/* exported Heritage, ViewHelpers, WidgetMethods, setNamedTimeout, clearNamedTimeout */
 var { Heritage, ViewHelpers, WidgetMethods, setNamedTimeout, clearNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
 var { gDevTools } = require("devtools/client/framework/devtools");
 
 // Events emitted by various objects in the panel.
 var EVENTS = require("devtools/client/performance/events");
 Object.defineProperty(this, "EVENTS", {
   value: EVENTS,
   enumerable: true,
   writable: false
 });
 
+/* exported React, ReactDOM, JITOptimizationsView, Services, promise, EventEmitter,
+   DevToolsUtils, system */
 var React = require("devtools/client/shared/vendor/react");
 var ReactDOM = require("devtools/client/shared/vendor/react-dom");
 var JITOptimizationsView = React.createFactory(require("devtools/client/performance/components/jit-optimizations"));
 var Services = require("Services");
 var promise = require("promise");
 var EventEmitter = require("devtools/shared/event-emitter");
 var DevToolsUtils = require("devtools/shared/DevToolsUtils");
 var system = require("devtools/shared/system");
 
 // Logic modules
-
+/* exported L10N, PerformanceTelemetry, TIMELINE_BLUEPRINT, RecordingUtils,
+   OptimizationsGraph, GraphsController, WaterfallHeader, MarkerView, MarkerDetails,
+   MarkerBlueprintUtils, WaterfallUtils, FrameUtils, CallView, ThreadNode, FrameNode */
 var { L10N } = require("devtools/client/performance/modules/global");
 var { PerformanceTelemetry } = require("devtools/client/performance/modules/logic/telemetry");
 var { TIMELINE_BLUEPRINT } = require("devtools/client/performance/modules/markers");
 var RecordingUtils = require("devtools/shared/performance/recording-utils");
 var { OptimizationsGraph, GraphsController } = require("devtools/client/performance/modules/widgets/graphs");
 var { WaterfallHeader } = require("devtools/client/performance/modules/widgets/waterfall-ticks");
 var { MarkerView } = require("devtools/client/performance/modules/widgets/marker-view");
 var { MarkerDetails } = require("devtools/client/performance/modules/widgets/marker-details");
@@ -45,29 +53,33 @@ var { MarkerBlueprintUtils } = require("
 var WaterfallUtils = require("devtools/client/performance/modules/logic/waterfall-utils");
 var FrameUtils = require("devtools/client/performance/modules/logic/frame-utils");
 var { CallView } = require("devtools/client/performance/modules/widgets/tree-view");
 var { ThreadNode } = require("devtools/client/performance/modules/logic/tree-model");
 var { FrameNode } = require("devtools/client/performance/modules/logic/tree-model");
 
 // Widgets modules
 
+/* exported OptionsView, FlameGraph, FlameGraphUtils, TreeWidget, SideMenuWidget */
 var { OptionsView } = require("devtools/client/shared/options-view");
 var { FlameGraph, FlameGraphUtils } = require("devtools/client/shared/widgets/FlameGraph");
 var { TreeWidget } = require("devtools/client/shared/widgets/TreeWidget");
-
 var { SideMenuWidget } = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
 
+/* exported BRANCH_NAME */
 var BRANCH_NAME = "devtools.performance.ui.";
 
 /**
  * The current target, toolbox and PerformanceFront, set by this tool's host.
  */
+/* exported gToolbox, gTarget, gFront */
 var gToolbox, gTarget, gFront;
 
+/* exported startupPerformance, shutdownPerformance, PerformanceController */
+
 /**
  * Initializes the profiler controller and views.
  */
 var startupPerformance = Task.async(function* () {
   yield PerformanceController.initialize();
   yield PerformanceView.initialize();
   PerformanceController.enableFrontEventListeners();
 });
@@ -278,18 +290,19 @@ var PerformanceController = {
    *        The file to stream the data into.
    */
   exportRecording: Task.async(function* (_, recording, file) {
     yield recording.exportRecording(file);
     this.emit(EVENTS.RECORDING_EXPORTED, recording, file);
   }),
 
    /**
-   * Clears all completed recordings from the list as well as the current non-console recording.
-   * Emits `EVENTS.RECORDING_DELETED` when complete so other components can clean up.
+   * Clears all completed recordings from the list as well as the current non-console
+   * recording. Emits `EVENTS.RECORDING_DELETED` when complete so other components can
+   * clean up.
    */
   clearRecordings: Task.async(function* () {
     for (let i = this._recordings.length - 1; i >= 0; i--) {
       let model = this._recordings[i];
       if (!model.isConsole() && model.isRecording()) {
         yield this.stopRecording();
       }
       // If last recording is not recording, but finalizing itself,
@@ -303,18 +316,17 @@ var PerformanceController = {
         this.emit(EVENTS.RECORDING_DELETED, model);
         this._recordings.splice(i, 1);
       }
     }
     if (this._recordings.length > 0) {
       if (!this._recordings.includes(this.getCurrentRecording())) {
         this.setCurrentRecording(this._recordings[0]);
       }
-    }
-    else {
+    } else {
       this.setCurrentRecording(null);
     }
   }),
 
   /**
    * Loads a recording from a file, adding it to the recordings list. Emits
    * `EVENTS.RECORDING_IMPORTED` when the file was loaded.
    *
@@ -453,18 +465,18 @@ var PerformanceController = {
   },
 
   /**
    * Utility method taking a string or an array of strings of feature names (like
    * "withAllocations" or "withMarkers"), and returns whether or not the current
    * recording supports that feature, based off of UI preferences and server support.
    *
    * @option {Array<string>|string} features
-   *         A string or array of strings indicating what configuration is needed on the recording
-   *         model, like `withTicks`, or `withMemory`.
+   *         A string or array of strings indicating what configuration is needed on the
+   *         recording model, like `withTicks`, or `withMemory`.
    *
    * @return boolean
    */
   isFeatureSupported: function (features) {
     if (!features) {
       return true;
     }
 
@@ -537,19 +549,18 @@ var PerformanceController = {
    * Called on init, sets an `e10s` attribute on the main view container with
    * "disabled" if e10s is possible on the platform and just not on, or "unsupported"
    * if e10s is not possible on the platform. If e10s is on, no attribute is set.
    */
   _setMultiprocessAttributes: function () {
     let { enabled, supported } = this.getMultiprocessStatus();
     if (!enabled && supported) {
       $("#performance-view").setAttribute("e10s", "disabled");
-    }
-    // Could be a chance where the directive goes away yet e10s is still on
-    else if (!enabled && !supported) {
+    } else if (!enabled && !supported) {
+      // Could be a chance where the directive goes away yet e10s is still on
       $("#performance-view").setAttribute("e10s", "unsupported");
     }
   },
 
   /**
    * Pipes an event from some source to the PerformanceController.
    */
   _pipe: function (eventName, ...data) {
@@ -562,14 +573,15 @@ var PerformanceController = {
 /**
  * Convenient way of emitting events from the controller.
  */
 EventEmitter.decorate(PerformanceController);
 
 /**
  * DOM query helpers.
  */
+/* exported $, $$ */
 function $(selector, target = document) {
   return target.querySelector(selector);
 }
 function $$(selector, target = document) {
   return target.querySelectorAll(selector);
 }
--- a/devtools/client/performance/performance-view.js
+++ b/devtools/client/performance/performance-view.js
@@ -1,55 +1,119 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 /* import-globals-from performance-controller.js */
+/* globals OverviewView, window */
 "use strict";
-
 /**
  * Master view handler for the performance tool.
  */
 var PerformanceView = {
 
   _state: null,
 
   // Set to true if the front emits a "buffer-status" event, indicating
   // that the server has support for determining buffer status.
   _bufferStatusSupported: false,
 
   // Mapping of state to selectors for different properties and their values,
   // from the main profiler view. Used in `PerformanceView.setState()`
   states: {
     "unavailable": [
-      { sel: "#performance-view", opt: "selectedPanel", val: () => $("#unavailable-notice") },
-      { sel: "#performance-view-content", opt: "hidden", val: () => true },
+      {
+        sel: "#performance-view",
+        opt: "selectedPanel",
+        val: () => $("#unavailable-notice")
+      },
+      {
+        sel: "#performance-view-content",
+        opt: "hidden",
+        val: () => true
+      },
     ],
     "empty": [
-      { sel: "#performance-view", opt: "selectedPanel", val: () => $("#empty-notice") },
-      { sel: "#performance-view-content", opt: "hidden", val: () => true },
+      {
+        sel: "#performance-view",
+        opt: "selectedPanel",
+        val: () => $("#empty-notice")
+      },
+      {
+        sel: "#performance-view-content",
+        opt: "hidden",
+        val: () => true
+      },
     ],
     "recording": [
-      { sel: "#performance-view", opt: "selectedPanel", val: () => $("#performance-view-content") },
-      { sel: "#performance-view-content", opt: "hidden", val: () => false },
-      { sel: "#details-pane-container", opt: "selectedPanel", val: () => $("#recording-notice") },
+      {
+        sel: "#performance-view",
+        opt: "selectedPanel",
+        val: () => $("#performance-view-content")
+      },
+      {
+        sel: "#performance-view-content",
+        opt: "hidden",
+        val: () => false
+      },
+      {
+        sel: "#details-pane-container",
+        opt: "selectedPanel",
+        val: () => $("#recording-notice")
+      },
     ],
     "console-recording": [
-      { sel: "#performance-view", opt: "selectedPanel", val: () => $("#performance-view-content") },
-      { sel: "#performance-view-content", opt: "hidden", val: () => false },
-      { sel: "#details-pane-container", opt: "selectedPanel", val: () => $("#console-recording-notice") },
+      {
+        sel: "#performance-view",
+        opt: "selectedPanel",
+        val: () => $("#performance-view-content")
+      },
+      {
+        sel: "#performance-view-content",
+        opt: "hidden",
+        val: () => false
+      },
+      {
+        sel: "#details-pane-container",
+        opt: "selectedPanel",
+        val: () => $("#console-recording-notice")
+      },
     ],
     "recorded": [
-      { sel: "#performance-view", opt: "selectedPanel", val: () => $("#performance-view-content") },
-      { sel: "#performance-view-content", opt: "hidden", val: () => false },
-      { sel: "#details-pane-container", opt: "selectedPanel", val: () => $("#details-pane") },
+      {
+        sel: "#performance-view",
+        opt: "selectedPanel",
+        val: () => $("#performance-view-content")
+      },
+      {
+        sel: "#performance-view-content",
+        opt: "hidden",
+        val: () => false
+      },
+      {
+        sel: "#details-pane-container",
+        opt: "selectedPanel",
+        val: () => $("#details-pane")
+      },
     ],
     "loading": [
-      { sel: "#performance-view", opt: "selectedPanel", val: () => $("#performance-view-content") },
-      { sel: "#performance-view-content", opt: "hidden", val: () => false },
-      { sel: "#details-pane-container", opt: "selectedPanel", val: () => $("#loading-notice") },
+      {
+        sel: "#performance-view",
+        opt: "selectedPanel",
+        val: () => $("#performance-view-content")
+      },
+      {
+        sel: "#performance-view-content",
+        opt: "hidden",
+        val: () => false
+      },
+      {
+        sel: "#details-pane-container",
+        opt: "selectedPanel",
+        val: () => $("#loading-notice")
+      },
     ]
   },
 
   /**
    * Sets up the view with event binding and main subviews.
    */
   initialize: Task.async(function* () {
     this._recordButton = $("#main-record-button");
@@ -67,20 +131,22 @@ var PerformanceView = {
     for (let button of $$(".record-button")) {
       button.addEventListener("click", this._onRecordButtonClick);
     }
     this._importButton.addEventListener("click", this._onImportButtonClick);
     this._clearButton.addEventListener("click", this._onClearButtonClick);
 
     // Bind to controller events to unlock the record button
     PerformanceController.on(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
-    PerformanceController.on(EVENTS.RECORDING_PROFILER_STATUS_UPDATE, this._onProfilerStatusUpdated);
+    PerformanceController.on(EVENTS.RECORDING_PROFILER_STATUS_UPDATE,
+                             this._onProfilerStatusUpdated);
     PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
     PerformanceController.on(EVENTS.RECORDING_ADDED, this._onRecordingStateChange);
-    PerformanceController.on(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START, this._onNewRecordingFailed);
+    PerformanceController.on(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START,
+                             this._onNewRecordingFailed);
 
     if (yield PerformanceController.canCurrentlyRecord()) {
       this.setState("empty");
     } else {
       this.setState("unavailable");
     }
 
     // Initialize the ToolbarView first, because other views may need access
@@ -97,35 +163,38 @@ var PerformanceView = {
   destroy: Task.async(function* () {
     for (let button of $$(".record-button")) {
       button.removeEventListener("click", this._onRecordButtonClick);
     }
     this._importButton.removeEventListener("click", this._onImportButtonClick);
     this._clearButton.removeEventListener("click", this._onClearButtonClick);
 
     PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
-    PerformanceController.off(EVENTS.RECORDING_PROFILER_STATUS_UPDATE, this._onProfilerStatusUpdated);
-    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
+    PerformanceController.off(EVENTS.RECORDING_PROFILER_STATUS_UPDATE,
+                              this._onProfilerStatusUpdated);
+    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE,
+                              this._onRecordingStateChange);
     PerformanceController.off(EVENTS.RECORDING_ADDED, this._onRecordingStateChange);
-    PerformanceController.off(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START, this._onNewRecordingFailed);
+    PerformanceController.off(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START,
+                              this._onNewRecordingFailed);
 
     yield ToolbarView.destroy();
     yield RecordingsView.destroy();
     yield OverviewView.destroy();
     yield DetailsView.destroy();
   }),
 
   /**
    * Sets the state of the profiler view. Possible options are "unavailable",
    * "empty", "recording", "console-recording", "recorded".
    */
   setState: function (state) {
     // Make sure that the focus isn't captured on a hidden iframe. This fixes a
     // XUL bug where shortcuts stop working.
-    const iframes = window.document.querySelectorAll('iframe');
+    const iframes = window.document.querySelectorAll("iframe");
     for (let iframe of iframes) {
       iframe.blur();
     }
     window.focus();
 
     let viewConfig = this.states[state];
     if (!viewConfig) {
       throw new Error(`Invalid state for PerformanceView: ${state}`);
@@ -279,17 +348,18 @@ var PerformanceView = {
     }
   },
 
   /**
    * Handler for clicking the import button.
    */
   _onImportButtonClick: function (e) {
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    fp.init(window, L10N.getStr("recordingsList.importDialogTitle"), Ci.nsIFilePicker.modeOpen);
+    fp.init(window, L10N.getStr("recordingsList.importDialogTitle"),
+            Ci.nsIFilePicker.modeOpen);
     fp.appendFilter(L10N.getStr("recordingsList.saveDialogJSONFilter"), "*.json");
     fp.appendFilter(L10N.getStr("recordingsList.saveDialogAllFilter"), "*.*");
 
     if (fp.show() == Ci.nsIFilePicker.returnOK) {
       this.emit(EVENTS.UI_IMPORT_RECORDING, fp.file);
     }
   },
 
--- a/devtools/client/performance/views/details-abstract-subview.js
+++ b/devtools/client/performance/views/details-abstract-subview.js
@@ -1,53 +1,60 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* exported DetailsSubview */
 "use strict";
 
 /**
  * A base class from which all detail views inherit.
  */
 var DetailsSubview = {
   /**
    * Sets up the view with event binding.
    */
   initialize: function () {
     this._onRecordingStoppedOrSelected = this._onRecordingStoppedOrSelected.bind(this);
     this._onOverviewRangeChange = this._onOverviewRangeChange.bind(this);
     this._onDetailsViewSelected = this._onDetailsViewSelected.bind(this);
     this._onPrefChanged = this._onPrefChanged.bind(this);
 
-    PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStoppedOrSelected);
-    PerformanceController.on(EVENTS.RECORDING_SELECTED, this._onRecordingStoppedOrSelected);
+    PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE,
+                             this._onRecordingStoppedOrSelected);
+    PerformanceController.on(EVENTS.RECORDING_SELECTED,
+                             this._onRecordingStoppedOrSelected);
     PerformanceController.on(EVENTS.PREF_CHANGED, this._onPrefChanged);
     OverviewView.on(EVENTS.UI_OVERVIEW_RANGE_SELECTED, this._onOverviewRangeChange);
     DetailsView.on(EVENTS.UI_DETAILS_VIEW_SELECTED, this._onDetailsViewSelected);
 
     let self = this;
     let originalRenderFn = this.render;
-    let afterRenderFn = () => this._wasRendered = true;
+    let afterRenderFn = () => {
+      this._wasRendered = true;
+    };
 
     this.render = Task.async(function* (...args) {
       let maybeRetval = yield originalRenderFn.apply(self, args);
       afterRenderFn();
       return maybeRetval;
     });
   },
 
   /**
    * Unbinds events.
    */
   destroy: function () {
     clearNamedTimeout("range-change-debounce");
 
-    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStoppedOrSelected);
-    PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingStoppedOrSelected);
+    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE,
+                              this._onRecordingStoppedOrSelected);
+    PerformanceController.off(EVENTS.RECORDING_SELECTED,
+                              this._onRecordingStoppedOrSelected);
     PerformanceController.off(EVENTS.PREF_CHANGED, this._onPrefChanged);
     OverviewView.off(EVENTS.UI_OVERVIEW_RANGE_SELECTED, this._onOverviewRangeChange);
     DetailsView.off(EVENTS.UI_DETAILS_VIEW_SELECTED, this._onDetailsViewSelected);
   },
 
   /**
    * Returns true if this view was rendered at least once.
    */
@@ -128,17 +135,18 @@ var DetailsSubview = {
   _onOverviewRangeChange: function (_, interval) {
     if (!this.requiresUpdateOnRangeChange) {
       return;
     }
     if (DetailsView.isViewSelected(this)) {
       let debounced = () => {
         if (!this.shouldUpdateWhileMouseIsActive && OverviewView.isMouseActive) {
           // Don't render yet, while the selection is still being dragged.
-          setNamedTimeout("range-change-debounce", this.rangeChangeDebounceTime, debounced);
+          setNamedTimeout("range-change-debounce", this.rangeChangeDebounceTime,
+                          debounced);
         } else {
           this.render(interval);
         }
       };
       setNamedTimeout("range-change-debounce", this.rangeChangeDebounceTime, debounced);
     } else {
       this.shouldUpdateWhenShown = true;
     }
--- a/devtools/client/performance/views/details-js-call-tree.js
+++ b/devtools/client/performance/views/details-js-call-tree.js
@@ -1,28 +1,30 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* globals DetailsSubview */
 "use strict";
 
 /**
  * CallTree view containing profiler call tree, controlled by DetailsView.
  */
 var JsCallTreeView = Heritage.extend(DetailsSubview, {
 
   rerenderPrefs: [
     "invert-call-tree",
     "show-platform-data",
     "flatten-tree-recursion",
     "show-jit-optimizations",
   ],
 
-  rangeChangeDebounceTime: 75, // ms
+  // Units are in milliseconds.
+  rangeChangeDebounceTime: 75,
 
   /**
    * Sets up the view with event binding.
    */
   initialize: function () {
     DetailsSubview.initialize.call(this);
 
     this._onLink = this._onLink.bind(this);
@@ -76,17 +78,16 @@ var JsCallTreeView = Heritage.extend(Det
   },
 
   hideOptimizations: function () {
     this.optimizationsElement.classList.add("hidden");
   },
 
   _onFocus: function (_, treeItem) {
     let showOptimizations = PerformanceController.getOption("show-jit-optimizations");
-    let recording = PerformanceController.getCurrentRecording();
     let frameNode = treeItem.frame;
     let optimizationSites = frameNode && frameNode.hasOptimizations()
                             ? frameNode.getOptimizations().optimizationSites
                             : [];
 
     if (!showOptimizations || !frameNode || optimizationSites.length === 0) {
       this.hideOptimizations();
       this.emit("focus", treeItem);
@@ -131,17 +132,18 @@ var JsCallTreeView = Heritage.extend(Det
 
   /**
    * Called when the recording is stopped and prepares data to
    * populate the call tree.
    */
   _prepareCallTree: function (profile, { startTime, endTime }, options) {
     let thread = profile.threads[0];
     let { contentOnly, invertTree, flattenRecursion } = options;
-    let threadNode = new ThreadNode(thread, { startTime, endTime, contentOnly, invertTree, flattenRecursion });
+    let threadNode = new ThreadNode(thread, { startTime, endTime, contentOnly, invertTree,
+                                              flattenRecursion });
 
     // Real profiles from nsProfiler (i.e. not synthesized from allocation
     // logs) always have a (root) node. Go down one level in the uninverted
     // view to avoid displaying both the synthesized root node and the (root)
     // node from the profiler.
     if (!invertTree) {
       threadNode.calls = threadNode.calls[0].calls;
     }
--- a/devtools/client/performance/views/details-js-flamegraph.js
+++ b/devtools/client/performance/views/details-js-flamegraph.js
@@ -1,13 +1,14 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* globals DetailsSubview */
 "use strict";
 
 /**
  * FlameGraph view containing a pyramid-like visualization of a profile,
  * controlled by DetailsView.
  */
 var JsFlameGraphView = Heritage.extend(DetailsSubview, {
 
@@ -61,17 +62,18 @@ var JsFlameGraphView = Heritage.extend(D
     let duration = recording.getDuration();
     let profile = recording.getProfile();
     let thread = profile.threads[0];
 
     let data = FlameGraphUtils.createFlameGraphDataFromThread(thread, {
       invertTree: PerformanceController.getOption("invert-flame-graph"),
       flattenRecursion: PerformanceController.getOption("flatten-tree-recursion"),
       contentOnly: !PerformanceController.getOption("show-platform-data"),
-      showIdleBlocks: PerformanceController.getOption("show-idle-blocks") && L10N.getStr("table.idle")
+      showIdleBlocks: PerformanceController.getOption("show-idle-blocks")
+                      && L10N.getStr("table.idle")
     });
 
     this.graph.setData({ data,
       bounds: {
         startTime: 0,
         endTime: duration
       },
       visible: {
--- a/devtools/client/performance/views/details-memory-call-tree.js
+++ b/devtools/client/performance/views/details-memory-call-tree.js
@@ -1,25 +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/. */
 /* import-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* globals DetailsSubview */
 "use strict";
 
 /**
  * CallTree view containing memory allocation sites, controlled by DetailsView.
  */
 var MemoryCallTreeView = Heritage.extend(DetailsSubview, {
 
   rerenderPrefs: [
     "invert-call-tree"
   ],
 
-  rangeChangeDebounceTime: 100, // ms
+  // Units are in milliseconds.
+  rangeChangeDebounceTime: 100,
 
   /**
    * Sets up the view with event binding.
    */
   initialize: function () {
     DetailsSubview.initialize.call(this);
 
     this._onLink = this._onLink.bind(this);
--- a/devtools/client/performance/views/details-memory-flamegraph.js
+++ b/devtools/client/performance/views/details-memory-flamegraph.js
@@ -1,13 +1,14 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* globals DetailsSubview */
 "use strict";
 
 /**
  * FlameGraph view containing a pyramid-like visualization of memory allocation
  * sites, controlled by DetailsView.
  */
 var MemoryFlameGraphView = Heritage.extend(DetailsSubview, {
 
@@ -59,17 +60,18 @@ var MemoryFlameGraphView = Heritage.exte
     let recording = PerformanceController.getCurrentRecording();
     let duration = recording.getDuration();
     let allocations = recording.getAllocations();
 
     let thread = RecordingUtils.getProfileThreadFromAllocations(allocations);
     let data = FlameGraphUtils.createFlameGraphDataFromThread(thread, {
       invertStack: PerformanceController.getOption("invert-flame-graph"),
       flattenRecursion: PerformanceController.getOption("flatten-tree-recursion"),
-      showIdleBlocks: PerformanceController.getOption("show-idle-blocks") && L10N.getStr("table.idle")
+      showIdleBlocks: PerformanceController.getOption("show-idle-blocks")
+                      && L10N.getStr("table.idle")
     });
 
     this.graph.setData({ data,
       bounds: {
         startTime: 0,
         endTime: duration
       },
       visible: {
--- a/devtools/client/performance/views/details-waterfall.js
+++ b/devtools/client/performance/views/details-waterfall.js
@@ -1,18 +1,19 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
-/* globals window */
+/* globals window, DetailsSubview */
 "use strict";
 
-const WATERFALL_RESIZE_EVENTS_DRAIN = 100; // ms
 const MARKER_DETAILS_WIDTH = 200;
+// Units are in milliseconds.
+const WATERFALL_RESIZE_EVENTS_DRAIN = 100;
 
 /**
  * Waterfall view containing the timeline markers, controlled by DetailsView.
  */
 var WaterfallView = Heritage.extend(DetailsSubview, {
 
   // Smallest unit of time between two markers. Larger by 10x^3 than Number.EPSILON.
   MARKER_EPSILON: 0.000000000001,
@@ -20,17 +21,18 @@ var WaterfallView = Heritage.extend(Deta
   observedPrefs: [
     "hidden-markers"
   ],
 
   rerenderPrefs: [
     "hidden-markers"
   ],
 
-  rangeChangeDebounceTime: 75, // ms
+  // Units are in milliseconds.
+  rangeChangeDebounceTime: 75,
 
   /**
    * Sets up the view with event binding.
    */
   initialize: function () {
     DetailsSubview.initialize.call(this);
 
     this._cache = new WeakMap();
@@ -41,17 +43,18 @@ var WaterfallView = Heritage.extend(Deta
     this._onShowAllocations = this._onShowAllocations.bind(this);
     this._hiddenMarkers = PerformanceController.getPref("hidden-markers");
 
     this.headerContainer = $("#waterfall-header");
     this.breakdownContainer = $("#waterfall-breakdown");
     this.detailsContainer = $("#waterfall-details");
     this.detailsSplitter = $("#waterfall-view > splitter");
 
-    this.details = new MarkerDetails($("#waterfall-details"), $("#waterfall-view > splitter"));
+    this.details = new MarkerDetails($("#waterfall-details"),
+                                     $("#waterfall-view > splitter"));
     this.details.hidden = true;
 
     this.details.on("resize", this._onResize);
     this.details.on("view-source", this._onViewSource);
     this.details.on("show-allocations", this._onShowAllocations);
     window.addEventListener("resize", this._onResize);
 
     // TODO bug 1167093 save the previously set width, and ensure minimum width
--- a/devtools/client/performance/views/details.js
+++ b/devtools/client/performance/views/details.js
@@ -1,13 +1,15 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* globals WaterfallView, JsCallTreeView, JsFlameGraphView, MemoryCallTreeView,
+           MemoryFlameGraphView, Iterator */
 "use strict";
 
 /**
  * Details view containing call trees, flamegraphs and markers waterfall.
  * Manages subviews and toggles visibility between them.
  */
 var DetailsView = {
   /**
@@ -53,42 +55,47 @@ var DetailsView = {
     this.setAvailableViews = this.setAvailableViews.bind(this);
 
     for (let button of $$("toolbarbutton[data-view]", this.toolbar)) {
       button.addEventListener("command", this._onViewToggle);
     }
 
     yield this.setAvailableViews();
 
-    PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStoppedOrSelected);
-    PerformanceController.on(EVENTS.RECORDING_SELECTED, this._onRecordingStoppedOrSelected);
+    PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE,
+                             this._onRecordingStoppedOrSelected);
+    PerformanceController.on(EVENTS.RECORDING_SELECTED,
+                             this._onRecordingStoppedOrSelected);
     PerformanceController.on(EVENTS.PREF_CHANGED, this.setAvailableViews);
   }),
 
   /**
    * Unbinds events, destroys subviews.
    */
   destroy: Task.async(function* () {
     for (let button of $$("toolbarbutton[data-view]", this.toolbar)) {
       button.removeEventListener("command", this._onViewToggle);
     }
 
-    for (let [_, component] of Iterator(this.components)) {
+    for (let [, component] of Iterator(this.components)) {
       component.initialized && (yield component.view.destroy());
     }
 
-    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStoppedOrSelected);
-    PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingStoppedOrSelected);
+    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE,
+                              this._onRecordingStoppedOrSelected);
+    PerformanceController.off(EVENTS.RECORDING_SELECTED,
+                              this._onRecordingStoppedOrSelected);
     PerformanceController.off(EVENTS.PREF_CHANGED, this.setAvailableViews);
   }),
 
   /**
    * Sets the possible views based off of recording features and server actor support
    * by hiding/showing the buttons that select them and going to default view
-   * if currently selected. Called when a preference changes in `devtools.performance.ui.`.
+   * if currently selected. Called when a preference changes in
+   * `devtools.performance.ui.`.
    */
   setAvailableViews: Task.async(function* () {
     let recording = PerformanceController.getCurrentRecording();
     let isCompleted = recording && recording.isCompleted();
     let invalidCurrentView = false;
 
     for (let [name, { view }] of Iterator(this.components)) {
       let isSupported = this._isViewSupported(name);
@@ -170,21 +177,20 @@ var DetailsView = {
    * and preferences enabled.
    */
   selectDefaultView: function () {
     // We want the waterfall to be default view in almost all cases, except when
     // timeline actor isn't supported, or we have markers disabled (which should only
     // occur temporarily via bug 1156499
     if (this._isViewSupported("waterfall")) {
       return this.selectView("waterfall");
-    } else {
-      // The JS CallTree should always be supported since the profiler
-      // actor is as old as the world.
-      return this.selectView("js-calltree");
     }
+    // The JS CallTree should always be supported since the profiler
+    // actor is as old as the world.
+    return this.selectView("js-calltree");
   },
 
   /**
    * Checks if the provided view is currently selected.
    *
    * @param object viewObject
    * @return boolean
    */
--- a/devtools/client/performance/views/overview.js
+++ b/devtools/client/performance/views/overview.js
@@ -1,21 +1,24 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
+/* globals Iterator */
 "use strict";
 
 // No sense updating the overview more often than receiving data from the
 // backend. Make sure this isn't lower than DEFAULT_TIMELINE_DATA_PULL_TIMEOUT
 // in devtools/server/actors/timeline.js
-const OVERVIEW_UPDATE_INTERVAL = 200; // ms
-const FRAMERATE_GRAPH_LOW_RES_INTERVAL = 100; // ms
-const FRAMERATE_GRAPH_HIGH_RES_INTERVAL = 16; // ms
+
+// The following units are in milliseconds.
+const OVERVIEW_UPDATE_INTERVAL = 200;
+const FRAMERATE_GRAPH_LOW_RES_INTERVAL = 100;
+const FRAMERATE_GRAPH_HIGH_RES_INTERVAL = 16;
 const GRAPH_REQUIREMENTS = {
   timeline: {
     features: ["withMarkers"]
   },
   framerate: {
     features: ["withTicks"]
   },
   memory: {
@@ -73,17 +76,18 @@ var OverviewView = {
   },
 
   /**
    * Unbinds events.
    */
   destroy: Task.async(function* () {
     PerformanceController.off(EVENTS.PREF_CHANGED, this._onPrefChanged);
     PerformanceController.off(EVENTS.THEME_CHANGED, this._onThemeChanged);
-    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
+    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE,
+                              this._onRecordingStateChange);
     PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
     this.graphs.off("selecting", this._onGraphSelecting);
     this.graphs.off("rendered", this._onGraphRendered);
     yield this.graphs.destroy();
   }),
 
   /**
    * Returns true if any of the overview graphs have mouse dragging active,
@@ -201,31 +205,32 @@ var OverviewView = {
     if (this.isRendering()) {
       this._timeoutId = setTimeout(this._onRecordingTick, this.OVERVIEW_UPDATE_INTERVAL);
     }
   },
 
   /**
    * Called when recording state changes.
    */
-  _onRecordingStateChange: OverviewViewOnStateChange(Task.async(function* (_, state, recording) {
-    if (state !== "recording-stopped") {
-      return;
-    }
-    // Check to see if the recording that just stopped is the current recording.
-    // If it is, render the high-res graphs. For manual recordings, it will also
-    // be the current recording, but profiles generated by `console.profile` can stop
-    // while having another profile selected -- in this case, OverviewView should keep
-    // rendering the current recording.
-    if (recording !== PerformanceController.getCurrentRecording()) {
-      return;
-    }
-    this.render(FRAMERATE_GRAPH_HIGH_RES_INTERVAL);
-    yield this._checkSelection(recording);
-  })),
+  _onRecordingStateChange: OverviewViewOnStateChange(Task.async(
+    function* (_, state, recording) {
+      if (state !== "recording-stopped") {
+        return;
+      }
+      // Check to see if the recording that just stopped is the current recording.
+      // If it is, render the high-res graphs. For manual recordings, it will also
+      // be the current recording, but profiles generated by `console.profile` can stop
+      // while having another profile selected -- in this case, OverviewView should keep
+      // rendering the current recording.
+      if (recording !== PerformanceController.getCurrentRecording()) {
+        return;
+      }
+      this.render(FRAMERATE_GRAPH_HIGH_RES_INTERVAL);
+      yield this._checkSelection(recording);
+    })),
 
   /**
    * Called when a new recording is selected.
    */
   _onRecordingSelected: OverviewViewOnStateChange(Task.async(function* (_, recording) {
     this._setGraphVisibilityFromRecordingFeatures(recording);
 
     // If this recording is complete, render the high res graph
@@ -297,30 +302,31 @@ var OverviewView = {
    * Called whenever a preference in `devtools.performance.ui.` changes.
    * Does not care about the enabling of memory/framerate graphs,
    * because those will set values on a recording model, and
    * the graphs will render based on the existence.
    */
   _onPrefChanged: Task.async(function* (_, prefName, prefValue) {
     switch (prefName) {
       case "hidden-markers": {
-        let graph;
-        if (graph = yield this.graphs.isAvailable("timeline")) {
+        let graph = yield this.graphs.isAvailable("timeline");
+        if (graph) {
           let filter = PerformanceController.getPref("hidden-markers");
           graph.setFilter(filter);
           graph.refresh({ force: true });
         }
         break;
       }
     }
   }),
 
   _setGraphVisibilityFromRecordingFeatures: function (recording) {
     for (let [graphName, requirements] of Iterator(GRAPH_REQUIREMENTS)) {
-      this.graphs.enable(graphName, PerformanceController.isFeatureSupported(requirements.features));
+      this.graphs.enable(graphName,
+                         PerformanceController.isFeatureSupported(requirements.features));
     }
   },
 
   /**
    * Fetch the multiprocess status and if e10s is not currently on, disable
    * realtime rendering.
    *
    * @return {boolean}
@@ -393,19 +399,18 @@ function OverviewViewOnStateChange(fn) {
 
     // If realtime rendering is not enabed (e10s not on), then
     // show the disabled message, or the full graphs if the recording is completed
     if (!this.isRealtimeRenderingEnabled()) {
       if (recording.isRecording()) {
         this._hideGraphsPanel();
         // Abort, as we do not want to change polling status.
         return;
-      } else {
-        this._showGraphsPanel(recording);
       }
+      this._showGraphsPanel(recording);
     }
 
     if (this.isRendering() && !currentRecording.isRecording()) {
       this._stopPolling();
     } else if (currentRecording.isRecording() && !this.isRendering()) {
       this._startPolling();
     }
 
--- a/devtools/client/performance/views/recordings.js
+++ b/devtools/client/performance/views/recordings.js
@@ -31,17 +31,18 @@ var RecordingsView = Heritage.extend(Wid
     PerformanceController.on(EVENTS.RECORDING_EXPORTED, this._onRecordingExported);
     this.widget.addEventListener("select", this._onSelect, false);
   },
 
   /**
    * Destruction function, called when the tool is closed.
    */
   destroy: function () {
-    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
+    PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE,
+                              this._onRecordingStateChange);
     PerformanceController.off(EVENTS.RECORDING_ADDED, this._onNewRecording);
     PerformanceController.off(EVENTS.RECORDING_DELETED, this._onRecordingDeleted);
     PerformanceController.off(EVENTS.RECORDING_EXPORTED, this._onRecordingExported);
     this.widget.removeEventListener("select", this._onSelect, false);
   },
 
   /**
    * Adds an empty recording to this container.
@@ -186,17 +187,18 @@ var RecordingsView = Heritage.extend(Wid
     this.emit(EVENTS.UI_RECORDING_SELECTED, model);
   }),
 
   /**
    * The click listener for the "save" button of each item in this container.
    */
   _onSaveButtonClick: function (e) {
     let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    fp.init(window, L10N.getStr("recordingsList.saveDialogTitle"), Ci.nsIFilePicker.modeSave);
+    fp.init(window, L10N.getStr("recordingsList.saveDialogTitle"),
+            Ci.nsIFilePicker.modeSave);
     fp.appendFilter(L10N.getStr("recordingsList.saveDialogJSONFilter"), "*.json");
     fp.appendFilter(L10N.getStr("recordingsList.saveDialogAllFilter"), "*.*");
     fp.defaultString = "profile.json";
 
     fp.open({ done: result => {
       if (result == Ci.nsIFilePicker.returnCancel) {
         return;
       }
--- a/devtools/client/performance/views/toolbar.js
+++ b/devtools/client/performance/views/toolbar.js
@@ -1,14 +1,14 @@
 /* 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-globals-from ../performance-controller.js */
 /* import-globals-from ../performance-view.js */
-/* globals document */
+/* globals document, Iterator */
 "use strict";
 
 /**
  * View handler for toolbar events (mostly option toggling and triggering)
  */
 var ToolbarView = {
   /**
    * Sets up the view with event binding.
@@ -30,43 +30,48 @@ var ToolbarView = {
     let experimentalEnabled = PerformanceController.getOption("experimental");
     this._toggleExperimentalUI(experimentalEnabled);
 
     yield this.optionsView.initialize();
     this.optionsView.on("pref-changed", this._onPrefChanged);
 
     this._buildMarkersFilterPopup();
     this._updateHiddenMarkersPopup();
-    $("#performance-filter-menupopup").addEventListener("popupshowing", this._onFilterPopupShowing);
-    $("#performance-filter-menupopup").addEventListener("popuphiding", this._onFilterPopupHiding);
+    $("#performance-filter-menupopup").addEventListener("popupshowing",
+                                                        this._onFilterPopupShowing);
+    $("#performance-filter-menupopup").addEventListener("popuphiding",
+                                                        this._onFilterPopupHiding);
   }),
 
   /**
    * Unbinds events and cleans up view.
    */
   destroy: function () {
-    $("#performance-filter-menupopup").removeEventListener("popupshowing", this._onFilterPopupShowing);
-    $("#performance-filter-menupopup").removeEventListener("popuphiding", this._onFilterPopupHiding);
+    $("#performance-filter-menupopup").removeEventListener("popupshowing",
+                                                           this._onFilterPopupShowing);
+    $("#performance-filter-menupopup").removeEventListener("popuphiding",
+                                                           this._onFilterPopupHiding);
     this._popup = null;
 
     this.optionsView.off("pref-changed", this._onPrefChanged);
     this.optionsView.destroy();
   },
 
   /**
    * Creates the timeline markers filter popup.
    */
   _buildMarkersFilterPopup: function () {
     for (let [markerName, markerDetails] of Iterator(TIMELINE_BLUEPRINT)) {
       let menuitem = document.createElement("menuitem");
       menuitem.setAttribute("closemenu", "none");
       menuitem.setAttribute("type", "checkbox");
       menuitem.setAttribute("align", "center");
       menuitem.setAttribute("flex", "1");
-      menuitem.setAttribute("label", MarkerBlueprintUtils.getMarkerGenericName(markerName));
+      menuitem.setAttribute("label",
+                            MarkerBlueprintUtils.getMarkerGenericName(markerName));
       menuitem.setAttribute("marker-type", markerName);
       menuitem.className = `marker-color-${markerDetails.colorName}`;
 
       menuitem.addEventListener("command", this._onHiddenMarkersChanged);
 
       $("#performance-filter-menupopup").appendChild(menuitem);
     }
   },
@@ -91,17 +96,18 @@ var ToolbarView = {
    * Fired when `devtools.performance.ui.experimental` is changed, or
    * during init. Toggles the visibility of experimental performance tool options
    * in the UI options.
    *
    * Sets or removes "experimental-enabled" on the menu and main elements,
    * hiding or showing all elements with class "experimental-option".
    *
    * TODO re-enable "#option-enable-memory" permanently once stable in bug 1163350
-   * TODO re-enable "#option-show-jit-optimizations" permanently once stable in bug 1163351
+   * TODO re-enable "#option-show-jit-optimizations" permanently once stable in
+   *      bug 1163351
    *
    * @param {boolean} isEnabled
    */
   _toggleExperimentalUI: function (isEnabled) {
     if (isEnabled) {
       $(".theme-body").classList.add("experimental-enabled");
       this._popup.classList.add("experimental-enabled");
     } else {
@@ -123,17 +129,18 @@ var ToolbarView = {
   _onFilterPopupHiding: function () {
     $("#filter-button").removeAttribute("open");
   },
 
   /**
    * Fired when a menu item in the markers filter popup is checked or unchecked.
    */
   _onHiddenMarkersChanged: function () {
-    let checkedMenuItems = $$("#performance-filter-menupopup menuitem[marker-type]:not([checked])");
+    let checkedMenuItems =
+      $$("#performance-filter-menupopup menuitem[marker-type]:not([checked])");
     let hiddenMarkers = Array.map(checkedMenuItems, e => e.getAttribute("marker-type"));
     PerformanceController.setPref("hidden-markers", hiddenMarkers);
   },
 
   /**
    * Fired when a preference changes in the underlying OptionsView.
    * Propogated by the PerformanceController.
    */
--- a/devtools/client/shared/components/reps/array.js
+++ b/devtools/client/shared/components/reps/array.js
@@ -27,17 +27,17 @@ define(function (require, exports, modul
     getTitle: function (object, context) {
       return "[" + object.length + "]";
     },
 
     arrayIterator: function (array, max) {
       let items = [];
       let delim;
 
-      for (let i = 0; i < array.length && i <= max; i++) {
+      for (let i = 0; i < array.length && i < max; i++) {
         try {
           let value = array[i];
 
           delim = (i == array.length - 1 ? "" : ", ");
 
           if (value === array) {
             items.push(Reference({
               key: i,
@@ -56,24 +56,22 @@ define(function (require, exports, modul
             object: exc,
             delim: delim,
             key: i
           }));
         }
       }
 
       if (array.length > max) {
-        items.pop();
-
         let objectLink = this.props.objectLink || DOM.span;
         items.push(Caption({
           key: "more",
           object: objectLink({
             object: this.props.object
-          }, "more…")
+          }, (array.length - max) + " more…")
         }));
       }
 
       return items;
     },
 
     /**
      * Returns true if the passed object is an array with additional (custom)
--- a/devtools/client/shared/components/reps/grip-array.js
+++ b/devtools/client/shared/components/reps/grip-array.js
@@ -54,17 +54,17 @@ define(function (require, exports, modul
       let array = grip.preview.items;
       if (!array) {
         return items;
       }
 
       let delim;
       let provider = this.props.provider;
 
-      for (let i = 0; i < array.length && i <= max; i++) {
+      for (let i = 0; i < array.length && i < max; i++) {
         try {
           let itemGrip = array[i];
           let value = provider ? provider.getValue(itemGrip) : itemGrip;
 
           delim = (i == array.length - 1 ? "" : ", ");
 
           if (value === array) {
             items.push(Reference({
@@ -84,23 +84,22 @@ define(function (require, exports, modul
             object: exc,
             delim: delim,
             key: i}
           )));
         }
       }
 
       if (array.length > max) {
-        items.pop();
         let objectLink = this.props.objectLink || span;
         items.push(Caption({
           key: "more",
           object: objectLink({
             object: this.props.object
-          }, "more…")
+          }, (grip.preview.length - max) + " more…")
         }));
       }
 
       return items;
     },
 
     render: function () {
       let mode = this.props.mode || "short";
--- a/devtools/client/shared/components/reps/grip.js
+++ b/devtools/client/shared/components/reps/grip.js
@@ -74,17 +74,17 @@ define(function (require, exports, modul
       if (props.length < object.ownPropertyLength) {
         // There are some undisplayed props. Then display "more...".
         let objectLink = this.props.objectLink || span;
 
         props.push(Caption({
           key: "more",
           object: objectLink({
             object: object
-          }, "more…")
+          }, ((object ? object.ownPropertyLength : 0) - max) + " more…")
         }));
       } else if (props.length > 0) {
         // Remove the last comma.
         // NOTE: do not change comp._store.props directly to update a property,
         // it should be re-rendered or cloned with changed props
         let last = props.length - 1;
         props[last] = React.cloneElement(props[last], {
           delim: ""
--- a/devtools/client/shared/components/reps/object.js
+++ b/devtools/client/shared/components/reps/object.js
@@ -73,17 +73,17 @@ define(function (require, exports, modul
       if (props.length > max) {
         props.pop();
         let objectLink = this.props.objectLink || span;
 
         props.push(Caption({
           key: "more",
           object: objectLink({
             object: object
-          }, "more…")
+          }, (Object.keys(object).length - max) + " more…")
         }));
       } else if (props.length > 0) {
         // Remove the last comma.
         props[props.length - 1] = React.cloneElement(
           props[props.length - 1], { delim: "" });
       }
 
       return props;
--- a/devtools/client/shared/components/test/mochitest/test_reps_array.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_array.html
@@ -102,17 +102,17 @@ window.onload = Task.async(function* () 
       }
     ];
 
     testRepRenderModes(modeTests, "testMaxProps", componentUnderTest, stub);
   }
 
   function testMoreThanShortMaxProps() {
     const stub = Array(maxLength.short + 1).fill("foo");
-    const defaultShortOutput = `[${Array(maxLength.short).fill("\"foo\"").join(", ")}, more…]`;
+    const defaultShortOutput = `[${Array(maxLength.short).fill("\"foo\"").join(", ")}, 1 more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultShortOutput,
       },
       {
         mode: "tiny",
@@ -128,18 +128,18 @@ window.onload = Task.async(function* () 
       }
     ];
 
     testRepRenderModes(modeTests, "testMoreThanMaxProps", componentUnderTest, stub);
   }
 
   function testMoreThanLongMaxProps() {
     const stub = Array(maxLength.long + 1).fill("foo");
-    const defaultShortOutput = `[${Array(maxLength.short).fill("\"foo\"").join(", ")}, more…]`;
-    const defaultLongOutput = `[${Array(maxLength.long).fill("\"foo\"").join(", ")}, more…]`;
+    const defaultShortOutput = `[${Array(maxLength.short).fill("\"foo\"").join(", ")}, ${maxLength.long + 1 - maxLength.short} more…]`;
+    const defaultLongOutput = `[${Array(maxLength.long).fill("\"foo\"").join(", ")}, 1 more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultShortOutput,
       },
       {
         mode: "tiny",
@@ -189,17 +189,17 @@ window.onload = Task.async(function* () 
     let stub = [
       {
         p1: "s1",
         p2: ["a1", "a2", "a3"],
         p3: "s3",
         p4: "s4"
       }
     ];
-    const defaultOutput = `[Object{p1: "s1", p3: "s3", p4: "s4", more…}]`;
+    const defaultOutput = `[Object{p1: "s1", p3: "s3", p4: "s4", 1 more…}]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -222,17 +222,17 @@ window.onload = Task.async(function* () 
     let stub = [
       "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
       "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
     ];
 
     const defaultOutput = `["a", "b", "c", "d", "e", "f", "g", "h", "i", "j",` +
                           ` "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",` +
                           ` "u", "v", "w", "x", "y", "z"]`;
-    const shortOutput = `["a", "b", "c", more…]`;
+    const shortOutput = `["a", "b", "c", 23 more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: shortOutput,
       },
       {
         mode: "tiny",
--- a/devtools/client/shared/components/test/mochitest/test_reps_grip-array.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_grip-array.html
@@ -101,17 +101,17 @@ window.onload = Task.async(function* () 
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testMoreThanShortMaxProps() {
     // Test array = `["test string"…] //4 items`
     const testName = "testMoreThanShortMaxProps";
 
-    const defaultOutput = `Array[${Array(maxLength.short).fill("\"test string\"").join(", ")}, more…]`;
+    const defaultOutput = `Array[${Array(maxLength.short).fill("\"test string\"").join(", ")}, 1 more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -129,18 +129,18 @@ window.onload = Task.async(function* () 
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testMoreThanLongMaxProps() {
     // Test array = `["test string"…] //301 items`
     const testName = "testMoreThanLongMaxProps";
 
-    const defaultShortOutput = `Array[${Array(maxLength.short).fill("\"test string\"").join(", ")}, more…]`;
-    const defaultLongOutput = `Array[${Array(maxLength.long).fill("\"test string\"").join(", ")}, more…]`;
+    const defaultShortOutput = `Array[${Array(maxLength.short).fill("\"test string\"").join(", ")}, ${maxLength.long + 1 - maxLength.short} more…]`;
+    const defaultLongOutput = `Array[${Array(maxLength.long).fill("\"test string\"").join(", ")}, 1 more…]`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultShortOutput,
       },
       {
         mode: "tiny",
--- a/devtools/client/shared/components/test/mochitest/test_reps_grip.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_grip.html
@@ -95,29 +95,29 @@ window.onload = Task.async(function* () 
         expectedOutput: defaultOutput,
       }
     ];
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testMoreThanMaxProps() {
-    // Test object = `{p0: "0", p1: "1", p2: "2", …, p101: "101"}`
+    // Test object = `{p0: "0", p1: "1", p2: "2", …, p100: "100"}`
     const testName = "testMoreThanMaxProps";
 
-    const defaultOutput = `Object {p0: "0", p1: "1", p2: "2", more…}`;
+    const defaultOutput = `Object {p0: "0", p1: "1", p2: "2", 98 more…}`;
 
     // Generate string with 100 properties, which is the max limit
     // for 'long' mode.
     let props = "";
     for (let i = 0; i < 100; i++) {
       props += "p" + i + ": \"" + i + "\", ";
     }
 
-    const longOutput = `Object {${props}more…}`;
+    const longOutput = `Object {${props}1 more…}`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -135,17 +135,17 @@ window.onload = Task.async(function* () 
 
     testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
   }
 
   function testUninterestingProps() {
     // Test object: `{a: undefined, b: undefined, c: "c", d: 1}`
     // @TODO This is not how we actually want the preview to be output.
     // See https://bugzilla.mozilla.org/show_bug.cgi?id=1276376
-    const expectedOutput = `Object {a: undefined, b: undefined, c: "c", more…}`;
+    const expectedOutput = `Object {a: undefined, b: undefined, c: "c", 1 more…}`;
   }
 
   function testNestedObject() {
     // Test object: `{objProp: {id: 1}, strProp: "test string"}`
     const testName = "testNestedObject";
 
     const defaultOutput = `Object {objProp: Object, strProp: "test string"}`;
 
--- a/devtools/client/shared/components/test/mochitest/test_reps_object.html
+++ b/devtools/client/shared/components/test/mochitest/test_reps_object.html
@@ -96,17 +96,17 @@ window.onload = Task.async(function* () 
     testRepRenderModes(modeTests, "testMaxProps", componentUnderTest, stub);
   }
 
   function testMoreThanMaxProps() {
     let stub = {};
     for (let i = 0; i<100; i++) {
       stub[`p${i}`] = i
     }
-    const defaultOutput = `Object{p0: 0, p1: 1, p2: 2, more…}`;
+    const defaultOutput = `Object{p0: 0, p1: 1, p2: 2, 97 more…}`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
@@ -122,17 +122,17 @@ window.onload = Task.async(function* () 
       }
     ];
 
     testRepRenderModes(modeTests, "testMoreThanMaxProps", componentUnderTest, stub);
   }
 
   function testUninterestingProps() {
     const stub = {a:undefined, b:undefined, c:"c", d:0};
-    const defaultOutput = `Object{c: "c", d: 0, a: undefined, more…}`;
+    const defaultOutput = `Object{c: "c", d: 0, a: undefined, 1 more…}`;
 
     const modeTests = [
       {
         mode: undefined,
         expectedOutput: defaultOutput,
       },
       {
         mode: "tiny",
--- a/devtools/client/shared/widgets/tooltip/TooltipToggle.js
+++ b/devtools/client/shared/widgets/tooltip/TooltipToggle.js
@@ -19,17 +19,17 @@ const DEFAULT_TOGGLE_DELAY = 50;
  * provided to the start() method to know whether or not the node being
  * hovered over should indeed receive the tooltip.
  */
 function TooltipToggle(tooltip) {
   this.tooltip = tooltip;
   this.win = tooltip.doc.defaultView;
 
   this._onMouseMove = this._onMouseMove.bind(this);
-  this._onMouseLeave = this._onMouseLeave.bind(this);
+  this._onMouseOut = this._onMouseOut.bind(this);
 
   this._onTooltipMouseOver = this._onTooltipMouseOver.bind(this);
   this._onTooltipMouseOut = this._onTooltipMouseOut.bind(this);
 }
 
 module.exports.TooltipToggle = TooltipToggle;
 
 TooltipToggle.prototype = {
@@ -79,17 +79,17 @@ TooltipToggle.prototype = {
     }
 
     this._baseNode = baseNode;
     this._targetNodeCb = targetNodeCb || (() => true);
     this._toggleDelay = toggleDelay;
     this._interactive = interactive;
 
     baseNode.addEventListener("mousemove", this._onMouseMove);
-    baseNode.addEventListener("mouseleave", this._onMouseLeave);
+    baseNode.addEventListener("mouseout", this._onMouseOut);
 
     if (this._interactive) {
       this.tooltip.container.addEventListener("mouseover", this._onTooltipMouseOver);
       this.tooltip.container.addEventListener("mouseout", this._onTooltipMouseOut);
     }
   },
 
   /**
@@ -100,17 +100,17 @@ TooltipToggle.prototype = {
   stop: function () {
     this.win.clearTimeout(this.toggleTimer);
 
     if (!this._baseNode) {
       return;
     }
 
     this._baseNode.removeEventListener("mousemove", this._onMouseMove);
-    this._baseNode.removeEventListener("mouseleave", this._onMouseLeave);
+    this._baseNode.removeEventListener("mouseout", this._onMouseOut);
 
     if (this._interactive) {
       this.tooltip.container.removeEventListener("mouseover", this._onTooltipMouseOver);
       this.tooltip.container.removeEventListener("mouseout", this._onTooltipMouseOut);
     }
 
     this._baseNode = null;
     this._targetNodeCb = null;
@@ -147,17 +147,22 @@ TooltipToggle.prototype = {
     let res = yield this._targetNodeCb(target, this.tooltip);
     if (res) {
       return res.nodeName ? res : target;
     }
 
     return null;
   }),
 
-  _onMouseLeave: function () {
+  _onMouseOut: function (event) {
+    // Only hide the tooltip if the mouse leaves baseNode.
+    if (event && this._baseNode && !this._baseNode.contains(event.relatedTarget)) {
+      return;
+    }
+
     this._lastHovered = null;
     this.win.clearTimeout(this.toggleTimer);
     this.toggleTimer = this.win.setTimeout(() => {
       this.tooltip.hide();
     }, this._toggleDelay);
   },
 
   _onTooltipMouseOver() {
--- a/devtools/client/themes/images/add.svg
+++ b/devtools/client/themes/images/add.svg
@@ -1,6 +1,6 @@
 <!-- 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/. -->
 <svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
-  <path d="M8.5 8.5V14a.5.5 0 1 1-1 0V8.5H2a.5.5 0 0 1 0-1h5.5V2a.5.5 0 0 1 1 0v5.5H14a.5.5 0 1 1 0 1H8.5z"/>
+  <path d="M8 8v5.5c0 .276-.224.5-.5.5s-.5-.224-.5-.5V8H1.5c-.276 0-.5-.224-.5-.5s.224-.5.5-.5H7V1.5c0-.276.224-.5.5-.5s.5.224.5.5V7h5.5c.276 0 .5.224.5.5s-.224.5-.5.5H8z"/>
 </svg>
--- a/devtools/server/actors/addon.js
+++ b/devtools/server/actors/addon.js
@@ -105,16 +105,25 @@ BrowserAddonActor.prototype = {
   },
 
   setOptions: function BAA_setOptions(aOptions) {
     if ("global" in aOptions) {
       this._global = aOptions.global;
     }
   },
 
+  onInstalled: function BAA_updateAddonWrapper(aAddon) {
+    if (aAddon.id != this._addon.id) {
+      return;
+    }
+
+    // Update the AddonManager's addon object on reload/update.
+    this._addon = aAddon;
+  },
+
   onDisabled: function BAA_onDisabled(aAddon) {
     if (aAddon != this._addon) {
       return;
     }
 
     this._global = null;
   },
 
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -2288,21 +2288,16 @@ Object.defineProperty(BrowserAddonList.p
         "onListChanged property may only be set to 'null' or a function");
     }
     this._onListChanged = v;
     this._adjustListener();
   }
 });
 
 BrowserAddonList.prototype.onInstalled = function (addon) {
-  if (this._actorByAddonId.get(addon.id)) {
-    // When an add-on gets upgraded or reloaded, it will not be uninstalled
-    // so this step is necessary to clear the cache.
-    this._actorByAddonId.delete(addon.id);
-  }
   this._notifyListChanged();
   this._adjustListener();
 };
 
 BrowserAddonList.prototype.onUninstalled = function (addon) {
   this._actorByAddonId.delete(addon.id);
   this._notifyListChanged();
   this._adjustListener();
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/unit/addons/web-extension-upgrade/manifest.json
@@ -0,0 +1,10 @@
+{
+  "manifest_version": 2,
+  "name": "Test Addons Actor Upgrade",
+  "version": "1.0",
+  "applications": {
+    "gecko": {
+      "id": "test-addons-actor@mozilla.org"
+    }
+  }
+}
--- a/devtools/server/tests/unit/test_addon_reload.js
+++ b/devtools/server/tests/unit/test_addon_reload.js
@@ -62,10 +62,37 @@ add_task(function* testReloadExitedAddon
   installedAddon2.uninstall();
   const [uninstalledAddon] = yield onUninstalled;
 
   // Try to re-list all add-ons after a reload.
   // This was throwing an exception because of the exited actor.
   const newAddonActor = yield findAddonInRootList(client, installedAddon.id);
   equal(newAddonActor.id, addonActor.id);
 
+  // The actor id should be the same after the reload
+  equal(newAddonActor.actor, addonActor.actor);
+
+  const onAddonListChanged = new Promise((resolve) => {
+    client.addListener("addonListChanged", function listener() {
+      client.removeListener("addonListChanged", listener);
+      resolve();
+    });
+  });
+
+  // Install an upgrade version of the first add-on.
+  const addonUpgradeFile = getSupportFile("addons/web-extension-upgrade");
+  const upgradedAddon = yield AddonManager.installTemporaryAddon(
+    addonUpgradeFile);
+
+  // Waiting for addonListChanged unsolicited event
+  yield onAddonListChanged;
+
+  // re-list all add-ons after an upgrade.
+  const upgradedAddonActor = yield findAddonInRootList(client, upgradedAddon.id);
+  equal(upgradedAddonActor.id, addonActor.id);
+  // The actor id should be the same after the upgrade.
+  equal(upgradedAddonActor.actor, addonActor.actor);
+
+  // The addon metadata has been updated.
+  equal(upgradedAddonActor.name, "Test Addons Actor Upgrade");
+
   yield close(client);
 });
--- a/devtools/server/tests/unit/xpcshell.ini
+++ b/devtools/server/tests/unit/xpcshell.ini
@@ -26,16 +26,17 @@ support-files =
   setBreakpoint-on-column-with-no-offsets-in-gcd-script.js
   setBreakpoint-on-line.js
   setBreakpoint-on-line-in-gcd-script.js
   setBreakpoint-on-line-with-multiple-offsets.js
   setBreakpoint-on-line-with-multiple-statements.js
   setBreakpoint-on-line-with-no-offsets.js
   setBreakpoint-on-line-with-no-offsets-in-gcd-script.js
   addons/web-extension/manifest.json
+  addons/web-extension-upgrade/manifest.json
   addons/web-extension2/manifest.json
 
 [test_addon_reload.js]
 [test_addons_actor.js]
 [test_animation_name.js]
 [test_animation_type.js]
 [test_actor-registry-actor.js]
 [test_nesting-01.js]
--- a/dom/base/nsHostObjectURI.cpp
+++ b/dom/base/nsHostObjectURI.cpp
@@ -156,21 +156,22 @@ nsHostObjectURI::SetScheme(const nsACStr
   // with a different protocol handler that doesn't expect us to be carrying
   // around a principal with nsIURIWithPrincipal.
   return NS_ERROR_FAILURE;
 }
 
 // nsIURI methods:
 nsresult
 nsHostObjectURI::CloneInternal(mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
+                               const nsACString& newRef,
                                nsIURI** aClone)
 {
   nsCOMPtr<nsIURI> simpleClone;
   nsresult rv =
-    mozilla::net::nsSimpleURI::CloneInternal(aRefHandlingMode, getter_AddRefs(simpleClone));
+    mozilla::net::nsSimpleURI::CloneInternal(aRefHandlingMode, newRef, getter_AddRefs(simpleClone));
   NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef DEBUG
   RefPtr<nsHostObjectURI> uriCheck;
   rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
   MOZ_ASSERT(NS_SUCCEEDED(rv) && uriCheck);
 #endif
 
--- a/dom/base/nsHostObjectURI.h
+++ b/dom/base/nsHostObjectURI.h
@@ -44,24 +44,30 @@ public:
   NS_DECL_NSISERIALIZABLE
   NS_DECL_NSICLASSINFO
   NS_DECL_NSIIPCSERIALIZABLEURI
 
   NS_IMETHOD SetScheme(const nsACString &aProtocol) override;
 
   // Override CloneInternal() and EqualsInternal()
   virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
+                                 const nsACString& newRef,
                                  nsIURI** aClone) override;
   virtual nsresult EqualsInternal(nsIURI* aOther,
                                   RefHandlingEnum aRefHandlingMode,
                                   bool* aResult) override;
 
   // Override StartClone to hand back a nsHostObjectURI
-  virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum /* unused */) override
-  { return new nsHostObjectURI(); }
+  virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
+                                                const nsACString& newRef) override
+  {
+    nsHostObjectURI* url = new nsHostObjectURI();
+    SetRefOnClone(url, refHandlingMode, newRef);
+    return url;
+  }
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
   RefPtr<mozilla::dom::BlobImpl> mBlobImpl;
 
 protected:
   virtual ~nsHostObjectURI() {}
 };
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -81,25 +81,23 @@ GetErrorMessage(void* aUserRef, const un
 }
 
 uint16_t
 GetErrorArgCount(const ErrNum aErrorNumber)
 {
   return GetErrorMessage(nullptr, aErrorNumber)->argCount;
 }
 
-bool
-ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...)
+void
+binding_detail::ThrowErrorMessage(JSContext* aCx, const unsigned aErrorNumber, ...)
 {
   va_list ap;
   va_start(ap, aErrorNumber);
-  JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr,
-                         static_cast<const unsigned>(aErrorNumber), ap);
+  JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr, aErrorNumber, ap);
   va_end(ap);
-  return false;
 }
 
 bool
 ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
                  bool aSecurityError, const char* aInterfaceName)
 {
   NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName);
   // This should only be called for DOM methods/getters/setters, which
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -62,18 +62,28 @@ uint16_t constexpr ErrorFormatNumArgs[] 
 #include "mozilla/dom/Errors.msg"
 #undef MSG_DEF
 };
 #endif
 
 uint16_t
 GetErrorArgCount(const ErrNum aErrorNumber);
 
-bool
-ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
+namespace binding_detail {
+void ThrowErrorMessage(JSContext* aCx, const unsigned aErrorNumber, ...);
+} // namespace binding_detail
+
+template<typename... Ts>
+inline bool
+ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, Ts&&... aArgs)
+{
+  binding_detail::ThrowErrorMessage(aCx, static_cast<const unsigned>(aErrorNumber),
+                                    mozilla::Forward<Ts>(aArgs)...);
+  return false;
+}
 
 struct StringArrayAppender
 {
   static void Append(nsTArray<nsString>& aArgs, uint16_t aCount)
   {
     MOZ_RELEASE_ASSERT(aCount == 0, "Must give at least as many string arguments as are required by the ErrNum.");
   }
 
--- a/dom/bindings/GenerateCSS2PropertiesWebIDL.py
+++ b/dom/bindings/GenerateCSS2PropertiesWebIDL.py
@@ -42,29 +42,29 @@ def generate(output, idlFilename, prepro
         if not prop.startswith("Moz"):
             prop = prop[0].lower() + prop[1:]
         props += generateLine(prop, extendedAttrs)
 
         # Per spec, what's actually supposed to happen here is that we're supposed
         # to have properties for:
         #
         # 1) Each supported CSS property name, camelCased.
-        # 2) Each supported name that contains dashes but doesn't start with a
-        #    dash, without any changes to the name.
+        # 2) Each supported name that contains or starts with dashes,
+        #    without any changes to the name.
         # 3) cssFloat
         #
         # Note that "float" will cause a property called "float" to exist due to (1)
         # in that list.
         #
         # In practice, cssFloat is the only case in which "name" doesn't contain
         # "-" but also doesn't match "prop".  So the above generatePropLine() call
         # covered (3) and all of (1) except "float".  If we now output attributes
-        # for all the cases where "name" doesn't match "prop" and "name" doesn't
-        # start with "-", that will cover "float" and (2).
-        if prop != name and name[0] != "-":
+        # for all the cases where "name" doesn't match "prop", that will cover
+        # "float" and (2).
+        if prop != name:
             extendedAttrs.append('BinaryName="%s"' % prop)
             # Throw in a '_' before the attribute name, because some of these
             # property names collide with IDL reserved words.
             props += generateLine("_" + name, extendedAttrs)
 
 
     idlFile = open(idlFilename, "r")
     idlTemplate = idlFile.read()
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -281,18 +281,20 @@ WebGLContext::DestroyResourcesAndContext
     mFakeBlack_2D_0001       = nullptr;
     mFakeBlack_CubeMap_0000  = nullptr;
     mFakeBlack_CubeMap_0001  = nullptr;
     mFakeBlack_3D_0000       = nullptr;
     mFakeBlack_3D_0001       = nullptr;
     mFakeBlack_2D_Array_0000 = nullptr;
     mFakeBlack_2D_Array_0001 = nullptr;
 
-    if (mFakeVertexAttrib0BufferObject)
+    if (mFakeVertexAttrib0BufferObject) {
         gl->fDeleteBuffers(1, &mFakeVertexAttrib0BufferObject);
+        mFakeVertexAttrib0BufferObject = 0;
+    }
 
     // disable all extensions except "WEBGL_lose_context". see bug #927969
     // spec: http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
     for (size_t i = 0; i < size_t(WebGLExtensionID::Max); ++i) {
         WebGLExtensionID extension = WebGLExtensionID(i);
 
         if (!IsExtensionEnabled(extension) || (extension == WebGLExtensionID::WEBGL_lose_context))
             continue;
@@ -302,17 +304,19 @@ WebGLContext::DestroyResourcesAndContext
     }
 
     // We just got rid of everything, so the context had better
     // have been going away.
     if (GLContext::ShouldSpew()) {
         printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
     }
 
-    gl = nullptr;
+    MOZ_ASSERT(gl);
+    mGL_OnlyClearInDestroyResourcesAndContext = nullptr;
+    MOZ_ASSERT(!gl);
 }
 
 void
 WebGLContext::Invalidate()
 {
     if (!mCanvasElement)
         return;
 
@@ -665,32 +669,37 @@ WebGLContext::CreateAndInitGLWith(FnCrea
                                   const gl::SurfaceCaps& baseCaps,
                                   gl::CreateContextFlags flags,
                                   std::vector<FailureReason>* const out_failReasons)
 {
     std::queue<gl::SurfaceCaps> fallbackCaps;
     PopulateCapFallbackQueue(baseCaps, &fallbackCaps);
 
     MOZ_RELEASE_ASSERT(!gl, "GFX: Already have a context.");
-    gl = nullptr;
+    RefPtr<gl::GLContext> potentialGL;
     while (!fallbackCaps.empty()) {
         const gl::SurfaceCaps& caps = fallbackCaps.front();
-        gl = fnCreateGL(caps, flags, this, out_failReasons);
-        if (gl)
+        potentialGL = fnCreateGL(caps, flags, this, out_failReasons);
+        if (potentialGL)
             break;
 
         fallbackCaps.pop();
     }
-    if (!gl)
+    if (!potentialGL)
         return false;
 
     FailureReason reason;
+
+    mGL_OnlyClearInDestroyResourcesAndContext = potentialGL;
+    MOZ_RELEASE_ASSERT(gl);
     if (!InitAndValidateGL(&reason)) {
+        DestroyResourcesAndContext();
+        MOZ_RELEASE_ASSERT(!gl);
+
         // The fail reason here should be specific enough for now.
-        gl = nullptr;
         out_failReasons->push_back(reason);
         return false;
     }
 
     return true;
 }
 
 bool
@@ -987,30 +996,32 @@ WebGLContext::SetDimensions(int32_t sign
         ThrowEvent_WebGLContextCreationError(text);
         return NS_ERROR_FAILURE;
     }
     MOZ_ASSERT(gl);
     MOZ_ASSERT_IF(mOptions.alpha, gl->Caps().alpha);
 
     if (mOptions.failIfMajorPerformanceCaveat) {
         if (gl->IsWARP()) {
-            gl = nullptr;
+            DestroyResourcesAndContext();
+            MOZ_ASSERT(!gl);
 
             failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_WARP");
             const nsLiteralCString text("failIfMajorPerformanceCaveat: Driver is not"
                                         " hardware-accelerated.");
             ThrowEvent_WebGLContextCreationError(text);
             return NS_ERROR_FAILURE;
         }
 
 #ifdef XP_WIN
         if (gl->GetContextType() == gl::GLContextType::WGL &&
             !gl::sWGLLib.HasDXInterop2())
         {
-            gl = nullptr;
+            DestroyResourcesAndContext();
+            MOZ_ASSERT(!gl);
 
             failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DXGL_INTEROP2");
             const nsLiteralCString text("Caveat: WGL without DXGLInterop2.");
             ThrowEvent_WebGLContextCreationError(text);
             return NS_ERROR_FAILURE;
         }
 #endif
     }
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1388,33 +1388,37 @@ protected:
 
     GLenum mPixelStore_ColorspaceConversion;
     bool mPixelStore_FlipY;
     bool mPixelStore_PremultiplyAlpha;
 
     ////////////////////////////////////
     class FakeBlackTexture {
     public:
+        static UniquePtr<FakeBlackTexture> Create(gl::GLContext* gl,
+                                                  TexTarget target,
+                                                  FakeBlackType type);
         gl::GLContext* const mGL;
         const GLuint mGLName;
 
-        FakeBlackTexture(gl::GLContext* gl, TexTarget target, FakeBlackType type);
         ~FakeBlackTexture();
+    protected:
+        explicit FakeBlackTexture(gl::GLContext* gl);
     };
 
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_0001;
     UniquePtr<FakeBlackTexture> mFakeBlack_CubeMap_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_CubeMap_0001;
     UniquePtr<FakeBlackTexture> mFakeBlack_3D_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_3D_0001;
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0000;
     UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0001;
 
-    void BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
+    bool BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
 
     ////////////////////////////////////
 
     // Generic Vertex Attributes
     UniquePtr<GLenum[]> mVertexAttribType;
     GLfloat mVertexAttrib0Vector[4];
     GLfloat mFakeVertexAttrib0BufferObjectVector[4];
     size_t mFakeVertexAttrib0BufferObjectSize;
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -131,17 +131,23 @@ ScopedResolveTexturesForDraw::ScopedReso
                                          funcName);
                 *out_error = true;
                 return;
             }
 
             if (fakeBlack == FakeBlackType::None)
                 continue;
 
-            mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack);
+            if (!mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack)) {
+                mWebGL->ErrorOutOfMemory("%s: Failed to create fake black texture.",
+                                         funcName);
+                *out_error = true;
+                return;
+            }
+
             mRebindRequests.push_back({texUnit, tex});
         }
     }
 
     *out_error = false;
 }
 
 ScopedResolveTexturesForDraw::~ScopedResolveTexturesForDraw()
@@ -154,17 +160,17 @@ ScopedResolveTexturesForDraw::~ScopedRes
     for (const auto& itr : mRebindRequests) {
         gl->fActiveTexture(LOCAL_GL_TEXTURE0 + itr.texUnit);
         gl->fBindTexture(itr.tex->Target().get(), itr.tex->mGLName);
     }
 
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mWebGL->mActiveTexture);
 }
 
-void
+bool
 WebGLContext::BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack)
 {
     MOZ_ASSERT(fakeBlack == FakeBlackType::RGBA0000 ||
                fakeBlack == FakeBlackType::RGBA0001);
 
     const auto fnGetSlot = [this, target, fakeBlack]() -> UniquePtr<FakeBlackTexture>*
     {
         switch (fakeBlack) {
@@ -193,22 +199,26 @@ WebGLContext::BindFakeBlack(uint32_t tex
 
     UniquePtr<FakeBlackTexture>* slot = fnGetSlot();
     if (!slot) {
         MOZ_CRASH("GFX: fnGetSlot failed.");
     }
     UniquePtr<FakeBlackTexture>& fakeBlackTex = *slot;
 
     if (!fakeBlackTex) {
-        fakeBlackTex.reset(new FakeBlackTexture(gl, target, fakeBlack));
+        fakeBlackTex = FakeBlackTexture::Create(gl, target, fakeBlack);
+        if (!fakeBlackTex) {
+            return false;
+        }
     }
 
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + texUnit);
     gl->fBindTexture(target.get(), fakeBlackTex->mGLName);
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
+    return true;
 }
 
 ////////////////////////////////////////
 
 bool
 WebGLContext::DrawInstanced_check(const char* info)
 {
     MOZ_ASSERT(IsWebGL2() ||
@@ -868,97 +878,74 @@ static GLuint
 CreateGLTexture(gl::GLContext* gl)
 {
     MOZ_ASSERT(gl->IsCurrent());
     GLuint ret = 0;
     gl->fGenTextures(1, &ret);
     return ret;
 }
 
-WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget target,
-                                                 FakeBlackType type)
-    : mGL(gl)
-    , mGLName(CreateGLTexture(gl))
+UniquePtr<WebGLContext::FakeBlackTexture>
+WebGLContext::FakeBlackTexture::Create(gl::GLContext* gl, TexTarget target,
+                                       FakeBlackType type)
 {
     GLenum texFormat;
     switch (type) {
     case FakeBlackType::RGBA0000:
         texFormat = LOCAL_GL_RGBA;
         break;
 
     case FakeBlackType::RGBA0001:
         texFormat = LOCAL_GL_RGB;
         break;
 
     default:
         MOZ_CRASH("GFX: bad type");
     }
 
-    gl::ScopedBindTexture scopedBind(mGL, mGLName, target.get());
+    UniquePtr<FakeBlackTexture> result(new FakeBlackTexture(gl));
+    gl::ScopedBindTexture scopedBind(gl, result->mGLName, target.get());
 
-    mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
-    mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
+    gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
+    gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
 
     // We allocate our zeros on the heap, and we overallocate (16 bytes instead of 4) to
     // minimize the risk of running into a driver bug in texImage2D, as it is a bit
     // unusual maybe to create 1x1 textures, and the stack may not have the alignment that
     // TexImage2D expects.
 
     const webgl::DriverUnpackInfo dui = {texFormat, texFormat, LOCAL_GL_UNSIGNED_BYTE};
     UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation.
 
     MOZ_ASSERT(gl->IsCurrent());
-    auto logANGLEError = [](GLenum source, GLenum type, GLuint id, GLenum severity,
-                            GLsizei length, const GLchar* message, const GLvoid* userParam)
-    {
-        gfxCriticalNote << message;
-    };
-
-    if (gl->IsANGLE()) {
-      gl->fEnable(LOCAL_GL_DEBUG_OUTPUT);
-      gl->fDebugMessageCallback(logANGLEError, nullptr);
-      gl->fDebugMessageControl(LOCAL_GL_DONT_CARE,
-                               LOCAL_GL_DONT_CARE,
-                               LOCAL_GL_DONT_CARE,
-                               0, nullptr,
-                               true);
-    }
 
     if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
         for (int i = 0; i < 6; ++i) {
             const TexImageTarget curTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
-            const GLenum error = DoTexImage(mGL, curTarget.get(), 0, &dui, 1, 1, 1,
+            const GLenum error = DoTexImage(gl, curTarget.get(), 0, &dui, 1, 1, 1,
                                             zeros.get());
             if (error) {
-                const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
-                                           "for `curTarget`: 0x%04x, "
-                                           "`dui`: {0x%04x, 0x%04x, 0x%04x}.",
-                                           error, curTarget.get(), dui.internalFormat,
-                                           dui.unpackFormat, dui.unpackType);
-                gfxCriticalError() << text.BeginReading();
-                MOZ_CRASH("GFX: Unexpected error during cube map FakeBlack creation.");
+                return nullptr;
             }
         }
     } else {
-        const GLenum error = DoTexImage(mGL, target.get(), 0, &dui, 1, 1, 1,
+        const GLenum error = DoTexImage(gl, target.get(), 0, &dui, 1, 1, 1,
                                         zeros.get());
         if (error) {
-            const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
-                                       "for `target`: 0x%04x, "
-                                       "`dui`: {0x%04x, 0x%04x, 0x%04x}.",
-                                       error, target.get(), dui.internalFormat,
-                                       dui.unpackFormat, dui.unpackType);
-            gfxCriticalError() << text.BeginReading();
-            MOZ_CRASH("GFX: Unexpected error during FakeBlack creation.");
+            return nullptr;
         }
     }
 
-    if (gl->IsANGLE()) {
-      gl->fDisable(LOCAL_GL_DEBUG_OUTPUT);
-    }
+    return result;
+}
+
+WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl)
+    : mGL(gl)
+    , mGLName(CreateGLTexture(gl))
+{
 }
 
 WebGLContext::FakeBlackTexture::~FakeBlackTexture()
 {
     mGL->MakeCurrent();
     mGL->fDeleteTextures(1, &mGLName);
 }
 
--- a/dom/canvas/WebGLContextUnchecked.cpp
+++ b/dom/canvas/WebGLContextUnchecked.cpp
@@ -7,18 +7,19 @@
 #include "WebGLContextUnchecked.h"
 
 #include "GLContext.h"
 #include "WebGLBuffer.h"
 #include "WebGLSampler.h"
 
 namespace mozilla {
 
-WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* gl)
-    : gl(gl)
+WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* _gl)
+    : mGL_OnlyClearInDestroyResourcesAndContext(_gl)
+    , gl(mGL_OnlyClearInDestroyResourcesAndContext) // const reference
 { }
 
 
 // -----------------------------------------------------------------------------
 // Buffer Objects
 
 void
 WebGLContextUnchecked::BindBuffer(GLenum target, WebGLBuffer* buffer)
--- a/dom/canvas/WebGLContextUnchecked.h
+++ b/dom/canvas/WebGLContextUnchecked.h
@@ -34,15 +34,21 @@ public:
     GLint   GetSamplerParameteriv(WebGLSampler* sampler, GLenum pname);
     GLfloat GetSamplerParameterfv(WebGLSampler* sampler, GLenum pname);
 
     void SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param);
     void SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const GLint* param);
     void SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param);
     void SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const GLfloat* param);
 
-protected: // data
-    RefPtr<gl::GLContext> gl;
+protected:
+    // We've had issues in the past with nulling `gl` without actually releasing
+    // all of our resources. This construction ensures that we are aware that we
+    // should only null `gl` in DestroyResourcesAndContext.
+    RefPtr<gl::GLContext> mGL_OnlyClearInDestroyResourcesAndContext;
+public:
+    // Grab a const reference so we can see changes, but can't make changes.
+    const decltype(mGL_OnlyClearInDestroyResourcesAndContext)& gl;
 };
 
 } // namespace mozilla
 
 #endif // !WEBGLCONTEXTUNCHECKED_H
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -735,17 +735,17 @@ TextTrackManager::TimeMarchesOn()
   for (uint32_t i = 0; i < eventList.Length(); ++i) {
     NS_DispatchToMainThread(eventList[i].forget());
   }
 
   // Step 16.
   for (uint32_t i = 0; i < affectedTracks.Length(); ++i) {
     TextTrack* ttrack = affectedTracks[i];
     if (ttrack) {
-      ttrack->DispatchTrustedEvent(NS_LITERAL_STRING("cuechange"));
+      ttrack->DispatchAsyncTrustedEvent(NS_LITERAL_STRING("cuechange"));
       HTMLTrackElement* trackElement = ttrack->GetTrackElement();
       if (trackElement) {
         trackElement->DispatchTrackRunnable(NS_LITERAL_STRING("cuechange"));
       }
     }
   }
 
   mLastTimeMarchesOnCalled = currentPlaybackTime;
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -1357,28 +1357,31 @@ nsJSURI::Deserialize(const mozilla::ipc:
     } else {
         mBaseURI = nullptr;
     }
     return true;
 }
 
 // nsSimpleURI methods:
 /* virtual */ mozilla::net::nsSimpleURI*
-nsJSURI::StartClone(mozilla::net::nsSimpleURI::RefHandlingEnum /* ignored */)
+nsJSURI::StartClone(mozilla::net::nsSimpleURI::RefHandlingEnum refHandlingMode,
+                    const nsACString& newRef)
 {
     nsCOMPtr<nsIURI> baseClone;
     if (mBaseURI) {
       // Note: We preserve ref on *base* URI, regardless of ref handling mode.
       nsresult rv = mBaseURI->Clone(getter_AddRefs(baseClone));
       if (NS_FAILED(rv)) {
         return nullptr;
       }
     }
 
-    return new nsJSURI(baseClone);
+    nsJSURI* url = new nsJSURI(baseClone);
+    SetRefOnClone(url, refHandlingMode, newRef);
+    return url;
 }
 
 /* virtual */ nsresult
 nsJSURI::EqualsInternal(nsIURI* aOther,
                         mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
                         bool* aResult)
 {
     NS_ENSURE_ARG_POINTER(aOther);
--- a/dom/jsurl/nsJSProtocolHandler.h
+++ b/dom/jsurl/nsJSProtocolHandler.h
@@ -74,17 +74,18 @@ public:
     nsIURI* GetBaseURI() const
     {
         return mBaseURI;
     }
 
     NS_DECL_ISUPPORTS_INHERITED
 
     // nsIURI overrides
-    virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode) override;
+    virtual mozilla::net::nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
+                                                  const nsACString& newRef) override;
 
     // nsISerializable overrides
     NS_IMETHOD Read(nsIObjectInputStream* aStream) override;
     NS_IMETHOD Write(nsIObjectOutputStream* aStream) override;
 
     // nsIIPCSerializableURI overrides
     NS_DECL_NSIIPCSERIALIZABLEURI
 
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -313,10 +313,21 @@ TextTrack::GetLanguage(nsAString& aLangu
 {
   if (mTrackElement) {
     mTrackElement->GetSrclang(aLanguage);
   } else {
     aLanguage = mLanguage;
   }
 }
 
+void
+TextTrack::DispatchAsyncTrustedEvent(const nsString& aEventName)
+{
+  RefPtr<TextTrack> self = this;
+  NS_DispatchToMainThread(
+    NS_NewRunnableFunction([self, aEventName]() {
+      self->DispatchTrustedEvent(aEventName);
+    })
+  );
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/TextTrack.h
+++ b/dom/media/TextTrack.h
@@ -111,16 +111,18 @@ public:
   TextTrackSource GetTextTrackSource() {
     return mTextTrackSource;
   }
 
   void SetCuesInactive();
 
   void NotifyCueUpdated(TextTrackCue *aCue);
 
+  void DispatchAsyncTrustedEvent(const nsString& aEventName);
+
 private:
   ~TextTrack();
 
   RefPtr<TextTrackList> mTextTrackList;
 
   TextTrackKind mKind;
   nsString mLabel;
   nsString mLanguage;
--- a/dom/media/eme/EMEUtils.cpp
+++ b/dom/media/eme/EMEUtils.cpp
@@ -143,9 +143,15 @@ KeySystemToGMPName(const nsAString& aKey
   }
   if (aKeySystem.EqualsLiteral("com.widevine.alpha")) {
     return NS_LITERAL_STRING("gmp-widevinecdm");
   }
   MOZ_ASSERT(false, "We should only call this for known GMPs");
   return EmptyString();
 }
 
+bool
+IsClearkeyKeySystem(const nsAString& aKeySystem)
+{
+  return aKeySystem.EqualsLiteral("org.w3.clearkey");
+}
+
 } // namespace mozilla
--- a/dom/media/eme/EMEUtils.h
+++ b/dom/media/eme/EMEUtils.h
@@ -97,11 +97,14 @@ struct ArrayData {
 //
 // Only call this on a properly initialized ArrayBufferViewOrArrayBuffer.
 ArrayData
 GetArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView);
 
 nsString
 KeySystemToGMPName(const nsAString& aKeySystem);
 
+bool
+IsClearkeyKeySystem(const nsAString& aKeySystem);
+
 } // namespace mozilla
 
 #endif // EME_LOG_H_
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -263,29 +263,25 @@ EnsureMinCDMVersion(mozIGeckoMediaPlugin
 
 /* static */
 MediaKeySystemStatus
 MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
                                          int32_t aMinCdmVersion,
                                          nsACString& aOutMessage,
                                          nsACString& aOutCdmVersion)
 {
-  MOZ_ASSERT(MediaPrefs::EMEEnabled());
+  MOZ_ASSERT(MediaPrefs::EMEEnabled() || IsClearkeyKeySystem(aKeySystem));
   nsCOMPtr<mozIGeckoMediaPluginService> mps =
     do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   if (NS_WARN_IF(!mps)) {
     aOutMessage = NS_LITERAL_CSTRING("Failed to get GMP service");
     return MediaKeySystemStatus::Error;
   }
 
   if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
-    if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
-      aOutMessage = NS_LITERAL_CSTRING("ClearKey was disabled");
-      return MediaKeySystemStatus::Cdm_disabled;
-    }
     return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, aOutMessage, aOutCdmVersion);
   }
 
   if (Preferences::GetBool("media.gmp-eme-adobe.visible", false)) {
     if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
       if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
         aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
         return MediaKeySystemStatus::Cdm_disabled;
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ b/dom/media/eme/MediaKeySystemAccessManager.cpp
@@ -107,18 +107,20 @@ MediaKeySystemAccessManager::Request(Det
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
                           NS_LITERAL_CSTRING("Key system string is invalid,"
                                              " or key system is unsupported"));
     diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
                                           aKeySystem, false, __func__);
     return;
   }
 
-  if (!MediaPrefs::EMEEnabled()) {
+  if (!MediaPrefs::EMEEnabled() && !IsClearkeyKeySystem(aKeySystem)) {
     // EME disabled by user, send notification to chrome so UI can inform user.
+    // Clearkey is allowed even when EME is disabled because we want the pref
+    // "media.eme.enabled" only taking effect on proprietary DRMs.
     MediaKeySystemAccess::NotifyObservers(mWindow,
                                           aKeySystem,
                                           MediaKeySystemStatus::Api_disabled);
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
                           NS_LITERAL_CSTRING("EME has been preffed off"));
     diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
                                           aKeySystem, false, __func__);
     return;
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp
@@ -3,27 +3,31 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WidevineVideoDecoder.h"
 
 #include "mp4_demuxer/AnnexB.h"
 #include "WidevineUtils.h"
 #include "WidevineVideoFrame.h"
+#include "mozilla/Move.h"
 
 using namespace cdm;
 
 namespace mozilla {
 
 WidevineVideoDecoder::WidevineVideoDecoder(GMPVideoHost* aVideoHost,
                                            RefPtr<CDMWrapper> aCDMWrapper)
   : mVideoHost(aVideoHost)
   , mCDMWrapper(Move(aCDMWrapper))
   , mExtraData(new MediaByteBuffer())
   , mSentInput(false)
+  , mReturnOutputCallDepth(0)
+  , mDrainPending(false)
+  , mResetInProgress(false)
 {
   // Expect to start with a CDM wrapper, will release it in DecodingComplete().
   MOZ_ASSERT(mCDMWrapper);
   Log("WidevineVideoDecoder created this=%p", this);
 
   // Corresponding Release is in DecodingComplete().
   AddRef();
 }
@@ -77,16 +81,18 @@ WidevineVideoDecoder::InitDecode(const G
 
 void
 WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
                              bool aMissingFrames,
                              const uint8_t* aCodecSpecificInfo,
                              uint32_t aCodecSpecificInfoLength,
                              int64_t aRenderTimeMs)
 {
+  // We should not be given new input if a drain has been initiated
+  MOZ_ASSERT(!mDrainPending);
   // We may not get the same out of the CDM decoder as we put in, and there
   // may be some latency, i.e. we may need to input (say) 30 frames before
   // we receive output. So we need to store the durations of the frames input,
   // and retrieve them on output.
   mFrameDurations[aInputFrame->TimeStamp()] = aInputFrame->Duration();
 
   mSentInput = true;
   InputBuffer sample;
@@ -119,121 +125,247 @@ WidevineVideoDecoder::Decode(GMPVideoEnc
   aInputFrame = nullptr;
 
   if (rv == kSuccess) {
     if (!ReturnOutput(frame)) {
       Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
       mCallback->Error(GMPDecodeErr);
       return;
     }
-    mCallback->InputDataExhausted();
+    // A reset should only be started at most at level mReturnOutputCallDepth 1,
+    // and if it's started it should be finished by that call by the time
+    // the it returns, so it should always be false by this point.
+    MOZ_ASSERT(!mResetInProgress);
+    // Only request more data if we don't have pending samples.
+    if (mFrameAllocationQueue.empty()) {
+      MOZ_ASSERT(mCDMWrapper);
+      mCallback->InputDataExhausted();
+    }
   } else if (rv == kNeedMoreData) {
+    MOZ_ASSERT(mCDMWrapper);
     mCallback->InputDataExhausted();
   } else {
     mCallback->Error(ToGMPErr(rv));
   }
+  // Finish a drain if pending and we have no pending ReturnOutput calls on the stack.
+  if (mDrainPending && mReturnOutputCallDepth == 0) {
+    Drain();
+  }
 }
 
+// Util class to assist with counting mReturnOutputCallDepth.
+class CounterHelper {
+public:
+  // RAII, increment counter
+  explicit CounterHelper(int32_t& counter)
+    : mCounter(counter)
+  {
+    mCounter++;
+  }
+
+  // RAII, decrement counter
+  ~CounterHelper()
+  {
+    mCounter--;
+  }
+
+private:
+  int32_t& mCounter;
+};
+
+// Util class to make sure GMP frames are freed. Holds a GMPVideoi420Frame*
+// and will destroy it when the helper is destroyed unless the held frame
+// if forgotten with ForgetFrame.
+class FrameDestroyerHelper {
+public:
+  explicit FrameDestroyerHelper(GMPVideoi420Frame*& frame)
+    : frame(frame)
+  {
+  }
+
+  // RAII, destroy frame if held.
+  ~FrameDestroyerHelper()
+  {
+    if (frame) {
+      frame->Destroy();
+    }
+    frame = nullptr;
+  }
+
+  // Forget the frame without destroying it.
+  void ForgetFrame()
+  {
+    frame = nullptr;
+  }
+
+private:
+  GMPVideoi420Frame* frame;
+};
+
+
+// Special handing is needed around ReturnOutput as it spins the IPC message
+// queue when creating an empty frame and can end up with reentrant calls into
+// the class methods.
 bool
 WidevineVideoDecoder::ReturnOutput(WidevineVideoFrame& aCDMFrame)
 {
-  GMPVideoFrame* f = nullptr;
-  auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
-  if (GMP_FAILED(err) || !f) {
-    Log("Failed to create i420 frame!\n");
-    return false;
+  MOZ_ASSERT(mReturnOutputCallDepth >= 0);
+  CounterHelper counterHelper(mReturnOutputCallDepth);
+  mFrameAllocationQueue.push_back(Move(aCDMFrame));
+  if (mReturnOutputCallDepth > 1) {
+    // In a reentrant call.
+    return true;
   }
-  auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
-  Size size = aCDMFrame.Size();
-  const int32_t yStride = aCDMFrame.Stride(VideoFrame::kYPlane);
-  const int32_t uStride = aCDMFrame.Stride(VideoFrame::kUPlane);
-  const int32_t vStride = aCDMFrame.Stride(VideoFrame::kVPlane);
-  const int32_t halfHeight = size.height / 2;
-  err = gmpFrame->CreateEmptyFrame(size.width,
-                                   size.height,
-                                   yStride,
-                                   uStride,
-                                   vStride);
-  ENSURE_GMP_SUCCESS(err, false);
-
-  err = gmpFrame->SetWidth(size.width);
-  ENSURE_GMP_SUCCESS(err, false);
-
-  err = gmpFrame->SetHeight(size.height);
-  ENSURE_GMP_SUCCESS(err, false);
+  while (!mFrameAllocationQueue.empty()) {
+    MOZ_ASSERT(mReturnOutputCallDepth == 1);
+    // If we're at call level 1 a reset should not have been started. A
+    // reset may be received during CreateEmptyFrame below, but we should not
+    // be in a reset at this stage -- this would indicate receiving decode
+    // messages before completing our reset, which we should not.
+    MOZ_ASSERT(!mResetInProgress);
+    WidevineVideoFrame currentCDMFrame = Move(mFrameAllocationQueue.front());
+    mFrameAllocationQueue.pop_front();
+    GMPVideoFrame* f = nullptr;
+    auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
+    if (GMP_FAILED(err) || !f) {
+      Log("Failed to create i420 frame!\n");
+      return false;
+    }
+    auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
+    FrameDestroyerHelper frameDestroyerHelper(gmpFrame);
+    Size size = currentCDMFrame.Size();
+    const int32_t yStride = currentCDMFrame.Stride(VideoFrame::kYPlane);
+    const int32_t uStride = currentCDMFrame.Stride(VideoFrame::kUPlane);
+    const int32_t vStride = currentCDMFrame.Stride(VideoFrame::kVPlane);
+    const int32_t halfHeight = size.height / 2;
+    // This call can cause a shmem alloc, during this alloc other calls
+    // may be made to this class and placed on the stack. ***WARNING***:
+    // other IPC calls can happen during this call, resulting in calls
+    // being made to the CDM. After this call state can have changed,
+    // and should be reevaluated.
+    err = gmpFrame->CreateEmptyFrame(size.width,
+                                     size.height,
+                                     yStride,
+                                     uStride,
+                                     vStride);
+    // Assert possible reentrant calls or resets haven't altered level unexpectedly.
+    MOZ_ASSERT(mReturnOutputCallDepth == 1);
+    ENSURE_GMP_SUCCESS(err, false);
 
-  Buffer* buffer = aCDMFrame.FrameBuffer();
-  uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
-  ENSURE_TRUE(outBuffer != nullptr, false);
-  MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
-  memcpy(outBuffer,
-         buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kYPlane),
-         yStride * size.height);
+    // If a reset started we need to dump the current frame and complete the reset.
+    if (mResetInProgress) {
+      MOZ_ASSERT(mCDMWrapper);
+      MOZ_ASSERT(mFrameAllocationQueue.empty());
+      CompleteReset();
+      return true;
+    }
+
+    err = gmpFrame->SetWidth(size.width);
+    ENSURE_GMP_SUCCESS(err, false);
 
-  outBuffer = gmpFrame->Buffer(kGMPUPlane);
-  ENSURE_TRUE(outBuffer != nullptr, false);
-  MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
-  memcpy(outBuffer,
-         buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kUPlane),
-         uStride * halfHeight);
+    err = gmpFrame->SetHeight(size.height);
+    ENSURE_GMP_SUCCESS(err, false);
+
+    Buffer* buffer = currentCDMFrame.FrameBuffer();
+    uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
+    ENSURE_TRUE(outBuffer != nullptr, false);
+    MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
+    memcpy(outBuffer,
+           buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kYPlane),
+           yStride * size.height);
 
-  outBuffer = gmpFrame->Buffer(kGMPVPlane);
-  ENSURE_TRUE(outBuffer != nullptr, false);
-  MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
-  memcpy(outBuffer,
-         buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kVPlane),
-         vStride * halfHeight);
+    outBuffer = gmpFrame->Buffer(kGMPUPlane);
+    ENSURE_TRUE(outBuffer != nullptr, false);
+    MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
+    memcpy(outBuffer,
+           buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kUPlane),
+           uStride * halfHeight);
 
-  gmpFrame->SetTimestamp(aCDMFrame.Timestamp());
+    outBuffer = gmpFrame->Buffer(kGMPVPlane);
+    ENSURE_TRUE(outBuffer != nullptr, false);
+    MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
+    memcpy(outBuffer,
+           buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kVPlane),
+           vStride * halfHeight);
+
+    gmpFrame->SetTimestamp(currentCDMFrame.Timestamp());
 
-  auto d = mFrameDurations.find(aCDMFrame.Timestamp());
-  if (d != mFrameDurations.end()) {
-    gmpFrame->SetDuration(d->second);
-    mFrameDurations.erase(d);
+    auto d = mFrameDurations.find(currentCDMFrame.Timestamp());
+    if (d != mFrameDurations.end()) {
+      gmpFrame->SetDuration(d->second);
+      mFrameDurations.erase(d);
+    }
+
+    // Forget frame so it's not deleted, call back taking ownership.
+    frameDestroyerHelper.ForgetFrame();
+    mCallback->Decoded(gmpFrame);
   }
 
-  mCallback->Decoded(gmpFrame);
-
   return true;
 }
 
 void
 WidevineVideoDecoder::Reset()
 {
   Log("WidevineVideoDecoder::Reset() mSentInput=%d", mSentInput);
+  // We shouldn't reset if a drain is pending.
+  MOZ_ASSERT(!mDrainPending);
+  mResetInProgress = true;
   if (mSentInput) {
     CDM()->ResetDecoder(kStreamTypeVideo);
   }
+  // Remove queued frames, but do not reset mReturnOutputCallDepth, let the
+  // ReturnOutput calls unwind and decrement the counter as needed.
+  mFrameAllocationQueue.clear();
   mFrameDurations.clear();
+  // Only if no ReturnOutput calls are in progress can we complete, otherwise
+  // ReturnOutput needs to finalize the reset.
+  if (mReturnOutputCallDepth == 0) {
+    CompleteReset();
+  }
+}
+
+void
+WidevineVideoDecoder::CompleteReset()
+{
   mCallback->ResetComplete();
   mSentInput = false;
+  mResetInProgress = false;
 }
 
 void
 WidevineVideoDecoder::Drain()
 {
   Log("WidevineVideoDecoder::Drain()");
+  if (mReturnOutputCallDepth > 0) {
+    Log("Drain call is reentrant, postponing drain");
+    mDrainPending = true;
+    return;
+  }
 
   Status rv = kSuccess;
   while (rv == kSuccess) {
     WidevineVideoFrame frame;
     InputBuffer sample;
     Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame);
     Log("WidevineVideoDecoder::Drain();  DecryptAndDecodeFrame() rv=%d", rv);
     if (frame.Format() == kUnknownVideoFormat) {
       break;
     }
     if (rv == kSuccess) {
       if (!ReturnOutput(frame)) {
         Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
       }
     }
   }
+  // Shouldn't be reset while draining.
+  MOZ_ASSERT(!mResetInProgress);
 
   CDM()->ResetDecoder(kStreamTypeVideo);
+  mDrainPending = false;
   mCallback->DrainComplete();
 }
 
 void
 WidevineVideoDecoder::DecodingComplete()
 {
   Log("WidevineVideoDecoder::DecodingComplete()");
   if (mCDMWrapper) {
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
@@ -11,16 +11,17 @@
 #include "gmp-api/gmp-video-decode.h"
 #include "gmp-api/gmp-video-host.h"
 #include "MediaData.h"
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"
 #include "WidevineDecryptor.h"
 #include "WidevineVideoFrame.h"
 #include <map>
+#include <deque>
 
 namespace mozilla {
 
 class WidevineVideoDecoder : public GMPVideoDecoder {
 public:
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WidevineVideoDecoder)
 
@@ -47,21 +48,32 @@ private:
   cdm::ContentDecryptionModule_8* CDM() const {
     // CDM should only be accessed before 'DecodingComplete'.
     MOZ_ASSERT(mCDMWrapper);
     // CDMWrapper ensure the CDM is non-null, no need to check again.
     return mCDMWrapper->GetCDM();
   }
 
   bool ReturnOutput(WidevineVideoFrame& aFrame);
+  void CompleteReset();
 
   GMPVideoHost* mVideoHost;
   RefPtr<CDMWrapper> mCDMWrapper;
   RefPtr<MediaByteBuffer> mExtraData;
   RefPtr<MediaByteBuffer> mAnnexB;
   GMPVideoDecoderCallback* mCallback;
   std::map<uint64_t, uint64_t> mFrameDurations;
   bool mSentInput;
+  // Frames waiting on allocation
+  std::deque<WidevineVideoFrame> mFrameAllocationQueue;
+  // Number of calls of ReturnOutput currently in progress.
+  int32_t mReturnOutputCallDepth;
+  // If we're waiting to drain. Used to prevent drain completing while
+  // ReturnOutput calls are still on the stack.
+  bool mDrainPending;
+  // If a reset is being performed. Used to track if ReturnOutput should
+  // dump current frame.
+  bool mResetInProgress;
 };
 
 } // namespace mozilla
 
 #endif // WidevineVideoDecoder_h_
--- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
@@ -17,16 +17,29 @@ WidevineVideoFrame::WidevineVideoFrame()
   , mBuffer(nullptr)
   , mTimestamp(0)
 {
   Log("WidevineVideoFrame::WidevineVideoFrame() this=%p", this);
   memset(mPlaneOffsets, 0, sizeof(mPlaneOffsets));
   memset(mPlaneStrides, 0, sizeof(mPlaneStrides));
 }
 
+WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther)
+  : mFormat(aOther.mFormat)
+  , mSize(aOther.mSize)
+  , mBuffer(aOther.mBuffer)
+  , mTimestamp(aOther.mTimestamp)
+{
+  Log("WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) this=%p, other=%p",
+      this, &aOther);
+  memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets));
+  memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides));
+  aOther.mBuffer = nullptr;
+}
+
 WidevineVideoFrame::~WidevineVideoFrame()
 {
   if (mBuffer) {
     mBuffer->Destroy();
     mBuffer = nullptr;
   }
 }
 
--- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h
@@ -10,16 +10,17 @@
 #include "content_decryption_module.h"
 #include <vector>
 
 namespace mozilla {
 
 class WidevineVideoFrame : public cdm::VideoFrame {
 public:
   WidevineVideoFrame();
+  WidevineVideoFrame(WidevineVideoFrame&& other);
   ~WidevineVideoFrame();
 
   void SetFormat(cdm::VideoFormat aFormat) override;
   cdm::VideoFormat Format() const override;
 
   void SetSize(cdm::Size aSize) override;
   cdm::Size Size() const override;
 
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DXVA2Manager.h"
 #include <d3d11.h>
 #include "nsThreadUtils.h"
 #include "ImageContainer.h"
 #include "gfxWindowsPlatform.h"
 #include "D3D9SurfaceImage.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/D3D11ShareHandleImage.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/Telemetry.h"
 #include "MediaTelemetryConstants.h"
 #include "mfapi.h"
 #include "MediaPrefs.h"
 #include "MFTDecoder.h"
 #include "DriverCrashGuard.h"
@@ -627,17 +628,17 @@ D3D11DXVA2Manager::Init(nsACString& aFai
 
   gfx::D3D11VideoCrashGuard crashGuard;
   if (crashGuard.Crashed()) {
     NS_WARNING("DXVA2D3D11 crash detected");
     aFailureReason.AssignLiteral("DXVA2D3D11 crashes detected in the past");
     return E_FAIL;
   }
 
-  mDevice = gfxWindowsPlatform::GetPlatform()->CreateD3D11DecoderDevice();
+  mDevice = gfx::DeviceManagerD3D11::Get()->CreateDecoderDevice();
   if (!mDevice) {
     aFailureReason.AssignLiteral("Failed to create D3D11 device for decoder");
     return E_FAIL;
   }
 
   mDevice->GetImmediateContext(getter_AddRefs(mContext));
   if (!mContext) {
     aFailureReason.AssignLiteral("Failed to get immediate context for d3d11 device");
--- a/dom/media/test/test_eme_request_notifications.html
+++ b/dom/media/test/test_eme_request_notifications.html
@@ -57,46 +57,39 @@ function Test(test) {
       );
     });
   });
 }
 
 var tests = [
   {
     keySystem: CLEARKEY_KEYSYSTEM,
-    shouldPass: false,
-    expectedStatus: 'api-disabled',
-    prefs: [["media.eme.enabled", false], ["media.eme.clearkey.enabled", true]]
+    shouldPass: true,
+    expectedStatus: 'cdm-created',
+    prefs: [["media.eme.enabled", false]]
   },
   {
-    keySystem: CLEARKEY_KEYSYSTEM,
-    shouldPass: false,
-    expectedStatus: 'cdm-disabled',
-    prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", false]]
-  },
-  {
-    keySystem: CLEARKEY_KEYSYSTEM + '.10000' , // A stupendously high min CDM version, presumably not installed.
+    keySystem: CLEARKEY_KEYSYSTEM + '.10000', // A stupendously high min CDM version, presumably not installed.
     shouldPass: false,
     expectedStatus: 'cdm-insufficient-version',
-    prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
+    prefs: [["media.eme.enabled", true]]
   },
   {
     keySystem: CLEARKEY_KEYSYSTEM,
     shouldPass: true,
     expectedStatus: 'cdm-created',
-    prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
+    prefs: [["media.eme.enabled", true]]
   },
 ];
 
 SetupEMEPref(function() {
   tests.reduce(function(p,c,i,array) {
     return p.then(function() { return Test(c); });
   }, Promise.resolve()).then(SimpleTest.finish);
 });
 
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
 </body>
 </html>
-
--- a/dom/plugins/ipc/D3D11SurfaceHolder.cpp
+++ b/dom/plugins/ipc/D3D11SurfaceHolder.cpp
@@ -1,44 +1,44 @@
 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 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/. */
 #include "nsDebug.h"
 #include "D3D11SurfaceHolder.h"
-#include "gfxWindowsPlatform.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include <d3d11.h>
 
 namespace mozilla {
 namespace plugins {
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 D3D11SurfaceHolder::D3D11SurfaceHolder(ID3D11Texture2D* back,
                                        SurfaceFormat format,
                                        const IntSize& size)
- : mDevice11(gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice()),
+ : mDevice11(DeviceManagerD3D11::Get()->GetContentDevice()),
    mBack(back),
    mFormat(format),
    mSize(size)
 {
 }
 
 D3D11SurfaceHolder::~D3D11SurfaceHolder()
 {
 }
 
 bool
 D3D11SurfaceHolder::IsValid()
 {
   // If a TDR occurred, platform devices will be recreated.
-  if (gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice() != mDevice11) {
+  if (DeviceManagerD3D11::Get()->GetContentDevice() != mDevice11) {
      return false;
   }
   return true;
 }
 
 bool
 D3D11SurfaceHolder::CopyToTextureClient(TextureClient* aClient)
 {
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -40,16 +40,17 @@
 #include "GLContextProvider.h"
 #include "gfxPrefs.h"
 #include "LayersLogging.h"
 #include "mozilla/layers/TextureWrapperImage.h"
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #if defined(XP_WIN)
 # include "mozilla/layers/D3D11ShareHandleImage.h"
+# include "mozilla/gfx/DeviceManagerD3D11.h"
 # include "mozilla/layers/TextureD3D11.h"
 #endif
 
 #ifdef XP_MACOSX
 #include "MacIOSurfaceImage.h"
 #endif
 
 #if defined(OS_WIN)
@@ -395,17 +396,17 @@ bool
 PluginInstanceParent::AnswerNPN_GetValue_PreferredDXGIAdapter(DxgiAdapterDesc* aOutDesc)
 {
     PodZero(aOutDesc);
 #ifdef XP_WIN
     if (!AllowDirectDXGISurfaceDrawing()) {
         return false;
     }
 
-    ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
+    RefPtr<ID3D11Device> device = DeviceManagerD3D11::Get()->GetContentDevice();
     if (!device) {
         return false;
     }
 
     RefPtr<IDXGIDevice> dxgi;
     if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgi))) || !dxgi) {
         return false;
     }
@@ -676,17 +677,17 @@ PluginInstanceParent::RecvInitDXGISurfac
         return true;
     }
 
     ImageBridgeChild* forwarder = ImageBridgeChild::GetSingleton();
     if (!forwarder) {
         return true;
     }
 
-    RefPtr<ID3D11Device> d3d11 = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
+    RefPtr<ID3D11Device> d3d11 = DeviceManagerD3D11::Get()->GetContentDevice();
     if (!d3d11) {
         return true;
     }
 
     // Create the texture we'll give to the plugin process.
     HANDLE sharedHandle = 0;
     RefPtr<ID3D11Texture2D> back;
     {
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -190,17 +190,19 @@ nsXBLDocumentInfo::ReadPrototypeBindings
 {
   *aDocInfo = nullptr;
 
   nsAutoCString spec(kXBLCachePrefix);
   nsresult rv = PathifyURI(aURI, spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   StartupCache* startupCache = StartupCache::GetSingleton();
-  NS_ENSURE_TRUE(startupCache, NS_ERROR_FAILURE);
+  if (!startupCache) {
+    return NS_ERROR_FAILURE;
+  }
 
   UniquePtr<char[]> buf;
   uint32_t len;
   rv = startupCache->GetBuffer(spec.get(), &buf, &len);
   // GetBuffer will fail if the binding is not in the cache.
   if (NS_FAILED(rv))
     return rv;
 
@@ -257,17 +259,19 @@ nsXBLDocumentInfo::WritePrototypeBinding
   if (!nsContentUtils::IsSystemPrincipal(mDocument->NodePrincipal()))
     return NS_OK;
 
   nsAutoCString spec(kXBLCachePrefix);
   nsresult rv = PathifyURI(DocumentURI(), spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   StartupCache* startupCache = StartupCache::GetSingleton();
-  NS_ENSURE_TRUE(startupCache, rv);
+  if (!startupCache) {
+    return rv;
+  }
 
   nsCOMPtr<nsIObjectOutputStream> stream;
   nsCOMPtr<nsIStorageStream> storageStream;
   rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(stream),
                                            getter_AddRefs(storageStream),
                                            true);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/embedding/browser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/nsDocShellTreeOwner.cpp
@@ -1118,16 +1118,18 @@ NS_IMPL_ISUPPORTS(ChromeTooltipListener,
 
 ChromeTooltipListener::ChromeTooltipListener(nsWebBrowser* aInBrowser,
                                              nsIWebBrowserChrome* aInChrome)
   : mWebBrowser(aInBrowser)
   , mWebBrowserChrome(aInChrome)
   , mTooltipListenerInstalled(false)
   , mMouseClientX(0)
   , mMouseClientY(0)
+  , mMouseScreenX(0)
+  , mMouseScreenY(0)
   , mShowingTooltip(false)
   , mTooltipShownOnce(false)
 {
   mTooltipTextProvider = do_GetService(NS_TOOLTIPTEXTPROVIDER_CONTRACTID);
   if (!mTooltipTextProvider) {
     mTooltipTextProvider = do_GetService(NS_DEFAULTTOOLTIPTEXTPROVIDER_CONTRACTID);
   }
 }
--- a/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt
+++ b/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt
@@ -1,11 +1,11 @@
 en_US-mozilla Hunspell Dictionary
-Generated from SCOWL Version 2016.01.19
-Thu Jan 21 14:36:28 EST 2016
+Generated from SCOWL Version 2016.06.26
+Tue Jul 26 12:40:24 EDT 2016
 
 http://wordlist.sourceforge.net
 
 README file for English Hunspell dictionaries derived from SCOWL.
 
 These dictionaries are created using the speller/make-hunspell-dict
 script in SCOWL.
 
@@ -314,9 +314,9 @@ from the Ispell distribution they are un
   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
 
-Build Date: Thu Jan 21 14:36:28 EST 2016
+Build Date: Tue Jul 26 12:40:24 EDT 2016
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added
@@ -4952,17 +4952,16 @@ Viv's
 Vivi
 Vivi's
 Viviana
 Viviana's
 Vivie
 Vivie's
 Vivien
 Vivien's
-VoIP
 Vodafone
 Vodafone's
 Von
 Von's
 WASPs
 Wadsworth
 Wadsworth's
 Wainwright
@@ -5308,17 +5307,16 @@ cryptologist's
 cryptologists
 cryptosystem
 cryptosystems
 cul-de-sac
 cultivar's
 cyber
 cytokine
 cytokine's
-cytokines
 datasheet
 datasheet's
 datasheets
 decertification
 decertifications
 decertified
 decertifies
 decertify
@@ -5421,18 +5419,16 @@ grey's
 greybeard's
 greybeards
 greyed
 greyer
 greyest
 greying
 greyness's
 greys
-guestbook's
-guestbooks
 hentai
 hexane's
 hexanes
 hijabs
 hippopotami
 holdem
 iPods
 idolator
@@ -5503,17 +5499,16 @@ metadata's
 methoxy
 migrator
 migrator's
 migrators
 misandrist
 misandrist's
 misandrists
 misandry
-miscommunications
 misjudgement
 misjudgement's
 misjudgements
 mitigations
 modeller
 modeller's
 modellers
 modelling
@@ -5525,16 +5520,24 @@ motorsports
 multicast
 murine
 musculus
 namespace
 namespace's
 namespaces
 nano
 natively
+nave
+navely
+naver
+navest
+navety
+navety's
+navet
+navet's
 neurophysiology's
 neuroscience's
 neurosciences
 neuroscientist
 neuroscientist's
 neuroscientists
 newswires
 octopi
@@ -5543,34 +5546,32 @@ opposable
 opposer
 parallelization
 parallelization's
 parallelizations
 parallelize
 parallelized
 parallelizes
 parallelizing
-parkour
 permalink
 permalink's
 permalinks
 permittee
 phlebotomist
 phlebotomist's
 phlebotomists
 phlebotomize
 phlebotomized
 phlebotomizes
 phlebotomizing
 pho
 phosphorylate
 phosphorylated
 phosphorylates
 phosphorylating
-phosphorylation
 plaintext
 polynucleotide
 polynucleotide's
 polynucleotides
 polypeptide's
 poutine
 poutines
 prejudgement
@@ -5661,17 +5662,16 @@ signups
 snarkily
 sommelier
 sommelier's
 sommeliers
 spelt
 spick
 spicks
 spywares
-stent's
 substituent's
 substituents
 subsumptions
 syllabi
 synches
 synesthesia
 synesthete
 synesthetes
@@ -5721,17 +5721,16 @@ uncancelled
 uncheck
 unchecking
 unchecks
 undeliverables
 undesignated
 unironic
 unironically
 unlabelled
-username's
 validator
 validators
 vertebrata
 volcanological
 volcanologist
 volcanologist's
 volcanologists
 volcanology
@@ -5740,12 +5739,11 @@ weaponized
 weaponizes
 weaponizing
 webdesign
 webdesign's
 webdesigns
 whitepaper
 whitepaper's
 whitepapers
-widescreen's
 wildcard's
 wildcards
 wop's
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
@@ -1,11 +1,11 @@
 en_US-custom Hunspell Dictionary
-Generated from SCOWL Version 2016.01.19
-Thu Jan 21 14:36:27 EST 2016
+Generated from SCOWL Version 2016.06.26
+Tue Jul 26 12:40:23 EDT 2016
 
 http://wordlist.sourceforge.net
 
 README file for English Hunspell dictionaries derived from SCOWL.
 
 These dictionaries are created using the speller/make-hunspell-dict
 script in SCOWL.
 
@@ -314,10 +314,10 @@ from the Ispell distribution they are un
   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
 
-Build Date: Thu Jan 21 14:36:27 EST 2016
+Build Date: Tue Jul 26 12:40:23 EDT 2016
 With Input Command: ../mk-list -v1 --accents=both en_US 60
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
@@ -1,9 +1,9 @@
-49404
+49464
 0/nm
 0th/pt
 1/n1
 1st/p
 1th/tc
 2/nm
 2nd/p
 2th/tc
@@ -32,16 +32,17 @@ ABM/SM
 ABS
 AC/M
 ACLU/M
 ACT
 ACTH/M
 AD/M
 ADC
 ADD
+ADM
 ADP/M
 AF
 AFAIK
 AFB
 AFC/M
 AFDC
 AFN
 AFT
@@ -529,16 +530,17 @@ Apatosaurus
 Apennines/M
 Aphrodite/M
 Apia/M
 Apocalypse/M
 Apocrypha/M
 Apollinaire/M
 Apollo/SM
 Apollonian/M
+Apostle/M
 Appalachia/M
 Appalachian/SM
 Appalachians/M
 Appaloosa/SM
 Apple/M
 Appleseed/M
 Appleton/M
 Appomattox/M
@@ -712,16 +714,17 @@ Athens/M
 Atkins/M
 Atkinson/M
 Atlanta/M
 Atlantes
 Atlantic/M
 Atlantis/M
 Atlas/MS
 Atman/M
+Atonement
 Atreus/M
 Atria/M
 Atropos/M
 Attic/M
 Attica/M
 Attila/M
 Attlee/M
 Attn
@@ -1274,16 +1277,17 @@ Boise/M
 Bojangles/M
 Boleyn/M
 Bolivar/M
 Bolivia/M
 Bolivian/MS
 Bollywood/M
 Bologna/M
 Bolshevik/SM
+Bolsheviki
 Bolshevism/M
 Bolshevist/M
 Bolshoi/M
 Bolton/M
 Boltzmann/M
 Bombay/M
 Bonaparte/M
 Bonaventure/M
@@ -2184,16 +2188,17 @@ Coltrane/M
 Columbia/M
 Columbine/M
 Columbus/M
 Com
 Comanche/MS
 Combs/M
 Comdr
 Comintern/M
+Commandment
 Commons/M
 Commonwealth
 Communion/SM
 Communism
 Communist/SM
 Como/M
 Comoran
 Comoros/M
@@ -2562,16 +2567,17 @@ Dayton/M
 DeGeneres/M
 Deadhead/M
 Dean/M
 Deana/M
 Deandre/M
 Deann/M
 Deanna/M
 Deanne/M
+Death/M
 Debbie/M
 Debby/M
 Debian/M
 Debora/M
 Deborah/M
 Debouillet/M
 Debra/M
 Debs/M
@@ -3561,16 +3567,17 @@ GE/M
 GED
 GHQ/M
 GHz
 GI
 GIF
 GIGO
 GM/M
 GMAT
+GMO
 GMT/M
 GNP/M
 GNU/M
 GOP/M
 GP/M
 GPA
 GPO
 GPS
@@ -4542,16 +4549,17 @@ IOU/M
 IP
 IPA
 IPO
 IQ/M
 IRA/SM
 IRC
 IRS/M
 ISBN
+ISIS
 ISO/M
 ISP
 ISS
 IT
 IUD
 IV/SM
 IVF
 Ia
@@ -5617,16 +5625,17 @@ Lewinsky/M
 Lewis/M
 Lexington/M
 Lexus/M
 Lhasa/MS
 Lhotse/M
 Li/MY
 Libby/M
 Liberace/M
+Liberal
 Liberia/M
 Liberian/SM
 Libra/MS
 LibreOffice/M
 Libreville/M
 Librium/M
 Libya/M
 Libyan/SM
@@ -5933,16 +5942,17 @@ Mackenzie/M
 Mackinac/M
 Mackinaw/M
 Macmillan/M
 Macon/M
 Macumba/M
 Macy/M
 Madagascan/SM
 Madagascar/M
+Madam
 Madden/M
 Maddox/M
 Madeira/SM
 Madeleine/M
 Madeline/M
 Madelyn/M
 Madge/M
 Madison/M
@@ -6433,16 +6443,17 @@ Mesolithic/M
 Mesopotamia/M
 Mesopotamian
 Mesozoic/M
 Messerschmidt/M
 Messiaen/M
 Messiah/M
 Messiahs
 Messianic
+Messieurs
 Metallica/M
 Metamucil/M
 Methodism/SM
 Methodist/SM
 Methuselah/M
 Metternich/M
 Meuse/M
 Mex
@@ -6642,16 +6653,17 @@ Mongoloid
 Monica/M
 Monique/M
 Monk/M
 Monmouth/M
 Monongahela/M
 Monroe/M
 Monrovia/M
 Monsanto/M
+Monsieur/M
 Monsignor/SM
 Mont/M
 Montague/M
 Montaigne/M
 Montana/M
 Montanan/SM
 Montcalm/M
 Monte/M
@@ -6838,16 +6850,17 @@ NP
 NPR/M
 NR
 NRA
 NRC
 NS
 NSA/M
 NSC
 NSF
+NSFW
 NT
 NV
 NW/M
 NWT
 NY
 NYC
 NYSE
 NZ
@@ -7055,17 +7068,17 @@ Nirenberg/M
 Nirvana/M
 Nisan/M
 Nisei/M
 Nissan/M
 Nita/M
 Nivea/M
 Nixon/M
 Nkrumah/M
-No/M
+No/SM
 NoDoz/M
 Noah/M
 Nobel/M
 Nobelist/MS
 Noble/M
 Noe/M
 Noel/SM
 Noelle/M
@@ -7278,32 +7291,34 @@ Ontarian
 Ontario/M
 Oort/M
 Opal/M
 Opel/M
 OpenOffice/M
 Ophelia/M
 Ophiuchus/M
 Oppenheimer/M
+Opposition
 Oprah/M
 Ora/M
 Oracle/M
 Oran/M
 Orange/M
 Oranjestad/M
 Orbison/M
 Ordovician/M
 Ore/N
 Oreg
 Oregon/M
 Oregonian/SM
 Oreo/M
 Orestes/M
 Orient/M
 Oriental/MS
+Orientalism
 Orin/M
 Orinoco/M
 Orion/M
 Oriya/M
 Orizaba/M
 Orkney/M
 Orlando/M
 Orleans/M
@@ -7467,16 +7482,17 @@ Parana/M
 Paraná/M
 Parcheesi/M
 Pareto/M
 Paris/M
 Parisian/MS
 Park/SMR
 Parker/M
 Parkinson/M
+Parkinsonism
 Parkman/M
 Parks/M
 Parliament/M
 Parmenides
 Parmesan/MS
 Parnassus/MS
 Parnell/M
 Parr/M
@@ -8435,16 +8451,17 @@ SD
 SDI
 SE/M
 SEATO
 SEC/M
 SF
 SGML/M
 SIDS/M
 SJ
+SJW
 SK
 SLR
 SO/S
 SOB/M
 SOP/M
 SOS/M
 SOSes
 SPCA
@@ -8786,16 +8803,17 @@ Seward/M
 Sextans/M
 Sexton/M
 Seychelles/M
 Seyfert/M
 Seymour/M
 Sgt
 Shackleton/M
 Shaffer/M
+Shah/M
 Shaka/M
 Shaker
 Shakespeare/M
 Shakespearean/M
 Shana/M
 Shane/M
 Shanghai/M
 Shankara/M
@@ -9881,16 +9899,17 @@ Urquhart/M
 Ursa/M
 Ursula/M
 Ursuline/M
 Uruguay/M
 Uruguayan/MS
 Urumqi/M
 Usenet/MS
 Ustinov/M
+Ut
 Utah/M
 Utahan/MS
 Ute/SM
 Utopia/SM
 Utopian/SM
 Utrecht/M
 Utrillo/M
 Uzbek/M
@@ -10070,16 +10089,17 @@ Vivaldi/M
 Vivekananda/M
 Vivian/M
 Vivienne/M
 Vlad/M
 Vladimir/M
 Vladivostok/M
 Vlaminck/M
 Vlasic/M
+VoIP
 Vogue/M
 Volcker/M
 Voldemort/M
 Volga/M
 Volgograd/M
 Volkswagen/M
 Volstead/M
 Volta/M
@@ -10532,16 +10552,17 @@ Zeus/M
 Zhdanov
 Zhengzhou/M
 Zhivago/M
 Zhukov/M
 Zibo/M
 Ziegfeld/M
 Ziegler/M
 Ziggy/M
+Zika
 Zimbabwe/M
 Zimbabwean/SM
 Zimmerman/M
 Zinfandel/M
 Zion/SM
 Zionism/SM
 Zionist/SM
 Ziploc/M
@@ -10971,16 +10992,17 @@ additive/SM
 addle/GDS
 address's
 address/AGDS
 addressable
 addressed/U
 addressee/SM
 adduce/GDS
 adenine/M
+adenocarcinoma
 adenoid/SM
 adenoidal
 adept/MYPS
 adeptness/M
 adequacy/IM
 adequate/IY
 adequateness/M
 adhere/GDS
@@ -11646,17 +11668,17 @@ amethyst/SM
 amiability/M
 amiable
 amiably
 amicability/M
 amicable
 amicably
 amid
 amide/MS
-amidships
+amidship/S
 amidst
 amigo/MS
 amino
 amir/SM
 amiss
 amity/M
 ammeter/SM
 ammo/M
@@ -12310,16 +12332,17 @@ ardor/MS
 arduous/YP
 arduousness/M
 are/SMB
 area/SM
 areal
 aren't
 arena/MS
 argent/M
+arginine
 argon/M
 argosy/SM
 argot/MS
 arguable/IU
 arguably/U
 argue/ZGDRS
 arguer/M
 argument/MS
@@ -13212,16 +13235,17 @@ baptist/S
 baptistery/SM
 baptistry/SM
 baptize/ZGDRS
 baptized/U
 baptizer/M
 bar's
 bar/ECUTS
 barb/SZGMDR
+barbacoa
 barbarian/SM
 barbarianism/MS
 barbaric
 barbarically
 barbarism/SM
 barbarity/SM
 barbarize/DSG
 barbarous/Y
@@ -15117,33 +15141,33 @@ burghs
 burglar/MS
 burglarize/GDS
 burglarproof
 burglary/SM
 burgle/DSG
 burgomaster/SM
 burgundy/SM
 burial/ASM
-burka/S
+burka/SM
 burl/MDS
 burlap/M
 burlesque/MGDS
 burliness/M
 burly/RPT
 burn/MDRZGSB
 burnable/SM
 burner/M
 burnish/ZGMDRS
 burnisher/M
 burnoose/MS
 burnous/MS
 burnout/MS
 burnt
 burp/MDGS
-burqa/S
+burqa/SM
 burr/MDGS
 burrito/MS
 burro/SM
 burrow/SMDRZG
 burrower/M
 bursa/M
 bursae
 bursar/SM
@@ -16219,16 +16243,17 @@ chastisement/SM
 chastiser/M
 chastity/M
 chasuble/SM
 chat/SM
 chateau/SM
 chateaux
 chatelaine/SM
 chatline/S
+chatroom/M
 chatted
 chattel/MS
 chatter/MDRZGS
 chatterbox/MS
 chatterer/M
 chattily
 chattiness/M
 chatting
@@ -16664,16 +16689,17 @@ citric
 citron/MS
 citronella/M
 citrous
 citrus/MS
 city/SM
 citywide
 civet/MS
 civic/S
+civically
 civics/M
 civil/UY
 civilian/MS
 civility/ISM
 civilization/MS
 civilize/GDS
 civilized/U
 civvies/M
@@ -17960,16 +17986,17 @@ contortion/MS
 contortionist/SM
 contraband/M
 contrabassoon/S
 contraception/M
 contraceptive/SM
 contract/MDG
 contractible
 contractile
+contractility
 contraction/S
 contractual/Y
 contradict/SDG
 contradiction/SM
 contradictory
 contradistinction/MS
 contraflow/S
 contrail/MS
@@ -18362,17 +18389,19 @@ counterfeit/ZGMDRS
 counterfeiter/M
 counterfoil/MS
 countering
 counterinsurgency/SM
 counterintelligence/M
 counterman/M
 countermand/GMDS
 countermeasure/SM
+countermelody/S
 countermen
+countermove/S
 counteroffensive/SM
 counteroffer/SM
 counterpane/SM
 counterpart/SM
 counterpetition
 counterpoint/MDGS
 counterpoise/MGDS
 counterproductive
@@ -19025,17 +19054,17 @@ cutthroat/SM
 cutting/MYS
 cuttlefish/MS
 cutup/SM
 cutworm/MS
 cw
 cwt
 cyan/M
 cyanide/M
-cyberbully/S
+cyberbully/SM
 cybercafe/S
 cybercafé/S
 cybernetic/S
 cybernetics/M
 cyberpunk/SM
 cybersex
 cyberspace/MS
 cyborg/SM
@@ -19061,16 +19090,17 @@ cynic/SM
 cynical/Y
 cynicism/M
 cynosure/MS
 cypher/M
 cypress/MS
 cyst/MS
 cystic
 cystitis
+cytokines
 cytologist/SM
 cytology/M
 cytoplasm/M
 cytoplasmic
 cytosine/M
 czar/MS
 czarina/SM
 czarism
@@ -19968,17 +19998,17 @@ diamondback/MS
 diapason/SM
 diaper/SMDG
 diaphanous
 diaphragm/SM
 diaphragmatic
 diarist/SM
 diarrhea/M
 diary/SM
-diaspora
+diaspora/SM
 diastase/M
 diastole/M
 diastolic
 diathermy/M
 diatom/SM
 diatomic
 diatonic
 diatribe/SM
@@ -21342,17 +21372,17 @@ effendi/SM
 efferent
 effervesce/GDS
 effervescence/M
 effervescent/Y
 effete/YP
 effeteness/M
 efficacious/Y
 efficacy/IM
-efficiency/IM
+efficiency/ISM
 efficient/IY
 effigy/SM
 efflorescence/M
 efflorescent
 effluence/M
 effluent/MS
 effluvia
 effluvium/M
@@ -21645,17 +21675,17 @@ emir/MS
 emirate/MS
 emissary/SM
 emission/SM
 emit/S
 emitted
 emitter/MS
 emitting
 emo/SM
-emoji
+emoji/SM
 emollient/MS
 emolument/MS
 emote/XDSGNV
 emoticon/SM
 emotion/M
 emotional/UY
 emotionalism/M
 emotionalize/GDS
@@ -21777,17 +21807,17 @@ endmost
 endocarditis
 endocrine/MS
 endocrinologist/MS
 endocrinology/M
 endogenous/Y
 endometrial
 endometriosis
 endometrium
-endorphin/M
+endorphin/MS
 endorse/LZGDRS
 endorsement/MS
 endorser/M
 endoscope/MS
 endoscopic
 endoscopy/M
 endothelial
 endothermic
@@ -23024,17 +23054,18 @@ fear/MDGS
 fearful/YP
 fearfulness/M
 fearless/PY
 fearlessness/M
 fearsome
 feasibility/M
 feasible/IU
 feasibly
-feast/SMDG
+feast/SMDRZG
+feaster/M
 feat/MS
 feather/SGMD
 featherbedding/M
 featherbrained
 featherless
 featherweight/MS
 feathery/TR
 feature/DSMG
@@ -23610,19 +23641,16 @@ flimsily
 flimsiness/M
 flimsy/TRP
 flinch/GMDS
 fling/GM
 flint/SM
 flintlock/SM
 flinty/TR
 flip/MS
-flipflop/S
-flipflopped
-flipflopping
 flippancy/M
 flippant/Y
 flipped
 flipper/MS
 flippest
 flipping
 flippy/S
 flirt/SGMD
@@ -24256,17 +24284,17 @@ friary/SM
 fricassee/DSM
 fricasseeing
 fricative/SM
 friction/SM
 frictional
 fridge/SM
 friedcake/MS
 friend's
-friend/US
+friend/UGSDY
 friendless
 friendlies
 friendliness/UM
 friendly's
 friendly/UPTR
 friendship/MS
 frieze/SM
 frig/S
@@ -24330,17 +24358,17 @@ frontward/S
 frosh/M
 frost's
 frost/CSDG
 frostbit
 frostbite/MGS
 frostbitten
 frostily
 frostiness/M
-frosting/M
+frosting/SM
 frosty/TPR
 froth/MDG
 frothiness/M
 froths
 frothy/TPR
 froufrou/M
 froward/P
 frowardness/M
@@ -25705,17 +25733,17 @@ guava/SM
 gubernatorial
 guerilla/SM
 guerrilla/SM
 guess/ZGBMDRS
 guesser/M
 guesstimate/DSMG
 guesswork/M
 guest/SGMD
-guestbook
+guestbook/SM
 guesthouse/S
 guestroom/S
 guff/M
 guffaw/MDGS
 guidance/M
 guide/DRSMZG
 guidebook/SM
 guided/U
@@ -25870,17 +25898,17 @@ habitué/SM
 hacienda/SM
 hack/MDRZGS
 hacker/M
 hacking/M
 hackish
 hackle/MS
 hackney/SMDG
 hacksaw/SM
-hacktivist/S
+hacktivist/MS
 hackwork/M
 had
 haddock/SM
 hadn't
 hadst
 hafnium/M
 haft/MS
 hag/SM
@@ -26423,16 +26451,17 @@ heliotrope/SM
 helipad/S
 heliport/MS
 helium/M
 helix/M
 hell/M
 hellbent
 hellcat/MS
 hellebore/M
+hellfire
 hellhole/MS
 hellion/MS
 hellish/YP
 hellishness/M
 hello/SM
 helluva
 helm/MS
 helmet/SMD
@@ -28043,17 +28072,16 @@ industriousness/M
 industry/SM
 indwell/SG
 inebriate/MGNDS
 inebriation/M
 inedible
 ineffability/M
 ineffable
 ineffably
-inefficiency/S
 inelastic
 ineligible/MS
 ineligibly
 ineluctable
 ineluctably
 inept/YP
 ineptitude/M
 ineptness/M
@@ -28981,16 +29009,17 @@ jesting/Y
 jet/SM
 jetliner/SM
 jetport/MS
 jetsam/M
 jetted
 jetting
 jettison/MDSG
 jetty/SM
+jew
 jewel/SZGMDR
 jeweler/M
 jewelry/SM
 jg
 jib/SGMD
 jibbed
 jibbing
 jibe/MS
@@ -29119,16 +29148,17 @@ joylessness/M
 joyous/YP
 joyousness/M
 joyridden
 joyride/RSMZG
 joyrider/M
 joyriding/M
 joyrode
 joystick/SM
+jr
 jubilant/Y
 jubilation/M
 jubilee/SM
 judder/GDS
 judge's
 judge/ADSG
 judgemental
 judgeship/M
@@ -29517,17 +29547,18 @@ kronur
 krypton/M
 króna/M
 krónur
 kt
 kuchen/SM
 kudos/M
 kudzu/SM
 kumquat/MS
-kvetch/GMDS
+kvetch/ZGMDRS
+kvetcher/M
 kw
 l/SDXTGJ
 la/M
 lab/SM
 label's
 label/ASDG
 labeled/U
 labia
@@ -29613,17 +29644,17 @@ lambast/GDS
 lambaste/S
 lambda/SM
 lambency/M
 lambent/Y
 lambkin/SM
 lambskin/SM
 lambswool
 lame/MYZTGDRSP
-lamebrain/MS
+lamebrain/MDS
 lameness/M
 lament/BSMDG
 lamentably
 lamentation/MS
 lamina/M
 laminae
 laminar
 laminate/MGNDS
@@ -30031,16 +30062,17 @@ letterbox/S
 lettered/U
 letterer/M
 letterhead/MS
 lettering/M
 letterpress/M
 letting/S
 lettuce/MS
 letup/SM
+leucine
 leucotomy/S
 leukemia/M
 leukemic/SM
 leukocyte/MS
 levee/SM
 level/PSZGMDRY
 leveler/M
 levelheaded/P
@@ -30162,16 +30194,17 @@ lighthouse/MS
 lighting's
 lightly
 lightness/M
 lightning/MDS
 lightproof
 lightship/MS
 lightweight/SM
 ligneous
+lignin
 lignite/M
 lii
 likability/M
 likable/P
 likableness/M
 like/EMGDST
 likeability/M
 likeable/P
@@ -30462,26 +30495,26 @@ logged
 logger/SM
 loggerhead/SM
 loggia/SM
 logging/M
 logic/M
 logical/Y
 logicality/M
 logician/MS
-login/S
+login/SM
 logistic/S
 logistical/Y
 logistics/M
 logjam/SM
 logo/MS
-logoff/S
-logon/S
+logoff/SM
+logon/SM
 logotype/SM
-logout/S
+logout/SM
 logrolling/M
 logy/RT
 loin/MS
 loincloth/M
 loincloths
 loiter/ZGSDR
 loiterer/M
 loitering/M
@@ -30820,19 +30853,20 @@ maddest
 madding
 made/AU
 mademoiselle/MS
 madhouse/SM
 madman/M
 madmen
 madness/M
 madras/MS
-madrasa/S
-madrassah
-madrassahs
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
 madrigal/SM
 madwoman/M
 madwomen
 maelstrom/SM
 maestro/SM
 mafia/SM
 mafiosi
 mafioso/M
@@ -31534,17 +31568,17 @@ melon/SM
 melt's
 melt/ADSG
 meltdown/SM
 member's
 member/EAS
 membership/SM
 membrane/SM
 membranous
-meme/S
+meme/MS
 memento/MS
 memo/MS
 memoir/MS
 memorabilia/M
 memorability/M
 memorable/U
 memorably
 memorandum/MS
@@ -31764,16 +31798,17 @@ mgr
 mi/MNX
 miasma/MS
 mic/S
 mica/M
 mice
 mick/S
 mickey/MS
 micro/SM
+microaggression/SM
 microbe/MS
 microbial
 microbiological
 microbiologist/MS
 microbiology/M
 microbrewery/SM
 microchip/MS
 microcircuit/SM
@@ -31899,17 +31934,17 @@ milkman/M
 milkmen
 milkshake/SM
 milksop/MS
 milkweed/SM
 milky/RTP
 mill/MDRSZGJ
 millage/M
 millennia
-millennial/MS
+millennial/M
 millennium/MS
 miller/M
 millet/M
 milliard/MS
 millibar/MS
 milligram/MS
 milliliter/MS
 millimeter/MS
@@ -31978,17 +32013,17 @@ minibus/MS
 minicab/S
 minicam/MS
 minicomputer/SM
 minifloppies
 minim/SM
 minimal/Y
 minimalism/M
 minimalist/MS
-minimization
+minimization/M
 minimize/DSG
 minimum/MS
 mining/M
 minion/M
 miniseries/M
 miniskirt/MS
 minister/SGMD
 ministerial
@@ -32060,17 +32095,17 @@ miscegenation/M
 miscellaneous/Y
 miscellany/SM
 mischance/SM
 mischief/M
 mischievous/YP
 mischievousness/M
 miscibility/M
 miscible
-miscommunication
+miscommunication/S
 misconceive/GDS
 misconception/SM
 misconduct/MDGS
 misconstruction/MS
 misconstrue/GDS
 miscount/MDSG
 miscreant/SM
 miscue/DSMG
@@ -32207,24 +32242,26 @@ mitigate/DSGN
 mitigated/U
 mitigation/M
 mitochondria
 mitochondrial
 mitochondrion
 mitoses
 mitosis/M
 mitotic
+mitral
 mitt/MNSX
 mitten/M
 mix/ZGMDRSB
 mixed/U
 mixer/M
 mixture/SM
 mizzen/MS
 mizzenmast/SM
+mkay
 mks
 ml
 mm
 mnemonic/MS
 mnemonically
 mo/CKHS
 moan/MDRSZG
 moaner/M
@@ -32236,17 +32273,17 @@ mobbing/C
 mobile/MS
 mobility/M
 mobilization/CM
 mobilizations
 mobilize/CDSG
 mobilizer/SM
 mobster/SM
 moccasin/SM
-mocha/M
+mocha/SM
 mock/DRSZG
 mocker/M
 mockery/SM
 mocking/Y
 mockingbird/SM
 mod/STM
 modal/SM
 modality/S
@@ -32639,16 +32676,17 @@ mousetrap/SM
 mousetrapped
 mousetrapping
 mousey
 mousiness/M
 moussaka/S
 mousse/MGDS
 mousy/PTR
 mouth/GMD
+mouthfeel
 mouthful/MS
 mouthiness/M
 mouthpiece/MS
 mouths
 mouthwash/MS
 mouthwatering
 mouthy/PTR
 mouton/M
@@ -32741,16 +32779,17 @@ multicultural
 multiculturalism/M
 multidimensional
 multidisciplinary
 multifaceted
 multifamily
 multifarious/PY
 multifariousness/M
 multiform
+multigrain
 multilateral/Y
 multilayered
 multilevel
 multilingual
 multilingualism/M
 multimedia/M
 multimillionaire/SM
 multinational/SM
@@ -32885,16 +32924,17 @@ mutineer/SM
 mutinous/Y
 mutiny/GDSM
 mutt/MS
 mutter/ZGJMDRS
 mutterer/M
 muttering/M
 mutton/M
 muttonchops/M
+muttony
 mutual/Y
 mutuality/M
 muumuu/MS
 muzak
 muzzily
 muzzle/DSMG
 muzzy/P
 my
@@ -33170,17 +33210,17 @@ nelson/SM
 nematode/SM
 nemeses
 nemesis/M
 neoclassic
 neoclassical
 neoclassicism/M
 neocolonialism/M
 neocolonialist/MS
-neocon/S
+neocon/SM
 neoconservative/SM
 neodymium/M
 neolithic
 neologism/SM
 neon/M
 neonatal
 neonate/MS
 neophilia
@@ -33188,16 +33228,17 @@ neophyte/MS
 neoplasm/MS
 neoplastic
 neoprene/M
 nepenthe/M
 nephew/SM
 nephrite/M
 nephritic
 nephritis/M
+nephropathy
 nepotism/M
 nepotist/SM
 nepotistic
 neptunium/M
 nerd/MS
 nerdy/RT
 nerve's
 nerve/UDSG
@@ -33318,17 +33359,17 @@ nickelodeon/SM
 nicker/MDG
 nickle/S
 nickname/DSMG
 nicotine/M
 niece/SM
 niff
 niffy
 nifty/TR
-nigga/S
+nigga/SM
 niggard/SMY
 niggardliness/M
 niggaz
 nigger/SM!
 niggle/MZGDRS
 niggler/M
 nigh/RT
 night/SMY
@@ -33624,17 +33665,17 @@ nonnative/MS
 nonnegotiable
 nonnuclear
 nonnumerical
 nonobjective
 nonobligatory
 nonobservance/M
 nonobservant
 nonoccupational
-nonoccurrence/M
+nonoccurence
 nonofficial
 nonoperational
 nonoperative
 nonparallel/MS
 nonpareil/MS
 nonparticipant/MS
 nonparticipating
 nonpartisan/SM
@@ -34423,17 +34464,17 @@ orator/SM
 oratorical/Y
 oratorio/MS
 oratory/SM
 orb/SM
 orbicular
 orbit/MDRZGS
 orbital/SM
 orbiter/M
-orc/S
+orc/SM
 orchard/SM
 orchestra/MS
 orchestral
 orchestrate/DSXGN
 orchestration/M
 orchid/SM
 ordain/SDLG
 ordainment/M
@@ -35343,16 +35384,17 @@ parimutuel/MS
 paring/M
 parish/MS
 parishioner/MS
 parity/ESM
 park/MDSG
 parka/SM
 parking/M
 parkland
+parkour
 parkway/MS
 parky
 parlance/M
 parlay/GMDS
 parley/GMDS
 parliament/SM
 parliamentarian/SM
 parliamentary
@@ -35361,16 +35403,17 @@ parlous
 parmigiana
 parmigiano
 parochial/Y
 parochialism/M
 parodist/SM
 parody/GDSM
 parole/MGDS
 parolee/MS
+parotid
 paroxysm/SM
 paroxysmal
 parquet/MDSG
 parquetry/M
 parred
 parricidal
 parricide/MS
 parring
@@ -36066,30 +36109,33 @@ pg
 phaeton/MS
 phage/S
 phagocyte/SM
 phalanger/SM
 phalanges
 phalanx/MS
 phalli
 phallic
+phallocentric
+phallocentrism
 phallus/M
 phantasm/MS
 phantasmagoria/MS
 phantasmagorical
 phantasmal
 phantom/SM
 pharaoh/M
 pharaohs
 pharisaic
 pharisee/SM
 pharmaceutic/MS
 pharmaceutical/SM
 pharmaceutics/M
 pharmacist/MS
+pharmacologic
 pharmacological
 pharmacologist/SM
 pharmacology/M
 pharmacopeia/SM
 pharmacopoeia/MS
 pharmacy/SM
 pharyngeal
 pharynges
@@ -36176,18 +36222,18 @@ phooey
 phosphate/MS
 phosphodiesterase
 phosphor/MS
 phosphorescence/M
 phosphorescent/Y
 phosphoric
 phosphorous
 phosphorus/M
+phosphorylation
 photo/SGMD
-photobomb/DGS
 photocell/MS
 photocopier/M
 photocopy/DRSMZG
 photoelectric
 photoelectrically
 photoengrave/DRSJZG
 photoengraver/M
 photoengraving/M
@@ -36687,18 +36733,16 @@ plughole/S
 plugin/SM
 plum/GMDS
 plumage/M
 plumb/MDRSZGJ
 plumbed/U
 plumber/M
 plumbing/M
 plume/MS
-plummer
-plummest
 plummet/SGMD
 plummy
 plump/MDRYSTGP
 plumpness/M
 plumy/RT
 plunder/SZGMDR
 plunderer/M
 plunge/DRSMZG
@@ -36736,17 +36780,17 @@ poaching/M
 pock/GMDS
 pocket/SMDG
 pocketbook/SM
 pocketful/SM
 pocketknife/M
 pocketknives
 pockmark/MDGS
 pod/SM
-podcast/SM
+podcast/SMG
 podded
 podding
 podiatrist/SM
 podiatry/M
 podium/SM
 poem/MS
 poesy/M
 poet/MS
@@ -37078,16 +37122,17 @@ postnatal
 postoperative
 postpaid
 postpartum
 postpone/DSGL
 postponement/SM
 postprandial
 postscript/SM
 postseason/SM
+postsynaptic
 postulate/XDSMGN
 postulation/M
 postural
 posture/MGJDS
 posturing/M
 postwar
 postwoman
 postwomen
@@ -37296,16 +37341,17 @@ preferably
 preference/MS
 preferential/Y
 preferment/M
 preferred
 preferring
 prefigure/GDS
 prefix/MDSG
 preform/GSD
+prefrontal
 pregame/SM
 pregnancy/SM
 pregnant
 preheat/GSD
 prehensile
 prehistorian/S
 prehistoric
 prehistorical/Y
@@ -38202,22 +38248,23 @@ pyre/MS
 pyrimidine/MS
 pyrite/SM
 pyrites/M
 pyromania/M
 pyromaniac/SM
 pyrotechnic/S
 pyrotechnical
 pyrotechnics/M
+pyruvate
 python/SM
 pyx/MS
 pzazz
 q
 qr
-qt
+qt/S
 qty
 qua
 quack/GMDS
 quackery/M
 quad/MS
 quadrangle/SM
 quadrangular
 quadrant/MS
@@ -38589,16 +38636,17 @@ rangy/RTP
 rani/MS
 rank/TGJPMDRYS
 ranking/M
 rankle/DSG
 rankness/M
 ransack/SGD
 ransom/SZGMDR
 ransomer/M
+ransomware
 rant/ZGMDJRS
 ranter/M
 rap/SZGMDR
 rapacious/PY
 rapaciousness/M
 rapacity/M
 rape/MS
 raper/M
@@ -39192,17 +39240,17 @@ renovate/DSXGN
 renovation/M
 renovator/MS
 renown/MD
 rent/ZGMDRS
 rental/SM
 renter/M
 renunciation/SM
 reopen/SDG
-reorg/DSG
+reorg/MDSG
 rep/SM
 repaint/GDS
 repair/BZR
 repairer/M
 repairman/M
 repairmen
 reparable
 reparation/MS
@@ -39755,17 +39803,17 @@ roasting/M
 rob/S
 robbed
 robber/MS
 robbery/SM
 robbing
 robe's
 robe/EGDS
 robin/MS
-robocall/SGD
+robocall/SGMD
 robot/MS
 robotic/S
 robotics/M
 robotize/GDS
 robust/RYPT
 robustness/M
 rock/ZGMDRS
 rockabilly/M
@@ -40050,32 +40098,35 @@ ruthenium/M
 rutherfordium/M
 ruthless/YP
 ruthlessness/M
 rutted
 rutting
 rutty/RT
 rye/M
 s/NYXB
+sabbath/M
+sabbaths
 sabbatical/SM
 saber/MS
 sable/MS
 sabot/MS
 sabotage/DSMG
 saboteur/SM
 sabra/MS
 sabre/MS
 sac/SM
 saccharin/M
 saccharine
 sacerdotal
 sachem/SM
 sachet/SM
-sack/GMDJS
+sack/ZGMDRJS
 sackcloth/M
+sacker/M
 sackful/MS
 sacking/M
 sacra
 sacrament/MS
 sacramental
 sacred/YP
 sacredness/M
 sacrifice/DSMG
@@ -40216,16 +40267,17 @@ same/SP
 sameness/M
 samey
 samizdat/S
 samosa/S
 samovar/SM
 sampan/SM
 sample/DRSMZGJ
 sampler/M
+sampling/M
 samurai/SM
 sanatorium/SM
 sanctification/M
 sanctify/GDSN
 sanctimonious/YP
 sanctimoniousness/M
 sanctimony/M
 sanction/GSMD
@@ -41411,17 +41463,17 @@ shibboleth/M
 shibboleths
 shield/MDGS
 shift/GMDS
 shiftily
 shiftiness/M
 shiftless/PY
 shiftlessness/M
 shifty/RPT
-shiitake/S
+shiitake/SM
 shill/GMDSJ
 shillelagh/M
 shillelaghs
 shilling/M
 shim/MS
 shimmed
 shimmer/SMDG
 shimmery
@@ -41503,17 +41555,17 @@ shogunate/M
 shone
 shoo/GDS
 shook
 shoot/ZGMRSJ
 shooter/M
 shooting/M
 shootout/MS
 shop/MS
-shopaholic/S
+shopaholic/MS
 shopfitter/S
 shopfitting
 shopfront/S
 shopkeeper/MS
 shoplift/DRZGS
 shoplifter/M
 shoplifting/M
 shoppe/MZGDRS
@@ -41766,17 +41818,17 @@ silt/GMDS
 silty/TR
 silvan
 silver/GMDS
 silverfish/MS
 silversmith/M
 silversmiths
 silverware/M
 silvery
-sim/S
+sim/SM
 simian/MS
 similar/Y
 similarity/ESM
 simile/MS
 similitude/EM
 simmer/GMDS
 simonize/DSG
 simony/M
@@ -42623,16 +42675,17 @@ soot/M
 sooth/MDRSZG
 soothe
 soother/M
 soothing/Y
 soothsayer/MS
 soothsaying/M
 sooty/RT
 sop/SM
+soph
 sophism/M
 sophist/MS
 sophistic
 sophistical
 sophisticate/DSMGN
 sophisticated/U
 sophistication/M
 sophistry/SM
@@ -42677,17 +42730,17 @@ soufflé/SM
 sough/MDG
 soughs
 sought/U
 souk/S
 soul/MS
 soulful/YP
 soulfulness/M
 soulless/YP
-soulmate/S
+soulmate/SM
 sound/JPSMDRYZTG
 soundalike/S
 soundbar/S
 soundbite/S
 soundboard/MS
 soundcheck/S
 sounder/M
 sounding/M
@@ -42880,17 +42933,17 @@ speedwell/M
 speedy/TPR
 speleological
 speleologist/MS
 speleology/M
 spell/JSMDRZG
 spellbind/ZGRS
 spellbinder/M
 spellbound
-spellcheck/DRZGS
+spellcheck/MDRZGS
 spellchecker/M
 spelldown/SM
 speller/M
 spelling/M
 spelunker/MS
 spelunking/M
 spend/BSRZG
 spender/M
@@ -43441,17 +43494,17 @@ stemming
 stemware/M
 stench/MS
 stencil/GMDS
 steno/SM
 stenographer/SM
 stenographic
 stenography/M
 stenosis
-stent/S
+stent/SM
 stentorian
 step/IMS
 stepbrother/SM
 stepchild/M
 stepchildren/M
 stepdad/MS
 stepdaughter/SM
 stepfather/SM
@@ -43836,17 +43889,17 @@ studentship/S
 studied/U
 studiedly
 studio/MS
 studious/PY
 studiousness/M
 studly/RT
 study's
 study/AGDS
-stuff/GSMD
+stuff/GSMDJ
 stuffily
 stuffiness/M
 stuffing/M
 stuffy/RPT
 stultification/M
 stultify/DSNG
 stumble/DRSMZG
 stumbler/M
@@ -44165,17 +44218,17 @@ sumptuousness/M
 sun/SM
 sunbath/ZGMDRS
 sunbathe
 sunbather/M
 sunbathing/M
 sunbaths
 sunbeam/SM
 sunbed/S
-sunbelt
+sunbelt/SM
 sunblock/MS
 sunbonnet/SM
 sunburn/SGMD
 sunburst/MS
 sundae/MS
 sundeck/S
 sunder/DSG
 sundial/SM
@@ -44931,17 +44984,17 @@ taxman
 taxmen
 taxon
 taxonomic
 taxonomical
 taxonomist/MS
 taxonomy/SM
 taxpayer/MS
 taxpaying
-tbs
+tb/S
 tbsp
 tea/SM
 teabag/S
 teacake/SM
 teach/ZGRSBJ
 teachable/U
 teacher/M
 teaching/M
@@ -45126,17 +45179,17 @@ tenantry/M
 tench
 tend/IEFDGS
 tended/U
 tendency/SM
 tendentious/YP
 tendentiousness/M
 tender/SMDRYTGP
 tenderfoot/MS
-tenderhearted/PY
+tenderhearted/P
 tenderheartedness/M
 tenderize/ZGDRS
 tenderizer/M
 tenderloin/SM
 tenderness/M
 tendinitis/M
 tendon/SM
 tendonitis/M
@@ -45599,16 +45652,17 @@ tighten/ZGDR
 tightener/M
 tightfisted
 tightness/M
 tightrope/MS
 tights/M
 tightwad/MS
 tigress/MS
 til
+tilapia
 tilde/SM
 tile/MZGDRS
 tiler/M
 tiling/M
 till's
 till/EDRZGS
 tillable
 tillage/M
@@ -46497,25 +46551,27 @@ trust/ESGMD
 trustee/MS
 trusteeship/SM
 trustful/EY
 trustfulness/M
 trusting/Y
 trustworthiness/M
 trustworthy/TPR
 trusty/TRSM
-truth/UM
+truth/ZMR
+truther/M
 truthful/UYP
 truthfulness/UM
 truthiness
 truths/U
 try's
 try/AGDS
 trying/Y
 tryout/SM
+tryptophan
 tryst/SMDG
 tsarists
 tsetse/MS
 tsp
 tsunami/SM
 ttys
 tub/SZGMDR
 tuba/MS
@@ -46654,18 +46710,19 @@ twangy/RT
 twas
 twat/S
 tweak/SMDG
 twee
 tweed/SM
 tweeds/M
 tweedy/RT
 tween
-tweet/SMDRZG
-tweeter/M
+tweet's
+tweet/ASDG
+tweeter/SM
 tweezers/M
 twelfth/M
 twelfths
 twelve/SM
 twelvemonth/M
 twelvemonths
 twentieth/M
 twentieths
@@ -46764,20 +46821,21 @@ ubiquitous/Y
 ubiquity/M
 udder/SM
 ufologist/SM
 ufology/M
 ugh
 ugliness/M
 ugly/RTP
 uh
+uhf
 ukase/SM
 ukulele/SM
 ulcer/SM
-ulcerate/DSGN
+ulcerate/XDSGN
 ulceration/M
 ulcerous
 ulna/M
 ulnae
 ulnar
 ulster/MS
 ult
 ulterior
@@ -47050,17 +47108,16 @@ unflagging/Y
 unflappability/M
 unflappable
 unflappably
 unflattering
 unflinching/Y
 unforgettably
 unforgivably
 unfortunate/MS
-unfriend/GD
 unfriendly/T
 unfrock/DG
 unfruitful
 unfunny
 ungainliness/M
 ungainly/RPT
 ungenerous
 ungentle
@@ -47231,16 +47288,17 @@ unthinking/Y
 untidy/PTR
 until
 untimely/T
 untiring/Y
 untouchable/MS
 untoward
 untrue/RT
 untrustworthy
+untruth/M
 unutterable
 unutterably
 unwarrantable
 unwary/T
 unwavering
 unwed
 unwelcome/G
 unwell
@@ -47272,16 +47330,17 @@ upholder/M
 upholster/ASGD
 upholsterer/MS
 upholstery/M
 upkeep/M
 upland/MS
 uplift/JSMDG
 upload/SDG
 upmarket
+upmost
 upon
 upped
 upper/SM
 uppercase/M
 upperclassman/M
 upperclassmen
 upperclasswoman
 upperclasswomen
@@ -47366,17 +47425,17 @@ usable/UA
 usage/SM
 use/AEDSMG
 used/U
 useful/PY
 usefulness/M
 useless/YP
 uselessness/M
 user/MS
-username/S
+username/MS
 usher/SMDG
 usherette/SM
 usu
 usual's
 usual/UY
 usurer/SM
 usurious
 usurp/SDRZG
@@ -47929,16 +47988,17 @@ viviparous
 vivisect/DGS
 vivisection/M
 vivisectional
 vivisectionist/SM
 vixen/SM
 vixenish/Y
 viz
 vizier/SM
+vlf
 vocab
 vocable/MS
 vocabulary/SM
 vocal/SMY
 vocalic
 vocalist/SM
 vocalization/MS
 vocalize/DSG
@@ -47951,17 +48011,17 @@ vociferous/YP
 vociferousness/M
 vodka/SM
 vogue/SM
 voguish
 voice/IDSMG
 voiced/U
 voiceless/PY
 voicelessness/M
-voicemail/M
+voicemail/SM
 void/MDSGB
 voila
 voile/M
 voilà
 vol/S
 volatile
 volatility/M
 volatilize/DSG
@@ -48031,17 +48091,17 @@ vulpine
 vulture/SM
 vulturous
 vulva/M
 vulvae
 vuvuzela/MS
 vying
 w/DNXTGVJ
 wabbit/S
-wack/RTS
+wack/MRTS
 wackiness/M
 wacko/SM
 wacky/RPT
 wad/SZGMDR
 wadded
 wadding/M
 waddle/DSMG
 wade/MS
@@ -48193,17 +48253,17 @@ warrior/SM
 warship/SM
 wart/MS
 warthog/SM
 wartime/M
 warty/TR
 wary/UPRT
 was
 wasabi
-wash/BMDRSZG
+wash/BJMDRSZG
 washable/SM
 washbasin/SM
 washboard/SM
 washbowl/SM
 washcloth/M
 washcloths
 washed/U
 washer/M
@@ -48244,17 +48304,18 @@ watchmaking/M
 watchman/M
 watchmen
 watchstrap/S
 watchtower/SM
 watchword/MS
 water/GSMD
 waterbed/MS
 waterbird/SM
-waterboard/DJSG
+waterboard/MDJSG
+waterboarding/M
 waterborne
 watercolor/MS
 watercourse/SM
 watercraft/M
 watercress/M
 waterfall/SM
 waterfowl/SM
 waterfront/MS
@@ -48362,17 +48423,16 @@ webcam/MS
 webcast/SMG
 webfeet
 webfoot/M
 webinar/SM
 webisode/MS
 weblog/MS
 webmaster/SM
 webmistress/MS
-webpage/SM
 website/SM
 wed/AS
 wedded/A
 wedder
 wedding/SM
 wedge/DSMG
 wedgie/MS
 wedlock/M
@@ -48655,17 +48715,17 @@ wickedness/M
 wicker/M
 wickerwork/M
 wicket/SM
 wide/YTRP
 widemouthed
 widen/SDRZG
 widener/M
 wideness/M
-widescreen/S
+widescreen/MS
 widespread
 widgeon/MS
 widget/S
 widow/SMDRZG
 widower/M
 widowhood/M
 width/M
 widths
@@ -48813,17 +48873,17 @@ wisdom/M
 wise/MYTGDRS
 wiseacre/SM
 wisecrack/MDSG
 wiseguy/S
 wish/MDRSZG
 wishbone/SM
 wisher/M
 wishful/Y
-wishlist/SM
+wishlist's
 wisp/MS
 wispy/RT
 wist
 wisteria/SM
 wistful/YP
 wistfulness/M
 wit/SM
 witch/MDSG
--- a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic
+++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic
@@ -1,9 +1,9 @@
-52286
+52342
 0/nm
 0th/pt
 1/n1
 1st/p
 1th/tc
 2/nm
 2nd/p
 2th/tc
@@ -32,16 +32,17 @@ ABM/SM
 ABS
 AC/M
 ACLU/M
 ACT
 ACTH/M
 AD/M
 ADC
 ADD
+ADM
 ADP/M
 AF
 AFAIK
 AFB
 AFC/M
 AFDC
 AFN
 AFT
@@ -706,16 +707,17 @@ Apatosaurus
 Apennines/M
 Aphrodite/M
 Apia/M
 Apocalypse/M
 Apocrypha/M
 Apollinaire/M
 Apollo/SM
 Apollonian/M
+Apostle/M
 Appalachia/M
 Appalachian/SM
 Appalachians/M
 Appaloosa/SM
 Apple/M
 Appleseed/M
 Appleton/M
 Appomattox/M
@@ -931,16 +933,17 @@ Athlon/M
 Atkins/M
 Atkinson/M
 Atlanta/M
 Atlantes
 Atlantic/M
 Atlantis/M
 Atlas/MS
 Atman/M
+Atonement
 Atreus/M
 Atria/M
 Atropos/M
 Attic/M
 Attica/M
 Attila/M
 Attlee/M
 Attn
@@ -1618,16 +1621,17 @@ Boise/M
 Bojangles/M
 Boleyn/M
 Bolivar/M
 Bolivia/M
 Bolivian/MS
 Bollywood/M
 Bologna/M
 Bolshevik/SM
+Bolsheviki
 Bolshevism/M
 Bolshevist/M
 Bolshoi/M
 Bolton/M
 Boltzmann/M
 Bombay/M
 Bonaparte/M
 Bonaventure/M
@@ -2719,16 +2723,17 @@ Columbia/M
 Columbine/M
 Columbus/M
 Com
 Comanche/MS
 Combs/M
 Comcast/M
 Comdr
 Comintern/M
+Commandment
 Commons/M
 Commonwealth
 Communion/SM
 Communism
 Communist/SM
 Como/M
 Comoran
 Comoros/M
@@ -3209,16 +3214,17 @@ Deadhead/M
 DealTime/M
 Dean/M
 Deana/M
 Deandre/M
 Deane/M
 Deann/M
 Deanna/M
 Deanne/M
+Death/M
 Deb/SM
 Debbi/M
 Debbie/M
 Debby/M
 Debi/M
 Debian/M
 Debora/M
 Deborah/M
@@ -4521,16 +4527,17 @@ GE/M
 GED
 GHQ/M
 GHz/M
 GI
 GIF
 GIGO
 GM/M
 GMAT
+GMO
 GMT/M
 GNP/M
 GNU/M
 GOP/M
 GP/M
 GPA
 GPO
 GPS
@@ -5777,16 +5784,17 @@ IOU/M
 IP
 IPA
 IPO/SM
 IQ/M
 IRA/SM
 IRC
 IRS/M
 ISBN
+ISIS
 ISO/M
 ISP
 ISS
 IT
 IUD
 IV/SM
 IVF
 Ia
@@ -7163,16 +7171,17 @@ Liam/M
 Lian/M
 Liana/M
 Liane/M
 Lianne/M
 Libbey/M
 Libbie/M
 Libby/M
 Liberace/M
+Liberal
 Liberia/M
 Liberian/SM
 Libra/MS
 LibreOffice/M
 Libreville/M
 Librium/M
 Libya/M
 Libyan/SM
@@ -7558,16 +7567,17 @@ Macmillan/M
 Macon/M
 Macromedia/M
 Macumba/M
 Macy/M
 Mada/M
 Madagascan/SM
 Madagascar/M
 Madalyn/M
+Madam
 Maddalena/M
 Madden/M
 Maddi/M
 Maddie/M
 Maddox/M
 Maddy/M
 Madeira/SM
 Madelaine/M
@@ -8206,16 +8216,17 @@ Mesolithic/M
 Mesopotamia/M
 Mesopotamian
 Mesozoic/M
 Messerschmidt/M
 Messiaen/M
 Messiah/M
 Messiahs
 Messianic
+Messieurs
 Metacafe/M
 Metallica/M
 Metamucil/M
 Methodism/SM
 Methodist/SM
 Methuselah/M
 Metternich/M
 Meuse/M
@@ -8453,16 +8464,17 @@ Monika/M
 Monique/M
 Monk/M
 Monmouth/M
 Monongahela/M
 Monro/M
 Monroe/M
 Monrovia/M
 Monsanto/M
+Monsieur/M
 Monsignor/SM
 Mont/M
 Montague/M
 Montaigne/M
 Montana/M
 Montanan/SM
 Montcalm/M
 Monte/M
@@ -8676,16 +8688,17 @@ NP
 NPR/M
 NR
 NRA
 NRC
 NS
 NSA/M
 NSC
 NSF
+NSFW
 NSPR/M
 NSS/M
 NT
 NV
 NW/M
 NWT
 NY
 NYC
@@ -8967,17 +8980,17 @@ Nisan/M
 Nisei/M
 Nissan/M
 Nita/M
 Niue/M
 Nivea/M
 Niven/M
 Nixon/M
 Nkrumah/M
-No/M
+No/SM
 NoDoz/M
 Noah/M
 Noam/M
 Nobel/M
 Nobelist/MS
 Noble/M
 Noe/M
 Noel/SM
@@ -9218,16 +9231,17 @@ Oort/M
 Opal/M
 Opaline/M
 Opel/M
 OpenBSD/M
 OpenOffice/M
 Ophelia/M
 Ophiuchus/M
 Oppenheimer/M
+Opposition
 Oprah/M
 Ora/M
 Oracle/M
 Oran/M
 Orange/M
 Oranjestad/M
 Orazio/M
 Orbison/M
@@ -9238,16 +9252,17 @@ Oregon/M
 Oregonian/SM
 Orel
 Oren/M
 Oreo/M
 Orestes/M
 Oriana/M
 Orient/M
 Oriental/MS
+Orientalism
 Orin/M
 Orinoco/M
 Orion/M
 Oriya/M
 Orizaba/M
 Orkney/M
 Orlan/M
 Orland/M
@@ -9442,16 +9457,17 @@ Paran/M
 Parcheesi/M
 Pareto/M
 Paris/M
 Parisian/MS
 Park/SMR
 Parke/M
 Parker/M
 Parkinson/M
+Parkinsonism
 Parkman/M
 Parks/M
 Parliament/M
 Parmenides
 Parmesan/MS
 Parnassus/MS
 Parnell/M
 Parr/M
@@ -10656,16 +10672,17 @@ SD
 SDI
 SE/M
 SEATO
 SEC/M
 SF
 SGML/M
 SIDS/M
 SJ
+SJW
 SK
 SLR
 SNP/SM
 SO/S
 SOB/M
 SOP/M
 SOS/M
 SOSes
@@ -11055,16 +11072,17 @@ Seward/M
 Sextans/M
 Sexton/M
 Seychelles/M
 Seyfert/M
 Seymour/M
 Sgt
 Shackleton/M
 Shaffer/M
+Shah/M
 Shaka/M
 Shaker
 Shakespeare/M
 Shakespearean/M
 Shalom's
 Shamus/M
 Shana/M
 Shandy/M
@@ -12391,16 +12409,17 @@ Urquhart/M
 Ursa/M
 Ursula/M
 Ursuline/M
 Uruguay/M
 Uruguayan/MS
 Urumqi/M
 Usenet/MS
 Ustinov/M
+Ut
 Uta/M
 Utah/M
 Utahan/MS
 Ute/SM
 Utopia/SM
 Utopian/SM
 Utrecht/M
 Utrillo/M
@@ -13203,16 +13222,17 @@ Zhivago/M
 Zhou/M
 Zhukov/M
 Zia/M
 Zibo/M
 Ziegfeld/M
 Ziegler/M
 Ziff/M
 Ziggy/M
+Zika
 Zimbabwe/M
 Zimbabwean/SM
 Zimmerman/M
 Zinfandel/M
 Zion/SM
 Zionism/SM
 Zionist/SM
 Ziploc/M
@@ -13646,16 +13666,17 @@ additive/SM
 addle/GDS
 address's
 address/AGDS
 addressable
 addressed/U
 addressee/SM
 adduce/GDS
 adenine/M
+adenocarcinoma
 adenoid/SM
 adenoidal
 adept/MYPS
 adeptness/M
 adequacy/IM
 adequate/IY
 adequateness/M
 adhere/GDS
@@ -14324,17 +14345,17 @@ amethyst/SM
 amiability/M
 amiable
 amiably
 amicability/M
 amicable
 amicably
 amid
 amide/MS
-amidships
+amidship/S
 amidst
 amigo/MS
 amino
 amir/SM
 amiss
 amity/M
 ammeter/SM
 ammo/M
@@ -14996,16 +15017,17 @@ ardor/MS
 arduous/YP
 arduousness/M
 are/SMB
 area/SM
 areal
 aren't
 arena/MS
 argent/M
+arginine
 argon/M
 argosy/SM
 argot/MS
 arguable/IU
 arguably/U
 argue/ZGDRS
 arguer/M
 argument/MS
@@ -15908,16 +15930,17 @@ baptist/S
 baptistery/SM
 baptistry/SM
 baptize/ZGDRS
 baptized/U
 baptizer/M
 bar's
 bar/ECUTS
 barb/SZGMDR
+barbacoa
 barbarian/SM
 barbarianism/MS
 barbaric
 barbarically
 barbarism/SM
 barbarity/SM
 barbarize/DSG
 barbarous/Y
@@ -17820,33 +17843,33 @@ burghs
 burglar/MS
 burglarize/GDS
 burglarproof
 burglary/SM
 burgle/DSG
 burgomaster/SM
 burgundy/SM
 burial/ASM
-burka/S
+burka/SM
 burl/MDS
 burlap/M
 burlesque/MGDS
 burliness/M
 burly/RPT
 burn/MDRZGSB
 burnable/SM
 burner/M
 burnish/ZGMDRS
 burnisher/M
 burnoose/MS
 burnous/MS
 burnout/MS
 burnt
 burp/MDGS
-burqa/S
+burqa/SM
 burr/MDGS
 burrito/MS
 burro/SM
 burrow/SMDRZG
 burrower/M
 bursa/M
 bursae
 bursar/SM
@@ -18929,16 +18952,17 @@ chastisement/SM
 chastiser/M
 chastity/M
 chasuble/SM
 chat/SM
 chateau/SM
 chateaux
 chatelaine/SM
 chatline/S
+chatroom/M
 chatted
 chattel/MS
 chatter/MDRZGS
 chatterbox/MS
 chatterer/M
 chattily
 chattiness/M
 chatting
@@ -19375,16 +19399,17 @@ citric
 citron/MS
 citronella/M
 citrous
 citrus/MS
 city/SM
 citywide
 civet/MS
 civic/S
+civically
 civics/M
 civil/UY
 civilian/MS
 civility/ISM
 civilization/MS
 civilize/GDS
 civilized/U
 civvies/M
@@ -20675,16 +20700,17 @@ contortion/MS
 contortionist/SM
 contraband/M
 contrabassoon/S
 contraception/M
 contraceptive/SM
 contract/MDG
 contractible
 contractile
+contractility
 contraction/S
 contractual/Y
 contradict/SDG
 contradiction/SM
 contradictory
 contradistinction/MS
 contraflow/S
 contrail/MS
@@ -21079,17 +21105,19 @@ counterfeit/ZGMDRS
 counterfeiter/M
 counterfoil/MS
 countering
 counterinsurgency/SM
 counterintelligence/M
 counterman/M
 countermand/GMDS
 countermeasure/SM
+countermelody/S
 countermen
+countermove/S
 counteroffensive/SM
 counteroffer/SM
 counterpane/SM
 counterpart/SM
 counterpetition
 counterpoint/MDGS
 counterpoise/MGDS
 counterproductive
@@ -21747,17 +21775,17 @@ cutting/MYS
 cuttlefish/MS
 cutup/SM
 cutworm/MS
 cw
 cwt
 cyan/M
 cyanide/M
 cyber
-cyberbully/S
+cyberbully/SM
 cybercafe/S
 cybercaf/S
 cybernetic/S
 cybernetics/M
 cyberpunk/SM
 cybersex
 cyberspace/MS
 cyborg/SM
@@ -22694,17 +22722,17 @@ diamondback/MS
 diapason/SM
 diaper/SMDG
 diaphanous
 diaphragm/SM
 diaphragmatic
 diarist/SM
 diarrhea/M
 diary/SM
-diaspora
+diaspora/SM
 diastase/M
 diastole/M
 diastolic
 diathermy/M
 diatom/SM
 diatomaceous
 diatomic
 diatonic
@@ -24075,17 +24103,17 @@ effendi/SM
 efferent
 effervesce/GDS
 effervescence/M
 effervescent/Y
 effete/YP
 effeteness/M
 efficacious/Y
 efficacy/IM
-efficiency/IM
+efficiency/ISM
 efficient/IY
 effigy/SM
 efflorescence/M
 efflorescent
 effluence/M
 effluent/MS
 effluvia
 effluvium/M
@@ -24379,17 +24407,17 @@ emir/MS
 emirate/MS
 emissary/SM
 emission/SM
 emit/S
 emitted
 emitter/MS
 emitting
 emo/SM
-emoji
+emoji/SM
 emollient/MS
 emolument/MS
 emote/XDSGNV
 emoticon/SM
 emotion/M
 emotional/UY
 emotionalism/M
 emotionalize/GDS
@@ -24512,17 +24540,17 @@ endmost
 endocarditis
 endocrine/MS
 endocrinologist/MS
 endocrinology/M
 endogenous/Y
 endometrial
 endometriosis
 endometrium
-endorphin/M
+endorphin/MS
 endorse/LZGDRS
 endorsement/MS
 endorser/M
 endoscope/MS
 endoscopic
 endoscopy/M
 endothelial
 endothermic
@@ -25764,17 +25792,18 @@ fear/MDGS
 fearful/YP
 fearfulness/M
 fearless/PY
 fearlessness/M
 fearsome
 feasibility/M
 feasible/IU
 feasibly
-feast/SMDG
+feast/SMDRZG
+feaster/M
 feat/MS
 feather/SGMD
 featherbedding/M
 featherbrained
 featherless
 featherweight/MS
 feathery/TR
 feature/DSMG
@@ -26351,19 +26380,16 @@ flimsily
 flimsiness/M
 flimsy/TRP
 flinch/GMDS
 fling/GM
 flint/SM
 flintlock/SM
 flinty/TR
 flip/MS
-flipflop/S
-flipflopped
-flipflopping
 flippancy/M
 flippant/Y
 flipped
 flipper/MS
 flippest
 flipping
 flippy/S
 flirt/SGMD
@@ -27003,17 +27029,17 @@ friary/SM
 fricassee/DSM
 fricasseeing
 fricative/SM
 friction/SM
 frictional
 fridge/SM
 friedcake/MS
 friend's
-friend/US
+friend/UGSDY
 friendless
 friendlies
 friendliness/UM
 friendly's
 friendly/UPTR
 friendship/MS
 frieze/SM
 frig/S
@@ -27077,17 +27103,17 @@ frontward/S
 frosh/M
 frost's
 frost/CSDG
 frostbit
 frostbite/MGS
 frostbitten
 frostily
 frostiness/M
-frosting/M
+frosting/SM
 frosty/TPR
 froth/MDG
 frothiness/M
 froths
 frothy/TPR
 froufrou/M
 froward/P
 frowardness/M
@@ -28627,17 +28653,17 @@ habitu/SM
 hacienda/SM
 hack/MDRZGS
 hacker/M
 hacking/M
 hackish
 hackle/MS
 hackney/SMDG
 hacksaw/SM
-hacktivist/S
+hacktivist/MS
 hackwork/M
 had
 haddock/SM
 hadn't
 hadst
 hafnium/M
 haft/MS
 hag/SM
@@ -29180,16 +29206,17 @@ heliotrope/SM
 helipad/S
 heliport/MS
 helium/M
 helix/M
 hell/M
 hellbent
 hellcat/MS
 hellebore/M
+hellfire
 hellhole/MS
 hellion/MS
 hellish/YP
 hellishness/M
 hello/SM
 helluva
 helm/MS
 helmet/SMD
@@ -30805,17 +30832,16 @@ industriousness/M
 industry/SM
 indwell/SG
 inebriate/MGNDS
 inebriation/M
 inedible
 ineffability/M
 ineffable
 ineffably
-inefficiency/S
 inelastic
 ineligible/MS
 ineligibly
 ineluctable
 ineluctably
 inept/YP
 ineptitude/M
 ineptness/M
@@ -31752,16 +31778,17 @@ jesting/Y
 jet/SM
 jetliner/SM
 jetport/MS
 jetsam/M
 jetted
 jetting
 jettison/MDSG
 jetty/SM
+jew
 jewel/SZGMDR
 jeweler/M
 jewellery
 jewelry/SM
 jg
 jib/SGMD
 jibbed
 jibbing
@@ -31891,16 +31918,17 @@ joylessness/M
 joyous/YP
 joyousness/M
 joyridden
 joyride/RSMZG
 joyrider/M
 joyriding/M
 joyrode
 joystick/SM
+jr
 jubilant/Y
 jubilation/M
 jubilee/SM
 judder/GDS
 judge's
 judge/ADSG
 judgement/SM
 judgemental
@@ -32293,17 +32321,18 @@ kronur
 krypton/M
 krna/M
 krnur
 kt
 kuchen/SM
 kudos/M
 kudzu/SM
 kumquat/MS
-kvetch/GMDS
+kvetch/ZGMDRS
+kvetcher/M
 kw
 l/SDXTGJ
 la/M
 lab/SM
 label's
 label/ASDG
 labeled/U
 labelled/U
@@ -32390,17 +32419,17 @@ lambast/GDS
 lambaste/S
 lambda/SM
 lambency/M
 lambent/Y
 lambkin/SM
 lambskin/SM
 lambswool
 lame/MYZTGDRSP
-lamebrain/MS
+lamebrain/MDS
 lameness/M
 lament/BSMDG
 lamentably
 lamentation/MS
 lamina/M
 laminae
 laminar
 laminate/MGNDS
@@ -32810,16 +32839,17 @@ letterbox/S
 lettered/U
 letterer/M
 letterhead/MS
 lettering/M
 letterpress/M
 letting/S
 lettuce/MS
 letup/SM
+leucine
 leucotomy/S
 leukemia/M
 leukemic/SM
 leukocyte/MS
 levee/SM
 level/PSZGMDRY
 leveler/M
 levelheaded/P
@@ -32941,16 +32971,17 @@ lighthouse/MS
 lighting's
 lightly
 lightness/M
 lightning/MDS
 lightproof
 lightship/MS
 lightweight/SM
 ligneous
+lignin
 lignite/M
 lii
 likability/M
 likable/P
 likableness/M
 like/EMGDST
 likeability/M
 likeable/P
@@ -33243,26 +33274,26 @@ logged
 logger/SM
 loggerhead/SM
 loggia/SM
 logging/M
 logic/M
 logical/Y
 logicality/M
 logician/MS
-login/S
+login/SM
 logistic/S
 logistical/Y
 logistics/M
 logjam/SM
 logo/MS
-logoff/S
-logon/S
+logoff/SM
+logon/SM
 logotype/SM
-logout/S
+logout/SM
 logrolling/M
 logy/RT
 loin/MS
 loincloth/M
 loincloths
 loiter/ZGSDR
 loiterer/M
 loitering/M
@@ -33602,19 +33633,20 @@ maddest
 madding
 made/AU
 mademoiselle/MS
 madhouse/SM
 madman/M
 madmen
 madness/M
 madras/MS
-madrasa/S
-madrassah
-madrassahs
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
 madrigal/SM
 madwoman/M
 madwomen
 maelstrom/SM
 maestro/SM
 mafia/SM
 mafiosi
 mafioso/M
@@ -34319,17 +34351,17 @@ melon/SM
 melt's
 melt/ADSG
 meltdown/SM
 member's
 member/EAS
 membership/SM
 membrane/SM
 membranous
-meme/S
+meme/MS
 memento/MS
 memo/MS
 memoir/MS
 memorabilia/M
 memorability/M
 memorable/U
 memorably
 memorandum/MS
@@ -34551,16 +34583,17 @@ mgr
 mi/MNX
 miasma/MS
 mic/S
 mica/M
 mice
 mick/S
 mickey/MS
 micro/SM
+microaggression/SM
 microbe/MS
 microbial
 microbiological
 microbiologist/MS
 microbiology/M
 microbrewery/SM
 microchip/MS
 microcircuit/SM
@@ -34687,17 +34720,17 @@ milkman/M
 milkmen
 milkshake/SM
 milksop/MS
 milkweed/SM
 milky/RTP
 mill/MDRSZGJ
 millage/M
 millennia
-millennial/MS
+millennial/M
 millennium/MS
 miller/M
 millet/M
 milliard/MS
 millibar/MS
 milligram/MS
 milliliter/MS
 millimeter/MS
@@ -34766,17 +34799,17 @@ minibus/MS
 minicab/S
 minicam/MS
 minicomputer/SM
 minifloppies
 minim/SM
 minimal/Y
 minimalism/M
 minimalist/MS
-minimization
+minimization/M
 minimize/DSG
 minimum/MS
 mining/M
 minion/M
 miniseries/M
 miniskirt/MS
 minister/SGMD
 ministerial
@@ -34998,24 +35031,26 @@ mitigate/XDSGN
 mitigated/U
 mitigation/M
 mitochondria
 mitochondrial
 mitochondrion
 mitoses
 mitosis/M
 mitotic
+mitral
 mitt/MNSX
 mitten/M
 mix/ZGMDRSB
 mixed/U
 mixer/M
 mixture/SM
 mizzen/MS
 mizzenmast/SM
+mkay
 mks
 ml
 mm
 mnemonic/MS
 mnemonically
 mo/CKHS
 moan/MDRSZG
 moaner/M
@@ -35027,17 +35062,17 @@ mobbing/C
 mobile/MS
 mobility/M
 mobilization/CM
 mobilizations
 mobilize/CDSG
 mobilizer/SM
 mobster/SM
 moccasin/SM
-mocha/M
+mocha/SM
 mock/DRSZG
 mocker/M
 mockery/SM
 mocking/Y
 mockingbird/SM
 mod/STM
 modal/SM
 modality/S
@@ -35433,16 +35468,17 @@ mousetrap/SM
 mousetrapped
 mousetrapping
 mousey
 mousiness/M
 moussaka/S
 mousse/MGDS
 mousy/PTR
 mouth/GMD
+mouthfeel
 mouthful/MS
 mouthiness/M
 mouthpiece/MS
 mouths
 mouthwash/MS
 mouthwatering
 mouthy/PTR
 mouton/M
@@ -35536,16 +35572,17 @@ multicultural
 multiculturalism/M
 multidimensional
 multidisciplinary
 multifaceted
 multifamily
 multifarious/PY
 multifariousness/M
 multiform
+multigrain
 multilateral/Y
 multilayered
 multilevel
 multilingual
 multilingualism/M
 multimedia/M
 multimillionaire/SM
 multinational/SM
@@ -35682,16 +35719,17 @@ mutineer/SM
 mutinous/Y
 mutiny/GDSM
 mutt/MS
 mutter/ZGJMDRS
 mutterer/M
 muttering/M
 mutton/M
 muttonchops/M
+muttony
 mutual/Y
 mutuality/M
 muumuu/MS
 muzak
 muzzily
 muzzle/DSMG
 muzzy/P
 my
@@ -35972,17 +36010,17 @@ nelson/SM
 nematode/SM
 nemeses
 nemesis/M
 neoclassic
 neoclassical
 neoclassicism/M
 neocolonialism/M
 neocolonialist/MS
-neocon/S
+neocon/SM
 neoconservative/SM
 neodymium/M
 neolithic
 neologism/SM
 neon/M
 neonatal
 neonate/MS
 neophilia
@@ -35990,16 +36028,17 @@ neophyte/MS
 neoplasm/MS
 neoplastic
 neoprene/M
 nepenthe/M
 nephew/SM
 nephrite/M
 nephritic
 nephritis/M
+nephropathy
 nepotism/M
 nepotist/SM
 nepotistic
 neptunium/M
 nerd/MS
 nerdy/RT
 nerve's
 nerve/UDSG
@@ -36125,17 +36164,17 @@ nickelodeon/SM
 nicker/MDG
 nickle/S
 nickname/DSMG
 nicotine/M
 niece/SM
 niff
 niffy
 nifty/TR
-nigga/S
+nigga/SM
 niggard/SMY
 niggardliness/M
 niggaz
 nigger/SM!
 niggle/MZGDRS
 niggler/M
 nigh/RT
 night/SMY
@@ -36430,17 +36469,17 @@ nonnative/MS
 nonnegotiable
 nonnuclear
 nonnumerical
 nonobjective
 nonobligatory
 nonobservance/M
 nonobservant
 nonoccupational
-nonoccurrence/M
+nonoccurence
 nonofficial
 nonoperational
 nonoperative
 nonparallel/MS
 nonpareil/MS
 nonparticipant/MS
 nonparticipating
 nonpartisan/SM
@@ -37231,17 +37270,17 @@ orator/SM
 oratorical/Y
 oratorio/MS
 oratory/SM
 orb/SM
 orbicular
 orbit/MDRZGS
 orbital/SM
 orbiter/M
-orc/S
+orc/SM
 orchard/SM
 orchestra/MS
 orchestral
 orchestrate/DSXGN
 orchestration/M
 orchid/SM
 ordain/SDLG
 ordainment/M
@@ -38172,16 +38211,17 @@ parlous
 parmigiana
 parmigiano
 parochial/Y
 parochialism/M
 parodist/SM
 parody/GDSM
 parole/MGDS
 parolee/MS
+parotid
 paroxysm/SM
 paroxysmal
 parquet/MDSG
 parquetry/M
 parred
 parricidal
 parricide/MS
 parring
@@ -38880,30 +38920,33 @@ pg
 phaeton/MS
 phage/S
 phagocyte/SM
 phalanger/SM
 phalanges
 phalanx/MS
 phalli
 phallic
+phallocentric
+phallocentrism
 phallus/M
 phantasm/MS
 phantasmagoria/MS
 phantasmagorical
 phantasmal
 phantom/SM
 pharaoh/M
 pharaohs
 pharisaic
 pharisee/SM
 pharmaceutic/MS
 pharmaceutical/SM
 pharmaceutics/M
 pharmacist/MS
+pharmacologic
 pharmacological
 pharmacologist/SM
 pharmacology/M
 pharmacopeia/SM
 pharmacopoeia/MS
 pharmacy/SM
 pharyngeal
 pharynges
@@ -38995,17 +39038,16 @@ phosphodiesterase
 phosphor/MS
 phosphorescence/M
 phosphorescent/Y
 phosphoric
 phosphorous
 phosphorus/M
 phosphorylate/DSGN
 photo/SGMD
-photobomb/DGS
 photocell/MS
 photocopier/M
 photocopy/DRSMZG
 photoelectric
 photoelectrically
 photoengrave/DRSJZG
 photoengraver/M
 photoengraving/M
@@ -39506,18 +39548,16 @@ plughole/S
 plugin/SM
 plum/GMDS
 plumage/M
 plumb/MDRSZGJ
 plumbed/U
 plumber/M
 plumbing/M
 plume/MS
-plummer
-plummest
 plummet/SGMD
 plummy
 plump/MDRYSTGP
 plumpness/M
 plumy/RT
 plunder/SZGMDR
 plunderer/M
 plunge/DRSMZG
@@ -39555,17 +39595,17 @@ poaching/M
 pock/GMDS
 pocket/SMDG
 pocketbook/SM
 pocketful/SM
 pocketknife/M
 pocketknives
 pockmark/MDGS
 pod/SM
-podcast/SM
+podcast/SMG
 podded
 podding
 podiatrist/SM
 podiatry/M
 podium/SM
 poem/MS
 poesy/M
 poet/MS
@@ -39899,16 +39939,17 @@ postnatal
 postoperative
 postpaid
 postpartum
 postpone/DSGL
 postponement/SM
 postprandial
 postscript/SM
 postseason/SM
+postsynaptic
 postulate/XDSMGN
 postulation/M
 postural
 posture/MGJDS
 posturing/M
 postwar
 postwoman
 postwomen
@@ -40118,16 +40159,17 @@ preferably
 preference/MS
 preferential/Y
 preferment/M
 preferred
 preferring
 prefigure/GDS
 prefix/MDSG
 preform/GSD
+prefrontal
 pregame/SM
 pregnancy/SM
 pregnant
 preheat/GSD
 prehensile
 prehistorian/S
 prehistoric
 prehistorical/Y
@@ -41030,22 +41072,23 @@ pyre/MS
 pyrimidine/MS
 pyrite/SM
 pyrites/M
 pyromania/M
 pyromaniac/SM
 pyrotechnic/S
 pyrotechnical
 pyrotechnics/M
+pyruvate
 python/SM
 pyx/MS
 pzazz
 q
 qr
-qt
+qt/S
 qty
 qua
 quack/GMDS
 quackery/M
 quad/MS
 quadrangle/SM
 quadrangular
 quadrant/MS
@@ -41419,16 +41462,17 @@ rangy/RTP
 rani/MS
 rank/TGJPMDRYS
 ranking/M
 rankle/DSG
 rankness/M
 ransack/SGD
 ransom/SZGMDR
 ransomer/M
+ransomware
 rant/ZGMDJRS
 ranter/M
 rap/SZGMDR
 rapacious/PY
 rapaciousness/M
 rapacity/M
 rape/MS
 raper/M
@@ -42028,17 +42072,17 @@ renovate/DSXGN
 renovation/M
 renovator/MS
 renown/MD
 rent/ZGMDRS
 rental/SM
 renter/M
 renunciation/SM
 reopen/SDG
-reorg/DSG
+reorg/MDSG
 rep/SM
 repaint/GDS
 repair/BZR
 repairer/M
 repairman/M
 repairmen
 reparable
 reparation/MS
@@ -42594,17 +42638,17 @@ roasting/M
 rob/S
 robbed
 robber/MS
 robbery/SM
 robbing
 robe's
 robe/EGDS
 robin/MS
-robocall/SGD
+robocall/SGMD
 robot/MS
 robotic/S
 robotics/M
 robotize/GDS
 robust/RYPT
 robustness/M
 rock/ZGMDRS
 rockabilly/M
@@ -42890,32 +42934,35 @@ ruthenium/M
 rutherfordium/M
 ruthless/YP
 ruthlessness/M
 rutted
 rutting
 rutty/RT
 rye/M
 s/NYXB
+sabbath/M
+sabbaths
 sabbatical/SM
 saber/MS
 sable/MS
 sabot/MS
 sabotage/DSMG
 saboteur/SM
 sabra/MS
 sabre/MS
 sac/SM
 saccharin/M
 saccharine
 sacerdotal
 sachem/SM
 sachet/SM
-sack/GMDJS
+sack/ZGMDRJS
 sackcloth/M
+sacker/M
 sackful/MS
 sacking/M
 sacra
 sacrament/MS
 sacramental
 sacred/YP
 sacredness/M
 sacrifice/DSMG
@@ -43056,16 +43103,17 @@ same/SP
 sameness/M
 samey
 samizdat/S
 samosa/S
 samovar/SM
 sampan/SM
 sample/DRSMZGJ
 sampler/M
+sampling/M
 samurai/SM
 sanatorium/SM
 sanctification/M
 sanctify/GDSN
 sanctimonious/YP
 sanctimoniousness/M
 sanctimony/M
 sanction/GSMD
@@ -44261,17 +44309,17 @@ shibboleth/M
 shibboleths
 shield/MDGS
 shift/GMDS
 shiftily
 shiftiness/M
 shiftless/PY
 shiftlessness/M
 shifty/RPT
-shiitake/S
+shiitake/SM
 shill/GMDSJ
 shillelagh/M
 shillelaghs
 shilling/M
 shim/MS
 shimmed
 shimmer/SMDG
 shimmery
@@ -44355,17 +44403,17 @@ shogunate/M
 shone
 shoo/GDS
 shook
 shoot/ZGMRSJ
 shooter/M
 shooting/M
 shootout/MS
 shop/MS
-shopaholic/S
+shopaholic/MS
 shopfitter/S
 shopfitting
 shopfront/S
 shopkeeper/MS
 shoplift/DRZGS
 shoplifter/M
 shoplifting/M
 shoppe/MZGDRS
@@ -44619,17 +44667,17 @@ silt/GMDS
 silty/TR
 silvan
 silver/GMDS
 silverfish/MS
 silversmith/M
 silversmiths
 silverware/M
 silvery
-sim/S
+sim/SM
 simian/MS
 similar/Y
 similarity/ESM
 simile/MS
 similitude/EM
 simmer/GMDS
 simonize/DSG
 simony/M
@@ -45476,16 +45524,17 @@ soot/M
 sooth/MDRSZG
 soothe
 soother/M
 soothing/Y
 soothsayer/MS
 soothsaying/M
 sooty/RT
 sop/SM
+soph
 sophism/M
 sophist/MS
 sophistic
 sophistical
 sophisticate/DSMGN
 sophisticated/U
 sophistication/M
 sophistry/SM
@@ -45530,17 +45579,17 @@ souffl/SM
 sough/MDG
 soughs
 sought/U
 souk/S
 soul/MS
 soulful/YP
 soulfulness/M
 soulless/YP
-soulmate/S
+soulmate/SM
 sound/JPSMDRYZTG
 soundalike/S
 soundbar/S
 soundbite/S
 soundboard/MS
 soundcheck/S
 sounder/M
 sounding/M
@@ -45733,17 +45782,17 @@ speedwell/M
 speedy/TPR
 speleological
 speleologist/MS
 speleology/M
 spell/JSMDRZG
 spellbind/ZGRS
 spellbinder/M
 spellbound
-spellcheck/DRZGS
+spellcheck/MDRZGS
 spellchecker/M
 spelldown/SM
 speller/M
 spelling/M
 spelt
 spelunker/MS
 spelunking/M
 spend/BSRZG
@@ -46691,17 +46740,17 @@ studentship/S
 studied/U
 studiedly
 studio/MS
 studious/PY
 studiousness/M
 studly/RT
 study's
 study/AGDS
-stuff/GSMD
+stuff/GSMDJ
 stuffily
 stuffiness/M
 stuffing/M
 stuffy/RPT
 stultification/M
 stultify/DSNG
 stumble/DRSMZG
 stumbler/M
@@ -47021,17 +47070,17 @@ sumptuousness/M
 sun/SM
 sunbath/ZGMDRS
 sunbathe
 sunbather/M
 sunbathing/M
 sunbaths
 sunbeam/SM
 sunbed/S
-sunbelt
+sunbelt/SM
 sunblock/MS
 sunbonnet/SM
 sunburn/SGMD
 sunburst/MS
 sundae/MS
 sundeck/S
 sunder/DSG
 sundial/SM
@@ -47794,17 +47843,17 @@ taxman
 taxmen
 taxon
 taxonomic
 taxonomical
 taxonomist/MS
 taxonomy/SM
 taxpayer/MS
 taxpaying
-tbs
+tb/S
 tbsp
 tea/SM
 teabag/S
 teacake/SM
 teach/ZGRSBJ
 teachable/U
 teacher/M
 teaching/M
@@ -47990,17 +48039,17 @@ tenantry/M
 tench
 tend/IFEDGS
 tended/U
 tendency/SM
 tendentious/YP
 tendentiousness/M
 tender/SMDRYTGP
 tenderfoot/MS
-tenderhearted/PY
+tenderhearted/P
 tenderheartedness/M
 tenderize/ZGDRS
 tenderizer/M
 tenderloin/SM
 tenderness/M
 tendinitis/M
 tendon/SM
 tendonitis/M
@@ -48468,16 +48517,17 @@ tighten/ZGDR
 tightener/M
 tightfisted
 tightness/M
 tightrope/MS
 tights/M
 tightwad/MS
 tigress/MS
 til
+tilapia
 tilde/SM
 tile/MZGDRS
 tiler/M
 tiling/M
 till's
 till/EDRZGS
 tillable
 tillage/M
@@ -49372,25 +49422,27 @@ trust/ESGMD
 trustee/MS
 trusteeship/SM
 trustful/EY
 trustfulness/M
 trusting/Y
 trustworthiness/M
 trustworthy/TPR
 trusty/TRSM
-truth/UM
+truth/ZMR
+truther/M
 truthful/UYP
 truthfulness/UM
 truthiness
 truths/U
 try's
 try/AGDS
 trying/Y
 tryout/SM
+tryptophan
 tryst/SMDG
 tsarists
 tsetse/MS
 tsp
 tsunami/SM
 ttys
 tub/SZGMDR
 tuba/MS
@@ -49530,18 +49582,19 @@ twas
 twat/S
 tweak/SMDG
 twee
 tweed/SM
 tweeds/M
 tweedy/RT
 tween
 tweep/S
-tweet/SMDRZG
-tweeter/M
+tweet's
+tweet/ASDG
+tweeter/SM
 tweezers/M
 twelfth/M
 twelfths
 twelve/SM
 twelvemonth/M
 twelvemonths
 twentieth/M
 twentieths
@@ -49640,20 +49693,21 @@ ubiquitous/Y
 ubiquity/M
 udder/SM
 ufologist/SM
 ufology/M
 ugh
 ugliness/M
 ugly/RTP
 uh
+uhf
 ukase/SM
 ukulele/SM
 ulcer/SM
-ulcerate/DSGN
+ulcerate/XDSGN
 ulceration/M
 ulcerous
 ulna/M
 ulnae
 ulnar
 ulster/MS
 ult
 ulterior
@@ -49926,17 +49980,16 @@ unflagging/Y
 unflappability/M
 unflappable
 unflappably
 unflattering
 unflinching/Y
 unforgettably
 unforgivably
 unfortunate/MS
-unfriend/GD
 unfriendly/T
 unfrock/DG
 unfruitful
 unfunny
 ungainliness/M
 ungainly/RPT
 ungenerous
 ungentle
@@ -50106,16 +50159,17 @@ unthinking/Y
 untidy/PTR
 until
 untimely/T
 untiring/Y
 untouchable/MS
 untoward
 untrue/RT
 untrustworthy
+untruth/M
 unutterable
 unutterably
 unwarrantable
 unwary/T
 unwavering
 unwed
 unwelcome/G
 unwell
@@ -50147,16 +50201,17 @@ upholder/M
 upholster/ASGD
 upholsterer/MS
 upholstery/M
 upkeep/M
 upland/MS
 uplift/JSMDG
 upload/SDG
 upmarket
+upmost
 upon
 upped
 upper/SM
 uppercase/M
 upperclassman/M
 upperclassmen
 upperclasswoman
 upperclasswomen
@@ -50806,16 +50861,17 @@ viviparous
 vivisect/DGS
 vivisection/M
 vivisectional
 vivisectionist/SM
 vixen/SM
 vixenish/Y
 viz
 vizier/SM
+vlf
 vocab
 vocable/MS
 vocabulary/SM
 vocal/SMY
 vocalic
 vocalist/SM
 vocalization/MS
 vocalize/DSG
@@ -50828,17 +50884,17 @@ vociferous/YP
 vociferousness/M
 vodka/SM
 vogue/SM
 voguish
 voice/IDSMG
 voiced/U
 voiceless/PY
 voicelessness/M
-voicemail/M
+voicemail/SM
 void/MDSGB
 voila
 voile/M
 voil
 vol/S
 volatile
 volatility/M
 volatilize/DSG
@@ -50911,17 +50967,17 @@ vulpine
 vulture/SM
 vulturous
 vulva/M
 vulvae
 vuvuzela/MS
 vying
 w/DNXTGVJ
 wabbit/S
-wack/RTS
+wack/MRTS
 wackiness/M
 wacko/SM
 wacky/RPT
 wad/SZGMDR
 wadded
 wadding/M
 waddle/DSMG
 wade/MS
@@ -51073,17 +51129,17 @@ warrior/SM
 warship/SM
 wart/MS
 warthog/SM
 wartime/M
 warty/TR
 wary/UPRT
 was
 wasabi
-wash/BMDRSZG
+wash/BJMDRSZG
 washable/SM
 washbasin/SM
 washboard/SM
 washbowl/SM
 washcloth/M
 washcloths
 washed/U
 washer/M
@@ -51124,17 +51180,18 @@ watchmaking/M
 watchman/M
 watchmen
 watchstrap/S
 watchtower/SM
 watchword/MS
 water/GSMD
 waterbed/MS
 waterbird/SM
-waterboard/DJSG
+waterboard/MDJSG
+waterboarding/M
 waterborne
 watercolor/MS
 watercourse/SM
 watercraft/M
 watercress/M
 waterfall/SM
 waterfowl/SM
 waterfront/MS
@@ -51243,17 +51300,16 @@ webcast/SMG
 webdesign/MS
 webfeet
 webfoot/M
 webinar/SM
 webisode/MS
 weblog/MS
 webmaster/SM
 webmistress/MS
-webpage/SM
 website/SM
 wed/AS
 wedded/A
 wedder
 wedding/SM
 wedge/DSMG
 wedgie/MS
 wedlock/M
@@ -51695,17 +51751,17 @@ wisdom/M
 wise/MYTGDRS
 wiseacre/SM
 wisecrack/MDSG
 wiseguy/S
 wish/MDRSZG
 wishbone/SM
 wisher/M
 wishful/Y
-wishlist/SM
+wishlist's
 wisp/MS
 wispy/RT
 wist
 wisteria/SM
 wistful/YP
 wistfulness/M
 wit/SM
 witch/MDSG
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -16,17 +16,17 @@
 #include "gfx2DGlue.h"
 #include "../layers/ipc/ShadowLayers.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/TextureClientSharedSurface.h"
 
 #ifdef XP_WIN
 #include "SharedSurfaceANGLE.h"         // for SurfaceFactory_ANGLEShareHandle
 #include "SharedSurfaceD3D11Interop.h"  // for SurfaceFactory_D3D11Interop
-#include "gfxWindowsPlatform.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include "SharedSurfaceGralloc.h"
 #include "nsXULAppAPI.h"
 #endif
 
 #ifdef XP_MACOSX
@@ -103,19 +103,20 @@ GLScreenBuffer::CreateFactory(GLContext*
                 }
 #endif
                 break;
             }
             case mozilla::layers::LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
                 // Enable surface sharing only if ANGLE and compositing devices
                 // are both WARP or both not WARP
+                gfx::DeviceManagerD3D11* dm = gfx::DeviceManagerD3D11::Get();
                 if (gl->IsANGLE() &&
-                    (gl->IsWARP() == gfxWindowsPlatform::GetPlatform()->IsWARP()) &&
-                    gfxWindowsPlatform::GetPlatform()->CompositorD3D11TextureSharingWorks())
+                    (gl->IsWARP() == dm->IsWARP()) &&
+                    dm->TextureSharingWorks())
                 {
                     factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, allocator, flags);
                 }
 
                 if (!factory && gfxPrefs::WebGLDXGLEnabled()) {
                   factory = SurfaceFactory_D3D11Interop::Create(gl, caps, allocator, flags);
                 }
 #endif
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -1,19 +1,19 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedSurfaceANGLE.h"
 
 #include <d3d11.h>
-#include "gfxWindowsPlatform.h"
 #include "GLContextEGL.h"
 #include "GLLibraryEGL.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 
 namespace mozilla {
 namespace gl {
 
 // Returns `EGL_NO_SURFACE` (`0`) on error.
 static EGLSurface
 CreatePBufferSurface(GLLibraryEGL* egl,
@@ -191,18 +191,19 @@ public:
             }
 
             if (FAILED(hr)) {
                 NS_WARNING("Failed to lock the texture");
                 return;
             }
         }
 
-        RefPtr<ID3D11Device> device;
-        if (!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device)) {
+        RefPtr<ID3D11Device> device =
+          gfx::DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
+        if (!device) {
             return;
         }
 
         device->GetImmediateContext(getter_AddRefs(mDeviceContext));
 
         mTexture->GetDesc(&mDesc);
         mDesc.BindFlags = 0;
         mDesc.Usage = D3D11_USAGE_STAGING;
@@ -247,18 +248,19 @@ public:
     D3D11_MAPPED_SUBRESOURCE mSubresource;
 };
 
 bool
 SharedSurface_ANGLEShareHandle::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
 {
     MOZ_ASSERT(out_surface);
 
-    RefPtr<ID3D11Device> device;
-    if (!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device)) {
+    RefPtr<ID3D11Device> device =
+      gfx::DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
+    if (!device) {
         return false;
     }
 
     RefPtr<ID3D11Texture2D> tex;
     HRESULT hr = device->OpenSharedResource(mShareHandle,
                                             __uuidof(ID3D11Texture2D),
                                             (void**)(ID3D11Texture2D**)getter_AddRefs(tex));
 
--- a/gfx/gl/SharedSurfaceD3D11Interop.cpp
+++ b/gfx/gl/SharedSurfaceD3D11Interop.cpp
@@ -5,16 +5,17 @@
 
 #include "SharedSurfaceD3D11Interop.h"
 
 #include <d3d11.h>
 #include "gfxPrefs.h"
 #include "GLContext.h"
 #include "WGLLibrary.h"
 #include "nsPrintfCString.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 
 namespace mozilla {
 namespace gl {
 
 /*
 Sample Code for WGL_NV_DX_interop2:
 Example: Render to Direct3D 11 backbuffer with openGL:
 
@@ -120,19 +121,18 @@ public:
 
     WGLLibrary* const mWGL;
     const RefPtr<ID3D11Device> mD3D; // Only needed for lifetime guarantee.
     const HANDLE mDXGLDeviceHandle;
 
     static already_AddRefed<DXGLDevice> Open(WGLLibrary* wgl)
     {
         MOZ_ASSERT(wgl->HasDXInterop2());
-        gfxWindowsPlatform* plat = gfxWindowsPlatform::GetPlatform();
 
-        RefPtr<ID3D11Device> d3d = plat->GetD3D11ContentDevice();
+        RefPtr<ID3D11Device> d3d = gfx::DeviceManagerD3D11::Get()->GetContentDevice();
         if (!d3d) {
             NS_WARNING("Failed to create D3D11 device.");
             return nullptr;
         }
 
         HANDLE dxglDeviceHandle = wgl->fDXOpenDevice(d3d);
         if (!dxglDeviceHandle) {
             NS_WARNING("Failed to open D3D device for use by WGL.");
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "IMFYCbCrImage.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include "mozilla/layers/CompositableClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/layers/TextureClient.h"
 #include "d3d9.h"
 
 namespace mozilla {
 namespace layers {
 
 IMFYCbCrImage::IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer)
@@ -219,18 +220,18 @@ IMFYCbCrImage::GetD3D9TextureClient(Comp
 
 TextureClient*
 IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
 {
   if (mTextureClient) {
     return mTextureClient;
   }
 
-  RefPtr<ID3D11Device> device;
-  gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(&device);
+  RefPtr<ID3D11Device> device =
+    gfx::DeviceManagerD3D11::Get()->GetImageBridgeDevice();
 
   LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType();
   if (!device || backend != LayersBackend::LAYERS_D3D11) {
     if (backend == LayersBackend::LAYERS_D3D9 ||
         backend == LayersBackend::LAYERS_D3D11) {
       return GetD3D9TextureClient(aClient);
     }
     return nullptr;
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -164,17 +164,17 @@ ScrollFrame(nsIContent* aContent,
   // input events to compensate.
   // Note that if the main-thread had a change in its scroll position, we don't
   // want to record that difference here, because it can be large and throw off
   // input events by a large amount. It is also going to be transient, because
   // any main-thread scroll position change will be synced to APZ and we will
   // get another repaint request when APZ confirms. In the interval while this
   // is happening we can just leave the callback transform as it was.
   bool mainThreadScrollChanged =
-    sf && sf->CurrentScrollGeneration() != aMetrics.GetScrollGeneration();
+    sf && sf->CurrentScrollGeneration() != aMetrics.GetScrollGeneration() && nsLayoutUtils::CanScrollOriginClobberApz(sf->LastScrollOrigin());
   if (aContent && !mainThreadScrollChanged) {
     CSSPoint scrollDelta = apzScrollOffset - actualScrollOffset;
     aContent->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(scrollDelta),
                           nsINode::DeleteProperty<CSSPoint>);
   }
 }
 
 static void
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -30,17 +30,17 @@
 #include "TiledLayerBuffer.h"
 #include "mozilla/dom/WindowBinding.h"  // for Overfill Callback
 #include "FrameLayerBuilder.h"          // for FrameLayerbuilder
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #include "LayerMetricsWrapper.h"
 #endif
 #ifdef XP_WIN
-#include "gfxWindowsPlatform.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #endif
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
@@ -767,17 +767,17 @@ ClientLayerManager::GetBackendName(nsASt
 {
   switch (mForwarder->GetCompositorBackendType()) {
     case LayersBackend::LAYERS_NONE: aName.AssignLiteral("None"); return;
     case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
     case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
     case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
     case LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
-      if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
+      if (DeviceManagerD3D11::Get()->IsWARP()) {
         aName.AssignLiteral("Direct3D 11 WARP");
       } else {
         aName.AssignLiteral("Direct3D 11");
       }
 #endif
       return;
     }
     default: NS_RUNTIMEABORT("Invalid backend");
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -29,16 +29,17 @@
 #include "LayersLogging.h"              // for AppendToString
 #include "gfxUtils.h"                   // for gfxUtils::GetAsLZ4Base64Str
 #include "IPDLActor.h"
 #include "BufferTexture.h"
 #include "gfxPrefs.h"
 #include "mozilla/layers/ShadowLayers.h"
 
 #ifdef XP_WIN
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/TextureD3D9.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include "mozilla/layers/TextureDIB.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #endif
 #ifdef MOZ_X11
 #include "mozilla/layers/TextureClientX11.h"
@@ -1034,17 +1035,17 @@ TextureClient::CreateForDrawing(TextureF
   int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
 #endif
 
 #ifdef XP_WIN
   if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
       (moz2DBackend == gfx::BackendType::DIRECT2D ||
        moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
        (!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
-        gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())) &&
+        DeviceManagerD3D11::Get()->GetContentDevice())) &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize)
   {
     data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
   }
   if (aLayersBackend == LayersBackend::LAYERS_D3D9 &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -7,16 +7,17 @@
 
 #include "TextureD3D11.h"
 #include "CompositorD3D11Shaders.h"
 #include "CompositorD3D11ShadersVR.h"
 
 #include "gfxWindowsPlatform.h"
 #include "nsIWidget.h"
 #include "nsIGfxInfo.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/layers/ImageHost.h"
 #include "mozilla/layers/ContentHost.h"
 #include "mozilla/layers/Effects.h"
 #include "nsWindowsHelpers.h"
 #include "gfxPrefs.h"
 #include "gfxConfig.h"
 #include "gfxCrashReporterUtils.h"
 #include "gfxVR.h"
@@ -198,17 +199,18 @@ bool
 CompositorD3D11::Initialize(nsCString* const out_failureReason)
 {
   ScopedGfxFeatureReporter reporter("D3D11 Layers");
 
   MOZ_ASSERT(gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING));
 
   HRESULT hr;
 
-  if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&mDevice)) {
+  mDevice = DeviceManagerD3D11::Get()->GetCompositorDevice();
+  if (!mDevice) {
     *out_failureReason = "FEATURE_FAILURE_D3D11_NO_DEVICE";
     return false;
   }
 
   mDevice->GetImmediateContext(getter_AddRefs(mContext));
 
   if (!mContext) {
     gfxCriticalNote << "[D3D11] failed to get immediate context";
@@ -1252,17 +1254,18 @@ CompositorD3D11::EndFrame()
   CD3D11_QUERY_DESC  desc(D3D11_QUERY_EVENT);
   mDevice->CreateQuery(&desc, getter_AddRefs(query));
   if (query) {
     mContext->End(query);
   }
 
   UINT presentInterval = 0;
 
-  if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
+  bool isWARP = DeviceManagerD3D11::Get()->IsWARP();
+  if (isWARP) {
     // When we're using WARP we cannot present immediately as it causes us
     // to tear when rendering. When not using WARP it appears the DWM takes
     // care of tearing for us.
     presentInterval = 1;
   }
 
   if (oldSize == mSize) {
     RefPtr<IDXGISwapChain1> chain;
@@ -1275,18 +1278,17 @@ CompositorD3D11::EndFrame()
     if (partialPresentPref > 0) {
       allowPartialPresent = true;
     } else if (partialPresentPref < 0) {
       allowPartialPresent = false;
     } else if (partialPresentPref == 0) {
       nsString vendorID;
       nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
       gfxInfo->GetAdapterVendorID(vendorID);
-      allowPartialPresent = !vendorID.EqualsLiteral("0x10de") ||
-                            gfxWindowsPlatform::GetPlatform()->IsWARP();
+      allowPartialPresent = !vendorID.EqualsLiteral("0x10de") || isWARP;
     }
 
     if (SUCCEEDED(hr) && chain && allowPartialPresent) {
       DXGI_PRESENT_PARAMETERS params;
       PodZero(&params);
       params.DirtyRectsCount = mInvalidRegion.GetNumRects();
       StackArray<RECT, 4> rects(params.DirtyRectsCount);
 
@@ -1500,17 +1502,17 @@ CompositorD3D11::UpdateRenderTarget()
 
   return true;
 }
 
 bool
 DeviceAttachmentsD3D11::InitSyncObject()
 {
   // Sync object is not supported on WARP.
-  if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
+  if (DeviceManagerD3D11::Get()->IsWARP()) {
     return true;
   }
 
   // It's okay to do this on Windows 8. But for now we'll just bail
   // whenever we're using WARP.
   CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1,
                              D3D11_BIND_SHADER_RESOURCE |
                              D3D11_BIND_RENDER_TARGET);
@@ -1702,18 +1704,17 @@ CompositorD3D11::HandleError(HRESULT hr,
   if (SUCCEEDED(hr)) {
     return;
   }
 
   if (aSeverity == Critical) {
     MOZ_CRASH("GFX: Unrecoverable D3D11 error");
   }
 
-  RefPtr<ID3D11Device> device;
-  if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device) || device != mDevice) {
+  if (mDevice && DeviceManagerD3D11::Get()->GetCompositorDevice() != mDevice) {
     gfxCriticalError() << "Out of sync D3D11 devices in HandleError, " << (int)mVerifyBuffersFailed;
   }
 
   HRESULT hrOnReset = S_OK;
   bool deviceRemoved = hr == DXGI_ERROR_DEVICE_REMOVED;
 
   if (deviceRemoved && mDevice) {
     hrOnReset = mDevice->GetDeviceRemovedReason();
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -6,16 +6,17 @@
 #include "TextureD3D11.h"
 #include "CompositorD3D11.h"
 #include "gfxContext.h"
 #include "Effects.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #include "gfxPrefs.h"
 #include "ReadbackManagerD3D11.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #include "mozilla/gfx/Logging.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
@@ -356,20 +357,21 @@ DXGITextureData::Create(IntSize aSize, S
   return D3D11TextureData::Create(aSize, aFormat, aFlags);
 }
 
 DXGITextureData*
 D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags,
                          ID3D11Device* aDevice)
 {
   RefPtr<ID3D11Device> device = aDevice;
-  if (!device &&
-      !gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device))
-  {
-    return nullptr;
+  if (!device) {
+    device = DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
+    if (!device) {
+      return nullptr;
+    }
   }
 
   CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
                                 aSize.width, aSize.height, 1, 1,
                                 D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
 
   newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
   if (!NS_IsMainThread() || !!(aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT)) {
@@ -652,19 +654,17 @@ DXGITextureHostD3D11::OpenSharedHandle()
 
 RefPtr<ID3D11Device>
 DXGITextureHostD3D11::GetDevice()
 {
   if (mFlags & TextureFlags::INVALID_COMPOSITOR) {
     return nullptr;
   }
 
-  RefPtr<ID3D11Device> device;
-  gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device);
-  return device;
+  return DeviceManagerD3D11::Get()->GetCompositorDevice();
 }
 
 static CompositorD3D11* AssertD3D11Compositor(Compositor* aCompositor)
 {
   CompositorD3D11* compositor = aCompositor ? aCompositor->AsCompositorD3D11()
                                             : nullptr;
   if (!compositor) {
     gfxCriticalNote << "[D3D11] Attempt to set an incompatible compositor";
@@ -790,19 +790,17 @@ DXGIYCbCrTextureHostD3D11::OpenSharedHan
 
 RefPtr<ID3D11Device>
 DXGIYCbCrTextureHostD3D11::GetDevice()
 {
   if (mFlags & TextureFlags::INVALID_COMPOSITOR) {
     return nullptr;
   }
 
-  RefPtr<ID3D11Device> device;
-  gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device);
-  return device;
+  return DeviceManagerD3D11::Get()->GetCompositorDevice();
 }
 
 void
 DXGIYCbCrTextureHostD3D11::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = AssertD3D11Compositor(aCompositor);
   if (!mCompositor) {
     mTextureSources[0] = nullptr;
@@ -1116,17 +1114,17 @@ SyncObjectD3D11::RegisterTexture(ID3D11T
 }
 
 void
 SyncObjectD3D11::FinalizeFrame()
 {
   HRESULT hr;
 
   if (!mD3D11Texture && mD3D11SyncedTextures.size()) {
-    ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
+    RefPtr<ID3D11Device> device = DeviceManagerD3D11::Get()->GetContentDevice();
 
     hr = device->OpenSharedResource(mHandle, __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
 
     if (FAILED(hr) || !mD3D11Texture) {
       gfxCriticalError() << "Failed to D3D11 OpenSharedResource for frame finalization: " << hexa(hr);
 
       if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
         return;
@@ -1159,18 +1157,17 @@ SyncObjectD3D11::FinalizeFrame()
       }
       gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
     }
 
     D3D11_BOX box;
     box.front = box.top = box.left = 0;
     box.back = box.bottom = box.right = 1;
 
-    ID3D11Device* dev = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
-
+    RefPtr<ID3D11Device> dev = DeviceManagerD3D11::Get()->GetContentDevice();
     if (!dev) {
       if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
         return;
       }
       MOZ_CRASH("GFX: Invalid D3D11 content device");
     }
 
     RefPtr<ID3D11DeviceContext> ctx;
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/LayersMessages.h"  // for Edit, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/SharedBufferManagerChild.h"
+#include "mozilla/layers/PTextureChild.h"
 #include "ShadowLayerUtils.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsTArray.h"                   // for AutoTArray, nsTArray, etc
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "mozilla/ReentrantMonitor.h"
 
 namespace mozilla {
@@ -431,16 +432,17 @@ ShadowLayerForwarder::UseTextures(Compos
 {
   MOZ_ASSERT(aCompositable && aCompositable->IsConnected());
 
   AutoTArray<TimedTexture,4> textures;
 
   for (auto& t : aTextures) {
     MOZ_ASSERT(t.mTextureClient);
     MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
+    MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
     FenceHandle fence = t.mTextureClient->GetAcquireFenceHandle();
     ReadLockDescriptor readLock;
     t.mTextureClient->SerializeReadLock(readLock);
     textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
                                         readLock,
                                         fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()),
                                         t.mTimeStamp, t.mPictureRect,
                                         t.mFrameID, t.mProducerID, t.mInputFrameID));
@@ -466,16 +468,18 @@ ShadowLayerForwarder::UseComponentAlphaT
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aCompositable->IsConnected());
   MOZ_ASSERT(aTextureOnWhite);
   MOZ_ASSERT(aTextureOnBlack);
   MOZ_ASSERT(aCompositable->GetIPDLActor());
   MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
   MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
   MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
+  MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
+  MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
 
   ReadLockDescriptor readLockW;
   ReadLockDescriptor readLockB;
   aTextureOnBlack->SerializeReadLock(readLockB);
   aTextureOnWhite->SerializeReadLock(readLockW);
 
   mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
   mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
@@ -535,16 +539,17 @@ ShadowLayerForwarder::DestroyInTransacti
 void
 ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable,
                                                     TextureClient* aTexture)
 {
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aTexture);
   MOZ_ASSERT(aCompositable->IsConnected());
   MOZ_ASSERT(aTexture->GetIPDLActor());
+  MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
   if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
     // We don't have an actor anymore, don't try to use it!
     return;
   }
 
   mTxn->AddEdit(
     CompositableOperation(
       nullptr, aCompositable->GetIPDLActor(),
--- a/gfx/src/gfxTelemetry.h
+++ b/gfx/src/gfxTelemetry.h
@@ -50,12 +50,18 @@ enum class FeatureStatus
   // This feature was attempted but later determined to be broken.
   Broken
 };
 
 const char* FeatureStatusToString(FeatureStatus aStatus);
 bool IsFeatureStatusFailure(FeatureStatus aStatus);
 bool IsFeatureStatusSuccess(FeatureStatus aStatus);
 
+enum class TelemetryDeviceCode : uint32_t {
+  Content = 0,
+  Image = 1,
+  D2D1 = 2
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif // gfx_src_gfxTelemetry_h__
--- a/gfx/tests/gtest/TestTreeTraversal.cpp
+++ b/gfx/tests/gtest/TestTreeTraversal.cpp
@@ -31,21 +31,21 @@ class TestNodeBase {
     void SetRegion(nsRegion aRegion);
     int GetExpectedTraversalRank();
     int GetActualTraversalRank();
     int GetValue();
     T GetType();
     nsRegion GetRegion();
     virtual bool IsLeaf() = 0;
   private:
-    int mExpectedTraversalRank;
-    int mActualTraversalRank;
-    int mValue;
-    nsRegion mRegion;
-    T mType;
+    MOZ_INIT_OUTSIDE_CTOR int mExpectedTraversalRank;
+    MOZ_INIT_OUTSIDE_CTOR int mActualTraversalRank;
+    MOZ_INIT_OUTSIDE_CTOR int mValue;
+    MOZ_INIT_OUTSIDE_CTOR nsRegion mRegion;
+    MOZ_INIT_OUTSIDE_CTOR T mType;
   protected:
     virtual ~TestNodeBase<T>() {};
 };
 
 template <class T>
 class TestNodeReverse : public TestNodeBase<T> {
   public:
     explicit TestNodeReverse(T aType, int aExpectedTraversalRank = -1);
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/D3D11Checks.cpp
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "D3D11Checks.h"
+#include "gfxConfig.h"
+#include "GfxDriverInfo.h"
+#include "gfxPrefs.h"
+#include "gfxWindowsPlatform.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/gfx/Logging.h"
+#include "nsIGfxInfo.h"
+#include <dxgi.h>
+#include <d3d10_1.h>
+#include <d3d11.h>
+
+namespace mozilla {
+namespace gfx {
+
+using namespace mozilla::widget;
+
+/* static */ bool
+D3D11Checks::DoesRenderTargetViewNeedRecreating(ID3D11Device *aDevice)
+{
+    bool result = false;
+    // CreateTexture2D is known to crash on lower feature levels, see bugs
+    // 1170211 and 1089413.
+    if (aDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
+        return true;
+    }
+
+    RefPtr<ID3D11DeviceContext> deviceContext;
+    aDevice->GetImmediateContext(getter_AddRefs(deviceContext));
+    int backbufferWidth = 32; int backbufferHeight = 32;
+    RefPtr<ID3D11Texture2D> offscreenTexture;
+    RefPtr<IDXGIKeyedMutex> keyedMutex;
+
+    D3D11_TEXTURE2D_DESC offscreenTextureDesc = { 0 };
+    offscreenTextureDesc.Width = backbufferWidth;
+    offscreenTextureDesc.Height = backbufferHeight;
+    offscreenTextureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    offscreenTextureDesc.MipLevels = 0;
+    offscreenTextureDesc.ArraySize = 1;
+    offscreenTextureDesc.SampleDesc.Count = 1;
+    offscreenTextureDesc.SampleDesc.Quality = 0;
+    offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
+    offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+    offscreenTextureDesc.CPUAccessFlags = 0;
+    offscreenTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+
+    HRESULT hr = aDevice->CreateTexture2D(&offscreenTextureDesc, NULL, getter_AddRefs(offscreenTexture));
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingCreateTexture2DFail";
+        return false;
+    }
+
+    hr = offscreenTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(keyedMutex));
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingKeyedMutexFailed";
+        return false;
+    }
+    D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
+    offscreenRTVDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+    offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+    offscreenRTVDesc.Texture2D.MipSlice = 0;
+
+    RefPtr<ID3D11RenderTargetView> offscreenRTView;
+    hr = aDevice->CreateRenderTargetView(offscreenTexture, &offscreenRTVDesc, getter_AddRefs(offscreenRTView));
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingCreateRenderTargetViewFailed";
+        return false;
+    }
+
+    // Acquire and clear
+    keyedMutex->AcquireSync(0, INFINITE);
+    FLOAT color1[4] = { 1, 1, 0.5, 1 };
+    deviceContext->ClearRenderTargetView(offscreenRTView, color1);
+    keyedMutex->ReleaseSync(0);
+
+
+    keyedMutex->AcquireSync(0, INFINITE);
+    FLOAT color2[4] = { 1, 1, 0, 1 };
+
+    deviceContext->ClearRenderTargetView(offscreenRTView, color2);
+    D3D11_TEXTURE2D_DESC desc;
+
+    offscreenTexture->GetDesc(&desc);
+    desc.Usage = D3D11_USAGE_STAGING;
+    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+    desc.MiscFlags = 0;
+    desc.BindFlags = 0;
+    ID3D11Texture2D* cpuTexture;
+    hr = aDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingCreateCPUTextureFailed";
+        return false;
+    }
+
+    deviceContext->CopyResource(cpuTexture, offscreenTexture);
+
+    D3D11_MAPPED_SUBRESOURCE mapped;
+    hr = deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
+    if (FAILED(hr)) {
+        gfxCriticalNote << "DoesRecreatingMapFailed " << hexa(hr);
+        return false;
+    }
+    int resultColor = *(int*)mapped.pData;
+    deviceContext->Unmap(cpuTexture, 0);
+    cpuTexture->Release();
+
+    // XXX on some drivers resultColor will not have changed to
+    // match the clear
+    if (resultColor != 0xffffff00) {
+        gfxCriticalNote << "RenderTargetViewNeedsRecreating";
+        result = true;
+    }
+
+    keyedMutex->ReleaseSync(0);
+    return result;
+}
+
+/* static */ bool
+D3D11Checks::DoesDeviceWork()
+{
+  static bool checked = false;
+  static bool result = false;
+
+  if (checked)
+      return result;
+  checked = true;
+
+  if (gfxPrefs::Direct2DForceEnabled() ||
+      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
+  {
+    result = true;
+    return true;
+  }
+
+  if (GetModuleHandleW(L"igd10umd32.dll")) {
+    const wchar_t* checkModules[] = {L"dlumd32.dll",
+                                     L"dlumd11.dll",
+                                     L"dlumd10.dll"};
+    for (int i=0; i<PR_ARRAY_SIZE(checkModules); i+=1) {
+      if (GetModuleHandleW(checkModules[i])) {
+        nsString displayLinkModuleVersionString;
+        gfxWindowsPlatform::GetDLLVersion(checkModules[i],
+                                          displayLinkModuleVersionString);
+        uint64_t displayLinkModuleVersion;
+        if (!ParseDriverVersion(displayLinkModuleVersionString,
+                                &displayLinkModuleVersion)) {
+          gfxCriticalError() << "DisplayLink: could not parse version "
+                             << checkModules[i];
+          return false;
+        }
+        if (displayLinkModuleVersion <= V(8,6,1,36484)) {
+          gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DisplayLink: too old version " << displayLinkModuleVersionString.get();
+          return false;
+        }
+      }
+    }
+  }
+  result = true;
+  return true;
+}
+
+static bool
+TryCreateTexture2D(ID3D11Device *device,
+                   D3D11_TEXTURE2D_DESC* desc,
+                   D3D11_SUBRESOURCE_DATA* data,
+                   RefPtr<ID3D11Texture2D>& texture)
+{
+  // Older Intel driver version (see bug 1221348 for version #s) crash when
+  // creating a texture with shared keyed mutex and data.
+  MOZ_SEH_TRY {
+    return !FAILED(device->CreateTexture2D(desc, data, getter_AddRefs(texture)));
+  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+    // For now we want to aggregrate all the crash signature to a known crash.
+    gfxDevCrash(LogReason::TextureCreation) << "Crash creating texture. See bug 1221348.";
+    return false;
+  }
+}
+
+// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
+// with E_OUTOFMEMORY.
+static bool
+DoesTextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT format, UINT bindflags)
+{
+  // CreateTexture2D is known to crash on lower feature levels, see bugs
+  // 1170211 and 1089413.
+  if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
+    return false;
+  }
+
+  if (gfxPrefs::Direct2DForceEnabled() ||
+      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
+  {
+    return true;
+  }
+
+  if (GetModuleHandleW(L"atidxx32.dll")) {
+    nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+    if (gfxInfo) {
+      nsString vendorID, vendorID2;
+      gfxInfo->GetAdapterVendorID(vendorID);
+      gfxInfo->GetAdapterVendorID2(vendorID2);
+      if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
+        if (!gfxPrefs::LayersAMDSwitchableGfxEnabled()) {
+          return false;
+        }
+        gfxCriticalError(CriticalLog::DefaultOptions(false)) << "PossiblyBrokenSurfaceSharing_UnexpectedAMDGPU";
+      }
+    }
+  }
+
+  RefPtr<ID3D11Texture2D> texture;
+  D3D11_TEXTURE2D_DESC desc;
+  const int texture_size = 32;
+  desc.Width = texture_size;
+  desc.Height = texture_size;
+  desc.MipLevels = 1;
+  desc.ArraySize = 1;
+  desc.Format = format;
+  desc.SampleDesc.Count = 1;
+  desc.SampleDesc.Quality = 0;
+  desc.Usage = D3D11_USAGE_DEFAULT;
+  desc.CPUAccessFlags = 0;
+  desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+  desc.BindFlags = bindflags;
+
+  uint32_t color[texture_size * texture_size];
+  for (size_t i = 0; i < sizeof(color)/sizeof(color[0]); i++) {
+    color[i] = 0xff00ffff;
+  }
+  // XXX If we pass the data directly at texture creation time we
+  //     get a crash on Intel 8.5.10.[18xx-1994] drivers.
+  //     We can work around this issue by doing UpdateSubresource.
+  if (!TryCreateTexture2D(device, &desc, nullptr, texture)) {
+    gfxCriticalNote << "DoesD3D11TextureSharingWork_TryCreateTextureFailure";
+    return false;
+  }
+
+  RefPtr<IDXGIKeyedMutex> sourceSharedMutex;
+  texture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sourceSharedMutex));
+  if (FAILED(sourceSharedMutex->AcquireSync(0, 30*1000))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceMutexTimeout";
+    // only wait for 30 seconds
+    return false;
+  }
+
+  RefPtr<ID3D11DeviceContext> deviceContext;
+  device->GetImmediateContext(getter_AddRefs(deviceContext));
+
+  int stride = texture_size * 4;
+  deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride, stride * texture_size);
+
+  if (FAILED(sourceSharedMutex->ReleaseSync(0))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceReleaseSyncTimeout";
+    return false;
+  }
+
+  HANDLE shareHandle;
+  RefPtr<IDXGIResource> otherResource;
+  if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
+                                     getter_AddRefs(otherResource))))
+  {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetResourceFailure";
+    return false;
+  }
+
+  if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
+    return false;
+  }
+
+  RefPtr<ID3D11Resource> sharedResource;
+  RefPtr<ID3D11Texture2D> sharedTexture;
+  if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
+                                        getter_AddRefs(sharedResource))))
+  {
+    gfxCriticalError(CriticalLog::DefaultOptions(false)) << "OpenSharedResource failed for format " << format;
+    return false;
+  }
+
+  if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
+                                            getter_AddRefs(sharedTexture))))
+  {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
+    return false;
+  }
+
+  // create a staging texture for readback
+  RefPtr<ID3D11Texture2D> cpuTexture;
+  desc.Usage = D3D11_USAGE_STAGING;
+  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+  desc.MiscFlags = 0;
+  desc.BindFlags = 0;
+  if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(cpuTexture)))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_CreateTextureFailure";
+    return false;
+  }
+
+  RefPtr<IDXGIKeyedMutex> sharedMutex;
+  sharedResource->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sharedMutex));
+  if (FAILED(sharedMutex->AcquireSync(0, 30*1000))) {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_AcquireSyncTimeout";
+    // only wait for 30 seconds
+    return false;
+  }
+
+  // Copy to the cpu texture so that we can readback
+  deviceContext->CopyResource(cpuTexture, sharedTexture);
+
+  D3D11_MAPPED_SUBRESOURCE mapped;
+  int resultColor = 0;
+  if (SUCCEEDED(deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped))) {
+    // read the texture
+    resultColor = *(int*)mapped.pData;
+    deviceContext->Unmap(cpuTexture, 0);
+  } else {
+    gfxCriticalError() << "DoesD3D11TextureSharingWork_MapFailed";
+    return false;
+  }
+
+  sharedMutex->ReleaseSync(0);
+
+  // check that the color we put in is the color we get out
+  if (resultColor != color[0]) {
+    // Shared surfaces seem to be broken on dual AMD & Intel HW when using the
+    // AMD GPU
+    gfxCriticalNote << "DoesD3D11TextureSharingWork_ColorMismatch";
+    return false;
+  }
+
+  RefPtr<ID3D11ShaderResourceView> sharedView;
+
+  // This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
+  if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, getter_AddRefs(sharedView)))) {
+    gfxCriticalNote << "CreateShaderResourceView failed for format" << format;
+    return false;
+  }
+
+  return true;
+}
+
+/* static */ bool
+D3D11Checks::DoesTextureSharingWork(ID3D11Device *device)
+{
+  return DoesTextureSharingWorkInternal(device, DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
+}
+
+/* static */ bool
+D3D11Checks::DoesAlphaTextureSharingWork(ID3D11Device *device)
+{
+  return DoesTextureSharingWorkInternal(device, DXGI_FORMAT_R8_UNORM, D3D11_BIND_SHADER_RESOURCE);
+}
+
+/* static */ bool
+D3D11Checks::GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out)
+{
+  RefPtr<IDXGIDevice> dxgiDevice;
+  HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice));
+  if (FAILED(hr)) {
+    return false;
+  }
+
+  RefPtr<IDXGIAdapter> dxgiAdapter;
+  if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
+    return false;
+  }
+
+  return SUCCEEDED(dxgiAdapter->GetDesc(out));
+}
+
+/* static */ void
+D3D11Checks::WarnOnAdapterMismatch(ID3D11Device *device)
+{
+  DXGI_ADAPTER_DESC desc;
+  PodZero(&desc);
+  GetDxgiDesc(device, &desc);
+
+  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+  nsString vendorID;
+  gfxInfo->GetAdapterVendorID(vendorID);
+  nsresult ec;
+  int32_t vendor = vendorID.ToInteger(&ec, 16);
+  if (vendor != desc.VendorId) {
+    gfxCriticalNote << "VendorIDMismatch V " << hexa(vendor) << " " << hexa(desc.VendorId);
+  }
+}
+
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/D3D11Checks.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_gfx_thebes_D3D11Checks_h
+#define mozilla_gfx_thebes_D3D11Checks_h
+
+struct ID3D11Device;
+struct DXGI_ADAPTER_DESC;
+
+namespace mozilla {
+namespace gfx {
+
+struct D3D11Checks
+{
+  static bool DoesRenderTargetViewNeedRecreating(ID3D11Device* aDevice);
+  static bool DoesDeviceWork();
+  static bool DoesTextureSharingWork(ID3D11Device *device);
+  static bool DoesAlphaTextureSharingWork(ID3D11Device *device);
+  static void WarnOnAdapterMismatch(ID3D11Device* device);
+  static bool GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out);
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // mozilla_gfx_thebes_D3D11Checks_h
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/DeviceManagerD3D11.cpp
@@ -0,0 +1,678 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DeviceManagerD3D11.h"
+#include "D3D11Checks.h"
+#include "gfxConfig.h"
+#include "GfxDriverInfo.h"
+#include "gfxPrefs.h"
+#include "gfxWindowsPlatform.h"
+#include "mozilla/D3DMessageUtils.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/WindowsVersion.h"
+#include "mozilla/gfx/GraphicsMessages.h"
+#include "mozilla/gfx/Logging.h"
+#include "nsIGfxInfo.h"
+#include "nsWindowsHelpers.h"
+#include <d3d11.h>
+
+namespace mozilla {
+namespace gfx {
+
+using namespace mozilla::widget;
+
+StaticAutoPtr<DeviceManagerD3D11> DeviceManagerD3D11::sInstance;
+
+// We don't have access to the D3D11CreateDevice type in gfxWindowsPlatform.h,
+// since it doesn't include d3d11.h, so we use a static here. It should only
+// be used within InitializeD3D11.
+decltype(D3D11CreateDevice)* sD3D11CreateDeviceFn = nullptr;
+
+/* static */ void
+DeviceManagerD3D11::Init()
+{
+  sInstance = new DeviceManagerD3D11();
+}
+
+/* static */ void
+DeviceManagerD3D11::Shutdown()
+{
+  sInstance = nullptr;
+}
+
+DeviceManagerD3D11::DeviceManagerD3D11()
+ : mDeviceLock("gfxWindowsPlatform.mDeviceLock"),
+   mIsWARP(false),
+   mTextureSharingWorks(false)
+{
+  // Set up the D3D11 feature levels we can ask for.
+  if (IsWin8OrLater()) {
+    mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
+  }
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
+  mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
+}
+
+static inline bool
+IsWARPStable()
+{
+  // It seems like nvdxgiwrap makes a mess of WARP. See bug 1154703.
+  if (!IsWin8OrLater() || GetModuleHandleA("nvdxgiwrap.dll")) {
+    return false;
+  }
+  return true;
+}
+
+bool
+DeviceManagerD3D11::CanUseD3D11ImageBridge()
+{
+  if (XRE_IsContentProcess()) {
+    if (!gfxPlatform::GetPlatform()->GetParentDevicePrefs().useD3D11ImageBridge()) {
+      return false;
+    }
+  }
+  return !mIsWARP;
+}
+
+void
+DeviceManagerD3D11::CreateDevices()
+{
+  FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
+  MOZ_ASSERT(d3d11.IsEnabled());
+
+  nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll"));
+  sD3D11CreateDeviceFn =
+    (decltype(D3D11CreateDevice)*)GetProcAddress(d3d11Module, "D3D11CreateDevice");
+
+  if (!sD3D11CreateDeviceFn) {
+    // We should just be on Windows Vista or XP in this case.
+    d3d11.SetFailed(FeatureStatus::Unavailable, "Direct3D11 not available on this computer",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_LIB"));
+    return;
+  }
+
+  // Check if a failure was injected for testing.
+  if (gfxPrefs::DeviceFailForTesting()) {
+    d3d11.SetFailed(FeatureStatus::Failed, "Direct3D11 device failure simulated by preference",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_SIM"));
+    return;
+  }
+
+  if (XRE_IsParentProcess()) {
+    if (!gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
+      AttemptD3D11DeviceCreation(d3d11);
+      if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
+        return;
+      }
+
+      // If we failed to get a device, but WARP is allowed and might work,
+      // re-enable D3D11 and switch to WARP.
+      if (!mCompositorDevice && IsWARPStable() && !gfxPrefs::LayersD3D11DisableWARP()) {
+        gfxConfig::Reenable(Feature::D3D11_COMPOSITING, Fallback::USE_D3D11_WARP_COMPOSITOR);
+      }
+    }
+
+    // If that failed, see if we can use WARP.
+    if (gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
+      MOZ_ASSERT(d3d11.IsEnabled());
+      MOZ_ASSERT(!mCompositorDevice);
+      MOZ_ASSERT(IsWARPStable() || gfxPrefs::LayersD3D11ForceWARP());
+
+      AttemptWARPDeviceCreation();
+      if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
+        return;
+      }
+    }
+
+    // If we still have no device by now, exit.
+    if (!mCompositorDevice) {
+      MOZ_ASSERT(!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING));
+      return;
+    }
+
+    // Either device creation function should have returned Available.
+    MOZ_ASSERT(d3d11.IsEnabled());
+  } else {
+    // Child processes do not need a compositor, but they do need to know
+    // whether the parent process is using WARP and whether or not texture
+    // sharing works.
+    mIsWARP = gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR);
+    mTextureSharingWorks =
+      gfxPlatform::GetPlatform()->GetParentDevicePrefs().d3d11TextureSharingWorks();
+  }
+
+  if (CanUseD3D11ImageBridge()) {
+    if (AttemptD3D11ImageBridgeDeviceCreation() == FeatureStatus::CrashedInHandler) {
+      DisableD3D11AfterCrash();
+      return;
+    }
+  }
+
+  if (AttemptD3D11ContentDeviceCreation() == FeatureStatus::CrashedInHandler) {
+    DisableD3D11AfterCrash();
+    return;
+  }
+
+  // We leak these everywhere and we need them our entire runtime anyway, let's
+  // leak it here as well. We keep the pointer to sD3D11CreateDeviceFn around
+  // as well for D2D1 and device resets.
+  d3d11Module.disown();
+}
+
+IDXGIAdapter1*
+DeviceManagerD3D11::GetDXGIAdapter()
+{
+  if (mAdapter) {
+    return mAdapter;
+  }
+
+  nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
+  decltype(CreateDXGIFactory1)* createDXGIFactory1 = (decltype(CreateDXGIFactory1)*)
+    GetProcAddress(dxgiModule, "CreateDXGIFactory1");
+
+  if (!createDXGIFactory1) {
+    return nullptr;
+  }
+
+  // Try to use a DXGI 1.1 adapter in order to share resources
+  // across processes.
+  RefPtr<IDXGIFactory1> factory1;
+  HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
+                                  getter_AddRefs(factory1));
+  if (FAILED(hr) || !factory1) {
+    // This seems to happen with some people running the iZ3D driver.
+    // They won't get acceleration.
+    return nullptr;
+  }
+
+  if (!XRE_IsContentProcess()) {
+    // In the parent process, we pick the first adapter.
+    if (FAILED(factory1->EnumAdapters1(0, getter_AddRefs(mAdapter)))) {
+      return nullptr;
+    }
+  } else {
+    const DxgiAdapterDesc& parent =
+      gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
+
+    // In the child process, we search for the adapter that matches the parent
+    // process. The first adapter can be mismatched on dual-GPU systems.
+    for (UINT index = 0; ; index++) {
+      RefPtr<IDXGIAdapter1> adapter;
+      if (FAILED(factory1->EnumAdapters1(index, getter_AddRefs(adapter)))) {
+        break;
+      }
+
+      DXGI_ADAPTER_DESC desc;
+      if (SUCCEEDED(adapter->GetDesc(&desc)) &&
+          desc.AdapterLuid.HighPart == parent.AdapterLuid.HighPart &&
+          desc.AdapterLuid.LowPart == parent.AdapterLuid.LowPart &&
+          desc.VendorId == parent.VendorId &&
+          desc.DeviceId == parent.DeviceId)
+      {
+        mAdapter = adapter.forget();
+        break;
+      }
+    }
+  }
+
+  if (!mAdapter) {
+    return nullptr;
+  }
+
+  // We leak this module everywhere, we might as well do so here as well.
+  dxgiModule.disown();
+  return mAdapter;
+}
+
+bool
+DeviceManagerD3D11::AttemptD3D11DeviceCreationHelper(
+  IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aOutDevice, HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(
+        aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+        // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
+        // to prevent bug 1092260. IE 11 also uses this flag.
+        D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
+  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+void
+DeviceManagerD3D11::AttemptD3D11DeviceCreation(FeatureState& d3d11)
+{
+  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
+  if (!adapter) {
+    d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI"));
+    return;
+  }
+
+  HRESULT hr;
+  RefPtr<ID3D11Device> device;
+  if (!AttemptD3D11DeviceCreationHelper(adapter, device, hr)) {
+    gfxCriticalError() << "Crash during D3D11 device creation";
+    d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1"));
+    return;
+  }
+
+  if (FAILED(hr) || !device) {
+    gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr);
+    d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2"));
+    return;
+  }
+  if (!D3D11Checks::DoesDeviceWork()) {
+    d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN"));
+    return;
+  }
+
+  {
+    MutexAutoLock lock(mDeviceLock);
+    mCompositorDevice = device;
+  }
+
+  // Only test this when not using WARP since it can fail and cause
+  // GetDeviceRemovedReason to return weird values.
+  mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
+
+  if (!mTextureSharingWorks) {
+    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
+                         FeatureStatus::Broken,
+                         "Texture sharing doesn't work");
+  }
+
+  if (D3D11Checks::DoesRenderTargetViewNeedRecreating(mCompositorDevice)) {
+    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
+                         FeatureStatus::Broken,
+                         "RenderTargetViews need recreating");
+  }
+
+  // It seems like this may only happen when we're using the NVIDIA gpu
+  D3D11Checks::WarnOnAdapterMismatch(mCompositorDevice);
+
+  mCompositorDevice->SetExceptionMode(0);
+  mIsWARP = false;
+}
+
+bool
+DeviceManagerD3D11::AttemptWARPDeviceCreationHelper(
+  ScopedGfxFeatureReporter& aReporterWARP,
+  RefPtr<ID3D11Device>& aOutDevice,
+  HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(
+        nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
+        // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
+        // to prevent bug 1092260. IE 11 also uses this flag.
+        D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
+
+    aReporterWARP.SetSuccessful();
+  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+void
+DeviceManagerD3D11::AttemptWARPDeviceCreation()
+{
+  ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
+  FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
+
+  HRESULT hr;
+  RefPtr<ID3D11Device> device;
+  if (!AttemptWARPDeviceCreationHelper(reporterWARP, device, hr)) {
+    gfxCriticalError() << "Exception occurred initializing WARP D3D11 device!";
+    d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed creating a D3D11 WARP device",
+                     NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE"));
+    return;
+  }
+
+  if (FAILED(hr) || !device) {
+    // This should always succeed... in theory.
+    gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr);
+    d3d11.SetFailed(FeatureStatus::Failed, "Failed to create a D3D11 WARP device",
+                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE2"));
+    return;
+  }
+
+  {
+    MutexAutoLock lock(mDeviceLock);
+    mCompositorDevice = device;
+  }
+
+  // Only test for texture sharing on Windows 8 since it puts the device into
+  // an unusable state if used on Windows 7
+  if (IsWin8OrLater()) {
+    mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
+  }
+  mCompositorDevice->SetExceptionMode(0);
+  mIsWARP = true;
+}
+
+bool
+DeviceManagerD3D11::AttemptD3D11ContentDeviceCreationHelper(
+  IDXGIAdapter1* aAdapter, HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(
+        aAdapter, mIsWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN,
+        nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(mContentDevice), nullptr, nullptr);
+
+  } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+FeatureStatus
+DeviceManagerD3D11::AttemptD3D11ContentDeviceCreation()
+{
+  RefPtr<IDXGIAdapter1> adapter;
+  if (!mIsWARP) {
+    adapter = GetDXGIAdapter();
+    if (!adapter) {
+      return FeatureStatus::Unavailable;
+    }
+  }
+
+  HRESULT hr;
+  if (!AttemptD3D11ContentDeviceCreationHelper(adapter, hr)) {
+    gfxCriticalNote << "Recovered from crash while creating a D3D11 content device";
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
+    return FeatureStatus::CrashedInHandler;
+  }
+
+  if (FAILED(hr) || !mContentDevice) {
+    gfxCriticalNote << "Failed to create a D3D11 content device: " << hexa(hr);
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
+    return FeatureStatus::Failed;
+  }
+
+  // InitializeD2D() will abort early if the compositor device did not support
+  // texture sharing. If we're in the content process, we can't rely on the
+  // parent device alone: some systems have dual GPUs that are capable of
+  // binding the parent and child processes to different GPUs. As a safety net,
+  // we re-check texture sharing against the newly created D3D11 content device.
+  // If it fails, we won't use Direct2D.
+  if (XRE_IsContentProcess()) {
+    if (!D3D11Checks::DoesTextureSharingWork(mContentDevice)) {
+      mContentDevice = nullptr;
+      return FeatureStatus::Failed;
+    }
+
+    DebugOnly<bool> ok = ContentAdapterIsParentAdapter(mContentDevice);
+    MOZ_ASSERT(ok);
+  }
+
+  mContentDevice->SetExceptionMode(0);
+
+  RefPtr<ID3D10Multithread> multi;
+  hr = mContentDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
+  if (SUCCEEDED(hr) && multi) {
+    multi->SetMultithreadProtected(TRUE);
+  }
+  return FeatureStatus::Available;
+}
+
+bool
+DeviceManagerD3D11::AttemptD3D11ImageBridgeDeviceCreationHelper(
+  IDXGIAdapter1* aAdapter,
+  HRESULT& aResOut)
+{
+  MOZ_SEH_TRY {
+    aResOut =
+      sD3D11CreateDeviceFn(GetDXGIAdapter(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+                           D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+                           mFeatureLevels.Elements(), mFeatureLevels.Length(),
+                           D3D11_SDK_VERSION, getter_AddRefs(mImageBridgeDevice), nullptr, nullptr);
+  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+FeatureStatus
+DeviceManagerD3D11::AttemptD3D11ImageBridgeDeviceCreation()
+{
+  HRESULT hr;
+  if (!AttemptD3D11ImageBridgeDeviceCreationHelper(GetDXGIAdapter(), hr)) {
+    gfxCriticalNote << "Recovered from crash while creating a D3D11 image bridge device";
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Image);
+    return FeatureStatus::CrashedInHandler;
+  }
+
+  if (FAILED(hr) || !mImageBridgeDevice) {
+    gfxCriticalNote << "Failed to create a content image bridge device: " << hexa(hr);
+    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Image);
+    return FeatureStatus::Failed;
+  }
+
+  mImageBridgeDevice->SetExceptionMode(0);
+  if (!D3D11Checks::DoesAlphaTextureSharingWork(mImageBridgeDevice)) {
+    mImageBridgeDevice = nullptr;
+    return FeatureStatus::Failed;
+  }
+
+  if (XRE_IsContentProcess()) {
+    ContentAdapterIsParentAdapter(mImageBridgeDevice);
+  }
+  return FeatureStatus::Available;
+}
+
+bool
+DeviceManagerD3D11::CreateD3D11DecoderDeviceHelper(
+  IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice, HRESULT& aResOut)
+{
+  MOZ_SEH_TRY{
+    aResOut =
+      sD3D11CreateDeviceFn(
+        aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+        D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
+        mFeatureLevels.Elements(), mFeatureLevels.Length(),
+        D3D11_SDK_VERSION, getter_AddRefs(aDevice), nullptr, nullptr);
+
+  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+    return false;
+  }
+  return true;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::CreateDecoderDevice()
+{
+   if (!sD3D11CreateDeviceFn) {
+    // We should just be on Windows Vista or XP in this case.
+    return nullptr;
+  }
+
+  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
+  if (!adapter) {
+    return nullptr;
+  }
+
+  RefPtr<ID3D11Device> device;
+
+  HRESULT hr;
+  if (!CreateD3D11DecoderDeviceHelper(adapter, device, hr)) {
+    return nullptr;
+  }
+  if (FAILED(hr) || !device || !D3D11Checks::DoesDeviceWork()) {
+    return nullptr;
+  }
+
+  RefPtr<ID3D10Multithread> multi;
+  device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
+
+  multi->SetMultithreadProtected(TRUE);
+  return device;
+}
+
+void
+DeviceManagerD3D11::ResetDevices()
+{
+  MutexAutoLock lock(mDeviceLock);
+
+  mCompositorDevice = nullptr;
+  mContentDevice = nullptr;
+  mImageBridgeDevice = nullptr;
+  Factory::SetDirect3D11Device(nullptr);
+}
+
+bool
+DeviceManagerD3D11::ContentAdapterIsParentAdapter(ID3D11Device* device)
+{
+  DXGI_ADAPTER_DESC desc;
+  if (!D3D11Checks::GetDxgiDesc(device, &desc)) {
+    gfxCriticalNote << "Could not query device DXGI adapter info";
+    return false;
+  }
+
+  const DxgiAdapterDesc& parent =
+    gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
+  if (desc.VendorId != parent.VendorId ||
+      desc.DeviceId != parent.DeviceId ||
+      desc.SubSysId != parent.SubSysId ||
+      desc.AdapterLuid.HighPart != parent.AdapterLuid.HighPart ||
+      desc.AdapterLuid.LowPart != parent.AdapterLuid.LowPart)
+  {
+    gfxCriticalNote << "VendorIDMismatch P " << hexa(parent.VendorId) << " " << hexa(desc.VendorId);
+    return false;
+  }
+
+  return true;
+}
+
+static DeviceResetReason HResultToResetReason(HRESULT hr)
+{
+  switch (hr) {
+  case DXGI_ERROR_DEVICE_HUNG:
+    return DeviceResetReason::HUNG;
+  case DXGI_ERROR_DEVICE_REMOVED:
+    return DeviceResetReason::REMOVED;
+  case DXGI_ERROR_DEVICE_RESET:
+    return DeviceResetReason::RESET;
+  case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+    return DeviceResetReason::DRIVER_ERROR;
+  case DXGI_ERROR_INVALID_CALL:
+    return DeviceResetReason::INVALID_CALL;
+  case E_OUTOFMEMORY:
+    return DeviceResetReason::OUT_OF_MEMORY;
+  default:
+    MOZ_ASSERT(false);
+  }
+  return DeviceResetReason::UNKNOWN;
+}
+
+static inline bool
+DidDeviceReset(RefPtr<ID3D11Device> aDevice, DeviceResetReason* aOutReason)
+{
+  if (!aDevice) {
+    return false;
+  }
+  HRESULT hr = aDevice->GetDeviceRemovedReason();
+  if (hr == S_OK) {
+    return false;
+  }
+
+  *aOutReason = HResultToResetReason(hr);
+  return true;
+}
+
+bool
+DeviceManagerD3D11::GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason)
+{
+  // Note: this can be called off the main thread, so we need to use
+  // our threadsafe getters.
+  if (DidDeviceReset(GetCompositorDevice(), aOutReason) ||
+      DidDeviceReset(GetImageBridgeDevice(), aOutReason) ||
+      DidDeviceReset(GetContentDevice(), aOutReason))
+  {
+    return true;
+  }
+  return false;
+}
+
+void
+DeviceManagerD3D11::DisableD3D11AfterCrash()
+{
+  gfxConfig::Disable(Feature::D3D11_COMPOSITING,
+    FeatureStatus::CrashedInHandler,
+    "Crashed while acquiring a Direct3D11 device",
+    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_CRASH"));
+  ResetDevices();
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetCompositorDevice()
+{
+  MutexAutoLock lock(mDeviceLock);
+  return mCompositorDevice;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetImageBridgeDevice()
+{
+  MutexAutoLock lock(mDeviceLock);
+  return mImageBridgeDevice;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetContentDevice()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  return mContentDevice;
+}
+
+RefPtr<ID3D11Device>
+DeviceManagerD3D11::GetDeviceForCurrentThread()
+{
+  if (NS_IsMainThread()) {
+    return GetContentDevice();
+  }
+  return GetCompositorDevice();
+}
+
+unsigned
+DeviceManagerD3D11::GetD3D11Version() const
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  if (!mCompositorDevice) {
+    return 0;
+  }
+  return mCompositorDevice->GetFeatureLevel();
+}
+
+bool
+DeviceManagerD3D11::TextureSharingWorks() const
+{
+  return mTextureSharingWorks;
+}
+
+bool
+DeviceManagerD3D11::IsWARP() const
+{
+  return mIsWARP;
+}
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/DeviceManagerD3D11.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_gfx_thebes_DeviceManagerD3D11_h
+#define mozilla_gfx_thebes_DeviceManagerD3D11_h
+
+#include "gfxPlatform.h"
+#include "gfxTelemetry.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPtr.h"
+#include "nsTArray.h"
+
+#include <windows.h>
+#include <objbase.h>
+
+#include <dxgi.h>
+
+// This header is available in the June 2010 SDK and in the Win8 SDK
+#include <d3dcommon.h>
+// Win 8.0 SDK types we'll need when building using older sdks.
+#if !defined(D3D_FEATURE_LEVEL_11_1) // defined in the 8.0 SDK only
+#define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
+#define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
+#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
+#endif
+
+struct ID3D11Device;
+
+namespace mozilla {
+class ScopedGfxFeatureReporter;
+
+namespace gfx {
+class FeatureState;
+
+class DeviceManagerD3D11 final
+{
+public:
+  static void Init();
+  static void Shutdown();
+
+  DeviceManagerD3D11();
+
+  static DeviceManagerD3D11* Get() {
+    return sInstance;
+  }
+
+  RefPtr<ID3D11Device> GetCompositorDevice();
+  RefPtr<ID3D11Device> GetImageBridgeDevice();
+  RefPtr<ID3D11Device> GetContentDevice();
+  RefPtr<ID3D11Device> GetDeviceForCurrentThread();
+  RefPtr<ID3D11Device> CreateDecoderDevice();
+
+  unsigned GetD3D11Version() const;
+  bool TextureSharingWorks() const;
+  bool IsWARP() const;
+
+  void CreateDevices();
+  void ResetDevices();
+
+  // Call GetDeviceRemovedReason on each device until one returns
+  // a failure.
+  bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason);
+
+private:
+  IDXGIAdapter1 *GetDXGIAdapter();
+
+  bool CanUseD3D11ImageBridge();
+
+  void DisableD3D11AfterCrash();
+
+  void AttemptD3D11DeviceCreation(mozilla::gfx::FeatureState& d3d11);
+  bool AttemptD3D11DeviceCreationHelper(
+      IDXGIAdapter1* aAdapter,
+      RefPtr<ID3D11Device>& aOutDevice,
+      HRESULT& aResOut);
+
+  void AttemptWARPDeviceCreation();
+  bool AttemptWARPDeviceCreationHelper(
+      mozilla::ScopedGfxFeatureReporter& aReporterWARP,
+      RefPtr<ID3D11Device>& aOutDevice,
+      HRESULT& aResOut);
+
+  bool AttemptD3D11ImageBridgeDeviceCreationHelper(
+      IDXGIAdapter1* aAdapter, HRESULT& aResOut);
+  mozilla::gfx::FeatureStatus AttemptD3D11ImageBridgeDeviceCreation();
+
+  mozilla::gfx::FeatureStatus AttemptD3D11ContentDeviceCreation();
+  bool AttemptD3D11ContentDeviceCreationHelper(
+      IDXGIAdapter1* aAdapter, HRESULT& aResOut);
+
+  // Create a D3D11 device to be used for DXVA decoding.
+  bool CreateD3D11DecoderDeviceHelper(
+      IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice,
+      HRESULT& aResOut);
+
+  bool ContentAdapterIsParentAdapter(ID3D11Device* device);
+
+private:
+  static StaticAutoPtr<DeviceManagerD3D11> sInstance;
+
+  mozilla::Mutex mDeviceLock;
+  nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
+  RefPtr<IDXGIAdapter1> mAdapter;
+  RefPtr<ID3D11Device> mCompositorDevice;
+  RefPtr<ID3D11Device> mContentDevice;
+  RefPtr<ID3D11Device> mImageBridgeDevice;
+  mozilla::Atomic<bool> mIsWARP;
+  mozilla::Atomic<bool> mTextureSharingWorks;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // mozilla_gfx_thebes_DeviceManagerD3D11_h
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -21,16 +21,17 @@
 #include "GeckoProfiler.h"
 #include "gfx2DGlue.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/gfx/DrawTargetTiled.h"
 #include <algorithm>
 
 #if XP_WIN
 #include "gfxWindowsPlatform.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 UserDataKey gfxContext::sDontUseAsSourceKey;
 
 
@@ -1237,17 +1238,18 @@ gfxContext::PushNewDT(gfxContentType con
 
   if (!newDT) {
     NS_WARNING("Failed to create DrawTarget of sufficient size.");
     newDT = mDT->CreateSimilarDrawTarget(IntSize(64, 64), format);
 
     if (!newDT) {
       if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()
 #ifdef XP_WIN
-          && !(mDT->GetBackendType() == BackendType::DIRECT2D1_1 && !gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())
+          && !(mDT->GetBackendType() == BackendType::DIRECT2D1_1 &&
+               !DeviceManagerD3D11::Get()->GetContentDevice())
 #endif
           ) {
         // If even this fails.. we're most likely just out of memory!
         NS_ABORT_OOM(BytesPerPixel(format) * 64 * 64);
       }
       newDT = CurrentState().drawTarget;
     }
   }
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -1773,8 +1773,13 @@ gfxFontUtils::IsCffFont(const uint8_t* a
     // this is only called after aFontData has passed basic validation,
     // so we know there is enough data present to allow us to read the version!
     const SFNTHeader *sfntHeader = reinterpret_cast<const SFNTHeader*>(aFontData);
     return (sfntHeader->sfntVersion == TRUETYPE_TAG('O','T','T','O'));
 }
 
 #endif
 
+#undef acceptablePlatform
+#undef isSymbol
+#undef isUVSEncoding
+#undef LOG
+#undef LOG_ENABLED
--- a/gfx/thebes/gfxGlyphExtents.h
+++ b/gfx/thebes/gfxGlyphExtents.h
@@ -10,30 +10,38 @@
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "mozilla/MemoryReporting.h"
 
 class gfxContext;
 struct gfxRect;
 
+namespace mozilla {
+namespace gfx {
+class DrawTarget;
+} // namespace gfx
+} // namespace mozilla
+
 /**
  * This stores glyph bounds information for a particular gfxFont, at
  * a particular appunits-per-dev-pixel ratio (because the compressed glyph
  * width array is stored in appunits).
  * 
  * We store a hashtable from glyph IDs to float bounding rects. For the
  * common case where the glyph has no horizontal left bearing, and no
  * y overflow above the font ascent or below the font descent, and tight
  * bounding boxes are not required, we avoid storing the glyph ID in the hashtable
  * and instead consult an array of 16-bit glyph XMost values (in appunits).
  * This array always has an entry for the font's space glyph --- the width is
  * assumed to be zero.
  */
 class gfxGlyphExtents {
+    typedef mozilla::gfx::DrawTarget DrawTarget;
+
 public:
     explicit gfxGlyphExtents(int32_t aAppUnitsPerDevUnit) :
         mAppUnitsPerDevUnit(aAppUnitsPerDevUnit) {
         MOZ_COUNT_CTOR(gfxGlyphExtents);
     }
     ~gfxGlyphExtents();
 
     enum { INVALID_WIDTH = 0xFFFF };
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -1598,8 +1598,11 @@ gfxPlatformFontList::AddSizeOfExcludingT
 
 void
 gfxPlatformFontList::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
                                             FontListSizes* aSizes) const
 {
     aSizes->mFontListSize += aMallocSizeOf(this);
     AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
 }
+
+#undef LOG
+#undef LOG_ENABLED
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -1427,8 +1427,11 @@ gfxUserFontSet::UserFontCache::Dump()
     printf("userfontcache dump count: %d ========\n", sUserFonts->Count());
     for (auto it = sUserFonts->Iter(); !it.Done(); it.Next()) {
         it.Get()->Dump();
     }
     printf("userfontcache dump ==================\n");
 }
 
 #endif
+
+#undef LOG
+#undef LOG_ENABLED
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -25,17 +25,16 @@
 
 #include "nsIWindowsRegKey.h"
 #include "nsIFile.h"
 #include "plbase64.h"
 #include "nsIXULRuntime.h"
 #include "imgLoader.h"
 
 #include "nsIGfxInfo.h"
-#include "GfxDriverInfo.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "gfxGDIFontList.h"
 #include "gfxGDIFont.h"
 
 #include "mozilla/layers/CompositorThread.h"
 #include "DeviceManagerD3D9.h"
@@ -69,29 +68,25 @@
 
 #include "base/thread.h"
 #include "SurfaceCache.h"
 #include "gfxPrefs.h"
 #include "gfxConfig.h"
 #include "VsyncSource.h"
 #include "DriverCrashGuard.h"
 #include "mozilla/dom/ContentParent.h"
+#include "mozilla/gfx/DeviceManagerD3D11.h"
+#include "D3D11Checks.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 using namespace mozilla::image;
 
-enum class TelemetryDeviceCode : uint32_t {
-  Content = 0,
-  Image = 1,
-  D2D1 = 2
-};
-
 DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget)
 {
   mDC = nullptr;
   if (aDrawTarget.GetBackendType() == BackendType::CAIRO) {
     cairo_t* ctx = static_cast<cairo_t*>
       (aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
     if (ctx) {
       cairo_surface_t* surf = cairo_get_group_target(ctx);
@@ -332,20 +327,18 @@ public:
   }
 };
 
 NS_IMPL_ISUPPORTS(D3DSharedTexturesReporter, nsIMemoryReporter)
 
 gfxWindowsPlatform::gfxWindowsPlatform()
   : mRenderMode(RENDER_GDI)
   , mDeviceLock("gfxWindowsPlatform.mDeviceLock")
-  , mIsWARP(false)
   , mHasDeviceReset(false)
   , mHasFakeDeviceReset(false)
-  , mCompositorD3D11TextureSharingWorks(false)
   , mHasD3D9DeviceReset(false)
 {
   mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
   mUseClearTypeAlways = UNINITIALIZED_VALUE;
 
   /* 
    * Initialize COM 
    */ 
@@ -353,25 +346,21 @@ gfxWindowsPlatform::gfxWindowsPlatform()
 
   RegisterStrongMemoryReporter(new GfxD2DVramReporter());
   RegisterStrongMemoryReporter(new GPUAdapterReporter());
   RegisterStrongMemoryReporter(new D3DSharedTexturesReporter());
 }
 
 gfxWindowsPlatform::~gfxWindowsPlatform()
 {
+  DeviceManagerD3D11::Shutdown();
   mDeviceManager = nullptr;
-  mD3D11Device = nullptr;
-  mD3D11ContentDevice = nullptr;
-  mD3D11ImageBridgeDevice = nullptr;
 
   mozilla::gfx::Factory::D2DCleanup();
 
-  mAdapter = nullptr;
-
   /* 
    * Uninitialize COM 
    */ 
   CoUninitialize();
 }
 
 static void
 UpdateANGLEConfig()
@@ -390,29 +379,32 @@ gfxWindowsPlatform::InitAcceleration()
   if (IsWin8OrLater()) {
     mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
   }
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
   mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
 
+  DeviceManagerD3D11::Init();
+
   InitializeConfig();
   InitializeDevices();
   UpdateANGLEConfig();
   UpdateRenderMode();
 }
 
 bool
 gfxWindowsPlatform::CanUseHardwareVideoDecoding()
 {
-  if (!gfxPrefs::LayersPreferD3D9() && !mCompositorD3D11TextureSharingWorks) {
+  DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
+  if (!gfxPrefs::LayersPreferD3D9() && !dm->TextureSharingWorks()) {
     return false;
   }
-  return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
+  return !dm->IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
 }
 
 bool
 gfxWindowsPlatform::InitDWriteSupport()
 {
   MOZ_ASSERT(!mDWriteFactory && IsVistaOrLater());
 
   mozilla::ScopedGfxFeatureReporter reporter("DWrite");
@@ -448,25 +440,23 @@ gfxWindowsPlatform::HandleDeviceReset()
     return false;
   }
 
   if (!mHasFakeDeviceReset) {
     Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(resetReason));
   }
 
   // Remove devices and adapters.
-  ResetD3D11Devices();
-  mAdapter = nullptr;
+  DeviceManagerD3D11::Get()->ResetDevices();
 
   // Reset local state. Note: we leave feature status variables as-is. They
   // will be recomputed by InitializeDevices().
   mHasDeviceReset = false;
   mHasFakeDeviceReset = false;
   mHasD3D9DeviceReset = false;
-  mCompositorD3D11TextureSharingWorks = false;
   mDeviceResetReason = DeviceResetReason::OK;
 
   imgLoader::NormalLoader()->ClearCache(true);
   imgLoader::NormalLoader()->ClearCache(false);
   imgLoader::PrivateBrowsingLoader()->ClearCache(true);
   imgLoader::PrivateBrowsingLoader()->ClearCache(false);
   gfxAlphaBoxBlur::ShutdownBlurCache();
 
@@ -912,58 +902,23 @@ gfxWindowsPlatform::IsFontFormatSupporte
     if (aFormatFlags != 0) {
         return false;
     }
 
     // no format hint set, need to look at data
     return true;
 }
 
-static DeviceResetReason HResultToResetReason(HRESULT hr)
-{
-  switch (hr) {
-  case DXGI_ERROR_DEVICE_HUNG:
-    return DeviceResetReason::HUNG;
-  case DXGI_ERROR_DEVICE_REMOVED:
-    return DeviceResetReason::REMOVED;
-  case DXGI_ERROR_DEVICE_RESET:
-    return DeviceResetReason::RESET;
-  case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
-    return DeviceResetReason::DRIVER_ERROR;
-  case DXGI_ERROR_INVALID_CALL:
-    return DeviceResetReason::INVALID_CALL;
-  case E_OUTOFMEMORY:
-    return DeviceResetReason::OUT_OF_MEMORY;
-  default:
-    MOZ_ASSERT(false);
-  }
-  return DeviceResetReason::UNKNOWN;
-}
-
 void
 gfxWindowsPlatform::CompositorUpdated()
 {
   ForceDeviceReset(ForcedDeviceResetReason::COMPOSITOR_UPDATED);
   UpdateRenderMode();
 }
 
-bool
-gfxWindowsPlatform::IsDeviceReset(HRESULT hr, DeviceResetReason* aResetReason)
-{
-  if (hr != S_OK) {
-    mDeviceResetReason = HResultToResetReason(hr);
-    mHasDeviceReset = true;
-    if (aResetReason) {
-      *aResetReason = mDeviceResetReason;
-    }
-    return true;
-  }
-  return false;
-}
-
 void
 gfxWindowsPlatform::TestDeviceReset(DeviceResetReason aReason)
 {
   if (mHasDeviceReset) {
     return;
   }
   mHasDeviceReset = true;
   mHasFakeDeviceReset = true;
@@ -978,28 +933,24 @@ gfxWindowsPlatform::DidRenderingDeviceRe
       *aResetReason = mDeviceResetReason;
     }
     return true;
   }
   if (aResetReason) {
     *aResetReason = DeviceResetReason::OK;
   }
 
-  if (mD3D11Device) {
-    HRESULT hr = mD3D11Device->GetDeviceRemovedReason();
-    if (IsDeviceReset(hr, aResetReason)) {
-      return true;
+  if (DeviceManagerD3D11::Get()->GetAnyDeviceRemovedReason(&mDeviceResetReason)) {
+    mHasDeviceReset = true;
+    if (aResetReason) {
+      *aResetReason = mDeviceResetReason;
     }
+    return true;
   }
-  if (mD3D11ContentDevice) {
-    HRESULT hr = mD3D11ContentDevice->GetDeviceRemovedReason();
-    if (IsDeviceReset(hr, aResetReason)) {
-      return true;
-    }
-  }
+
   if (mHasD3D9DeviceReset) {
     return true;
   }
   if (XRE_IsParentProcess() && gfxPrefs::DeviceResetForTesting()) {
     TestDeviceReset((DeviceResetReason)gfxPrefs::DeviceResetForTesting());
     if (aResetReason) {
       *aResetReason = mDeviceResetReason;
     }
@@ -1407,48 +1358,16 @@ gfxWindowsPlatform::GetD3D9DeviceManager
     }
   }
 
   MutexAutoLock lock(mDeviceLock);
   result = mDeviceManager;
   return result.forget();
 }
 
-bool
-gfxWindowsPlatform::GetD3D11Device(RefPtr<ID3D11Device>* aOutDevice)
-{
-  MutexAutoLock lock(mDeviceLock);
-  *aOutDevice = mD3D11Device;
-  return !!mD3D11Device;
-}
-
-ID3D11Device*
-gfxWindowsPlatform::GetD3D11ContentDevice()
-{
-  return mD3D11ContentDevice;
-}
-
-bool
-gfxWindowsPlatform::GetD3D11ImageBridgeDevice(RefPtr<ID3D11Device>* aOutDevice)
-{
-  MutexAutoLock lock(mDeviceLock);
-  *aOutDevice = mD3D11ImageBridgeDevice;
-  return !!mD3D11ImageBridgeDevice;
-}
-
-bool
-gfxWindowsPlatform::GetD3D11DeviceForCurrentThread(RefPtr<ID3D11Device>* aOutDevice)
-{
-  if (NS_IsMainThread()) {
-    *aOutDevice = mD3D11ContentDevice;
-    return !!mD3D11ContentDevice;
-  }
-  return GetD3D11ImageBridgeDevice(aOutDevice);
-}
-
 ReadbackManagerD3D11*
 gfxWindowsPlatform::GetReadbackManager()
 {
   if (!mD3D11ReadbackManager) {
     mD3D11ReadbackManager = new ReadbackManagerD3D11();
   }
 
   return mD3D11ReadbackManager;
@@ -1466,448 +1385,16 @@ gfxWindowsPlatform::IsOptimus()
             knowIsOptimus = 1;
         } else {
             knowIsOptimus = 0;
         }
     }
     return knowIsOptimus;
 }
 
-IDXGIAdapter1*
-gfxWindowsPlatform::GetDXGIAdapter()
-{
-  if (mAdapter) {
-    return mAdapter;
-  }
-
-  nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
-  decltype(CreateDXGIFactory1)* createDXGIFactory1 = (decltype(CreateDXGIFactory1)*)
-    GetProcAddress(dxgiModule, "CreateDXGIFactory1");
-
-  if (!createDXGIFactory1) {
-    return nullptr;
-  }
-
-  // Try to use a DXGI 1.1 adapter in order to share resources
-  // across processes.
-  RefPtr<IDXGIFactory1> factory1;
-  HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
-                                  getter_AddRefs(factory1));
-  if (FAILED(hr) || !factory1) {
-    // This seems to happen with some people running the iZ3D driver.
-    // They won't get acceleration.
-    return nullptr;
-  }
-
-  if (!XRE_IsContentProcess()) {
-    // In the parent process, we pick the first adapter.
-    if (FAILED(factory1->EnumAdapters1(0, getter_AddRefs(mAdapter)))) {
-      return nullptr;
-    }
-  } else {
-    const DxgiAdapterDesc& parent = GetParentDevicePrefs().adapter();
-
-    // In the child process, we search for the adapter that matches the parent
-    // process. The first adapter can be mismatched on dual-GPU systems.
-    for (UINT index = 0; ; index++) {
-      RefPtr<IDXGIAdapter1> adapter;
-      if (FAILED(factory1->EnumAdapters1(index, getter_AddRefs(adapter)))) {
-        break;
-      }
-
-      DXGI_ADAPTER_DESC desc;
-      if (SUCCEEDED(adapter->GetDesc(&desc)) &&
-          desc.AdapterLuid.HighPart == parent.AdapterLuid.HighPart &&
-          desc.AdapterLuid.LowPart == parent.AdapterLuid.LowPart &&
-          desc.VendorId == parent.VendorId &&
-          desc.DeviceId == parent.DeviceId)
-      {
-        mAdapter = adapter.forget();
-        break;
-      }
-    }
-  }
-
-  if (!mAdapter) {
-    return nullptr;
-  }
-
-  // We leak this module everywhere, we might as well do so here as well.
-  dxgiModule.disown();
-  return mAdapter;
-}
-
-bool DoesD3D11DeviceWork()
-{
-  static bool checked = false;
-  static bool result = false;
-
-  if (checked)
-      return result;
-  checked = true;
-
-  if (gfxPrefs::Direct2DForceEnabled() ||
-      gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
-  {
-    result = true;
-    return true;
-  }
-
-  if (GetModuleHandleW(L"igd10umd32.dll")) {
-    const wchar_t* checkModules[] = {L"dlumd32.dll",
-                                     L"dlumd11.dll",
-                                     L"dlumd10.dll"};
-    for (int i=0; i<PR_ARRAY_SIZE(checkModules); i+=1) {
-      if (GetModuleHandleW(checkModules[i])) {
-        nsString displayLinkModuleVersionString;
-        gfxWindowsPlatform::GetDLLVersion(checkModules[i],
-                                          displayLinkModuleVersionString);
-        uint64_t displayLinkModuleVersion;
-        if (!ParseDriverVersion(displayLinkModuleVersionString,
-                                &displayLinkModuleVersion)) {
-          gfxCriticalError() << "DisplayLink: could not parse version "
-                             << checkModules[i];
-          return false;
-        }
-        if (displayLinkModuleVersion <= V(8,6,1,36484)) {
-          gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DisplayLink: too old version " << displayLinkModuleVersionString.get();
-          return false;
-        }
-      }
-    }
-  }
-  result = true;
-  return true;
-}
-
-static bool
-GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out)
-{
-  RefPtr<IDXGIDevice> dxgiDevice;
-  HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice));
-  if (FAILED(hr)) {
-    return false;
-  }
-
-  RefPtr<IDXGIAdapter> dxgiAdapter;
-  if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
-    return false;
-  }
-
-  return SUCCEEDED(dxgiAdapter->GetDesc(out));
-}
-
-static void
-CheckForAdapterMismatch(ID3D11Device *device)
-{
-  DXGI_ADAPTER_DESC desc;
-  PodZero(&desc);
-  GetDxgiDesc(device, &desc);
-
-  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-  nsString vendorID;
-  gfxInfo->GetAdapterVendorID(vendorID);
-  nsresult ec;
-  int32_t vendor = vendorID.ToInteger(&ec, 16);
-  if (vendor != desc.VendorId) {
-      gfxCriticalNote << "VendorIDMismatch V " << hexa(vendor) << " " << hexa(desc.VendorId);
-  }
-}
-
-bool DoesRenderTargetViewNeedsRecreating(ID3D11Device *device)
-{
-    bool result = false;
-    // CreateTexture2D is known to crash on lower feature levels, see bugs
-    // 1170211 and 1089413.
-    if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
-        return true;
-    }
-
-    RefPtr<ID3D11DeviceContext> deviceContext;
-    device->GetImmediateContext(getter_AddRefs(deviceContext));
-    int backbufferWidth = 32; int backbufferHeight = 32;
-    RefPtr<ID3D11Texture2D> offscreenTexture;
-    RefPtr<IDXGIKeyedMutex> keyedMutex;
-
-    D3D11_TEXTURE2D_DESC offscreenTextureDesc = { 0 };
-    offscreenTextureDesc.Width = backbufferWidth;
-    offscreenTextureDesc.Height = backbufferHeight;
-    offscreenTextureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-    offscreenTextureDesc.MipLevels = 0;
-    offscreenTextureDesc.ArraySize = 1;
-    offscreenTextureDesc.SampleDesc.Count = 1;
-    offscreenTextureDesc.S