merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 15 Jan 2016 11:46:47 +0100
changeset 280145 e1486d83107fc4933982d371828d038ad57682e4
parent 280144 7a91754ea08371fd44cf4842d12f5e64841a38aa (current diff)
parent 280053 3c18be4736c724170aac5f811246c3caa22a864d (diff)
child 280146 de9a0fc7828dbc3cbe6a921e796a64971cf78d3a
child 280210 e7b76c3445d4d82b17d05ebd62ca246f540ff721
child 280222 34ff473cbd8633d9def2fbe37b1437912ca082e9
child 280236 5fb09f6e31fd580b509c82356ac26944c518ddbe
push id70334
push usercbook@mozilla.com
push dateFri, 15 Jan 2016 10:48:53 +0000
treeherdermozilla-inbound@de9a0fc7828d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone46.0a1
first release with
nightly linux32
e1486d83107f / 46.0a1 / 20160115030235 / files
nightly linux64
e1486d83107f / 46.0a1 / 20160115030235 / files
nightly mac
e1486d83107f / 46.0a1 / 20160115030235 / files
nightly win32
e1486d83107f / 46.0a1 / 20160115030235 / files
nightly win64
e1486d83107f / 46.0a1 / 20160115030235 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central a=merge
browser/base/content/tabbrowser.xml
browser/base/content/test/general/browser.ini
embedding/android/geckoview_example/AndroidManifest.xml.in
embedding/android/geckoview_example/GeckoViewExample.java
embedding/android/geckoview_example/Makefile.in
embedding/android/geckoview_example/main.xml
embedding/android/geckoview_example/moz.build
extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US.txt
extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US.aff
extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US.dic
testing/profiles/prefs_general.js
testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-redirect.https.html.ini
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -29,24 +29,35 @@
 #include "nsView.h"
 #include "nsGkAtoms.h"
 
 #include "nsComponentManagerUtils.h"
 
 #include "nsITreeBoxObject.h"
 #include "nsITreeColumns.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/HTMLLabelElement.h"
 
 using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsCoreUtils
 ////////////////////////////////////////////////////////////////////////////////
 
 bool
+nsCoreUtils::IsLabelWithControl(nsIContent* aContent)
+{
+  dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromContent(aContent);
+  if (label && label->GetControl())
+    return true;
+
+  return false;
+}
+
+bool
 nsCoreUtils::HasClickListener(nsIContent *aContent)
 {
   NS_ENSURE_TRUE(aContent, false);
   EventListenerManager* listenerManager =
     aContent->GetExistingListenerManager();
 
   return listenerManager &&
     (listenerManager->HasListenersFor(nsGkAtoms::onclick) ||
--- a/accessible/base/nsCoreUtils.h
+++ b/accessible/base/nsCoreUtils.h
@@ -24,16 +24,21 @@ class nsIWidget;
 
 /**
  * Core utils.
  */
 class nsCoreUtils
 {
 public:
   /**
+   * Return true if the given node is a label of a control.
+   */
+  static bool IsLabelWithControl(nsIContent *aContent);
+
+  /**
    * Return true if the given node has registered click, mousedown or mouseup
    * event listeners.
    */
   static bool HasClickListener(nsIContent *aContent);
 
   /**
    * Dispatch click event to XUL tree cell.
    *
--- a/accessible/generic/BaseAccessibles.cpp
+++ b/accessible/generic/BaseAccessibles.cpp
@@ -110,30 +110,34 @@ LinkableAccessible::Value(nsString& aVal
   if (isLink) {
     actionAcc->Value(aValue);
   }
 }
 
 uint8_t
 LinkableAccessible::ActionCount()
 {
-  bool isLink, isOnclick;
-  ActionWalk(&isLink, &isOnclick);
-  return (isLink || isOnclick) ? 1 : 0;
+  bool isLink, isOnclick, isLabelWithControl;
+  ActionWalk(&isLink, &isOnclick, &isLabelWithControl);
+  return (isLink || isOnclick || isLabelWithControl) ? 1 : 0;
 }
 
 Accessible*
-LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick)
+LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick,
+                               bool* aIsLabelWithControl)
 {
   if (aIsOnclick) {
     *aIsOnclick = false;
   }
   if (aIsLink) {
     *aIsLink = false;
   }
+  if (aIsLabelWithControl) {
+    *aIsLabelWithControl = false;
+  }
 
   if (nsCoreUtils::HasClickListener(mContent)) {
     if (aIsOnclick) {
       *aIsOnclick = true;
     }
     return nullptr;
   }
 
@@ -150,32 +154,39 @@ LinkableAccessible::ActionWalk(bool* aIs
     }
 
     if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
       if (aIsOnclick) {
         *aIsOnclick = true;
       }
       return walkUpAcc;
     }
+
+    if (nsCoreUtils::IsLabelWithControl(walkUpAcc->GetContent())) {
+      if (aIsLabelWithControl) {
+        *aIsLabelWithControl = true;
+      }
+      return walkUpAcc;
+    }
   }
   return nullptr;
 }
 
 void
 LinkableAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
 {
   aName.Truncate();
 
   // Action 0 (default action): Jump to link
   if (aIndex == eAction_Jump) {
-    bool isOnclick, isLink;
-    ActionWalk(&isLink, &isOnclick);
+    bool isOnclick, isLink, isLabelWithControl;
+    ActionWalk(&isLink, &isOnclick, &isLabelWithControl);
     if (isLink) {
       aName.AssignLiteral("jump");
-    } else if (isOnclick) {
+    } else if (isOnclick || isLabelWithControl) {
       aName.AssignLiteral("click");
     }
   }
 }
 
 bool
 LinkableAccessible::DoAction(uint8_t aIndex)
 {
--- a/accessible/generic/BaseAccessibles.h
+++ b/accessible/generic/BaseAccessibles.h
@@ -71,17 +71,18 @@ public:
   // ActionAccessible
   virtual uint8_t ActionCount() override;
   virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
   virtual bool DoAction(uint8_t index) override;
   virtual KeyBinding AccessKey() const override;
 
   // ActionAccessible helpers
   Accessible* ActionWalk(bool* aIsLink = nullptr,
-                          bool* aIsOnclick = nullptr);
+                         bool* aIsOnclick = nullptr,
+                         bool* aIsLabelWithControl = nullptr);
   // HyperLinkAccessible
   virtual already_AddRefed<nsIURI> AnchorURIAt(uint32_t aAnchorIndex) override;
 
 protected:
   virtual ~LinkableAccessible() {}
 
 };
 
--- a/accessible/html/HTMLElementAccessibles.cpp
+++ b/accessible/html/HTMLElementAccessibles.cpp
@@ -70,16 +70,42 @@ HTMLLabelAccessible::RelationByType(Rela
   if (aType == RelationType::LABEL_FOR) {
     dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromContent(mContent);
     rel.AppendTarget(mDoc, label->GetControl());
   }
 
   return rel;
 }
 
+uint8_t
+HTMLLabelAccessible::ActionCount()
+{
+  return nsCoreUtils::IsLabelWithControl(mContent) ? 1 : 0;
+}
+
+void
+HTMLLabelAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
+{
+  if (aIndex == 0) {
+    if (nsCoreUtils::IsLabelWithControl(mContent))
+      aName.AssignLiteral("click");
+  }
+}
+
+bool
+HTMLLabelAccessible::DoAction(uint8_t aIndex)
+{
+  if (aIndex != 0)
+    return false;
+
+  DoCommand();
+  return true;
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLOuputAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLOutputAccessible, HyperTextAccessible)
 
 Relation
 HTMLOutputAccessible::RelationByType(RelationType aType)
--- a/accessible/html/HTMLElementAccessibles.h
+++ b/accessible/html/HTMLElementAccessibles.h
@@ -57,16 +57,21 @@ public:
   HTMLLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual Relation RelationByType(RelationType aType) override;
 
+  // ActionAccessible
+  virtual uint8_t ActionCount() override;
+  virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
+  virtual bool DoAction(uint8_t aIndex) override;
+
 protected:
   virtual ~HTMLLabelAccessible() {}
   virtual ENameValueFlag NativeName(nsString& aName) override;
 };
 
 /**
  * Used for HTML output element.
  */
--- a/accessible/tests/mochitest/actions/test_general.html
+++ b/accessible/tests/mochitest/actions/test_general.html
@@ -34,21 +34,29 @@
           ID: "li_clickable3",
           actionName: "click",
           events: CLICK_EVENTS
         },
         {
           ID: "onclick_img",
           actionName: "click",
           events: CLICK_EVENTS
+        },
+        {
+          ID: "label1",
+          actionName: "click",
+          events: CLICK_EVENTS
         }
+
       ];
 
       testActions(actionsArray);
 
+      is(getAccessible("label1").firstChild.actionCount, 1, "label text should have 1 action");
+
       getAccessible("onclick_img").takeFocus();
       is(getAccessible("link1").actionCount, 1, "links should have one action");
       is(getAccessible("link2").actionCount, 1, "link with onclick handler should have 1 action");
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
@@ -82,10 +90,18 @@
     <li id="li_clickable3" onmouseup="">Clickable list item</li>
   </ul>
 
   <!-- linkable accessibles -->
   <img id="onclick_img" onclick="" src="../moz.png">
 
   <a id="link1" href="www">linkable textleaf accessible</a>
   <div id="link2" onclick="">linkable textleaf accessible</div>
+
+  <div>
+    <label for="TextBox_t2" id="label1">
+      <span>Explicit</span>
+    </label>
+    <input name="in2" id="TextBox_t2" type="text" maxlength="17">
+  </div>
+
 </body>
 </html>
--- a/accessible/tests/mochitest/actions/test_general.xul
+++ b/accessible/tests/mochitest/actions/test_general.xul
@@ -56,27 +56,34 @@
           events: XUL_EVENTS
         },
         {
           ID: "buttonmenu",
           actionName: "press",
           events: CLICK_EVENTS
         },
         {
+          ID: "name_entry_label",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
           ID: "labelWithPopup",
           actionName: "click",
           events: CLICK_EVENTS
         }/*, // XXX: bug 490288
         {
           ID: "buttonmenu_item",
           actionName: "click",
           events: CLICK_EVENTS
         }*/
       ];
 
+      is(getAccessible("name_entry_label").firstChild.actionCount, 1, "label text should have 1 action");
+
       testActions(actionsArray);
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
@@ -120,12 +127,16 @@
           <menuitem label="item1" id="buttonmenu_item"/>
           <menuitem label="item1"/>
         </menupopup>
       </button>
 
       <label id="labelWithPopup" value="file name"
              popup="fileContext"
              tabindex="0"/>
+      <hbox>
+        <label id="name_entry_label" value="Name" control="name_entry"/>
+        <textbox id="name_entry"/>
+      </hbox>
     </vbox>
   </hbox>
 </window>
 
--- a/b2g/app/B2GLoader.cpp
+++ b/b2g/app/B2GLoader.cpp
@@ -247,17 +247,19 @@ ReserveFileDescriptors(FdArray& aReserve
       MOZ_CRASH("ProcLoader error: a magic file descriptor is occupied.");
     }
 
     int fd = open("/dev/null", O_RDWR);
     if (fd == -1) {
       MOZ_CRASH("ProcLoader error: failed to reserve a magic file descriptor.");
     }
 
-    aReservedFds.append(target);
+    if (!aReservedFds.append(target)) {
+      MOZ_CRASH("Failed to append to aReservedFds");
+    }
 
     if (fd == target) {
       // No need to call dup2(). We already occupy the desired file descriptor.
       continue;
     }
 
     if (dup2(fd, target)) {
       MOZ_CRASH("ProcLoader error: failed to reserve a magic file descriptor.");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5,16 +5,17 @@
 
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/NotificationDB.jsm");
 Cu.import("resource:///modules/RecentWindow.jsm");
+Cu.import("resource:///modules/UserContextUI.jsm");
 
 
 XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
                                   "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
                                   "resource://gre/modules/Deprecated.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
                                   "resource:///modules/BrowserUITelemetry.jsm");
@@ -4054,34 +4055,17 @@ function updateUserContextUIIndicator(br
   if (!browser.hasAttribute("usercontextid")) {
     hbox.removeAttribute("usercontextid");
     return;
   }
 
   let label = document.getElementById("userContext-label");
   let userContextId = browser.getAttribute("usercontextid");
   hbox.setAttribute("usercontextid", userContextId);
-  switch (userContextId) {
-    case "1":
-      label.value = gBrowserBundle.GetStringFromName("usercontext.personal.label");
-      break;
-    case "2":
-      label.value = gBrowserBundle.GetStringFromName("usercontext.work.label");
-      break;
-    case "3":
-      label.value = gBrowserBundle.GetStringFromName("usercontext.banking.label");
-      break;
-    case "4":
-      label.value = gBrowserBundle.GetStringFromName("usercontext.shopping.label");
-      break;
-    // Display the context IDs for values outside the pre-defined range.
-    // Used for debugging, no localization necessary.
-    default:
-      label.value = "Context " + userContextId;
-  }
+  label.value = UserContextUI.getUserContextLabel(userContextId);
 }
 
 /**
  * Makes the Character Encoding menu enabled or disabled as appropriate.
  * To be called when the View menu or the app menu is opened.
  */
 function updateCharacterEncodingMenuState()
 {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -753,17 +753,17 @@
                 // failed URI (particularly for SSL errors). However, don't clear the value
                 // if the error page's URI is about:blank, because that causes complete
                 // loss of urlbar contents for invalid URI errors (see bug 867957).
                 // Another reason to clear the userTypedValue is if this was an anchor
                 // navigation.
                 if (this.mBrowser.userTypedClear > 0 ||
                     ((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
                      aLocation.spec != "about:blank") ||
-                     aFlags && Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
+                     aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
                   this.mBrowser.userTypedValue = null;
                 }
 
                 // If the browser was playing audio, we should remove the playing state.
                 if (this.mTab.hasAttribute("soundplaying") &&
                     (!this.mBrowser.lastURI ||
                      this.mBrowser.lastURI.spec != aLocation.spec)) {
                   this.mTab.removeAttribute("soundplaying");
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -412,17 +412,17 @@ skip-if = buildapp == 'mulet'
 skip-if = buildapp == 'mulet' || (e10s && debug) # Bug 1150036: In e10s, content process crashes, main process leaks!
 [browser_tab_dragdrop2.js]
 skip-if = buildapp == 'mulet'
 [browser_tabbar_big_widgets.js]
 skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
                                        # Disabled on OS X because of bug 967917
 [browser_tabfocus.js]
 [browser_tabkeynavigation.js]
-skip-if = e10s
+skip-if = (os == "mac" && !e10s) 
 [browser_tabopen_reflows.js]
 [browser_tabs_close_beforeunload.js]
 support-files =
   close_beforeunload_opens_second_tab.html
   close_beforeunload.html
 [browser_tabs_isActive.js]
 [browser_tabs_owner.js]
 [browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js]
--- a/browser/base/content/test/general/browser_tabkeynavigation.js
+++ b/browser/base/content/test/general/browser_tabkeynavigation.js
@@ -37,108 +37,94 @@ function test() {
     // Kill the animation for simpler test.
     Services.prefs.setBoolPref("browser.tabs.animate", false);
 
     gBrowser.selectedTab = tab1;
     browser1.contentWindow.focus();
 
     is(gBrowser.selectedTab, tab1,
        "Tab1 should be activated");
-    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true },
-                             browser1.contentWindow);
+    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true });
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated by pressing Ctrl+Tab on Tab1");
 
-    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true },
-                             browser2.contentWindow);
+    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true });
     is(gBrowser.selectedTab, tab3,
        "Tab3 should be activated by pressing Ctrl+Tab on Tab2");
 
-    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: true },
-                             browser3.contentWindow);
+    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: true });
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated by pressing Ctrl+Shift+Tab on Tab3");
 
-    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: true },
-                             browser2.contentWindow);
+    EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: true });
     is(gBrowser.selectedTab, tab1,
        "Tab1 should be activated by pressing Ctrl+Shift+Tab on Tab2");
 
     gBrowser.selectedTab = tab1;
     browser1.contentWindow.focus();
 
     is(gBrowser.selectedTab, tab1,
        "Tab1 should be activated");
-    EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true },
-                             browser1.contentWindow);
+    EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true });
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated by pressing Ctrl+PageDown on Tab1");
 
-    EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true },
-                             browser2.contentWindow);
+    EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true });
     is(gBrowser.selectedTab, tab3,
        "Tab3 should be activated by pressing Ctrl+PageDown on Tab2");
 
-    EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true },
-                             browser3.contentWindow);
+    EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true });
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated by pressing Ctrl+PageUp on Tab3");
 
-    EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true },
-                             browser2.contentWindow);
+    EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true });
     is(gBrowser.selectedTab, tab1,
        "Tab1 should be activated by pressing Ctrl+PageUp on Tab2");
 
     if (gBrowser.mTabBox._handleMetaAltArrows) {
       gBrowser.selectedTab = tab1;
       browser1.contentWindow.focus();
 
       let ltr =
         window.getComputedStyle(gBrowser.mTabBox, "").direction == "ltr";
       let advanceKey = ltr ? "VK_RIGHT" : "VK_LEFT";
       let reverseKey = ltr ? "VK_LEFT" : "VK_RIGHT";
 
       is(gBrowser.selectedTab, tab1,
          "Tab1 should be activated");
-      EventUtils.synthesizeKey(advanceKey, { altKey: true, metaKey: true },
-                               browser1.contentWindow);
+      EventUtils.synthesizeKey(advanceKey, { altKey: true, metaKey: true });
       is(gBrowser.selectedTab, tab2,
          "Tab2 should be activated by pressing Ctrl+" + advanceKey + " on Tab1");
 
-      EventUtils.synthesizeKey(advanceKey, { altKey: true, metaKey: true },
-                               browser2.contentWindow);
+      EventUtils.synthesizeKey(advanceKey, { altKey: true, metaKey: true });
       is(gBrowser.selectedTab, tab3,
          "Tab3 should be activated by pressing Ctrl+" + advanceKey + " on Tab2");
 
-      EventUtils.synthesizeKey(reverseKey, { altKey: true, metaKey: true },
-                               browser3.contentWindow);
+      EventUtils.synthesizeKey(reverseKey, { altKey: true, metaKey: true });
       is(gBrowser.selectedTab, tab2,
          "Tab2 should be activated by pressing Ctrl+" + reverseKey + " on Tab3");
 
-      EventUtils.synthesizeKey(reverseKey, { altKey: true, metaKey: true },
-                               browser2.contentWindow);
+      EventUtils.synthesizeKey(reverseKey, { altKey: true, metaKey: true });
       is(gBrowser.selectedTab, tab1,
          "Tab1 should be activated by pressing Ctrl+" + reverseKey + " on Tab2");
     }
 
     gBrowser.selectedTab = tab2;
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated");
     is(gBrowser.tabContainer.selectedIndex, 2,
        "Tab2 index should be 2");
 
-    EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true, shiftKey: true },
-                             browser2.contentWindow);
+    EventUtils.synthesizeKey("VK_PAGE_DOWN", { ctrlKey: true, shiftKey: true });
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated after Ctrl+Shift+PageDown");
     is(gBrowser.tabContainer.selectedIndex, 3,
        "Tab2 index should be 1 after Ctrl+Shift+PageDown");
 
-    EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true, shiftKey: true },
-                             browser2.contentWindow);
+    EventUtils.synthesizeKey("VK_PAGE_UP", { ctrlKey: true, shiftKey: true });
     is(gBrowser.selectedTab, tab2,
        "Tab2 should be activated after Ctrl+Shift+PageUp");
     is(gBrowser.tabContainer.selectedIndex, 2,
        "Tab2 index should be 2 after Ctrl+Shift+PageUp");
 
     if (navigator.platform.indexOf("Mac") == 0) {
       gBrowser.selectedTab = tab1;
       browser1.contentWindow.focus();
@@ -148,55 +134,48 @@ function test() {
 
       let ltr =
         window.getComputedStyle(gBrowser.mTabBox, "").direction == "ltr";
       let advanceKey = ltr ? "}" : "{";
       let reverseKey = ltr ? "{" : "}";
 
       is(gBrowser.selectedTab, tab1,
          "Tab1 should be activated");
-      EventUtils.synthesizeKey(advanceKey, { metaKey: true },
-                               browser1.contentWindow);
+
+      EventUtils.synthesizeKey(advanceKey, { metaKey: true });
       is(gBrowser.selectedTab, tab2,
          "Tab2 should be activated by pressing Ctrl+" + advanceKey + " on Tab1");
 
-      EventUtils.synthesizeKey(advanceKey, { metaKey: true },
-                               browser2.contentWindow);
-      todo_is(gBrowser.selectedTab, tab3,
-              "Tab3 should be activated by pressing Ctrl+" + advanceKey + " on Tab2");
+      EventUtils.synthesizeKey(advanceKey, { metaKey: true });
+      is(gBrowser.selectedTab, tab3,
+         "Tab3 should be activated by pressing Ctrl+" + advanceKey + " on Tab2");
 
-      if (gBrowser.selectedTab != tab3) {
-        EventUtils.synthesizeKey(reverseKey, { metaKey: true },
-                                 browser3.contentWindow);
-        is(gBrowser.selectedTab, tab2,
-           "Tab2 should be activated by pressing Ctrl+" + reverseKey + " on Tab3");
-      }
+      EventUtils.synthesizeKey(reverseKey, { metaKey: true });
+      is(gBrowser.selectedTab, tab2,
+         "Tab2 should be activated by pressing Ctrl+" + reverseKey + " on Tab3");
 
-      EventUtils.synthesizeKey(reverseKey, { metaKey: true },
-                               browser2.contentWindow);
-      todo_is(gBrowser.selectedTab, tab1,
-              "Tab1 should be activated by pressing Ctrl+" + reverseKey + " on Tab2");
+      EventUtils.synthesizeKey(reverseKey, { metaKey: true });
+      is(gBrowser.selectedTab, tab1,
+         "Tab1 should be activated by pressing Ctrl+" + reverseKey + " on Tab2");
     } else {
       gBrowser.selectedTab = tab2;
-      EventUtils.synthesizeKey("VK_F4", { type: "keydown", ctrlKey: true },
-                               browser2.contentWindow);
+      EventUtils.synthesizeKey("VK_F4", { type: "keydown", ctrlKey: true });
 
       isnot(gBrowser.selectedTab, tab2,
             "Tab2 should be closed by pressing Ctrl+F4 on Tab2");
       is(gBrowser.tabs.length, 3,
-         "The count of tabs should be 3 since tab2 should be closed");
+        "The count of tabs should be 3 since tab2 should be closed");
 
       let activeWindow =
         gBrowser.getBrowserForTab(gBrowser.selectedTab).contentWindow;
       // NOTE: keypress event shouldn't be fired since the keydown event should
       //       be consumed by tab2.
-      EventUtils.synthesizeKey("VK_F4", { type: "keyup", ctrlKey: true },
-                               activeWindow);
-      is(gBrowser.tabs.length, 3,
-         "The count of tabs should be 3 since renaming key events shouldn't close other tabs");
+        EventUtils.synthesizeKey("VK_F4", { type: "keyup", ctrlKey: true });
+        is(gBrowser.tabs.length, 3,
+          "The count of tabs should be 3 since renaming key events shouldn't close other tabs");
     }
 
     gBrowser.selectedTab = tab3;
     while (gBrowser.tabs.length > 1) {
       gBrowser.removeCurrentTab();
     }
 
     Services.prefs.clearUserPref("browser.tabs.animate");
--- a/browser/components/newtab/NewTabURL.jsm
+++ b/browser/components/newtab/NewTabURL.jsm
@@ -10,35 +10,27 @@
 const {utils: Cu} = Components;
 
 this.EXPORTED_SYMBOLS = ["NewTabURL"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
-XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
-                                  "resource://gre/modules/Deprecated.jsm");
-
-const DepecationURL = "https://bugzilla.mozilla.org/show_bug.cgi?id=1204983#c89";
 
 this.NewTabURL = {
 
   get: function() {
-    Deprecated.warning("NewTabURL.get is deprecated, please query aboutNewTabService.newTabURL", DepecationURL);
     return aboutNewTabService.newTabURL;
   },
 
   get overridden() {
-    Deprecated.warning("NewTabURL.overridden is deprecated, please query aboutNewTabService.overridden", DepecationURL);
     return aboutNewTabService.overridden;
   },
 
   override: function(newURL) {
-    Deprecated.warning("NewTabURL.override is deprecated, please set aboutNewTabService.newTabURL", DepecationURL);
     aboutNewTabService.newTabURL = newURL;
   },
 
   reset: function() {
-    Deprecated.warning("NewTabURL.reset is deprecated, please use aboutNewTabService.resetNewTabURL()", DepecationURL);
     aboutNewTabService.resetNewTabURL();
   }
 };
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2969,19 +2969,16 @@ var DefaultBrowserCheck = {
       popup.remove();
       delete this._notification;
     }
   },
 };
 
 #ifdef E10S_TESTING_ONLY
 var E10SUINotification = {
-  // Increase this number each time we want to roll out an
-  // e10s testing period to Nightly users.
-  CURRENT_NOTICE_COUNT: 4,
   CURRENT_PROMPT_PREF: "browser.displayedE10SPrompt.1",
   PREVIOUS_PROMPT_PREF: "browser.displayedE10SPrompt",
 
   get forcedOn() {
     try {
       return Services.prefs.getBoolPref("browser.tabs.remote.force-enable");
     } catch (e) {}
     return false;
@@ -3002,45 +2999,28 @@ var E10SUINotification = {
 
   checkStatus: function() {
     let updateChannel = UpdateUtils.UpdateChannel;
     let channelAuthorized = updateChannel == "nightly" || updateChannel == "aurora";
     if (!channelAuthorized) {
       return;
     }
 
-    if (Services.appinfo.browserTabsRemoteAutostart) {
-      if (this.forcedOn) {
-        return;
-      }
-      let notice = 0;
-      try {
-        notice = Services.prefs.getIntPref("browser.displayedE10SNotice");
-      } catch(e) {}
-      let activationNoticeShown = notice >= this.CURRENT_NOTICE_COUNT;
-
-      if (!activationNoticeShown) {
-        this._showE10sActivatedNotice();
-      }
-    } else {
+    if (!Services.appinfo.browserTabsRemoteAutostart) {
       let displayFeedbackRequest = false;
       try {
         displayFeedbackRequest = Services.prefs.getBoolPref("browser.requestE10sFeedback");
       } catch (e) {}
 
       if (displayFeedbackRequest) {
         let win = RecentWindow.getMostRecentBrowserWindow();
         if (!win) {
           return;
         }
 
-        // The user has just voluntarily disabled e10s. Subtract one from displayedE10SNotice
-        // so that the next time e10s is activated (either by the user or forced by us), they
-        // can see the notice again.
-        Services.prefs.setIntPref("browser.displayedE10SNotice", this.CURRENT_NOTICE_COUNT - 1);
         Services.prefs.clearUserPref("browser.requestE10sFeedback");
 
         let url = Services.urlFormatter.formatURLPref("app.feedback.baseURL");
         url += "?utm_source=tab&utm_campaign=e10sfeedback";
 
         win.openUILinkIn(url, "tab");
         return;
       }
@@ -3079,42 +3059,16 @@ var E10SUINotification = {
           }
         }, Ci.nsIThread.DISPATCH_NORMAL);
       }
     }
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
 
-  _showE10sActivatedNotice: function() {
-    let win = RecentWindow.getMostRecentBrowserWindow();
-    if (!win)
-      return;
-
-    Services.prefs.setIntPref("browser.displayedE10SNotice", this.CURRENT_NOTICE_COUNT);
-
-    let nb = win.document.getElementById("high-priority-global-notificationbox");
-    let message = win.gNavigatorBundle.getFormattedString(
-                    "e10s.postActivationInfobar.message",
-                    [gBrandBundle.GetStringFromName("brandShortName")]
-                  );
-    let buttons = [
-      {
-        label: win.gNavigatorBundle.getString("e10s.postActivationInfobar.learnMore.label"),
-        accessKey: win.gNavigatorBundle.getString("e10s.postActivationInfobar.learnMore.accesskey"),
-        callback: function () {
-          win.openUILinkIn("https://wiki.mozilla.org/Electrolysis", "tab");
-        }
-      }
-    ];
-    nb.appendNotification(message, "e10s-activated-noticed",
-                          null, nb.PRIORITY_WARNING_MEDIUM, buttons);
-
-  },
-
   _showE10SPrompt: function BG__showE10SPrompt() {
     let win = RecentWindow.getMostRecentBrowserWindow();
     if (!win)
       return;
 
     let browser = win.gBrowser.selectedBrowser;
 
     let promptMessage = win.gNavigatorBundle.getFormattedString(
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -1,16 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
 
 const nsICookie = Components.interfaces.nsICookie;
 
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm")
+Components.utils.import("resource:///modules/UserContextUI.jsm");
 
 var gCookiesWindow = {
   _cm               : Components.classes["@mozilla.org/cookiemanager;1"]
                                 .getService(Components.interfaces.nsICookieManager),
   _ds               : Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
                                 .getService(Components.interfaces.nsIScriptableDateFormat),
   _hosts            : {},
   _hostOrder        : [],
@@ -24,16 +26,20 @@ var gCookiesWindow = {
     os.addObserver(this, "perm-changed", false);
 
     this._bundle = document.getElementById("bundlePreferences");
     this._tree = document.getElementById("cookiesList");
 
     this._populateList(true);
 
     document.getElementById("filter").focus();
+
+    if (!Services.prefs.getBoolPref("privacy.userContext.enabled")) {
+      document.getElementById("userContextRow").hidden = true;
+    }
   },
 
   uninit: function () {
     var os = Components.classes["@mozilla.org/observer-service;1"]
                        .getService(Components.interfaces.nsIObserverService);
     os.removeObserver(this, "cookie-changed");
     os.removeObserver(this, "perm-changed");
   },
@@ -448,26 +454,27 @@ var gCookiesWindow = {
 
     var c = this._makeCookieObject(aStrippedHost, aCookie);
     this._hosts[aStrippedHost].cookies.push(c);
   },
 
   _makeCookieObject: function (aStrippedHost, aCookie) {
     var host = aCookie.host;
     var formattedHost = host.charAt(0) == "." ? host.substring(1, host.length) : host;
-    var c = { name        : aCookie.name,
-              value       : aCookie.value,
-              isDomain    : aCookie.isDomain,
-              host        : aCookie.host,
-              rawHost     : aStrippedHost,
-              path        : aCookie.path,
-              isSecure    : aCookie.isSecure,
-              expires     : aCookie.expires,
-              level       : 1,
-              container   : false };
+    var c = { name            : aCookie.name,
+              value           : aCookie.value,
+              isDomain        : aCookie.isDomain,
+              host            : aCookie.host,
+              rawHost         : aStrippedHost,
+              path            : aCookie.path,
+              isSecure        : aCookie.isSecure,
+              expires         : aCookie.expires,
+              level           : 1,
+              container       : false,
+              originAttributes: aCookie.originAttributes };
     return c;
   },
 
   _loadCookies: function () {
     var e = this._cm.enumerator;
     var hostCount = { value: 0 };
     this._hosts = {};
     this._hostOrder = [];
@@ -495,36 +502,39 @@ var gCookiesWindow = {
                                      date.getMinutes(),
                                      date.getSeconds());
     }
     return this._bundle.getString("expireAtEndOfSession");
   },
 
   _updateCookieData: function (aItem) {
     var seln = this._view.selection;
-    var ids = ["name", "value", "host", "path", "isSecure", "expires"];
+    var ids = ["name", "value", "host", "path", "isSecure", "expires", "userContext"];
     var properties;
 
     if (aItem && !aItem.container && seln.count > 0) {
       properties = { name: aItem.name, value: aItem.value, host: aItem.host,
                      path: aItem.path, expires: this.formatExpiresString(aItem.expires),
                      isDomain: aItem.isDomain ? this._bundle.getString("domainColon")
                                               : this._bundle.getString("hostColon"),
                      isSecure: aItem.isSecure ? this._bundle.getString("forSecureOnly")
-                                              : this._bundle.getString("forAnyConnection") };
-      for (var i = 0; i < ids.length; ++i)
+                                              : this._bundle.getString("forAnyConnection"),
+                     userContext: UserContextUI.getUserContextLabel(aItem.originAttributes.userContextId) };
+      for (var i = 0; i < ids.length; ++i) {
         document.getElementById(ids[i]).disabled = false;
+      }
     }
     else {
       var noneSelected = this._bundle.getString("noCookieSelected");
       properties = { name: noneSelected, value: noneSelected, host: noneSelected,
                      path: noneSelected, expires: noneSelected,
-                     isSecure: noneSelected };
-      for (i = 0; i < ids.length; ++i)
+                     isSecure: noneSelected, userContext: noneSelected };
+      for (i = 0; i < ids.length; ++i) {
         document.getElementById(ids[i]).disabled = true;
+      }
     }
     for (var property in properties)
       document.getElementById(property).value = properties[property];
   },
 
   onCookieSelected: function () {
     var item;
     var seln = this._tree.view.selection;
--- a/browser/components/preferences/cookies.xul
+++ b/browser/components/preferences/cookies.xul
@@ -80,16 +80,20 @@
           <row align="center">
             <hbox pack="end"><label id="isSecureLabel" control="isSecure" value="&props.secure.label;"/></hbox>
             <textbox id="isSecure" readonly="true" class="plain"/>
           </row>
           <row align="center">
             <hbox pack="end"><label id="expiresLabel" control="expires" value="&props.expires.label;"/></hbox>
             <textbox id="expires" readonly="true" class="plain"/>
           </row>
+          <row align="center" id="userContextRow">
+            <hbox pack="end"><label id="userContextLabel" control="userContext" value="&props.container.label;"/></hbox>
+            <textbox id="userContext" readonly="true" class="plain"/>
+          </row>
         </rows>
       </grid>
     </hbox>
   </vbox>
   <hbox align="end">
     <hbox class="actionButtons" flex="1">
       <button id="removeSelectedCookies" disabled="true" icon="clear"
               accesskey="&button.removeSelectedCookies.accesskey;"
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -741,36 +741,30 @@ appMenuRemoteTabs.mobilePromo.ios = Fire
 
 # LOCALIZATION NOTE (e10s.offerPopup.mainMessage
 #                    e10s.offerPopup.highlight1
 #                    e10s.offerPopup.highlight2
 #                    e10s.offerPopup.enableAndRestart.label
 #                    e10s.offerPopup.enableAndRestart.accesskey
 #                    e10s.offerPopup.noThanks.label
 #                    e10s.offerPopup.noThanks.accesskey
-#                    e10s.postActivationInfobar.message
-#                    e10s.postActivationInfobar.learnMore.label
-#                    e10s.postActivationInfobar.learnMore.accesskey
 #                    e10s.accessibilityNotice.mainMessage
 #                    e10s.accessibilityNotice.enableAndRestart.label
 #                    e10s.accessibilityNotice.enableAndRestart.accesskey
 # These strings are related to the messages we display to offer e10s (Multi-process) to users
 # on the pre-release channels. They won't be used in release but they will likely be used in
 # beta starting from version 41, so it's still useful to have these strings properly localized.
 # %S is brandShortName
 e10s.offerPopup.mainMessage = Multi-process is coming soon to %S. You can start using it now to get early access to some of the benefits:
 e10s.offerPopup.highlight1 = Improved responsiveness
 e10s.offerPopup.highlight2 = Fewer crashes
 e10s.offerPopup.enableAndRestart.label = Enable and Restart
 e10s.offerPopup.enableAndRestart.accesskey = E
 e10s.offerPopup.noThanks.label = No, thanks
 e10s.offerPopup.noThanks.accesskey = N
-e10s.postActivationInfobar.message = You're now helping to test multi-process in %S! Please report problems you find.
-e10s.postActivationInfobar.learnMore.label = Learn More
-e10s.postActivationInfobar.learnMore.accesskey = L
 e10s.accessibilityNotice.mainMessage2 = Accessibility support is partially disabled due to compatibility issues with new %S features.
 e10s.accessibilityNotice.acceptButton.label = OK
 e10s.accessibilityNotice.acceptButton.accesskey = O
 e10s.accessibilityNotice.enableAndRestart.label = Enable (Requires Restart)
 e10s.accessibilityNotice.enableAndRestart.accesskey = E
 
 # LOCALIZATION NOTE (usercontext.personal.label,
 #                    usercontext.work.label,
--- a/browser/locales/en-US/chrome/browser/preferences/cookies.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/cookies.dtd
@@ -16,16 +16,17 @@
 <!ENTITY     button.removeAllCookies.accesskey "A">
 
 <!ENTITY     props.name.label               "Name:">
 <!ENTITY     props.value.label              "Content:">
 <!ENTITY     props.domain.label             "Host:">
 <!ENTITY     props.path.label               "Path:">
 <!ENTITY     props.secure.label             "Send For:">
 <!ENTITY     props.expires.label            "Expires:">
+<!ENTITY     props.container.label          "Container:">
 
 <!ENTITY     window.title                   "Cookies">
 <!ENTITY     windowClose.key                "w">
 <!ENTITY     focusSearch1.key               "f">
 <!ENTITY     focusSearch2.key               "k">
 
 <!ENTITY     filter.label                   "Search:">
 <!ENTITY     filter.accesskey               "S">
new file mode 100644
--- /dev/null
+++ b/browser/modules/UserContextUI.jsm
@@ -0,0 +1,32 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+this.EXPORTED_SYMBOLS = ["UserContextUI"];
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm")
+
+XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
+  return Services.strings.createBundle("chrome://browser/locale/browser.properties");
+});
+
+this.UserContextUI = {
+  getUserContextLabel(userContextId) {
+    switch (userContextId) {
+      // No UserContext:
+      case 0: return "";
+
+      case 1: return gBrowserBundle.GetStringFromName("usercontext.personal.label");
+      case 2: return gBrowserBundle.GetStringFromName("usercontext.work.label");
+      case 3: return gBrowserBundle.GetStringFromName("usercontext.shopping.label");
+      case 4: return gBrowserBundle.GetStringFromName("usercontext.banking.label");
+
+      // Display the context IDs for values outside the pre-defined range.
+      // Used for debugging, no localization necessary.
+      default: return "Context " + userContextId;
+    }
+  }
+}
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -38,16 +38,17 @@ EXTRA_JS_MODULES += [
     'RecentWindow.jsm',
     'RemotePrompt.jsm',
     'Sanitizer.jsm',
     'SelfSupportBackend.jsm',
     'SitePermissions.jsm',
     'Social.jsm',
     'TabGroupsMigrator.jsm',
     'TransientPrefs.jsm',
+    'UserContextUI.jsm',
     'WebappManager.jsm',
     'webrtcUI.jsm',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     EXTRA_JS_MODULES += [
         'Windows8WindowFrameColor.jsm',
         'WindowsJumpLists.jsm',
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -359,40 +359,65 @@ BasePrincipal::CheckMayLoad(nsIURI* aURI
 NS_IMETHODIMP
 BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
 {
   NS_IF_ADDREF(*aCsp = mCSP);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
+BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument,
+                         nsIContentSecurityPolicy** aCSP)
 {
   if (mCSP) {
-    return NS_ERROR_ALREADY_INITIALIZED;
+    // if there is a CSP already associated with this principal
+    // then just return that - do not overwrite it!!!
+    NS_IF_ADDREF(*aCSP = mCSP);
+    return NS_OK;
   }
 
-  mCSP = aCsp;
+  nsresult rv = NS_OK;
+  mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Store the request context for violation reports
+  rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr)
+                 : mCSP->SetRequestContext(nullptr, this);
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_IF_ADDREF(*aCSP = mCSP);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
 {
   NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-BasePrincipal::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP)
+BasePrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
+                                nsIContentSecurityPolicy** aPreloadCSP)
 {
   if (mPreloadCSP) {
-    return NS_ERROR_ALREADY_INITIALIZED;
+    // if there is a speculative CSP already associated with this principal
+    // then just return that - do not overwrite it!!!
+    NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
+    return NS_OK;
   }
-  mPreloadCSP = aPreloadCSP;
+
+  nsresult rv = NS_OK;
+  mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Store the request context for violation reports
+  rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr)
+                 : mPreloadCSP->SetRequestContext(nullptr, this);
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
 {
   outCSPinJSON.Truncate();
   dom::CSPPolicies jsonPolicies;
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -197,19 +197,19 @@ public:
   NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
   NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
   NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
-  NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
+  NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
-  NS_IMETHOD SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP) override;
+  NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
   NS_IMETHOD GetIsNullPrincipal(bool* aResult) override;
   NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override;
   NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override;
   NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override;
   NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) final;
   NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
   NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -10,22 +10,23 @@
 %{C++
 struct JSPrincipals;
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 %}
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
+interface nsIDOMDocument;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 [ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
 
-[scriptable, builtinclass, uuid(188fc4a2-3157-4956-a7a2-d674991770da)]
+[scriptable, builtinclass, uuid(d0391e86-1ad7-4ab0-bb7c-14d6d9967369)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Returns whether the other principal is equivalent to this principal.
      * Principals are considered equal if they are the same principal, or
      * they have the same origin.
      */
     boolean equals(in nsIPrincipal other);
@@ -128,37 +129,50 @@ interface nsIPrincipal : nsISerializable
      * @throws NS_ERROR_DOM_BAD_URI if the load is not allowed.
      */
     void checkMayLoad(in nsIURI uri, in boolean report,
                       in boolean allowIfInheritsPrincipal);
 
     /**
      * A Content Security Policy associated with this principal.
      *
-     * Please note that if a csp was already set on the
-     * principal, then it should not be destroyed! Instead, the
-     * current csp should be quried and extended by
-     * calling AppendPolicy() on it.
+     * Use this function to query the associated CSP with this principal.
      */
-    [noscript] attribute nsIContentSecurityPolicy csp;
+    [noscript] readonly attribute nsIContentSecurityPolicy csp;
+
+    /*
+     * Use this function to query a CSP associated with this principal.
+     * If no CSP is associated with this principal then one is created
+     * internally and setRequestContext is called on the CSP using aDocument.
+     *
+     * Please note if aDocument is null, then setRequestContext on the
+     * CSP object is called using the current principal.
+     */
+    [noscript] nsIContentSecurityPolicy ensureCSP(in nsIDOMDocument aDocument);
 
     /**
      * A speculative Content Security Policy associated with this
      * principal. Set during speculative loading (preloading) and
      * used *only* for preloads.
      *
      * If you want to query the CSP associated with that principal,
      * then this is *not* what you want. Instead query 'csp'.
-     * 
-     * Please note that if a preloadCSP was already set on the
-     * principal, then it should not be destroyed! Instead, the
-     * current preloadCSP should be quried and extended by
-     * calling AppendPolicy() on it.
      */
-    [noscript] attribute nsIContentSecurityPolicy preloadCsp;
+    [noscript] readonly attribute nsIContentSecurityPolicy preloadCsp;
+
+    /*
+     * Use this function to query a speculative CSP associated with this
+     * principal. If no speculative CSP is associated with this principal
+     * then one is created internally and setRequestContext is called on
+     * the CSP using aDocument.
+     *
+     * Please note if aDocument is null, then setRequestContext on the
+     * speculative CSP object is called using the current principal.
+     */
+    [noscript] nsIContentSecurityPolicy ensurePreloadCSP(in nsIDOMDocument aDocument);
 
     /**
      * The CSP of the principal in JSON notation.
      * Note, that the CSP itself is not exposed to JS, but script
      * should be able to obtain a JSON representation of the CSP.
      */
     readonly attribute AString cspJSON;
 
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsPrincipal.cpp
@@ -393,29 +393,24 @@ nsPrincipal::Read(nsIObjectInputStream* 
 
   PrincipalOriginAttributes attrs;
   bool ok = attrs.PopulateFromSuffix(suffix);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
 
   rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // This may be null.
-  nsCOMPtr<nsIContentSecurityPolicy> csp = do_QueryInterface(supports, &rv);
-
   rv = Init(codebase, attrs);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = SetCsp(csp);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // need to link in the CSP context here (link in the URI of the protected
-  // resource).
-  if (csp) {
-    csp->SetRequestContext(nullptr, this);
+  mCSP = do_QueryInterface(supports, &rv);
+  // make sure setRequestContext is called after Init(),
+  // to make sure  the principals URI been initalized.
+  if (mCSP) {
+    mCSP->SetRequestContext(nullptr, this);
   }
 
   SetDomain(domain);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/caps/nsSystemPrincipal.cpp
+++ b/caps/nsSystemPrincipal.cpp
@@ -65,31 +65,33 @@ nsSystemPrincipal::GetOriginInternal(nsA
 NS_IMETHODIMP
 nsSystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
 {
   *aCsp = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
+nsSystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument,
+                             nsIContentSecurityPolicy** aCSP)
 {
   // CSP on a system principal makes no sense
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
 {
   *aPreloadCSP = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP)
+nsSystemPrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
+                                    nsIContentSecurityPolicy** aPreloadCSP)
 {
   // CSP on a system principal makes no sense
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSystemPrincipal::GetDomain(nsIURI** aDomain)
 {
--- a/caps/nsSystemPrincipal.h
+++ b/caps/nsSystemPrincipal.h
@@ -25,19 +25,19 @@ class nsSystemPrincipal final : public m
 public:
   NS_DECL_NSISERIALIZABLE
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
-  NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
+  NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
-  NS_IMETHOD SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP) override;
+  NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   nsSystemPrincipal() {}
 
   virtual void GetScriptLocation(nsACString &aStr) override;
 
 protected:
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -1182,17 +1182,17 @@ Animation::IsPossiblyOrphanedPendingAnim
 
 StickyTimeDuration
 Animation::EffectEnd() const
 {
   if (!mEffect) {
     return StickyTimeDuration(0);
   }
 
-  return mEffect->Timing().mDelay
+  return mEffect->SpecifiedTiming().mDelay
          + mEffect->GetComputedTiming().mActiveDuration;
 }
 
 nsIDocument*
 Animation::GetRenderedDocument() const
 {
   if (!mEffect) {
     return nullptr;
--- a/dom/animation/AnimationEffectReadOnly.h
+++ b/dom/animation/AnimationEffectReadOnly.h
@@ -9,35 +9,36 @@
 
 #include "mozilla/dom/BindingDeclarations.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 
 namespace mozilla {
 namespace dom {
 
+class AnimationEffectTimingReadOnly;
 struct ComputedTimingProperties;
 
 class AnimationEffectReadOnly : public nsISupports,
                                 public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationEffectReadOnly)
 
   explicit AnimationEffectReadOnly(nsISupports* aParent)
     : mParent(aParent)
   {
   }
 
   nsISupports* GetParentObject() const { return mParent; }
 
-  virtual void GetComputedTimingAsDict(ComputedTimingProperties& aRetVal) const
-  {
-  }
+  virtual already_AddRefed<AnimationEffectTimingReadOnly> Timing() const = 0;
+
+  virtual void GetComputedTimingAsDict(ComputedTimingProperties& aRetVal) const = 0;
 
 protected:
   virtual ~AnimationEffectReadOnly() = default;
 
 protected:
   nsCOMPtr<nsISupports> mParent;
 };
 
new file mode 100644
--- /dev/null
+++ b/dom/animation/AnimationEffectTimingReadOnly.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/AnimationEffectTimingReadOnly.h"
+#include "mozilla/dom/AnimationEffectTimingReadOnlyBinding.h"
+
+namespace mozilla {
+
+TimingParams&
+TimingParams::operator=(const dom::AnimationEffectTimingProperties& aRhs)
+{
+  mDuration = aRhs.mDuration;
+  mDelay = TimeDuration::FromMilliseconds(aRhs.mDelay);
+  mIterations = aRhs.mIterations;
+  mDirection = aRhs.mDirection;
+  mFill = aRhs.mFill;
+
+  return *this;
+}
+
+bool
+TimingParams::operator==(const TimingParams& aOther) const
+{
+  bool durationEqual;
+  if (mDuration.IsUnrestrictedDouble()) {
+    durationEqual = aOther.mDuration.IsUnrestrictedDouble() &&
+                    (mDuration.GetAsUnrestrictedDouble() ==
+                     aOther.mDuration.GetAsUnrestrictedDouble());
+  } else {
+    // We consider all string values and uninitialized values as meaning "auto".
+    // Since mDuration is either a string or uninitialized, we consider it equal
+    // if aOther.mDuration is also either a string or uninitialized.
+    durationEqual = !aOther.mDuration.IsUnrestrictedDouble();
+  }
+  return durationEqual &&
+         mDelay == aOther.mDelay &&
+         mIterations == aOther.mIterations &&
+         mDirection == aOther.mDirection &&
+         mFill == aOther.mFill;
+}
+
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectTimingReadOnly, mParent)
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationEffectTimingReadOnly, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationEffectTimingReadOnly, Release)
+
+JSObject*
+AnimationEffectTimingReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return AnimationEffectTimingReadOnlyBinding::Wrap(aCx, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/animation/AnimationEffectTimingReadOnly.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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_dom_AnimationEffectTimingReadOnly_h
+#define mozilla_dom_AnimationEffectTimingReadOnly_h
+
+#include "js/TypeDecls.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/UnionTypes.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+// X11 has a #define for None
+#ifdef None
+#undef None
+#endif
+#include "mozilla/dom/AnimationEffectReadOnlyBinding.h"  // for FillMode
+                                                         // and PlaybackDirection
+
+namespace mozilla {
+
+struct TimingParams
+{
+  // The unitialized state of mDuration represents "auto".
+  // Bug 1237173: We will replace this with Maybe<TimeDuration>.
+  dom::OwningUnrestrictedDoubleOrString mDuration;
+  TimeDuration mDelay;      // Initializes to zero
+  double mIterations = 1.0; // Can be NaN, negative, +/-Infinity
+  dom::PlaybackDirection mDirection = dom::PlaybackDirection::Normal;
+  dom::FillMode mFill = dom::FillMode::Auto;
+
+  TimingParams& operator=(const dom::AnimationEffectTimingProperties& aRhs);
+
+  bool operator==(const TimingParams& aOther) const;
+  bool operator!=(const TimingParams& aOther) const
+  {
+    return !(*this == aOther);
+  }
+};
+
+
+namespace dom {
+
+class AnimationEffectTimingReadOnly : public nsWrapperCache
+{
+public:
+  AnimationEffectTimingReadOnly() = default;
+  explicit AnimationEffectTimingReadOnly(const TimingParams& aTiming)
+    : mTiming(aTiming) { }
+
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEffectTimingReadOnly)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationEffectTimingReadOnly)
+
+protected:
+  virtual ~AnimationEffectTimingReadOnly() = default;
+
+public:
+  nsISupports* GetParentObject() const { return mParent; }
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+  double Delay() const { return mTiming.mDelay.ToMilliseconds(); }
+  double EndDelay() const { return 0.0; }
+  FillMode Fill() const { return mTiming.mFill; }
+  double IterationStart() const { return 0.0; }
+  double Iterations() const { return mTiming.mIterations; }
+  void GetDuration(OwningUnrestrictedDoubleOrString& aRetVal) const
+  {
+    aRetVal = mTiming.mDuration;
+  }
+  PlaybackDirection Direction() const { return mTiming.mDirection; }
+  void GetEasing(nsString& aRetVal) const { aRetVal.AssignLiteral("linear"); }
+
+  const TimingParams& AsTimingParams() const { return mTiming; }
+  void SetTimingParams(const TimingParams& aTiming) { mTiming = aTiming; }
+
+protected:
+  nsCOMPtr<nsISupports> mParent;
+  TimingParams mTiming;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_AnimationEffectTimingReadOnly_h
--- a/dom/animation/ComputedTimingFunction.h
+++ b/dom/animation/ComputedTimingFunction.h
@@ -45,9 +45,9 @@ private:
   nsTimingFunction::Type mType;
   nsSMILKeySpline mTimingFunction;
   uint32_t mSteps;
   nsTimingFunction::StepSyntax mStepSyntax;
 };
 
 } // namespace mozilla
 
-#endif // mozilla_dom_AnimationEffectReadOnly_h
+#endif // mozilla_ComputedTimingFunction_h
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/KeyframeEffect.h"
 
-#include "mozilla/dom/AnimationEffectReadOnlyBinding.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/dom/PropertyIndexedKeyframesBinding.h"
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
 #include "mozilla/StyleAnimationValue.h"
 #include "Layers.h" // For Layer
@@ -19,42 +18,29 @@
 #include "nsCSSPropertySet.h"
 #include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
 #include "nsCSSValue.h"
 #include "nsStyleUtil.h"
 #include <algorithm> // For std::max
 
 namespace mozilla {
 
-bool
-AnimationTiming::FillsForwards() const
-{
-  return mFillMode == dom::FillMode::Both ||
-         mFillMode == dom::FillMode::Forwards;
-}
-
-bool
-AnimationTiming::FillsBackwards() const
-{
-  return mFillMode == dom::FillMode::Both ||
-         mFillMode == dom::FillMode::Backwards;
-}
-
 // Helper functions for generating a ComputedTimingProperties dictionary
 static void
 GetComputedTimingDictionary(const ComputedTiming& aComputedTiming,
                             const Nullable<TimeDuration>& aLocalTime,
-                            const AnimationTiming& aTiming,
+                            const TimingParams& aTiming,
                             dom::ComputedTimingProperties& aRetVal)
 {
   // AnimationEffectTimingProperties
   aRetVal.mDelay = aTiming.mDelay.ToMilliseconds();
-  aRetVal.mFill = aTiming.mFillMode;
-  aRetVal.mIterations = aTiming.mIterationCount;
-  aRetVal.mDuration.SetAsUnrestrictedDouble() = aTiming.mIterationDuration.ToMilliseconds();
+  aRetVal.mFill = aComputedTiming.mFill;
+  aRetVal.mIterations = aComputedTiming.mIterations;
+  aRetVal.mDuration.SetAsUnrestrictedDouble() =
+    aComputedTiming.mDuration.ToMilliseconds();
   aRetVal.mDirection = aTiming.mDirection;
 
   // ComputedTimingProperties
   aRetVal.mActiveDuration = aComputedTiming.mActiveDuration.ToMilliseconds();
   aRetVal.mEndTime
     = std::max(aRetVal.mDelay + aRetVal.mActiveDuration + aRetVal.mEndDelay, 0.0);
   aRetVal.mLocalTime = AnimationUtils::TimeDurationToDouble(aLocalTime);
   aRetVal.mProgress = aComputedTiming.mProgress;
@@ -84,24 +70,25 @@ NS_INTERFACE_MAP_END_INHERITING(Animatio
 
 NS_IMPL_ADDREF_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
 NS_IMPL_RELEASE_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
 
 KeyframeEffectReadOnly::KeyframeEffectReadOnly(
   nsIDocument* aDocument,
   Element* aTarget,
   nsCSSPseudoElements::Type aPseudoType,
-  const AnimationTiming& aTiming)
+  const TimingParams& aTiming)
   : AnimationEffectReadOnly(aDocument)
   , mTarget(aTarget)
-  , mTiming(aTiming)
   , mPseudoType(aPseudoType)
   , mInEffectOnLastAnimationTimingUpdate(false)
 {
   MOZ_ASSERT(aTarget, "null animation target is not yet supported");
+
+  mTiming = new AnimationEffectTimingReadOnly(aTiming);
 }
 
 JSObject*
 KeyframeEffectReadOnly::WrapObject(JSContext* aCx,
                                    JS::Handle<JSObject*> aGivenProto)
 {
   return KeyframeEffectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
 }
@@ -113,23 +100,30 @@ KeyframeEffectReadOnly::IterationComposi
 }
 
 CompositeOperation
 KeyframeEffectReadOnly::Composite() const
 {
   return CompositeOperation::Replace;
 }
 
+already_AddRefed<AnimationEffectTimingReadOnly>
+KeyframeEffectReadOnly::Timing() const
+{
+  RefPtr<AnimationEffectTimingReadOnly> temp(mTiming);
+  return temp.forget();
+}
+
 void
-KeyframeEffectReadOnly::SetTiming(const AnimationTiming& aTiming)
+KeyframeEffectReadOnly::SetSpecifiedTiming(const TimingParams& aTiming)
 {
-  if (mTiming == aTiming) {
+  if (mTiming->AsTimingParams() == aTiming) {
     return;
   }
-  mTiming = aTiming;
+  mTiming->SetTimingParams(aTiming);
   if (mAnimation) {
     mAnimation->NotifyEffectTimingUpdated();
   }
   // NotifyEffectTimingUpdated will eventually cause
   // NotifyAnimationTimingUpdated to be called on this object which will
   // update our registration with the target element.
 }
 
@@ -200,41 +194,46 @@ KeyframeEffectReadOnly::GetLocalTime() c
   }
   return result;
 }
 
 void
 KeyframeEffectReadOnly::GetComputedTimingAsDict(ComputedTimingProperties& aRetVal) const
 {
   const Nullable<TimeDuration> currentTime = GetLocalTime();
-  GetComputedTimingDictionary(GetComputedTimingAt(currentTime, mTiming),
+  GetComputedTimingDictionary(GetComputedTimingAt(currentTime,
+                                                  SpecifiedTiming()),
                               currentTime,
-                              mTiming,
+                              SpecifiedTiming(),
                               aRetVal);
 }
 
 ComputedTiming
 KeyframeEffectReadOnly::GetComputedTimingAt(
                           const Nullable<TimeDuration>& aLocalTime,
-                          const AnimationTiming& aTiming)
+                          const TimingParams& aTiming)
 {
-  const TimeDuration zeroDuration;
-
-  // Currently we expect negative durations to be picked up during CSS
-  // parsing but when we start receiving timing parameters from other sources
-  // we will need to clamp negative durations here.
-  // For now, if we're hitting this it probably means we're overflowing
-  // integer arithmetic in mozilla::TimeStamp.
-  MOZ_ASSERT(aTiming.mIterationDuration >= zeroDuration,
-             "Expecting iteration duration >= 0");
+  const StickyTimeDuration zeroDuration;
 
   // Always return the same object to benefit from return-value optimization.
   ComputedTiming result;
 
-  result.mActiveDuration = ActiveDuration(aTiming);
+  if (aTiming.mDuration.IsUnrestrictedDouble()) {
+    double durationMs = aTiming.mDuration.GetAsUnrestrictedDouble();
+    if (!IsNaN(durationMs) && durationMs >= 0.0f) {
+      result.mDuration = StickyTimeDuration::FromMilliseconds(durationMs);
+    }
+  }
+  result.mIterations = IsNaN(aTiming.mIterations) || aTiming.mIterations < 0.0f ?
+                       1.0f :
+                       aTiming.mIterations;
+  result.mActiveDuration = ActiveDuration(result.mDuration, result.mIterations);
+  result.mFill = aTiming.mFill == dom::FillMode::Auto ?
+                 dom::FillMode::None :
+                 aTiming.mFill;
 
   // The default constructor for ComputedTiming sets all other members to
   // values consistent with an animation that has not been sampled.
   if (aLocalTime.IsNull()) {
     return result;
   }
   const TimeDuration& localTime = aLocalTime.Value();
 
@@ -242,86 +241,85 @@ KeyframeEffectReadOnly::GetComputedTimin
   // the end of the final iteration and not the start of the next iteration
   // so we set up a flag for that case.
   bool isEndOfFinalIteration = false;
 
   // Get the normalized time within the active interval.
   StickyTimeDuration activeTime;
   if (localTime >= aTiming.mDelay + result.mActiveDuration) {
     result.mPhase = ComputedTiming::AnimationPhase::After;
-    if (!aTiming.FillsForwards()) {
+    if (!result.FillsForwards()) {
       // The animation isn't active or filling at this time.
       result.mProgress.SetNull();
       return result;
     }
     activeTime = result.mActiveDuration;
     // Note that infinity == floor(infinity) so this will also be true when we
     // have finished an infinitely repeating animation of zero duration.
-    isEndOfFinalIteration =
-      aTiming.mIterationCount != 0.0 &&
-      aTiming.mIterationCount == floor(aTiming.mIterationCount);
+    isEndOfFinalIteration = result.mIterations != 0.0 &&
+                            result.mIterations == floor(result.mIterations);
   } else if (localTime < aTiming.mDelay) {
     result.mPhase = ComputedTiming::AnimationPhase::Before;
-    if (!aTiming.FillsBackwards()) {
+    if (!result.FillsBackwards()) {
       // The animation isn't active or filling at this time.
       result.mProgress.SetNull();
       return result;
     }
     // activeTime is zero
   } else {
     MOZ_ASSERT(result.mActiveDuration != zeroDuration,
                "How can we be in the middle of a zero-duration interval?");
     result.mPhase = ComputedTiming::AnimationPhase::Active;
     activeTime = localTime - aTiming.mDelay;
   }
 
   // Get the position within the current iteration.
   StickyTimeDuration iterationTime;
-  if (aTiming.mIterationDuration != zeroDuration) {
+  if (result.mDuration != zeroDuration) {
     iterationTime = isEndOfFinalIteration
-                    ? StickyTimeDuration(aTiming.mIterationDuration)
-                    : activeTime % aTiming.mIterationDuration;
+                    ? result.mDuration
+                    : activeTime % result.mDuration;
   } /* else, iterationTime is zero */
 
   // Determine the 0-based index of the current iteration.
   if (isEndOfFinalIteration) {
     result.mCurrentIteration =
-      aTiming.mIterationCount == NS_IEEEPositiveInfinity()
+      IsInfinite(result.mIterations) // Positive Infinity?
       ? UINT64_MAX // In GetComputedTimingDictionary(), we will convert this
                    // into Infinity.
-      : static_cast<uint64_t>(aTiming.mIterationCount) - 1;
+      : static_cast<uint64_t>(result.mIterations) - 1;
   } else if (activeTime == zeroDuration) {
     // If the active time is zero we're either in the first iteration
     // (including filling backwards) or we have finished an animation with an
     // iteration duration of zero that is filling forwards (but we're not at
     // the exact end of an iteration since we deal with that above).
     result.mCurrentIteration =
       result.mPhase == ComputedTiming::AnimationPhase::After
-      ? static_cast<uint64_t>(aTiming.mIterationCount) // floor
+      ? static_cast<uint64_t>(result.mIterations) // floor
       : 0;
   } else {
     result.mCurrentIteration =
-      static_cast<uint64_t>(activeTime / aTiming.mIterationDuration); // floor
+      static_cast<uint64_t>(activeTime / result.mDuration); // floor
   }
 
   // Normalize the iteration time into a fraction of the iteration duration.
   if (result.mPhase == ComputedTiming::AnimationPhase::Before) {
     result.mProgress.SetValue(0.0);
   } else if (result.mPhase == ComputedTiming::AnimationPhase::After) {
     double progress = isEndOfFinalIteration
                       ? 1.0
-                      : fmod(aTiming.mIterationCount, 1.0f);
+                      : fmod(result.mIterations, 1.0);
     result.mProgress.SetValue(progress);
   } else {
     // We are in the active phase so the iteration duration can't be zero.
-    MOZ_ASSERT(aTiming.mIterationDuration != zeroDuration,
+    MOZ_ASSERT(result.mDuration != zeroDuration,
                "In the active phase of a zero-duration animation?");
-    double progress = aTiming.mIterationDuration == TimeDuration::Forever()
+    double progress = result.mDuration == StickyTimeDuration::Forever()
                       ? 0.0
-                      : iterationTime / aTiming.mIterationDuration;
+                      : iterationTime / result.mDuration;
     result.mProgress.SetValue(progress);
   }
 
   bool thisIterationReverse = false;
   switch (aTiming.mDirection) {
     case PlaybackDirection::Normal:
       thisIterationReverse = false;
       break;
@@ -340,29 +338,29 @@ KeyframeEffectReadOnly::GetComputedTimin
   if (thisIterationReverse) {
     result.mProgress.SetValue(1.0 - result.mProgress.Value());
   }
 
   return result;
 }
 
 StickyTimeDuration
-KeyframeEffectReadOnly::ActiveDuration(const AnimationTiming& aTiming)
+KeyframeEffectReadOnly::ActiveDuration(const StickyTimeDuration& aIterationDuration,
+                                       double aIterationCount)
 {
-  if (aTiming.mIterationCount == mozilla::PositiveInfinity<float>()) {
+  if (IsInfinite(aIterationCount)) {
     // An animation that repeats forever has an infinite active duration
     // unless its iteration duration is zero, in which case it has a zero
     // active duration.
     const StickyTimeDuration zeroDuration;
-    return aTiming.mIterationDuration == zeroDuration
-           ? zeroDuration
-           : StickyTimeDuration::Forever();
+    return aIterationDuration == zeroDuration ?
+           zeroDuration :
+           StickyTimeDuration::Forever();
   }
-  return StickyTimeDuration(
-    aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount));
+  return aIterationDuration.MultDouble(aIterationCount);
 }
 
 // https://w3c.github.io/web-animations/#in-play
 bool
 KeyframeEffectReadOnly::IsInPlay() const
 {
   if (!mAnimation || mAnimation->PlayState() == AnimationPlayState::Finished) {
     return false;
@@ -636,63 +634,29 @@ DumpAnimationProperties(nsTArray<Animati
       printf("  %f..%f: %s..%s\n", s.mFromKey, s.mToKey,
              NS_ConvertUTF16toUTF8(fromValue).get(),
              NS_ConvertUTF16toUTF8(toValue).get());
     }
   }
 }
 #endif
 
-// Extract an iteration duration from an UnrestrictedDoubleOrXXX object.
-template <typename T>
-static TimeDuration
-GetIterationDuration(const T& aDuration) {
-  // Always return the same object to benefit from return-value optimization.
-  TimeDuration result;
-  if (aDuration.IsUnrestrictedDouble()) {
-    double durationMs = aDuration.GetAsUnrestrictedDouble();
-    if (!IsNaN(durationMs) && durationMs >= 0.0f) {
-      result = TimeDuration::FromMilliseconds(durationMs);
-    }
-  }
-  // else, aDuration should be zero
-  return result;
-}
-
-/* static */ AnimationTiming
+/* static */ TimingParams
 KeyframeEffectReadOnly::ConvertKeyframeEffectOptions(
     const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions)
 {
-  AnimationTiming animationTiming;
+  TimingParams timing;
 
   if (aOptions.IsKeyframeEffectOptions()) {
-    const KeyframeEffectOptions& opt = aOptions.GetAsKeyframeEffectOptions();
-
-    animationTiming.mIterationDuration = GetIterationDuration(opt.mDuration);
-    animationTiming.mDelay = TimeDuration::FromMilliseconds(opt.mDelay);
-    // FIXME: Covert mIterationCount to a valid value.
-    // Bug 1214536 should revise this and keep the original value, so
-    // AnimationTimingEffectReadOnly can get the original iterations.
-    animationTiming.mIterationCount = (IsNaN(opt.mIterations) ||
-                                      opt.mIterations < 0.0f) ?
-                                        1.0f :
-                                        opt.mIterations;
-    animationTiming.mDirection = opt.mDirection;
-    // FIXME: We should store original value.
-    animationTiming.mFillMode = (opt.mFill == FillMode::Auto) ?
-                                  FillMode::None :
-                                  opt.mFill;
+    timing = aOptions.GetAsKeyframeEffectOptions();
   } else {
-    animationTiming.mIterationDuration = GetIterationDuration(aOptions);
-    animationTiming.mDelay = TimeDuration(0);
-    animationTiming.mIterationCount = 1.0f;
-    animationTiming.mDirection = PlaybackDirection::Normal;
-    animationTiming.mFillMode = FillMode::None;
+    timing.mDuration.SetAsUnrestrictedDouble() =
+      aOptions.GetAsUnrestrictedDouble();
   }
-  return animationTiming;
+  return timing;
 }
 
 /**
  * A property and StyleAnimationValue pair.
  */
 struct KeyframeValue
 {
   nsCSSProperty mProperty;
@@ -1718,17 +1682,17 @@ KeyframeEffectReadOnly::Constructor(
     ErrorResult& aRv)
 {
   if (!aTarget) {
     // We don't support null targets yet.
     aRv.Throw(NS_ERROR_DOM_ANIM_NO_TARGET_ERR);
     return nullptr;
   }
 
-  AnimationTiming timing = ConvertKeyframeEffectOptions(aOptions);
+  TimingParams timing = ConvertKeyframeEffectOptions(aOptions);
 
   InfallibleTArray<AnimationProperty> animationProperties;
   BuildAnimationPropertyList(aGlobal.Context(), aTarget, aFrames,
                              animationProperties, aRv);
 
   if (aRv.Failed()) {
     return nullptr;
   }
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -10,89 +10,81 @@
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCSSPseudoElements.h"
 #include "nsIDocument.h"
 #include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ComputedTimingFunction.h" // ComputedTimingFunction
 #include "mozilla/LayerAnimationInfo.h"     // LayerAnimations::kRecords
+#include "mozilla/OwningNonNull.h"          // OwningNonNull<...>
 #include "mozilla/StickyTimeDuration.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/dom/AnimationEffectReadOnly.h"
+#include "mozilla/dom/AnimationEffectTimingReadOnly.h" // TimingParams
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/KeyframeBinding.h"
 #include "mozilla/dom/Nullable.h"
 
+
 struct JSContext;
 class nsCSSPropertySet;
 class nsIContent;
 class nsIDocument;
 class nsIFrame;
 class nsPresContext;
 
 namespace mozilla {
 
 struct AnimationCollection;
 class AnimValuesStyleRule;
 
 namespace dom {
-struct ComputedTimingProperties;
 class UnrestrictedDoubleOrKeyframeEffectOptions;
 enum class IterationCompositeOperation : uint32_t;
 enum class CompositeOperation : uint32_t;
 }
 
 /**
- * Input timing parameters.
- *
- * Eventually this will represent all the input timing parameters specified
- * by content but for now it encapsulates just the subset of those
- * parameters passed to GetPositionInIteration.
- */
-struct AnimationTiming
-{
-  TimeDuration mIterationDuration;
-  TimeDuration mDelay;
-  float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
-  dom::PlaybackDirection mDirection;
-  dom::FillMode mFillMode;
-
-  bool FillsForwards() const;
-  bool FillsBackwards() const;
-  bool operator==(const AnimationTiming& aOther) const {
-    return mIterationDuration == aOther.mIterationDuration &&
-           mDelay == aOther.mDelay &&
-           mIterationCount == aOther.mIterationCount &&
-           mDirection == aOther.mDirection &&
-           mFillMode == aOther.mFillMode;
-  }
-  bool operator!=(const AnimationTiming& aOther) const {
-    return !(*this == aOther);
-  }
-};
-
-/**
  * Stores the results of calculating the timing properties of an animation
  * at a given sample time.
  */
 struct ComputedTiming
 {
   // The total duration of the animation including all iterations.
   // Will equal StickyTimeDuration::Forever() if the animation repeats
   // indefinitely.
   StickyTimeDuration  mActiveDuration;
   // Progress towards the end of the current iteration. If the effect is
   // being sampled backwards, this will go from 1.0 to 0.0.
   // Will be null if the animation is neither animating nor
   // filling at the sampled time.
   Nullable<double>    mProgress;
   // Zero-based iteration index (meaningless if mProgress is null).
   uint64_t            mCurrentIteration = 0;
+  // Unlike TimingParams::mIterations, this value is
+  // guaranteed to be in the range [0, Infinity].
+  double              mIterations = 1.0;
+  StickyTimeDuration  mDuration;
+
+  // This is the computed fill mode so it is never auto
+  dom::FillMode       mFill = dom::FillMode::None;
+  bool FillsForwards() const {
+    MOZ_ASSERT(mFill != dom::FillMode::Auto,
+               "mFill should not be Auto in ComputedTiming.");
+    return mFill == dom::FillMode::Both ||
+           mFill == dom::FillMode::Forwards;
+  }
+  bool FillsBackwards() const {
+    MOZ_ASSERT(mFill != dom::FillMode::Auto,
+               "mFill should not be Auto in ComputedTiming.");
+    return mFill == dom::FillMode::Both ||
+           mFill == dom::FillMode::Backwards;
+  }
 
   enum class AnimationPhase {
     Null,   // Not sampled (null sample time)
     Before, // Sampled prior to the start of the active interval
     Active, // Sampled within the active interval
     After   // Sampled after (or at) the end of the active interval
   };
   AnimationPhase      mPhase = AnimationPhase::Null;
@@ -173,17 +165,17 @@ namespace dom {
 class Animation;
 
 class KeyframeEffectReadOnly : public AnimationEffectReadOnly
 {
 public:
   KeyframeEffectReadOnly(nsIDocument* aDocument,
                          Element* aTarget,
                          nsCSSPseudoElements::Type aPseudoType,
-                         const AnimationTiming& aTiming);
+                         const TimingParams& aTiming);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(KeyframeEffectReadOnly,
                                                         AnimationEffectReadOnly)
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
@@ -222,51 +214,58 @@ public:
   }
 
   IterationCompositeOperation IterationComposite() const;
   CompositeOperation Composite() const;
   void GetSpacing(nsString& aRetVal) const {
     aRetVal.AssignLiteral("distribute");
   }
 
-  const AnimationTiming& Timing() const { return mTiming; }
-  AnimationTiming& Timing() { return mTiming; }
-  void SetTiming(const AnimationTiming& aTiming);
+  already_AddRefed<AnimationEffectTimingReadOnly> Timing() const override;
+
+  const TimingParams& SpecifiedTiming() const
+  {
+    return mTiming->AsTimingParams();
+  }
+  void SetSpecifiedTiming(const TimingParams& aTiming);
   void NotifyAnimationTimingUpdated();
 
   Nullable<TimeDuration> GetLocalTime() const;
 
   // This function takes as input the timing parameters of an animation and
   // returns the computed timing at the specified local time.
   //
   // The local time may be null in which case only static parameters such as the
   // active duration are calculated. All other members of the returned object
   // are given a null/initial value.
   //
   // This function returns a null mProgress member of the return value
   // if the animation should not be run
   // (because it is not currently active and is not filling at this time).
   static ComputedTiming
   GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
-                      const AnimationTiming& aTiming);
+                      const TimingParams& aTiming);
 
   // Shortcut for that gets the computed timing using the current local time as
   // calculated from the timeline time.
   ComputedTiming
-  GetComputedTiming(const AnimationTiming* aTiming = nullptr) const
+  GetComputedTiming(const TimingParams* aTiming = nullptr) const
   {
-    return GetComputedTimingAt(GetLocalTime(), aTiming ? *aTiming : mTiming);
+    return GetComputedTimingAt(GetLocalTime(),
+                               aTiming ? *aTiming : SpecifiedTiming());
   }
 
   void
   GetComputedTimingAsDict(ComputedTimingProperties& aRetVal) const override;
 
-  // Return the duration of the active interval for the given timing parameters.
+  // Return the duration of the active interval for the given duration and
+  // iteration count.
   static StickyTimeDuration
-  ActiveDuration(const AnimationTiming& aTiming);
+  ActiveDuration(const StickyTimeDuration& aIterationDuration,
+                 double aIterationCount);
 
   bool IsInPlay() const;
   bool IsCurrent() const;
   bool IsInEffect() const;
 
   void SetAnimation(Animation* aAnimation);
   Animation* GetAnimation() const { return mAnimation; }
 
@@ -329,30 +328,30 @@ protected:
   // (b) It is "relevant" (i.e. yet to finish but not idle, or finished but
   //     filling forwards)
   //
   // As a result, we need to make sure this gets called whenever anything
   // changes with regards to this effects's timing including changes to the
   // owning Animation's timing.
   void UpdateTargetRegistration();
 
-  static AnimationTiming ConvertKeyframeEffectOptions(
+  static TimingParams ConvertKeyframeEffectOptions(
     const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions);
 
   static void BuildAnimationPropertyList(
     JSContext* aCx,
     Element* aTarget,
     const Optional<JS::Handle<JSObject*>>& aFrames,
     InfallibleTArray<AnimationProperty>& aResult,
     ErrorResult& aRv);
 
   nsCOMPtr<Element> mTarget;
   RefPtr<Animation> mAnimation;
 
-  AnimationTiming mTiming;
+  OwningNonNull<AnimationEffectTimingReadOnly> mTiming;
   nsCSSPseudoElements::Type mPseudoType;
 
   InfallibleTArray<AnimationProperty> mProperties;
 
   // The computed progress last time we composed the style rule. This is
   // used to detect when the progress is not changing (e.g. due to a step
   // timing function) so we can avoid unnecessary style updates.
   Nullable<double> mProgressOnLastCompose;
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
 EXPORTS.mozilla.dom += [
     'Animation.h',
     'AnimationEffectReadOnly.h',
+    'AnimationEffectTimingReadOnly.h',
     'AnimationTimeline.h',
     'DocumentTimeline.h',
     'KeyframeEffect.h',
 ]
 
 EXPORTS.mozilla += [
     'AnimationComparator.h',
     'AnimationUtils.h',
@@ -24,16 +25,17 @@ EXPORTS.mozilla += [
     'EffectSet.h',
     'PendingAnimationTracker.h',
     'PseudoElementHashEntry.h',
 ]
 
 UNIFIED_SOURCES += [
     'Animation.cpp',
     'AnimationEffectReadOnly.cpp',
+    'AnimationEffectTimingReadOnly.cpp',
     'AnimationTimeline.cpp',
     'AnimationUtils.cpp',
     'AnimValuesStyleRule.cpp',
     'ComputedTimingFunction.cpp',
     'DocumentTimeline.cpp',
     'EffectCompositor.cpp',
     'EffectSet.cpp',
     'KeyframeEffect.cpp',
--- a/dom/base/TextInputProcessor.cpp
+++ b/dom/base/TextInputProcessor.cpp
@@ -339,17 +339,17 @@ TextInputProcessor::PrepareKeyboardEvent
                       uint32_t& aKeyFlags,
                       uint8_t aOptionalArgc,
                       WidgetKeyboardEvent*& aKeyboardEvent)
 {
   aKeyboardEvent = nullptr;
 
   aKeyboardEvent =
     aOptionalArgc && aDOMKeyEvent ?
-      aDOMKeyEvent->GetInternalNSEvent()->AsKeyboardEvent() : nullptr;
+      aDOMKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent() : nullptr;
   if (!aKeyboardEvent || aOptionalArgc < 2) {
     aKeyFlags = 0;
   }
 
   if (!aKeyboardEvent) {
     return NS_OK;
   }
 
@@ -764,17 +764,17 @@ TextInputProcessor::Keydown(nsIDOMKeyEve
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
   if (!aOptionalArgc) {
     aKeyFlags = 0;
   }
   if (NS_WARN_IF(!aDOMKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   WidgetKeyboardEvent* originalKeyEvent =
-    aDOMKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aDOMKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   if (NS_WARN_IF(!originalKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   return KeydownInternal(*originalKeyEvent, aKeyFlags, true, *aConsumedFlags);
 }
 
 TextEventDispatcher::DispatchTo
 TextInputProcessor::GetDispatchTo() const
@@ -870,17 +870,17 @@ TextInputProcessor::Keyup(nsIDOMKeyEvent
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
   if (!aOptionalArgc) {
     aKeyFlags = 0;
   }
   if (NS_WARN_IF(!aDOMKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   WidgetKeyboardEvent* originalKeyEvent =
-    aDOMKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aDOMKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   if (NS_WARN_IF(!originalKeyEvent)) {
     return NS_ERROR_INVALID_ARG;
   }
   return KeyupInternal(*originalKeyEvent, aKeyFlags, *aDoDefault);
 }
 
 nsresult
 TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -1556,17 +1556,17 @@ WebSocketImpl::Init(JSContext* aCx,
     return;
   }
 
   // Potentially the page uses the CSP directive 'upgrade-insecure-requests'.
   // In such a case we have to upgrade ws: to wss: and also update mSecure
   // to reflect that upgrade. Please note that we can not upgrade from ws:
   // to wss: before performing content policy checks because CSP needs to
   // send reports in case the scheme is about to be upgraded.
-  if (!mSecure && originDoc && originDoc->GetUpgradeInsecureRequests()) {
+  if (!mSecure && originDoc && originDoc->GetUpgradeInsecureRequests(false)) {
     // let's use the old specification before the upgrade for logging
     NS_ConvertUTF8toUTF16 reportSpec(mURI);
 
     // upgrade the request from ws:// to wss:// and mark as secure
     mURI.ReplaceSubstring("ws://", "wss://");
     if (NS_WARN_IF(mURI.Find("wss://") != 0)) {
       return;
     }
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -111,18 +111,18 @@ nsContentPolicy::CheckPolicy(CPMethod   
         if (doc) {
             requestingLocation = doc->GetDocumentURI();
         }
     }
 
     nsContentPolicyType externalType =
         nsContentUtils::InternalContentPolicyTypeToExternal(contentType);
 
-    nsContentPolicyType externalTypeOrScript =
-        nsContentUtils::InternalContentPolicyTypeToExternalOrScript(contentType);
+    nsContentPolicyType externalTypeOrMCBInternal =
+        nsContentUtils::InternalContentPolicyTypeToExternalOrMCBInternal(contentType);
 
     nsContentPolicyType externalTypeOrCSPInternal =
        nsContentUtils::InternalContentPolicyTypeToExternalOrCSPInternal(contentType);
 
     nsCOMPtr<nsIContentPolicy> mixedContentBlocker =
         do_GetService(NS_MIXEDCONTENTBLOCKER_CONTRACTID);
 
     nsCOMPtr<nsIContentPolicy> cspService =
@@ -135,21 +135,23 @@ nsContentPolicy::CheckPolicy(CPMethod   
     nsresult rv;
     nsCOMArray<nsIContentPolicy> entries;
     mPolicies.GetEntries(entries);
     int32_t count = entries.Count();
     for (int32_t i = 0; i < count; i++) {
         /* check the appropriate policy */
         // Send the internal content policy type to the mixed content blocker
         // which needs to know about TYPE_INTERNAL_WORKER,
-        // TYPE_INTERNAL_SHARED_WORKER and TYPE_INTERNAL_SERVICE_WORKER.
+        // TYPE_INTERNAL_SHARED_WORKER and TYPE_INTERNAL_SERVICE_WORKER
+        // and also preloads: TYPE_INTERNAL_SCRIPT_PRELOAD,
+        // TYPE_INTERNAL_IMAGE_PRELOAD, TYPE_INTERNAL_STYLESHEET_PRELOAD
         bool isMixedContentBlocker = mixedContentBlocker == entries[i];
         nsContentPolicyType type = externalType;
         if (isMixedContentBlocker) {
-            type = externalTypeOrScript;
+            type = externalTypeOrMCBInternal;
         }
         // Send the internal content policy type for CSP which needs to
         // know about preloads and workers, in particular:
         // * TYPE_INTERNAL_SCRIPT_PRELOAD
         // * TYPE_INTERNAL_IMAGE_PRELOAD
         // * TYPE_INTERNAL_STYLESHEET_PRELOAD
         // * TYPE_INTERNAL_WORKER
         // * TYPE_INTERNAL_SHARED_WORKER
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -4950,23 +4950,23 @@ IsCaseChangeableChar(uint32_t aChar)
 /* static */
 void
 nsContentUtils::GetAccelKeyCandidates(nsIDOMKeyEvent* aDOMKeyEvent,
                   nsTArray<nsShortcutCandidate>& aCandidates)
 {
   NS_PRECONDITION(aCandidates.IsEmpty(), "aCandidates must be empty");
 
   nsAutoString eventType;
-  aDOMKeyEvent->GetType(eventType);
+  aDOMKeyEvent->AsEvent()->GetType(eventType);
   // Don't process if aDOMKeyEvent is not a keypress event.
   if (!eventType.EqualsLiteral("keypress"))
     return;
 
   WidgetKeyboardEvent* nativeKeyEvent =
-    aDOMKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aDOMKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   if (nativeKeyEvent) {
     NS_ASSERTION(nativeKeyEvent->mClass == eKeyboardEventClass,
                  "wrong type of native event");
     // nsShortcutCandidate::mCharCode is a candidate charCode.
     // nsShoftcutCandidate::mIgnoreShift means the mCharCode should be tried to
     // execute a command with/without shift key state. If this is TRUE, the
     // shifted key state should be ignored. Otherwise, don't ignore the state.
     // the priority of the charCodes are (shift key is not pressed):
@@ -7986,27 +7986,27 @@ nsContentUtils::InternalContentPolicyTyp
 
   default:
     return aType;
   }
 }
 
 /* static */
 nsContentPolicyType
-nsContentUtils::InternalContentPolicyTypeToExternalOrScript(nsContentPolicyType aType)
+nsContentUtils::InternalContentPolicyTypeToExternalOrMCBInternal(nsContentPolicyType aType)
 {
   switch (aType) {
   case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
   case nsIContentPolicy::TYPE_INTERNAL_WORKER:
   case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
   case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
     return aType;
 
   default:
-    return InternalContentPolicyTypeToExternal(aType);
+    return InternalContentPolicyTypeToExternalOrPreload(aType);
   }
 }
 
 /* static */
 nsContentPolicyType
 nsContentUtils::InternalContentPolicyTypeToExternalOrPreload(nsContentPolicyType aType)
 {
   if (aType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -981,26 +981,28 @@ public:
   static nsIContentPolicy *GetContentPolicy();
 
   /**
    * Map internal content policy types to external ones.
    */
   static nsContentPolicyType InternalContentPolicyTypeToExternal(nsContentPolicyType aType);
 
   /**
-   * Map internal content policy types to external ones or script types:
+   * Map internal content policy types to external ones or script types or preload types:
    *   * TYPE_INTERNAL_SCRIPT
    *   * TYPE_INTERNAL_WORKER
    *   * TYPE_INTERNAL_SHARED_WORKER
    *   * TYPE_INTERNAL_SERVICE_WORKER
-   *
+   *   * TYPE_INTERNAL_SCRIPT_PRELOAD
+   *   * TYPE_INTERNAL_IMAGE_PRELOAD
+   *   * TYPE_INTERNAL_STYLESHEET_PRELOAD
    *
    * Note: DO NOT call this function unless you know what you're doing!
    */
-  static nsContentPolicyType InternalContentPolicyTypeToExternalOrScript(nsContentPolicyType aType);
+  static nsContentPolicyType InternalContentPolicyTypeToExternalOrMCBInternal(nsContentPolicyType aType);
 
   /**
    * Map internal content policy types to external ones or preload types:
    *   * TYPE_INTERNAL_SCRIPT_PRELOAD
    *   * TYPE_INTERNAL_IMAGE_PRELOAD
    *   * TYPE_INTERNAL_STYLESHEET_PRELOAD
    *
    * Note: DO NOT call this function unless you know what you're doing!
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -2545,22 +2545,22 @@ nsDocument::StartDocumentLoad(const char
   // toplevel document, but also to nested documents. Let's propagate that
   // flag from the parent to the nested document.
   nsCOMPtr<nsIDocShellTreeItem> treeItem = this->GetDocShell();
   if (treeItem) {
     nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
     treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
     if (sameTypeParent) {
       mUpgradeInsecureRequests =
-        sameTypeParent->GetDocument()->GetUpgradeInsecureRequests();
+        sameTypeParent->GetDocument()->GetUpgradeInsecureRequests(false);
       // if the parent document makes use of upgrade-insecure-requests
       // then subdocument preloads should always be upgraded.
       mUpgradeInsecurePreloads =
         mUpgradeInsecureRequests ||
-        sameTypeParent->GetDocument()->GetUpgradeInsecurePreloads();
+        sameTypeParent->GetDocument()->GetUpgradeInsecureRequests(true);
     }
   }
 
   // If this is not a data document, set CSP.
   if (!mLoadedAsData) {
     nsresult rv = InitCSP(aChannel);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -2780,29 +2780,18 @@ nsDocument::InitCSP(nsIChannel* aChannel
       MOZ_LOG(gCspPRLog, LogLevel::Debug, ("%s %s %s",
            "This document is sharing principal with another document.",
            "Since the document is an app, CSP was already set.",
            "Skipping attempt to set CSP."));
       return NS_OK;
     }
   }
 
-  csp = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
-
-  if (NS_FAILED(rv)) {
-    MOZ_LOG(gCspPRLog, LogLevel::Debug, ("Failed to create CSP object: %x", rv));
-    return rv;
-  }
-
-  // used as a "self" identifier for the CSP.
-  nsCOMPtr<nsIURI> selfURI;
-  aChannel->GetURI(getter_AddRefs(selfURI));
-
-  // Store the request context for violation reports
-  csp->SetRequestContext(this, nullptr);
+  rv = principal->EnsureCSP(this, getter_AddRefs(csp));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // ----- if the doc is an app and we want a default CSP, apply it.
   if (applyAppDefaultCSP) {
     csp->AppendPolicy(appDefaultCSP, false, false);
   }
 
   // ----- if the doc is an app and specifies a CSP in its manifest, apply it.
   if (applyAppManifestCSP) {
@@ -2842,24 +2831,17 @@ nsDocument::InitCSP(nsIChannel* aChannel
 
     if (NS_FAILED(rv) || !safeAncestry) {
       MOZ_LOG(gCspPRLog, LogLevel::Debug,
               ("CSP doesn't like frame's ancestry, not loading."));
       // stop!  ERROR page!
       aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
     }
   }
-
-  rv = principal->SetCsp(csp);
-  NS_ENSURE_SUCCESS(rv, rv);
-  MOZ_LOG(gCspPRLog, LogLevel::Debug,
-         ("Inserted CSP into principal %p", principal));
-
   ApplySettingsFromCSP(false);
-
   return NS_OK;
 }
 
 void
 nsDocument::StopDocumentLoad()
 {
   if (mParser) {
     mParserAborted = true;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -316,30 +316,25 @@ public:
 
   /**
    * If true, this flag indicates that all subresource loads for this
    * document need to be upgraded from http to https.
    * This flag becomes true if the CSP of the document itself, or any
    * of the document's ancestors up to the toplevel document makes use
    * of the CSP directive 'upgrade-insecure-requests'.
    */
-  bool GetUpgradeInsecureRequests() const
+  bool GetUpgradeInsecureRequests(bool aPreload) const
   {
+    if (aPreload) {
+      return mUpgradeInsecurePreloads;
+    }
     return mUpgradeInsecureRequests;
   }
 
   /**
-   * Same as GetUpgradeInsecureRequests() but *only* for preloads.
-   */
-  bool GetUpgradeInsecurePreloads() const
-  {
-    return mUpgradeInsecurePreloads;
-  }
-
-  /**
    * Set the principal responsible for this document.
    */
   virtual void SetPrincipal(nsIPrincipal *aPrincipal) = 0;
 
   /**
    * Return the LoadGroup for the document. May return null.
    */
   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -641,16 +641,31 @@ nsScriptLoader::ProcessScriptElement(nsI
       return true;
     }
 
     if (request->IsDoneLoading() && ReadyToExecuteScripts()) {
       // The request has already been loaded and there are no pending style
       // sheets. If the script comes from the network stream, cheat for
       // performance reasons and avoid a trip through the event loop.
       if (aElement->GetParserCreated() == FROM_PARSER_NETWORK) {
+        // Attempt to compile script off-thread first -- it reduces locking of
+        // the main thread for long time.
+        if (NumberOfProcessors() > 1 &&
+            AttemptAsyncScriptCompile(request) == NS_OK) {
+          NS_ASSERTION(request->mProgress == nsScriptLoadRequest::Progress_Compiling,
+              "Request should be off-thread compiling now.");
+          NS_ASSERTION(!mParserBlockingRequest,
+              "There can be only one parser-blocking script at a time");
+          NS_ASSERTION(mXSLTRequests.isEmpty(),
+              "Parser-blocking scripts and XSLT scripts in the same doc!");
+          mParserBlockingRequest = request;
+          return true;
+        }
+        // And process a request if off-thread compilation heuristics think that
+        // non-async way will be faster.
         return ProcessRequest(request) == NS_ERROR_HTMLPARSER_BLOCK;
       }
       // Otherwise, we've got a document.written script, make a trip through
       // the event loop to hide the preload effects from the scripts on the
       // Web page.
       NS_ASSERTION(!mParserBlockingRequest,
           "There can be only one parser-blocking script at a time");
       NS_ASSERTION(mXSLTRequests.isEmpty(),
@@ -1786,17 +1801,17 @@ nsScriptLoadHandler::TryDecodeRawData(co
                       &srcLen,
                       mBuffer.begin() + haveRead,
                       &dstLen);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   haveRead += dstLen;
   MOZ_ASSERT(haveRead <= capacity, "mDecoder produced more data than expected");
-  mBuffer.resizeUninitialized(haveRead);
+  MOZ_ALWAYS_TRUE(mBuffer.resizeUninitialized(haveRead));
 
   return NS_OK;
 }
 
 bool
 nsScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
                                    const uint8_t* aData,
                                    uint32_t aDataLength,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3235,17 +3235,17 @@ class CGConstructorEnabled(CGAbstractMet
                                    Argument("JS::Handle<JSObject*>", "aObj")])
 
     def definition_body(self):
         body = CGList([], "\n")
 
         conditions = []
         iface = self.descriptor.interface
 
-        if not iface.isExposedInWindow():
+        if not iface.isExposedOnMainThread():
             exposedInWindowCheck = dedent(
                 """
                 MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
                 """)
             body.append(CGGeneric(exposedInWindowCheck))
 
         if iface.isExposedInSomeButNotAllWorkers():
             workerGlobals = sorted(iface.getWorkerExposureSet())
@@ -3254,17 +3254,17 @@ class CGConstructorEnabled(CGAbstractMet
             exposedInWorkerCheck = fill(
                 """
                 const char* name = js::GetObjectClass(aObj)->name;
                 if (${workerCondition}) {
                   return false;
                 }
                 """, workerCondition=workerCondition.define())
             exposedInWorkerCheck = CGGeneric(exposedInWorkerCheck)
-            if iface.isExposedInWindow():
+            if iface.isExposedOnMainThread():
                 exposedInWorkerCheck = CGIfWrapper(exposedInWorkerCheck,
                                                    "!NS_IsMainThread()")
             body.append(exposedInWorkerCheck)
 
         pref = iface.getExtendedAttribute("Pref")
         if pref:
             assert isinstance(pref, list) and len(pref) == 1
             conditions.append('Preferences::GetBool("%s")' % pref[0])
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -496,16 +496,20 @@ class IDLExposureMixins():
             self._exposureGlobalNames.add(scope.primaryGlobalName)
 
         globalNameSetToExposureSet(scope, self._exposureGlobalNames,
                                    self.exposureSet)
 
     def isExposedInWindow(self):
         return 'Window' in self.exposureSet
 
+    def isExposedOnMainThread(self):
+        return (self.isExposedInWindow() or
+                self.isExposedInSystemGlobals())
+
     def isExposedInAnyWorker(self):
         return len(self.getWorkerExposureSet()) > 0
 
     def isExposedInSystemGlobals(self):
         return 'BackstagePass' in self.exposureSet
 
     def isExposedInSomeButNotAllWorkers(self):
         """
--- a/dom/canvas/WebGL2ContextVertices.cpp
+++ b/dom/canvas/WebGL2ContextVertices.cpp
@@ -117,20 +117,20 @@ WebGL2Context::VertexAttribI4i(GLuint in
       gl->fVertexAttribI4i(index, x, y, z, w);
     }
   }
 }
 
 void
 WebGL2Context::VertexAttribI4iv(GLuint index, size_t length, const GLint* v)
 {
-  if (!ValidateAttribIndex(index, "vertexAttribI4iv"))
+  if (!ValidateAttribArraySetter("vertexAttribI4iv", 4, length))
     return;
 
-  if (!ValidateAttribArraySetter("vertexAttribI4iv", 4, length))
+  if (!ValidateAttribIndex(index, "vertexAttribI4iv"))
     return;
 
   mVertexAttribType[index] = LOCAL_GL_INT;
 
   MakeContextCurrent();
 
   if (index) {
     gl->fVertexAttribI4iv(index, v);
@@ -178,17 +178,17 @@ WebGL2Context::VertexAttribI4ui(GLuint i
 }
 
 void
 WebGL2Context::VertexAttribI4uiv(GLuint index, size_t length, const GLuint* v)
 {
   if (IsContextLost())
     return;
 
-  if (!ValidateAttribIndex(index, "vertexAttribI4uiv"))
+  if (!ValidateAttribArraySetter("vertexAttribI4uiv", 4, length))
     return;
 
   if (!ValidateAttribIndex(index, "vertexAttribI4uiv"))
     return;
 
   mVertexAttribType[index] = LOCAL_GL_UNSIGNED_INT;
 
   MakeContextCurrent();
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -443,18 +443,18 @@ WebGLContext::ValidateUniformLocation(We
 bool
 WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t setterElemSize,
                                         uint32_t arrayLength)
 {
     if (IsContextLost())
         return false;
 
     if (arrayLength < setterElemSize) {
-        ErrorInvalidOperation("%s: Array must have >= %d elements.", name,
-                              setterElemSize);
+        ErrorInvalidValue("%s: Array must have >= %d elements.", name,
+                          setterElemSize);
         return false;
     }
 
     return true;
 }
 
 bool
 WebGLContext::ValidateUniformSetter(WebGLUniformLocation* loc,
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -579,30 +579,30 @@ IMEStateManager::OnMouseButtonEventInEdi
   if (!sActiveIMEContentObserver->IsManaging(aPresContext, aContent)) {
     MOZ_LOG(sISMLog, LogLevel::Debug,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "the active IMEContentObserver isn't managing the editor"));
     return false;
   }
 
   WidgetMouseEvent* internalEvent =
-    aMouseEvent->GetInternalNSEvent()->AsMouseEvent();
+    aMouseEvent->AsEvent()->GetInternalNSEvent()->AsMouseEvent();
   if (NS_WARN_IF(!internalEvent)) {
     MOZ_LOG(sISMLog, LogLevel::Debug,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "the internal event of aMouseEvent isn't WidgetMouseEvent"));
     return false;
   }
 
   bool consumed =
     sActiveIMEContentObserver->OnMouseButtonEvent(aPresContext, internalEvent);
 
   if (MOZ_LOG_TEST(sISMLog, LogLevel::Info)) {
     nsAutoString eventType;
-    aMouseEvent->GetType(eventType);
+    aMouseEvent->AsEvent()->GetType(eventType);
     MOZ_LOG(sISMLog, LogLevel::Info,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "mouse event (type=%s, button=%d) is %s",
        NS_ConvertUTF16toUTF8(eventType).get(), internalEvent->button,
        consumed ? "consumed" : "not consumed"));
   }
 
   return consumed;
@@ -625,17 +625,17 @@ IMEStateManager::OnClickInEditor(nsPresC
        "the mouse event isn't fired on the editor managed by ISM"));
     return;
   }
 
   nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
   NS_ENSURE_TRUE_VOID(widget);
 
   bool isTrusted;
-  nsresult rv = aMouseEvent->GetIsTrusted(&isTrusted);
+  nsresult rv = aMouseEvent->AsEvent()->GetIsTrusted(&isTrusted);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (!isTrusted) {
     MOZ_LOG(sISMLog, LogLevel::Debug,
       ("ISM:   IMEStateManager::OnClickInEditor(), "
        "the mouse event isn't a trusted event"));
     return; // ignore untrusted event.
   }
 
--- a/dom/events/UIEvent.cpp
+++ b/dom/events/UIEvent.cpp
@@ -341,16 +341,22 @@ UIEvent::GetIsChar(bool* aIsChar)
 
 bool
 UIEvent::IsChar() const
 {
   WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
   return keyEvent ? keyEvent->isChar : false;
 }
 
+mozilla::dom::Event*
+UIEvent::AsEvent(void)
+{
+  return this;
+}
+
 NS_IMETHODIMP
 UIEvent::DuplicatePrivateData()
 {
   mClientPoint =
     Event::GetClientCoords(mPresContext, mEvent, mEvent->refPoint,
                            mClientPoint);
   mMovementPoint = GetMovementPoint();
   mLayerPoint = GetLayerPoint();
--- a/dom/fetch/InternalRequest.h
+++ b/dom/fetch/InternalRequest.h
@@ -83,17 +83,17 @@ class Request;
 
 class InternalRequest final
 {
   friend class Request;
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
 
-  explicit InternalRequest()
+  InternalRequest()
     : mMethod("GET")
     , mHeaders(new InternalHeaders(HeadersGuardEnum::None))
     , mContentPolicyType(nsIContentPolicy::TYPE_FETCH)
     , mReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR))
     , mMode(RequestMode::No_cors)
     , mCredentialsMode(RequestCredentials::Omit)
     , mResponseTainting(LoadTainting::Basic)
     , mCacheMode(RequestCache::Default)
@@ -108,16 +108,46 @@ public:
     , mSameOriginDataURL(true)
     , mSkipServiceWorker(false)
     , mSynchronous(false)
     , mUnsafeRequest(false)
     , mUseURLCredentials(false)
   {
   }
 
+  InternalRequest(const nsACString& aURL,
+                  const nsACString& aMethod,
+                  already_AddRefed<InternalHeaders> aHeaders,
+                  RequestMode aMode,
+                  RequestRedirect aRequestRedirect,
+                  RequestCredentials aRequestCredentials,
+                  const nsAString& aReferrer,
+                  nsContentPolicyType aContentPolicyType)
+    : mMethod(aMethod)
+    , mURL(aURL)
+    , mHeaders(aHeaders)
+    , mContentPolicyType(aContentPolicyType)
+    , mReferrer(aReferrer)
+    , mMode(aMode)
+    , mCredentialsMode(aRequestCredentials)
+    , mResponseTainting(LoadTainting::Basic)
+    , mCacheMode(RequestCache::Default)
+    , mRedirectMode(aRequestRedirect)
+    , mAuthenticationFlag(false)
+    , mForceOriginHeader(false)
+    , mPreserveContentCodings(false)
+      // FIXME See the above comment in the default constructor.
+    , mSameOriginDataURL(true)
+    , mSkipServiceWorker(false)
+    , mSynchronous(false)
+    , mUnsafeRequest(false)
+    , mUseURLCredentials(false)
+  {
+  }
+
   already_AddRefed<InternalRequest> Clone();
 
   void
   GetMethod(nsCString& aMethod) const
   {
     aMethod.Assign(mMethod);
   }
 
--- a/dom/gamepad/cocoa/CocoaGamepad.cpp
+++ b/dom/gamepad/cocoa/CocoaGamepad.cpp
@@ -326,36 +326,36 @@ DarwinGamepadService::InputValueChanged(
         dpad_buttons newState = { false, false, false, false };
         UnpackDpad(IOHIDValueGetIntegerValue(value),
                    IOHIDElementGetLogicalMin(element),
                    IOHIDElementGetLogicalMax(element),
                    newState);
         const int numButtons = gamepad.numButtons();
         for (unsigned b = 0; b < ArrayLength(newState); b++) {
           if (newState[b] != oldState[b]) {
-            NewButtonEvent(i, numButtons - 4 + b, newState[b]);
+            NewButtonEvent(gamepad.mSuperIndex, numButtons - 4 + b, newState[b]);
           }
         }
         gamepad.setDpadState(newState);
       } else if (const Axis* axis = gamepad.lookupAxis(element)) {
         double d = IOHIDValueGetIntegerValue(value);
         double v = 2.0f * (d - axis->min) /
           (double)(axis->max - axis->min) - 1.0f;
-        NewAxisMoveEvent(i, axis->id, v);
+        NewAxisMoveEvent(gamepad.mSuperIndex, axis->id, v);
       } else if (const Button* button = gamepad.lookupButton(element)) {
         int iv = IOHIDValueGetIntegerValue(value);
         bool pressed = iv != 0;
         double v = 0;
         if (button->analog) {
           double dv = iv;
           v = (dv - button->min) / (double)(button->max - button->min);
         } else {
           v = pressed ? 1.0 : 0.0;
         }
-        NewButtonEvent(i, button->id, pressed, v);
+        NewButtonEvent(gamepad.mSuperIndex, button->id, pressed, v);
       }
       return;
     }
   }
 }
 
 void
 DarwinGamepadService::DeviceAddedCallback(void* data, IOReturn result,
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -85,16 +85,17 @@ class nsGeolocationRequest final
   NS_DECL_NSIGEOLOCATIONUPDATE
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGeolocationRequest, nsIContentPermissionRequest)
 
   nsGeolocationRequest(Geolocation* aLocator,
                        const GeoPositionCallback& aCallback,
                        const GeoPositionErrorCallback& aErrorCallback,
                        PositionOptions* aOptions,
+                       uint8_t aProtocolType,
                        bool aWatchPositionRequest = false,
                        int32_t aWatchId = 0);
   void Shutdown();
 
   void SendLocation(nsIDOMGeoPosition* aLocation);
   bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
   void SetTimeoutTimer();
   void StopTimeoutTimer();
@@ -115,16 +116,17 @@ class nsGeolocationRequest final
   GeoPositionErrorCallback mErrorCallback;
   nsAutoPtr<PositionOptions> mOptions;
 
   RefPtr<Geolocation> mLocator;
 
   int32_t mWatchId;
   bool mShutdown;
   nsCOMPtr<nsIContentPermissionRequester> mRequester;
+  uint8_t mProtocolType;
 };
 
 static PositionOptions*
 CreatePositionOptionsCopy(const PositionOptions& aOptions)
 {
   nsAutoPtr<PositionOptions> geoOptions(new PositionOptions());
 
   geoOptions->mEnableHighAccuracy = aOptions.mEnableHighAccuracy;
@@ -349,25 +351,27 @@ PositionError::NotifyCallback(const GeoP
 ////////////////////////////////////////////////////
 // nsGeolocationRequest
 ////////////////////////////////////////////////////
 
 nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
                                            const GeoPositionCallback& aCallback,
                                            const GeoPositionErrorCallback& aErrorCallback,
                                            PositionOptions* aOptions,
+                                           uint8_t aProtocolType,
                                            bool aWatchPositionRequest,
                                            int32_t aWatchId)
   : mIsWatchPositionRequest(aWatchPositionRequest),
     mCallback(aCallback),
     mErrorCallback(aErrorCallback),
     mOptions(aOptions),
     mLocator(aLocator),
     mWatchId(aWatchId),
-    mShutdown(false)
+    mShutdown(false),
+    mProtocolType(aProtocolType)
 {
   nsCOMPtr<nsIDOMWindow> win = do_QueryReferent(mLocator->GetOwner());
   if (win) {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(win);
     if (window) {
       mRequester = new nsContentPermissionRequester(window);
     }
   }
@@ -448,29 +452,41 @@ nsGeolocationRequest::GetElement(nsIDOME
   NS_ENSURE_ARG_POINTER(aRequestingElement);
   *aRequestingElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::Cancel()
 {
+  if (mRequester) {
+    // Record the number of denied requests for regular web content.
+    // This method is only called when the user explicitly denies the request,
+    // and is not called when the page is simply unloaded, or similar.
+    Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType);
+  }
+
   if (mLocator->ClearPendingRequest(this)) {
     return NS_OK;
   }
 
   NotifyError(nsIDOMGeoPositionError::PERMISSION_DENIED);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::Allow(JS::HandleValue aChoices)
 {
   MOZ_ASSERT(aChoices.isUndefined());
 
+  if (mRequester) {
+    // Record the number of granted requests for regular web content.
+    Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType + 10);
+  }
+
   if (mLocator->ClearPendingRequest(this)) {
     return NS_OK;
   }
 
   RefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
 
   bool canUseCache = false;
   CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
@@ -1188,17 +1204,18 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(Geolocat
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Geolocation)
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Geolocation,
                                       mPendingCallbacks,
                                       mWatchingCallbacks,
                                       mPendingRequests)
 
 Geolocation::Geolocation()
-: mLastWatchId(0)
+: mProtocolType(ProtocolType::OTHER)
+, mLastWatchId(0)
 {
 }
 
 Geolocation::~Geolocation()
 {
   if (mService) {
     Shutdown();
   }
@@ -1229,16 +1246,34 @@ Geolocation::Init(nsIDOMWindow* aContent
 
     if (XRE_IsContentProcess()) {
       doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
                                   /* listener */ this,
                                   /* use capture */ true,
                                   /* wants untrusted */ false);
     }
 
+    nsCOMPtr<nsIURI> uri;
+    nsresult rv = mPrincipal->GetURI(getter_AddRefs(uri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    bool isHttp;
+    rv = uri->SchemeIs("http", &isHttp);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    bool isHttps;
+    rv = uri->SchemeIs("https", &isHttps);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // Store the protocol to send via telemetry later.
+    if (isHttp) {
+      mProtocolType = ProtocolType::HTTP;
+    } else if (isHttps) {
+      mProtocolType = ProtocolType::HTTPS;
+    }
   }
 
   // If no aContentDom was passed into us, we are being used
   // by chrome/c++ and have no mOwner, no mPrincipal, and no need
   // to prompt.
   mService = nsGeolocationService::GetGeolocationService();
   if (mService) {
     mService->AddLocator(this);
@@ -1489,21 +1524,23 @@ nsresult
 Geolocation::GetCurrentPosition(GeoPositionCallback& callback,
                                 GeoPositionErrorCallback& errorCallback,
                                 PositionOptions *options)
 {
   if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  RefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this,
-                                                                    callback,
-                                                                    errorCallback,
-                                                                    options,
-                                                                    false);
+  // Count the number of requests per protocol/scheme.
+  Telemetry::Accumulate(Telemetry::GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN,
+                        static_cast<uint8_t>(mProtocolType));
+
+  RefPtr<nsGeolocationRequest> request =
+    new nsGeolocationRequest(this, callback, errorCallback, options,
+                             static_cast<uint8_t>(mProtocolType), false);
 
   if (!sGeoEnabled) {
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
     NS_DispatchToMainThread(ev);
     return NS_OK;
   }
 
   if (!mOwner && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
@@ -1578,25 +1615,26 @@ Geolocation::WatchPosition(GeoPositionCa
                            GeoPositionErrorCallback& aErrorCallback,
                            PositionOptions* aOptions,
                            int32_t* aRv)
 {
   if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  // Count the number of requests per protocol/scheme.
+  Telemetry::Accumulate(Telemetry::GEOLOCATION_WATCHPOSITION_SECURE_ORIGIN,
+                        static_cast<uint8_t>(mProtocolType));
+
   // The watch ID:
   *aRv = mLastWatchId++;
 
-  RefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this,
-                                                                    aCallback,
-                                                                    aErrorCallback,
-                                                                    aOptions,
-                                                                    true,
-                                                                    *aRv);
+  RefPtr<nsGeolocationRequest> request =
+    new nsGeolocationRequest(this, aCallback, aErrorCallback, aOptions,
+                             static_cast<uint8_t>(mProtocolType), true, *aRv);
 
   if (!sGeoEnabled) {
     GPSLOG("request allow event");
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
     NS_DispatchToMainThread(ev);
     return NS_OK;
   }
 
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -213,16 +213,22 @@ private:
   nsTArray<RefPtr<nsGeolocationRequest> > mWatchingCallbacks;
 
   // window that this was created for.  Weak reference.
   nsWeakPtr mOwner;
 
   // where the content was loaded from
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
+  // the protocols we want to measure
+  enum class ProtocolType: uint8_t { OTHER, HTTP, HTTPS };
+
+  // the protocol used to load the content
+  ProtocolType mProtocolType;
+
   // owning back pointer.
   RefPtr<nsGeolocationService> mService;
 
   // Watch ID
   uint32_t mLastWatchId;
 
   // Pending requests are used when the service is not ready
   nsTArray<RefPtr<nsGeolocationRequest> > mPendingRequests;
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -1741,17 +1741,17 @@ HTMLFormElement::GetActionURL(nsIURI** a
   }
 
   // Potentially the page uses the CSP directive 'upgrade-insecure-requests'. In
   // such a case we have to upgrade the action url from http:// to https://.
   // If the actionURL is not http, then there is nothing to do.
   bool isHttpScheme = false;
   rv = actionURL->SchemeIs("http", &isHttpScheme);
   NS_ENSURE_SUCCESS(rv, rv);
-  if (isHttpScheme && document->GetUpgradeInsecureRequests()) {
+  if (isHttpScheme && document->GetUpgradeInsecureRequests(false)) {
     // let's use the old specification before the upgrade for logging
     nsAutoCString spec;
     rv = actionURL->GetSpec(spec);
     NS_ENSURE_SUCCESS(rv, rv);
     NS_ConvertUTF8toUTF16 reportSpec(spec);
 
     // upgrade the actionURL from http:// to use https://
     rv = actionURL->SetScheme(NS_LITERAL_CSTRING("https"));
--- a/dom/html/HTMLMetaElement.cpp
+++ b/dom/html/HTMLMetaElement.cpp
@@ -124,36 +124,23 @@ HTMLMetaElement::BindToTree(nsIDocument*
       
       nsAutoString content;
       rv = GetContent(content);
       NS_ENSURE_SUCCESS(rv, rv);
       content = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(content);
 
       nsIPrincipal* principal = aDocument->NodePrincipal();
       nsCOMPtr<nsIContentSecurityPolicy> csp;
-      rv = principal->GetCsp(getter_AddRefs(csp));
+      nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDocument);
+      rv = principal->EnsureCSP(domDoc, getter_AddRefs(csp));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Multiple CSPs (delivered through either header of meta tag) need to be
       // joined together, see:
       // https://w3c.github.io/webappsec/specs/content-security-policy/#delivery-html-meta-element
-      if (!csp) {
-        csp = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        // Store the request context so CSP can resolve 'self'
-        nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDocument);
-        rv = csp->SetRequestContext(domDoc, nullptr);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        // set the new CSP
-        rv = principal->SetCsp(csp);
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
       rv = csp->AppendPolicy(content,
                              false, // csp via meta tag can not be report only
                              true); // delivered through the meta tag
       NS_ENSURE_SUCCESS(rv, rv);
 
       aDocument->ApplySettingsFromCSP(false);
     }
   }
--- a/dom/html/HTMLSharedObjectElement.cpp
+++ b/dom/html/HTMLSharedObjectElement.cpp
@@ -338,22 +338,17 @@ HTMLSharedObjectElement::IntrinsicState(
   return nsGenericHTMLElement::IntrinsicState() | ObjectState();
 }
 
 uint32_t
 HTMLSharedObjectElement::GetCapabilities() const
 {
   uint32_t capabilities = eSupportPlugins | eAllowPluginSkipChannel;
   if (mNodeInfo->Equals(nsGkAtoms::embed)) {
-    capabilities |= eSupportSVG | eSupportImages;
-  }
-  // If this is a rewritten youtube flash embed, add documents to capabilities
-  // so that we can render HTML5 if possible.
-  if (mRewrittenYoutubeEmbed) {
-    capabilities |= eSupportDocuments;
+    capabilities |= eSupportSVG | eSupportImages | eSupportDocuments;
   }
 
   return capabilities;
 }
 
 void
 HTMLSharedObjectElement::DestroyContent()
 {
--- a/dom/interfaces/events/nsIDOMAnimationEvent.idl
+++ b/dom/interfaces/events/nsIDOMAnimationEvent.idl
@@ -1,19 +1,20 @@
 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
 /* 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
 
 /**
  * Animation events are defined in:
  * http://www.w3.org/TR/css3-animations/#animation-events-
  * http://dev.w3.org/csswg/css3-animations/#animation-events-
  */
 
-[builtinclass, uuid(772c7069-3f7d-42cf-97ab-b32f1c0b83da)]
-interface nsIDOMAnimationEvent : nsIDOMEvent {
+[builtinclass, uuid(ce6d1db3-53b8-4ade-9baa-70f4947200a2)]
+interface nsIDOMAnimationEvent : nsISupports
+{
   readonly attribute DOMString          animationName;
   readonly attribute float              elapsedTime;
   readonly attribute DOMString          pseudoElement;
 };
--- a/dom/interfaces/events/nsIDOMBeforeUnloadEvent.idl
+++ b/dom/interfaces/events/nsIDOMBeforeUnloadEvent.idl
@@ -1,26 +1,26 @@
 /* -*- Mode: IDL; 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
 
 /**
  * The nsIDOMBeforeUnloadEvent interface is the interface for events
  * sent to handlers of the "beforeunload" event. This event is
  * non-standard. Interface derived from Microsoft IE's event
  * implementation.
  *
  * http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/events.asp
  *
  */
 
-[builtinclass, uuid(96abf41b-32a8-4ff6-a0d6-4ade4ddebf89)]
-interface nsIDOMBeforeUnloadEvent : nsIDOMEvent
+[builtinclass, uuid(26c83933-a5a4-455e-8c46-69fa24dfa991)]
+interface nsIDOMBeforeUnloadEvent : nsISupports
 {
   /**
    * Attribute used to pass back a return value from a beforeunload
    * handler
    */
            attribute DOMString          returnValue;
 };
--- a/dom/interfaces/events/nsIDOMClipboardEvent.idl
+++ b/dom/interfaces/events/nsIDOMClipboardEvent.idl
@@ -1,20 +1,20 @@
 /* -*- 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 "domstubs.idl"
-#include "nsIDOMEvent.idl"
+#include "nsISupports.idl"
 
 interface nsIDOMDataTransfer;
 
-[builtinclass, uuid(4ef84980-52c2-425c-b41a-2ee75ec5d497)]
-interface nsIDOMClipboardEvent : nsIDOMEvent
+[builtinclass, uuid(b54d6144-3980-4895-83c7-82f158bc1cf5)]
+interface nsIDOMClipboardEvent : nsISupports
 {
   readonly attribute nsIDOMDataTransfer clipboardData;
 
   // The constructor must be used from script to initialize
   // clipboard events.
   [noscript] void initClipboardEvent(in DOMString typeArg,
                                      in boolean canBubbleArg,
                                      in boolean cancelableArg,
--- a/dom/interfaces/events/nsIDOMCommandEvent.idl
+++ b/dom/interfaces/events/nsIDOMCommandEvent.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
 
-[builtinclass, uuid(7efbe68a-811a-4159-801c-226948cfd08f)]
-interface nsIDOMCommandEvent : nsIDOMEvent
+[builtinclass, uuid(73a50e55-3eaa-4a38-a588-9b68a6d65032)]
+interface nsIDOMCommandEvent : nsISupports
 {
   readonly attribute DOMString command;
 
   void initCommandEvent(in DOMString typeArg,
                         in boolean canBubbleArg,
                         in boolean canCancelArg,
                         in DOMString command);
 };
--- a/dom/interfaces/events/nsIDOMDataContainerEvent.idl
+++ b/dom/interfaces/events/nsIDOMDataContainerEvent.idl
@@ -1,18 +1,18 @@
 /* -*- 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
 #include "nsIVariant.idl"
 
-[builtinclass, uuid(31ceb43e-5f49-43bf-9a18-3b60a535c814)]
-interface nsIDOMDataContainerEvent : nsIDOMEvent
+[builtinclass, uuid(a9f1f528-d106-4fea-8663-2d7f64b627a9)]
+interface nsIDOMDataContainerEvent : nsISupports
 {
   /**
    * Return the data associated with the given key.
    *
    * @param  key  the key
    * @return      the data associated with the key
    */
   nsIVariant getData(in DOMString key);
--- a/dom/interfaces/events/nsIDOMMessageEvent.idl
+++ b/dom/interfaces/events/nsIDOMMessageEvent.idl
@@ -1,24 +1,25 @@
 /* -*- Mode: IDL; 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
+#include "nsIDOMWindow.idl"
 
 /**
  * The nsIDOMMessageEvent interface is used for server-sent events and for
  * cross-domain messaging.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#messageevent
  */
-[builtinclass, uuid(4408a2f5-614f-40a3-8786-e16bd3f74e32)]
-interface nsIDOMMessageEvent : nsIDOMEvent
+[builtinclass, uuid(5d57bc56-30cf-4839-9e98-17f940120ec0)]
+interface nsIDOMMessageEvent : nsISupports
 {
   /**
    * Custom string data associated with this event.
    */
   [implicit_jscontext]
   readonly attribute jsval data;
   
   /**
--- a/dom/interfaces/events/nsIDOMMutationEvent.idl
+++ b/dom/interfaces/events/nsIDOMMutationEvent.idl
@@ -1,17 +1,18 @@
 /* -*- Mode: IDL; 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
+#include "nsIDOMNode.idl"
 
-[builtinclass, uuid(df7e4cd9-e41f-4c8e-a764-2e3191d2f463)]
-interface nsIDOMMutationEvent : nsIDOMEvent
+[builtinclass, uuid(30c9997f-bc4c-4890-b890-febb6ae3051b)]
+interface nsIDOMMutationEvent : nsISupports
 {
   const unsigned short      MODIFICATION       = 1;
   const unsigned short      ADDITION           = 2;
   const unsigned short      REMOVAL            = 3;
 
   readonly attribute nsIDOMNode       relatedNode;
   readonly attribute DOMString        prevValue;
   readonly attribute DOMString        newValue;
--- a/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
+++ b/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
@@ -1,24 +1,26 @@
 /* -*- Mode: IDL; 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
+#include "nsIDOMClientRectList.idl"
+#include "nsIDOMClientRect.idl"
 
 interface nsIDOMPaintRequestList;
 
 /**
  * The nsIDOMNotifyPaintEvent interface is used for the MozDOMAfterPaint
  * event, which fires at a window when painting has happened in
  * that window.
  */
-[builtinclass, uuid(550f660c-65a5-4e17-b828-3dbec7c44304)]
-interface nsIDOMNotifyPaintEvent : nsIDOMEvent
+[builtinclass, uuid(63f573a0-3e4e-474b-a0c2-bb4ca93febaa)]
+interface nsIDOMNotifyPaintEvent : nsISupports
 {
   /**
    * Get a list of rectangles which are affected. The rectangles are in CSS pixels
    * relative to the viewport origin.
    * If the caller is not trusted (e.g., regular Web content) then only painting
    * caused by the current document is reported; in particular, painting in subdocuments
    * is not reported.
    */
--- a/dom/interfaces/events/nsIDOMTransitionEvent.idl
+++ b/dom/interfaces/events/nsIDOMTransitionEvent.idl
@@ -1,19 +1,19 @@
 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
 /* 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
 
 /**
  * Transition events are defined in:
  * http://www.w3.org/TR/css3-transitions/#transition-events-
  * http://dev.w3.org/csswg/css3-transitions/#transition-events-
  */
 
-[builtinclass, uuid(acb69403-0dcb-4db0-9ffc-8a22cc56c4eb)]
-interface nsIDOMTransitionEvent : nsIDOMEvent {
+[builtinclass, uuid(ee3499bf-0f14-4bb6-829c-19ad24fd4a85)]
+interface nsIDOMTransitionEvent : nsISupports {
   readonly attribute DOMString           propertyName;
   readonly attribute float               elapsedTime;
   readonly attribute DOMString           pseudoElement;
 };
--- a/dom/interfaces/events/nsIDOMUIEvent.idl
+++ b/dom/interfaces/events/nsIDOMUIEvent.idl
@@ -1,25 +1,36 @@
 /* -*- Mode: IDL; 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 "nsIDOMEvent.idl"
+#include "nsISupports.idl"
+#include "nsIDOMWindow.idl"
 
 /**
  * The nsIDOMUIEvent interface is the datatype for all UI events in the
  * Document Object Model.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Events/
  */
 
-[builtinclass, uuid(db058d10-1db9-4cf9-bb4c-483c304a137f)]
-interface nsIDOMUIEvent : nsIDOMEvent
+%{C++
+namespace mozilla {
+namespace dom {
+class Event;
+}
+}
+%}
+
+[ptr] native EventPtr(mozilla::dom::Event);
+
+[builtinclass, uuid(75996b57-51f0-4c9c-aaaa-e35eaf347b66)]
+interface nsIDOMUIEvent : nsISupports
 {
   readonly attribute nsIDOMWindow       view;
   readonly attribute long               detail;
   void                      initUIEvent(in DOMString typeArg,
                                         in boolean canBubbleArg,
                                         in boolean cancelableArg,
                                         in nsIDOMWindow viewArg,
                                         in long detailArg);
@@ -33,9 +44,11 @@ interface nsIDOMUIEvent : nsIDOMEvent
   readonly attribute long               pageY;
   readonly attribute unsigned long      which;
   readonly attribute nsIDOMNode         rangeParent;
   readonly attribute long               rangeOffset;
 
            attribute boolean            cancelBubble;
 
   readonly attribute boolean            isChar;
+
+  [notxpcom, nostdcall] EventPtr AsEvent();
 };
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -646,40 +646,44 @@ GeckoMediaPluginServiceParent::UnloadPlu
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   MOZ_ASSERT(!mShuttingDownOnGMPThread);
   mShuttingDownOnGMPThread = true;
 #ifdef MOZ_CRASHREPORTER
       SetAsyncShutdownPluginState(nullptr, '2',
         NS_LITERAL_CSTRING("Starting to unload plugins"));
 #endif
 
+  nsTArray<RefPtr<GMPParent>> plugins;
   {
     MutexAutoLock lock(mMutex);
-    LOGD(("%s::%s plugins:%u including async:%u", __CLASS__, __FUNCTION__,
-          mPlugins.Length(), mAsyncShutdownPlugins.Length()));
+    // Move all plugins references to a local array. This way mMutex won't be
+    // locked when calling CloseActive (to avoid inter-locking).
+    plugins = Move(mPlugins);
+  }
+
+  LOGD(("%s::%s plugins:%u including async:%u", __CLASS__, __FUNCTION__,
+        plugins.Length(), mAsyncShutdownPlugins.Length()));
 #ifdef DEBUG
-    for (const auto& plugin : mPlugins) {
-      LOGD(("%s::%s plugin: '%s'", __CLASS__, __FUNCTION__,
-            plugin->GetDisplayName().get()));
-    }
-    for (const auto& plugin : mAsyncShutdownPlugins) {
-      LOGD(("%s::%s async plugin: '%s'", __CLASS__, __FUNCTION__,
-            plugin->GetDisplayName().get()));
-    }
+  for (const auto& plugin : plugins) {
+    LOGD(("%s::%s plugin: '%s'", __CLASS__, __FUNCTION__,
+          plugin->GetDisplayName().get()));
+  }
+  for (const auto& plugin : mAsyncShutdownPlugins) {
+    LOGD(("%s::%s async plugin: '%s'", __CLASS__, __FUNCTION__,
+          plugin->GetDisplayName().get()));
+  }
 #endif
-    // Note: CloseActive may be async; it could actually finish
-    // shutting down when all the plugins have unloaded.
-    for (size_t i = 0; i < mPlugins.Length(); i++) {
+  // Note: CloseActive may be async; it could actually finish
+  // shutting down when all the plugins have unloaded.
+  for (const auto& plugin : plugins) {
 #ifdef MOZ_CRASHREPORTER
-      SetAsyncShutdownPluginState(mPlugins[i], 'S',
-          NS_LITERAL_CSTRING("CloseActive"));
+    SetAsyncShutdownPluginState(plugin, 'S',
+        NS_LITERAL_CSTRING("CloseActive"));
 #endif
-      mPlugins[i]->CloseActive(true);
-    }
-    mPlugins.Clear();
+    plugin->CloseActive(true);
   }
 
 #ifdef MOZ_CRASHREPORTER
       SetAsyncShutdownPluginState(nullptr, '3',
         NS_LITERAL_CSTRING("Dispatching sync-shutdown-complete"));
 #endif
   nsCOMPtr<nsIRunnable> task(NS_NewRunnableMethod(
     this, &GeckoMediaPluginServiceParent::NotifySyncShutdownComplete));
@@ -1056,16 +1060,23 @@ GeckoMediaPluginServiceParent::RemoveOnG
     MutexAutoUnlock unlock(mMutex);
     for (auto& gmp : deadPlugins) {
       gmp->AbortAsyncShutdown();
       gmp->CloseActive(true);
     }
   }
 
   if (aDeleteFromDisk && !inUse) {
+    // Ensure the GMP dir and all files in it are writable, so we have
+    // permission to delete them.
+    directory->SetPermissions(0700);
+    DirectoryEnumerator iter(directory, DirectoryEnumerator::FilesAndDirs);
+    for (nsCOMPtr<nsIFile> dirEntry; (dirEntry = iter.Next()) != nullptr;) {
+      dirEntry->SetPermissions(0700);
+    }
     if (NS_SUCCEEDED(directory->Remove(true))) {
       mPluginsWaitingForDeletion.RemoveElement(aDirectory);
       NS_DispatchToMainThread(new NotifyObserversTask("gmp-directory-deleted",
                                                       nsString(aDirectory)),
                               NS_DISPATCH_NORMAL);
     }
   }
 }
--- a/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp
+++ b/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/Monitor.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/GrallocTextureClient.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include <binder/MemoryDealer.h>
 #include <media/IOMX.h>
 #include <utils/List.h>
 #include <media/stagefright/OMXCodec.h>
+#include <cutils/properties.h>
 
 extern mozilla::LogModule* GetPDMLog();
 
 #ifdef LOG
 #undef LOG
 #endif
 
 #define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("GonkOmxPlatformLayer:: " arg, ##__VA_ARGS__))
@@ -38,16 +39,23 @@ namespace mozilla {
 
 extern void GetPortIndex(nsTArray<uint32_t>& aPortIndex);
 
 bool IsSoftwareCodec(const char* aComponentName) {
   nsAutoCString str(aComponentName);
   return (str.Find(NS_LITERAL_CSTRING("OMX.google.")) == -1 ? false : true);
 }
 
+bool IsInEmulator()
+{
+  char propQemu[PROPERTY_VALUE_MAX];
+  property_get("ro.kernel.qemu", propQemu, "");
+  return !strncmp(propQemu, "1", 1);
+}
+
 class GonkOmxObserver : public BnOMXObserver {
 public:
   void onMessage(const omx_message& aMsg)
   {
     switch (aMsg.type) {
       case omx_message::EVENT:
       {
         sp<GonkOmxObserver> self = this;
@@ -284,17 +292,20 @@ GonkBufferData::InitGraphicBuffer(OMX_VI
 already_AddRefed<MediaData>
 GonkBufferData::GetPlatformMediaData()
 {
   if (mGonkPlatformLayer->GetTrackInfo()->GetAsAudioInfo()) {
     // This is audio decoding.
     return nullptr;
   }
 
-  MOZ_RELEASE_ASSERT(mTextureClientRecycleHandler);
+  if (!mTextureClientRecycleHandler) {
+    // There is no GraphicBuffer, it should fallback to normal YUV420 VideoData.
+    return nullptr;
+  }
 
   VideoInfo info;
   info.mDisplay = mGonkPlatformLayer->GetTrackInfo()->GetAsVideoInfo()->mDisplay;
   info.mImage = mGonkPlatformLayer->GetTrackInfo()->GetAsVideoInfo()->mImage;
   RefPtr<VideoData> data = VideoData::Create(info,
                                              mGonkPlatformLayer->GetImageContainer(),
                                              0,
                                              mBuffer->nTimeStamp,
@@ -515,45 +526,49 @@ GonkOmxPlatformLayer::InitOmxToStateLoad
   if (err != OK) {
       return OMX_ErrorUndefined;
   }
   mOmx = mOmxClient.interface();
   if (!mOmx.get()) {
     return OMX_ErrorUndefined;
   }
 
+  bool useHardwareCodecOnly = false;
+
+  // H264 and H263 has different profiles, software codec doesn't support high profile.
+  // So we use hardware codec only.
+  if (!IsInEmulator() &&
+      (mInfo->mMimeType.EqualsLiteral("video/avc") ||
+       mInfo->mMimeType.EqualsLiteral("video/mp4") ||
+       mInfo->mMimeType.EqualsLiteral("video/mp4v-es") ||
+       mInfo->mMimeType.EqualsLiteral("video/3gp"))) {
+    useHardwareCodecOnly = true;
+  }
+
+  LOG("find componenet for mime type %s", mInfo->mMimeType.Data());
   // In Gonk, the software component name has prefix "OMX.google". It needs to
   // have a way to use hardware codec first.
   android::Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
-  const char* swcomponent = nullptr;
+  nsTArray<const char*> components;
   OMXCodec::findMatchingCodecs(mInfo->mMimeType.Data(),
                                0,
                                nullptr,
                                0,
                                &matchingCodecs);
   for (uint32_t i = 0; i < matchingCodecs.size(); i++) {
-    const char* componentName = matchingCodecs.itemAt(i).mName.string();
-    if (IsSoftwareCodec(componentName)) {
-      swcomponent = componentName;
-    } else {
-      // Try to use hardware codec first.
-      if (LoadComponent(componentName)) {
-        mUsingHardwareCodec = true;
-        return OMX_ErrorNone;
-      }
-      LOG("failed to load component %s", componentName);
-    }
+    components.AppendElement(matchingCodecs.itemAt(i).mName.string());
   }
 
-  // TODO: in android ICS, the software codec is allocated in mediaserver by
-  //       default, it may be necessary to allocate it in local process.
-  //
-  // fallback to sw codec
-  if (swcomponent && LoadComponent(swcomponent)) {
-    return OMX_ErrorNone;
+  for (auto name : components) {
+    if (IsSoftwareCodec(name) && useHardwareCodecOnly) {
+      continue;
+    }
+    if (LoadComponent(name)) {
+      return OMX_ErrorNone;
+    }
   }
 
   LOG("no component is loaded");
   return OMX_ErrorUndefined;
 }
 
 OMX_ERRORTYPE
 GonkOmxPlatformLayer::EmptyThisBuffer(BufferData* aData)
--- a/dom/media/platforms/omx/OmxDataDecoder.cpp
+++ b/dom/media/platforms/omx/OmxDataDecoder.cpp
@@ -18,16 +18,18 @@ extern mozilla::LogModule* GetPDMLog();
 #define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("OmxDataDecoder::%s: " arg, __func__, ##__VA_ARGS__))
 
 #define CHECK_OMX_ERR(err)     \
   if (err != OMX_ErrorNone) {  \
     NotifyError(err, __func__);\
     return;                    \
   }                            \
 
+// There should be a better way to calculate it.
+#define MIN_VIDEO_INPUT_BUFFER_SIZE 64 * 1024
 
 namespace mozilla {
 
 static const char*
 StateTypeToStr(OMX_STATETYPE aType)
 {
   MOZ_ASSERT(aType == OMX_StateLoaded ||
              aType == OMX_StateIdle ||
@@ -55,29 +57,69 @@ StateTypeToStr(OMX_STATETYPE aType)
 }
 
 // There should be 2 ports and port number start from 0.
 void GetPortIndex(nsTArray<uint32_t>& aPortIndex) {
   aPortIndex.AppendElement(0);
   aPortIndex.AppendElement(1);
 }
 
+template<class T> void
+InitOmxParameter(T* aParam)
+{
+  PodZero(aParam);
+  aParam->nSize = sizeof(T);
+  aParam->nVersion.s.nVersionMajor = 1;
+}
+
+// A helper class to retrieve AudioData or VideoData.
+class MediaDataHelper {
+protected:
+  virtual ~MediaDataHelper() {}
+
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataHelper)
+
+  MediaDataHelper(const TrackInfo* aTrackInfo,
+                  layers::ImageContainer* aImageContainer,
+                  OmxPromiseLayer* aOmxLayer);
+
+  already_AddRefed<MediaData> GetMediaData(BufferData* aBufferData, bool& aPlatformDepenentData);
+
+protected:
+  already_AddRefed<AudioData> CreateAudioData(BufferData* aBufferData);
+
+  already_AddRefed<VideoData> CreateYUV420VideoData(BufferData* aBufferData);
+
+  const TrackInfo* mTrackInfo;
+
+  OMX_PARAM_PORTDEFINITIONTYPE mOutputPortDef;
+
+  // audio output
+  MediaQueue<AudioData> mAudioQueue;
+
+  AudioCompactor mAudioCompactor;
+
+  // video output
+  RefPtr<layers::ImageContainer> mImageContainer;
+};
+
 OmxDataDecoder::OmxDataDecoder(const TrackInfo& aTrackInfo,
                                MediaDataDecoderCallback* aCallback,
                                layers::ImageContainer* aImageContainer)
   : mMonitor("OmxDataDecoder")
   , mOmxTaskQueue(CreateMediaDecodeTaskQueue())
+  , mImageContainer(aImageContainer)
   , mWatchManager(this, mOmxTaskQueue)
   , mOmxState(OMX_STATETYPE::OMX_StateInvalid, "OmxDataDecoder::mOmxState")
   , mTrackInfo(aTrackInfo.Clone())
   , mFlushing(false)
   , mShuttingDown(false)
   , mCheckingInputExhausted(false)
   , mPortSettingsChanged(-1, "OmxDataDecoder::mPortSettingsChanged")
-  , mAudioCompactor(mAudioQueue)
   , mCallback(aCallback)
 {
   LOG("(%p)", this);
   mOmxLayer = new OmxPromiseLayer(mOmxTaskQueue, this, aImageContainer);
 
   nsCOMPtr<nsIRunnable> r =
     NS_NewRunnableMethod(this, &OmxDataDecoder::InitializationTask);
   mOmxTaskQueue->Dispatch(r.forget());
@@ -267,107 +309,35 @@ OmxDataDecoder::DoAsyncShutdown()
            })
     ->CompletionPromise()
     ->Then(mOmxTaskQueue, __func__,
            [self] () {
              LOG("DoAsyncShutdown: OMX_StateLoaded, it is safe to shutdown omx");
              self->mOmxLayer->Shutdown();
              self->mWatchManager.Shutdown();
              self->mOmxLayer = nullptr;
+             self->mMediaDataHelper = nullptr;
 
              MonitorAutoLock lock(self->mMonitor);
              self->mShuttingDown = false;
              self->mMonitor.Notify();
            },
            [self] () {
              self->mOmxLayer->Shutdown();
              self->mWatchManager.Shutdown();
              self->mOmxLayer = nullptr;
+             self->mMediaDataHelper = nullptr;
 
              MonitorAutoLock lock(self->mMonitor);
              self->mShuttingDown = false;
              self->mMonitor.Notify();
            });
 }
 
 void
-OmxDataDecoder::OutputAudio(BufferData* aBufferData)
-{
-  // TODO: it'd be better to move these code to BufferData::GetPlatformMediaData() or
-  //       some kind of abstract layer.
-  MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
-  OMX_BUFFERHEADERTYPE* buf = aBufferData->mBuffer;
-  AudioInfo* info = mTrackInfo->GetAsAudioInfo();
-  if (buf->nFilledLen) {
-    uint64_t offset = 0;
-    uint32_t frames = buf->nFilledLen / (2 * info->mChannels);
-    if (aBufferData->mRawData) {
-      offset = aBufferData->mRawData->mOffset;
-    }
-    typedef AudioCompactor::NativeCopy OmxCopy;
-    mAudioCompactor.Push(offset,
-                         buf->nTimeStamp,
-                         info->mRate,
-                         frames,
-                         info->mChannels,
-                         OmxCopy(buf->pBuffer + buf->nOffset,
-                                 buf->nFilledLen,
-                                 info->mChannels));
-    RefPtr<AudioData> audio = mAudioQueue.PopFront();
-    mCallback->Output(audio);
-  }
-  aBufferData->mStatus = BufferData::BufferStatus::FREE;
-}
-
-void
-OmxDataDecoder::OutputVideo(BufferData* aBufferData)
-{
-  MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
-
-  RefPtr<MediaData> data = aBufferData->GetPlatformMediaData();
-  MOZ_RELEASE_ASSERT(data);
-
-  VideoData* video(data->As<VideoData>());
-  if (aBufferData->mRawData) {
-    video->mTime = aBufferData->mRawData->mTime;
-    video->mTimecode = aBufferData->mRawData->mTimecode;
-    video->mOffset = aBufferData->mRawData->mOffset;
-    video->mDuration = aBufferData->mRawData->mDuration;
-    video->mKeyframe = aBufferData->mRawData->mKeyframe;
-  }
-
-  aBufferData->mStatus = BufferData::BufferStatus::OMX_CLIENT_OUTPUT;
-
-  // TextureClient's recycle callback is called when reference count of
-  // TextureClient becomes 1. In most cases, the last reference count is held
-  // by ITextureClientRecycleAllocator.
-  // And then promise will be resolved in the callback.
-  // TODO:
-  //   Because it is gonk specific behaviour, it needs to find a way to
-  //   proper abstracting it.
-  MOZ_RELEASE_ASSERT(aBufferData->mPromise.IsEmpty());
-  RefPtr<OmxBufferPromise> p = aBufferData->mPromise.Ensure(__func__);
-
-  RefPtr<OmxDataDecoder> self = this;
-  RefPtr<BufferData> buffer = aBufferData;
-  p->Then(mOmxTaskQueue, __func__,
-          [self, buffer] () {
-            MOZ_RELEASE_ASSERT(buffer->mStatus == BufferData::BufferStatus::OMX_CLIENT_OUTPUT);
-            buffer->mStatus = BufferData::BufferStatus::FREE;
-            self->FillAndEmptyBuffers();
-          },
-          [buffer] () {
-            MOZ_RELEASE_ASSERT(buffer->mStatus == BufferData::BufferStatus::OMX_CLIENT_OUTPUT);
-            buffer->mStatus = BufferData::BufferStatus::FREE;
-          });
-
-  mCallback->Output(video);
-}
-
-void
 OmxDataDecoder::FillBufferDone(BufferData* aData)
 {
   MOZ_ASSERT(!aData || aData->mStatus == BufferData::BufferStatus::OMX_CLIENT);
 
   // Don't output sample when flush or shutting down, especially for video
   // decoded frame. Because video decoded frame has a promise in BufferData
   // waiting for layer to resolve it via recycle callback on Gonk, if other
   // module doesn't send it to layer, it will cause a unresolved promise and
@@ -378,28 +348,64 @@ OmxDataDecoder::FillBufferDone(BufferDat
     return;
   }
 
   if (aData->mBuffer->nFlags & OMX_BUFFERFLAG_EOS) {
     // Reach eos, it's an empty data so it doesn't need to output.
     EndOfStream();
     aData->mStatus = BufferData::BufferStatus::FREE;
   } else {
-    if (mTrackInfo->IsAudio()) {
-      OutputAudio(aData);
-    } else if (mTrackInfo->IsVideo()) {
-      OutputVideo(aData);
-    } else {
-      MOZ_ASSERT(0);
-    }
+    Output(aData);
     FillAndEmptyBuffers();
   }
 }
 
 void
+OmxDataDecoder::Output(BufferData* aData)
+{
+  if (!mMediaDataHelper) {
+    mMediaDataHelper = new MediaDataHelper(mTrackInfo.get(), mImageContainer, mOmxLayer);
+  }
+
+  bool isPlatformData = false;
+  RefPtr<MediaData> data = mMediaDataHelper->GetMediaData(aData, isPlatformData);
+  if (!data) {
+    aData->mStatus = BufferData::BufferStatus::FREE;
+    return;
+  }
+
+  if (isPlatformData) {
+    // If the MediaData is platform dependnet data, it's mostly a kind of
+    // limited resource, for example, GraphicBuffer on Gonk. So we use promise
+    // to notify when the resource is free.
+    aData->mStatus = BufferData::BufferStatus::OMX_CLIENT_OUTPUT;
+
+    MOZ_RELEASE_ASSERT(aData->mPromise.IsEmpty());
+    RefPtr<OmxBufferPromise> p = aData->mPromise.Ensure(__func__);
+
+    RefPtr<OmxDataDecoder> self = this;
+    RefPtr<BufferData> buffer = aData;
+    p->Then(mOmxTaskQueue, __func__,
+        [self, buffer] () {
+          MOZ_RELEASE_ASSERT(buffer->mStatus == BufferData::BufferStatus::OMX_CLIENT_OUTPUT);
+          buffer->mStatus = BufferData::BufferStatus::FREE;
+          self->FillAndEmptyBuffers();
+        },
+        [buffer] () {
+          MOZ_RELEASE_ASSERT(buffer->mStatus == BufferData::BufferStatus::OMX_CLIENT_OUTPUT);
+          buffer->mStatus = BufferData::BufferStatus::FREE;
+        });
+  } else {
+    aData->mStatus = BufferData::BufferStatus::FREE;
+  }
+
+  mCallback->Output(data);
+}
+
+void
 OmxDataDecoder::FillBufferFailure(OmxBufferFailureHolder aFailureHolder)
 {
   NotifyError(aFailureHolder.mError, __func__);
 }
 
 void
 OmxDataDecoder::EmptyBufferDone(BufferData* aData)
 {
@@ -510,16 +516,17 @@ OmxDataDecoder::FindAvailableBuffer(OMX_
 {
   BUFFERLIST* buffers = GetBuffers(aType);
 
   for (uint32_t i = 0; i < buffers->Length(); i++) {
     BufferData* buf = buffers->ElementAt(i);
     if (buf->mStatus == BufferData::BufferStatus::FREE) {
       return buf;
     }
+    LOG("buffer is owned by %d, type %d", buf->mStatus, aType);
   }
 
   return nullptr;
 }
 
 nsresult
 OmxDataDecoder::AllocateBuffers(OMX_DIRTYPE aType)
 {
@@ -684,16 +691,20 @@ OmxDataDecoder::ConfigVideoCodec()
     OMX_VIDEO_CODINGTYPE codetype;
     if (videoInfo->mMimeType.EqualsLiteral("video/avc")) {
       codetype = OMX_VIDEO_CodingAVC;
     }
 
     if (def.eDir == OMX_DirInput) {
       def.format.video.eCompressionFormat = codetype;
       def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+      if (def.nBufferSize < MIN_VIDEO_INPUT_BUFFER_SIZE) {
+        def.nBufferSize = videoInfo->mImage.width * videoInfo->mImage.height;
+        LOG("Change input buffer size to %d", def.nBufferSize);
+      }
     } else {
       def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
     }
 
     err = mOmxLayer->SetParameter(OMX_IndexParamPortDefinition,
                                   &def,
                                   sizeof(def));
     if (err != OMX_ErrorNone) {
@@ -744,47 +755,43 @@ OmxDataDecoder::Event(OMX_EVENTTYPE aEve
 
   if (mOmxLayer->Event(aEvent, aData1, aData2)) {
     return true;
   }
 
   switch (aEvent) {
     case OMX_EventPortSettingsChanged:
     {
-      // According to spec: "To prevent the loss of any input data, the
-      // component issuing the OMX_EventPortSettingsChanged event on its input
-      // port should buffer all input port data that arrives between the
-      // emission of the OMX_EventPortSettingsChanged event and the arrival of
-      // the command to disable the input port."
-      //
-      // So client needs to disable port and reallocate buffers.
-      MOZ_ASSERT(mPortSettingsChanged == -1);
-      mPortSettingsChanged = aData1;
+      // Don't always disable port. See bug 1235340.
+      if (aData2 == 0 ||
+          aData2 == OMX_IndexParamPortDefinition) {
+        // According to spec: "To prevent the loss of any input data, the
+        // component issuing the OMX_EventPortSettingsChanged event on its input
+        // port should buffer all input port data that arrives between the
+        // emission of the OMX_EventPortSettingsChanged event and the arrival of
+        // the command to disable the input port."
+        //
+        // So client needs to disable port and reallocate buffers.
+        MOZ_ASSERT(mPortSettingsChanged == -1);
+        mPortSettingsChanged = aData1;
+      }
       LOG("Got OMX_EventPortSettingsChanged event");
       break;
     }
     default:
     {
       LOG("WARNING: got none handle event: %d, aData1: %d, aData2: %d",
           aEvent, aData1, aData2);
       return false;
     }
   }
 
   return true;
 }
 
-template<class T> void
-OmxDataDecoder::InitOmxParameter(T* aParam)
-{
-  PodZero(aParam);
-  aParam->nSize = sizeof(T);
-  aParam->nVersion.s.nVersionMajor = 1;
-}
-
 bool
 OmxDataDecoder::BuffersCanBeReleased(OMX_DIRTYPE aType)
 {
   BUFFERLIST* buffers = GetBuffers(aType);
   uint32_t len = buffers->Length();
   for (uint32_t i = 0; i < len; i++) {
     BufferData::BufferStatus buf_status = buffers->ElementAt(i)->mStatus;
     if (buf_status == BufferData::BufferStatus::OMX_COMPONENT ||
@@ -970,9 +977,155 @@ void OmxDataDecoder::FlushFailure(OmxCom
 {
   NotifyError(OMX_ErrorUndefined, __func__);
   mFlushing = false;
 
   MonitorAutoLock lock(mMonitor);
   mMonitor.Notify();
 }
 
+MediaDataHelper::MediaDataHelper(const TrackInfo* aTrackInfo,
+                                 layers::ImageContainer* aImageContainer,
+                                 OmxPromiseLayer* aOmxLayer)
+  : mTrackInfo(aTrackInfo)
+  , mAudioCompactor(mAudioQueue)
+  , mImageContainer(aImageContainer)
+{
+  // Get latest port definition.
+  nsTArray<uint32_t> ports;
+  GetPortIndex(ports);
+  for (auto idx : ports) {
+    InitOmxParameter(&mOutputPortDef);
+    mOutputPortDef.nPortIndex = idx;
+    aOmxLayer->GetParameter(OMX_IndexParamPortDefinition, &mOutputPortDef, sizeof(mOutputPortDef));
+    if (mOutputPortDef.eDir == OMX_DirOutput) {
+      break;
+    }
+  }
 }
+
+already_AddRefed<MediaData>
+MediaDataHelper::GetMediaData(BufferData* aBufferData, bool& aPlatformDepenentData)
+{
+  aPlatformDepenentData = false;
+  RefPtr<MediaData> data;
+
+  if (mTrackInfo->IsAudio()) {
+    if (!aBufferData->mBuffer->nFilledLen) {
+      return nullptr;
+    }
+    data = CreateAudioData(aBufferData);
+  } else if (mTrackInfo->IsVideo()) {
+    data = aBufferData->GetPlatformMediaData();
+    if (data) {
+      aPlatformDepenentData = true;
+    } else {
+      if (!aBufferData->mBuffer->nFilledLen) {
+        return nullptr;
+      }
+      // Get YUV VideoData, it uses more CPU, in most cases, on software codec.
+      data = CreateYUV420VideoData(aBufferData);
+    }
+
+    // Update video time code, duration... from the raw data.
+    VideoData* video(data->As<VideoData>());
+    if (aBufferData->mRawData) {
+      video->mTime = aBufferData->mRawData->mTime;
+      video->mTimecode = aBufferData->mRawData->mTimecode;
+      video->mOffset = aBufferData->mRawData->mOffset;
+      video->mDuration = aBufferData->mRawData->mDuration;
+      video->mKeyframe = aBufferData->mRawData->mKeyframe;
+    }
+  }
+
+  return data.forget();
+}
+
+already_AddRefed<AudioData>
+MediaDataHelper::CreateAudioData(BufferData* aBufferData)
+{
+  RefPtr<AudioData> audio;
+  OMX_BUFFERHEADERTYPE* buf = aBufferData->mBuffer;
+  const AudioInfo* info = mTrackInfo->GetAsAudioInfo();
+  if (buf->nFilledLen) {
+    uint64_t offset = 0;
+    uint32_t frames = buf->nFilledLen / (2 * info->mChannels);
+    if (aBufferData->mRawData) {
+      offset = aBufferData->mRawData->mOffset;
+    }
+    typedef AudioCompactor::NativeCopy OmxCopy;
+    mAudioCompactor.Push(offset,
+                         buf->nTimeStamp,
+                         info->mRate,
+                         frames,
+                         info->mChannels,
+                         OmxCopy(buf->pBuffer + buf->nOffset,
+                                 buf->nFilledLen,
+                                 info->mChannels));
+    audio = mAudioQueue.PopFront();
+  }
+
+  return audio.forget();
+}
+
+already_AddRefed<VideoData>
+MediaDataHelper::CreateYUV420VideoData(BufferData* aBufferData)
+{
+  uint8_t *yuv420p_buffer = (uint8_t *)aBufferData->mBuffer->pBuffer;
+  int32_t stride = mOutputPortDef.format.video.nStride;
+  int32_t slice_height = mOutputPortDef.format.video.nSliceHeight;
+  int32_t width = mTrackInfo->GetAsVideoInfo()->mImage.width;
+  int32_t height = mTrackInfo->GetAsVideoInfo()->mImage.height;
+
+  // TODO: convert other formats to YUV420.
+  if (mOutputPortDef.format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar) {
+    return nullptr;
+  }
+
+  size_t yuv420p_y_size = stride * slice_height;
+  size_t yuv420p_u_size = ((stride + 1) / 2) * ((slice_height + 1) / 2);
+  uint8_t *yuv420p_y = yuv420p_buffer;
+  uint8_t *yuv420p_u = yuv420p_y + yuv420p_y_size;
+  uint8_t *yuv420p_v = yuv420p_u + yuv420p_u_size;
+
+  VideoData::YCbCrBuffer b;
+  b.mPlanes[0].mData = yuv420p_y;
+  b.mPlanes[0].mWidth = width;
+  b.mPlanes[0].mHeight = height;
+  b.mPlanes[0].mStride = stride;
+  b.mPlanes[0].mOffset = 0;
+  b.mPlanes[0].mSkip = 0;
+
+  b.mPlanes[1].mData = yuv420p_u;
+  b.mPlanes[1].mWidth = (width + 1) / 2;
+  b.mPlanes[1].mHeight = (height + 1) / 2;
+  b.mPlanes[1].mStride = (stride + 1) / 2;
+  b.mPlanes[1].mOffset = 0;
+  b.mPlanes[1].mSkip = 0;
+
+  b.mPlanes[2].mData = yuv420p_v;
+  b.mPlanes[2].mWidth =(width + 1) / 2;
+  b.mPlanes[2].mHeight = (height + 1) / 2;
+  b.mPlanes[2].mStride = (stride + 1) / 2;
+  b.mPlanes[2].mOffset = 0;
+  b.mPlanes[2].mSkip = 0;
+
+  VideoInfo info;
+  info.mDisplay = mTrackInfo->GetAsVideoInfo()->mDisplay;
+  info.mImage = mTrackInfo->GetAsVideoInfo()->mImage;
+  RefPtr<VideoData> data = VideoData::Create(info,
+                                             mImageContainer,
+                                             0, // Filled later by caller.
+                                             0, // Filled later by caller.
+                                             1, // We don't know the duration.
+                                             b,
+                                             0, // Filled later by caller.
+                                             -1,
+                                             info.mImage);
+
+  LOG("YUV420 VideoData: disp width %d, height %d, pic width %d, height %d, time %ld",
+      info.mDisplay.width, info.mDisplay.height, info.mImage.width,
+      info.mImage.height, aBufferData->mBuffer->nTimeStamp);
+
+  return data.forget();
+}
+
+}
--- a/dom/media/platforms/omx/OmxDataDecoder.h
+++ b/dom/media/platforms/omx/OmxDataDecoder.h
@@ -7,19 +7,23 @@
 #if !defined(OmxDataDecoder_h_)
 #define OmxDataDecoder_h_
 
 #include "mozilla/Monitor.h"
 #include "PlatformDecoderModule.h"
 #include "OmxPromiseLayer.h"
 #include "MediaInfo.h"
 #include "AudioCompactor.h"
+#include "OMX_Component.h"
+#include "ImageContainer.h"
 
 namespace mozilla {
 
+class MediaDataHelper;
+
 typedef OmxPromiseLayer::OmxCommandPromise OmxCommandPromise;
 typedef OmxPromiseLayer::OmxBufferPromise OmxBufferPromise;
 typedef OmxPromiseLayer::OmxBufferFailureHolder OmxBufferFailureHolder;
 typedef OmxPromiseLayer::OmxCommandFailureHolder OmxCommandFailureHolder;
 typedef OmxPromiseLayer::BufferData BufferData;
 typedef OmxPromiseLayer::BUFFERLIST BUFFERLIST;
 
 /* OmxDataDecoder is the major class which performs followings:
@@ -105,19 +109,17 @@ protected:
   void SendEosBuffer();
 
   void EndOfStream();
 
   // It could be called after codec specific data is sent and component found
   // the port format is changed due to different codec specific.
   void PortSettingsChanged();
 
-  void OutputAudio(BufferData* aBufferData);
-
-  void OutputVideo(BufferData* aBufferData);
+  void Output(BufferData* aData);
 
   // Buffer can be released if its status is not OMX_COMPONENT or
   // OMX_CLIENT_OUTPUT.
   bool BuffersCanBeReleased(OMX_DIRTYPE aType);
 
   OMX_DIRTYPE GetPortDirection(uint32_t aPortIndex);
 
   void DoAsyncShutdown();
@@ -131,29 +133,29 @@ protected:
   BUFFERLIST* GetBuffers(OMX_DIRTYPE aType);
 
   nsresult AllocateBuffers(OMX_DIRTYPE aType);
 
   nsresult ReleaseBuffers(OMX_DIRTYPE aType);
 
   BufferData* FindAvailableBuffer(OMX_DIRTYPE aType);
 
-  template<class T> void InitOmxParameter(T* aParam);
-
   // aType could be OMX_DirMax for all types.
   RefPtr<OmxPromiseLayer::OmxBufferPromise::AllPromiseType>
   CollectBufferPromises(OMX_DIRTYPE aType);
 
   Monitor mMonitor;
 
   // The Omx TaskQueue.
   RefPtr<TaskQueue> mOmxTaskQueue;
 
   RefPtr<TaskQueue> mReaderTaskQueue;
 
+  RefPtr<layers::ImageContainer> mImageContainer;
+
   WatchManager<OmxDataDecoder> mWatchManager;
 
   // It is accessed in omx TaskQueue.
   Watchable<OMX_STATETYPE> mOmxState;
 
   RefPtr<OmxPromiseLayer> mOmxLayer;
 
   UniquePtr<TrackInfo> mTrackInfo;
@@ -180,21 +182,16 @@ protected:
 
   // It is access in Omx TaskQueue.
   nsTArray<RefPtr<MediaRawData>> mMediaRawDatas;
 
   BUFFERLIST mInPortBuffers;
 
   BUFFERLIST mOutPortBuffers;
 
-  // For audio output.
-  // TODO: because this class is for both video and audio decoding, so there
-  // should be some kind of abstract things to these members.
-  MediaQueue<AudioData> mAudioQueue;
-
-  AudioCompactor mAudioCompactor;
+  RefPtr<MediaDataHelper> mMediaDataHelper;
 
   MediaDataDecoderCallback* mCallback;
 };
 
 }
 
 #endif /* OmxDataDecoder_h_ */
--- a/dom/media/platforms/omx/OmxDecoderModule.cpp
+++ b/dom/media/platforms/omx/OmxDecoderModule.cpp
@@ -39,13 +39,18 @@ PlatformDecoderModule::ConversionRequire
 OmxDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
 {
   return kNeedNone;
 }
 
 bool
 OmxDecoderModule::SupportsMimeType(const nsACString& aMimeType) const
 {
+  // TODO: it could be better to query the support mine types from OMX instead
+  // of hard coding.
   return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
+         aMimeType.EqualsLiteral("video/mp4v-es") ||
+         aMimeType.EqualsLiteral("video/mp4") ||
+         aMimeType.EqualsLiteral("video/3gp") ||
          aMimeType.EqualsLiteral("video/avc");
 }
 
 }
--- a/dom/media/platforms/omx/OmxPromiseLayer.cpp
+++ b/dom/media/platforms/omx/OmxPromiseLayer.cpp
@@ -114,17 +114,17 @@ OmxPromiseLayer::GetBufferHolders(OMX_DI
 
   return &mOutbufferHolders;
 }
 
 already_AddRefed<MediaRawData>
 OmxPromiseLayer::FindAndRemoveRawData(OMX_TICKS aTimecode)
 {
   for (auto raw : mRawDatas) {
-    if (raw->mTimecode == aTimecode) {
+    if (raw->mTime == aTimecode) {
       mRawDatas.RemoveElement(raw);
       return raw.forget();
     }
   }
   return nullptr;
 }
 
 already_AddRefed<BufferData>
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -20,67 +20,80 @@
 #include "nsIDocument.h"
 #include "nsIXPConnect.h"
 #include "xpcpublic.h"
 #include "nsIDOMElement.h"
 #include "prmem.h"
 #include "nsIContent.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsWrapperCacheInlines.h"
-#include "js/HashTable.h"
+#include "js/GCHashTable.h"
+#include "js/TracingAPI.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/plugins/PluginAsyncSurrogate.h"
 
 using mozilla::plugins::AsyncNPObject;
 using mozilla::plugins::PluginAsyncSurrogate;
 
 #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
 
 using namespace mozilla::plugins::parent;
 using namespace mozilla;
 
 #include "mozilla/plugins/PluginScriptableObjectParent.h"
 using mozilla::plugins::PluginScriptableObjectParent;
 using mozilla::plugins::ParentNPObject;
 
-struct JSObjWrapperHasher : public js::DefaultHasher<nsJSObjWrapperKey>
+struct JSObjWrapperHasher
 {
   typedef nsJSObjWrapperKey Key;
   typedef Key Lookup;
 
   static uint32_t hash(const Lookup &l) {
-    return HashGeneric(l.mJSObj, l.mNpp);
+    return js::MovableCellHasher<JS::Heap<JSObject*>>::hash(l.mJSObj) ^
+           HashGeneric(l.mNpp);
   }
 
-  static void rekey(Key &k, const Key& newKey) {
-    MOZ_ASSERT(k.mNpp == newKey.mNpp);
-    k.mJSObj = newKey.mJSObj;
+  static bool match(const Key& k, const Lookup &l) {
+      return js::MovableCellHasher<JS::Heap<JSObject*>>::match(k.mJSObj, l.mJSObj) &&
+             k.mNpp == l.mNpp;
   }
 };
 
+namespace js {
+template <>
+struct DefaultGCPolicy<nsJSObjWrapper*> {
+    static void trace(JSTracer* trc, nsJSObjWrapper** wrapper, const char* name) {
+        MOZ_ASSERT(wrapper);
+        MOZ_ASSERT(*wrapper);
+        (*wrapper)->trace(trc);
+    }
+};
+} // namespace js
+
 class NPObjWrapperHashEntry : public PLDHashEntryHdr
 {
 public:
   NPObject *mNPObj; // Must be the first member for the PLDHash stubs to work
   JS::TenuredHeap<JSObject*> mJSObj;
   NPP mNpp;
 };
 
 // Hash of JSObject wrappers that wraps JSObjects as NPObjects. There
 // will be one wrapper per JSObject per plugin instance, i.e. if two
 // plugins access the JSObject x, two wrappers for x will be
 // created. This is needed to be able to properly drop the wrappers
 // when a plugin is torn down in case there's a leak in the plugin (we
 // don't want to leak the world just because a plugin leaks an
 // NPObject).
-typedef js::HashMap<nsJSObjWrapperKey,
-                    nsJSObjWrapper*,
-                    JSObjWrapperHasher,
-                    js::SystemAllocPolicy> JSObjWrapperTable;
+typedef js::GCHashMap<nsJSObjWrapperKey,
+                      nsJSObjWrapper*,
+                      JSObjWrapperHasher,
+                      js::SystemAllocPolicy> JSObjWrapperTable;
 static JSObjWrapperTable sJSObjWrappers;
 
 // Whether it's safe to iterate sJSObjWrappers.  Set to true when sJSObjWrappers
 // has been initialized and is not currently being enumerated.
 static bool sJSObjWrappersAccessible = false;
 
 // Hash of NPObject wrappers that wrap NPObjects as JSObjects.
 static PLDHashTable* sNPObjWrappers;
@@ -273,30 +286,18 @@ static const JSClass sNPObjectMemberClas
   };
 
 static void
 OnWrapperDestroyed();
 
 static void
 TraceJSObjWrappers(JSTracer *trc, void *data)
 {
-  if (!sJSObjWrappers.initialized()) {
-    return;
-  }
-
-  // Trace all JSObjects in the sJSObjWrappers table and rekey the entries if
-  // any of them moved.
-  for (JSObjWrapperTable::Enum e(sJSObjWrappers); !e.empty(); e.popFront()) {
-    nsJSObjWrapperKey key = e.front().key();
-    JS::UnsafeTraceRoot(trc, &key.mJSObj, "sJSObjWrappers key object");
-    nsJSObjWrapper *wrapper = e.front().value();
-    JS::TraceEdge(trc, &wrapper->mJSObj, "sJSObjWrappers wrapper object");
-    if (key != e.front().key()) {
-      e.rekeyFront(key);
-    }
+  if (sJSObjWrappers.initialized()) {
+    sJSObjWrappers.trace(trc);
   }
 }
 
 static void
 DelayedReleaseGCCallback(JSGCStatus status)
 {
   if (JSGC_END == status) {
     // Take ownership of sDelayedReleases and null it out now. The
@@ -1074,43 +1075,16 @@ nsJSObjWrapper::NP_Enumerate(NPObject *n
 //static
 bool
 nsJSObjWrapper::NP_Construct(NPObject *npobj, const NPVariant *args,
                              uint32_t argCount, NPVariant *result)
 {
   return doInvoke(npobj, NPIdentifier_VOID, args, argCount, true, result);
 }
 
-
-
-/*
- * This function is called during minor GCs for each key in the sJSObjWrappers
- * table that has been moved.
- *
- * Note that the wrapper may be dead at this point, and even the table may have
- * been finalized if all wrappers have died.
- */
-static void
-JSObjWrapperKeyMarkCallback(JSTracer *trc, JSObject *obj, void *data) {
-  NPP npp = static_cast<NPP>(data);
-  MOZ_ASSERT(sJSObjWrappersAccessible);
-  if (!sJSObjWrappers.initialized())
-    return;
-
-  JSObject *prior = obj;
-  nsJSObjWrapperKey oldKey(prior, npp);
-  JSObjWrapperTable::Ptr p = sJSObjWrappers.lookup(oldKey);
-  if (!p)
-    return;
-
-  js::UnsafeTraceManuallyBarrieredEdge(trc, &obj, "sJSObjWrappers key object");
-  nsJSObjWrapperKey newKey(obj, npp);
-  sJSObjWrappers.rekeyIfMoved(oldKey, newKey);
-}
-
 // Look up or create an NPObject that wraps the JSObject obj.
 
 // static
 NPObject *
 nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
 {
   if (!npp) {
     NS_ERROR("Null NPP passed to nsJSObjWrapper::GetNewOrUsed()!");
@@ -1186,26 +1160,22 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
     // Out of memory, entry not yet added to table.
     return nullptr;
   }
 
   wrapper->mJSObj = obj;
 
   // Insert the new wrapper into the hashtable, rooting the JSObject. Its
   // lifetime is now tied to that of the NPObject.
-  nsJSObjWrapperKey key(obj, npp);
-  if (!sJSObjWrappers.putNew(key, wrapper)) {
+  if (!sJSObjWrappers.putNew(nsJSObjWrapperKey(obj, npp), wrapper)) {
     // Out of memory, free the wrapper we created.
     _releaseobject(wrapper);
     return nullptr;
   }
 
-  // Add postbarrier for the hashtable key
-  JS_StoreObjectPostBarrierCallback(cx, JSObjWrapperKeyMarkCallback, obj, wrapper->mNpp);
-
   return wrapper;
 }
 
 // Climb the prototype chain, unwrapping as necessary until we find an NP object
 // wrapper.
 //
 // Because this function unwraps, its return value must be wrapped for the cx
 // compartment for callers that plan to hold onto the result or do anything
--- a/dom/plugins/base/nsJSNPRuntime.h
+++ b/dom/plugins/base/nsJSNPRuntime.h
@@ -5,16 +5,17 @@
 
 #ifndef nsJSNPRuntime_h_
 #define nsJSNPRuntime_h_
 
 #include "nscore.h"
 #include "npapi.h"
 #include "npruntime.h"
 #include "PLDHashTable.h"
+#include "js/RootingAPI.h"
 
 class nsJSNPRuntime
 {
 public:
   static void OnPluginDestroy(NPP npp);
   static void OnPluginDestroyPending(NPP npp);
 };
 
@@ -28,31 +29,39 @@ public:
 
   bool operator==(const nsJSObjWrapperKey& other) const {
     return mJSObj == other.mJSObj && mNpp == other.mNpp;
   }
   bool operator!=(const nsJSObjWrapperKey& other) const {
     return !(*this == other);
   }
 
-  JSObject * mJSObj;
+  void trace(JSTracer* trc) {
+      JS::TraceEdge(trc, &mJSObj, "nsJSObjWrapperKey");
+  }
+
+  JS::Heap<JSObject*> mJSObj;
   const NPP mNpp;
 };
 
 class nsJSObjWrapper : public NPObject
 {
 public:
   JS::Heap<JSObject *> mJSObj;
   const NPP mNpp;
   bool mDestroyPending;
 
   static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
                                 JS::Handle<JSObject*> obj);
   static bool HasOwnProperty(NPObject* npobj, NPIdentifier npid);
 
+  void trace(JSTracer* trc) {
+      JS::TraceEdge(trc, &mJSObj, "nsJSObjWrapper");
+  }
+
 protected:
   explicit nsJSObjWrapper(NPP npp);
   ~nsJSObjWrapper();
 
   static NPObject * NP_Allocate(NPP npp, NPClass *aClass);
   static void NP_Deallocate(NPObject *obj);
   static void NP_Invalidate(NPObject *obj);
   static bool NP_HasMethod(NPObject *, NPIdentifier identifier);
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -50,16 +50,17 @@ using mozilla::DefaultXDisplay;
 #include "ImageContainer.h"
 #include "nsIDOMHTMLCollection.h"
 #include "GLContext.h"
 #include "EGLUtils.h"
 #include "nsIContentInlines.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/TabChild.h"
 #include "nsFrameSelection.h"
 #include "PuppetWidget.h"
 #include "nsPIWindowRoot.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/TextComposition.h"
 #include "mozilla/AutoRestore.h"
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -28,16 +28,17 @@
 #include "mozilla/ProcessHangMonitor.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
 #include "nsIFile.h"
 #include "nsIObserverService.h"
+#include "nsIXULRuntime.h"
 #include "nsNPAPIPlugin.h"
 #include "nsPrintfCString.h"
 #include "prsystem.h"
 #include "PluginQuirks.h"
 #include "GeckoProfiler.h"
 #include "nsPluginTags.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
@@ -674,17 +675,18 @@ PluginModuleParent::PluginModuleParent(b
     , mIsFlashPlugin(false)
     , mIsStartingAsync(false)
     , mNPInitialized(false)
     , mIsNPShutdownPending(false)
     , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED)
 {
 #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
     mIsStartingAsync = aAllowAsyncInit &&
-                       Preferences::GetBool(kAsyncInitPref, false);
+                       Preferences::GetBool(kAsyncInitPref, false) &&
+                       !BrowserTabsRemoteAutostart();
 #if defined(MOZ_CRASHREPORTER)
     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"),
                                        mIsStartingAsync ?
                                            NS_LITERAL_CSTRING("1") :
                                            NS_LITERAL_CSTRING("0"));
 #endif
 #endif
 }
--- a/dom/presentation/PresentationRequest.cpp
+++ b/dom/presentation/PresentationRequest.cpp
@@ -76,16 +76,23 @@ PresentationRequest::WrapObject(JSContex
                                 JS::Handle<JSObject*> aGivenProto)
 {
   return PresentationRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<Promise>
 PresentationRequest::Start(ErrorResult& aRv)
 {
+  return StartWithDevice(NullString(), aRv);
+}
+
+already_AddRefed<Promise>
+PresentationRequest::StartWithDevice(const nsAString& aDeviceId,
+                                     ErrorResult& aRv)
+{
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
   if (NS_WARN_IF(!global)) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   // Get the origin.
   nsAutoString origin;
@@ -119,17 +126,17 @@ PresentationRequest::Start(ErrorResult& 
     do_GetService(PRESENTATION_SERVICE_CONTRACTID);
   if(NS_WARN_IF(!service)) {
     promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
     return promise.forget();
   }
 
   nsCOMPtr<nsIPresentationServiceCallback> callback =
     new PresentationRequesterCallback(this, mUrl, id, promise);
-  rv = service->StartSession(mUrl, id, origin, callback);
+  rv = service->StartSession(mUrl, id, origin, aDeviceId, callback);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
   }
 
   return promise.forget();
 }
 
 already_AddRefed<Promise>
--- a/dom/presentation/PresentationRequest.h
+++ b/dom/presentation/PresentationRequest.h
@@ -28,16 +28,19 @@ public:
                                                            ErrorResult& aRv);
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
   // WebIDL (public APIs)
   already_AddRefed<Promise> Start(ErrorResult& aRv);
 
+  already_AddRefed<Promise> StartWithDevice(const nsAString& aDeviceId,
+                                            ErrorResult& aRv);
+
   already_AddRefed<Promise> GetAvailability(ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(connectionavailable);
 
   nsresult DispatchConnectionAvailableEvent(PresentationConnection* aConnection);
 
 private:
   PresentationRequest(nsPIDOMWindow* aWindow,
--- a/dom/presentation/PresentationService.cpp
+++ b/dom/presentation/PresentationService.cpp
@@ -379,42 +379,85 @@ PresentationService::IsAppInstalled(nsIU
 
   return true;
 }
 
 NS_IMETHODIMP
 PresentationService::StartSession(const nsAString& aUrl,
                                   const nsAString& aSessionId,
                                   const nsAString& aOrigin,
+                                  const nsAString& aDeviceId,
                                   nsIPresentationServiceCallback* aCallback)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aCallback);
   MOZ_ASSERT(!aSessionId.IsEmpty());
 
   // Create session info  and set the callback. The callback is called when the
   // request is finished.
   RefPtr<PresentationSessionInfo> info =
     new PresentationControllingInfo(aUrl, aSessionId, aCallback);
   mSessionInfo.Put(aSessionId, info);
 
-  // Pop up a prompt and ask user to select a device.
-  nsCOMPtr<nsIPresentationDevicePrompt> prompt =
-    do_GetService(PRESENTATION_DEVICE_PROMPT_CONTRACTID);
-  if (NS_WARN_IF(!prompt)) {
+  nsCOMPtr<nsIPresentationDeviceRequest> request =
+    new PresentationDeviceRequest(aUrl, aSessionId, aOrigin);
+
+  if (aDeviceId.IsVoid()) {
+    // Pop up a prompt and ask user to select a device.
+    nsCOMPtr<nsIPresentationDevicePrompt> prompt =
+      do_GetService(PRESENTATION_DEVICE_PROMPT_CONTRACTID);
+    if (NS_WARN_IF(!prompt)) {
+      return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
+    }
+
+    nsresult rv = prompt->PromptDeviceSelection(request);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
+    }
+
+    return NS_OK;
+  }
+
+  // Find the designated device from available device list.
+  nsCOMPtr<nsIPresentationDeviceManager> deviceManager =
+    do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID);
+  if (NS_WARN_IF(!deviceManager)) {
     return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
   }
-  nsCOMPtr<nsIPresentationDeviceRequest> request =
-    new PresentationDeviceRequest(aUrl, aSessionId, aOrigin);
-  nsresult rv = prompt->PromptDeviceSelection(request);
+
+  nsCOMPtr<nsIArray> devices;
+  nsresult rv = deviceManager->GetAvailableDevices(getter_AddRefs(devices));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
   }
 
-  return NS_OK;
+  nsCOMPtr<nsISimpleEnumerator> enumerator;
+  rv = devices->Enumerate(getter_AddRefs(enumerator));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR);
+  }
+
+  NS_ConvertUTF16toUTF8 utf8DeviceId(aDeviceId);
+  bool hasMore;
+  while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore){
+    nsCOMPtr<nsISupports> isupports;
+    rv = enumerator->GetNext(getter_AddRefs(isupports));
+
+    nsCOMPtr<nsIPresentationDevice> device(do_QueryInterface(isupports));
+    MOZ_ASSERT(device);
+
+    nsAutoCString id;
+    if (NS_SUCCEEDED(device->GetId(id)) && id.Equals(utf8DeviceId)) {
+      request->Select(device);
+      return NS_OK;
+    }
+  }
+
+  // Reject if designated device is not available.
+  return info->ReplyError(NS_ERROR_DOM_NOT_FOUND_ERR);
 }
 
 NS_IMETHODIMP
 PresentationService::SendSessionMessage(const nsAString& aSessionId,
                                         nsIInputStream* aStream)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aStream);
--- a/dom/presentation/interfaces/nsIPresentationService.idl
+++ b/dom/presentation/interfaces/nsIPresentationService.idl
@@ -28,34 +28,37 @@ interface nsIPresentationServiceCallback
   /*
    * Called when the operation fails.
    *
    * @param error: error message.
    */
   void notifyError(in nsresult error);
 };
 
-[scriptable, uuid(c177a13a-bf1a-48bf-8032-d415c3343c46)]
+[scriptable, uuid(2e360359-c45c-4949-bf95-410242ce483f)]
 interface nsIPresentationService : nsISupports
 {
   /*
    * Start a new presentation session and display a prompt box which asks users
    * to select a device.
    *
    * @param url: The url of presenting page.
    * @param sessionId: An ID to identify presentation session.
    * @param origin: The url of requesting page.
+   * @param deviceId: The specified device of handling this request, null string
+                      for prompt device selection dialog.
    * @param callback: Invoke the callback when the operation is completed.
    *                  NotifySuccess() is called with |id| if a session is
    *                  established successfully with the selected device.
    *                  Otherwise, NotifyError() is called with a error message.
    */
   void startSession(in DOMString url,
                     in DOMString sessionId,
                     in DOMString origin,
+                    in DOMString deviceId,
                     in nsIPresentationServiceCallback callback);
 
   /*
    * Send the message wrapped with an input stream to the session.
    *
    * @param sessionId: An ID to identify presentation session.
    * @param stream: The message is converted to an input stream.
    */
--- a/dom/presentation/ipc/PPresentation.ipdl
+++ b/dom/presentation/ipc/PPresentation.ipdl
@@ -12,16 +12,17 @@ include InputStreamParams;
 namespace mozilla {
 namespace dom {
 
 struct StartSessionRequest
 {
   nsString url;
   nsString sessionId;
   nsString origin;
+  nsString deviceId;
 };
 
 struct SendSessionMessageRequest
 {
   nsString sessionId;
   InputStreamParams data;
 };
 
--- a/dom/presentation/ipc/PresentationIPCService.cpp
+++ b/dom/presentation/ipc/PresentationIPCService.cpp
@@ -44,20 +44,23 @@ PresentationIPCService::~PresentationIPC
   mRespondingWindowIds.Clear();
   sPresentationChild = nullptr;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::StartSession(const nsAString& aUrl,
                                      const nsAString& aSessionId,
                                      const nsAString& aOrigin,
+                                     const nsAString& aDeviceId,
                                      nsIPresentationServiceCallback* aCallback)
 {
-  return SendRequest(aCallback,
-                     StartSessionRequest(nsAutoString(aUrl), nsAutoString(aSessionId), nsAutoString(aOrigin)));
+  return SendRequest(aCallback, StartSessionRequest(nsAutoString(aUrl),
+                                                    nsAutoString(aSessionId),
+                                                    nsAutoString(aOrigin),
+                                                    nsAutoString(aDeviceId)));
 }
 
 NS_IMETHODIMP
 PresentationIPCService::SendSessionMessage(const nsAString& aSessionId,
                                            nsIInputStream* aStream)
 {
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aStream);
--- a/dom/presentation/ipc/PresentationParent.cpp
+++ b/dom/presentation/ipc/PresentationParent.cpp
@@ -247,17 +247,17 @@ PresentationRequestParent::ActorDestroy(
   mService = nullptr;
 }
 
 nsresult
 PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest)
 {
   MOZ_ASSERT(mService);
   return mService->StartSession(aRequest.url(), aRequest.sessionId(),
-                                aRequest.origin(), this);
+                                aRequest.origin(), aRequest.deviceId(), this);
 }
 
 nsresult
 PresentationRequestParent::DoRequest(const SendSessionMessageRequest& aRequest)
 {
   MOZ_ASSERT(mService);
 
   // Validate the accessibility (primarily for receiver side) so that a
--- a/dom/presentation/tests/mochitest/mochitest.ini
+++ b/dom/presentation/tests/mochitest/mochitest.ini
@@ -12,16 +12,18 @@ support-files =
 [test_presentation_sender_disconnect.html]
 skip-if = toolkit == 'android' # Bug 1129785
 [test_presentation_sender_establish_connection_error.html]
 skip-if = toolkit == 'android' # Bug 1129785
 [test_presentation_sender.html]
 skip-if = toolkit == 'android' # Bug 1129785
 [test_presentation_sender_default_request.html]
 skip-if = toolkit == 'android' # Bug 1129785
+[test_presentation_sender_startWithDevice.html]
+skip-if = toolkit == 'android' # Bug 1129785
 [test_presentation_receiver_establish_connection_error.html]
 skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android' || os == 'mac' || os == 'win' || buildapp == 'mulet') # Bug 1129785, Bug 1204709
 [test_presentation_receiver_establish_connection_timeout.html]
 skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
 [test_presentation_receiver.html]
 skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
 [test_presentation_receiver_oop.html]
 skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
new file mode 100644
--- /dev/null
+++ b/dom/presentation/tests/mochitest/test_presentation_sender_startWithDevice.html
@@ -0,0 +1,173 @@
+<!DOCTYPE HTML>
+<html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<head>
+  <meta charset="utf-8">
+  <title>Test startWithDevice for B2G Presentation API at sender side</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1239242">Test startWithDevice for B2G Presentation API at sender side</a>
+<script type="application/javascript;version=1.8">
+
+'use strict';
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
+var request;
+var connection;
+
+function testSetup() {
+  return new Promise(function(aResolve, aReject) {
+    request = new PresentationRequest("http://example.com");
+
+    request.getAvailability().then(
+      function(aAvailability) {
+        aAvailability.onchange = function() {
+          aAvailability.onchange = null;
+          ok(aAvailability.value, "Device should be available.");
+          aResolve();
+        }
+      },
+      function(aError) {
+        ok(false, "Error occurred when getting availability: " + aError);
+        teardown();
+        aReject();
+      }
+    );
+
+    gScript.sendAsyncMessage('trigger-device-add');
+  });
+}
+
+function testStartConnectionWithDevice() {
+  return new Promise(function(aResolve, aReject) {
+    gScript.addMessageListener('device-prompt', function devicePromptHandler() {
+      gScript.removeMessageListener('device-prompt', devicePromptHandler);
+      ok(false, "Device prompt should not be triggered.");
+      teardown();
+      aReject();
+    });
+
+    gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
+      gScript.removeMessageListener('control-channel-established', controlChannelEstablishedHandler);
+      info("A control channel is established.");
+      gScript.sendAsyncMessage('trigger-control-channel-open');
+    });
+
+    gScript.addMessageListener('control-channel-opened', function controlChannelOpenedHandler(aReason) {
+      gScript.removeMessageListener('control-channel-opened', controlChannelOpenedHandler);
+      info("The control channel is opened.");
+    });
+
+    gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
+      gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
+      info("The control channel is closed. " + aReason);
+    });
+
+    gScript.addMessageListener('offer-sent', function offerSentHandler(aIsValid) {
+      gScript.removeMessageListener('offer-sent', offerSentHandler);
+      ok(aIsValid, "A valid offer is sent out.");
+      gScript.sendAsyncMessage('trigger-incoming-transport');
+    });
+
+    gScript.addMessageListener('answer-received', function answerReceivedHandler() {
+      gScript.removeMessageListener('answer-received', answerReceivedHandler);
+      info("An answer is received.");
+    });
+
+    gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() {
+      gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler);
+      info("Data transport channel is initialized.");
+      gScript.sendAsyncMessage('trigger-incoming-answer');
+    });
+
+    gScript.addMessageListener('data-transport-notification-enabled', function dataTransportNotificationEnabledHandler() {
+      gScript.removeMessageListener('data-transport-notification-enabled', dataTransportNotificationEnabledHandler);
+      info("Data notification is enabled for data transport channel.");
+    });
+
+    var connectionFromEvent;
+    request.onconnectionavailable = function(aEvent) {
+      request.onconnectionavailable = null;
+      connectionFromEvent = aEvent.connection;
+      ok(connectionFromEvent, "|connectionavailable| event is fired with a connection.");
+
+      if (connection) {
+        is(connection, connectionFromEvent, "The connection from promise and the one from |connectionavailable| event should be the same.");
+        aResolve();
+      }
+    };
+
+    request.startWithDevice('id').then(
+      function(aConnection) {
+        connection = aConnection;
+        ok(connection, "Connection should be available.");
+        ok(connection.id, "Connection ID should be set.");
+        is(connection.state, "connected", "Connection state at sender side should be connected by default.");
+
+        if (connectionFromEvent) {
+          is(connection, connectionFromEvent, "The connection from promise and the one from |connectionavailable| event should be the same.");
+          aResolve();
+        }
+      },
+      function(aError) {
+        ok(false, "Error occurred when establishing a connection: " + aError);
+        teardown();
+        aReject();
+      }
+    );
+  });
+}
+
+function testStartConnectionWithDeviceNotFoundError() {
+  return new Promise(function(aResolve, aReject) {
+    request.startWithDevice('').then(
+      function(aConnection) {
+        ok(false, "Should not establish connection to an unknown device");
+        teardown();
+        aReject();
+      },
+      function(aError) {
+        is(aError.name, 'NotFoundError', "Expect NotFoundError occurred when establishing a connection");
+        aResolve();
+      }
+    );
+  });
+}
+
+function teardown() {
+  gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
+    gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
+    gScript.destroy();
+    SimpleTest.finish();
+  });
+
+  gScript.sendAsyncMessage('teardown');
+}
+
+function runTests() {
+  ok(window.PresentationRequest, "PresentationRequest should be available.");
+
+  testSetup().
+  then(testStartConnectionWithDevice).
+  then(testStartConnectionWithDeviceNotFoundError).
+  then(teardown);
+}
+
+//SimpleTest.expectAssertions(0, 5);
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPermissions([
+  {type: 'presentation-device-manage', allow: true, context: document},
+  {type: 'presentation', allow: true, context: document},
+], function() {
+  SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
+                                      ["dom.presentation.test.enabled", true],
+                                      ["dom.presentation.test.stage", 0]]},
+                            runTests);
+});
+
+</script>
+</body>
+</html>
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -405,17 +405,19 @@ nsCSPContext::reportInlineViolation(nsCo
   nsCOMPtr<nsISupportsCString> selfICString(do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
   if (selfICString) {
     selfICString->SetData(nsDependentCString("self"));
   }
   nsCOMPtr<nsISupports> selfISupports(do_QueryInterface(selfICString));
 
   // use selfURI as the sourceFile
   nsAutoCString sourceFile;
-  mSelfURI->GetSpec(sourceFile);
+  if (mSelfURI) {
+    mSelfURI->GetSpec(sourceFile);
+  }
 
   nsAutoString codeSample(aContent);
   // cap the length of the script sample at 40 chars
   if (codeSample.Length() > 40) {
     codeSample.Truncate(40);
     codeSample.AppendLiteral("...");
   }
   AsyncReportViolation(selfISupports,                      // aBlockedContentSource
@@ -586,16 +588,17 @@ nsCSPContext::SetRequestContext(nsIDOMDo
   NS_PRECONDITION(aDOMDocument || aPrincipal,
                   "Can't set context without doc or principal");
   NS_ENSURE_ARG(aDOMDocument || aPrincipal);
 
   if (aDOMDocument) {
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDOMDocument);
     mLoadingContext = do_GetWeakReference(doc);
     mSelfURI = doc->GetDocumentURI();
+    mLoadingPrincipal = doc->NodePrincipal();
     doc->GetReferrer(mReferrer);
     mInnerWindowID = doc->InnerWindowID();
     // the innerWindowID is not available for CSPs delivered through the
     // header at the time setReqeustContext is called - let's queue up
     // console messages until it becomes available, see flushConsoleMessages
     mQueueUpMessages = !mInnerWindowID;
     mCallingChannelLoadGroup = doc->GetDocumentLoadGroup();
   }
@@ -664,16 +667,61 @@ nsCSPContext::logToConsole(const char16_
     return;
   }
   CSP_LogLocalizedStr(aName, aParams, aParamsLength, aSourceName,
                       aSourceLine, aLineNumber, aColumnNumber,
                       aSeverityFlag, "CSP", mInnerWindowID);
 }
 
 /**
+ * Strip URI for reporting according to:
+ * http://www.w3.org/TR/CSP/#violation-reports
+ *
+ * @param aURI
+ *        The uri to be stripped for reporting
+ * @param aProtectedResourcePrincipal
+ *        The loadingPrincipal of the protected resource
+ *        which is needed to enforce the SOP.
+ * @return ASCII serialization of the uri to be reported.
+ */
+void
+StripURIForReporting(nsIURI* aURI,
+                     nsIPrincipal* aProtectedResourcePrincipal,
+                     nsACString& outStrippedURI)
+{
+  // 1) If the origin of uri is a globally unique identifier (for example,
+  // aURI has a scheme of data, blob, or filesystem), then return the
+  // ASCII serialization of uri’s scheme.
+  bool isHttp =
+    (NS_SUCCEEDED(aURI->SchemeIs("http", &isHttp)) && isHttp) ||
+    (NS_SUCCEEDED(aURI->SchemeIs("https", &isHttp)) && isHttp);
+  if (!isHttp) {
+    // not strictly spec compliant, but what we really care about is
+    // http/https. If it's not http/https, then treat aURI as if
+    // it's a globally unique identifier and just return the scheme.
+    aURI->GetScheme(outStrippedURI);
+    return;
+  }
+
+  // 2) If the origin of uri is not the same as the origin of the protected
+  // resource, then return the ASCII serialization of uri’s origin.
+  bool sameOrigin =
+    NS_SUCCEEDED(aProtectedResourcePrincipal->CheckMayLoad(aURI, false, false));
+  if (!sameOrigin) {
+    // cross origin redirects also fall into this category, see:
+    // http://www.w3.org/TR/CSP/#violation-reports
+    aURI->GetPrePath(outStrippedURI);
+    return;
+  }
+
+  // 3) Return uri, with any fragment component removed.
+  aURI->GetSpecIgnoringRef(outStrippedURI);
+}
+
+/**
  * Sends CSP violation reports to all sources listed under report-uri.
  *
  * @param aBlockedContentSource
  *        Either a CSP Source (like 'self', as string) or nsIURI: the source
  *        of the violation.
  * @param aOriginalUri
  *        The original URI if the blocked content is a redirect, else null
  * @param aViolatedDirective
@@ -709,42 +757,34 @@ nsCSPContext::SendReports(nsISupports* a
   nsresult rv;
 
   // blocked-uri
   if (aBlockedContentSource) {
     nsAutoCString reportBlockedURI;
     nsCOMPtr<nsIURI> uri = do_QueryInterface(aBlockedContentSource);
     // could be a string or URI
     if (uri) {
-      // aOriginalURI will only be *not* null in case of a redirect in which
-      // case aOriginalURI is the uri before the redirect.
-      if (aOriginalURI) {
-        // do not report anything else than the origin in case of a redirect, see:
-        // http://www.w3.org/TR/CSP/#violation-reports
-        uri->GetPrePath(reportBlockedURI);
-      } else {
-        uri->GetSpecIgnoringRef(reportBlockedURI);
-      }
+      StripURIForReporting(uri, mLoadingPrincipal, reportBlockedURI);
     } else {
       nsCOMPtr<nsISupportsCString> cstr = do_QueryInterface(aBlockedContentSource);
       if (cstr) {
         cstr->GetData(reportBlockedURI);
       }
     }
     if (reportBlockedURI.IsEmpty()) {
       // this can happen for frame-ancestors violation where the violating
       // ancestor is cross-origin.
       NS_WARNING("No blocked URI (null aBlockedContentSource) for CSP violation report.");
     }
     report.mCsp_report.mBlocked_uri = NS_ConvertUTF8toUTF16(reportBlockedURI);
   }
 
   // document-uri
   nsAutoCString reportDocumentURI;
-  mSelfURI->GetSpecIgnoringRef(reportDocumentURI);
+  StripURIForReporting(mSelfURI, mLoadingPrincipal, reportDocumentURI);
   report.mCsp_report.mDocument_uri = NS_ConvertUTF8toUTF16(reportDocumentURI);
 
   // original-policy
   nsAutoString originalPolicy;
   rv = this->GetPolicy(aViolatedPolicyIndex, originalPolicy);
   NS_ENSURE_SUCCESS(rv, rv);
   report.mCsp_report.mOriginal_policy = originalPolicy;
 
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -305,17 +305,17 @@ nsMixedContentBlocker::AsyncOnChannelRed
       return NS_OK;
     }
     // We set the requestingLocation from the RequestingPrincipal.
     rv = requestingPrincipal->GetURI(getter_AddRefs(requestingLocation));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   int16_t decision = REJECT_REQUEST;
-  rv = ShouldLoad(nsContentUtils::InternalContentPolicyTypeToExternalOrScript(contentPolicyType),
+  rv = ShouldLoad(nsContentUtils::InternalContentPolicyTypeToExternalOrMCBInternal(contentPolicyType),
                   newUri,
                   requestingLocation,
                   loadInfo->LoadingNode(),
                   EmptyCString(),       // aMimeGuess
                   nullptr,              // aExtra
                   requestingPrincipal,
                   &decision);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -373,19 +373,21 @@ nsMixedContentBlocker::ShouldLoad(bool a
                                   nsIPrincipal* aRequestPrincipal,
                                   int16_t* aDecision)
 {
   // Asserting that we are on the main thread here and hence do not have to lock
   // and unlock sBlockMixedScript and sBlockMixedDisplay before reading/writing
   // to them.
   MOZ_ASSERT(NS_IsMainThread());
 
-  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternalOrScript(aContentType),
+  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternalOrMCBInternal(aContentType),
              "We should only see external content policy types here.");
 
+   bool isPreload = nsContentUtils::IsPreloadType(aContentType);
+
   // The content policy type that we receive may be an internal type for
   // scripts.  Let's remember if we have seen a worker type, and reset it to the
   // external type in all cases right now.
   bool isWorkerType = aContentType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
                       aContentType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER ||
                       aContentType == nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER;
   aContentType = nsContentUtils::InternalContentPolicyTypeToExternal(aContentType);
 
@@ -663,17 +665,17 @@ nsMixedContentBlocker::ShouldLoad(bool a
   // http: and ws: (for websockets). Websockets are not subject to mixed content
   // blocking since insecure websockets are not allowed within secure pages. Hence,
   // we only have to check against http: here. Skip mixed content blocking if the
   // subresource load uses http: and the CSP directive 'upgrade-insecure-requests'
   // is present on the page.
   bool isHttpScheme = false;
   rv = aContentLocation->SchemeIs("http", &isHttpScheme);
   NS_ENSURE_SUCCESS(rv, rv);
-  if (isHttpScheme && docShell->GetDocument()->GetUpgradeInsecureRequests()) {
+  if (isHttpScheme && docShell->GetDocument()->GetUpgradeInsecureRequests(isPreload)) {
     *aDecision = ACCEPT;
     return NS_OK;
   }
 
   bool rootHasSecureConnection = false;
   bool allowMixedContent = false;
   bool isRootDocShell = false;
   rv = docShell->GetAllowMixedContentAndConnectionData(&rootHasSecureConnection, &allowMixedContent, &isRootDocShell);
--- a/dom/security/test/csp/file_bug836922_npolicies.html
+++ b/dom/security/test/csp/file_bug836922_npolicies.html
@@ -1,15 +1,12 @@
 <html>
   <head>
     <link rel='stylesheet' type='text/css'
           href='/tests/dom/security/test/csp/file_CSP.sjs?testid=css_self&type=text/css' />
-    <link rel='stylesheet' type='text/css'
-          href='http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=css_examplecom&type=text/css' />
 
   </head>
   <body>
     <img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img_self&type=img/png"> </img>
-    <img src="http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=img_examplecom&type=img/png"> </img>
     <script src='/tests/dom/security/test/csp/file_CSP.sjs?testid=script_self&type=text/javascript'></script>
 
   </body>
 </html>
--- a/dom/security/test/csp/test_bug836922_npolicies.html
+++ b/dom/security/test/csp/test_bug836922_npolicies.html
@@ -15,31 +15,25 @@
 <script class="testbody" type="text/javascript">
 
 var path = "/tests/dom/security/test/csp/";
 
 // These are test results: verified indicates whether or not the test has run.
 // true/false is the pass/fail result.
 window.loads = {
   css_self: {expected: true, verified: false},
-  css_examplecom: {expected: false, verified: false},
   img_self: {expected: false, verified: false},
-  img_examplecom: {expected: false, verified: false},
   script_self: {expected: true, verified: false},
 };
 
 window.violation_reports = {
   css_self:
   {expected: 0, expected_ro: 0},  /* totally fine */
-  css_examplecom:
-  {expected: 1, expected_ro: 0},  /* violates enforced CSP */
   img_self:
   {expected: 1, expected_ro: 0},  /* violates enforced CSP */
-  img_examplecom:
-  {expected: 1, expected_ro: 1},  /* violates both CSPs */
   script_self:
   {expected: 0, expected_ro: 1},  /* violates report-only */
 };
 
 // This is used to watch the blocked data bounce off CSP and allowed data
 // get sent out to the wire.  This also watches for violation reports to go out.
 function examiner() {
   SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
--- a/dom/security/test/csp/test_report_for_import.html
+++ b/dom/security/test/csp/test_report_for_import.html
@@ -52,17 +52,17 @@ function checkResults(reportStr) {
     is(cspReport["violated-directive"],
        "style-src http://mochi.test:8888",
        "Incorrect violated-directive");
     is(cspReport["original-policy"],
        "style-src http://mochi.test:8888; report-uri " +
        "http://mochi.test:8888/tests/dom/security/test/csp/file_report_for_import_server.sjs?report",
        "Incorrect original-policy");
     is(cspReport["blocked-uri"],
-       "http://example.com/tests/dom/security/test/csp/file_report_for_import_server.sjs?stylesheet",
+       "http://example.com",
        "Incorrect blocked-uri");
 
     // we do not always set the following fields
     is(cspReport["source-file"], undefined, "Incorrect source-file");
     is(cspReport["script-sample"], undefined, "Incorrect script-sample");
     is(cspReport["line-number"], undefined, "Incorrect line-number");
   }
   catch (e) {
--- a/dom/security/test/unit/test_csp_reports.js
+++ b/dom/security/test/unit/test_csp_reports.js
@@ -34,19 +34,19 @@ function makeReportHandler(testpath, mes
     }
 
     // obtain violation report
     var reportObj = JSON.parse(
           NetUtil.readInputStreamToString(
             request.bodyInputStream,
             request.bodyInputStream.available()));
 
-    dump("GOT REPORT:\n" + JSON.stringify(reportObj) + "\n");
-    dump("TESTPATH:    " + testpath + "\n");
-    dump("EXPECTED:  \n" + JSON.stringify(expectedJSON) + "\n\n");
+    // dump("GOT REPORT:\n" + JSON.stringify(reportObj) + "\n");
+    // dump("TESTPATH:    " + testpath + "\n");
+    // dump("EXPECTED:  \n" + JSON.stringify(expectedJSON) + "\n\n");
 
     for (var i in expectedJSON)
       do_check_eq(expectedJSON[i], reportObj['csp-report'][i]);
 
     testsToFinish--;
     httpServer.registerPathHandler(testpath, null);
     if (testsToFinish < 1)
       httpServer.stop(do_test_finished);
@@ -127,17 +127,17 @@ function run_test() {
           // force the logging, since the getter doesn't.
           csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_EVAL,
                                   selfuri.asciiSpec,
                                   "script sample",
                                   1);
         }
       });
 
-  makeTest(2, {"blocked-uri": "http://blocked.test/foo.js"}, false,
+  makeTest(2, {"blocked-uri": "http://blocked.test"}, false,
       function(csp) {
         // shouldLoad creates and sends out the report here.
         csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
                       NetUtil.newURI("http://blocked.test/foo.js"),
                       null, null, null, null);
       });
 
   // test that inline script violations cause a report in report-only policy
@@ -167,9 +167,41 @@ function run_test() {
         if (oReportViolation.value) {
           // force the logging, since the getter doesn't.
           csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_INLINE_SCRIPT,
                                   selfuri.asciiSpec,
                                   "script sample",
                                   4);
         }
       });
+
+  // test that only the uri's scheme is reported for globally unique identifiers
+  makeTest(5, {"blocked-uri": "data"}, false,
+    function(csp) {
+      var base64data =
+        "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" +
+        "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
+      // shouldLoad creates and sends out the report here.
+      csp.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
+                     NetUtil.newURI("data:image/png;base64," + base64data),
+                     null, null, null, null);
+      });
+
+  // test that only the uri's scheme is reported for globally unique identifiers
+  makeTest(6, {"blocked-uri": "intent"}, false,
+    function(csp) {
+      // shouldLoad creates and sends out the report here.
+      csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
+                     NetUtil.newURI("intent://mymaps.com/maps?um=1&ie=UTF-8&fb=1&sll"),
+                     null, null, null, null);
+      });
+
+  // test fragment removal
+  var selfSpec = REPORT_SERVER_URI + ":" + REPORT_SERVER_PORT + "/foo/self/foo.js";
+  makeTest(7, {"blocked-uri": selfSpec}, false,
+    function(csp) {
+      var uri = NetUtil
+      // shouldLoad creates and sends out the report here.
+      csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
+                     NetUtil.newURI(selfSpec + "#bar"),
+                     null, null, null, null);
+      });
 }
--- a/dom/svg/test/mochitest.ini
+++ b/dom/svg/test/mochitest.ini
@@ -65,16 +65,17 @@ skip-if = true
 [test_pointer-events-3.xhtml]
 skip-if = android_version == '18' # bug 1147994
 [test_pointer-events-4.xhtml]
 [test_pointer-events-5.xhtml]
 [test_pointer-events-6.xhtml]
 [test_pointer-events-7.xhtml]
 [test_scientific.html]
 [test_selectSubString.xhtml]
+[test_style_sheet.html]
 [test_stroke-hit-testing.xhtml]
 [test_stroke-linecap-hit-testing.xhtml]
 [test_SVGLengthList-2.xhtml]
 [test_SVGLengthList.xhtml]
 [test_SVGMatrix.xhtml]
 [test_SVG_namespace_ids.html]
 [test_SVGNumberList.xhtml]
 [test_SVGPathSegList.xhtml]
new file mode 100644
--- /dev/null
+++ b/dom/svg/test/test_style_sheet.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Test for Bug 1239128</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1239128">Mozilla Bug 1239128</a>
+<p id="display"</p>
+
+<svg>
+  <style>svg { fill: blue; }</style>
+</svg>
+
+<pre id="test">
+<script class="testbody" type="application/javascript">
+var style = document.querySelector("style");
+
+var exceptionThrown = false;
+try {
+  is(style.sheet.cssRules[0].cssText, "svg { fill: blue; }",
+     "Should get the fill: blue rule back");
+} catch (e) {
+  exceptionThrown = true;
+}
+
+ok(!exceptionThrown, "Should be able to access data: <style> stylesheet");
+</script>
+</pre>
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -124,16 +124,18 @@ var interfaceNamesInGlobalScope =
     {name: "AlarmsManager", b2g: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "AnalyserNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "Animation", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "AnimationEffectReadOnly", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "AnimationEffectTimingReadOnly", release: false},
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "AnimationEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "AnimationPlaybackEvent", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "AnimationTimeline", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Attr",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/webidl/AnimationEffectReadOnly.webidl
+++ b/dom/webidl/AnimationEffectReadOnly.webidl
@@ -41,14 +41,13 @@ dictionary ComputedTimingProperties : An
   unrestricted double   activeDuration = 0.0;
   double?               localTime = null;
   unrestricted double?  progress = null;
   unrestricted double?  currentIteration = null;
 };
 
 [Func="nsDocument::IsWebAnimationsEnabled"]
 interface AnimationEffectReadOnly {
-  // Not yet implemented:
-  // readonly attribute AnimationEffectTimingReadOnly timing;
-
+  [Cached, Constant]
+  readonly attribute AnimationEffectTimingReadOnly timing;
   [BinaryName="getComputedTimingAsDict"]
   ComputedTimingProperties getComputedTiming();
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/AnimationEffectTimingReadOnly.webidl
@@ -0,0 +1,23 @@
+/* -*- Mode: IDL; 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/.
+ *
+ * The origin of this IDL file is
+ * https://w3c.github.io/web-animations/#animationeffecttimingreadonly
+ *
+ * Copyright © 2015 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+[Func="nsDocument::IsWebAnimationsEnabled"]
+interface AnimationEffectTimingReadOnly {
+  readonly attribute double                             delay;
+  readonly attribute double                             endDelay;
+  readonly attribute FillMode                           fill;
+  readonly attribute double                             iterationStart;
+  readonly attribute unrestricted double                iterations;
+  readonly attribute (unrestricted double or DOMString) duration;
+  readonly attribute PlaybackDirection                  direction;
+  readonly attribute DOMString                          easing;
+};
--- a/dom/webidl/PresentationRequest.webidl
+++ b/dom/webidl/PresentationRequest.webidl
@@ -38,9 +38,29 @@ interface PresentationRequest : EventTar
   [Throws]
   Promise<PresentationAvailability> getAvailability();
 
   /*
    * It is called when a connection associated with a PresentationRequest is created.
    * The event is fired for all connections that are created for the controller.
    */
   attribute EventHandler onconnectionavailable;
+
+  /*
+   * A chrome page, or page which has presentation-device-manage permissiongs,
+   * uses startWithDevice() to start a new connection with specified device,
+   * and it will be returned with the promise. UA may show a prompt box with a
+   * list of available devices and ask the user to grant permission, choose a
+   * device, or cancel the operation.
+   *
+   * The promise is resolved when the presenting page is successfully loaded and
+   * the communication channel is established, i.e., the connection state is
+   * "connected".
+   *
+   * The promise may be rejected duo to one of the following reasons:
+   * - "OperationError": Unexpected error occurs.
+   * - "NotFoundError":  No available device.
+   * - "NetworkError":   Failed to establish the control channel or data channel.
+   * - "TimeoutError":   Presenting page takes too long to load.
+   */
+  [CheckAnyPermissions="presentation-device-manage", Throws]
+  Promise<PresentationConnection> startWithDevice(DOMString deviceId);
 };
--- a/dom/webidl/SVGStyleElement.webidl
+++ b/dom/webidl/SVGStyleElement.webidl
@@ -17,9 +17,10 @@ interface SVGStyleElement : SVGElement {
   attribute DOMString type;
   [SetterThrows]
   attribute DOMString media;
   [SetterThrows]
   attribute DOMString title;
   [SetterThrows]
   attribute boolean scoped;
 };
+SVGStyleElement implements LinkStyle;
 
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -19,16 +19,17 @@ WEBIDL_FILES = [
     'AbortablePromise.webidl',
     'AbstractWorker.webidl',
     'ActivityRequestHandler.webidl',
     'AlarmsManager.webidl',
     'AnalyserNode.webidl',
     'Animatable.webidl',
     'Animation.webidl',
     'AnimationEffectReadOnly.webidl',
+    'AnimationEffectTimingReadOnly.webidl',
     'AnimationEvent.webidl',
     'AnimationTimeline.webidl',
     'AnonymousContent.webidl',
     'AppInfo.webidl',
     'AppNotificationServiceOptions.webidl',
     'Apps.webidl',
     'APZTestData.webidl',
     'ArchiveReader.webidl',
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -1180,63 +1180,51 @@ private:
   bool
   DispatchFetchEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     MOZ_ASSERT(aCx);
     MOZ_ASSERT(aWorkerPrivate);
     MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
     GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
 
-    NS_ConvertUTF8toUTF16 local(mSpec);
-    RequestOrUSVString requestInfo;
-    requestInfo.SetAsUSVString().Rebind(local.Data(), local.Length());
-
-    RootedDictionary<RequestInit> reqInit(aCx);
-    reqInit.mMethod.Construct(mMethod);
-
     RefPtr<InternalHeaders> internalHeaders = new InternalHeaders(HeadersGuardEnum::Request);
     MOZ_ASSERT(mHeaderNames.Length() == mHeaderValues.Length());
     for (uint32_t i = 0; i < mHeaderNames.Length(); i++) {
       ErrorResult result;
       internalHeaders->Set(mHeaderNames[i], mHeaderValues[i], result);
       if (NS_WARN_IF(result.Failed())) {
         result.SuppressException();
         return false;
       }
     }
 
-    RefPtr<Headers> headers = new Headers(globalObj.GetAsSupports(), internalHeaders);
-    reqInit.mHeaders.Construct();
-    reqInit.mHeaders.Value().SetAsHeaders() = headers;
-
-    reqInit.mMode.Construct(mRequestMode);
-    reqInit.mRedirect.Construct(mRequestRedirect);
-    reqInit.mCredentials.Construct(mRequestCredentials);
-
     ErrorResult result;
-    RefPtr<Request> request = Request::Constructor(globalObj, requestInfo, reqInit, result);
+    internalHeaders->SetGuard(HeadersGuardEnum::Immutable, result);
     if (NS_WARN_IF(result.Failed())) {
       result.SuppressException();
       return false;
     }
+
+    RefPtr<InternalRequest> internalReq = new InternalRequest(mSpec,
+                                                              mMethod,
+                                                              internalHeaders.forget(),
+                                                              mRequestMode,
+                                                              mRequestRedirect,
+                                                              mRequestCredentials,
+                                                              NS_ConvertUTF8toUTF16(mReferrer),
+                                                              mContentPolicyType);
+    internalReq->SetBody(mUploadStream);
     // For Telemetry, note that this Request object was created by a Fetch event.
-    RefPtr<InternalRequest> internalReq = request->GetInternalRequest();
-    MOZ_ASSERT(internalReq);
     internalReq->SetCreatedByFetchEvent();
 
-    internalReq->SetBody(mUploadStream);
-    internalReq->SetReferrer(NS_ConvertUTF8toUTF16(mReferrer));
-
-    request->SetContentPolicyType(mContentPolicyType);
-
-    request->GetInternalHeaders()->SetGuard(HeadersGuardEnum::Immutable, result);
-    if (NS_WARN_IF(result.Failed())) {
-      result.SuppressException();
+    nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(globalObj.GetAsSupports());
+    if (NS_WARN_IF(!global)) {
       return false;
     }
+    RefPtr<Request> request = new Request(global, internalReq);
 
     // TODO: remove conditional on http here once app protocol support is
     //       removed from service worker interception
     MOZ_ASSERT_IF(mIsHttpChannel && internalReq->IsNavigationRequest(),
                   request->Redirect() == RequestRedirect::Manual);
 
     RootedDictionary<FetchEventInit> init(aCx);
     init.mRequest = request;
--- a/dom/workers/test/serviceworkers/fetch/fetch_tests.js
+++ b/dom/workers/test/serviceworkers/fetch/fetch_tests.js
@@ -116,16 +116,22 @@ fetchXHR('nonpromise.txt', null, functio
 });
 
 fetchXHR('headers.txt', function(xhr) {
   my_ok(xhr.status == 200, "load should be successful");
   my_ok(xhr.responseText == "1", "request header checks should have passed");
   finish();
 }, null, [["X-Test1", "header1"], ["X-Test2", "header2"]]);
 
+fetchXHR('http://user:pass@mochi.test:8888/user-pass', function(xhr) {
+  my_ok(xhr.status == 200, "load should be successful");
+  my_ok(xhr.responseText == 'http://user:pass@mochi.test:8888/user-pass', 'The username and password should be preserved');
+  finish();
+});
+
 var expectedUncompressedResponse = "";
 for (var i = 0; i < 10; ++i) {
   expectedUncompressedResponse += "hello";
 }
 expectedUncompressedResponse += "\n";
 
 // ServiceWorker does not intercept, at which point the network request should
 // be correctly decoded.
--- a/dom/workers/test/serviceworkers/fetch_event_worker.js
+++ b/dom/workers/test/serviceworkers/fetch_event_worker.js
@@ -93,16 +93,20 @@ onfetch = function(ev) {
     var ok = true;
     ok &= ev.request.headers.get("X-Test1") == "header1";
     ok &= ev.request.headers.get("X-Test2") == "header2";
     ev.respondWith(Promise.resolve(
       new Response(ok.toString(), {})
     ));
   }
 
+  else if (ev.request.url.includes('user-pass')) {
+    ev.respondWith(new Response(ev.request.url));
+  }
+
   else if (ev.request.url.includes("nonexistent_image.gif")) {
     var imageAsBinaryString = atob("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs");
     var imageLength = imageAsBinaryString.length;
 
     // If we just pass |imageAsBinaryString| to the Response constructor, an
     // encoding conversion occurs that corrupts the image. Instead, we need to
     // convert it to a typed array.
     // typed array.
--- a/dom/xbl/nsXBLEventHandler.cpp
+++ b/dom/xbl/nsXBLEventHandler.cpp
@@ -85,28 +85,28 @@ nsXBLKeyEventHandler::~nsXBLKeyEventHand
 NS_IMPL_ISUPPORTS(nsXBLKeyEventHandler, nsIDOMEventListener)
 
 bool
 nsXBLKeyEventHandler::ExecuteMatchedHandlers(
                         nsIDOMKeyEvent* aKeyEvent,
                         uint32_t aCharCode,
                         const IgnoreModifierState& aIgnoreModifierState)
 {
-  WidgetEvent* event = aKeyEvent->GetInternalNSEvent();
-  nsCOMPtr<EventTarget> target = aKeyEvent->InternalDOMEvent()->GetCurrentTarget();
+  WidgetEvent* event = aKeyEvent->AsEvent()->GetInternalNSEvent();
+  nsCOMPtr<EventTarget> target = aKeyEvent->AsEvent()->InternalDOMEvent()->GetCurrentTarget();
 
   bool executed = false;
   for (uint32_t i = 0; i < mProtoHandlers.Length(); ++i) {
     nsXBLPrototypeHandler* handler = mProtoHandlers[i];
     bool hasAllowUntrustedAttr = handler->HasAllowUntrustedAttr();
     if ((event->mFlags.mIsTrusted ||
         (hasAllowUntrustedAttr && handler->AllowUntrustedEvents()) ||
         (!hasAllowUntrustedAttr && !mIsBoundToChrome && !mUsingContentXBLScope)) &&
         handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreModifierState)) {
-      handler->ExecuteHandler(target, aKeyEvent);
+      handler->ExecuteHandler(target, aKeyEvent->AsEvent());
       executed = true;
     }
   }
 #ifdef XP_WIN
   // Windows native applications ignore Windows-Logo key state when checking
   // shortcut keys even if the key is pressed.  Therefore, if there is no
   // shortcut key which exactly matches current modifier state, we should
   // retry to look for a shortcut key without the Windows-Logo key press.
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -904,17 +904,17 @@ nsXBLPrototypeHandler::ReportKeyConflict
                                   nullptr, EmptyString(), mLineNumber);
 }
 
 bool
 nsXBLPrototypeHandler::ModifiersMatchMask(
                          nsIDOMUIEvent* aEvent,
                          const IgnoreModifierState& aIgnoreModifierState)
 {
-  WidgetInputEvent* inputEvent = aEvent->GetInternalNSEvent()->AsInputEvent();
+  WidgetInputEvent* inputEvent = aEvent->AsEvent()->GetInternalNSEvent()->AsInputEvent();
   NS_ENSURE_TRUE(inputEvent, false);
 
   if (mKeyMask & cMetaMask) {
     if (inputEvent->IsMeta() != ((mKeyMask & cMeta) != 0)) {
       return false;
     }
   }
 
--- a/dom/xbl/nsXBLWindowKeyHandler.cpp
+++ b/dom/xbl/nsXBLWindowKeyHandler.cpp
@@ -257,36 +257,36 @@ nsXBLWindowKeyHandler::EnsureHandlers()
 
   return NS_OK;
 }
 
 nsresult
 nsXBLWindowKeyHandler::WalkHandlers(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType)
 {
   bool prevent;
-  aKeyEvent->GetDefaultPrevented(&prevent);
+  aKeyEvent->AsEvent()->GetDefaultPrevented(&prevent);
   if (prevent)
     return NS_OK;
 
   bool trustedEvent = false;
   // Don't process the event if it was not dispatched from a trusted source
-  aKeyEvent->GetIsTrusted(&trustedEvent);
+  aKeyEvent->AsEvent()->GetIsTrusted(&trustedEvent);
 
   if (!trustedEvent)
     return NS_OK;
 
   nsresult rv = EnsureHandlers();
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool isDisabled;
   nsCOMPtr<Element> el = GetElement(&isDisabled);
   if (!el) {
     if (mUserHandler) {
       WalkHandlersInternal(aKeyEvent, aEventType, mUserHandler, true);
-      aKeyEvent->GetDefaultPrevented(&prevent);
+      aKeyEvent->AsEvent()->GetDefaultPrevented(&prevent);
       if (prevent)
         return NS_OK; // Handled by the user bindings. Our work here is done.
     }
   }
 
   // skip keysets that are disabled
   if (el && isDisabled) {
     return NS_OK;
@@ -317,24 +317,24 @@ nsXBLWindowKeyHandler::HandleEvent(nsIDO
 
   return WalkHandlers(keyEvent, eventTypeAtom);
 }
 
 void
 nsXBLWindowKeyHandler::HandleEventOnCapture(nsIDOMKeyEvent* aEvent)
 {
   WidgetKeyboardEvent* widgetEvent =
-    aEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
 
   if (widgetEvent->mFlags.mNoCrossProcessBoundaryForwarding) {
     return;
   }
 
   nsCOMPtr<mozilla::dom::Element> originalTarget =
-    do_QueryInterface(aEvent->GetInternalNSEvent()->originalTarget);
+    do_QueryInterface(aEvent->AsEvent()->GetInternalNSEvent()->originalTarget);
   if (!EventStateManager::IsRemoteTarget(originalTarget)) {
     return;
   }
 
   bool aReservedForChrome = false;
   if (!HasHandlerForEvent(aEvent, &aReservedForChrome)) {
     return;
   }
@@ -348,17 +348,17 @@ nsXBLWindowKeyHandler::HandleEventOnCapt
     // Inform the child process that this is a event that we want a reply
     // from.
     widgetEvent->mFlags.mWantReplyFromContentProcess = true;
 
     // If this event hadn't been marked as mNoCrossProcessBoundaryForwarding
     // yet, it means it wasn't processed by content. We'll not call any
     // of the handlers at this moment, and will wait for the event to be
     // redispatched with mNoCrossProcessBoundaryForwarding = 1 to process it.
-    aEvent->StopPropagation();
+    aEvent->AsEvent()->StopPropagation();
   }
 }
 
 //
 // EventMatched
 //
 // See if the given handler cares about this particular key event
 //
@@ -473,17 +473,17 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
                          bool aExecute,
                          bool* aOutReservedForChrome)
 {
   nsresult rv;
 
   // Try all of the handlers until we find one that matches the event.
   for (nsXBLPrototypeHandler *currHandler = aHandler; currHandler;
        currHandler = currHandler->GetNextHandler()) {
-    bool stopped = aKeyEvent->IsDispatchStopped();
+    bool stopped = aKeyEvent->AsEvent()->IsDispatchStopped();
     if (stopped) {
       // The event is finished, don't execute any more handlers
       return false;
     }
 
     if (!EventMatched(currHandler, aEventType, aKeyEvent,
                       aCharCode, aIgnoreModifierState)) {
       continue;  // try the next one
@@ -547,61 +547,61 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
     } else {
       piTarget = mTarget;
     }
 
     if (!aExecute) {
       return true;
     }
 
-    rv = currHandler->ExecuteHandler(piTarget, aKeyEvent);
+    rv = currHandler->ExecuteHandler(piTarget, aKeyEvent->AsEvent());
     if (NS_SUCCEEDED(rv)) {
       return true;
     }
   }
 
 #ifdef XP_WIN
   // Windows native applications ignore Windows-Logo key state when checking
   // shortcut keys even if the key is pressed.  Therefore, if there is no
   // shortcut key which exactly matches current modifier state, we should
   // retry to look for a shortcut key without the Windows-Logo key press.
   if (!aIgnoreModifierState.mOS) {
     WidgetKeyboardEvent* keyEvent =
-      aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+      aKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
     if (keyEvent && keyEvent->IsOS()) {
       IgnoreModifierState ignoreModifierState(aIgnoreModifierState);
       ignoreModifierState.mOS = true;
       return WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, aCharCode,
                                     ignoreModifierState, aExecute);
     }
   }
 #endif
 
   return false;
 }
 
 bool
 nsXBLWindowKeyHandler::HasHandlerForEvent(nsIDOMKeyEvent* aEvent,
                                           bool* aOutReservedForChrome)
 {
-  if (!aEvent->InternalDOMEvent()->IsTrusted()) {
+  if (!aEvent->AsEvent()->InternalDOMEvent()->IsTrusted()) {
     return false;
   }
 
   nsresult rv = EnsureHandlers();
   NS_ENSURE_SUCCESS(rv, false);
 
   bool isDisabled;
   nsCOMPtr<Element> el = GetElement(&isDisabled);
   if (el && isDisabled) {
     return false;
   }
 
   nsAutoString eventType;
-  aEvent->GetType(eventType);
+  aEvent->AsEvent()->GetType(eventType);
   nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(eventType);
   NS_ENSURE_TRUE(eventTypeAtom, false);
 
   return WalkHandlersInternal(aEvent, eventTypeAtom, mHandler, false,
                               aOutReservedForChrome);
 }
 
 already_AddRefed<Element>
--- a/dom/xul/nsXULPopupListener.cpp
+++ b/dom/xul/nsXULPopupListener.cpp
@@ -110,17 +110,17 @@ nsXULPopupListener::HandleEvent(nsIDOMEv
 
   nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent);
   if (!mouseEvent) {
     //non-ui event passed in.  bad things.
     return NS_OK;
   }
 
   // Get the node that was clicked on.
-  EventTarget* target = mouseEvent->InternalDOMEvent()->GetTarget();
+  EventTarget* target = mouseEvent->AsEvent()->InternalDOMEvent()->GetTarget();
   nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(target);
 
   if (!targetNode && mIsContext) {
     // Not a DOM node, see if it's the DOM window (bug 380818).
     nsCOMPtr<nsPIDOMWindow> domWin = do_QueryInterface(target);
     if (!domWin) {
       return NS_ERROR_DOM_WRONG_TYPE_ERR;
     }
@@ -139,17 +139,17 @@ nsXULPopupListener::HandleEvent(nsIDOMEv
     return NS_OK;
   }
   if (targetContent->IsXULElement(nsGkAtoms::browser) &&
       EventStateManager::IsRemoteTarget(targetContent)) {
     return NS_OK;
   }
 
   bool preventDefault;
-  mouseEvent->GetDefaultPrevented(&preventDefault);
+  mouseEvent->AsEvent()->GetDefaultPrevented(&preventDefault);
   if (preventDefault && targetNode && mIsContext) {
     // Someone called preventDefault on a context menu.
     // Let's make sure they are allowed to do so.
     bool eventEnabled =
       Preferences::GetBool("dom.event.contextmenu.enabled", true);
     if (!eventEnabled) {
       // If the target node is for plug-in, we should not open XUL context
       // menu on windowless plug-ins.
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -29,16 +29,17 @@
 #include "mozilla/IMEStateManager.h"    // for IMEStateManager
 #include "mozilla/Preferences.h"        // for Preferences
 #include "mozilla/dom/Selection.h"      // for Selection, etc
 #include "mozilla/Services.h"           // for GetObserverService
 #include "mozilla/TextComposition.h"    // for TextComposition
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/Element.h"        // for Element, nsINode::AsElement
 #include "mozilla/dom/Text.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAString.h"                  // for nsAString_internal::Length, etc
 #include "nsCCUncollectableMarker.h"    // for nsCCUncollectableMarker
 #include "nsCaret.h"                    // for nsCaret
 #include "nsCaseTreatment.h"
 #include "nsCharTraits.h"               // for NS_IS_HIGH_SURROGATE, etc
 #include "nsComponentManagerUtils.h"    // for do_CreateInstance
 #include "nsComputedDOMStyle.h"         // for nsComputedDOMStyle
@@ -4610,58 +4611,58 @@ nsEditor::HandleKeyPressEvent(nsIDOMKeyE
   // NOTE: When you change this method, you should also change:
   //   * editor/libeditor/tests/test_texteditor_keyevent_handling.html
   //   * editor/libeditor/tests/test_htmleditor_keyevent_handling.html
   //
   // And also when you add new key handling, you need to change the subclass's
   // HandleKeyPressEvent()'s switch statement.
 
   WidgetKeyboardEvent* nativeKeyEvent =
-    aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   NS_ENSURE_TRUE(nativeKeyEvent, NS_ERROR_UNEXPECTED);
   NS_ASSERTION(nativeKeyEvent->mMessage == eKeyPress,
                "HandleKeyPressEvent gets non-keypress event");
 
   // if we are readonly or disabled, then do nothing.
   if (IsReadonly() || IsDisabled()) {
     // consume backspace for disabled and readonly textfields, to prevent
     // back in history, which could be confusing to users
     if (nativeKeyEvent->keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) {
-      aKeyEvent->PreventDefault();
+      aKeyEvent->AsEvent()->PreventDefault();
     }
     return NS_OK;
   }
 
   switch (nativeKeyEvent->keyCode) {
     case nsIDOMKeyEvent::DOM_VK_META:
     case nsIDOMKeyEvent::DOM_VK_WIN:
     case nsIDOMKeyEvent::DOM_VK_SHIFT:
     case nsIDOMKeyEvent::DOM_VK_CONTROL:
     case nsIDOMKeyEvent::DOM_VK_ALT:
-      aKeyEvent->PreventDefault(); // consumed
+      aKeyEvent->AsEvent()->PreventDefault(); // consumed
       return NS_OK;
     case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
       if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() ||
           nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) {
         return NS_OK;
       }
       DeleteSelection(nsIEditor::ePrevious, nsIEditor::eStrip);
-      aKeyEvent->PreventDefault(); // consumed
+      aKeyEvent->AsEvent()->PreventDefault(); // consumed
       return NS_OK;
     case nsIDOMKeyEvent::DOM_VK_DELETE:
       // on certain platforms (such as windows) the shift key
       // modifies what delete does (cmd_cut in this case).
       // bailing here to allow the keybindings to do the cut.
       if (nativeKeyEvent->IsShift() || nativeKeyEvent->IsControl() ||
           nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
           nativeKeyEvent->IsOS()) {
         return NS_OK;
       }
       DeleteSelection(nsIEditor::eNext, nsIEditor::eStrip);
-      aKeyEvent->PreventDefault(); // consumed
+      aKeyEvent->AsEvent()->PreventDefault(); // consumed
       return NS_OK;
   }
   return NS_OK;
 }
 
 nsresult
 nsEditor::HandleInlineSpellCheck(EditAction action,
                                    Selection* aSelection,
--- a/editor/libeditor/nsEditorEventListener.cpp
+++ b/editor/libeditor/nsEditorEventListener.cpp
@@ -443,17 +443,17 @@ nsEditorEventListener::HandleEvent(nsIDO
     // click
     case eMouseClick: {
       nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent);
       NS_ENSURE_TRUE(mouseEvent, NS_OK);
       // If the preceding mousedown event or mouseup event was consumed,
       // editor shouldn't handle this click event.
       if (mMouseDownOrUpConsumedByIME) {
         mMouseDownOrUpConsumedByIME = false;
-        mouseEvent->PreventDefault();
+        mouseEvent->AsEvent()->PreventDefault();
         return NS_OK;
       }
       return MouseClick(mouseEvent);
     }
     // focus
     case eFocus:
       return Focus(aEvent);
     // blur
@@ -606,89 +606,89 @@ nsEditorEventListener::KeyDown(nsIDOMKey
 }
 #endif
 
 nsresult
 nsEditorEventListener::KeyPress(nsIDOMKeyEvent* aKeyEvent)
 {
   NS_ENSURE_TRUE(aKeyEvent, NS_OK);
 
-  if (!mEditor->IsAcceptableInputEvent(aKeyEvent)) {
+  if (!mEditor->IsAcceptableInputEvent(aKeyEvent->AsEvent())) {
     return NS_OK;
   }
 
   // DOM event handling happens in two passes, the client pass and the system
   // pass.  We do all of our processing in the system pass, to allow client
   // handlers the opportunity to cancel events and prevent typing in the editor.
   // If the client pass cancelled the event, defaultPrevented will be true
   // below.
 
   bool defaultPrevented;
-  aKeyEvent->GetDefaultPrevented(&defaultPrevented);
+  aKeyEvent->AsEvent()->GetDefaultPrevented(&defaultPrevented);
   if (defaultPrevented) {
     return NS_OK;
   }
 
   nsresult rv = mEditor->HandleKeyPressEvent(aKeyEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aKeyEvent->GetDefaultPrevented(&defaultPrevented);
+  aKeyEvent->AsEvent()->GetDefaultPrevented(&defaultPrevented);
   if (defaultPrevented) {
     return NS_OK;
   }
 
   if (!ShouldHandleNativeKeyBindings(aKeyEvent)) {
     return NS_OK;
   }
 
   // Now, ask the native key bindings to handle the event.
   WidgetKeyboardEvent* keyEvent =
-    aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   MOZ_ASSERT(keyEvent,
              "DOM key event's internal event must be WidgetKeyboardEvent");
   nsIWidget* widget = keyEvent->widget;
   // If the event is created by chrome script, the widget is always nullptr.
   if (!widget) {
     nsCOMPtr<nsIPresShell> ps = GetPresShell();
     nsPresContext* pc = ps ? ps->GetPresContext() : nullptr;
     widget = pc ? pc->GetNearestWidget() : nullptr;
     NS_ENSURE_TRUE(widget, NS_OK);
   }
 
   nsCOMPtr<nsIDocument> doc = mEditor->GetDocument();
   bool handled = widget->ExecuteNativeKeyBinding(
                            nsIWidget::NativeKeyBindingsForRichTextEditor,
                            *keyEvent, DoCommandCallback, doc);
   if (handled) {
-    aKeyEvent->PreventDefault();
+    aKeyEvent->AsEvent()->PreventDefault();
   }
   return NS_OK;
 }
 
 nsresult
 nsEditorEventListener::MouseClick(nsIDOMMouseEvent* aMouseEvent)
 {
   // nothing to do if editor isn't editable or clicked on out of the editor.
   if (mEditor->IsReadonly() || mEditor->IsDisabled() ||
-      !mEditor->IsAcceptableInputEvent(aMouseEvent)) {
+      !mEditor->IsAcceptableInputEvent(aMouseEvent->AsEvent())) {
     return NS_OK;
   }
 
   // Notifies clicking on editor to IMEStateManager even when the event was
   // consumed.
   if (EditorHasFocus()) {
     nsPresContext* presContext = GetPresContext();
     if (presContext) {
       IMEStateManager::OnClickInEditor(presContext, GetFocusedRootContent(),
                                        aMouseEvent);
      }
   }
 
   bool preventDefault;
-  nsresult rv = aMouseEvent->GetDefaultPrevented(&preventDefault);
+  nsresult rv = aMouseEvent->AsEvent()->GetDefaultPrevented(&preventDefault);
   if (NS_FAILED(rv) || preventDefault) {
     // We're done if 'preventdefault' is true (see for example bug 70698).
     return rv;
   }
 
   // If we got a mouse down inside the editing area, we should force the
   // IME to commit before we change the cursor position
   mEditor->ForceCompositionEnd();
@@ -749,33 +749,33 @@ nsEditorEventListener::HandleMiddleClick
   if (mailEditor) {
     mailEditor->PasteAsQuotation(clipboard);
   } else {
     mEditor->Paste(clipboard);
   }
 
   // Prevent the event from propagating up to be possibly handled
   // again by the containing window:
-  aMouseEvent->StopPropagation();
-  aMouseEvent->PreventDefault();
+  aMouseEvent->AsEvent()->StopPropagation();
+  aMouseEvent->AsEvent()->PreventDefault();
 
   // We processed the event, whether drop/paste succeeded or not
   return NS_OK;
 }
 
 bool
 nsEditorEventListener::NotifyIMEOfMouseButtonEvent(
                          nsIDOMMouseEvent* aMouseEvent)
 {
   if (!EditorHasFocus()) {
     return false;
   }
 
   bool defaultPrevented;
-  nsresult rv = aMouseEvent->GetDefaultPrevented(&defaultPrevented);
+  nsresult rv = aMouseEvent->AsEvent()->GetDefaultPrevented(&defaultPrevented);
   NS_ENSURE_SUCCESS(rv, false);
   if (defaultPrevented) {
     return false;
   }
   nsPresContext* presContext = GetPresContext();
   NS_ENSURE_TRUE(presContext, false);
   return IMEStateManager::OnMouseButtonEventInEditor(presContext,
                                                      GetFocusedRootContent(),
@@ -835,27 +835,27 @@ nsEditorEventListener::DragEnter(nsIDOMD
 
 nsresult
 nsEditorEventListener::DragOver(nsIDOMDragEvent* aDragEvent)
 {
   NS_ENSURE_TRUE(aDragEvent, NS_OK);
 
   nsCOMPtr<nsIDOMNode> parent;
   bool defaultPrevented;
-  aDragEvent->GetDefaultPrevented(&defaultPrevented);
+  aDragEvent->AsEvent()->GetDefaultPrevented(&defaultPrevented);
   if (defaultPrevented) {
     return NS_OK;
   }
 
   aDragEvent->GetRangeParent(getter_AddRefs(parent));
   nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
   NS_ENSURE_TRUE(dropParent, NS_ERROR_FAILURE);
 
   if (dropParent->IsEditable() && CanDrop(aDragEvent)) {
-    aDragEvent->PreventDefault(); // consumed
+    aDragEvent->AsEvent()->PreventDefault(); // consumed
 
     if (!mCaret) {
       return NS_OK;
     }
 
     int32_t offset = 0;
     nsresult rv = aDragEvent->GetRangeOffset(&offset);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -864,17 +864,17 @@ nsEditorEventListener::DragOver(nsIDOMDr
     mCaret->SetCaretPosition(parent, offset);
 
     return NS_OK;
   }
 
   if (!IsFileControlTextBox()) {
     // This is needed when dropping on an input, to prevent the editor for
     // the editable parent from receiving the event.
-    aDragEvent->StopPropagation();
+    aDragEvent->AsEvent()->StopPropagation();
   }
 
   if (mCaret) {
     mCaret->SetVisible(false);
   }
   return NS_OK;
 }
 
@@ -909,17 +909,17 @@ nsEditorEventListener::DragExit(nsIDOMDr
 nsresult
 nsEditorEventListener::Drop(nsIDOMDragEvent* aDragEvent)
 {
   NS_ENSURE_TRUE(aDragEvent, NS_OK);
 
   CleanupDragDropCaret();
 
   bool defaultPrevented;
-  aDragEvent->GetDefaultPrevented(&defaultPrevented);
+  aDragEvent->AsEvent()->GetDefaultPrevented(&defaultPrevented);
   if (defaultPrevented) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMNode> parent;
   aDragEvent->GetRangeParent(getter_AddRefs(parent));
   nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
   NS_ENSURE_TRUE(dropParent, NS_ERROR_FAILURE);
@@ -927,24 +927,24 @@ nsEditorEventListener::Drop(nsIDOMDragEv
   if (!dropParent->IsEditable() || !CanDrop(aDragEvent)) {
     // was it because we're read-only?
     if ((mEditor->IsReadonly() || mEditor->IsDisabled()) &&
         !IsFileControlTextBox()) {
       // it was decided to "eat" the event as this is the "least surprise"
       // since someone else handling it might be unintentional and the
       // user could probably re-drag to be not over the disabled/readonly
       // editfields if that is what is desired.
-      return aDragEvent->StopPropagation();
+      return aDragEvent->AsEvent()->StopPropagation();
     }
     return NS_OK;
   }
 
-  aDragEvent->StopPropagation();
-  aDragEvent->PreventDefault();
-  return mEditor->InsertFromDrop(aDragEvent);
+  aDragEvent->AsEvent()->StopPropagation();
+  aDragEvent->AsEvent()->PreventDefault();
+  return mEditor->InsertFromDrop(aDragEvent->AsEvent());
 }
 
 bool
 nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
 {
   // if the target doc is read-only, we can't drop
   if (mEditor->IsReadonly() || mEditor->IsDisabled()) {
     return false;
@@ -1178,17 +1178,17 @@ nsEditorEventListener::ShouldHandleNativ
   // editing host in order to match the similar decision made in
   // nsXBLWindowKeyHandler.
   // Note that IsAcceptableInputEvent doesn't check for the active editing
   // host for keyboard events, otherwise this check would have been
   // unnecessary.  IsAcceptableInputEvent currently makes a similar check for
   // mouse events.
 
   nsCOMPtr<nsIDOMEventTarget> target;
-  aKeyEvent->GetTarget(getter_AddRefs(target));
+  aKeyEvent->AsEvent()->GetTarget(getter_AddRefs(target));
   nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target);
   if (!targetContent) {
     return false;
   }
 
   nsCOMPtr<nsIHTMLEditor> htmlEditor =
     do_QueryInterface(static_cast<nsIEditor*>(mEditor));
   if (!htmlEditor) {
--- a/editor/libeditor/nsHTMLEditor.cpp
+++ b/editor/libeditor/nsHTMLEditor.cpp
@@ -612,17 +612,17 @@ nsHTMLEditor::HandleKeyPressEvent(nsIDOM
 
   if (IsReadonly() || IsDisabled()) {
     // When we're not editable, the events are handled on nsEditor, so, we can
     // bypass nsPlaintextEditor.
     return nsEditor::HandleKeyPressEvent(aKeyEvent);
   }
 
   WidgetKeyboardEvent* nativeKeyEvent =
-    aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   NS_ENSURE_TRUE(nativeKeyEvent, NS_ERROR_UNEXPECTED);
   NS_ASSERTION(nativeKeyEvent->mMessage == eKeyPress,
                "HandleKeyPressEvent gets non-keypress event");
 
   switch (nativeKeyEvent->keyCode) {
     case nsIDOMKeyEvent::DOM_VK_META:
     case nsIDOMKeyEvent::DOM_VK_WIN:
     case nsIDOMKeyEvent::DOM_VK_SHIFT:
@@ -671,47 +671,47 @@ nsHTMLEditor::HandleKeyPressEvent(nsIDOM
       } else if (nsHTMLEditUtils::IsListItem(blockParent)) {
         rv = Indent(nativeKeyEvent->IsShift()
                     ? NS_LITERAL_STRING("outdent")
                     : NS_LITERAL_STRING("indent"));
         handled = true;
       }
       NS_ENSURE_SUCCESS(rv, rv);
       if (handled) {
-        return aKeyEvent->PreventDefault(); // consumed
+        return aKeyEvent->AsEvent()->PreventDefault(); // consumed
       }
       if (nativeKeyEvent->IsShift()) {
         return NS_OK; // don't type text for shift tabs
       }
-      aKeyEvent->PreventDefault();
+      aKeyEvent->AsEvent()->PreventDefault();
       return TypedText(NS_LITERAL_STRING("\t"), eTypedText);
     }
     case nsIDOMKeyEvent::DOM_VK_RETURN:
       if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() ||
           nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) {
         return NS_OK;
       }
-      aKeyEvent->PreventDefault(); // consumed
+      aKeyEvent->AsEvent()->PreventDefault(); // consumed
       if (nativeKeyEvent->IsShift() && !IsPlaintextEditor()) {
         // only inserts a br node
         return TypedText(EmptyString(), eTypedBR);
       }
       // uses rules to figure out what to insert
       return TypedText(EmptyString(), eTypedBreak);
   }
 
   // NOTE: On some keyboard layout, some characters are inputted with Control
   // key or Alt key, but at that time, widget sets FALSE to these keys.
   if (nativeKeyEvent->charCode == 0 || nativeKeyEvent->IsControl() ||
       nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
       nativeKeyEvent->IsOS()) {
     // we don't PreventDefault() here or keybindings like control-x won't work
     return NS_OK;
   }
-  aKeyEvent->PreventDefault();
+  aKeyEvent->AsEvent()->PreventDefault();
   nsAutoString str(nativeKeyEvent->charCode);
   return TypedText(str, eTypedText);
 }
 
 static void
 AssertParserServiceIsCorrect(nsIAtom* aTag, bool aIsBlock)
 {
 #ifdef DEBUG
--- a/editor/libeditor/nsHTMLEditorEventListener.cpp
+++ b/editor/libeditor/nsHTMLEditorEventListener.cpp
@@ -56,17 +56,17 @@ nsHTMLEditorEventListener::GetHTMLEditor
 }
 
 nsresult
 nsHTMLEditorEventListener::MouseUp(nsIDOMMouseEvent* aMouseEvent)
 {
   nsHTMLEditor* htmlEditor = GetHTMLEditor();
 
   nsCOMPtr<nsIDOMEventTarget> target;
-  nsresult rv = aMouseEvent->GetTarget(getter_AddRefs(target));
+  nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
 
   int32_t clientX, clientY;
   aMouseEvent->GetClientX(&clientX);
   aMouseEvent->GetClientY(&clientY);
   htmlEditor->MouseUp(clientX, clientY, element);
@@ -75,17 +75,17 @@ nsHTMLEditorEventListener::MouseUp(nsIDO
 }
 
 nsresult
 nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
 {
   nsHTMLEditor* htmlEditor = GetHTMLEditor();
   // Contenteditable should disregard mousedowns outside it.
   // IsAcceptableInputEvent() checks it for a mouse event.
-  if (!htmlEditor->IsAcceptableInputEvent(aMouseEvent)) {
+  if (!htmlEditor->IsAcceptableInputEvent(aMouseEvent->AsEvent())) {
     // If it's not acceptable mousedown event (including when mousedown event
     // is fired outside of the active editing host), we need to commit
     // composition because it will be change the selection to the clicked
     // point.  Then, we won't be able to commit the composition.
     return nsEditorEventListener::MouseDown(aMouseEvent);
   }
 
   // Detect only "context menu" click
@@ -98,17 +98,17 @@ nsHTMLEditorEventListener::MouseDown(nsI
 
   bool isContextClick = buttonNumber == 2;
 
   int32_t clickCount;
   rv = aMouseEvent->GetDetail(&clickCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMEventTarget> target;
-  rv = aMouseEvent->GetExplicitOriginalTarget(getter_AddRefs(target));
+  rv = aMouseEvent->AsEvent()->GetExplicitOriginalTarget(getter_AddRefs(target));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
 
   if (isContextClick || (buttonNumber == 0 && clickCount == 2)) {
     RefPtr<Selection> selection = mEditor->GetSelection();
     NS_ENSURE_TRUE(selection, NS_OK);
 
@@ -185,35 +185,35 @@ nsHTMLEditorEventListener::MouseDown(nsI
     }
     // HACK !!! Context click places the caret but the context menu consumes
     // the event; so we need to check resizing state ourselves
     htmlEditor->CheckSelectionStateForAnonymousButtons(selection);
 
     // Prevent bubbling if we changed selection or
     //   for all context clicks
     if (element || isContextClick) {
-      aMouseEvent->PreventDefault();
+      aMouseEvent->AsEvent()->PreventDefault();
       return NS_OK;
     }
   } else if (!isContextClick && buttonNumber == 0 && clickCount == 1) {
     // if the target element is an image, we have to display resizers
     int32_t clientX, clientY;
     aMouseEvent->GetClientX(&clientX);
     aMouseEvent->GetClientY(&clientY);
-    htmlEditor->MouseDown(clientX, clientY, element, aMouseEvent);
+    htmlEditor->MouseDown(clientX, clientY, element, aMouseEvent->AsEvent());
   }
 
   return nsEditorEventListener::MouseDown(aMouseEvent);
 }
 
 nsresult
 nsHTMLEditorEventListener::MouseClick(nsIDOMMouseEvent* aMouseEvent)
 {
   nsCOMPtr<nsIDOMEventTarget> target;
-  nsresult rv = aMouseEvent->GetTarget(getter_AddRefs(target));
+  nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
 
   GetHTMLEditor()->DoInlineTableEditingAction(element);
 
   return nsEditorEventListener::MouseClick(aMouseEvent);
 }
--- a/editor/libeditor/nsPlaintextEditor.cpp
+++ b/editor/libeditor/nsPlaintextEditor.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsPlaintextEditor.h"
 
 #include "gfxFontUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Selection.h"
+#include "mozilla/dom/Event.h"
 #include "mozilla/TextComposition.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
 #include "nsCaret.h"
@@ -356,17 +357,17 @@ nsPlaintextEditor::HandleKeyPressEvent(n
   // HandleKeyPressEvent()'s switch statement.
 
   if (IsReadonly() || IsDisabled()) {
     // When we're not editable, the events handled on nsEditor.
     return nsEditor::HandleKeyPressEvent(aKeyEvent);
   }
 
   WidgetKeyboardEvent* nativeKeyEvent =
-    aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    aKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent();
   NS_ENSURE_TRUE(nativeKeyEvent, NS_ERROR_UNEXPECTED);
   NS_ASSERTION(nativeKeyEvent->mMessage == eKeyPress,
                "HandleKeyPressEvent gets non-keypress event");
 
   switch (nativeKeyEvent->keyCode) {
     case nsIDOMKeyEvent::DOM_VK_META:
     case nsIDOMKeyEvent::DOM_VK_WIN:
     case nsIDOMKeyEvent::DOM_VK_SHIFT:
@@ -383,38 +384,38 @@ nsPlaintextEditor::HandleKeyPressEvent(n
 
       if (nativeKeyEvent->IsShift() || nativeKeyEvent->IsControl() ||
           nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
           nativeKeyEvent->IsOS()) {
         return NS_OK;
       }
 
       // else we insert the tab straight through
-      aKeyEvent->PreventDefault();
+      aKeyEvent->AsEvent()->PreventDefault();
       return TypedText(NS_LITERAL_STRING("\t"), eTypedText);
     }
     case nsIDOMKeyEvent::DOM_VK_RETURN:
       if (IsSingleLineEditor() || nativeKeyEvent->IsControl() ||
           nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
           nativeKeyEvent->IsOS()) {
         return NS_OK;
       }
-      aKeyEvent->PreventDefault();
+      aKeyEvent->AsEvent()->PreventDefault();
       return TypedText(EmptyString(), eTypedBreak);
   }
 
   // NOTE: On some keyboard layout, some characters are inputted with Control
   // key or Alt key, but at that time, widget sets FALSE to these keys.
   if (nativeKeyEvent->charCode == 0 || nativeKeyEvent->IsControl() ||
       nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() ||
       nativeKeyEvent->IsOS()) {
     // we don't PreventDefault() here or keybindings like control-x won't work
     return NS_OK;
   }
-  aKeyEvent->PreventDefault();
+  aKeyEvent->AsEvent()->PreventDefault();
   nsAutoString str(nativeKeyEvent->charCode);
   return TypedText(str, eTypedText);
 }
 
 /* This routine is needed to provide a bottleneck for typing for logging
    purposes.  Can't use HandleKeyPress() (above) for that since it takes
    a nsIDOMKeyEvent* parameter.  So instead we pass enough info through
    to TypedText() to determine what action to take, but without passing
deleted file mode 100644
--- a/embedding/android/geckoview_example/AndroidManifest.xml.in
+++ /dev/null
@@ -1,23 +0,0 @@
-#filter substitution
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="org.mozilla.geckoviewexample"
-          android:versionCode="1"
-          android:versionName="1.0">
-  <uses-sdk android:minSdkVersion="8"
-            android:targetSdkVersion="@ANDROID_TARGET_SDK@"/>
-  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-  <uses-permission android:name="android.permission.INTERNET"/>
-  <uses-feature android:glEsVersion="0x00020000" android:required="true" />
-  <application android:label="@string/app_name"
-               android:icon="@drawable/ic_launcher"
-               android:hardwareAccelerated="true">
-    <activity android:name="GeckoViewExample"
-              android:label="@string/app_name">
-      <intent-filter>
-        <action android:name="android.intent.action.MAIN" />
-        <category android:name="android.intent.category.LAUNCHER" />
-      </intent-filter>
-    </activity>
-  </application>
-</manifest>
deleted file mode 100644
--- a/embedding/android/geckoview_example/GeckoViewExample.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.mozilla.geckoviewexample;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.AttributeSet;
-
-public class GeckoViewExample extends Activity {
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-    }
-}
deleted file mode 100644
--- a/embedding/android/geckoview_example/Makefile.in
+++ /dev/null
@@ -1,65 +0,0 @@
-PP_TARGETS = properties manifest
-
-manifest = AndroidManifest.xml.in
-
-include $(topsrcdir)/config/rules.mk
-
-GARBAGE = \
-	AndroidManifest.xml \
-	proguard-project.txt \
-	project.properties \
-	ant.properties \
-	build.xml \
-	local.properties \
-	geckoview_example.apk \
-	$(NULL)
-
-GARBAGE_DIRS = \
-	assets \
-	geckoview_library \
-	gen \
-	bin \
-	libs \
-	res \
-	src \
-	binaries \
-	$(NULL)
-
-ANDROID=$(ANDROID_TOOLS)/android
-
-TARGET="android-$(ANDROID_TARGET_SDK)"
-
-PACKAGE_DEPS = \
-	assets/libxul.so \
-	build.xml \
-	src/org/mozilla/geckoviewexample/GeckoViewExample.java \
-	$(CURDIR)/res/layout/main.xml \
-	$(CURDIR)/AndroidManifest.xml \
-	$(NULL)
-
-$(CURDIR)/res/layout/main.xml: $(srcdir)/main.xml
-	$(NSINSTALL) $(srcdir)/main.xml res/layout/
-
-src/org/mozilla/geckoviewexample/GeckoViewExample.java: $(srcdir)/GeckoViewExample.java
-	$(NSINSTALL) $(srcdir)/GeckoViewExample.java src/org/mozilla/geckoviewexample/
-
-assets/libxul.so: $(DIST)/geckoview_library/geckoview_assets.zip FORCE
-	$(UNZIP) -o $(DIST)/geckoview_library/geckoview_assets.zip
-
-build.xml: $(CURDIR)/AndroidManifest.xml
-	mv AndroidManifest.xml AndroidManifest.xml.save
-	$(ANDROID) create project --name GeckoViewExample --target $(TARGET) --path $(CURDIR) --activity GeckoViewExample --package org.mozilla.geckoviewexample
-	$(ANDROID) update project --target $(TARGET) --path $(CURDIR) --library $(DEPTH)/mobile/android/geckoview_library
-	$(RM) $(CURDIR)/res/layout/main.xml
-	$(NSINSTALL) $(srcdir)/main.xml res/layout/
-	$(RM) AndroidManifest.xml
-	mv AndroidManifest.xml.save AndroidManifest.xml
-	echo jar.libs.dir=libs >> project.properties
-
-bin/GeckoViewExample-debug.apk: $(PACKAGE_DEPS)
-	ant debug
-
-geckoview_example.apk: bin/GeckoViewExample-debug.apk
-	cp $< $@
-
-package: geckoview_example.apk FORCE
deleted file mode 100644
--- a/embedding/android/geckoview_example/main.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              xmlns:gecko="http://schemas.android.com/apk/res-auto"
-              android:orientation="vertical"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent"
-              >
-  <org.mozilla.gecko.GeckoView android:id="@+id/gecko_view"
-                               android:layout_width="fill_parent"
-                               android:layout_height="fill_parent"
-                               gecko:url="about:mozilla"/>
-</LinearLayout>
deleted file mode 100644
--- a/embedding/moz.build
+++ b/embedding/moz.build
@@ -1,19 +1,16 @@
 # -*- 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/.
 
 DIRS += ['components', 'browser']
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
-    DIRS += ['android/geckoview_example']
-
 TEST_DIRS += ['test']
 
 if CONFIG['ENABLE_TESTS']:
     XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
 
 XPIDL_SOURCES += [
     'nsIWindowCreator.idl',
     'nsIWindowCreator2.idl',
--- 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 2015.08.24
-Thu Aug 27 23:04:57 EDT 2015
+Sun Jan 10 15:07:17 EST 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.
 
@@ -306,9 +306,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 Aug 27 23:04:57 EDT 2015
+Build Date: Sun Jan 10 15:07:17 EST 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
@@ -4464,16 +4464,18 @@ Freemon
 Freemon's
 Friederike
 Friederike's
 Friedrich
 Friedrick
 Friedrick's
 FrontPage
 FrontPage's
+Fukushima
+Fukushima's
 Fulvia
 Fulvia's
 GHz's
 GaAs
 Gabbey
 Gabbey's
 Gabbi
 Gabbi's
@@ -12051,19 +12053,16 @@ Zuzana's
 abridgement
 abridgement's
 abridgements
 absorbance
 absorbances
 absorbancy
 absorbancy's
 acetyl
-acknowledgement
-acknowledgement's
-acknowledgements
 actin
 acyl
 admin's
 advocator
 advocator's
 advocators
 adware's
 adwares
@@ -12080,27 +12079,25 @@ anonymize
 anonymized
 anonymizes
 anonymizing
 anthropomorphize
 anthropomorphized
 anthropomorphizes
 antisense
 antivirus's
-antiviruses
 apatosaurus
 apatosaurus's
 arXiv
 arXiv's
 archaeoastronomy
 archaeoastronomy's
 archaeologic
 archaeomagnetic
 archaeomagnetism
-archeologically
 aryl
 aryl's
 aryls
 assignee
 assignee's
 astroarchaeologies
 astroarchaeology
 astroarchaeology's
@@ -12143,22 +12140,19 @@ bloviators
 blowjob
 blowjob's
 blowjobs
 bookselling
 botnet's
 botnets
 broadcasted
 cDNA
-cancelled
 canceller
 canceller's
-cancelling
 capita
-caravanserai
 carboxylic
 carnitas
 cerevisiae
 cerevisiae's
 cerevisiaes
 charcuterie
 chemistries
 chickenshit's
@@ -12173,39 +12167,23 @@ codon
 codon's
 codons
 coli
 colonoscope
 colonoscope's
 colonoscopes
 commenters
 compositeness
-concurrent's
 concurrents
-concuss's
-condole's
 conferable
 config
 config's
 configs
-configure's
-conform's
 conformant
-confront's
-confuse's
-conjoin's
 conmanly
-conmans
-connote's
-consign's
-conspire's
-constrain's
-contort's
-contribute's
-converge's
 corrigibility
 corrigibility's
 corrigible
 corruptibly
 court-martial
 court-martialed
 court-martialing
 court-martials
@@ -12218,147 +12196,59 @@ cryptologist's
 cryptologists
 cryptosystem
 cryptosystems
 cul-de-sac
 cultivar
 cultivar's
 cultivars
 cyber
-cysteine's
 cytokine
 cytokine's
 cytokines
 datasheet
 datasheet's
 datasheets
-debar's
-debark's
-debase's
-debrief's
-debug's
-debunk's
-decamp's
-decant's
 decertification
 decertifications
 decertified
 decertifies
 decertify
 decertifying
-decipher's
-declaim's
-declaimable
-decode's
-decommission's
-decompress's
-deconstruct's
 deconstructionist's
-decontrol's
-decouple's
-decrypt's
-deduct's
-deface's
-define's
-deflower's
-defog's
-deforest's
-deform's
-defray's
-defrock's
-defrost's
-defuse's
-degas's
 degenerations
-degrade's
-dehydrate's
 dehydrogenase
 dehydrogenase's
-deice's
-delimit's
-delint's
 deliverables
-delouse's
-demist's
-demob's
-demote's
-denature's
-denote's
-depart's
-deplane's
-deport's
-depose's
-depress's
 dequeue
 dequeued
 dequeues
 dequeuing
-derail's
-derange's
-deride's
-desalt's
-descale's
-describe's
-deserve's
 designee
 designings
-deskill's
-despoil's
-detest's
-dethrone's
-detract's
-devalue's
-devote's
 dialoged
 dialoging
+dialogs
 dialogued
 dialoguer
 dialoguing
 diatomaceous
 dihydro
-disabuse's
-disaffect's
-disaffiliate's
-disarm's
 disarrangements
-disassociate's
-disband's
-disbar's
-disclaim's
+disassembler
+disassembler's
+disassemblers
+disassembly
+disassembly's
 disclaimable
 disclosable
-disclose's
-discolor's
-discomfit's
-discommode's
-disconcert's
 discountenance's
-discover's
-discursive's
-discuss's
-disfigure's
-disfranchise's
-disgorge's
-disincentive's
-disincline's
 disintermediation
 disintermediations
-disjoint's
-dismantle's
-dismember's
-dismiss's
-disorient's
-displace's
-disport's
-dispose's
-disrobe's
 dissentious
-distill's
-distort's
-distract's
 djinn
 donator
 donator's
 donators
 durian
 durian's
 durians
 eBook
@@ -12389,17 +12279,16 @@ exactingness
 exactions
 exactor
 exactor's
 exactors
 exon
 exon's
 exons
 experimentalism
-faggoting
 faux
 filesystem
 filesystem's
 filesystems
 filmography
 financials
 fluidize
 fluidizes
@@ -12425,17 +12314,16 @@ gastroenterologist's
 gastroenterology
 genomics
 gigajoule
 gigajoule's
 gigajoules
 gigapixel
 gigapixel's
 gigapixels
-glycerine
 grande
 grey
 grey's
 greybeard's
 greybeards
 greyed
 greyer
 greyest
@@ -12451,48 +12339,27 @@ hexanes
 hijab
 hijabs
 hippopotami
 holdem
 iPods
 idolator
 idolator's
 idolators
-inactive's
 inactives
 inactivities
 incentivize
 incentivized
 incentivizes
 incentivizing
-incite's
 inclosable
-inclose's
-incommode's
 incorrigibleness
-incrust's
-indoor's
-induct's
-indue's
-infill's
-infiltrate's
-infold's
-inform's
-infringe's
-infuse's
-inhabit's
 inkjet
 inkjet's
 inkjets
-inoffensive's
-inquire's
-inscribe's
-inspire's
-inspirit's
-instill's
 intermediacies
 intermediacy
 intermediated
 intermediateness
 intermediating
 intermediation
 intermediations
 intermediator
@@ -12500,21 +12367,16 @@ intermediator's
 intermediators
 interruptible
 intersex
 intersexual
 intersexual's
 intersexualism
 intersexuality
 intersexuals
-intone's
-intrench's
-intrust's
-invariant's
-invest's
 jewellery
 judgement
 judgement's
 judgements
 kbps
 keylogger
 keylogger's
 keyloggers
@@ -12530,28 +12392,26 @@ lepidopterist
 lepidopterist's
 lepidopterists
 limnological
 limnologist
 limnologist's
 limnologists
 limnology
 limnology's
-linguini
 linguistical
 mRNA
 mage
 mage's
 mages
 malwares
 mammalia
 meetup
 meetup's
 meetups
-megadeathes
 megajoule
 megajoule's
 mesothelioma
 mesothelioma's
 metadata
 metadata's
 meth
 methoxy
@@ -12577,17 +12437,16 @@ modelling's
 modellings
 motorsport
 motorsport's
 motorsports
 multicast
 murine
 musculus
 must've
-mySimon
 namespace
 namespace's
 namespaces
 nano
 natively
 neurophysiology's
 neuroscience's
 neurosciences
@@ -12637,216 +12496,80 @@ polypeptide's
 popup
 popup's
 popups
 poutine
 poutines
 prejudgement
 prejudgement's
 prejudgements
-proactive's
-proactives
-proclaim's
+preliminarily
 proclaimable
 procreations
-procure's
 profiler
 profiler's
 profilers
 programmatically
-prolong's
-promote's
 pronate
 pronated
 pronates
 pronating
 pronation
 pronator
 pronator's
 pronators
-propose's
-propound's
 proprietorships
 propyl
-prorogue's
-proscribe's
-protract's
 pseudorandom
 pseudorandomly
 quinoa
 racoon
 rasterization
 rasterization's
 rasterize
 rasterized
 rasterizer
 rasterizes
 rasterizing
-react's
 reactivity's
-readdress's
 reappointments
-rearm's
-reassign's
-reattempt's
-rebind's
-reboot's
 rebroadcasted
 recency
-recent's
-recharter's
-recite's
-reclaim's
-recode's
-recollect's
-recolor's
-recombine's
-recommission's
 recompilation's
-recondition's
-reconstruct's
-reconvert's
-recook's
-recoup's
-recover's
-recross's
-recurrent's
-recurrents
 recurse
 recursed
 recurses
 recursing
-recursive's
 recuse
 recused
 recuses
 recusing
-redistrict's
-redouble's
-redraft's
 reductase
 reductase's
-reduplicate's
-reecho's
-reedit's
-reelect's
-reemploy's
-reface's
-refactor's
-refile's
-refinance's
-refine's
-refinish's
 reflux's
-refocus's
-refold's
-reforest's
-refreeze's
-refuel's
-regain's
-regale's
-regrade's
-rehearse's
-reheat's
-rehire's
-rehouse's
-reinsert's
-rejig's
-rejigger's
-rejoin's
-rejudge's
-relabel's
-relight's
-reload's
 relocations
-remap's
-remaster's
-remeasure's
-remelt's
-remember's
-remind's
-remortgage's
-rename's
 renominations
-renumber's
-reorient's
-repack's
-repackage's
-repartition's
 repartitions
-repay's
-rephrase's
-repine's
-replace's
-reposition's
-repress's
-reprice's
-reprocess's
-reproduce's
-require's
-reroute's
-rescale's
-rescan's
-reschedule's
-reseal's
-reseed's
-resell's
-resettle's
-reshape's
-reship's
-reside's
-resign's
 resizable
 resize
-resize's
 resized
 resizer
 resizes
-resow's
-respire's
-respray's
-restaff's
-restitch's
-restock's
-restore's
-restrain's
-restructure's
-restudy's
-restyle's
 resubmission's
-resurface's
-resurvey's
-retie's
-retire's
-retool's
-retract's
 retransmission's
-retrench's
-retry's
-retype's
-revalue's
-revisit's
-reweigh's
-rewire's
-reword's
-rework's
-rezone's
 rheumatological
 rheumatologist
 rheumatologist's
 rheumatologists
 rheumatology
 rheumatology's
 rootkit
 rootkit's
 rootkits
 rotatably
-sabre
-sabre's
-sabres
 sativa
 savoir
 schnaps
 schrod
 schrods
 scot-free
 screensaver
 screensaver's
@@ -12869,18 +12592,16 @@ showtime's
 showtimes
 signalling
 signup
 signup's
 signups
 sitemap
 sitemap's
 sitemaps
-smoulder
-smouldering
 snarkily
 sommelier
 sommelier's
 sommeliers
 spelt
 spick
 spicks
 spywares
@@ -12939,116 +12660,39 @@ toolbar's
 toolbars
 traceur
 traceur's
 traceurs
 trackback
 trackback's
 trackbacks
 transfect
-transfect's
 transfected
 transfecting
 transfects
 transgenderism
 transgene
-transgene's
 transgenes
 triages
 triaging
 tweep
 tweeps
-unbalance's
-unbar's
-unbind's
-unblock's
-unbolt's
-unbosom's
-unbuckle's
-unburden's
-unbutton's
 uncancelled
-unchain's
 uncheck
-uncheck's
 unchecking
 unchecks
-unclasp's
-unclassified's
-unclassifieds
-uncloak's
-unclog's
-uncoil's
-uncolored's
-uncoloreds
-uncommon's
-uncork's
-uncouple's
-uncover's
-uncross's
-uncurl's
 undeliverables
 undesignated
-unearth's
-unfaithful's
-unfetter's
-unfold's
-unfreeze's
-unfriendly's
-unfrock's
-unfurl's
-unhand's
-unharness's
-unhinge's
-unhitch's
-unhook's
-unhorse's
 uninterruptible
 unironic
 unironically
-unkind's
 unlabelled
-unlace's
-unlatch's
-unleash's
-unload's
-unmake's
-unman's
-unmask's
-unnatural's
-unnerve's
-unpack's
-unplug's
-unquote's
-unravel's
-unreel's
-unsaddle's
-unsafe's
-unsay's
-unscramble's
-unscrew's
-unseal's
-unseat's
-unsettle's
-unshackle's
-unsnap's
-unsnarl's
-unstop's
-unstrap's
-untangle's
-untie's
-untwist's
-unusual's
-unveil's
-unwind's
-unworthy's
-unwrap's
-unyoke's
-unzip's
 username's
+validator
+validators
 vertebrata
 volcanological
 volcanologist
 volcanologist's
 volcanologists
 volcanology
 volcanology's
 weaponize
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-removed
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-removed
@@ -1,2 +1,1 @@
 ABCs
-megadeaths
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/install-new-dict
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/install-new-dict
@@ -11,24 +11,28 @@ WKDIR="`pwd`"
 export SCOWL="$WKDIR/scowl/"
 SPELLER="$SCOWL/speller"
 
 set -x
 
 if [ -e orig-bk ]; then echo "$0: directory 'orig-bk' exists." 1>&2 ; exit 0; fi
 mv orig orig-bk
 mkdir orig
-cp $SPELLER/en_US.dic $SPELLER/en_US.aff $SPELLER/README_en_US.txt orig
+cp $SPELLER/en_US-custom.dic $SPELLER/en_US-custom.aff $SPELLER/README_en_US-custom.txt orig
 
 mkdir mozilla-bk
 mv ../en-US.dic ../en-US.aff ../README_en_US.txt mozilla-bk
 
 # Convert the affix file to ISO8859-1
 sed -i=bak -e '/^ICONV/d' -e 's/^SET UTF8$/SET ISO8859-1/' en_US-mozilla.aff
 
+# Convert the dictionary to ISO8859-1
+mv en_US-mozilla.dic en_US-mozilla-utf8.dic
+iconv -f utf-8 -t iso-8859-1 < en_US-mozilla-utf8.dic > en_US-mozilla.dic
+
 cp en_US-mozilla.aff ../en-US.aff
 cp en_US-mozilla.dic ../en-US.dic
 cp README_en_US-mozilla.txt ../README_en_US.txt
 
 set +x
 
 echo "New dictionary copied into place.  Please commit the changes."
 
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/make-new-dict
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/make-new-dict
@@ -25,31 +25,42 @@ export SCOWL="$WKDIR/scowl/"
 ORIG="$WKDIR/orig/"
 SPELLER="$SCOWL/speller"
 
 expand() {
   grep -v '^[0-9]\+$' | $SPELLER/munch-list expand $1 | sort -u
 }
 
 cd $SPELLER
-./make-hunspell-dict -all > ./make-hunspell-dict.log
+MK_LIST="../mk-list -v1 --accents=both en_US 60"
+cat <<EOF > params.txt
+With Input Command: $MK_LIST
+EOF
+# note: output of make-hunspell-dict is utf-8
+$MK_LIST | ./make-hunspell-dict -one en_US-custom params.txt > ./make-hunspell-dict.log
 cd $WKDIR
 
-expand $SPELLER/en.aff < $SPELLER/en.dic.supp > 0-special
+# Note: Input and output of "expand" is always iso-8859-1.
+#       All expanded word list files are thus in iso-8859-1.
 
-expand $ORIG/en_US.aff < $ORIG/en_US.dic > 1-base.txt
+expand $SPELLER/en.aff < $SPELLER/en.dic.supp > 0-special # input: ASCII
 
-expand ../en-US.aff < ../en-US.dic > 2-mozilla.txt
+# input in utf-8, expand expects iso-8859-1 so use iconv
+iconv -f utf-8 -t iso-8859-1 $ORIG/en_US-custom.dic | expand $ORIG/en_US-custom.aff > 1-base.txt
 
-expand $SPELLER/en.aff < $SPELLER/en_US.dic   > 3-upstream.txt
+expand ../en-US.aff < ../en-US.dic > 2-mozilla.txt # input: iso-8850-1
+
+# input in utf-8, expand expects iso-8859-1 so use iconv
+iconv -f utf-8 -t iso-8859-1 $SPELLER/en_US-custom.dic | expand $SPELLER/en_US-custom.aff > 3-upstream.txt 
 
 comm -23 1-base.txt 2-mozilla.txt > 2-mozilla-rem
 comm -13 1-base.txt 2-mozilla.txt > 2-mozilla-add
 comm -23 3-upstream.txt 2-mozilla-rem | cat - 2-mozilla-add | sort -u > 4-patched.txt
 
+# note: output of make-hunspell-dict is utf-8
 cat 4-patched.txt | comm -23 - 0-special | $SPELLER/make-hunspell-dict -one en_US-mozilla /dev/null
 
 # sanity check should yield identical results
 #comm -23 1-base.txt 3-upstream.txt > 3-upstream-rem
 #comm -13 1-base.txt 3-upstream.txt > 3-upstream-add
 #comm -23 2-mozilla.txt 3-upstream-rem | cat - 3-upstream-add | sort -u > 4-patched-v2.txt
 
 expand ../en-US.aff < mozilla-specific.txt > 5-mozilla-specific
rename from extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US.txt
rename to extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US.txt
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
@@ -1,11 +1,11 @@
-en_US Hunspell Dictionary
+en_US-custom Hunspell Dictionary
 Generated from SCOWL Version 2015.08.24
-Thu Aug 27 23:04:43 EDT 2015
+Sun Jan 10 15:07:16 EST 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.
 
@@ -306,10 +306,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 Aug 27 23:04:43 EDT 2015
-Wordlist Command: mk-list --accents=strip en_US 60
+Build Date: Sun Jan 10 15:07:16 EST 2016
+With Input Command: ../mk-list -v1 --accents=both en_US 60
rename from extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US.aff
rename to extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.aff
rename from extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US.dic
rename to extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
--- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US.dic
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
@@ -1,9 +1,9 @@
-48756
+49245
 0/nm
 0th/pt
 1/n1
 1st/p
 1th/tc
 2/nm
 2nd/p
 2th/tc
@@ -685,24 +685,27 @@ Astana/M
 Astarte/M
 Aston/M
 Astor/M
 Astoria/M
 Astrakhan/M
 AstroTurf/M
 Asturias/M
 Asuncion/M
+Asunción/M
 Aswan/M
 At/SM
 Atacama/M
 Atahualpa/M
 Atalanta/M
 Atari/M
 Ataturk/M
+Atatürk/M
 Athabasca/M
+Athabaska
 Athabaskan/SM
 Athanasius
 Athena/M
 Athene/M
 Athenian/SM
 Athens/M
 Atkins/M
 Atkinson/M
@@ -947,20 +950,22 @@ Barry/M
 Barrymore/M
 Bart/M
 Barth/MS
 Bartholdi/M
 Bartholomew/M
 Bartlett/M
 Bartok/M
 Barton/M
+Bartók/M
 Baruch/M
 Baryshnikov/M
 Basel/M
 Basho/M
+Basic
 Basie/M
 Basil/M
 Basque/MS
 Basra/M
 Bass/M
 Basseterre/M
 Bastille/M
 Basutoland/M
@@ -1055,16 +1060,17 @@ Bellow/M
 Belmont/M
 Belmopan/M
 Belorussian/MS
 Belshazzar/M
 Beltane/M
 Belushi/M
 Ben/M
 Benacerraf/M
+Benares/M
 Benchley/M
 Bender/M
 Bendix/M
 Benedict/M
 Benedictine/MS
 Benelux/M
 Benet/M
 Benetton/M
@@ -1160,16 +1166,17 @@ Bhopal/M
 Bhutan/M
 Bhutanese/M
 Bhutto/M
 Bi/M
 Bialystok/M
 Bianca/M
 Bib
 Bible/MS
+Biblical/M
 Bic/M
 Biddle/M
 Biden/M
 Bierce/M
 Bigfoot/M
 Biggles/M
 Biko/M
 Bilbao/M
@@ -1193,16 +1200,17 @@ Bismarck/M
 Bismark/M
 Bisquick/M
 Bissau/M
 BitTorrent/M
 Bizet/M
 Bjerknes/M
 Bjork/M
 Bk/M
+Black/MS
 Blackbeard/M
 Blackburn/M
 Blackfeet/M
 Blackfoot/M
 Blackpool/M
 Blackshirt/M
 Blackstone/M
 Blackwell/M
@@ -1248,16 +1256,17 @@ Bodhisattva/M
 Bodleian
 Boeing/M
 Boeotia/M
 Boeotian/M
 Boer/SM
 Boethius/M
 Bogart/M
 Bogota/M
+Bogotá/M
 Bohemia/M
 Bohemian/SM
 Bohr/M
 Boise/M
 Bojangles/M
 Boleyn/M
 Bolivar/M
 Bolivia/M
@@ -1326,16 +1335,17 @@ Bowell/M
 Bowen/M
 Bowers/M
 Bowery/M
 Bowie/M
 Bowman/M
 Boyd/M
 Boyer/M
 Boyle/M
+Boötes/M
 Br/MT
 Brad/MY
 Bradbury/M
 Braddock/M
 Bradford/M
 Bradley/M
 Bradly/M
 Bradshaw/M
@@ -1544,16 +1554,17 @@ Burundi/M
 Burundian/MS
 Busch/M
 Bush/M
 Bushido/M
 Bushnell/M
 Butler/M
 Butterfingers/M
 Buxtehude/M
+Buñuel/M
 Byblos/M
 Byers/M
 Byrd/M
 Byron/M
 Byronic/M
 Byzantine/MS
 Byzantium/M
 C/SM
@@ -1793,16 +1804,17 @@ Caspar/M
 Caspian/M
 Cassandra/SM
 Cassatt/M
 Cassidy/M
 Cassie/M
 Cassiopeia/M
 Cassius/M
 Castaneda/M
+Castile/M
 Castillo/M
 Castlereagh/M
 Castor/M
 Castries/M
 Castro/M
 Catalan/SM
 Catalina/M
 Catalonia/M
@@ -1840,16 +1852,17 @@ Ceausescu/M
 Cebu/M
 Cebuano/M
 Cecelia/M
 Cecil/M
 Cecile/M
 Cecilia/M
 Cecily/M
 Cedric/M
+Celebes/M
 Celeste/M
 Celia/M
 Celina/M
 Cellini/M
 Celsius/M
 Celt/SM
 Celtic/SM
 Cenozoic/M
@@ -2179,16 +2192,17 @@ Comoran
 Comoros/M
 Compaq/M
 Compton/M
 CompuServe/M
 Comte/M
 Conakry/M
 Conan/M
 Concepcion/M
+Concepción/M
 Concetta/M
 Concord/SM
 Concorde/M
 Condillac/M
 Condorcet/M
 Conestoga/M
 Confederacy/M
 Confederate/MS
@@ -2469,16 +2483,17 @@ Dame/MN
 Damian/M
 Damien/M
 Damion/M
 Damocles/M
 Damon/M
 Dan/M
 Dana/M
 Danae/M
+Danaë/M
 Dane/SM
 Danelaw/M
 Dangerfield/M
 Danial/M
 Daniel/SM
 Danielle/M
 Daniels/M
 Danish/M
@@ -2632,18 +2647,20 @@ Dermot/M
 Derrick/M
 Derrida/M
 Descartes/M
 Desdemona/M
 Desiree/M
 Desmond/M
 Detroit/M
 Deuteronomy/M
+Deutschmark/SM
 Devanagari/M
 Devi/M
+Devil/M
 Devin/M
 Devon/M
 Devonian/M
 Dewar/M
 Dewayne/M
 Dewey/M
 Dewitt/M
 Dexedrine/M
@@ -2706,17 +2723,19 @@ Divine/M
 Diwali/M
 Dix/M
 Dixie/M
 Dixiecrat/M
 Dixieland/SM
 Dixon/M
 Djibouti/M
 Dmitri/M
+Dnepr
 Dnepropetrovsk/M
+Dnieper/M
 Dniester/M
 Dobbin/M
 Doberman/M
 Dobro/M
 Doctor
 Doctorow/M
 Dodge/M
 Dodgson/M
@@ -2798,16 +2817,17 @@ Drano/M
 Dravidian/M
 Dreiser/M
 Dresden/M
 Drew/M
 Dreyfus/M
 Dristan/M
 Dropbox/M
 Drudge/M
+Druid/M
 Dryden/M
 Dschubba/M
 Du
 DuPont/M
 Duane/M
 Dubai/M
 Dubcek/M
 Dubhe/M
@@ -2852,24 +2872,27 @@ Dustin/M
 Dusty/M
 Dutch/M
 Dutchman/M
 Dutchmen/M
 Dutchwoman
 Duvalier/M
 Dvina/M
 Dvorak/M
+Dvorák/M
 Dwayne/M
 Dwight/M
 Dy/M
 Dyer/M
 Dylan/M
 Dyson/M
 Dzerzhinsky/M
 Dzungaria/M
+Dürer/M
+Düsseldorf/M
 E/SM
 EC
 ECG/M
 ECMAScript/M
 EDP/M
 EDT
 EEC/M
 EEG/M
@@ -3025,16 +3048,17 @@ Elvia/M
 Elvin/M
 Elvira/M
 Elvis/M
 Elway/M
 Elwood/M
 Elysee/M
 Elysian/M
 Elysium/SM
+Elysée/M
 Emacs/M
 Emanuel/M
 Emerson/M
 Emery/M
 Emil/M
 Emile/M
 Emilia/M
 Emilio/M
@@ -3092,16 +3116,18 @@ Erector/M
 Erewhon/M
 Erhard/M
 Eric/M
 Erica/M
 Erich/M
 Erick/M
 Ericka/M
 Erickson/M
+Ericson/M
+Ericsson/M
 Eridanus/M
 Erie/M
 Erik/M
 Erika/M
 Erin/M
 Eris/MS
 Eritrea/M
 Eritrean/SM
@@ -3136,16 +3162,17 @@ Essex/M
 Essie/M
 Establishment
 Esteban/M
 Estela/M
 Estella/M
 Estelle/M
 Ester/M
 Esterhazy/M
+Esterházy/M
 Estes/M
 Esther/M
 Estonia/M
 Estonian/SM
 Estrada/M
 Ethan/M
 Ethel/M
 Ethelred/M
@@ -3156,16 +3183,17 @@ Etna/M
 Eton/M
 Etruria/M
 Etruscan/M
 Etta/M
 Eu/M
 Eucharist/MS
 Eucharistic
 Euclid/M
+Euclidean/M
 Eugene/M
 Eugenia/M
 Eugenie/M
 Eugenio/M
 Eula/M
 Euler/M
 Eumenides/M
 Eunice/M
@@ -3236,16 +3264,17 @@ FSF/M
 FSLIC
 FTC
 FUD/S
 FWD
 FWIW
 FY
 FYI
 Faberge/M
+Fabergé/M
 Fabian/MS
 Facebook/M
 Faeroe/M
 Fafnir/M
 Fagin/M
 Fahd/M
 Fahrenheit/M
 Fairbanks/M
@@ -3264,16 +3293,17 @@ Faraday/M
 Fargo/M
 Farley/M
 Farmer/M
 Farragut/M
 Farrakhan/M
 Farrell/M
 Farrow/M
 Farsi/M
+Fascist
 Fassbinder/M
 Fatah/M
 Fates/M
 Father/SM
 Fatima/M
 Fatimid/M
 Faulkner/M
 Faulknerian/M
@@ -3504,16 +3534,17 @@ Fulani/M
 Fulbright/M
 Fuller/M
 Fullerton/M
 Fulton/M
 Funafuti/M
 Fundy/M
 Furies/M
 Furtwangler/M
+Furtwängler/M
 Fushun/M
 Fuzhou/M
 Fuzzbuster/M
 G/MNRB
 GA
 GAO
 GATT/M
 GB/M
@@ -3684,16 +3715,17 @@ Geronimo/M
 Gerry/M
 Gershwin/M
 Gertrude/M
 Gestapo/SM
 Gethsemane/M
 Getty/M
 Gettysburg/M
 Gewurztraminer/M
+Gewürztraminer/M
 Ghana/M
 Ghanaian
 Ghats/M
 Ghazvanid/M
 Ghent/M
 Ghibelline/M
 Giacometti/M
 Giannini/M
@@ -3902,16 +3934,18 @@ Grosz/M
 Grotius/M
 Grover/M
 Grozny
 Grumman/M
 Grundy/M
 Grunewald/M
 Grus/M
 Gruyere/SM
+Gruyère/M
+Grünewald/M
 Guadalajara/M
 Guadalcanal/M
 Guadalquivir/M
 Guadalupe/M
 Guadeloupe/M
 Guallatiri/M
 Guam/M
 Guamanian
@@ -3960,16 +3994,18 @@ Guyana/M
 Guyanese/M
 Guzman/M
 Gwalior/M
 Gwen/M
 Gwendoline/M
 Gwendolyn/M
 Gwyn/M
 Gypsy/SM
+Gödel/M
+Göteborg/M
 H/M
 HBO/M
 HDD
 HDMI
 HDTV
 HF/M
 HHS
 HI
@@ -4059,16 +4095,17 @@ Hannibal/M
 Hanoi/M
 Hanover/M
 Hanoverian/M
 Hans/MN
 Hansel/M
 Hansen/M
 Hanson/M
 Hanuka
+Hanukah/M
 Hanukkah/M
 Hanukkahs
 Hapsburg/M
 Harare/M
 Harbin/M
 Hardin/M
 Harding/M
 Hardy/M
@@ -4460,16 +4497,17 @@ Huygens/M
 Hyades/M
 Hyde/M
 Hyderabad/M
 Hydra/M
 Hymen/M
 Hyperion/M
 Hyundai/M
 Hz/M
+Héloise/M
 I'd
 I'll
 I'm
 I've
 I/M
 IA
 IBM/M
 ICBM/SM
@@ -4539,16 +4577,17 @@ Ikhnaton/M
 Ila/M
 Ilene/M
 Iliad/SM
 Ill
 Illinois/M
 Illinoisan/MS
 Illuminati/M
 Ilyushin/M
+Imam
 Imelda/M
 Imhotep/M
 Imodium/M
 Imogene/M
 Imus/M
 In/M
 Ina/M
 Inc
@@ -4882,16 +4921,17 @@ Johnathan/M
 Johnathon/M
 Johnie/M
 Johnnie/M
 Johnny/M
 Johns/M
 Johnson/M
 Johnston/M
 Jolene/M
+Joliet/M
 Jolson/M
 Jon/M
 Jonah/M
 Jonahs
 Jonas/M
 Jonathan/M
 Jonathon/M
 Jones/M
@@ -5053,16 +5093,17 @@ Kathie/M
 Kathleen/M
 Kathmandu/M
 Kathrine/M
 Kathryn/M
 Kathy/M
 Katie/M
 Katina/M
 Katmai/M
+Katmandu/M
 Katowice/M
 Katrina/M
 Katy/M
 Kauai/M
 Kaufman/M
 Kaunas/M
 Kaunda/M
 Kawabata/M
@@ -5250,16 +5291,17 @@ Kory/M
 Korzybski/M
 Kosciusko/M
 Kossuth/M
 Kosygin/M
 Koufax/M
 Kowloon/M
 Kr/M
 Kraft/M
+Krakatau/M
 Krakatoa/M
 Krakow/M
 Kramer/M
 Krasnodar/M
 Krasnoyarsk/M
 Krebs/M
 Kremlin/M
 Kremlinologist
@@ -5303,16 +5345,17 @@ Kurtis/M
 Kusch/M
 Kutuzov/M
 Kuwait/M
 Kuwaiti/SM
 Kuznets/M
 Kuznetsk/M
 Kwakiutl/M
 Kwan/M
+Kwangchow/M
 Kwangju/M
 Kwanzaa/MS
 Ky/MH
 Kyle/M
 Kyoto/M
 Kyrgyzstan/M
 Kyushu/M
 L'Amour/M
@@ -5342,16 +5385,17 @@ LPN/SM
 LSAT
 LSD/M
 LVN
 La/SM
 Lab
 Laban/M
 Labrador/SM
 Labradorean
+Labradorian
 Lacey/M
 Lachesis/M
 Lacy/M
 Ladoga/M
 Ladonna/M
 Lady/M
 Ladyship/MS
 Lafayette/M
@@ -5769,16 +5813,17 @@ Lugosi/M
 Luigi/M
 Luis/M
 Luisa/M
 Luke/M
 Lula/M
 Lully/M
 Lulu/M
 Lumiere/M
+Lumière/M
 Luna/M
 Lupe/M
 Lupercalia/M
 Lupus/M
 Luria/M
 Lusaka/M
 Lusitania/M
 Luther/M
@@ -5962,29 +6007,31 @@ Maldivian/MS
 Maldonado/M
 Male/M
 Mali/M
 Malian/SM
 Malibu/M
 Malinda/M
 Malinowski/M
 Mallarme/M
+Mallarmé/M
 Mallomars/M
 Mallory/M
 Malone/M
 Malory/M
 Malplaquet/M
 Malraux/M
 Malta/M
 Maltese/M
 Malthus/M
 Malthusian/SM
 Mameluke/M
 Mamet/M
 Mamie/M
+Mammon/SM
 Mamore/M
 Man/M
 Managua/M
 Manama/M
 Manasseh/M
 Manchester/M
 Manchu/SM
 Manchuria/M
@@ -6363,16 +6410,17 @@ Merrick/M
 Merrill/M
 Merrimack/M
 Merritt/M
 Merthiolate/M
 Merton/M
 Mervin/M
 Mesa/M
 Mesabi/M
+Meshed/M
 Mesmer/M
 Mesolithic/M
 Mesopotamia/M
 Mesopotamian
 Mesozoic/M
 Messerschmidt/M
 Messiaen/M
 Messiah/M
@@ -6647,16 +6695,17 @@ Morse/M
 Mort/M
 Mortimer/M
 Morton/M
 Mosaic/M
 Moscow/M
 Moseley/M
 Moselle/M
 Moses/M
+Moslem/M
 Mosley/M
 Moss/M
 Mosul/M
 Motorola/M
 Motown/M
 Motrin/M
 Mott/M
 Moulton/M
@@ -6737,16 +6786,17 @@ Mylar/MS
 Myles/M
 Myra/M
 Myrdal/M
 Myrna/M
 Myron/M
 Myrtle/M
 Mysore/M
 Myst/M
+Münchhausen/M
 N'Djamena
 N/MD
 NAACP/M
 NAFTA/M
 NASA/M
 NASCAR/M
 NASDAQ/M
 NATO/M
@@ -6844,16 +6894,17 @@ Natasha/M
 Natchez/M
 Nate/MN
 Nathan/SM
 Nathaniel/M
 Nathans/M
 Nation/M
 Nationwide/M
 Nativity/M
+Nature
 Naugahyde/M
 Nauru/M
 Nautilus/M
 Navajo/SM
 Navajoes
 Navarre/M
 Navarro/M
 Navratilova/M
@@ -6972,16 +7023,17 @@ Nigerian/MS
 Nigerien/M
 Nightingale/M
 Nijinsky/M
 Nike/M
 Nikita/M
 Nikkei/M
 Nikki/M
 Nikolai/M
+Nikolayev/M
 Nikon/M
 Nile/M
 Nimitz/M
 Nimrod/M
 Nina/M
 Nineveh/M
 Nintendo/M
 Niobe/M
@@ -7026,16 +7078,17 @@ Normandy/M
 Norplant/M
 Norris/M
 Norse/M
 Norseman/M
 Norsemen/M
 North/M
 Northampton/M
 Northeast/MS
+Northern/MR
 Northerner/M
 Northrop/M
 Northrup/M
 Norths
 Northwest/SM
 Norton/M
 Norw
 Norway/M
@@ -7349,16 +7402,17 @@ Paganini/M
 Page/M
 Paglia/M
 Pahlavi/M
 Paige/M
 Paine/M
 Paiute/SM
 Pakistan/M
 Pakistani/SM
+Palau/M
 Palembang/M
 Paleocene/M
 Paleogene/M
 Paleolithic/M
 Paleozoic/M
 Palermo/M
 Palestine/M
 Palestinian/SM
@@ -7393,32 +7447,35 @@ Paracelsus/M
 Paraclete/M
 Paradise
 Paraguay/M
 Paraguayan/MS
 Paralympic/S
 Paramaribo/M
 Paramount/M
 Parana/M
+Paraná/M
 Parcheesi/M
 Pareto/M
 Paris/M
 Parisian/MS
 Park/SMR
 Parker/M
 Parkinson/M
 Parkman/M
 Parks/M
 Parliament/M
 Parmenides
 Parmesan/MS
 Parnassus/MS
 Parnell/M
 Parr/M
 Parrish/M
+Parsee/SM
+Parsi/MS
 Parsifal/M
 Parsons/M
 Parthenon/M
 Parthia/M
 Pasadena/M
 Pascal/SM
 Pasquale/M
 Passion/SM
@@ -7469,16 +7526,17 @@ Peckinpah/M
 Pecos/M
 Pedro/M
 Peel/M
 Peg/M
 Pegasus/MS
 Peggy/M
 Pei/M
 Peiping/M
+Pekinese/M
 Peking/SM
 Pekingese/SM
 Pele/M
 Pelee/M
 Peloponnese/M
 Pembroke/M
 Pen/M
 Pena/M
@@ -7622,16 +7680,17 @@ Pitcairn/M
 Pitt/SM
 Pittman/M
 Pitts/M
 Pittsburgh/M
 Pius/M
 Pizarro/M
 Pkwy
 Pl
+Place
 Planck/M
 Plano
 Plantagenet/M
 Plasticine/M
 Plataea/M
 Plath/M
 Plato/M
 Platonic
@@ -7656,21 +7715,23 @@ Pocahontas/M
 Pocono/SM
 Poconos/M
 Podgorica/M
 Podhoretz/M
 Podunk/M
 Poe/M
 Pogo/M
 Poincare/M
+Poincaré/M
 Poiret/M
 Poirot/M
 Poisson/M
 Poitier/M
 Pokemon/M
+Pokémon/M
 Pol/MY
 Poland/M
 Polanski/M
 Polaris/M
 Polaroid/MS
 Pole/SM
 Polish/M
 Politburo/M
@@ -7783,16 +7844,17 @@ Protagoras/M
 Proterozoic/M
 Protestant/MS
 Protestantism/SM
 Proteus/M
 Proudhon/M
 Proust/M
 Provencal/MS
 Provence/M
+Provençal/M
 Proverbs
 Providence/SM
 Provo/M
 Prozac/MS
 Prudence/M
 Prudential/M
 Pruitt/M
 Prussia/M
@@ -7820,16 +7882,17 @@ Pulitzer/M
 Pullman/MS
 Punch/M
 Punic/M
 Punjab/M
 Punjabi/M
 Purana/M
 Purcell/M
 Purdue/M
+Purgatory
 Purim/MS
 Purina/M
 Puritan/M
 Puritanism/MS
 Purus/M
 Pusan/M
 Pusey/M
 Pushkin/M
@@ -7847,16 +7910,18 @@ Pyongyang/M
 Pyotr/M
 Pyrenees/M
 Pyrex/MS
 Pyrrhic/M
 Pythagoras/M
 Pythagorean/M
 Pythias/M
 Python/M
+Pétain/M
+Pôrto/M
 Q
 QA
 QB
 QC
 QED
 QM
 QWERTY
 Qaddafi/M
@@ -7870,16 +7935,17 @@ Quaalude/M
 Quaker/MS
 Quakerism/SM
 Quaoar/M
 Quasimodo/M
 Quaternary/M
 Quayle/M
 Que
 Quebec/M
+Quebecker
 Quebecois/M
 Quechua/M
 Queen/MS
 Queens/M
 Queensland/M
 Quentin/M
 Quetzalcoatl/M
 Quezon/M
@@ -7889,17 +7955,22 @@ Quintilian/M
 Quinton/M
 Quirinal/M
 Quisling/M
 Quito/M
 Quixote/M
 Quixotism/M
 Qumran/M
 Quonset/M
-R/M
+Qur'an
+Qur'anic
+Quran
+Quranic
+Québecois/M
+R/MD
 RAF/M
 RAM/SM
 RBI
 RC
 RCA/M
 RCMP
 RD
 RDA
@@ -7935,16 +8006,17 @@ Rachel/M
 Rachelle/M
 Rachmaninoff/M
 Racine/M
 Radcliffe/M
 Rae/M
 Rafael/M
 Raffles/M
 Ragnarok/M
+Ragnarök/M
 Rainier/M
 Raleigh/M
 Ralph/M
 Rama/M
 Ramada/M
 Ramadan/MS
 Ramakrishna/M
 Ramanujan/M
@@ -7999,16 +8071,17 @@ Reading/M
 Reagan/M
 Reaganomics/M
 Realtor/M
 Reasoner/M
 Reba/M
 Rebekah/M
 Recife/M
 Reconstruction/M
+Red/SM
 Redeemer/M
 Redford/M
 Redgrave/M
 Redmond/M
 Reebok/M
 Reed/M
 Reese/M
 Reeves/M
@@ -8200,16 +8273,17 @@ Rom
 Roman/MS
 Romanesque/MS
 Romania/M
 Romanian/MS
 Romano/M
 Romanov/M
 Romans/M
 Romansh/M
+Romantic
 Romanticism
 Romany/SM
 Rome/SM
 Romeo/M
 Romero/M
 Rommel/M
 Romney/M
 Romulus/M
@@ -8291,19 +8365,21 @@ Rubin/M
 Rubinstein/M
 Ruby/M
 Ruchbah/M
 Rudolf/M
 Rudolph/M
 Rudy/M
 Rudyard/M
 Rufus/M
+Rugby
 Ruhr/M
 Ruiz/M
 Rukeyser/M
+Rumanian/SM
 Rumpelstiltskin/M
 Rumsfeld/M
 Runnymede/M
 Runyon/M
 Rupert/M
 Rush/M
 Rushdie/M
 Rushmore/M
@@ -8458,16 +8534,17 @@ Sampson/M
 Samson/M
 Samsonite/M
 Samsung/M
 Samuel/M
 Samuelson/M
 San'a
 San/M
 Sana/M
+Sanaa/M
 Sanchez/M
 Sancho/M
 Sand/ZM
 Sandburg/M
 Sanders/M
 Sandinista/M
 Sandoval/M
 Sandra/M
@@ -8560,16 +8637,17 @@ Schmidt/M
 Schnabel/M
 Schnauzer/M
 Schneider/M
 Schoenberg/M
 Schopenhauer/M
 Schrieffer/M
 Schrodinger/M
 Schroeder/M
+Schrödinger/M
 Schubert/M
 Schultz/M
 Schulz/M
 Schumann/M
 Schumpeter/M
 Schuyler/M
 Schuylkill/M
 Schwartz/M
@@ -8792,16 +8870,17 @@ Shreveport/M
 Shriner/M
 Shropshire/M
 Shula/M
 Shylock/M
 Shylockian/M
 Si/M
 Siam/M
 Siamese/M
+Sian/M
 Sibelius/M
 Siberia/M
 Siberian/MS
 Sibyl/M
 Sicilian/SM
 Sicily/M
 Sid/M
 Siddhartha/M
@@ -8844,16 +8923,17 @@ Singaporean/SM
 Singer/M
 Singh/M
 Singleton/M
 Sinhalese/M
 Sinkiang/M
 Sioux/M
 Sir/SM
 Sirius/M
+Sister/MS
 Sistine/M
 Sisyphean/M
 Sisyphus/M
 Siva/M
 Sivan/M
 Sjaelland/M
 Skinner/M
 Skippy/M
@@ -8941,17 +9021,18 @@ Sorbonne/M
 Sosa/M
 Soto/M
 Souphanouvong/M
 Sourceforge/M
 Sousa/M
 South/M
 Southampton/M
 Southeast/MS
-Southerner/SM
+Southern/ZR
+Southerner/M
 Southey/M
 Souths
 Southwest/MS
 Soviet/M
 Soweto/M
 Soyinka/M
 Soyuz/M
 Sp
@@ -9021,18 +9102,20 @@ Stanford/M
 Stanislavsky/M
 Stanley/M
 Stanton/M
 Staples/M
 Starbucks/M
 Stark/M
 Starkey/M
 Starr/M
+Statehouse/MS
 Staten/M
 States
+Stateside
 Staubach/M
 Ste
 Steadicam/M
 Steele/M
 Stefan/M
 Stefanie/M
 Stein/MR
 Steinbeck/M
@@ -9112,16 +9195,18 @@ Suetonius/M
 Suez/M
 Suffolk/M
 Sufi/M
 Sufism/M
 Suharto/M
 Sui/M
 Sukarno/M
 Sukkot
+Sukkoth/M
+Sukkoths
 Sulawesi/M
 Suleiman/M
 Sulla/M
 Sullivan/M
 Sumatra/M
 Sumatran/SM
 Sumeria/M
 Sumerian/SM
@@ -9141,16 +9226,17 @@ Sunni/SM
 Sunnite/MS
 Sunnyvale/M
 Superbowl/M
 Superfund/M
 Superglue/M
 Superior/M
 Superman/M
 Supt
+Surabaja
 Surabaya/M
 Surat/M
 Suriname/M
 Surinamese
 Surya/M
 Susan/M
 Susana/M
 Susanna/M
@@ -9199,16 +9285,17 @@ Sylvia/M
 Sylvie/M
 Synge/M
 Syracuse/M
 Syria/M
 Syriac/M
 Syrian/MS
 Szilard/M
 Szymborska/M
+Sèvres/M
 T'ang/M
 T/MDG
 TA
 TARP
 TB/M
 TBA
 TD
 TDD
@@ -9292,32 +9379,34 @@ Tancred/M
 Taney/M
 Tanganyika/M
 Tangier/MS
 Tangshan/M
 Tania/M
 Tanisha/M
 Tanner/M
 Tannhauser/M
+Tannhäuser/M
 Tantalus/M
 Tanya/M
 Tanzania/M
 Tanzanian/SM
 Tao/M
 Taoism/MS
 Taoist/MS
 Tara/M
 Tarantino/M
 Tarawa/M
 Tarazed/M
 Tarbell/M
 Target/M
 Tarim/M
 Tarkenton/M
 Tarkington/M
+Tartar/MS
 Tartary/M
 Tartuffe/M
 Tarzan/M
 Tasha/M
 Tashkent/M
 Tasman/M
 Tasmania/M
 Tasmanian/M
@@ -9368,16 +9457,17 @@ Terpsichore/M
 Terr/M
 Terra/M
 Terran/M
 Terrance/M
 Terrell/M
 Terrence/M
 Terri/M
 Terrie/M
+Territory
 Terry/M
 Tertiary/M
 Tesla/M
 Tess/M
 Tessa/M
 Tessie/M
 Tet/M
 Tethys/M
@@ -9421,16 +9511,17 @@ Therese/M
 Thermopylae/M
 Thermos
 Theron/M
 Theseus/M
 Thespian/M
 Thespis/M
 Thessalonian/SM
 Thessaloniki/M
+Thessaloníki/M
 Thessaly/M
 Thieu/M
 Thimbu/M
 Thimphu
 Thomas/M
 Thomism/M
 Thomistic/M
 Thompson/M
@@ -9460,16 +9551,17 @@ Tianjin/M
 Tiber/M
 Tiberius/M
 Tibet/M
 Tibetan/MS
 Ticketmaster/M
 Ticonderoga/M
 Tide/M
 Tienanmen/M
+Tientsin/M
 Tiffany/M
 Tigris/M
 Tijuana/M
 Tillich/M
 Tillman/M
 Tilsit/M
 Tim/M
 Timbuktu/M
@@ -9835,16 +9927,17 @@ Valery/M
 Valhalla/M
 Valium/MS
 Valkyrie/SM
 Vallejo
 Valletta/M
 Valois/M
 Valparaiso/M
 Valvoline/M
+Valéry/M
 Van/M
 Vance/M
 Vancouver/M
 Vandal/MS
 Vanderbilt/M
 Vandyke/M
 Vanessa/M
 Vang/M
@@ -9859,26 +9952,29 @@ Vassar/M
 Vatican/M
 Vauban/M
 Vaughan/M
 Vaughn/M
 Vazquez/M
 Veblen/M
 Veda/SM
 Vedanta/M
+Veep
 Vega/SM
 Vegas/M
 Vegemite/M
 Vela/M
 Velasquez/M
 Velazquez/M
 Velcro/MS
 Velez/M
 Velma/M
 Velveeta/M
+Velásquez/M
+Velázquez/M
 Venetian/SM
 Venezuela/M
 Venezuelan/SM
 Venice/M
 Venn/M
 Ventolin/M
 Venus/MS
 Venusian/M
@@ -9944,16 +10040,17 @@ Vinson/M
 Viola/M
 Violet/M
 Virgie/M
 Virgil/M
 Virginia/M
 Virginian/SM
 Virgo/SM
 Visa/M
+Visakhapatnam/M
 Visayans/M
 Vishnu/M
 Visigoth/M
 Visigoths
 Vistula/M
 Vitim/M
 Vito/M
 Vitus/M
@@ -10412,16 +10509,17 @@ Zeffirelli/M
 Zeke/M
 Zelig/M
 Zelma/M
 Zen/M
 Zenger/M
 Zeno/M
 Zephaniah/M
 Zephyrus/M
+Zeppelin/M
 Zest/M
 Zeus/M
 Zhdanov
 Zhengzhou/M
 Zhivago/M
 Zhukov/M
 Zibo/M
 Ziegfeld/M
@@ -10456,16 +10554,17 @@ Zulu/SM
 Zululand
 Zuni/M
 Zurich/M
 Zwingli/M
 Zworykin/M
 Zyrtec/M
 Zyuganov/M
 Zzz
+Zürich/M
 a/S
 aah
 aardvark/SM
 ab/SDY
 aback
 abacus/MS
 abaft
 abalone/SM
@@ -10483,30 +10582,32 @@ abattoir/MS
 abbe/SM
 abbess/MS
 abbey/MS
 abbot/MS
 abbr
 abbrev/S
 abbreviate/DSGNX
 abbreviation/M
+abbé/SM
 abdicate/GNDSX
 abdication/M
 abdomen/SM
 abdominal
 abduct/DSG
 abductee/MS
 abduction/SM
 abductor/MS
 abeam
 aberrant
 aberration/MS
 aberrational
 abet/S
 abetted
+abetter/SM
 abetting
 abettor/SM
 abeyance/M
 abhor/S
 abhorred
 abhorrence/M
 abhorrent/Y
 abhorring
@@ -10691,16 +10792,18 @@ account/MDSBG
 accountability/M
 accountable/U
 accountancy/M
 accountant/MS
 accounted/U
 accounting/M
 accouter/SGD
 accouterments/M
+accoutre/DSG
+accoutrements
 accredit/SGD
 accreditation/M
 accredited/U
 accretion/MS
 accrual/MS
 accrue/GDS
 acct
 acculturate/DSGN
@@ -10742,18 +10845,19 @@ achoo/M
 achromatic
 achy/TR
 acid/SMY
 acidic
 acidify/GDS
 acidity/M
 acidosis/M
 acidulous
-acknowledge/DSG
+acknowledge/DSGL
 acknowledged/U
+acknowledgement/MS
 acknowledgment/SM
 acme/SM
 acne/M
 acolyte/MS
 aconite/MS
 acorn/MS
 acoustic/S
 acoustical/Y
@@ -10838,16 +10942,17 @@ adaptability/M
 adaptation/MS
 adapter/M
 adaption/S
 add/SDRBZG
 addend/MS
 addenda
 addendum/M
 adder/M
+addible
 addict/GVMDS
 addiction/SM
 addition/SM
 additional/Y
 additive/SM
 addle/GDS
 address's
 address/AGDS
@@ -10868,16 +10973,17 @@ adherence/M
 adherent/SM
 adhesion/M
 adhesive/PSM
 adhesiveness/M
 adiabatic
 adieu/MS
 adios
 adipose
+adiós
 adj
 adjacency/M
 adjacent/Y
 adjectival/Y
 adjective/MS
 adjoin/GDS
 adjourn/DGLS
 adjournment/SM
@@ -10998,39 +11104,43 @@ advertorial/SM
 advice/M
 advisability/IM
 advisable/I
 advisably
 advise/LDRSZGB
 advised/UY
 advisement/M
 adviser/M
+advisor/SM
 advisory/SM
 advocacy/M
 advocate/MGDS
 advt
 adware
-adze/SM
+adz/MS
+adze/M
 aegis/M
+aeon/SM
 aerate/DSGN
 aeration/M
 aerator/SM
 aerial/SMY
 aerialist/MS
 aerie/MS
 aerobatic/S
 aerobatics/M
 aerobic/S
 aerobically
 aerobics/M
 aerodrome/MS
 aerodynamic/S
 aerodynamically
 aerodynamics/M
 aerogram/S
+aerogramme/S
 aeronautic/S
 aeronautical
 aeronautics/M
 aerosol/MS
 aerospace/M
 aesthete/MS
 aesthetic/S
 aesthetically
@@ -11109,16 +11219,17 @@ afterward/S
 afterword/MS
 again
 against
 agape/M
 agar/M
 agate/MS
 agave/M
 age/DSMGJ
+ageing/SM
 ageism/M
 ageist/SM
 ageless/YP
 agelessness/M
 agency/SM
 agenda/SM
 agent/AMS
 ageratum/M
@@ -11208,24 +11319,24 @@ airdrome/S
 airdrop/SM
 airdropped
 airdropping
 airfare/SM
 airfield/SM
 airflow/M
 airfoil/SM
 airfreight/M
-airguns
+airgun/S
 airhead/SM
 airily
 airiness/M
 airing/M
 airless/P
 airlessness/M
-airletters
+airletter/S
 airlift/SGMD
 airline/RSMZ
 airliner/M
 airlock/SM
 airmail/GSMD
 airman/M
 airmen
 airplane/MS
@@ -11315,17 +11426,17 @@ aligner/MS
 alignment/AMS
 alike/U
 aliment/MDSG
 alimentary
 alimony/M
 aliveness/M
 aliyah/M
 aliyahs
-alkali/M
+alkali/MS
 alkalies
 alkaline
 alkalinity/M
 alkalize/DSG
 alkaloid/SM
 alkyd/MS
 all/M
 allay/GDS
@@ -11468,16 +11579,17 @@ ambassador/SM
 ambassadorial
 ambassadorship/MS
 ambassadress/MS
 amber/M
 ambergris/M
 ambiance/MS
 ambidexterity/M
 ambidextrous/Y
+ambience/MS
 ambient
 ambiguity/SM
 ambiguous/UY
 ambit
 ambition/MS
 ambitious/YP
 ambitiousness/M
 ambivalence/M
@@ -11492,16 +11604,20 @@ ambulancemen
 ambulancewoman
 ambulancewomen
 ambulant
 ambulate/DSXGN
 ambulation/M
 ambulatory/SM
 ambuscade/MGDS
 ambush/GMDS
+ameba/MS
+amebae
+amebic
+ameboid
 ameliorate/GNVDS
 amelioration/M
 amen/B
 amenability/M
 amenably
 amend/BLGDS
 amendment/SM
 amenity/SM
@@ -11513,18 +11629,20 @@ amiability/M
 amiable
 amiably
 amicability/M
 amicable
 amicably
 amid
 amide/MS
 amidships
+amidst
 amigo/MS
 amino
+amir/SM
 amiss
 amity/M
 ammeter/SM
 ammo/M
 ammonia/M
 ammonium
 ammunition/M
 amnesia/M
@@ -11563,21 +11681,23 @@ amphitheater/SM
 amphora/M
 amphorae
 ampicillin
 ample/TR
 amplification/M
 amplifier/M
 amplify/NDRSXZG
 amplitude/SM
+ampoule/MS
 ampule/MS
 amputate/GNDSX
 amputation/M
 amputee/MS
 amt
+amuck
 amulet/MS
 amuse/LGDS
 amusement/MS
 amusing/Y
 amylase/M
 an/CS
 anabolism/M
 anachronism/SM
@@ -11599,16 +11719,17 @@ analogousness/M
 analogue/SM
 analogy/SM
 analysand/MS
 analyses/A
 analysis/AM
 analyst/SM
 analytic
 analytical/Y
+analyticalally
 analyzable
 analyze/ADSG
 analyzer/SM
 anapest/SM
 anapestic/MS
 anarchic
 anarchically
 anarchism/M
@@ -11812,16 +11933,17 @@ anti/SM
 antiabortion
 antiabortionist/MS
 antiaircraft
 antibacterial/MS
 antibiotic/MS
 antibody/SM
 antic/MS
 anticancer
+antichrist/SM
 anticipate/GNXDS
 anticipated/U
 anticipation/M
 anticipatory
 anticked
 anticking
 anticlerical
 anticlimactic
@@ -12018,16 +12140,18 @@ applicability/M
 applicable/I
 applicably
 applicant/SM
 application/AM
 applicator/SM
 applier/MS
 applique/DSM
 appliqueing
+appliqué/SMG
+appliquéd
 apply/ANXGDS
 appoint/AELSVGD
 appointee/SM
 appointment's/A
 appointment/ESM
 apportion/AGDLS
 apportionment/AM
 appose/GDS
@@ -12131,23 +12255,27 @@ archangel/MS
 archbishop/SM
 archbishopric/SM
 archdeacon/SM
 archdiocesan
 archdiocese/MS
 archduchess/MS
 archduke/MS
 archenemy/SM
+archeological/Y
+archeologist/SM
+archeology/M
 archer/M
 archery/M
 archetypal
 archetype/MS
 archfiend/MS
 archiepiscopal
 archipelago/MS
+archipelagoes
 architect/SM
 architectonic/S
 architectonics/M
 architectural/Y
 architecture/MS
 architrave/SM
 archival
 archive/DSMG
@@ -12517,16 +12645,17 @@ atrociousness/M
 atrocity/SM
 atrophy/DSMG
 atropine/M
 attach/ALGDS
 attache/BM
 attached/U
 attachment/AM
 attachments
+attaché/MS
 attack/ZGMDRS
 attacker/M
 attain/AGDS
 attainability/M
 attainable/U
 attainder/M
 attainment/SM
 attar/M
@@ -12602,16 +12731,17 @@ augur/GMDS
 augury/SM
 august/PTRY
 augustness/M
 auk/SM
 aunt/SM
 auntie/SM
 aura/MS
 aural/Y
+aureola/M
 aureole/SM
 auricle/SM
 auricular
 aurora/SM
 auscultate/GNDSX
 auscultation/M
 auspice/SM
 auspicious/IY
@@ -12747,16 +12877,17 @@ awfulness/M
 awhile
 awkward/RYPT
 awkwardness/M
 awl/SM
 awn/GJSM
 awning/M
 awoke
 awoken
+awol
 awry
 ax/MDSG
 axial/Y
 axiom/SM
 axiomatic
 axiomatically
 axis/M
 axle/MS
@@ -12878,17 +13009,18 @@ bactericide/SM
 bacteriologic
 bacteriological
 bacteriologist/SM
 bacteriology/M
 bacterium/M
 bad/MYP
 badder
 baddest
-baddie/MS
+baddie/M
+baddy/SM
 bade
 badge/MZRS
 badger/GMD
 badinage/M
 badlands/M
 badman/M
 badmen
 badminton/M
@@ -12988,25 +13120,27 @@ bamboo/SM
 bamboozle/DSG
 ban/SM
 banal/Y
 banality/SM
 banana/SM
 band's
 band/ESGD
 bandage/DSMG
+bandana/SM
 bandanna/MS
 bandbox/MS
 bandeau/M
 bandeaux
 bandit/SM
 banditry/M
 bandleader/S
 bandmaster/SM
 bandoleer/SM
+bandolier/SM
 bandsman/M
 bandsmen
 bandstand/SM
 bandwagon/SM
 bandwidth
 bandwidths
 bandy/DRSTG
 bane/SM
@@ -13044,16 +13178,17 @@ bantering/Y
 banyan/SM
 banzai/SM
 baobab/SM
 bap/S
 baptism/MS
 baptismal
 baptist/S
 baptistery/SM
+baptistry/SM
 baptize/ZGDRS
 baptized/U
 baptizer/M
 bar's
 bar/ECUTS
 barb/SZGMDR
 barbarian/SM
 barbarianism/MS
@@ -13125,16 +13260,18 @@ barony/SM
 baroque/M
 barque/SM
 barrack/MDGS
 barracuda/SM
 barrage/MGDS
 barre/MGJDS
 barred/UEC
 barrel/GSMD
+barrelled
+barrelling
 barren/TPSMR
 barrenness/M
 barrette/SM
 barricade/MGDS
 barrier/MS
 barring/ECU
 barrio/SM
 barrister/MS
@@ -13204,34 +13341,37 @@ bathhouse/MS
 bathing/M
 bathmat/MS
 bathos/M
 bathrobe/SM
 bathroom/SM
 baths
 bathtub/MS
 bathwater
-bathyscaphe/SM
+bathyscaph/MS
+bathyscaphe/M
+bathyscaphs
 bathysphere/MS
 batik/MS
 batiste/M
 batman/M
 batmen
 baton/MS
 batsman/M
 batsmen
 battalion/SM
 batted
 batten/GSMD
 batter/JZGSMDR
 batterer/M
 battery/SM
 batting/M
 battle/LDRSMZG
-battleaxe/MS
+battleax/MS
+battleaxe/M
 battledore/SM
 battledress
 battlefield/MS
 battlefront/MS
 battleground/MS
 battlement/SM
 battler/M
 battleship/SM
@@ -13304,16 +13444,17 @@ beau/SM
 beaut/MS
 beauteous/Y
 beautician/SM
 beautification/M
 beautifier/M
 beautiful/Y
 beautify/NDRSZG
 beauty/SM
+beaux
 beaver/SGMD
 bebop/MS
 becalm/GSD
 became
 because
 beck/SM
 beckon/SGD
 becloud/GDS
@@ -13620,16 +13761,18 @@ bey/SM
 beyond
 bezel/MS
 bf
 bhaji
 bi/SMRZ
 biannual/Y
 bias/GMDS
 biased/U
+biassed
+biassing
 biathlon/SM
 bib/SM
 bible/MS
 biblical
 bibliographer/MS
 bibliographic
 bibliographical/Y
 bibliography/SM
@@ -13728,17 +13871,18 @@ bimonthly/SM
 bin/SM
 binary/SM
 bind's
 bind/AUGS
 binder/MS
 bindery/SM
 binding/MS
 bindweed/M
-binge/MDS
+binge/MGDS
+bingeing
 bingo/M
 binman
 binmen
 binnacle/SM
 binned
 binning
 binocular/MS
 binomial/SM
@@ -13889,16 +14033,17 @@ blacktopping
 bladder/MS
 blade/MDS
 blag/S
 blagged
 blagging
 blah/M
 blahs/M
 blame/BMGDRS
+blameable
 blameless/YP
 blamelessness/M
 blameworthiness/M
 blameworthy/P
 blammo
 blanch/GDS
 blancmange/MS
 bland/PTRY
@@ -13913,16 +14058,17 @@ blarney/SMDG
 blase
 blaspheme/ZGDRS
 blasphemer/M
 blasphemous/Y
 blasphemy/SM
 blast/ZGMDRS
 blaster/M
 blastoff/MS
+blasé
 blat/S
 blatancy/SM
 blatant/Y
 blather/SMDG
 blaze/MZGDRS
 blazer/M
 blazon/MDGS
 bldg
@@ -14050,34 +14196,37 @@ blower/M
 blowfly/SM
 blowgun/MS
 blowhard/MS
 blowhole/S
 blowlamp/S
 blown
 blowout/SM
 blowpipe/SM
+blowsy/RT
 blowtorch/MS
 blowup/MS
 blowy/TR
 blowzy/RT
 blubber/GSMD
 blubbery
 bludgeon/MDGS
 blue/DRSPMTG
 bluebell/MS
 blueberry/SM
 bluebird/MS
 bluebonnet/SM
 bluebottle/SM
 bluefish/MS
 bluegill/MS
 bluegrass/M
+blueing/M
 blueish
 bluejacket/SM
+bluejay/SM
 bluejeans/M
 blueness/M
 bluenose/MS
 bluepoint/MS
 blueprint/MDGS
 bluestocking/SM
 bluesy/RT
 bluet/MS
@@ -14138,16 +14287,18 @@ bobolink/SM
 bobsled/SM
 bobsledded
 bobsledder/MS
 bobsledding
 bobsleigh/M
 bobsleighs
 bobtail/SM
 bobwhite/MS
+bocce/M
+bocci/M
 boccie/M
 bock/M
 bod/SMDG
 bodacious
 bode/S
 bodega/MS
 bodge/GDS
 bodice/MS
@@ -14194,17 +14345,19 @@ bolero/MS
 bolivar/MS
 bolivares
 boll/SM
 bollard/S
 bollix/GMDS
 bollocking/S
 bollocks
 bologna/M
+bolshevik/SM
 bolshie
+bolshy
 bolster/GMDS
 bolt's
 bolt/USGD
 bolthole/S
 bolus/MS
 bomb/SJZGMDR
 bombard/GDLS
 bombardier/MS
@@ -14245,16 +14398,17 @@ bonk/SZGD
 bonnet/MS
 bonny/TR
 bonobo/MS
 bonsai/M
 bonus/MS
 bony/PTR
 boo/SMDHG
 boob/SGMD
+booboo/MS
 booby/SM
 boodle/MS
 booger/S
 boogeyman/M
 boogeymen
 boogie/MDS
 boogieing
 boogieman/M
@@ -14297,16 +14451,17 @@ boorishness/MS
 boost/ZGMDRS
 booster/M
 boot's
 boot/ASGD
 bootblack/SM
 bootee/MS
 booth/M
 booths
+bootie/M
 bootlace/S
 bootleg/MS
 bootlegged
 bootlegger/MS
 bootlegging/M
 bootless
 bootstrap/MS
 bootstrapped
@@ -14331,28 +14486,30 @@ boring/Y
 born/IAU
 borne
 boron/M
 borough/M
 boroughs
 borrow/SDRZGJ
 borrower/M
 borrowing/M
+borsch/M
 borscht/M
 borstal/S
 borzoi/SM
 bosh/M
 bosom's
 bosom/US
 bosomy
 boss/DSGM
 bossily
 bossiness/M
 bossism/M
 bossy/RTP
+bosun/SM
 bot/S
 botanic
 botanical/Y
 botanist/SM
 botany/M
 botch/DRSZGM
 botcher/M
 both
@@ -14397,16 +14554,17 @@ bounty/SM
 bouquet/SM
 bourbon/SM
 bourgeois/M
 bourgeoisie/M
 boustrophedon
 bout/MS
 boutique/SM
 boutonniere/MS
+boutonnière/MS
 bouzouki/MS
 bovine/SM
 bovver
 bow/ZGSMDR
 bowdlerization/MS
 bowdlerize/DSG
 bowed/U
 bowel/SM
@@ -14530,16 +14688,17 @@ breadth/M
 breadths
 breadwinner/SM
 break/BMZGRS
 breakable/MS
 breakage/MS
 breakaway/MS
 breakdown/MS
 breaker/M
+breakeven/M
 breakfast/MDGS
 breakfront/MS
 breakneck
 breakout/MS
 breakpoints
 breakthrough/M
 breakthroughs
 breakup/SM
@@ -14578,16 +14737,17 @@ brevet/SM
 brevetted
 brevetting
 breviary/SM
 brevity/M
 brew/MDRZGS
 brewer/M
 brewery/SM
 brewpub/SM
+briar/SM
 bribe/DRSMZG
 briber/M
 bribery/M
 brick/SMDG
 brickbat/SM
 brickie/S
 bricklayer/MS
 bricklaying/M
@@ -14639,16 +14799,17 @@ brindle/DM
 brine/M
 bring/SRZG
 bringer/M
 brininess/M
 brink/SM
 brinkmanship/M
 briny/RTP
 brioche/SM
+briquet/SM
 briquette/MS
 brisk/SDRYTGP
 brisket/SM
 briskness/M
 bristle/DSMG
 bristly/TR
 britches/M
 brittle/PRMT
@@ -14873,28 +15034,30 @@ bumpiness/M
 bumpkin/MS
 bumptious/PY
 bumptiousness/M
 bumpy/PRT
 bun/SM
 bunch/MDSG
 bunchy/RT
 bunco/SMDG
+buncombe/M
 bundle/DSMG
 bung/MDGS
 bungalow/MS
 bungee/SM
 bunghole/MS
 bungle/DRSMZG
 bungler/M
 bunion/SM
 bunk's
 bunk/CDGS
 bunker/SM
 bunkhouse/SM
+bunko/SMDG
 bunkum/M
 bunny/SM
 bunt/MDGSJ
 bunting/M
 buoy/MDGS
 buoyancy/M
 buoyant/Y
 bur/SMY
@@ -14932,16 +15095,17 @@ 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
 burr/MDGS
 burrito/MS
 burro/SM
 burrow/SMDRZG
@@ -15046,22 +15210,23 @@ bystander/MS
 byte/MS
 byway/SM
 byword/SM
 byzantine
 c/IES
 ca
 cab/SMRZ
 cabal/MS
-cabala's
+cabala/M
 caballero/MS
 cabana/SM
 cabaret/SM
 cabbage/MS
 cabbed
+cabbie/M
 cabbing
 cabby/SM
 cabdriver/SM
 cabin/MS
 cabinet/SM
 cabinetmaker/MS
 cabinetmaking/M
 cabinetry/M
@@ -15095,24 +15260,26 @@ cadence/DSM
 cadenza/SM
 cadet/MS
 cadge/ZGDRS
 cadger/M
 cadmium/M
 cadre/MS
 caducei
 caduceus/M
+caesarean/MS
 caesura/SM
 cafe/SM
 cafeteria/MS
 cafetiere/S
 caff/CS
 caffeinated
 caffeine/M
 caftan/MS
+café/SM
 cage/DSMG
 cagey
 cagier
 cagiest
 cagily
 caginess/M
 cagoule/S
 cahoot/MS
@@ -15145,25 +15312,26 @@ calculable/I
 calculate/AGNVDSX
 calculated/Y
 calculating/Y
 calculation/AM
 calculator/SM
 calculi
 calculus/M
 caldera/SM
+caldron/SM
 calendar/MDGS
 calender's
 calf/M
 calfskin/M
 caliber/SM
 calibrate/GNDSX
 calibration/M
 calibrator/SM
-calico/M
+calico/MS
 calicoes
 californium/M
 caliper/SGMD
 caliph/M
 caliphate/MS
 caliphs
 calisthenic/S
 calisthenics/M
@@ -15204,27 +15372,28 @@ cam/SM
 camaraderie/M
 camber/MDSG
 cambial
 cambium/SM
 cambric/M
 camcorder/SM
 came
 camel/MS
-camelhair
+camelhair/M
 camellia/MS
 cameo/MS
 camera/MS
 cameraman/M
 cameramen
 camerawoman/M
 camerawomen
 camerawork
 camiknickers
 camisole/SM
+camomile/SM
 camouflage/MZGDRS
 camouflager/M
 camp's
 camp/CSGD
 campaign/SMDRZG
 campaigner/M
 campanile/SM
 campanologist/MS
@@ -15239,23 +15408,26 @@ campus/MS
 campy/TR
 camshaft/SM
 can't
 can/SMDRZG
 canal/MS
 canalization/M
 canalize/GDS
 canape/MS
+canapé/MS
 canard/MS
 canary/SM
 canasta/M
 cancan/MS
 cancel/DRSZG
 canceler/M
 cancellation/SM
+cancelled
+cancelling
 cancer/MS
 cancerous
 candelabra/SM
 candelabrum/M
 candid/YP
 candida
 candidacy/SM
 candidate/MS
@@ -15388,17 +15560,19 @@ captor/MS
 capture/ADSMG
 car/SMDRZG
 carafe/MS
 caramel/SM
 caramelize/DSG
 carapace/SM
 carat/MS
 caravan/SM
+caravansarai/S
 caravansary/SM
+caravanserai/M
 caravel/SM
 caraway/SM
 carbide/SM
 carbine/SM
 carbohydrate/SM
 carbolic
 carbon/MS
 carbonaceous
@@ -15472,16 +15646,18 @@ carjacker/M
 carjacking/M
 carload/SM
 carmine/SM
 carnage/M
 carnal/Y
 carnality/M
 carnation/IMS
 carnelian/MS
+carney/MS
+carnie/M
 carnival/MS
 carnivora
 carnivore/SM
 carnivorous/PY
 carnivorousness/M
 carny/SM
 carob/MS
 carol/ZGMDRS
@@ -15599,16 +15775,18 @@ cataclysm/MS
 cataclysmal
 cataclysmic
 catacomb/SM
 catafalque/MS
 catalepsy/M
 cataleptic/MS
 catalog/ZGSMDR
 cataloger/M
+catalogue/DSMG
+catalogued/U
 catalpa/SM
 catalyses
 catalysis/M
 catalyst/MS
 catalytic/M
 catalyze/GDS
 catamaran/SM
 catapult/GMDS
@@ -15657,16 +15835,17 @@ catholicity/M
 cation/MS
 catkin/MS
 catlike
 catnap/MS
 catnapped
 catnapping
 catnip/M
 catsuit/S
+catsup/MS
 cattail/SM
 catted
 cattery/S
 cattily
 cattiness/M
 catting
 cattle/M
 cattleman/M
@@ -15932,16 +16111,17 @@ chap/SM
 chaparral/SM
 chapati/S
 chapatti/S
 chapbook/MS
 chapeau/SM
 chapel/MS
 chaperon/MDGS
 chaperonage/M
+chaperone/SM
 chaperoned/U
 chaplain/MS
 chaplaincy/SM
 chaplet/SM
 chapped
 chapping
 chappy/S
 chapter/SM
@@ -16159,16 +16339,17 @@ children
 chili/M
 chilies
 chill/JPZTGMDRS
 chiller/M
 chilliness/M
 chilling/Y
 chillness/M
 chilly/TPR
+chimaera/MS
 chime/MZGDRS
 chimer/M
 chimera/MS
 chimeric
 chimerical
 chimney/MS
 chimp/MS
 chimpanzee/SM
@@ -16201,28 +16382,33 @@ chiropody/M
 chiropractic/SM
 chiropractor/SM
 chirp/GMDS
 chirpily
 chirpy/PTR
 chirrup/GMDS
 chisel/ZGMDRS
 chiseler/M
+chiselled
+chiseller/MS
+chiselling
 chit/SM
 chitchat/SM
 chitchatted
 chitchatting
 chitin/M
 chitinous
+chitlins/M
 chitosan
 chitterlings/M
 chivalrous/PY
 chivalrousness/M
 chivalry/M
 chive/MS
+chivvy/GDS
 chivy/GDS
 chlamydia/MS
 chlamydiae
 chloral/M
 chlordane/M
 chloride/MS
 chlorinate/GNDS
 chlorination/M
@@ -16232,16 +16418,17 @@ chloroform/SGMD
 chlorophyll/M
 chloroplast/MS
 chm
 choc/S
 chock/GMDS
 chockablock
 chocoholic/SM
 chocolate/MS
+chocolatey
 chocolaty
 choice/MTRS
 choir/MS
 choirboy/MS
 choirmaster/SM
 choke/MZGDRS
 chokecherry/SM
 choker/M
@@ -16346,16 +16533,19 @@ churl/MS
 churlish/PY
 churlishness/M
 churn/ZGMDRS
 churner/M
 chute/MS
 chutney/MS
 chutzpah/M
 chyme/M
+château/M
+châteaux
+châtelaine/SM
 ciabatta/SM
 ciao/S
 cicada/MS
 cicatrices
 cicatrix/M
 cicerone/SM
 ciceroni
 cider's
@@ -16430,16 +16620,17 @@ cite's
 cite/IAGSD
 citified
 citizen/MS
 citizenry/M
 citizenship/M
 citric
 citron/MS
 citronella/M
+citrous
 citrus/MS
 city/SM
 citywide
 civet/MS
 civic/S
 civics/M
 civil/UY
 civilian/MS
@@ -16494,16 +16685,17 @@ clapperboard/S
 clapping/M
 claptrap/M
 claque/MS
 claret/MS
 clarification/M
 clarify/XDSNG
 clarinet/SM
 clarinetist/SM
+clarinettist/MS
 clarion/MDGS
 clarity/M
 clash/GMDS
 clasp's
 clasp/UGDS
 class/GMDS
 classic/MS
 classical/MY
@@ -16575,20 +16767,23 @@ clerical/Y
 clericalism/M
 clerk/GMDS
 clerkship/M
 clever/PTRY
 cleverness/M
 clevis/MS
 clew/SGMD
 cliche/MDS
+cliché/MS
+clichéd
 click/BZGMDRS
 clicker/M
 client/MS
 clientele/MS
+clientèle/MS
 cliff/MS
 cliffhanger/SM
 cliffhanging
 clifftop/S
 clii
 climacteric/M
 climactic
 climate/SM
@@ -16642,16 +16837,17 @@ clockwork/SM
 clod/MS
 cloddish
 clodhopper/MS
 clog's
 clog/US
 clogged/U
 clogging/U
 cloisonne/M
+cloisonné/M
 cloister/SMDG
 cloistral
 clomp/SDG
 clonal
 clone/DSMG
 clonk/SMDG
 clop/MS
 clopped
@@ -16883,17 +17079,17 @@ cohere/DSG
 coherence/IM
 coherency/M
 coherent/IY
 cohesion/M
 cohesive/YP
 cohesiveness/M
 coho/MS
 cohort/SM
-coif/MS
+coif/MDGS
 coiffed
 coiffing
 coiffure/DSMG
 coil's/A
 coil/UADGS
 coin/MDRZGS
 coinage/SM
 coincide/DSG
@@ -16936,16 +17132,17 @@ collarless
 collate/DSXGN
 collateral/MY
 collateralize
 collation/M
 collator/MS
 colleague/MS
 collect's
 collect/ASGVD
+collectable/MS
 collected/U
 collectedly
 collectible/SM
 collection/AMS
 collective/MYS
 collectivism/M
 collectivist/SM
 collectivization/M
@@ -17284,16 +17481,17 @@ compunction/SM
 computation/SM
 computational/Y
 compute/ADSG
 computer/MS
 computerate
 computerization/M
 computerize/GDS
 computing/M
+compère/DSG
 comrade/SMY
 comradeship/M
 con/GSM
 concatenate/XDSGN
 concatenation/M
 concave/YP
 concaveness/M
 conceal/SDRZGBL
@@ -17399,17 +17597,17 @@ conductance/M
 conductibility/M
 conductible
 conduction/M
 conductivity/M
 conductor/MS
 conductress/MS
 conduit/SM
 cone/M
-coneys
+coney/SM
 confab/SM
 confabbed
 confabbing
 confabulate/XDSGN
 confabulation/M
 confection/SZMR
 confectioner/M
 confectionery/SM
@@ -17459,16 +17657,17 @@ conform/ZB
 conformable/U
 conformance/M
 conformism/M
 conformist/SM
 conformity/M
 confrere/MS
 confrontation/SM
 confrontational
+confrère/SM
 confuse/RZ
 confused/Y
 confusing/Y
 confutation/M
 confute/DSG
 conga/SMDG
 congeal/SLDG
 congealment/M
@@ -17591,16 +17790,17 @@ consolable/I
 consolation/MS
 consolatory
 consolidate/XDSGN
 consolidated/U
 consolidation/M
 consolidator/MS
 consoling/Y
 consomme/M
+consommé/M
 consonance/SM
 consonant/SMY
 consortia
 consortium/M
 conspectus/MS
 conspicuous/IPY
 conspicuousness/IM
 conspiracy/SM
@@ -17781,16 +17981,17 @@ convalescent/SM
 convection/M
 convectional
 convective
 convector/S
 convene/ADSG
 convener/MS
 convenience/IMS
 convenient/IY
+convenor/MS
 convent/SM
 conventicle/MS
 convention/SM
 conventional/UY
 conventionality/UM
 conventionalize/GDS
 conventioneer/S
 convergence/MS
@@ -17801,16 +18002,17 @@ conversational/Y
 conversationalist/SM
 converse/Y
 convert's
 convert/AGSD
 converted/U
 converter/SM
 convertibility/M
 convertible/SM
+convertor/SM
 convex/Y
 convexity/M
 convey/SBDG
 conveyance/MGS
 conveyor/MS
 convict/GSMD
 conviction/MS
 convince/GDS
@@ -17820,29 +18022,30 @@ convivial/Y
 conviviality/M
 convoke/DSG
 convoluted
 convolution/MS
 convoy/SMDG
 convulse/GNVXDS
 convulsion/M
 convulsive/Y
-cony/M
+cony/SM
 coo/GSMD
 cook's
 cook/ADGS
 cookbook/MS
 cooked/U
 cooker/SM
 cookery/SM
 cookhouse/S
-cookie/SM
+cookie/M
 cooking/M
 cookout/SM
 cookware/SM
+cooky/SM
 cool/MDRYZTGPS
 coolant/SM
 cooler/M
 coolie/SM
 coolness/M
 coon/MS!
 coonskin/MS
 coop/MDRZGS
@@ -18009,16 +18212,17 @@ corruptness/M
 corsage/MS
 corsair/MS
 corset/SGMD
 cortege/MS
 cortex/M
 cortical
 cortices
 cortisone/M
+cortège/SM
 corundum/M
 coruscate/GNDS
 coruscation/M
 corvette/SM
 cos/M
 cosh/DSG
 cosign/ZGSDR
 cosignatory/SM
@@ -18078,16 +18282,17 @@ cougar/SM
 cough/MDG
 coughs
 could
 could've
 couldn't
 coulee/SM
 coulis
 coulomb/MS
+coulée/SM
 council/MS
 councilman/M
 councilmen
 councilor/MS
 councilperson/SM
 councilwoman/M
 councilwomen
 counsel/JMDGS
@@ -18192,16 +18397,17 @@ cover's
 cover/AEUGDS
 coverage/M
 coverall/MS
 covering's
 coverings
 coverlet/MS
 covert/SPMY
 covertness/M
+coverup/MS
 covet/SDG
 covetous/YP
 covetousness/M
 covey/SM
 cow/ZGSMDR
 coward/SMY
 cowardice/M
 cowardliness/M
@@ -18517,28 +18723,31 @@ crow/MDGS
 crowbar/MS
 crowd/SMDG
 crowded/U
 crowdfund/SDG
 crowfeet
 crowfoot/SM
 crown/SMDG
 crowned/U
+crozier/MS
+croûton/MS
 crucial/Y
 crucible/SM
 crucifix/MS
 crucifixion/SM
 cruciform/SM
 crucify/DSG
 crud/M
 cruddy/TR
 crude/RMYTP
 crudeness/M
 crudites/M
 crudity/SM
+crudités/M
 cruel/RYPT
 cruelness/M
 cruelty/SM
 cruet/SM
 cruft/SD
 crufty
 cruise/DRSMZG
 cruiser/M
@@ -18583,16 +18792,17 @@ cryptogram/SM
 cryptographer/SM
 cryptography/M
 crystal/SM
 crystalline
 crystallization/M
 crystallize/ADSG
 crystallographic
 crystallography
+crèche/MS
 ct
 ctn
 ctr
 cu
 cub/ZGSMDR
 cubbyhole/MS
 cube/MS
 cuber/M
@@ -18611,16 +18821,17 @@ cud/SM
 cuddle/DSMG
 cuddly/TR
 cudgel/SGMDJ
 cue/DSMG
 cuff/MDGS
 cuisine/SM
 culinary
 cull/MDGS
+cullender/MS
 culminate/XDSGN
 culmination/M
 culotte/SM
 culpability/M
 culpable/I
 culpably
 culprit/SM
 cult/MS
@@ -18667,16 +18878,17 @@ cur/SMY
 curability/M
 curacao
 curacy/SM
 curare/M
 curate/DSMGV
 curative/MS
 curator/KMS
 curatorial
+curaçao
 curb/MDGS
 curbing/M
 curbside
 curbstone/SM
 curd/MS
 curdle/DSG
 cure's
 cure/KZGBDRS
@@ -18773,43 +18985,46 @@ cuttlefish/MS
 cutup/SM
 cutworm/MS
 cw
 cwt
 cyan/M
 cyanide/M
 cyberbully/S
 cybercafe/S
+cybercafé/S
 cybernetic/S
 cybernetics/M
 cyberpunk/SM
 cybersex
 cyberspace/MS
 cyborg/SM
 cyclamen/MS
 cycle/ADSMG
 cyclic
 cyclical/Y
 cyclist/MS
 cyclometer/MS
 cyclone/MS
 cyclonic
+cyclopaedia/MS
 cyclopedia/MS
 cyclopes
 cyclops/M
 cyclotron/MS
 cygnet/MS
 cylinder/MS
 cylindrical
 cymbal/MS
 cymbalist/MS
 cynic/SM
 cynical/Y
 cynicism/M
 cynosure/MS
+cypher/M
 cypress/MS
 cyst/MS
 cystic
 cystitis
 cytologist/SM
 cytology/M
 cytoplasm/M
 cytoplasmic
@@ -18832,17 +19047,17 @@ dace/SM
 dacha/MS
 dachshund/MS
 dactyl/MS
 dactylic/MS
 dad/SM
 dadaism/M
 dadaist/MS
 daddy/SM
-dado/M
+dado/SM
 dadoes
 daemon/MS
 daemonic
 daffiness/M
 daffodil/SM
 daffy/PTR
 daft/PTRY
 daftness/M
@@ -19009,16 +19224,17 @@ dealer/M
 dealership/SM
 dealing/M
 dealt
 dean/M
 deanery/SM
 deanship/M
 dear/SPTMRYH
 dearest/S
+dearie/M
 dearness/M
 dearth/M
 dearths
 deary/SM
 death/MY
 deathbed/SM
 deathblow/MS
 deathless/Y
@@ -19383,16 +19599,17 @@ denounce/LDSG
 denouncement/SM
 dense/PYTR
 denseness/M
 density/SM
 dent/ISGMD
 dental/Y
 dentifrice/SM
 dentin/M
+dentine/M
 dentist/MS
 dentistry/M
 dentition/M
 denture/IMS
 denuclearize/GDS
 denudation/M
 denude/GDS
 denunciation/SM
@@ -19475,16 +19692,17 @@ dermatology/M
 dermis/M
 derogate/DSGN
 derogation/M
 derogatorily
 derogatory
 derrick/SM
 derriere/SM
 derringer/SM
+derrière/SM
 derv
 dervish/MS
 desalinate/GNDS
 desalination/M
 desalinization/M
 desalinize/GDS
 descant/M
 descend/FGDS
@@ -19502,16 +19720,17 @@ desecrate/DSGN
 desecration/M
 deselection
 desert/SDRZGM
 deserter/M
 desertification
 desertion/SM
 deserved/UY
 deserving/U
+deshabille/M
 desiccant/SM
 desiccate/DSGN
 desiccation/M
 desiccator/SM
 desiderata
 desideratum/M
 design/ASDG
 designate/DSGNX
@@ -19690,16 +19909,17 @@ dialectics/M
 dialing/S
 dialog
 dialogue/SM
 dialyses
 dialysis/M
 dialyzes
 diam
 diamante
+diamanté
 diameter/SM
 diametric
 diametrical/Y
 diamond/SM
 diamondback/MS
 diapason/SM
 diaper/SMDG
 diaphanous
@@ -19725,16 +19945,17 @@ dicey
 dichotomous
 dichotomy/SM
 dicier
 diciest
 dick/MRXZS
 dicker/DG
 dickey/SM
 dickhead/S
+dicky/SM
 dickybird/S
 dicotyledon/MS
 dicotyledonous
 dict
 dicta
 dictate/DSMGNX
 dictation/M
 dictator/SM
@@ -19748,29 +19969,31 @@ didactic
 didactically
 diddle/DRSZG
 diddler/M
 diddly
 diddlysquat
 diddums
 didgeridoo/S
 didn't
-dido/M
+dido/MS
 didoes
 didst
 die/DSM
+diehard/SM
 dielectric/MS
 diereses
 dieresis/M
 diesel/SMDG
 diet/MDRZGS
 dietary/SM
 dieter/M
 dietetic/S
 dietetics/M
+dietician/MS
 dietitian/MS
 diff/DRZGS
 differ/DG
 difference/IM
 differences
 different/IY
 differential/SM
 differentiate/DSGN
@@ -19836,16 +20059,17 @@ dilution/M
 dim/PSRY
 dime/MS
 dimension/SM
 dimensional
 dimensionless
 diminish/GDS
 diminished/U
 diminuendo/SM
+diminuendoes
 diminution/SM
 diminutive/SM
 dimity/M
 dimmed/U
 dimmer/SM
 dimmest
 dimming
 dimness/M
@@ -19855,16 +20079,17 @@ dimwit/SM
 dimwitted
 din/ZGSMDR
 dinar/SM
 dine/S
 diner/M
 dinette/MS
 ding/MDG
 dingbat/MS
+dingdong/SGMD
 dinghy/SM
 dingily
 dinginess/M
 dingle/SM
 dingo/M
 dingoes
 dingus/MS
 dingy/RPT
@@ -20168,18 +20393,20 @@ disturbing/Y
 disunion/M
 disyllabic
 ditch/MDSG
 dither/SMDRZG
 ditherer/M
 ditransitive
 ditsy
 ditto/SMDG
+dittoes
 ditty/SM
 ditz/MS
+ditzy/R
 diuretic/MS
 diurnal/Y
 div
 diva/MS
 divalent
 divan/SM
 dive/MZTGDRS
 diver/M
@@ -20212,24 +20439,26 @@ divisible/I
 division/MS
 divisional
 divisive/PY
 divisiveness/M
 divisor/SM
 divorce/DSLMG
 divorcee/MS
 divorcement/MS
+divorcée/MS
 divot/SM
 divulge/GDS
 divvy/DSMG
 dixieland/M
 dizzily
 dizziness/M
 dizzy/DRSPTG
 djellaba/MS
+djellabahs
 do/SJMRHZG
 doable
 dob/S
 dobbed
 dobbin/SM
 dobbing
 doberman/MS
 dobro
@@ -20267,24 +20496,26 @@ doer/M
 does/AU
 doeskin/MS
 doesn't
 doff/DGS
 dog/SM
 dogcart/SM
 dogcatcher/SM
 doge/MS
-dogeared
+dogear/SMDG
 dogfight/SM
 dogfish/MS
 dogged/PY
 doggedness/M
 doggerel/M
+doggie/M
 dogging
-doggone/TGRS
+doggone/TGDRS
+doggoned/TR
 doggy/RSMT
 doghouse/SM
 dogie/SM
 dogleg/SM
 doglegged
 doglegging
 dogma/SM
 dogmatic
@@ -20292,16 +20523,17 @@ dogmatically
 dogmatism/M
 dogmatist/SM
 dogsbody/S
 dogsled/S
 dogtrot/MS
 dogtrotted
 dogtrotting
 dogwood/MS
+doh/M
 doily/SM
 doing/USM
 doldrums/M
 dole's
 dole/FGDS
 doleful/YP
 dolefulness/M
 doll/MDGS
@@ -20388,16 +20620,17 @@ dopamine
 dope/MZGDRS
 doper/M
 dopey
 dopier
 dopiest
 dopiness/M
 doping/M
 doppelganger/S
+doppelgänger/S
 dork/MS
 dorky/RT
 dorm/MRZS
 dormancy/M
 dormant
 dormer/M
 dormice
 dormitory/SM
@@ -20603,16 +20836,17 @@ driblet/MS
 drier/M
 drift/SMDRZG
 drifter/M
 driftnet/S
 driftwood/M
 drill/SMDRZG
 driller/M
 drillmaster/SM
+drily
 drink/SMRBJZG
 drinkable/U
 drinker/M
 drip/MS
 dripped
 dripping/SM
 drippy/TR
 drive/RSMZGJ
@@ -20716,17 +20950,18 @@ duct's/K
 duct/CKIFS
 ductile
 ductility/M
 ducting
 ductless
 dud/GSMD
 dude/MS
 dudgeon/M
-due/SM
+due's
+due/IS
 duel/MDRJZGS
 dueler/M
 duelist/SM
 duenna/MS
 duet/MS
 duff/MDRZGS
 duffer/M
 dug
@@ -20848,16 +21083,23 @@ dysfunctional
 dyslectic/SM
 dyslexia/M
 dyslexic/SM
 dyspepsia/M
 dyspeptic/MS
 dysprosium/M
 dystonia
 dz
+débutante/SM
+décolletage/SM
+décolleté
+démodé
+dérailleur/MS
+déshabillé/M
+détente/M
 e'en
 e'er
 e/FDST
 eBay/M
 eMusic/M
 ea
 each
 eager/PTRY
@@ -20987,16 +21229,17 @@ ecumenism/M
 eczema/M
 ed/ACSM
 edamame
 eddy/DSMG
 edelweiss/M
 edema/SM
 edge/MZGJDRS
 edger/M
+edgeways
 edgewise
 edgily
 edginess/M
 edging/M
 edgy/RTP
 edibility/M
 edible/SMP
 edibleness/M
@@ -21360,16 +21603,17 @@ emolument/MS
 emote/XDSGNV
 emoticon/SM
 emotion/M
 emotional/UY
 emotionalism/M
 emotionalize/GDS
 emotionless
 emotive/Y
+empanel/GDS
 empathetic
 empathize/DSG
 empathy/M
 emperor/MS
 emphases
 emphasis/M
 emphasize/AGDS
 emphatic/U
@@ -21648,23 +21892,25 @@ entrenchment/MS
 entrepreneur/SM
 entrepreneurial
 entrepreneurship
 entropy/M
 entrust/SGD
 entry/ASM
 entryphone/S
 entryway/MS
+entrée/MS
 entwine/DSG
 enumerable
 enumerate/DSGNX
 enumeration/M
 enumerator/SM
 enunciate/DSGN
 enunciation/M
+enure/DSG
 enuresis/M
 envelop/SLDRZG
 envelope/SM
 enveloper/M
 envelopment/M
 envenom/SDG
 enviable/U
 enviably
@@ -21859,17 +22105,17 @@ eschatology
 eschew/SDG
 escort/SMDG
 escritoire/MS
 escrow/SM
 escudo/SM
 escutcheon/SM
 esophageal
 esophagi
-esophagus/M
+esophagus/MS
 esoteric
 esoterically
 esp
 espadrille/MS
 espalier/MDSG
 especial/Y
 espionage/M
 esplanade/MS
@@ -21886,16 +22132,17 @@ essence/SM
 essential/IMS
 essentially
 establish/AESDGL
 establishment/AEM
 establishments
 estate/SM
 esteem/ESMDG
 ester/SM
+esthetic/S
 estimable/I
 estimate/MGNDSX
 estimation/M
 estimator/SM
 estrange/LDSG
 estrangement/MS
 estrogen/M
 estrous
@@ -22338,16 +22585,17 @@ ext
 extant
 extemporaneous/PY
 extemporaneousness/M
 extempore
 extemporization/M
 extemporize/GDS
 extend/SZGDRB
 extender/M
+extendible
 extensible
 extension/SM
 extensional
 extensive/YP
 extensiveness/M
 extent/SM
 extenuate/DSGN
 extenuation/M
@@ -22420,17 +22668,17 @@ exudation/M
 exude/DSG
 exult/SDG
 exultant/Y
 exultation/M
 exurb/SM
 exurban
 exurbanite/SM
 exurbia/M
-eye/DSM
+eye/DSMG
 eyeball/GMDS
 eyebrow/SM
 eyedropper/SM
 eyeful/SM
 eyeglass/MS
 eyeing
 eyelash/MS
 eyeless
@@ -22457,16 +22705,17 @@ fabrication/M
 fabricator/SM
 fabulous/Y
 facade/SM
 face's
 face/ACSDG
 facecloth/M
 facecloths
 faceless
+facelift/SM
 facet/SMDG
 facetious/YP
 facetiousness/M
 facial/SMY
 facile/Y
 facilitate/GNDS
 facilitation/M
 facilitator/MS
@@ -22496,17 +22745,17 @@ faddist/MS
 faddy/P
 fade/MS
 fading/U
 faerie/SM
 faff/DGS
 fag/SM
 fagged
 fagging
-faggot/SM
+faggot/SMG
 fagot/SMG
 faience/M
 fail/MDGJS
 failing/M
 faille/M
 failure/SM
 fain/RT
 faint/SMDRYTGP
@@ -22601,16 +22850,17 @@ fanzine/MS
 far
 farad/SM
 faradize/DG
 faraway
 farce/SM
 farcical/Y
 fare/MGDS
 farewell/SM
+farfetched
 farina/M
 farinaceous
 farm/MDRZGSJ
 farmer/M
 farmhand/SM
 farmhouse/SM
 farming/M
 farmland/MS
@@ -22703,16 +22953,17 @@ favorably/U
 favorite/SM
 favoritism/M
 fawn/MDRZGS
 fawner/M
 fax/GMDS
 fay/TSMR
 faze/GDS
 fazed/U
+faïence/M
 fealty/M
 fear/MDGS
 fearful/YP
 fearfulness/M
 fearless/PY
 fearlessness/M
 fearsome
 feasibility/M
@@ -22868,17 +23119,19 @@ few/TPMR
 fewness/M
 fey
 fez/M
 fezzes
 ff
 fiance/CM
 fiancee/MS
 fiances
-fiasco/M
+fiancé/SM
+fiancée/MS
+fiasco/SM
 fiascoes
 fiat/MS
 fib/ZSMR
 fibbed
 fibber/SM
 fibbing
 fiber/M
 fiberboard/M
@@ -23170,16 +23423,17 @@ flakiness/M
 flaky/TRP
 flamage
 flambe/MS
 flambeed
 flambeing
 flamboyance/M
 flamboyancy/M
 flamboyant/Y
+flambé/MD
 flame/DRSJMZG
 flamenco/MS
 flameproof/DGS
 flamethrower/SM
 flamingo/MS
 flammability/IM
 flammable/SM
 flan/MS
@@ -23201,16 +23455,17 @@ flashbulb/SM
 flashcard/SM
 flashcube/SM
 flasher/M
 flashgun/SM
 flashily
 flashiness/M
 flashing/M
 flashlight/MS
+flashpoint/SM
 flashy/RTP
 flask/SM
 flat/MYPS
 flatbed/SM
 flatboat/SM
 flatbread
 flatcar/SM
 flatfeet
@@ -23331,16 +23586,17 @@ floodgate/MS
 floodlight/MDSG
 floodlit
 floodplain/MS
 floodwater/MS
 floor/SMDG
 floorboard/MS
 flooring/M
 floorwalker/SM
+floozie/M
 floozy/SM
 flop/MS
 flophouse/MS
 flopped
 floppily
 floppiness/M
 flopping
 floppy/PRSMT
@@ -23436,16 +23692,17 @@ flypaper/SM
 flypast/S
 flysheet/S
 flyspeck/GMDS
 flyswatter/MS
 flytrap/S
 flyway/SM
 flyweight/SM
 flywheel/MS
+fo'c'sle/MS
 foal/MDGS
 foam/MDGS
 foaminess/M
 foamy/RTP
 fob/SM
 fobbed
 fobbing
 focal/Y
@@ -23498,16 +23755,17 @@ foment/SGD
 fomentation/M
 fond/RYTP
 fondant/MS
 fondle/DSG
 fondness/M
 fondue/SM
 font/MS
 fontanel/MS
+fontanelle/MS
 foo
 foobar
 food/MS
 foodie/SM
 foodstuff/SM
 fool/MDGS
 foolery/SM
 foolhardily
@@ -23586,16 +23844,17 @@ foreclose/DSG
 foreclosure/MS
 forecourt/SM
 foredoom/DGS
 forefather/MS
 forefeet
 forefinger/SM
 forefoot/M
 forefront/SM
+foregather/GDS
 forego/G
 foregoes
 foregone
 foreground/GMDS
 forehand/MS
 forehead/MS
 foreign/ZRP
 foreigner/M
@@ -23702,16 +23961,17 @@ former/FIAM
 formerly
 formfitting
 formic
 formidable
 formidably
 formless/PY
 formlessness/M
 formula/MS
+formulae
 formulaic
 formulate/ADSGNX
 formulated/U
 formulation/AM
 formulator/SM
 fornicate/GNDS
 fornication/M
 fornicator/MS
@@ -23821,27 +24081,29 @@ frame/DRSMZG
 framed/U
 framer/M
 framework/SM
 franc/SM
 franchise's
 franchise/EDSG
 franchisee/SM
 franchiser/SM
+franchisor/SM
 francium/M
 francophone
 frangibility/M
 frangible
 frank/SMDRYTGP
 frankfurter/MS
 frankincense/M
 frankness/M
 frantic
 frantically
 frappe/SM
+frappé/M
 frat/MS
 fraternal/Y
 fraternity/FSM
 fraternization/M
 fraternize/ZGDRS
 fraternizer/M
 fratricidal
 fratricide/MS
@@ -23852,21 +24114,23 @@ fraudulence/M
 fraudulent/Y
 fraught
 fray's
 fray/CDGS
 frazzle/MGDS
 freak/SMDG
 freakish/YP
 freakishness/M
+freakout/MS
 freaky/RT
 freckle/DSMG
 freckly
 free/YTDRS
 freebase/MGDS
+freebee/SM
 freebie/SM
 freebooter/SM
 freeborn
 freedman/M
 freedmen
 freedom/SM
 freehand
 freehold/ZMRS
@@ -24015,16 +24279,17 @@ frosty/TPR
 froth/MDG
 frothiness/M
 froths
 frothy/TPR
 froufrou/M
 froward/P
 frowardness/M
 frown/SMDG
+frowsy/TR
 frowzily
 frowziness/M
 frowzy/TPR
 froze/AU
 frozen/UA
 fructify/DSG
 fructose/M
 frugal/Y
@@ -24158,16 +24423,17 @@ furtiveness/M
 fury/SM
 furze/M
 fuse's/A
 fuse/CAIFGDS
 fusee/SM
 fuselage/SM
 fusibility/M
 fusible
+fusileer/SM
 fusilier/SM
 fusillade/MS
 fusion/IFKSM
 fuss/MDSG
 fussbudget/MS
 fussily
 fussiness/M
 fusspot/SM
@@ -24189,16 +24455,17 @@ futurology/M
 futz/DSG
 fuzz/MDSG
 fuzzball/S
 fuzzily
 fuzziness/M
 fuzzy/PTR
 fwd
 fwy
+fête/SM
 g/SNXB
 gab/SM
 gabardine/SM
 gabbed
 gabbiness/M
 gabbing
 gabble/DSMG
 gabby/RTP
@@ -24273,16 +24540,17 @@ gambol/SMDG
 game/MYTGDRSP
 gamecock/MS
 gamekeeper/MS
 gameness/M
 gamesmanship/M
 gamester/MS
 gamete/SM
 gametic
+gamey
 gamin/SM
 gamine/SM
 gaminess/M
 gaming/M
 gamma/SM
 gammon/M
 gammy
 gamut/SM
@@ -24330,24 +24598,27 @@ garlic/M
 garlicky
 garment/MS
 garner/SGD
 garnet/SM
 garnish/GLMDS
 garnishee/DSM
 garnisheeing
 garnishment/SM
+garotte/MGDS
 garret/SM
 garrison/MDSG
 garrote/MZGDRS
 garroter/M
+garrotte/MGDS
 garrulity/M
 garrulous/PY
 garrulousness/M
 garter/SM
+garçon/SM
 gas's
 gas/CS
 gasbag/SM
 gaseous
 gash/MDSG
 gasholder/S
 gasket/SM
 gaslight/MS
@@ -24438,16 +24709,17 @@ gelatinous
 gelcap/M
 geld/DJGS
 gelding/M
 gelid
 gelignite/M
 gelled
 gelling
 gem/SM
+gemmology/M
 gemological
 gemologist/MS
 gemology/M
 gemstone/MS
 gendarme/MS
 gender/MDS
 gene/MS
 genealogical/Y
@@ -24649,32 +24921,33 @@ gimp/MDGS
 gimpy
 gin/SM
 ginger/GSMDY
 gingerbread/M
 gingersnap/SM
 gingery
 gingham/M
 gingivitis/M