Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Tue, 05 Aug 2014 17:05:58 -0700
changeset 219632 6cbdd4d523a7cb521ccbe993e995e6f97dcfa5ae
parent 219536 e66e1130da318dd06853572df55373a3196f9d10 (current diff)
parent 219631 3dbc718058d2a7a3b92256455d794211e2af0f7e (diff)
child 219642 4ee966227774f51c745c8d0d32ee1206da30aa31
child 219669 3fd543e150c8cd8aba420395fd8cbdbd27919933
child 219704 7fd0966c2650ffa0d2665a4073d44c4704ee3c8e
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone34.0a1
first release with
nightly linux32
6cbdd4d523a7 / 34.0a1 / 20140806030201 / files
nightly linux64
6cbdd4d523a7 / 34.0a1 / 20140806030201 / files
nightly mac
6cbdd4d523a7 / 34.0a1 / 20140806030201 / files
nightly win32
6cbdd4d523a7 / 34.0a1 / 20140806030201 / files
nightly win64
6cbdd4d523a7 / 34.0a1 / 20140806030201 / 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 inbound to m-c a=merge
content/media/test/seek1.js
content/media/test/seek10.js
content/media/test/seek11.js
content/media/test/seek12.js
content/media/test/seek13.js
content/media/test/seek2.js
content/media/test/seek3.js
content/media/test/seek4.js
content/media/test/seek5.js
content/media/test/seek6.js
content/media/test/seek7.js
content/media/test/seek8.js
content/media/test/seek9.js
content/media/test/test_seek.html
content/media/test/test_seek2.html
modules/libjar/zipwriter/public/moz.build
modules/libjar/zipwriter/public/nsIZipWriter.idl
modules/libjar/zipwriter/src/StreamFunctions.cpp
modules/libjar/zipwriter/src/StreamFunctions.h
modules/libjar/zipwriter/src/ZipWriterModule.cpp
modules/libjar/zipwriter/src/moz.build
modules/libjar/zipwriter/src/nsDeflateConverter.cpp
modules/libjar/zipwriter/src/nsDeflateConverter.h
modules/libjar/zipwriter/src/nsZipDataStream.cpp
modules/libjar/zipwriter/src/nsZipDataStream.h
modules/libjar/zipwriter/src/nsZipHeader.cpp
modules/libjar/zipwriter/src/nsZipHeader.h
modules/libjar/zipwriter/src/nsZipWriter.cpp
modules/libjar/zipwriter/src/nsZipWriter.h
services/sync/tests/unit/test_password_mpenabled.js
--- a/accessible/mac/mozHTMLAccessible.mm
+++ b/accessible/mac/mozHTMLAccessible.mm
@@ -12,19 +12,20 @@
 
 #import "nsCocoaUtils.h"
 
 @implementation mozHeadingAccessible
 
 - (NSString*)title
 {
   nsAutoString title;
+  mozilla::ErrorResult rv;
   // XXX use the flattening API when there are available
   // see bug 768298
-  mGeckoAccessible->GetContent()->GetTextContent(title);
+  mGeckoAccessible->GetContent()->GetTextContent(title, rv);
 
   return nsCocoaUtils::ToNSString(title);
 }
 
 - (id)value
 {
   if (!mGeckoAccessible || !mGeckoAccessible->IsHyperText())
     return nil;
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -7,16 +7,19 @@
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FxAccounts.jsm");
 
 let fxAccountsCommon = {};
 Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
 
+// for master-password utilities
+Cu.import("resource://services-sync/util.js");
+
 const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash";
 const PREF_SYNC_SHOW_CUSTOMIZATION = "services.sync.ui.showCustomizationDialog";
 
 const OBSERVER_TOPICS = [
   fxAccountsCommon.ONVERIFIED_NOTIFICATION,
   fxAccountsCommon.ONLOGOUT_NOTIFICATION,
 ];
 
@@ -99,16 +102,22 @@ let wrapper = {
                   .wrappedJSObject;
 
     // Don't show about:accounts with FxA disabled.
     if (!weave.fxAccountsEnabled) {
       document.body.remove();
       return;
     }
 
+    // If a master-password is enabled, we want to encourage the user to
+    // unlock it.  Things still work if not, but the user will probably need
+    // to re-auth next startup (in which case we will get here again and
+    // re-prompt)
+    Utils.ensureMPUnlocked();
+
     let iframe = document.getElementById("remote");
     this.iframe = iframe;
     iframe.addEventListener("load", this);
 
     try {
       iframe.src = url || fxAccounts.getAccountsSignUpURI();
     } catch (e) {
       error("Couldn't init Firefox Account wrapper: " + e.message);
--- a/browser/base/content/aboutneterror/netError.css
+++ b/browser/base/content/aboutneterror/netError.css
@@ -47,17 +47,17 @@ ul {
   margin-top: 1.2em;
 }
 
 #errorContainer {
   display: none;
 }
 
 @media (max-width: 675px) {
-  #errorTitle {
+  #errorTitleText {
     padding-top: 0;
     background-image: none;
     -moz-padding-start: 0;
     -moz-margin-start: 0;
   }
 }
 
 
--- a/browser/base/content/sync/customize.js
+++ b/browser/base/content/sync/customize.js
@@ -1,25 +1,11 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-let service = Cc["@mozilla.org/weave/service;1"]
-                .getService(Ci.nsISupports)
-                .wrappedJSObject;
-
-if (!service.allowPasswordsEngine) {
-  let checkbox = document.getElementById("fxa-pweng-chk");
-  checkbox.checked = false;
-  checkbox.disabled = true;
-}
-
 addEventListener("dialogaccept", function () {
   let pane = document.getElementById("sync-customize-pane");
   pane.writePreferences(true);
   window.arguments[0].accepted = true;
 });
--- a/browser/base/content/sync/customize.xul
+++ b/browser/base/content/sync/customize.xul
@@ -40,18 +40,17 @@
 
   <vbox align="start">
       <checkbox label="&engine.tabs.label;"
                 accesskey="&engine.tabs.accesskey;"
                 preference="engine.tabs"/>
       <checkbox label="&engine.bookmarks.label;"
                 accesskey="&engine.bookmarks.accesskey;"
                 preference="engine.bookmarks"/>
-      <checkbox id="fxa-pweng-chk"
-                label="&engine.passwords.label;"
+      <checkbox label="&engine.passwords.label;"
                 accesskey="&engine.passwords.accesskey;"
                 preference="engine.passwords"/>
       <checkbox label="&engine.history.label;"
                 accesskey="&engine.history.accesskey;"
                 preference="engine.history"/>
       <checkbox label="&engine.addons.label;"
                 accesskey="&engine.addons.accesskey;"
                 preference="engine.addons"/>
--- a/browser/base/content/sync/utils.js
+++ b/browser/base/content/sync/utils.js
@@ -82,22 +82,16 @@ let gSyncUtils = {
     this._openLink(Weave.Svc.Prefs.get(root + "termsURL"));
   },
 
   openPrivacyPolicy: function () {
     let root = this.fxAccountsEnabled ? "fxa." : "";
     this._openLink(Weave.Svc.Prefs.get(root + "privacyURL"));
   },
 
-  openMPInfoPage: function (event) {
-    event.stopPropagation();
-    let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
-    this._openLink(baseURL + "sync-master-password");
-  },
-
   openFirstSyncProgressPage: function () {
     this._openLink("about:sync-progress");
   },
 
   /**
    * Prepare an invisible iframe with the passphrase backup document.
    * Used by both the print and saving methods.
    *
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -777,19 +777,17 @@ nsDefaultCommandLineHandler.prototype = 
         var uri = resolveURIInternal(cmdLine, ar);
         urilist.push(uri);
       }
     }
     catch (e) {
       Components.utils.reportError(e);
     }
 
-    count = cmdLine.length;
-
-    for (i = 0; i < count; ++i) {
+    for (let i = 0; i < cmdLine.length; ++i) {
       var curarg = cmdLine.getArgument(i);
       if (curarg.match(/^-/)) {
         Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
         // To emulate the pre-nsICommandLine behavior, we ignore
         // the argument after an unrecognized flag.
         ++i;
       } else {
         try {
--- a/browser/components/preferences/in-content/sync.js
+++ b/browser/components/preferences/in-content/sync.js
@@ -149,27 +149,16 @@ let gSyncPane = {
         document.getElementById("fxaEmailAddress1").textContent = data.email;
         document.getElementById("fxaEmailAddress2").textContent = data.email;
         document.getElementById("fxaEmailAddress3").textContent = data.email;
         document.getElementById("fxaSyncComputerName").value = Weave.Service.clientsEngine.localName;
         let engines = document.getElementById("fxaSyncEngines")
         for (let checkbox of engines.querySelectorAll("checkbox")) {
           checkbox.disabled = enginesListDisabled;
         }
-
-        let checkbox = document.getElementById("fxa-pweng-chk");
-        let help = document.getElementById("fxa-pweng-help");
-        let allowPasswordsEngine = service.allowPasswordsEngine;
-
-        if (!allowPasswordsEngine) {
-          checkbox.checked = false;
-        }
-
-        checkbox.disabled = !allowPasswordsEngine || enginesListDisabled;
-        help.hidden = allowPasswordsEngine || enginesListDisabled;
       });
     // If fxAccountEnabled is false and we are in a "not configured" state,
     // then fxAccounts is probably fully disabled rather than just unconfigured,
     // so handle this case.  This block can be removed once we remove support
     // for fxAccounts being disabled.
     } else if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
                Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
       this.page = PAGE_NO_ACCOUNT;
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -271,30 +271,19 @@
       <hbox id="fxaSyncEngines">
         <vbox align="start">
           <checkbox label="&engine.tabs.label;"
                     accesskey="&engine.tabs.accesskey;"
                     preference="engine.tabs"/>
           <checkbox label="&engine.bookmarks.label;"
                     accesskey="&engine.bookmarks.accesskey;"
                     preference="engine.bookmarks"/>
-          <hbox>
-            <checkbox id="fxa-pweng-chk"
-                      label="&engine.passwords.label;"
-                      accesskey="&engine.passwords.accesskey;"
-                      preference="engine.passwords"/>
-
-            <vbox id="fxa-pweng-help">
-              <spacer flex="1"/>
-              <hbox id="fxa-pweng-help-link">
-                <image onclick="gSyncUtils.openMPInfoPage(event);" />
-              </hbox>
-              <spacer flex="1"/>
-            </vbox>
-          </hbox>
+          <checkbox label="&engine.passwords.label;"
+                    accesskey="&engine.passwords.accesskey;"
+                    preference="engine.passwords"/>
           <checkbox label="&engine.history.label;"
                     accesskey="&engine.history.accesskey;"
                     preference="engine.history"/>
           <checkbox label="&engine.addons.label;"
                     accesskey="&engine.addons.accesskey;"
                     preference="engine.addons"/>
           <checkbox label="&engine.prefs.label;"
                     accesskey="&engine.prefs.accesskey;"
--- a/browser/components/preferences/sync.js
+++ b/browser/components/preferences/sync.js
@@ -149,27 +149,16 @@ let gSyncPane = {
         document.getElementById("fxaEmailAddress1").textContent = data.email;
         document.getElementById("fxaEmailAddress2").textContent = data.email;
         document.getElementById("fxaEmailAddress3").textContent = data.email;
         document.getElementById("fxaSyncComputerName").value = Weave.Service.clientsEngine.localName;
         let engines = document.getElementById("fxaSyncEngines")
         for (let checkbox of engines.querySelectorAll("checkbox")) {
           checkbox.disabled = enginesListDisabled;
         }
-
-        let checkbox = document.getElementById("fxa-pweng-chk");
-        let help = document.getElementById("fxa-pweng-help");
-        let allowPasswordsEngine = service.allowPasswordsEngine;
-
-        if (!allowPasswordsEngine) {
-          checkbox.checked = false;
-        }
-
-        checkbox.disabled = !allowPasswordsEngine || enginesListDisabled;
-        help.hidden = allowPasswordsEngine || enginesListDisabled;
       });
     // If fxAccountEnabled is false and we are in a "not configured" state,
     // then fxAccounts is probably fully disabled rather than just unconfigured,
     // so handle this case.  This block can be removed once we remove support
     // for fxAccounts being disabled.
     } else if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
                Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
       this.page = PAGE_NO_ACCOUNT;
--- a/browser/components/preferences/sync.xul
+++ b/browser/components/preferences/sync.xul
@@ -260,30 +260,19 @@
             <hbox id="fxaSyncEngines">
               <vbox>
                 <checkbox label="&engine.tabs.label;"
                           accesskey="&engine.tabs.accesskey;"
                           preference="engine.tabs"/>
                 <checkbox label="&engine.bookmarks.label;"
                           accesskey="&engine.bookmarks.accesskey;"
                           preference="engine.bookmarks"/>
-                <hbox>
-                  <checkbox id="fxa-pweng-chk"
-                            label="&engine.passwords.label;"
-                            accesskey="&engine.passwords.accesskey;"
-                            preference="engine.passwords"/>
-
-                  <vbox id="fxa-pweng-help">
-                    <spacer flex="1"/>
-                    <hbox id="fxa-pweng-help-link">
-                      <image onclick="gSyncUtils.openMPInfoPage(event);" />
-                    </hbox>
-                    <spacer flex="1"/>
-                  </vbox>
-                </hbox>
+                <checkbox label="&engine.passwords.label;"
+                          accesskey="&engine.passwords.accesskey;"
+                          preference="engine.passwords"/>
                 <checkbox label="&engine.history.label;"
                           accesskey="&engine.history.accesskey;"
                           preference="engine.history"/>
                 <checkbox label="&engine.addons.label;"
                           accesskey="&engine.addons.accesskey;"
                           preference="engine.addons"/>
                 <checkbox label="&engine.prefs.label;"
                           accesskey="&engine.prefs.accesskey;"
--- a/browser/themes/linux/preferences/preferences.css
+++ b/browser/themes/linux/preferences/preferences.css
@@ -166,17 +166,9 @@ label.small {
   margin: 5px;
   line-height: 1.2em;
 }
 
 #noFxaAccount > label:first-child {
   margin-bottom: 0.6em;
 }
 
-#fxa-pweng-help-link > label {
-  margin: 0;
-}
-
-#fxa-pweng-help-link > image {
-  list-style-image: url("chrome://global/skin/icons/question-16.png");
-}
-
 %endif
--- a/browser/themes/osx/preferences/preferences.css
+++ b/browser/themes/osx/preferences/preferences.css
@@ -228,25 +228,9 @@ html|a.inline-link:-moz-focusring {
   margin: 12px 4px;
   line-height: 1.2em;
 }
 
 #noFxaAccount > label:first-child {
   margin-bottom: 0.6em;
 }
 
-#fxa-pweng-help-link > label {
-  margin: 0;
-}
-
-#fxa-pweng-help-link > image {
-  width: 16px;
-  height: 16px;
-  list-style-image: url("chrome://global/skin/icons/question-16.png");
-}
-
-@media (min-resolution: 2dppx) {
-  #fxa-pweng-help-link > image {
-    list-style-image: url("chrome://global/skin/icons/question-32.png");
-  }
-}
-
 %endif
--- a/browser/themes/windows/preferences/preferences.css
+++ b/browser/themes/windows/preferences/preferences.css
@@ -156,17 +156,9 @@ label.small {
   margin: 6px;
   line-height: 1.2em;
 }
 
 #noFxaAccount > label:first-child {
   margin-bottom: 0.6em;
 }
 
-#fxa-pweng-help-link > label {
-  margin: 0;
-}
-
-#fxa-pweng-help-link > image {
-  list-style-image: url("chrome://global/skin/icons/question-16.png");
-}
-
 %endif
--- a/build/gyp.mozbuild
+++ b/build/gyp.mozbuild
@@ -28,16 +28,19 @@ gyp_vars = {
     'libyuv_dir': '/media/libyuv',
     'yuv_disable_avx2': 0 if CONFIG['HAVE_X86_AVX2'] else 1,
     # don't use openssl
     'use_openssl': 0,
 
     # saves 4MB when webrtc_trace is off
     'enable_lazy_trace_alloc': 0,
 
+    'use_x11': 1 if CONFIG['MOZ_X11'] else 0,
+    'use_glib': 1 if CONFIG['GLIB_LIBS'] else 0,
+
      # turn off mandatory use of NEON and instead use NEON detection
     'arm_neon': 0,
     'arm_neon_optional': 1,
 
     'moz_widget_toolkit_gonk': 0,
     'moz_webrtc_omx': 0,
 
     # (for vp8) chromium sets to 0 also
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -134,17 +134,17 @@ class DestinationInsertionPointList;
 #define NS_ELEMENT_IID \
 { 0xd123f791, 0x124a, 0x43f3, \
   { 0x84, 0xe3, 0x55, 0x81, 0x0b, 0x6c, 0xf3, 0x08 } }
 
 class Element : public FragmentOrElement
 {
 public:
 #ifdef MOZILLA_INTERNAL_API
-  Element(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) :
+  explicit Element(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) :
     FragmentOrElement(aNodeInfo),
     mState(NS_EVENT_STATE_MOZ_READONLY)
   {
     NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
                       "Bad NodeType in aNodeInfo");
     SetIsElement();
   }
 #endif // MOZILLA_INTERNAL_API
@@ -1208,17 +1208,17 @@ private:
 
   // Data members
   EventStates mState;
 };
 
 class DestinationInsertionPointList : public nsINodeList
 {
 public:
-  DestinationInsertionPointList(Element* aElement);
+  explicit DestinationInsertionPointList(Element* aElement);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DestinationInsertionPointList)
 
   // nsIDOMNodeList
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList
--- a/content/base/public/FragmentOrElement.h
+++ b/content/base/public/FragmentOrElement.h
@@ -43,17 +43,17 @@ class Element;
  * Class that implements the nsIDOMNodeList interface (a list of children of
  * the content), by holding a reference to the content and delegating GetLength
  * and Item to its existing child list.
  * @see nsIDOMNodeList
  */
 class nsChildContentList MOZ_FINAL : public nsINodeList
 {
 public:
-  nsChildContentList(nsINode* aNode)
+  explicit nsChildContentList(nsINode* aNode)
     : mNode(aNode)
   {
     SetIsDOMBinding();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
 
@@ -91,17 +91,17 @@ class nsNode3Tearoff : public nsIDOMXPat
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
 
   NS_DECL_NSIDOMXPATHNSRESOLVER
 
-  nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
+  explicit nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
   {
   }
 
 protected:
   virtual ~nsNode3Tearoff() {}
 
 private:
   nsCOMPtr<nsINode> mNode;
@@ -109,17 +109,17 @@ private:
 
 /**
  * A class that implements nsIWeakReference
  */
 
 class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference
 {
 public:
-  nsNodeWeakReference(nsINode* aNode)
+  explicit nsNodeWeakReference(nsINode* aNode)
     : mNode(aNode)
   {
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIWeakReference
@@ -138,17 +138,17 @@ private:
 };
 
 /**
  * Tearoff to use for nodes to implement nsISupportsWeakReference
  */
 class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference
 {
 public:
-  nsNodeSupportsWeakRefTearoff(nsINode* aNode)
+  explicit nsNodeSupportsWeakRefTearoff(nsINode* aNode)
     : mNode(aNode)
   {
   }
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsISupportsWeakReference
@@ -170,32 +170,33 @@ namespace mozilla {
 namespace dom {
 
 class ShadowRoot;
 class UndoManager;
 
 class FragmentOrElement : public nsIContent
 {
 public:
-  FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
-  FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
+  explicit FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
   // nsINode interface methods
   virtual uint32_t GetChildCount() const MOZ_OVERRIDE;
   virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
   virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE;
   virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify) MOZ_OVERRIDE;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
-  virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE;
+  virtual void GetTextContentInternal(nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError) MOZ_OVERRIDE;
   virtual void SetTextContentInternal(const nsAString& aTextContent,
                                       mozilla::ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIContent interface methods
   virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) MOZ_OVERRIDE;
   virtual const nsTextFragment *GetText() MOZ_OVERRIDE;
   virtual uint32_t TextLength() const MOZ_OVERRIDE;
   virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength,
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -749,17 +749,17 @@ private:
 } // file namespace
 
 class nsDOMFileList MOZ_FINAL : public nsIDOMFileList,
                                 public nsWrapperCache
 {
   ~nsDOMFileList() {}
 
 public:
-  nsDOMFileList(nsISupports *aParent) : mParent(aParent)
+  explicit nsDOMFileList(nsISupports *aParent) : mParent(aParent)
   {
     SetIsDOMBinding();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMFileList)
 
   NS_DECL_NSIDOMFILELIST
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -49,17 +49,17 @@ enum nsLinkState {
 class nsIContent : public nsINode {
 public:
   typedef mozilla::widget::IMEState IMEState;
 
 #ifdef MOZILLA_INTERNAL_API
   // If you're using the external API, the only thing you can know about
   // nsIContent is that it exists with an IID
 
-  nsIContent(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+  explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsINode(aNodeInfo)
   {
     MOZ_ASSERT(mNodeInfo);
     SetNodeIsContent();
   }
 #endif // MOZILLA_INTERNAL_API
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_IID)
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -683,17 +683,17 @@ public:
 
 protected:
   virtual Element *GetRootElementInternal() const = 0;
 
 private:
   class SelectorCacheKey
   {
     public:
-      SelectorCacheKey(const nsAString& aString) : mKey(aString)
+      explicit SelectorCacheKey(const nsAString& aString) : mKey(aString)
       {
         MOZ_COUNT_CTOR(SelectorCacheKey);
       }
 
       nsString mKey;
       nsExpirationState mState;
 
       nsExpirationState* GetExpirationState() { return &mState; }
@@ -2723,17 +2723,17 @@ public:
 private:
   nsCOMPtr<nsINode>     mTarget;
   nsCOMPtr<nsIDocument> mSubtreeOwner;
 };
 
 class MOZ_STACK_CLASS nsAutoSyncOperation
 {
 public:
-  nsAutoSyncOperation(nsIDocument* aDocument);
+  explicit nsAutoSyncOperation(nsIDocument* aDocument);
   ~nsAutoSyncOperation();
 private:
   nsCOMArray<nsIDocument> mDocuments;
   uint32_t                mMicroTaskLevel;
 };
 
 // XXX These belong somewhere else
 nsresult
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -332,17 +332,17 @@ public:
   }
 
   friend class nsNodeUtils;
   friend class nsNodeWeakReference;
   friend class nsNodeSupportsWeakRefTearoff;
   friend class nsAttrAndChildArray;
 
 #ifdef MOZILLA_INTERNAL_API
-  nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+  explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : mNodeInfo(aNodeInfo),
     mParent(nullptr),
     mBoolFlags(0),
     mNextSibling(nullptr),
     mPreviousSibling(nullptr),
     mFirstChild(nullptr),
     mSubtreeRoot(MOZ_THIS_IN_INITIALIZER_LIST()),
     mSlots(nullptr)
@@ -1131,19 +1131,20 @@ protected:
   nsIURI* GetExplicitBaseURI() const {
     if (HasExplicitBaseURI()) {
       return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
     }
     return nullptr;
   }
   
 public:
-  void GetTextContent(nsAString& aTextContent)
+  void GetTextContent(nsAString& aTextContent,
+                      mozilla::ErrorResult& aError)
   {
-    GetTextContentInternal(aTextContent);
+    GetTextContentInternal(aTextContent, aError);
   }
   void SetTextContent(const nsAString& aTextContent,
                       mozilla::ErrorResult& aError)
   {
     SetTextContentInternal(aTextContent, aError);
   }
 
   mozilla::dom::Element* QuerySelector(const nsAString& aSelector,
@@ -1744,17 +1745,18 @@ protected:
   }
 
   bool IsEditableInternal() const;
   virtual bool IsEditableExternal() const
   {
     return IsEditableInternal();
   }
 
-  virtual void GetTextContentInternal(nsAString& aTextContent);
+  virtual void GetTextContentInternal(nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError);
   virtual void SetTextContentInternal(const nsAString& aTextContent,
                                       mozilla::ErrorResult& aError)
   {
   }
 
 #ifdef DEBUG
   // Note: virtual so that IsInNativeAnonymousSubtree can be called accross
   // module boundaries.
@@ -2027,18 +2029,19 @@ ToCanonicalSupports(nsINode* aPointer)
     return NS_OK; \
   } \
   NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ \
   { \
     return nsINode::CompareDocumentPosition(aOther, aResult); \
   } \
   NS_IMETHOD GetTextContent(nsAString& aTextContent) __VA_ARGS__ \
   { \
-    nsINode::GetTextContent(aTextContent); \
-    return NS_OK; \
+    mozilla::ErrorResult rv; \
+    nsINode::GetTextContent(aTextContent, rv); \
+    return rv.ErrorCode(); \
   } \
   NS_IMETHOD SetTextContent(const nsAString& aTextContent) __VA_ARGS__ \
   { \
     mozilla::ErrorResult rv; \
     nsINode::SetTextContent(aTextContent, rv); \
     return rv.ErrorCode(); \
   } \
   NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) __VA_ARGS__ \
--- a/content/base/public/nsNameSpaceManager.h
+++ b/content/base/public/nsNameSpaceManager.h
@@ -15,17 +15,17 @@ class nsIAtom;
 class nsAString;
 
 class nsNameSpaceKey : public PLDHashEntryHdr
 {
 public:
   typedef const nsAString* KeyType;
   typedef const nsAString* KeyTypePointer;
 
-  nsNameSpaceKey(KeyTypePointer aKey) : mKey(aKey)
+  explicit nsNameSpaceKey(KeyTypePointer aKey) : mKey(aKey)
   {
   }
   nsNameSpaceKey(const nsNameSpaceKey& toCopy) : mKey(toCopy.mKey)
   {
   }
 
   KeyType GetKey() const
   {
--- a/content/base/src/Attr.cpp
+++ b/content/base/src/Attr.cpp
@@ -297,17 +297,18 @@ already_AddRefed<nsIURI>
 Attr::GetBaseURI(bool aTryUseXHRDocBaseURI) const
 {
   Element* parent = GetElement();
 
   return parent ? parent->GetBaseURI(aTryUseXHRDocBaseURI) : nullptr;
 }
 
 void
-Attr::GetTextContentInternal(nsAString& aTextContent)
+Attr::GetTextContentInternal(nsAString& aTextContent,
+                             ErrorResult& aError)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
 
   GetValue(aTextContent);
 }
 
 void
 Attr::SetTextContentInternal(const nsAString& aTextContent,
--- a/content/base/src/Attr.h
+++ b/content/base/src/Attr.h
@@ -37,17 +37,18 @@ public:
        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
        const nsAString& aValue,
        bool aNsAware);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsIDOMNode interface
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE;
+  virtual void GetTextContentInternal(nsAString& aTextContent,
+                                      ErrorResult& aError) MOZ_OVERRIDE;
   virtual void SetTextContentInternal(const nsAString& aTextContent,
                                       ErrorResult& aError) MOZ_OVERRIDE;
   virtual void GetNodeValueInternal(nsAString& aNodeValue) MOZ_OVERRIDE;
   virtual void SetNodeValueInternal(const nsAString& aNodeValue,
                                     ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIDOMAttr interface
   NS_DECL_NSIDOMATTR
--- a/content/base/src/DOMRect.h
+++ b/content/base/src/DOMRect.h
@@ -28,17 +28,17 @@ class DOMRectReadOnly : public nsISuppor
 {
 protected:
   virtual ~DOMRectReadOnly() {}
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectReadOnly)
 
-  DOMRectReadOnly(nsISupports* aParent)
+  explicit DOMRectReadOnly(nsISupports* aParent)
     : mParent(aParent)
   {
     SetIsDOMBinding();
   }
 
   nsISupports* GetParentObject() const
   {
     MOZ_ASSERT(mParent);
@@ -75,18 +75,18 @@ public:
 protected:
   nsCOMPtr<nsISupports> mParent;
 };
 
 class DOMRect MOZ_FINAL : public DOMRectReadOnly
                         , public nsIDOMClientRect
 {
 public:
-  DOMRect(nsISupports* aParent, double aX = 0, double aY = 0,
-          double aWidth = 0, double aHeight = 0)
+  explicit DOMRect(nsISupports* aParent, double aX = 0, double aY = 0,
+                   double aWidth = 0, double aHeight = 0)
     : DOMRectReadOnly(aParent)
     , mX(aX)
     , mY(aY)
     , mWidth(aWidth)
     , mHeight(aHeight)
   {
   }
   
@@ -145,17 +145,17 @@ protected:
 };
 
 class DOMRectList MOZ_FINAL : public nsIDOMClientRectList,
                               public nsWrapperCache
 {
   ~DOMRectList() {}
 
 public:
-  DOMRectList(nsISupports *aParent) : mParent(aParent)
+  explicit DOMRectList(nsISupports *aParent) : mParent(aParent)
   {
     SetIsDOMBinding();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectList)
 
   NS_DECL_NSIDOMCLIENTRECTLIST
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -1097,20 +1097,22 @@ FragmentOrElement::RemoveChildAt(uint32_
   NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
 
   if (oldKid) {
     doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
   }
 }
 
 void
-FragmentOrElement::GetTextContentInternal(nsAString& aTextContent)
+FragmentOrElement::GetTextContentInternal(nsAString& aTextContent,
+                                          ErrorResult& aError)
 {
-  if(!nsContentUtils::GetNodeTextContent(this, true, aTextContent))
-    NS_RUNTIMEABORT("OOM");
+  if(!nsContentUtils::GetNodeTextContent(this, true, aTextContent)) {
+    aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+  }
 }
 
 void
 FragmentOrElement::SetTextContentInternal(const nsAString& aTextContent,
                                           ErrorResult& aError)
 {
   aError = nsContentUtils::SetNodeTextContent(this, aTextContent, false);
 }
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -62,17 +62,17 @@ struct ImageValue;
  * assumes the string is maximally large, given the nsStringBuffer's storage
  * size.  This means the given string buffer *must* be sized exactly correctly
  * for the string it contains (including one byte for a null terminator).  If
  * it has any unused storage space, then that will result in bogus characters
  * at the end of our nsCheapString.
  */
 class nsCheapString : public nsString {
 public:
-  nsCheapString(nsStringBuffer* aBuf)
+  explicit nsCheapString(nsStringBuffer* aBuf)
   {
     if (aBuf)
       aBuf->ToString(aBuf->StorageSize()/sizeof(char16_t) - 1, *this);
   }
 };
 
 class nsAttrValue {
   friend struct MiscContainer;
--- a/content/base/src/nsDOMAttributeMap.h
+++ b/content/base/src/nsDOMAttributeMap.h
@@ -50,17 +50,17 @@ public:
  * PLDHashEntryHdr implementation for nsAttrKey.
  */
 class nsAttrHashKey : public PLDHashEntryHdr
 {
 public:
   typedef const nsAttrKey& KeyType;
   typedef const nsAttrKey* KeyTypePointer;
 
-  nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
+  explicit nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
   nsAttrHashKey(const nsAttrHashKey& aCopy) : mKey(aCopy.mKey) {}
   ~nsAttrHashKey() {}
 
   KeyType GetKey() const { return mKey; }
   bool KeyEquals(KeyTypePointer aKey) const
     {
       return mKey.mLocalName == aKey->mLocalName &&
              mKey.mNamespaceID == aKey->mNamespaceID;
@@ -84,17 +84,17 @@ private:
 class nsDOMAttributeMap : public nsIDOMMozNamedAttrMap
                         , public nsWrapperCache
 {
 public:
   typedef mozilla::dom::Attr Attr;
   typedef mozilla::dom::Element Element;
   typedef mozilla::ErrorResult ErrorResult;
 
-  nsDOMAttributeMap(Element *aContent);
+  explicit nsDOMAttributeMap(Element *aContent);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsDOMAttributeMap)
 
   // nsIDOMMozNamedAttrMap interface
   NS_DECL_NSIDOMMOZNAMEDATTRMAP
 
   void DropReference();
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -2321,17 +2321,17 @@ nsFrameLoader::DoSendAsyncMessage(JSCont
     if (!BuildClonedMessageDataForParent(cp, aData, data)) {
       return false;
     }
     InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
     if (aCpows && !cp->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
     return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows,
-                                       aPrincipal);
+                                       IPC::Principal(aPrincipal));
   }
 
   if (mChildMessageManager) {
     nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
                                                          aData, aCpows,
                                                          aPrincipal);
     NS_DispatchToCurrentThread(ev);
     return true;
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -1724,20 +1724,20 @@ public:
       return false;
     }
     InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
     if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
     if (aIsSync) {
       return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
-                                 aPrincipal, aJSONRetVal);
+                                 IPC::Principal(aPrincipal), aJSONRetVal);
     }
     return cc->CallRpcMessage(PromiseFlatString(aMessage), data, cpows,
-                              aPrincipal, aJSONRetVal);
+                              IPC::Principal(aPrincipal), aJSONRetVal);
   }
 
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
                                   JS::Handle<JSObject *> aCpows,
                                   nsIPrincipal* aPrincipal) MOZ_OVERRIDE
   {
@@ -1750,17 +1750,17 @@ public:
     if (!BuildClonedMessageDataForChild(cc, aData, data)) {
       return false;
     }
     InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
     if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
     return cc->SendAsyncMessage(PromiseFlatString(aMessage), data, cpows,
-                                aPrincipal);
+                                IPC::Principal(aPrincipal));
   }
 
 };
 
 
 class nsAsyncMessageToSameProcessParent : public nsSameProcessAsyncMessageBase,
                                           public nsRunnable
 {
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -88,17 +88,18 @@ public:
   // nsINode methods
   virtual uint32_t GetChildCount() const MOZ_OVERRIDE;
   virtual nsIContent *GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
   virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const MOZ_OVERRIDE;
   virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify) MOZ_OVERRIDE;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) MOZ_OVERRIDE;
-  virtual void GetTextContentInternal(nsAString& aTextContent) MOZ_OVERRIDE
+  virtual void GetTextContentInternal(nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError) MOZ_OVERRIDE
   {
     GetNodeValue(aTextContent);
   }
   virtual void SetTextContentInternal(const nsAString& aTextContent,
                                       mozilla::ErrorResult& aError) MOZ_OVERRIDE
   {
     // Batch possible DOMSubtreeModified events.
     mozAutoSubtreeModified subtree(OwnerDoc(), nullptr);
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -375,17 +375,17 @@ nsINode::ChildNodes()
       NS_ADDREF(slots->mChildNodes);
     }
   }
 
   return slots->mChildNodes;
 }
 
 void
-nsINode::GetTextContentInternal(nsAString& aTextContent)
+nsINode::GetTextContentInternal(nsAString& aTextContent, ErrorResult& aError)
 {
   SetDOMStringToNull(aTextContent);
 }
 
 nsIDocument*
 nsINode::GetComposedDocInternal() const
 {
   MOZ_ASSERT(HasFlag(NODE_IS_IN_SHADOW_TREE) && IsContent(),
--- a/content/base/src/nsMappedAttributeElement.h
+++ b/content/base/src/nsMappedAttributeElement.h
@@ -23,17 +23,17 @@ typedef void (*nsMapRuleToAttributesFunc
 
 typedef nsStyledElement nsMappedAttributeElementBase;
 
 class nsMappedAttributeElement : public nsMappedAttributeElementBase
 {
 
 protected:
 
-  nsMappedAttributeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+  explicit nsMappedAttributeElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsMappedAttributeElementBase(aNodeInfo)
   {}
 
 public:
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
 
   static void MapNoAttributesInto(const nsMappedAttributes* aAttributes, 
                                   nsRuleData* aRuleData);
--- a/content/base/src/nsPropertyTable.h
+++ b/content/base/src/nsPropertyTable.h
@@ -47,18 +47,18 @@ class nsIFrame;
 class nsPropertyOwner
 {
 public:
   nsPropertyOwner(const nsPropertyOwner& aOther) : mObject(aOther.mObject) {}
 
   // These are the types of objects that can own properties. No object should
   // inherit more then one of these classes.
   // To add support for more types just add to this list.
-  nsPropertyOwner(const nsINode* aObject) : mObject(aObject) {}
-  nsPropertyOwner(const nsIFrame* aObject) : mObject(aObject) {}
+  MOZ_IMPLICIT nsPropertyOwner(const nsINode* aObject) : mObject(aObject) {}
+  MOZ_IMPLICIT nsPropertyOwner(const nsIFrame* aObject) : mObject(aObject) {}
 
   operator const void*() { return mObject; }
   const void* get() { return mObject; }
 
 private:
   const void* mObject;
 };
 
--- a/content/base/src/nsRange.h
+++ b/content/base/src/nsRange.h
@@ -36,17 +36,17 @@ class nsRange MOZ_FINAL : public nsIDOMR
 {
   typedef mozilla::ErrorResult ErrorResult;
   typedef mozilla::dom::DOMRect DOMRect;
   typedef mozilla::dom::DOMRectList DOMRectList;
 
   virtual ~nsRange();
 
 public:
-  nsRange(nsINode* aNode)
+  explicit nsRange(nsINode* aNode)
     : mRoot(nullptr)
     , mStartOffset(0)
     , mEndOffset(0)
     , mIsPositioned(false)
     , mIsDetached(false)
     , mMaySpanAnonymousSubtrees(false)
     , mInSelection(false)
     , mStartOffsetWasIncremented(false)
@@ -285,17 +285,17 @@ protected:
    * That is, it's a faster version of GetCommonAncestor that only works
    * for ranges in a Selection.  The method will assert and the behavior
    * is undefined if called on a range where IsInSelection() is false.
    */
   nsINode* GetRegisteredCommonAncestor();
 
   struct MOZ_STACK_CLASS AutoInvalidateSelection
   {
-    AutoInvalidateSelection(nsRange* aRange) : mRange(aRange)
+    explicit AutoInvalidateSelection(nsRange* aRange) : mRange(aRange)
     {
 #ifdef DEBUG
       mWasInSelection = mRange->IsInSelection();
 #endif
       if (!mRange->IsInSelection() || mIsNested) {
         return;
       }
       mIsNested = true;
--- a/content/base/src/nsStyledElement.h
+++ b/content/base/src/nsStyledElement.h
@@ -25,17 +25,17 @@ class StyleRule;
 
 typedef mozilla::dom::Element nsStyledElementBase;
 
 class nsStyledElementNotElementCSSInlineStyle : public nsStyledElementBase
 {
 
 protected:
 
-  inline nsStyledElementNotElementCSSInlineStyle(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+  inline explicit nsStyledElementNotElementCSSInlineStyle(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsStyledElementBase(aNodeInfo)
   {}
 
 public:
   // nsIContent interface methods
   virtual mozilla::css::StyleRule* GetInlineStyleRule();
   virtual nsresult SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule,
                                       const nsAString* aSerialized,
@@ -67,14 +67,14 @@ protected:
    * string.  If aForceInDataDoc is true, will reparse even if we're in a data
    * document.
    */
   nsresult  ReparseStyleAttribute(bool aForceInDataDoc);
 };
 
 class nsStyledElement : public nsStyledElementNotElementCSSInlineStyle {
 protected:
-  inline nsStyledElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+  inline explicit nsStyledElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsStyledElementNotElementCSSInlineStyle(aNodeInfo)
   {}
 };
 
 #endif // __NS_STYLEDELEMENT_H_
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -108,17 +108,17 @@ protected:
 };
 
 } // namespace mozilla
 
 class nsXHREventTarget : public mozilla::DOMEventTargetHelper,
                          public nsIXMLHttpRequestEventTarget
 {
 protected:
-  nsXHREventTarget(mozilla::DOMEventTargetHelper* aOwner)
+  explicit nsXHREventTarget(mozilla::DOMEventTargetHelper* aOwner)
     : mozilla::DOMEventTargetHelper(aOwner)
   {
   }
 
   nsXHREventTarget()
   {
   }
 
@@ -146,17 +146,17 @@ public:
   
   virtual void DisconnectFromOwner();
 };
 
 class nsXMLHttpRequestUpload MOZ_FINAL : public nsXHREventTarget,
                                          public nsIXMLHttpRequestUpload
 {
 public:
-  nsXMLHttpRequestUpload(mozilla::DOMEventTargetHelper* aOwner)
+  explicit nsXMLHttpRequestUpload(mozilla::DOMEventTargetHelper* aOwner)
     : nsXHREventTarget(aOwner)
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget)
   NS_DECL_NSIXMLHTTPREQUESTUPLOAD
@@ -338,41 +338,41 @@ private:
   virtual ~nsXMLHttpRequest();
 
   class RequestBody
   {
   public:
     RequestBody() : mType(Uninitialized)
     {
     }
-    RequestBody(const mozilla::dom::ArrayBuffer* aArrayBuffer) : mType(ArrayBuffer)
+    explicit RequestBody(const mozilla::dom::ArrayBuffer* aArrayBuffer) : mType(ArrayBuffer)
     {
       mValue.mArrayBuffer = aArrayBuffer;
     }
-    RequestBody(const mozilla::dom::ArrayBufferView* aArrayBufferView) : mType(ArrayBufferView)
+    explicit RequestBody(const mozilla::dom::ArrayBufferView* aArrayBufferView) : mType(ArrayBufferView)
     {
       mValue.mArrayBufferView = aArrayBufferView;
     }
-    RequestBody(nsIDOMBlob* aBlob) : mType(Blob)
+    explicit RequestBody(nsIDOMBlob* aBlob) : mType(Blob)
     {
       mValue.mBlob = aBlob;
     }
-    RequestBody(nsIDocument* aDocument) : mType(Document)
+    explicit RequestBody(nsIDocument* aDocument) : mType(Document)
     {
       mValue.mDocument = aDocument;
     }
-    RequestBody(const nsAString& aString) : mType(DOMString)
+    explicit RequestBody(const nsAString& aString) : mType(DOMString)
     {
       mValue.mString = &aString;
     }
-    RequestBody(nsFormData& aFormData) : mType(FormData)
+    explicit RequestBody(nsFormData& aFormData) : mType(FormData)
     {
       mValue.mFormData = &aFormData;
     }
-    RequestBody(nsIInputStream* aStream) : mType(InputStream)
+    explicit RequestBody(nsIInputStream* aStream) : mType(InputStream)
     {
       mValue.mStream = aStream;
     }
 
     enum Type {
       Uninitialized,
       ArrayBuffer,
       ArrayBufferView,
@@ -804,17 +804,17 @@ class nsXMLHttpRequestXPCOMifier MOZ_FIN
                                              public nsIProgressEventSink,
                                              public nsIInterfaceRequestor,
                                              public nsITimerCallback
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpRequestXPCOMifier,
                                            nsIStreamListener)
 
-  nsXMLHttpRequestXPCOMifier(nsXMLHttpRequest* aXHR) :
+  explicit nsXMLHttpRequestXPCOMifier(nsXMLHttpRequest* aXHR) :
     mXHR(aXHR)
   {
   }
 
 private:
   ~nsXMLHttpRequestXPCOMifier() {
     if (mXHR) {
       mXHR->mXPCOMifier = nullptr;
@@ -842,17 +842,17 @@ public:
   {
     nsCOMPtr<nsIXMLHttpRequest> xhr = do_QueryReferent(mXHR);
     if (xhr) {
       static_cast<nsXMLHttpRequest*>(xhr.get())->ChangeStateToDone();
     }
     mXHR = nullptr;
     return NS_OK;
   }
-  nsXHRParseEndListener(nsIXMLHttpRequest* aXHR)
+  explicit nsXHRParseEndListener(nsIXMLHttpRequest* aXHR)
     : mXHR(do_GetWeakReference(aXHR)) {}
 private:
   virtual ~nsXHRParseEndListener() {}
 
   nsWeakPtr mXHR;
 };
 
 #endif
--- a/content/html/content/public/HTMLCanvasElement.h
+++ b/content/html/content/public/HTMLCanvasElement.h
@@ -42,17 +42,17 @@ class HTMLCanvasElement MOZ_FINAL : publ
     DEFAULT_CANVAS_WIDTH = 300,
     DEFAULT_CANVAS_HEIGHT = 150
   };
 
   typedef layers::CanvasLayer CanvasLayer;
   typedef layers::LayerManager LayerManager;
 
 public:
-  HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLCanvasElement, canvas)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMHTMLCanvasElement
   NS_DECL_NSIDOMHTMLCANVASELEMENT
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -3890,16 +3890,21 @@ void HTMLMediaElement::UpdateAudioChanne
   bool playingThroughTheAudioChannel =
      (!mPaused &&
       (HasAttr(kNameSpaceID_None, nsGkAtoms::loop) ||
        (mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
         !IsPlaybackEnded())));
   if (playingThroughTheAudioChannel != mPlayingThroughTheAudioChannel) {
     mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
 
+    // If we are not playing, we don't need to create a new audioChannelAgent.
+    if (!mAudioChannelAgent && !mPlayingThroughTheAudioChannel) {
+       return;
+    }
+
     if (!mAudioChannelAgent) {
       nsresult rv;
       mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
       if (!mAudioChannelAgent) {
         return;
       }
       // Use a weak ref so the audio channel agent can't leak |this|.
       if (AudioChannel::Normal == mAudioChannel && IsVideo()) {
--- a/content/html/content/src/HTMLTimeElement.cpp
+++ b/content/html/content/src/HTMLTimeElement.cpp
@@ -32,17 +32,18 @@ HTMLTimeElement::WrapNode(JSContext* cx)
 }
 
 void
 HTMLTimeElement::GetItemValueText(nsAString& text)
 {
   if (HasAttr(kNameSpaceID_None, nsGkAtoms::datetime)) {
     GetDateTime(text);
   } else {
-    GetTextContentInternal(text);
+    ErrorResult rv;
+    GetTextContentInternal(text, rv);
   }
 }
 
 void
 HTMLTimeElement::SetItemValueText(const nsAString& text)
 {
   ErrorResult rv;
   SetDateTime(text, rv);
--- a/content/html/content/src/ValidityState.h
+++ b/content/html/content/src/ValidityState.h
@@ -70,17 +70,17 @@ public:
     return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_CUSTOM_ERROR);
   }
   bool Valid() const
   {
     return !mConstraintValidation || mConstraintValidation->IsValid();
   }
 
 protected:
-  ValidityState(nsIConstraintValidation* aConstraintValidation);
+  explicit ValidityState(nsIConstraintValidation* aConstraintValidation);
 
   /**
    * Helper function to get a validity state from constraint validation instance.
    */
   inline bool GetValidityState(nsIConstraintValidation::ValidityStateType aState) const
   {
     return mConstraintValidation &&
            mConstraintValidation->GetValidityState(aState);
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -3121,17 +3121,18 @@ nsGenericHTMLElement::SetItemValue(nsIVa
   aValue->GetAsAString(string);
   SetItemValueText(string);
   return NS_OK;
 }
 
 void
 nsGenericHTMLElement::GetItemValueText(nsAString& text)
 {
-  GetTextContentInternal(text);
+  ErrorResult rv;
+  GetTextContentInternal(text, rv);
 }
 
 void
 nsGenericHTMLElement::SetItemValueText(const nsAString& text)
 {
   mozilla::ErrorResult rv;
   SetTextContentInternal(text, rv);
 }
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -46,17 +46,17 @@ typedef nsMappedAttributeElement nsGener
 
 /**
  * A common superclass for HTML elements
  */
 class nsGenericHTMLElement : public nsGenericHTMLElementBase,
                              public nsIDOMHTMLElement
 {
 public:
-  nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+  explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElementBase(aNodeInfo),
       mScrollgrab(false)
   {
     NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
                  "Unexpected namespace");
     AddStatesSilently(NS_EVENT_STATE_LTR);
     SetFlags(NODE_HAS_DIRECTION_LTR);
   }
@@ -1258,17 +1258,17 @@ ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPE
 
 /**
  * A helper class for form elements that can contain children
  */
 class nsGenericHTMLFormElement : public nsGenericHTMLElement,
                                  public nsIFormControl
 {
 public:
-  nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   mozilla::dom::ParentObject GetParentObject() const;
 
   virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
   virtual void SaveSubtreeState() MOZ_OVERRIDE;
 
@@ -1416,17 +1416,17 @@ protected:
 
   /* This is a pointer to our closest fieldset parent if any */
   mozilla::dom::HTMLFieldSetElement* mFieldSet;
 };
 
 class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
 {
 public:
-  nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  explicit nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
   /**
    * Get the presentation state for a piece of content, or create it if it does
    * not exist.  Generally used by SaveState().
    */
   nsPresState* GetPrimaryPresState();
 
   /**
--- a/content/html/content/test/file_fullscreen-plugins.html
+++ b/content/html/content/test/file_fullscreen-plugins.html
@@ -10,16 +10,18 @@ Test plugins with DOM full-screen API:
 * Request for full-screen is not denied when the only plugin present is windowless.
 * Adding an existing (out-of-doc) windowed plugin to a full-screen document causes document to exit full-screen.
 * Create windowed plugin and adding it to full-screen document caused exit from full-screen.
 
 -->
 <head>
   <title>Test for Bug 545812</title>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="enableTestPlugin.js"></script>
   <script type="application/javascript" src="file_fullscreen-utils.js"></script>
   <style>
   body:-moz-full-screen, div:-moz-full-screen {
     background-color: red;
   }
   </style>
 </head>
 <body>
--- a/content/html/content/test/mochitest.ini
+++ b/content/html/content/test/mochitest.ini
@@ -12,16 +12,17 @@ support-files =
   bug277890_iframe.html
   bug277890_load.html
   bug340800_iframe.txt
   bug372098-link-target.html
   bug392567.jar
   bug392567.jar^headers^
   bug441930_iframe.html
   bug514856_iframe.html
+  enableTestPlugin.js
   file_bug209275_1.html
   file_bug209275_2.html
   file_bug209275_3.html
   file_bug297761.html
   file_bug417760.png
   file_bug893537.html
   file_formSubmission_img.jpg
   file_formSubmission_text.txt
--- a/content/html/content/test/test_iframe_sandbox_plugins.html
+++ b/content/html/content/test/test_iframe_sandbox_plugins.html
@@ -3,16 +3,17 @@
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=341604
 Implement HTML5 sandbox attribute for IFRAMEs
 -->
 <head>
   <meta charset="utf-8">
   <title>Test for Bug 341604 - plugins</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="enableTestPlugin.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <script type="application/javascript">
 /** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
 /** Plugin tests **/
 SimpleTest.waitForExplicitFinish();
 
 function doTest() {
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -555,33 +555,39 @@ nsresult MediaDecoder::InitializeStateMa
   NS_ASSERTION(mDecoderStateMachine, "Cannot initialize null state machine!");
 
   MediaDecoder* cloneDonor = static_cast<MediaDecoder*>(aCloneDonor);
   if (NS_FAILED(mDecoderStateMachine->Init(cloneDonor ?
                                            cloneDonor->mDecoderStateMachine : nullptr))) {
     DECODER_LOG(PR_LOG_WARNING, "Failed to init state machine!");
     return NS_ERROR_FAILURE;
   }
-  {
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    mDecoderStateMachine->SetDuration(mDuration);
-    mDecoderStateMachine->SetVolume(mInitialVolume);
-    mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
-    SetPlaybackRate(mInitialPlaybackRate);
-    mDecoderStateMachine->SetPreservesPitch(mInitialPreservesPitch);
-    if (mMinimizePreroll) {
-      mDecoderStateMachine->SetMinimizePrerollUntilPlaybackStarts();
-    }
-  }
+
+  // If some parameters got set before the state machine got created,
+  // set them now
+  SetStateMachineParameters();
 
   ChangeState(PLAY_STATE_LOADING);
 
   return ScheduleStateMachineThread();
 }
 
+void MediaDecoder::SetStateMachineParameters()
+{
+  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
+  mDecoderStateMachine->SetDuration(mDuration);
+  mDecoderStateMachine->SetVolume(mInitialVolume);
+  mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
+  SetPlaybackRate(mInitialPlaybackRate);
+  mDecoderStateMachine->SetPreservesPitch(mInitialPreservesPitch);
+  if (mMinimizePreroll) {
+    mDecoderStateMachine->SetMinimizePrerollUntilPlaybackStarts();
+  }
+}
+
 void MediaDecoder::SetMinimizePrerollUntilPlaybackStarts()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mMinimizePreroll = true;
 }
 
 nsresult MediaDecoder::ScheduleStateMachineThread()
 {
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -1006,16 +1006,17 @@ public:
   // Can be called on any thread.
   virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_OVERRIDE
   {
     GetFrameStatistics().NotifyDecodedFrames(aParsed, aDecoded);
   }
 
 protected:
   virtual ~MediaDecoder();
+  void SetStateMachineParameters();
 
   /******
    * The following members should be accessed with the decoder lock held.
    ******/
 
   // Current decoding position in the stream. This is where the decoder
   // is up to consuming the stream. This is not adjusted during decoder
   // seek operations, but it's updated at the end when we start playing
--- a/content/media/mediasource/MediaSourceDecoder.cpp
+++ b/content/media/mediasource/MediaSourceDecoder.cpp
@@ -305,17 +305,24 @@ MediaSourceDecoder::Load(nsIStreamListen
 {
   MOZ_ASSERT(!mDecoderStateMachine);
   mDecoderStateMachine = CreateStateMachine();
   if (!mDecoderStateMachine) {
     NS_WARNING("Failed to create state machine!");
     return NS_ERROR_FAILURE;
   }
 
-  return mDecoderStateMachine->Init(nullptr);
+
+  nsresult rv = mDecoderStateMachine->Init(nullptr);
+
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  SetStateMachineParameters();
+
+  return rv;
 }
 
 nsresult
 MediaSourceDecoder::GetSeekable(dom::TimeRanges* aSeekable)
 {
   double duration = mMediaSource->Duration();
   if (IsNaN(duration)) {
     // Return empty range.
--- a/content/media/omx/MediaCodecReader.cpp
+++ b/content/media/omx/MediaCodecReader.cpp
@@ -118,17 +118,17 @@ bool MediaCodecReader::TrackInputCopier:
   memcpy(aCodecBuffer->data(), aSourceBuffer->data() + aSourceBuffer->range_offset(), aSourceBuffer->range_length());
 
   return true;
 }
 
 MediaCodecReader::Track::Track()
   : mDurationUs(INT64_C(0))
   , mInputIndex(sInvalidInputIndex)
-  , mEndOfStream(false)
+  , mInputEndOfStream(false)
   , mSeekTimeUs(sInvalidTimestampUs)
   , mFlushed(false)
 {
 }
 
 // Append the value of |kKeyValidSamples| to the end of each vorbis buffer.
 // https://github.com/mozilla-b2g/platform_frameworks_av/blob/master/media/libstagefright/OMXCodec.cpp#L3128
 // https://github.com/mozilla-b2g/platform_frameworks_av/blob/master/media/libstagefright/NuMediaExtractor.cpp#L472
@@ -224,23 +224,24 @@ MediaCodecReader::DecodeAudioData()
   MOZ_ASSERT(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   if (mAudioTrack.mCodec == nullptr || !mAudioTrack.mCodec->allocated()) {
     return false;
   }
 
   // Get one audio output data from MediaCodec
   CodecBufferInfo bufferInfo;
+  status_t status;
   TimeStamp timeout = TimeStamp::Now() + TimeDuration::FromSeconds(sMaxAudioDecodeDurationS);
   while (true) {
     if (timeout < TimeStamp::Now()) {
       return true; // Try it again later.
     }
-    status_t status = GetCodecOutputData(mAudioTrack, bufferInfo, sInvalidTimestampUs, timeout);
-    if (status == OK) {
+    status = GetCodecOutputData(mAudioTrack, bufferInfo, sInvalidTimestampUs, timeout);
+    if (status == OK || status == ERROR_END_OF_STREAM) {
       break;
     } else if (status == -EAGAIN) {
       return true; // Try it again later.
     } else if (status == INFO_FORMAT_CHANGED) {
       if (UpdateAudioInfo()) {
         continue; // Try it again now.
       } else {
         return false;
@@ -267,16 +268,20 @@ MediaCodecReader::DecodeAudioData()
         AudioCompactor::NativeCopy(
             bufferInfo.mBuffer->data() + bufferInfo.mOffset,
             bufferInfo.mSize,
             mInfo.mAudio.mChannels));
   }
 
   mAudioTrack.mCodec->releaseOutputBuffer(bufferInfo.mIndex);
 
+  if (status == ERROR_END_OF_STREAM) {
+    return false;
+  }
+
   return result;
 }
 
 bool
 MediaCodecReader::DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold)
 {
   MOZ_ASSERT(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
@@ -286,23 +291,24 @@ MediaCodecReader::DecodeVideoFrame(bool 
 
   int64_t threshold = sInvalidTimestampUs;
   if (aKeyframeSkip && IsValidTimestampUs(aTimeThreshold)) {
     threshold = aTimeThreshold;
   }
 
   // Get one video output data from MediaCodec
   CodecBufferInfo bufferInfo;
+  status_t status;
   TimeStamp timeout = TimeStamp::Now() + TimeDuration::FromSeconds(sMaxVideoDecodeDurationS);
   while (true) {
     if (timeout < TimeStamp::Now()) {
       return true; // Try it again later.
     }
-    status_t status = GetCodecOutputData(mVideoTrack, bufferInfo, threshold, timeout);
-    if (status == OK) {
+    status = GetCodecOutputData(mVideoTrack, bufferInfo, threshold, timeout);
+    if (status == OK || status == ERROR_END_OF_STREAM) {
       break;
     } else if (status == -EAGAIN) {
       return true; // Try it again later.
     } else if (status == INFO_FORMAT_CHANGED) {
       if (UpdateVideoInfo()) {
         continue; // Try it again now.
       } else {
         return false;
@@ -387,16 +393,20 @@ MediaCodecReader::DecodeVideoFrame(bool 
       aKeyframeSkip = false;
     } else {
       NS_WARNING("Unable to create VideoData");
     }
   }
 
   mVideoTrack.mCodec->releaseOutputBuffer(bufferInfo.mIndex);
 
+  if (status == ERROR_END_OF_STREAM) {
+    return false;
+  }
+
   return result;
 }
 
 bool
 MediaCodecReader::HasAudio()
 {
   return mInfo.mAudio.mHasAudio;
 }
@@ -470,18 +480,18 @@ MediaCodecReader::Seek(int64_t aTime,
   VideoFrameContainer* videoframe = mDecoder->GetVideoFrameContainer();
   if (videoframe != nullptr) {
     mozilla::layers::ImageContainer *image = videoframe->GetImageContainer();
     if (image != nullptr) {
       image->ClearAllImagesExceptFront();
     }
   }
 
-  mAudioTrack.mEndOfStream = false;
-  mVideoTrack.mEndOfStream = false;
+  mAudioTrack.mInputEndOfStream = false;
+  mVideoTrack.mInputEndOfStream = false;
 
   mAudioTrack.mSeekTimeUs = aTime;
   mVideoTrack.mSeekTimeUs = aTime;
 
   mAudioTrack.mFlushed = false;
   mVideoTrack.mFlushed = false;
 
   // Regulate the seek time to the closest sync point of video data.
@@ -990,17 +1000,17 @@ MediaCodecReader::FlushCodecData(Track &
 // FIXME: change to non-blocking read
 status_t
 MediaCodecReader::FillCodecInputData(Track &aTrack)
 {
   if (aTrack.mSource == nullptr || aTrack.mCodec == nullptr || !aTrack.mCodec->allocated()) {
     return UNKNOWN_ERROR;
   }
 
-  if (aTrack.mEndOfStream) {
+  if (aTrack.mInputEndOfStream) {
     return ERROR_END_OF_STREAM;
   }
 
   if (IsValidTimestampUs(aTrack.mSeekTimeUs) && !aTrack.mFlushed) {
     FlushCodecData(aTrack);
   }
 
   size_t index = 0;
@@ -1019,29 +1029,31 @@ MediaCodecReader::FillCodecInputData(Tra
     } else {
       status = aTrack.mSource->read(&source_buffer);
     }
 
     // read() fails
     if (status == INFO_FORMAT_CHANGED) {
       return INFO_FORMAT_CHANGED;
     } else if (status == ERROR_END_OF_STREAM) {
-      aTrack.mEndOfStream = true;
-      aTrack.mCodec->signalEndOfInputStream();
+      aTrack.mInputEndOfStream = true;
+      status = aTrack.mCodec->queueInputBuffer(aTrack.mInputIndex.value(),
+                                               0, 0, 0,
+                                               MediaCodec::BUFFER_FLAG_EOS);
       return ERROR_END_OF_STREAM;
     } else if (status == -ETIMEDOUT) {
       return OK; // try it later
     } else if (status != OK) {
       return status;
     } else if (source_buffer == nullptr) {
       return UNKNOWN_ERROR;
     }
 
     // read() successes
-    aTrack.mEndOfStream = false;
+    aTrack.mInputEndOfStream = false;
     aTrack.mSeekTimeUs = sInvalidTimestampUs;
 
     sp<ABuffer> input_buffer = nullptr;
     if (aTrack.mInputIndex.value() < aTrack.mInputBuffers.size()) {
       input_buffer = aTrack.mInputBuffers[aTrack.mInputIndex.value()];
     }
     if (input_buffer != nullptr &&
         aTrack.mInputCopier != nullptr &&
@@ -1074,27 +1086,38 @@ MediaCodecReader::GetCodecOutputData(Tra
                                      int64_t aThreshold,
                                      const TimeStamp &aTimeout)
 {
   // Read next frame.
   CodecBufferInfo info;
 
   // Try to fill more input buffers and then get one output buffer.
   // FIXME: use callback from MediaCodec
-  status_t status = FillCodecInputData(aTrack);
-  int64_t duration = (int64_t)(aTimeout - TimeStamp::Now()).ToMicroseconds();
-  if (!IsValidDurationUs(duration)) {
-    return -EAGAIN;
-  }
-  if (status == OK) {
-    status = aTrack.mCodec->dequeueOutputBuffer(
-        &info.mIndex, &info.mOffset, &info.mSize, &info.mTimeUs, &info.mFlags, duration);
-  }
+  status_t status = OK;
 
-  while (status == OK || status == INFO_OUTPUT_BUFFERS_CHANGED || status == -EAGAIN) {
+  while (status == OK || status == INFO_OUTPUT_BUFFERS_CHANGED ||
+         status == -EAGAIN || status == ERROR_END_OF_STREAM) {
+    // Try to fill more input buffers and then get one output buffer.
+    // FIXME: use callback from MediaCodec
+    status = FillCodecInputData(aTrack);
+    int64_t duration = (int64_t)(aTimeout - TimeStamp::Now()).ToMicroseconds();
+    if (!IsValidDurationUs(duration)) {
+      return -EAGAIN;
+    }
+
+    if (status == OK || status == ERROR_END_OF_STREAM) {
+      status = aTrack.mCodec->dequeueOutputBuffer(
+          &info.mIndex, &info.mOffset, &info.mSize, &info.mTimeUs, &info.mFlags, duration);
+      if (info.mFlags & MediaCodec::BUFFER_FLAG_EOS) {
+        aBuffer = info;
+        aBuffer.mBuffer = aTrack.mOutputBuffers[info.mIndex];
+        return ERROR_END_OF_STREAM;
+      }
+    }
+
     if (status == OK) {
       if (!IsValidTimestampUs(aThreshold) || info.mTimeUs >= aThreshold) {
         // Get a valid output buffer.
         break;
       } else {
         aTrack.mCodec->releaseOutputBuffer(info.mIndex);
       }
     } else if (status == INFO_OUTPUT_BUFFERS_CHANGED) {
@@ -1105,31 +1128,16 @@ MediaCodecReader::GetCodecOutputData(Tra
         return UNKNOWN_ERROR;
       }
     }
 
     if (TimeStamp::Now() > aTimeout) {
       // Don't let this loop run for too long. Try it again later.
       return -EAGAIN;
     }
-
-    // FIXME: use callback from MediaCodec
-    status = FillCodecInputData(aTrack);
-    if (status == INFO_OUTPUT_BUFFERS_CHANGED) {
-      continue;
-    } else if (status != OK) {
-      return status;
-    }
-
-    duration = (int64_t)(aTimeout - TimeStamp::Now()).ToMicroseconds();
-    if (!IsValidDurationUs(duration)) {
-      return -EAGAIN;
-    }
-    status = aTrack.mCodec->dequeueOutputBuffer(
-        &info.mIndex, &info.mOffset, &info.mSize, &info.mTimeUs, &info.mFlags, duration);
   }
 
   if (status != OK) {
     // Something wrong.
     return status;
   }
 
   if (info.mIndex >= aTrack.mOutputBuffers.size()) {
--- a/content/media/omx/MediaCodecReader.h
+++ b/content/media/omx/MediaCodecReader.h
@@ -104,17 +104,17 @@ protected:
     // pipeline copier
     nsAutoPtr<TrackInputCopier> mInputCopier;
 
     // media parameters
     int64_t mDurationUs;
 
     // playback parameters
     CheckedUint32 mInputIndex;
-    bool mEndOfStream;
+    bool mInputEndOfStream;
     int64_t mSeekTimeUs;
     bool mFlushed; // meaningless when mSeekTimeUs is invalid.
   };
 
   // Receive a message from MessageHandler.
   // Called on MediaCodecReader::mLooper thread.
   void onMessageReceived(const android::sp<android::AMessage> &aMessage);
 
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -1,23 +1,23 @@
-skip-if(B2G) load 0-timescale.html
-skip-if(B2G) load 459439-1.html # bug 888557
+skip-if(Android||B2G) load 0-timescale.html # bug 1048628 for Android
+skip-if(Android||B2G) load 459439-1.html # bug 888557
 load 466607-1.html
 load 466945-1.html
 load 468763-1.html
 load 474744-1.html
 HTTP load 481136-1.html # needs to be HTTP to recognize the ogg as an audio file?
 load 493915-1.html
+load 492286-1.xhtml
 skip-if(Android) load 495794-1.html
-load 492286-1.xhtml
 load 576612-1.html
 skip-if(Android||B2G) load 691096-1.html # Android sound API can't handle playing large number of sounds at once, bug 852821 for B2G
 load 752784-1.html
+skip-if(Android||B2G) load 789075-1.html # load failed, bug 833371 for B2G
 skip-if(Android||B2G) HTTP load 795892-1.html # load failed, bug 833371 for B2G
-skip-if(Android||B2G) load 789075-1.html # load failed, bug 833371 for B2G
 load 844563.html
 load 846612.html
 load 852838.html
 load 865537-1.html
 load 868504.html
 load 874869.html
 load 874915.html
 load 874934.html
@@ -28,32 +28,32 @@ load 875911.html
 load 876024-1.html
 load 876024-2.html
 load 876118.html
 load 876207.html
 load 876215.html
 load 876249.html
 load 876252.html
 load 876834.html
+load 877527.html
 load 877820.html
 load 878014.html
 load 878328.html
 load 878407.html
 load 878478.html
-load 877527.html
 load 880129.html
 skip-if(B2G) load 880202.html # load failed, bug 908306 for B2G
 load 880342-1.html
 load 880342-2.html
 load 880384.html
 load 880404.html
 load 880724.html
 load 881775.html
+test-pref(media.webvtt.enabled,true) load 882549.html
 load 882956.html
-test-pref(media.webvtt.enabled,true) load 882549.html
 load 884459.html
 load 889042.html
 test-pref(media.webvtt.enabled,true) load 894104.html
 load 907986-1.html
 load 907986-2.html
 load 907986-3.html
 load 907986-4.html
 load 910171-1.html
@@ -63,16 +63,16 @@ load 925619-2.html
 load 926619.html
 load 933151.html
 load 933156.html
 load 944851.html
 load 952756.html
 load 966636.html
 load 986901.html
 load 990794.html
+load 1015662.html
+skip-if(Android||B2G) test-pref(media.navigator.permission.disabled,true) load 1028458.html
 load buffer-source-ended-1.html
-load offline-buffer-source-ended-1.html
 HTTP load media-element-source-seek-1.html
 skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338
 skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338
-load 1015662.html
+load offline-buffer-source-ended-1.html
 include ../../mediasource/test/crashtests/crashtests.list
-test-pref(media.navigator.permission.disabled,true) load 1028458.html
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -206,29 +206,17 @@ support-files =
   region.vtt
   sample.3gp
   sample.3g2
   seek.ogv
   seek.ogv^headers^
   seek.webm
   seek.webm^headers^
   seek.yuv
-  seek1.js
-  seek10.js
-  seek11.js
-  seek12.js
-  seek13.js
-  seek2.js
-  seek3.js
-  seek4.js
-  seek5.js
-  seek6.js
-  seek7.js
-  seek8.js
-  seek9.js
+  seek_support.js
   seekLies.sjs
   seek_with_sound.ogg^headers^
   short-video.ogv
   short-video.ogv^headers^
   small-shot-mp3.mp4
   small-shot-mp3.mp4^headers^
   small-shot.m4a
   small-shot.mp3
@@ -348,16 +336,17 @@ skip-if = buildapp == 'b2g' || e10s # b2
 skip-if = buildapp == 'b2g' # bug 1021676
 [test_error_in_video_document.html]
 skip-if = toolkit == 'android' # bug 608634
 [test_error_on_404.html]
 [test_fastSeek.html]
 [test_fastSeek-forwards.html]
 [test_info_leak.html]
 [test_invalid_reject.html]
+[test_invalid_seek.html]
 [test_load.html]
 [test_load_candidates.html]
 [test_load_same_resource.html]
 [test_load_source.html]
 [test_loop.html]
 [test_media_selection.html]
 skip-if = toolkit == 'gonk' && !debug # bug 1021677
 [test_media_sniffer.html]
@@ -413,19 +402,29 @@ skip-if = true # bug 493692
 [test_readyState.html]
 [test_referer.html]
 [test_replay_metadata.html]
 [test_reset_events_async.html]
 [test_reset_src.html]
 [test_resume.html]
 skip-if = true # bug 1021673
 [test_seek_out_of_range.html]
-[test_seek.html]
-skip-if = buildapp == 'b2g' || toolkit == 'android' # Intermittent test failures in bug 1023564 and bug 981153
-[test_seek2.html]
+[test_seek-1.html]
+[test_seek-2.html]
+[test_seek-3.html]
+[test_seek-4.html]
+[test_seek-5.html]
+[test_seek-6.html]
+[test_seek-7.html]
+[test_seek-8.html]
+[test_seek-9.html]
+[test_seek-10.html]
+[test_seek-11.html]
+[test_seek-12.html]
+[test_seek-13.html]
 [test_seekable1.html]
 [test_seekable2.html]
 [test_seekable3.html]
 [test_seekLies.html]
 [test_source.html]
 [test_source_media.html]
 [test_source_null.html]
 [test_source_write.html]
deleted file mode 100644
--- a/content/media/test/seek1.js
+++ /dev/null
@@ -1,68 +0,0 @@
-function test_seek1(v, seekTime, is, ok, finish) {
-
-var startPassed = false;
-var endPassed = false;
-var seekFlagStart = false;
-var seekFlagEnd = false;
-var readonly = true;
-var completed = false;
-
-function startTest() {
-  if (completed)
-    return;
-  ok(!v.seeking, "seeking should default to false");
-  try {
-    v.seeking = true;
-    readonly = v.seeking === false;
-  }
-  catch(e) {
-    readonly = "threw exception: " + e;
-  }
-  is(readonly, true, "seeking should be readonly");
-
-  v.play();
-  v.currentTime=seekTime;
-  seekFlagStart = v.seeking;
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-  ok(v.currentTime >= seekTime - 0.1,
-     "Video currentTime should be around " + seekTime + ": " + v.currentTime + " (seeking)");
-  v.pause();
-  startPassed = true;
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-
-  var t = v.currentTime;
-  // Since we were playing, and we only paused asynchronously, we can't be
-  // sure that we paused before the seek finished, so we may have played
-  // ahead arbitrarily far.
-  ok(t >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + t + " (seeked)");
-  v.play();
-  endPassed = true;
-  seekFlagEnd = v.seeking;
-}
-
-function playbackEnded() {
-  if (completed)
-    return;
-
-  completed = true;
-  ok(startPassed, "seeking event");
-  ok(endPassed, "seeked event");
-  ok(seekFlagStart, "seeking flag on start should be true");
-  ok(!seekFlagEnd, "seeking flag on end should be false");
-  finish();
-}
-
-v.addEventListener("ended", playbackEnded, false);
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek10.js
+++ /dev/null
@@ -1,30 +0,0 @@
-function test_seek10(v, seekTime, is, ok, finish) {
-
-// Test bug 523335 - ensure that if we close a stream while seeking, we
-// don't hang during shutdown. This test won't "fail" per se if it's regressed,
-// it will instead start to cause random hangs in the mochitest harness on
-// shutdown.
-
-function startTest() {
-  // Must be duration*0.9 rather than seekTime, else we don't hit that problem.
-  // This is probably due to the seek bisection finishing too quickly, before
-  // we can close the stream.
-  v.currentTime = v.duration * 0.9;
-}
-
-function done(evt) {
-  ok(true, "We don't acutally test anything...");
-  finish();
-}
-
-function seeking() {
-  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
-  v.onerror = done;
-  v.src = "not a valid video file.";
-  v.load(); // Cause the existing stream to close.
-}
-
-v.addEventListener("loadeddata", startTest, false);
-v.addEventListener("seeking", seeking, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek11.js
+++ /dev/null
@@ -1,49 +0,0 @@
-function test_seek11(v, seekTime, is, ok, finish) {
-
-// Test for bug 476973, multiple seeks to the same position shouldn't cause problems.
-
-var seekedNonZero = false;
-var completed = false;
-var target = 0;
-
-function startTest() {
-  if (completed)
-    return;
-  target = v.duration / 2;
-  v.currentTime = target;
-  v.currentTime = target;
-  v._seekTarget = target;
-}
-
-function startSeeking() {
-  ok(v.currentTime >= v._seekTarget - 0.1,
-     "Video currentTime should be around " + v._seekTarget + ": " + v.currentTime);
-  if (!seekedNonZero) {
-    v.currentTime = target;
-    v._seekTarget = target;
-    seekedNonZero = true;
-  }
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-
-  if (v.currentTime > 0) {
-    ok(v.currentTime > target - 0.1 && v.currentTime < target + 0.1,
-       "Seek to wrong destination " + v.currentTime);
-    v.currentTime = 0.0;
-    v._seekTarget = 0.0;
-  } else {
-    ok(seekedNonZero, "Successfully seeked to nonzero");
-    ok(true, "Seek back to zero was successful");
-    completed = true;
-    finish();
-  }
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", startSeeking, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek12.js
+++ /dev/null
@@ -1,33 +0,0 @@
-function test_seek12(v, seekTime, is, ok, finish) {
-var completed = false;
-
-function startTest() {
-  if (completed)
-    return;
-  ok(!v.seeking, "seeking should default to false");
-  v.currentTime = seekTime;
-  is(v.currentTime, seekTime, "currentTime must report seek target immediately");
-  is(v.seeking, true, "seeking flag on start should be true");
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-  //is(v.currentTime, seekTime, "seeking: currentTime must be seekTime");
-  ok(Math.abs(v.currentTime - seekTime) < 0.01, "seeking: currentTime must be seekTime");
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-  completed = true;
-  //is(v.currentTime, seekTime, "seeked: currentTime must be seekTime");
-  ok(Math.abs(v.currentTime - seekTime) < 0.01, "seeked: currentTime must be seekTime");
-  is(v.seeking, false, "seeking flag on end should be false");
-  finish();
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-}
deleted file mode 100644
--- a/content/media/test/seek13.js
+++ /dev/null
@@ -1,46 +0,0 @@
-function test_seek13(v, seekTime, is, ok, finish) {
-var completed = false;
-
-function startTest() {
-  if (completed)
-    return;
-  ok(!v.seeking, "seeking should default to false");
-  v.currentTime = v.duration;
-  is(v.currentTime, v.duration, "currentTime must report seek target immediately");
-  is(v.seeking, true, "seeking flag on start should be true");
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-  //is(v.currentTime, v.duration, "seeking: currentTime must be duration");
-  ok(Math.abs(v.currentTime - v.duration) < 0.01,
-     "seeking: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")");
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-  //is(v.currentTime, v.duration, "seeked: currentTime must be duration");
-  ok(Math.abs(v.currentTime - v.duration) < 0.01,
-     "seeked: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")");
-  is(v.seeking, false, "seeking flag on end should be false");
-}
-
-function playbackEnded() {
-  if (completed)
-    return;
-  completed = true;
-  //is(v.currentTime, v.duration, "ended: currentTime must be duration");
-  ok(Math.abs(v.currentTime - v.duration) < 0.01,
-     "ended: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")");
-  is(v.seeking, false, "seeking flag on end should be false");
-  is(v.ended, true, "ended must be true");
-  finish();
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-v.addEventListener("ended", playbackEnded, false);
-}
deleted file mode 100644
--- a/content/media/test/seek2.js
+++ /dev/null
@@ -1,49 +0,0 @@
-function test_seek2(v, seekTime, is, ok, finish) {
-
-// Test seeking works if current time is set before video is
-// playing.
-var startPassed = false;
-var endPassed = false;
-var completed = false;
-
-function startTest() {
-  if (completed)
-    return;
-
-  v.currentTime=seekTime;
-  v.play();
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-
-  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
-  startPassed = true;
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-
-  endPassed = true;
-}
-
-function playbackEnded() {
-  if (completed)
-    return;
-
-  completed = true;
-  ok(startPassed, "send seeking event");
-  ok(endPassed, "send seeked event");
-  ok(v.ended, "Checking playback has ended");
-  ok(Math.abs(v.currentTime - v.duration) <= 0.1, "Checking currentTime at end: " + v.currentTime);
-  finish();
-}
-
-v.addEventListener("ended", playbackEnded, false);
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek3.js
+++ /dev/null
@@ -1,44 +0,0 @@
-function test_seek3(v, seekTime, is, ok, finish) {
-
-// Test seeking works if current time is set but video is not played.
-var startPassed = false;
-var completed = false;
-var gotTimeupdate = false;
-
-function startTest() {
-  if (completed)
-    return;
-
-  v.currentTime=seekTime;
-}
-
-function timeupdate() {
-  gotTimeupdate = true;
-  v.removeEventListener("timeupdate", timeupdate, false);
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-
-  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
-  v.addEventListener("timeupdate", timeupdate, false);
-  startPassed = true;
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-
-  var t = v.currentTime;
-  ok(Math.abs(t - seekTime) <= 0.1, "Video currentTime should be around " + seekTime + ": " + t);
-  ok(gotTimeupdate, "Should have got timeupdate between seeking and seekended");
-  completed = true;
-  finish();
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek4.js
+++ /dev/null
@@ -1,44 +0,0 @@
-function test_seek4(v, seekTime, is, ok, finish) {
-
-// Test for a seek, followed by another seek before the first is complete.
-var seekCount = 0;
-var completed = false;
-
-function startTest() {
-  if (completed)
-    return;
-
-  v.currentTime=seekTime;
-  v._seekTarget=seekTime;
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-
-  seekCount += 1;
-
-  ok(v.currentTime >= v._seekTarget - 0.1,
-     "Video currentTime should be around " + v._seekTarget + ": " + v.currentTime);
-  if (seekCount == 1) {
-    v.currentTime=seekTime/2;
-    v._seekTarget=seekTime/2;
-  }
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-
-  if (seekCount == 2) {
-    ok(Math.abs(v.currentTime - seekTime/2) <= 0.1, "seek on target: " + v.currentTime);
-    completed = true;
-    finish();
-  }
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek5.js
+++ /dev/null
@@ -1,43 +0,0 @@
-function test_seek5(v, seekTime, is, ok, finish) {
-
-// Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek.
-var startPassed = false;
-var endPassed = false;
-var completed = false;
-
-function startTest() {
-  if (completed)
-    return;
-
-  v.currentTime=seekTime;
-}
-
-function seekStarted() {
-  if (completed)
-    return;
-  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
-  startPassed = true;
-  v.play();
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-  endPassed = true;
-}
-
-function playbackEnded() {
-  if (completed)
-    return;
-  ok(startPassed, "Got seeking event");
-  ok(endPassed, "Got seeked event");
-  completed = true;
-  finish();
-}
-
-v.addEventListener("ended", playbackEnded, false);
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeking", seekStarted, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek6.js
+++ /dev/null
@@ -1,39 +0,0 @@
-function test_seek6(v, seekTime, is, ok, finish) {
-
-// Test for bug identified by Chris Pearce in comment 40 on
-// bug 449159.
-var seekCount = 0;
-var completed = false;
-var interval;
-var sum = 0;
-
-function poll() {
-  sum += v.currentTime;
-}
-
-function startTest() {
-  if (completed)
-    return;
-  interval = setInterval(poll, 10);
-  v.currentTime = Math.random() * v.duration;
-}
-
-function seekEnded() {
-  if (completed)
-    return;
-
-  seekCount++;
-  ok(true, "Seek " + seekCount);
-  if (seekCount == 3) {
-    clearInterval(interval);
-    completed = true;
-    finish();
-  } else {
-    v.currentTime = Math.random() * v.duration;
-  }
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek7.js
+++ /dev/null
@@ -1,34 +0,0 @@
-function test_seek7(v, seekTime, is, ok, finish) {
-
-// If a NaN is passed to currentTime, make sure this is caught
-// otherwise an infinite loop in the Ogg backend occurs.
-var completed = false;
-var thrown1 = false;
-var thrown2 = false;
-var thrown3 = false;
-
-function startTest() {
-  if (completed)
-    return;
-
-  try {
-    v.currentTime = NaN;
-  } catch(e) {
-    thrown1 = true;
-  }
-
-  try {
-    v.currentTime = Math.random;
-  } catch(e) {
-    thrown3 = true;
-  }
-
-  completed = true;
-  ok(thrown1, "Setting currentTime to invalid value of NaN");
-  ok(thrown3, "Setting currentTime to invalid value of a function");
-  finish();
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek8.js
+++ /dev/null
@@ -1,16 +0,0 @@
-function test_seek8(v, seekTime, is, ok, finish) {
-
-function startTest() {
-  v.currentTime = 1000;
-}
-
-function seekEnded() {
-  ok(Math.abs(v.currentTime - v.duration) < 0.2,
-     "currentTime " + v.currentTime + " close to " + v.duration);
-  finish();
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
deleted file mode 100644
--- a/content/media/test/seek9.js
+++ /dev/null
@@ -1,15 +0,0 @@
-function test_seek9(v, seekTime, is, ok, finish) {
-
-function startTest() {
-  v.currentTime = -1000;
-}
-
-function seekEnded() {
-  is(v.currentTime, 0, "currentTime clamped to 0");
-  finish();
-}
-
-v.addEventListener("loadedmetadata", startTest, false);
-v.addEventListener("seeked", seekEnded, false);
-
-}
new file mode 100644
--- /dev/null
+++ b/content/media/test/seek_support.js
@@ -0,0 +1,55 @@
+SimpleTest.requestLongerTimeout(3);
+var manager = new MediaTestManager;
+
+// https://bugzilla.mozilla.org/show_bug.cgi?id=634747
+if (navigator.platform.startsWith("Win")) {
+  SimpleTest.expectAssertions(0, 5);
+} else {
+  // This is "###!!! ASSERTION: Page read cursor should be inside range: 'mPageOffset <= endOffset'"
+  // https://bugzilla.mozilla.org/show_bug.cgi?id=846769
+  SimpleTest.expectAssertions(0, 5);
+}
+
+function createTestArray() {
+  var tests = [];
+  var tmpVid = document.createElement("video");
+
+  for (var testNum=0; testNum<gSeekTests.length; testNum++) {
+    var test = gSeekTests[testNum];
+    if (!tmpVid.canPlayType(test.type)) {
+      continue;
+    }
+
+    var t = new Object;
+    t.name = test.name;
+    t.type = test.type;
+    t.duration = test.duration;
+    t.number = SEEK_TEST_NUMBER;
+    tests.push(t);
+  }
+  return tests;
+}
+
+function startTest(test, token) {
+  var v = document.createElement('video');
+  v.token = token += "-seek" + test.number + ".js";
+  manager.started(v.token);
+  v.src = test.name;
+  v.preload = "metadata";
+  document.body.appendChild(v);
+  var name = test.name + " seek test " + test.number;
+  var localIs = function(name) { return function(a, b, msg) {
+    is(a, b, name + ": " + msg);
+  }}(name);
+  var localOk = function(name) { return function(a, msg) {
+    ok(a, name + ": " + msg);
+  }}(name);
+  var localFinish = function(v, manager) { return function() {
+    v.onerror = null;
+    removeNodeAndSource(v);
+    dump("SEEK-TEST: Finished " + name + " token: " + v.token + "\n");
+    manager.finished(v.token);
+  }}(v, manager);
+  dump("SEEK-TEST: Started " + name + "\n");
+  window['test_seek' + test.number](v, test.duration/2, localIs, localOk, localFinish);
+}
rename from content/media/test/test_seek2.html
rename to content/media/test/test_invalid_seek.html
--- a/content/media/test/test_seek2.html
+++ b/content/media/test/test_invalid_seek.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-  <title>Media test: seek test 2</title>
+  <title>Media test: invalide seek test</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <video id='v'></video>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-seek
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-1.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 1;
+
+function test_seek1(v, seekTime, is, ok, finish) {
+
+var startPassed = false;
+var endPassed = false;
+var seekFlagStart = false;
+var seekFlagEnd = false;
+var readonly = true;
+var completed = false;
+
+function startTest() {
+  if (completed)
+    return;
+  ok(!v.seeking, "seeking should default to false");
+  try {
+    v.seeking = true;
+    readonly = v.seeking === false;
+  }
+  catch(e) {
+    readonly = "threw exception: " + e;
+  }
+  is(readonly, true, "seeking should be readonly");
+
+  v.play();
+  v.currentTime=seekTime;
+  seekFlagStart = v.seeking;
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+  ok(v.currentTime >= seekTime - 0.1,
+     "Video currentTime should be around " + seekTime + ": " + v.currentTime + " (seeking)");
+  v.pause();
+  startPassed = true;
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+
+  var t = v.currentTime;
+  // Since we were playing, and we only paused asynchronously, we can't be
+  // sure that we paused before the seek finished, so we may have played
+  // ahead arbitrarily far.
+  ok(t >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + t + " (seeked)");
+  v.play();
+  endPassed = true;
+  seekFlagEnd = v.seeking;
+}
+
+function playbackEnded() {
+  if (completed)
+    return;
+
+  completed = true;
+  ok(startPassed, "seeking event");
+  ok(endPassed, "seeked event");
+  ok(seekFlagStart, "seeking flag on start should be true");
+  ok(!seekFlagEnd, "seeking flag on end should be false");
+  finish();
+}
+
+v.addEventListener("ended", playbackEnded, false);
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-10.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 10;
+
+function test_seek10(v, seekTime, is, ok, finish) {
+
+// Test bug 523335 - ensure that if we close a stream while seeking, we
+// don't hang during shutdown. This test won't "fail" per se if it's regressed,
+// it will instead start to cause random hangs in the mochitest harness on
+// shutdown.
+
+function startTest() {
+  // Must be duration*0.9 rather than seekTime, else we don't hit that problem.
+  // This is probably due to the seek bisection finishing too quickly, before
+  // we can close the stream.
+  v.currentTime = v.duration * 0.9;
+}
+
+function done(evt) {
+  ok(true, "We don't acutally test anything...");
+  finish();
+}
+
+function seeking() {
+  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
+  v.onerror = done;
+  v.src = "not a valid video file.";
+  v.load(); // Cause the existing stream to close.
+}
+
+v.addEventListener("loadeddata", startTest, false);
+v.addEventListener("seeking", seeking, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-11.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+PARALLEL_TESTS = 1;
+const SEEK_TEST_NUMBER = 11;
+
+function test_seek11(v, seekTime, is, ok, finish) {
+
+// Test for bug 476973, multiple seeks to the same position shouldn't cause problems.
+
+var seekedNonZero = false;
+var completed = false;
+var target = 0;
+
+function startTest() {
+  if (completed)
+    return;
+  target = v.duration / 2;
+  v.currentTime = target;
+  v.currentTime = target;
+  v._seekTarget = target;
+}
+
+function startSeeking() {
+  ok(v.currentTime >= v._seekTarget - 0.1,
+     "Video currentTime should be around " + v._seekTarget + ": " + v.currentTime);
+  if (!seekedNonZero) {
+    v.currentTime = target;
+    v._seekTarget = target;
+    seekedNonZero = true;
+  }
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+
+  if (v.currentTime > 0) {
+    ok(v.currentTime > target - 0.1 && v.currentTime < target + 0.1,
+       "Seek to wrong destination " + v.currentTime);
+    v.currentTime = 0.0;
+    v._seekTarget = 0.0;
+  } else {
+    ok(seekedNonZero, "Successfully seeked to nonzero");
+    ok(true, "Seek back to zero was successful");
+    completed = true;
+    finish();
+  }
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", startSeeking, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-12.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 12;
+
+function test_seek12(v, seekTime, is, ok, finish) {
+var completed = false;
+
+function startTest() {
+  if (completed)
+    return;
+  ok(!v.seeking, "seeking should default to false");
+  v.currentTime = seekTime;
+  is(v.currentTime, seekTime, "currentTime must report seek target immediately");
+  is(v.seeking, true, "seeking flag on start should be true");
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+  //is(v.currentTime, seekTime, "seeking: currentTime must be seekTime");
+  ok(Math.abs(v.currentTime - seekTime) < 0.01, "seeking: currentTime must be seekTime");
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+  completed = true;
+  //is(v.currentTime, seekTime, "seeked: currentTime must be seekTime");
+  ok(Math.abs(v.currentTime - seekTime) < 0.01, "seeked: currentTime must be seekTime");
+  is(v.seeking, false, "seeking flag on end should be false");
+  finish();
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-13.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 13;
+
+function test_seek13(v, seekTime, is, ok, finish) {
+var completed = false;
+
+function startTest() {
+  if (completed)
+    return;
+  ok(!v.seeking, "seeking should default to false");
+  v.currentTime = v.duration;
+  is(v.currentTime, v.duration, "currentTime must report seek target immediately");
+  is(v.seeking, true, "seeking flag on start should be true");
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+  //is(v.currentTime, v.duration, "seeking: currentTime must be duration");
+  ok(Math.abs(v.currentTime - v.duration) < 0.01,
+     "seeking: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")");
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+  //is(v.currentTime, v.duration, "seeked: currentTime must be duration");
+  ok(Math.abs(v.currentTime - v.duration) < 0.01,
+     "seeked: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")");
+  is(v.seeking, false, "seeking flag on end should be false");
+}
+
+function playbackEnded() {
+  if (completed)
+    return;
+  completed = true;
+  //is(v.currentTime, v.duration, "ended: currentTime must be duration");
+  ok(Math.abs(v.currentTime - v.duration) < 0.01,
+     "ended: currentTime (" + v.currentTime + ") must be duration (" + v.duration + ")");
+  is(v.seeking, false, "seeking flag on end should be false");
+  is(v.ended, true, "ended must be true");
+  finish();
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+v.addEventListener("ended", playbackEnded, false);
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-2.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+PARALLEL_TESTS = 1;
+const SEEK_TEST_NUMBER = 2;
+
+function test_seek2(v, seekTime, is, ok, finish) {
+
+// Test seeking works if current time is set before video is
+// playing.
+var startPassed = false;
+var endPassed = false;
+var completed = false;
+
+function startTest() {
+  if (completed)
+    return;
+
+  v.currentTime=seekTime;
+  v.play();
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+
+  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
+  startPassed = true;
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+
+  endPassed = true;
+}
+
+function playbackEnded() {
+  if (completed)
+    return;
+
+  completed = true;
+  ok(startPassed, "send seeking event");
+  ok(endPassed, "send seeked event");
+  ok(v.ended, "Checking playback has ended");
+  ok(Math.abs(v.currentTime - v.duration) <= 0.1, "Checking currentTime at end: " + v.currentTime);
+  finish();
+}
+
+v.addEventListener("ended", playbackEnded, false);
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-3.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 3;
+
+function test_seek3(v, seekTime, is, ok, finish) {
+
+// Test seeking works if current time is set but video is not played.
+var startPassed = false;
+var completed = false;
+var gotTimeupdate = false;
+
+function startTest() {
+  if (completed)
+    return;
+
+  v.currentTime=seekTime;
+}
+
+function timeupdate() {
+  gotTimeupdate = true;
+  v.removeEventListener("timeupdate", timeupdate, false);
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+
+  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
+  v.addEventListener("timeupdate", timeupdate, false);
+  startPassed = true;
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+
+  var t = v.currentTime;
+  ok(Math.abs(t - seekTime) <= 0.1, "Video currentTime should be around " + seekTime + ": " + t);
+  ok(gotTimeupdate, "Should have got timeupdate between seeking and seekended");
+  completed = true;
+  finish();
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-4.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 4;
+
+function test_seek4(v, seekTime, is, ok, finish) {
+
+// Test for a seek, followed by another seek before the first is complete.
+var seekCount = 0;
+var completed = false;
+
+function startTest() {
+  if (completed)
+    return;
+
+  v.currentTime=seekTime;
+  v._seekTarget=seekTime;
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+
+  seekCount += 1;
+
+  ok(v.currentTime >= v._seekTarget - 0.1,
+     "Video currentTime should be around " + v._seekTarget + ": " + v.currentTime);
+  if (seekCount == 1) {
+    v.currentTime=seekTime/2;
+    v._seekTarget=seekTime/2;
+  }
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+
+  if (seekCount == 2) {
+    ok(Math.abs(v.currentTime - seekTime/2) <= 0.1, "seek on target: " + v.currentTime);
+    completed = true;
+    finish();
+  }
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-5.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 5;
+
+function test_seek5(v, seekTime, is, ok, finish) {
+
+// Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek.
+var startPassed = false;
+var endPassed = false;
+var completed = false;
+
+function startTest() {
+  if (completed)
+    return;
+
+  v.currentTime=seekTime;
+}
+
+function seekStarted() {
+  if (completed)
+    return;
+  ok(v.currentTime >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + v.currentTime);
+  startPassed = true;
+  v.play();
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+  endPassed = true;
+}
+
+function playbackEnded() {
+  if (completed)
+    return;
+  ok(startPassed, "Got seeking event");
+  ok(endPassed, "Got seeked event");
+  completed = true;
+  finish();
+}
+
+v.addEventListener("ended", playbackEnded, false);
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeking", seekStarted, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-6.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 6;
+
+function test_seek6(v, seekTime, is, ok, finish) {
+
+// Test for bug identified by Chris Pearce in comment 40 on
+// bug 449159.
+var seekCount = 0;
+var completed = false;
+var interval;
+var sum = 0;
+
+function poll() {
+  sum += v.currentTime;
+}
+
+function startTest() {
+  if (completed)
+    return;
+  interval = setInterval(poll, 10);
+  v.currentTime = Math.random() * v.duration;
+}
+
+function seekEnded() {
+  if (completed)
+    return;
+
+  seekCount++;
+  ok(true, "Seek " + seekCount);
+  if (seekCount == 3) {
+    clearInterval(interval);
+    completed = true;
+    finish();
+  } else {
+    v.currentTime = Math.random() * v.duration;
+  }
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-7.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 7;
+
+function test_seek7(v, seekTime, is, ok, finish) {
+
+// If a NaN is passed to currentTime, make sure this is caught
+// otherwise an infinite loop in the Ogg backend occurs.
+var completed = false;
+var thrown1 = false;
+var thrown2 = false;
+var thrown3 = false;
+
+function startTest() {
+  if (completed)
+    return;
+
+  try {
+    v.currentTime = NaN;
+  } catch(e) {
+    thrown1 = true;
+  }
+
+  try {
+    v.currentTime = Math.random;
+  } catch(e) {
+    thrown3 = true;
+  }
+
+  completed = true;
+  ok(thrown1, "Setting currentTime to invalid value of NaN");
+  ok(thrown3, "Setting currentTime to invalid value of a function");
+  finish();
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-8.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 8;
+
+function test_seek8(v, seekTime, is, ok, finish) {
+
+function startTest() {
+  v.currentTime = 1000;
+}
+
+function seekEnded() {
+  ok(Math.abs(v.currentTime - v.duration) < 0.2,
+     "currentTime " + v.currentTime + " close to " + v.duration);
+  finish();
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_seek-9.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: seek tests</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="seek_support.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// The data being used in these tests is specified in manifest.js.
+// The functions to build the test array and to run a specific test are in
+//      seek_support.js.
+
+const SEEK_TEST_NUMBER = 9;
+
+function test_seek9(v, seekTime, is, ok, finish) {
+
+function startTest() {
+  v.currentTime = -1000;
+}
+
+function seekEnded() {
+  is(v.currentTime, 0, "currentTime clamped to 0");
+  finish();
+}
+
+v.addEventListener("loadedmetadata", startTest, false);
+v.addEventListener("seeked", seekEnded, false);
+
+}
+
+manager.runTests(createTestArray(), startTest);
+
+</script>
+</pre>
+</body>
+</html>
deleted file mode 100644
--- a/content/media/test/test_seek.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Media test: seek tests</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-  <script type="text/javascript" src="manifest.js"></script>
-  <script type="text/javascript" src="seek1.js"></script>
-  <script type="text/javascript" src="seek2.js"></script>
-  <script type="text/javascript" src="seek3.js"></script>
-  <script type="text/javascript" src="seek4.js"></script>
-  <script type="text/javascript" src="seek5.js"></script>
-  <script type="text/javascript" src="seek6.js"></script>
-  <script type="text/javascript" src="seek7.js"></script>
-  <script type="text/javascript" src="seek8.js"></script>
-  <script type="text/javascript" src="seek9.js"></script>
-  <script type="text/javascript" src="seek10.js"></script>
-  <script type="text/javascript" src="seek11.js"></script>
-  <script type="text/javascript" src="seek12.js"></script>
-  <script type="text/javascript" src="seek13.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-SimpleTest.requestLongerTimeout(3);
-var manager = new MediaTestManager;
-
-// https://bugzilla.mozilla.org/show_bug.cgi?id=634747
-if (navigator.platform.startsWith("Win")) {
-  SimpleTest.expectAssertions(0, 5);
-} else {
-  // This is "###!!! ASSERTION: Page read cursor should be inside range: 'mPageOffset <= endOffset'"
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=846769
-  SimpleTest.expectAssertions(0, 5);
-}
-
-const NUM_SEEK_TESTS = 13;
-
-function createTestArray() {
-  var tests = [];
-  var tmpVid = document.createElement("video");
-
-  for (var testNum=0; testNum<gSeekTests.length; testNum++) {
-    var test = gSeekTests[testNum];
-    if (!tmpVid.canPlayType(test.type)) {
-      continue;
-    }
-
-    for (var i = 1; i <= NUM_SEEK_TESTS; ++i) {
-      var t = new Object;
-      t.name = test.name;
-      t.type = test.type;
-      t.duration = test.duration;
-      t.number = i;
-      tests.push(t);
-    }
-  }
-  return tests;
-}
-
-function startTest(test, token) {
-  var v = document.createElement('video');
-  v.token = token += "-seek" + test.number + ".js";
-  manager.started(v.token);
-  v.src = test.name;
-  v.preload = "metadata";
-  document.body.appendChild(v);
-  var name = test.name + " seek test " + test.number;
-  var localIs = function(name) { return function(a, b, msg) {
-    is(a, b, name + ": " + msg);
-  }}(name);
-  var localOk = function(name) { return function(a, msg) {
-    ok(a, name + ": " + msg);
-  }}(name);
-  var localFinish = function(v, manager) { return function() {
-    v.onerror = null;
-    removeNodeAndSource(v);
-    dump("SEEK-TEST: Finished " + name + " token: " + v.token + "\n");
-    manager.finished(v.token);
-  }}(v, manager);
-  dump("SEEK-TEST: Started " + name + "\n");
-  window['test_seek' + test.number](v, test.duration/2, localIs, localOk, localFinish);
-}
-
-manager.runTests(createTestArray(), startTest);
-
-</script>
-</pre>
-</body>
-</html>
--- a/docshell/base/nsDSURIContentListener.h
+++ b/docshell/base/nsDSURIContentListener.h
@@ -24,17 +24,17 @@ class nsDSURIContentListener :
 friend class nsDocShell;
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIURICONTENTLISTENER
 
     nsresult Init();
 
 protected:
-    nsDSURIContentListener(nsDocShell* aDocShell);
+    explicit nsDSURIContentListener(nsDocShell* aDocShell);
     virtual ~nsDSURIContentListener();
 
     void DropDocShellreference() {
         mDocShell = nullptr;
     }
 
     // Determine if X-Frame-Options allows content to be framed
     // as a subdocument
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -660,17 +660,17 @@ protected:
      * After calling this, mTiming is non-null.
      */
     void MaybeInitTiming();
 
     // Event type dispatched by RestorePresentation
     class RestorePresentationEvent : public nsRunnable {
     public:
         NS_DECL_NSIRUNNABLE
-        RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {}
+        explicit RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {}
         void Revoke() { mDocShell = nullptr; }
     private:
         nsRefPtr<nsDocShell> mDocShell;
     };
 
     bool JustStartedNetworkLoad();
 
     enum FrameType {
@@ -923,17 +923,17 @@ private:
 #ifdef DEBUG
     // We're counting the number of |nsDocShells| to help find leaks
     static unsigned long gNumberOfDocShells;
 #endif /* DEBUG */
 
 public:
     class InterfaceRequestorProxy : public nsIInterfaceRequestor {
     public:
-        InterfaceRequestorProxy(nsIInterfaceRequestor* p);
+        explicit InterfaceRequestorProxy(nsIInterfaceRequestor* p);
         NS_DECL_THREADSAFE_ISUPPORTS
         NS_DECL_NSIINTERFACEREQUESTOR
  
     protected:
         virtual ~InterfaceRequestorProxy();
         InterfaceRequestorProxy() {}
         nsWeakPtr mWeakPtr;
     };
--- a/docshell/base/nsDocShellEditorData.h
+++ b/docshell/base/nsDocShellEditorData.h
@@ -15,17 +15,17 @@
 class nsIDocShell;
 class nsIEditingSession;
 class nsIEditor;
 
 class nsDocShellEditorData
 {
 public:
 
-  nsDocShellEditorData(nsIDocShell* inOwningDocShell);
+  explicit nsDocShellEditorData(nsIDocShell* inOwningDocShell);
   ~nsDocShellEditorData();
 
   nsresult MakeEditable(bool inWaitForUriLoad);
   bool GetEditable();
   nsresult CreateEditor();
   nsresult GetEditingSession(nsIEditingSession **outEditingSession);
   nsresult GetEditor(nsIEditor **outEditor);
   nsresult SetEditor(nsIEditor *inEditor);
--- a/docshell/base/nsDocShellEnumerator.h
+++ b/docshell/base/nsDocShellEnumerator.h
@@ -37,17 +37,17 @@ protected:
     enumerateForwards,
     enumerateBackwards
   };
 
   virtual                     ~nsDocShellEnumerator();
 
 public:
 
-                              nsDocShellEnumerator(int32_t inEnumerationDirection);
+                              explicit nsDocShellEnumerator(int32_t inEnumerationDirection);
 
   // nsISupports
   NS_DECL_ISUPPORTS
   
   // nsISimpleEnumerator
   NS_DECL_NSISIMPLEENUMERATOR
   
 public:
--- a/docshell/shistory/src/nsSHistory.h
+++ b/docshell/shistory/src/nsSHistory.h
@@ -103,17 +103,17 @@ protected:
 //*****************************************************************************
 class nsSHEnumerator : public nsISimpleEnumerator
 {
 public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISIMPLEENUMERATOR
 
-  nsSHEnumerator(nsSHistory *  aHistory);
+  explicit nsSHEnumerator(nsSHistory *  aHistory);
   
 protected:
   friend class nsSHistory;
   virtual ~nsSHEnumerator();
 private:
   int32_t     mIndex;
   nsSHistory *  mSHistory;  
 };
--- a/dom/audiochannel/AudioChannelAgent.cpp
+++ b/dom/audiochannel/AudioChannelAgent.cpp
@@ -75,19 +75,16 @@ AudioChannelAgent::InitWithVideo(nsIDOMW
                       /* withVideo = */ true);
 }
 
 nsresult
 AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
                                 nsIAudioChannelAgentCallback *aCallback,
                                 bool aUseWeakRef, bool aWithVideo)
 {
-  // We need the window only for IPC.
-  MOZ_ASSERT(aWindow || XRE_GetProcessType() == GeckoProcessType_Default);
-
   // We syncd the enum of channel type between nsIAudioChannelAgent.idl and
   // AudioChannelBinding.h the same.
   MOZ_ASSERT(int(AUDIO_AGENT_CHANNEL_NORMAL) == int(AudioChannel::Normal) &&
              int(AUDIO_AGENT_CHANNEL_CONTENT) == int(AudioChannel::Content) &&
              int(AUDIO_AGENT_CHANNEL_NOTIFICATION) == int(AudioChannel::Notification) &&
              int(AUDIO_AGENT_CHANNEL_ALARM) == int(AudioChannel::Alarm) &&
              int(AUDIO_AGENT_CHANNEL_TELEPHONY) == int(AudioChannel::Telephony) &&
              int(AUDIO_AGENT_CHANNEL_RINGER) == int(AudioChannel::Ringer) &&
--- a/dom/base/DOMError.h
+++ b/dom/base/DOMError.h
@@ -39,17 +39,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMError)
 
   NS_DECLARE_STATIC_IID_ACCESSOR(DOMERROR_IID)
 
   // aWindow can be null if this DOMError is not associated with a particular
   // window.
 
-  DOMError(nsPIDOMWindow* aWindow);
+  explicit DOMError(nsPIDOMWindow* aWindow);
 
   DOMError(nsPIDOMWindow* aWindow, nsresult aValue);
 
   DOMError(nsPIDOMWindow* aWindow, const nsAString& aName);
 
   DOMError(nsPIDOMWindow* aWindow, const nsAString& aName,
            const nsAString& aMessage);
 
--- a/dom/base/MessageChannel.h
+++ b/dom/base/MessageChannel.h
@@ -26,17 +26,17 @@ class MessageChannel MOZ_FINAL : public 
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MessageChannel)
 
   static bool Enabled(JSContext* aCx, JSObject* aGlobal);
 
 public:
-  MessageChannel(nsPIDOMWindow* aWindow);
+  explicit MessageChannel(nsPIDOMWindow* aWindow);
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -23,17 +23,17 @@
 namespace mozilla {
 namespace dom {
 
 class DispatchEventRunnable : public nsRunnable
 {
   friend class MessagePort;
 
   public:
-    DispatchEventRunnable(MessagePort* aPort)
+    explicit DispatchEventRunnable(MessagePort* aPort)
       : mPort(aPort)
     {
     }
 
     NS_IMETHOD
     Run()
     {
       nsRefPtr<DispatchEventRunnable> mKungFuDeathGrip(this);
--- a/dom/base/MessagePort.h
+++ b/dom/base/MessagePort.h
@@ -15,17 +15,17 @@ namespace mozilla {
 namespace dom {
 
 class DispatchEventRunnable;
 class PostMessageRunnable;
 
 class MessagePortBase : public DOMEventTargetHelper
 {
 protected:
-  MessagePortBase(nsPIDOMWindow* aWindow);
+  explicit MessagePortBase(nsPIDOMWindow* aWindow);
   MessagePortBase();
 
 public:
 
   virtual void
   PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                 const Optional<Sequence<JS::Value>>& aTransferable,
                 ErrorResult& aRv) = 0;
@@ -56,17 +56,17 @@ class MessagePort MOZ_FINAL : public Mes
   friend class DispatchEventRunnable;
   friend class PostMessageRunnable;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort,
                                            DOMEventTargetHelper)
 
-  MessagePort(nsPIDOMWindow* aWindow);
+  explicit MessagePort(nsPIDOMWindow* aWindow);
 
   virtual JSObject*
   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   virtual void
   PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                  const Optional<Sequence<JS::Value>>& aTransferable,
                  ErrorResult& aRv) MOZ_OVERRIDE;
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -53,17 +53,17 @@ private:
   nsTArray<bool> mNodeIsRoot;
   uint32_t mLength;
 };
 
 class nsDOMWindowUtils MOZ_FINAL : public nsIDOMWindowUtils,
                                    public nsSupportsWeakReference
 {
 public:
-  nsDOMWindowUtils(nsGlobalWindow *aWindow);
+  explicit nsDOMWindowUtils(nsGlobalWindow *aWindow);
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMWINDOWUTILS
 
 protected:
   ~nsDOMWindowUtils();
 
   nsWeakPtr mWindow;
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -705,17 +705,17 @@ nsFocusManager::WindowRaised(nsIDOMWindo
 
   nsCOMPtr<nsIDocShell> currentDocShell = currentWindow->GetDocShell();
 
   nsCOMPtr<nsIPresShell> presShell = currentDocShell->GetPresShell();
   if (presShell) {
     // disable selection mousedown state on activation
     // XXXndeakin P3 not sure if this is necessary, but it doesn't hurt
     nsRefPtr<nsFrameSelection> frameSelection = presShell->FrameSelection();
-    frameSelection->SetMouseDownState(false);
+    frameSelection->SetDragState(false);
   }
 
   Focus(currentWindow, currentFocus, 0, true, false, true, true);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8641,17 +8641,17 @@ nsGlobalWindow::EnterModalState()
         nsContentUtils::ContentIsCrossDocDescendantOf(activeShell->GetDocument(), mDoc) ||
         nsContentUtils::ContentIsCrossDocDescendantOf(mDoc, activeShell->GetDocument()))) {
       EventStateManager::ClearGlobalActiveContent(activeESM);
 
       activeShell->SetCapturingContent(nullptr, 0);
 
       if (activeShell) {
         nsRefPtr<nsFrameSelection> frameSelection = activeShell->FrameSelection();
-        frameSelection->SetMouseDownState(false);
+        frameSelection->SetDragState(false);
       }
     }
   }
 
   // If there are any drag and drop operations in flight, try to end them.
   nsCOMPtr<nsIDragService> ds =
     do_GetService("@mozilla.org/widget/dragservice;1");
   if (ds) {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -518,17 +518,17 @@ public:
   bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
                     JS::Handle<jsid> aId,
                     JS::MutableHandle<JSPropertyDescriptor> aDesc);
 
   void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
                            mozilla::ErrorResult& aRv);
 
   // Object Management
-  nsGlobalWindow(nsGlobalWindow *aOuterWindow);
+  explicit nsGlobalWindow(nsGlobalWindow *aOuterWindow);
 
   static nsGlobalWindow *FromSupports(nsISupports *supports)
   {
     // Make sure this matches the casts we do in QueryInterface().
     return (nsGlobalWindow *)(mozilla::dom::EventTarget *)supports;
   }
   static nsGlobalWindow *FromWrapper(nsIXPConnectWrappedNative *wrapper)
   {
@@ -1661,17 +1661,17 @@ class nsGlobalChromeWindow : public nsGl
 {
 public:
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMChromeWindow interface
   NS_DECL_NSIDOMCHROMEWINDOW
 
-  nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow)
+  explicit nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow)
     : nsGlobalWindow(aOuterWindow),
       mGroupMessageManagers(1)
   {
     mIsChrome = true;
     mCleanMessageManager = true;
   }
 
   static PLDHashOperator
@@ -1728,17 +1728,17 @@ public:
  * nsGlobalModalWindow inherits from nsGlobalWindow. It is the global
  * object created for a modal content windows only (i.e. not modal
  * chrome dialogs).
  */
 class nsGlobalModalWindow : public nsGlobalWindow,
                             public nsIDOMModalContentWindow
 {
 public:
-  nsGlobalModalWindow(nsGlobalWindow *aOuterWindow)
+  explicit nsGlobalModalWindow(nsGlobalWindow *aOuterWindow)
     : nsGlobalWindow(aOuterWindow)
   {
     mIsModalContentWindow = true;
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMMODALCONTENTWINDOW
 
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -724,17 +724,17 @@ public:
   {
     return mMarkedCCGeneration;
   }
 protected:
   // The nsPIDOMWindow constructor. The aOuterWindow argument should
   // be null if and only if the created window itself is an outer
   // window. In all other cases aOuterWindow should be the outer
   // window for the inner window that is being created.
-  nsPIDOMWindow(nsPIDOMWindow *aOuterWindow);
+  explicit nsPIDOMWindow(nsPIDOMWindow *aOuterWindow);
 
   ~nsPIDOMWindow();
 
   void SetChromeEventHandlerInternal(mozilla::dom::EventTarget* aChromeEventHandler) {
     mChromeEventHandler = aChromeEventHandler;
     // mParentTarget will be set when the next event is dispatched.
     mParentTarget = nullptr;
   }
@@ -837,17 +837,17 @@ PopPopupControlState(PopupControlState a
 // part of the layout library than it does in code outside the layout
 // library.  We give the two object layouts different names so the symbols
 // don't conflict, but code should always use the name
 // |nsAutoPopupStatePusher|.
 class NS_AUTO_POPUP_STATE_PUSHER
 {
 public:
 #ifdef MOZILLA_INTERNAL_API
-  NS_AUTO_POPUP_STATE_PUSHER(PopupControlState aState, bool aForce = false)
+  explicit NS_AUTO_POPUP_STATE_PUSHER(PopupControlState aState, bool aForce = false)
     : mOldState(::PushPopupControlState(aState, aForce))
   {
   }
 
   ~NS_AUTO_POPUP_STATE_PUSHER()
   {
     PopPopupControlState(mOldState);
   }
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1443,16 +1443,17 @@ WrapNativeParent(JSContext* cx, T* p, ns
   // If useXBLScope is true, it means that the canonical reflector for this
   // native object should live in the content XBL scope. Note that we never put
   // anonymous content inside an add-on scope.
   if (xpc::IsInContentXBLScope(parent)) {
     return parent;
   }
   JS::Rooted<JSObject*> rootedParent(cx, parent);
   JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScope(cx, rootedParent));
+  NS_ENSURE_TRUE(xblScope, nullptr);
   JSAutoCompartment ac(cx, xblScope);
   if (NS_WARN_IF(!JS_WrapObject(cx, &rootedParent))) {
     return nullptr;
   }
 
   return rootedParent;
 }
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -10443,16 +10443,69 @@ class CGDOMJSProxyHandlerDefiner(CGThing
         return self.handlerThing.define()
 
 
 def stripTrailingWhitespace(text):
     tail = '\n' if text.endswith('\n') else ''
     lines = text.splitlines()
     return '\n'.join(line.rstrip() for line in lines) + tail
 
+class MemberProperties:
+    def __init__(self):
+        self.isGenericMethod = False
+        self.isCrossOriginMethod = False
+        self.isPromiseReturningMethod = False
+        self.isGenericGetter = False
+        self.isLenientGetter = False
+        self.isCrossOriginGetter = False
+        self.isGenericSetter = False
+        self.isLenientSetter = False
+        self.isCrossOriginSetter = False
+        self.isJsonifier = False
+
+def memberProperties(m, descriptor):
+    props = MemberProperties()
+    if m.isMethod():
+        if m == descriptor.operations['Jsonifier']:
+            props.isGenericMethod = descriptor.needsSpecialGenericOps()
+            props.isJsonifier = True
+        elif (not m.isIdentifierLess() or m == descriptor.operations['Stringifier']):
+            if not m.isStatic() and descriptor.interface.hasInterfacePrototypeObject():
+                if m.returnsPromise() and descriptor.needsSpecialGenericOps():
+                    props.isPromiseReturningMethod = True
+                if m.getExtendedAttribute("CrossOriginCallable"):
+                    props.isCrossOriginMethod = True
+                elif descriptor.needsSpecialGenericOps():
+                    props.isGenericMethod = True
+    elif m.isAttr():
+        if not m.isStatic() and descriptor.interface.hasInterfacePrototypeObject():
+            if m.hasLenientThis():
+                props.isLenientGetter = True
+            elif m.getExtendedAttribute("CrossOriginReadable"):
+                props.isCrossOriginGetter = True
+            elif descriptor.needsSpecialGenericOps():
+                props.isGenericGetter = True
+        if not m.readonly:
+            if not m.isStatic() and descriptor.interface.hasInterfacePrototypeObject():
+                if m.hasLenientThis():
+                    props.isLenientSetter = True
+                elif IsCrossOriginWritable(m, descriptor):
+                    props.isCrossOriginSetter = True
+                elif descriptor.needsSpecialGenericOps():
+                    props.isGenericSetter = True
+        elif m.getExtendedAttribute("PutForwards"):
+            if IsCrossOriginWritable(m, descriptor):
+                props.isCrossOriginSetter = True
+            elif descriptor.needsSpecialGenericOps():
+                props.isGenericSetter = True
+        elif m.getExtendedAttribute("Replaceable"):
+            if descriptor.needsSpecialGenericOps():
+                props.isGenericSetter = True
+
+    return props
 
 class CGDescriptor(CGThing):
     def __init__(self, descriptor):
         CGThing.__init__(self)
 
         assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 
         if descriptor.nativeOwnership == 'owned' and (
@@ -10462,99 +10515,93 @@ class CGDescriptor(CGThing):
 
         self._deps = descriptor.interface.getDeps()
 
         cgThings = []
         cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" %
                                   descriptor.nativeType))
         # These are set to true if at least one non-static
         # method/getter/setter or jsonifier exist on the interface.
-        (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasJsonifier,
-            hasLenientSetter,
-            hasPromiseReturningMethod) = False, False, False, False, False, False, False
+        (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter,
+            hasPromiseReturningMethod) = False, False, False, False, False, False
+        jsonifierMethod = None
         crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
         for n in descriptor.interface.namedConstructors:
             cgThings.append(CGClassConstructor(descriptor, n,
                                                NamedConstructorName(n)))
         for m in descriptor.interface.members:
             if m.isMethod() and m.identifier.name == 'queryInterface':
                 continue
             if not isMaybeExposedIn(m, descriptor):
                 continue
-            if m.isMethod() and m == descriptor.operations['Jsonifier']:
-                hasJsonifier = True
-                hasMethod = descriptor.needsSpecialGenericOps()
-                jsonifierMethod = m
-            elif (m.isMethod() and
-                  (not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])):
-                if m.isStatic():
-                    assert descriptor.interface.hasInterfaceObject()
-                    cgThings.append(CGStaticMethod(descriptor, m))
-                    if m.returnsPromise():
-                        cgThings.append(CGStaticMethodJitinfo(m))
-                elif descriptor.interface.hasInterfacePrototypeObject():
-                    specializedMethod = CGSpecializedMethod(descriptor, m)
-                    cgThings.append(specializedMethod)
-                    if m.returnsPromise():
-                        if descriptor.needsSpecialGenericOps():
-                            hasPromiseReturningMethod = True
-                        cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod))
-                    cgThings.append(CGMemberJITInfo(descriptor, m))
-                    if m.getExtendedAttribute("CrossOriginCallable"):
-                        crossOriginMethods.add(m.identifier.name)
-                    elif descriptor.needsSpecialGenericOps():
-                        hasMethod = True
+
+            props = memberProperties(m, descriptor)
+
+            if m.isMethod():
+                if props.isJsonifier:
+                    jsonifierMethod = m
+                elif not m.isIdentifierLess() or m == descriptor.operations['Stringifier']:
+                    if m.isStatic():
+                        assert descriptor.interface.hasInterfaceObject()
+                        cgThings.append(CGStaticMethod(descriptor, m))
+                        if m.returnsPromise():
+                            cgThings.append(CGStaticMethodJitinfo(m))
+                    elif descriptor.interface.hasInterfacePrototypeObject():
+                        specializedMethod = CGSpecializedMethod(descriptor, m)
+                        cgThings.append(specializedMethod)
+                        if m.returnsPromise():
+                            cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod))
+                        cgThings.append(CGMemberJITInfo(descriptor, m))
+                        if props.isCrossOriginMethod:
+                            crossOriginMethods.add(m.identifier.name)
             elif m.isAttr():
                 if m.stringifier:
                     raise TypeError("Stringifier attributes not supported yet. "
                                     "See bug 824857.\n"
                                     "%s" % m.location)
                 if m.isStatic():
                     assert descriptor.interface.hasInterfaceObject()
                     cgThings.append(CGStaticGetter(descriptor, m))
                 elif descriptor.interface.hasInterfacePrototypeObject():
                     cgThings.append(CGSpecializedGetter(descriptor, m))
-                    if m.hasLenientThis():
-                        hasLenientGetter = True
-                    elif m.getExtendedAttribute("CrossOriginReadable"):
+                    if props.isCrossOriginGetter:
                         crossOriginGetters.add(m.identifier.name)
-                    elif descriptor.needsSpecialGenericOps():
-                        hasGetter = True
                 if not m.readonly:
                     for extAttr in ["PutForwards", "Replaceable"]:
                         if m.getExtendedAttribute(extAttr):
                             raise TypeError("Writable attributes should not "
                                             "have %s specified.\n"
                                             "%s" %
                                             (extAttr, m.location))
                     if m.isStatic():
                         assert descriptor.interface.hasInterfaceObject()
                         cgThings.append(CGStaticSetter(descriptor, m))
                     elif descriptor.interface.hasInterfacePrototypeObject():
                         cgThings.append(CGSpecializedSetter(descriptor, m))
-                        if m.hasLenientThis():
-                            hasLenientSetter = True
-                        elif IsCrossOriginWritable(m, descriptor):
+                        if props.isCrossOriginSetter:
                             crossOriginSetters.add(m.identifier.name)
-                        elif descriptor.needsSpecialGenericOps():
-                            hasSetter = True
                 elif m.getExtendedAttribute("PutForwards"):
                     cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
-                    if IsCrossOriginWritable(m, descriptor):
+                    if props.isCrossOriginSetter:
                         crossOriginSetters.add(m.identifier.name)
-                    elif descriptor.needsSpecialGenericOps():
-                        hasSetter = True
                 elif m.getExtendedAttribute("Replaceable"):
                     cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))
-                    if descriptor.needsSpecialGenericOps():
-                        hasSetter = True
                 if (not m.isStatic() and
                     descriptor.interface.hasInterfacePrototypeObject()):
                     cgThings.append(CGMemberJITInfo(descriptor, m))
-        if hasJsonifier:
+
+            hasMethod = hasMethod or props.isGenericMethod
+            hasPromiseReturningMethod = (hasPromiseReturningMethod or
+                                         props.isPromiseReturningMethod)
+            hasGetter = hasGetter or props.isGenericGetter
+            hasLenientGetter = hasLenientGetter or props.isLenientGetter
+            hasSetter = hasSetter or props.isGenericSetter
+            hasLenientSetter = hasLenientSetter or props.isLenientSetter
+
+        if jsonifierMethod:
             cgThings.append(CGJsonifierMethod(descriptor, jsonifierMethod))
             cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
         if hasMethod:
             cgThings.append(CGGenericMethod(descriptor))
         if hasPromiseReturningMethod:
             cgThings.append(CGGenericPromiseReturningMethod(descriptor))
         if len(crossOriginMethods):
             cgThings.append(CGGenericMethod(descriptor,
@@ -11598,20 +11645,40 @@ class CGForwardDeclarations(CGWrapper):
 
 class CGBindingRoot(CGThing):
     """
     Root codegen class for binding generation. Instantiate the class, and call
     declare or define to generate header or cpp code (respectively).
     """
     def __init__(self, config, prefix, webIDLFile):
         bindingHeaders = {}
+        bindingDeclareHeaders = dict.fromkeys((
+            'mozilla/dom/BindingDeclarations.h',
+            'mozilla/dom/Nullable.h',
+            'mozilla/ErrorResult.h',
+            ),
+            True)
+
         descriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                             hasInterfaceOrInterfacePrototypeObject=True,
                                             skipGen=False)
 
+        def descriptorHasCrossOriginProperties(desc):
+            def hasCrossOriginProperty(m):
+                props = memberProperties(m, desc)
+                return (props.isCrossOriginMethod or
+                        props.isCrossOriginGetter or
+                        props.isCrossOriginSetter)
+
+            return any(hasCrossOriginProperty(m) for m in desc.interface.members)
+
+        bindingDeclareHeaders["jsapi.h"] = any(descriptorHasCrossOriginProperties(d) for d in descriptors)
+        bindingDeclareHeaders["jspubtd.h"] = not bindingDeclareHeaders["jsapi.h"]
+        bindingDeclareHeaders["js/RootingAPI.h"] = not bindingDeclareHeaders["jsapi.h"]
+
         def descriptorRequiresPreferences(desc):
             iface = desc.interface
             return any(m.getExtendedAttribute("Pref") for m in iface.members + [iface])
 
         bindingHeaders["mozilla/Preferences.h"] = any(
             descriptorRequiresPreferences(d) for d in descriptors)
         bindingHeaders["mozilla/dom/NonRefcountedDOMObject.h"] = any(
             d.nativeOwnership == 'owned' for d in descriptors)
@@ -11642,16 +11709,17 @@ class CGBindingRoot(CGThing):
         mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
                                             workers=False)
         workerCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
                                               workers=True)
         callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                                     isCallback=True)
         jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
                                               isJSImplemented=True)
+        bindingDeclareHeaders["nsWeakReference.h"] = jsImplemented
         bindingHeaders["nsPIDOMWindow.h"] = jsImplemented
         bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors
 
         def addHeaderBasedOnTypes(header, typeChecker):
             bindingHeaders[header] = (
                 bindingHeaders.get(header, False) or
                 any(map(typeChecker,
                         getAllTypes(descriptors + callbackDescriptors,
@@ -11746,31 +11814,25 @@ class CGBindingRoot(CGThing):
                                              callbackDescriptors + jsImplemented),
                        curr],
                       "\n")
 
         # Add header includes.
         bindingHeaders = [header
                           for header, include in bindingHeaders.iteritems()
                           if include]
-        declareIncludes = [
-            'mozilla/dom/BindingDeclarations.h',
-            'mozilla/dom/Nullable.h',
-            'mozilla/ErrorResult.h',
-            'jspubtd.h',
-            'js/RootingAPI.h',
-        ]
-        if jsImplemented:
-            declareIncludes.append('nsWeakReference.h')
+        bindingDeclareHeaders = [header
+                                 for header, include in bindingDeclareHeaders.iteritems()
+                                 if include]
 
         curr = CGHeaders(descriptors,
                          dictionaries,
                          mainCallbacks + workerCallbacks,
                          callbackDescriptors,
-                         declareIncludes,
+                         bindingDeclareHeaders,
                          bindingHeaders,
                          prefix,
                          curr,
                          config,
                          jsImplemented)
 
         # Add include guards.
         curr = CGIncludeGuard(prefix, curr)
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -228,17 +228,17 @@ typedef TypedArray<uint8_t, js::UnwrapAr
 //       So this is best used to pass from things that understand nsTArray to
 //       things that understand TypedArray, as with Promise::ArgumentToJSValue.
 template<typename TypedArrayType>
 class TypedArrayCreator
 {
   typedef nsTArray<typename TypedArrayType::element_type> ArrayType;
 
   public:
-    TypedArrayCreator(const ArrayType& aArray)
+    explicit TypedArrayCreator(const ArrayType& aArray)
       : mArray(aArray)
     {}
 
     JSObject* Create(JSContext* aCx) const
     {
       return TypedArrayType::Create(aCx, mArray.Length(), mArray.Elements());
     }
 
@@ -293,17 +293,17 @@ private:
 };
 
 // Class for easily setting up a rooted typed array object on the stack
 template<typename ArrayType>
 class MOZ_STACK_CLASS RootedTypedArray : public ArrayType,
                                          private TypedArrayRooter<ArrayType>
 {
 public:
-  RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
+  explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
     ArrayType(),
     TypedArrayRooter<ArrayType>(cx,
                                 MOZ_THIS_IN_INITIALIZER_LIST()
                                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
   {
   }
 
   RootedTypedArray(JSContext* cx, JSObject* obj MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -31,26 +31,26 @@ class DOMEventTargetHelper : public dom:
 {
 public:
   DOMEventTargetHelper()
     : mParentObject(nullptr)
     , mOwnerWindow(nullptr)
     , mHasOrHasHadOwnerWindow(false)
   {
   }
-  DOMEventTargetHelper(nsPIDOMWindow* aWindow)
+  explicit DOMEventTargetHelper(nsPIDOMWindow* aWindow)
     : mParentObject(nullptr)
     , mOwnerWindow(nullptr)
     , mHasOrHasHadOwnerWindow(false)
   {
     BindToOwner(aWindow);
     // All objects coming through here are WebIDL objects
     SetIsDOMBinding();
   }
-  DOMEventTargetHelper(DOMEventTargetHelper* aOther)
+  explicit DOMEventTargetHelper(DOMEventTargetHelper* aOther)
     : mParentObject(nullptr)
     , mOwnerWindow(nullptr)
     , mHasOrHasHadOwnerWindow(false)
   {
     BindToOwner(aOther);
     // All objects coming through here are WebIDL objects
     SetIsDOMBinding();
   }
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -39,17 +39,17 @@ class EventBase : public nsIDOMEvent
 
 class Event : public EventBase,
               public nsWrapperCache
 {
 public:
   Event(EventTarget* aOwner,
         nsPresContext* aPresContext,
         WidgetEvent* aEvent);
-  Event(nsPIDOMWindow* aWindow);
+  explicit Event(nsPIDOMWindow* aWindow);
 
 protected:
   virtual ~Event();
 
 private:
   void ConstructorInit(EventTarget* aOwner,
                        nsPresContext* aPresContext,
                        WidgetEvent* aEvent);
--- a/dom/events/EventDispatcher.h
+++ b/dom/events/EventDispatcher.h
@@ -193,17 +193,17 @@ public:
    * which should be used when the event is handled at mParentTarget.
    */
   dom::EventTarget* mEventTargetAtParent;
 };
 
 class EventChainPostVisitor : public mozilla::EventChainVisitor
 {
 public:
-  EventChainPostVisitor(EventChainVisitor& aOther)
+  explicit EventChainPostVisitor(EventChainVisitor& aOther)
     : EventChainVisitor(aOther.mPresContext, aOther.mEvent,
                         aOther.mDOMEvent, aOther.mEventStatus)
   {
   }
 };
 
 /**
  * If an EventDispatchingCallback object is passed to Dispatch,
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -206,17 +206,17 @@ public:
       // FIXME Should check !mFlags.mCapture when the event is in target
       //       phase because capture phase event listeners should not be fired.
       //       But it breaks at least <xul:dialog>'s buttons. Bug 235441.
       return ((mFlags.mCapture && aEvent->mFlags.mInCapturePhase) ||
               (!mFlags.mCapture && aEvent->mFlags.mInBubblingPhase));
     }
   };
 
-  EventListenerManager(dom::EventTarget* aTarget);
+  explicit EventListenerManager(dom::EventTarget* aTarget);
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(EventListenerManager)
 
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(EventListenerManager)
 
   void AddEventListener(const nsAString& aType,
                         nsIDOMEventListener* aListener,
                         bool aUseCapture,
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -1439,20 +1439,20 @@ EventStateManager::FireContextClick()
       FillInEventFromGestureDown(&event);
         
       // stop selection tracking, we're in control now
       if (mCurrentTarget)
       {
         nsRefPtr<nsFrameSelection> frameSel =
           mCurrentTarget->GetFrameSelection();
         
-        if (frameSel && frameSel->GetMouseDownState()) {
+        if (frameSel && frameSel->GetDragState()) {
           // note that this can cause selection changed events to fire if we're in
           // a text field, which will null out mCurrentTarget
-          frameSel->SetMouseDownState(false);
+          frameSel->SetDragState(false);
         }
       }
 
       nsIDocument* doc = mGestureDownContent->GetCrossShadowCurrentDoc();
       AutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc);
 
       // dispatch to DOM
       EventDispatcher::Dispatch(mGestureDownContent, mPresContext, &event,
@@ -1561,17 +1561,17 @@ EventStateManager::GenerateDragGesture(n
       return;
     }
 
     // Check if selection is tracking drag gestures, if so
     // don't interfere!
     if (mCurrentTarget)
     {
       nsRefPtr<nsFrameSelection> frameSel = mCurrentTarget->GetFrameSelection();
-      if (frameSel && frameSel->GetMouseDownState()) {
+      if (frameSel && frameSel->GetDragState()) {
         StopTrackingDragGesture();
         return;
       }
     }
 
     // If non-native code is capturing the mouse don't start a drag.
     if (nsIPresShell::IsMouseCapturePreventingDrag()) {
       StopTrackingDragGesture();
@@ -2903,17 +2903,17 @@ EventStateManager::PostHandleEvent(nsPre
         // Make sure to dispatch the click even if there is no frame for
         // the current target element. This is required for Web compatibility.
         ret = CheckForAndDispatchClick(presContext, mouseEvent, aStatus);
       }
 
       nsIPresShell *shell = presContext->GetPresShell();
       if (shell) {
         nsRefPtr<nsFrameSelection> frameSelection = shell->FrameSelection();
-        frameSelection->SetMouseDownState(false);
+        frameSelection->SetDragState(false);
       }
     }
     break;
   case NS_WHEEL_STOP:
     {
       MOZ_ASSERT(aEvent->mFlags.mIsTrusted);
       ScrollbarsForWheel::MayInactivate();
     }
--- a/dom/events/JSEventHandler.h
+++ b/dom/events/JSEventHandler.h
@@ -30,27 +30,27 @@ public:
     eTypeBits = 0x3
   };
 
   TypedEventHandler()
     : mBits(0)
   {
   }
 
-  TypedEventHandler(dom::EventHandlerNonNull* aHandler)
+  explicit TypedEventHandler(dom::EventHandlerNonNull* aHandler)
   {
     Assign(aHandler, eNormal);
   }
 
-  TypedEventHandler(dom::OnErrorEventHandlerNonNull* aHandler)
+  explicit TypedEventHandler(dom::OnErrorEventHandlerNonNull* aHandler)
   {
     Assign(aHandler, eOnError);
   }
 
-  TypedEventHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
+  explicit TypedEventHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
   {
     Assign(aHandler, eOnBeforeUnload);
   }
 
   TypedEventHandler(const TypedEventHandler& aOther)
   {
     if (aOther.HasEventHandler()) {
       // Have to make sure we take our own ref
--- a/dom/events/StorageEvent.h
+++ b/dom/events/StorageEvent.h
@@ -23,17 +23,17 @@ namespace dom {
 class DOMStorage;
 
 class StorageEvent : public Event
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(StorageEvent, Event)
 
-  StorageEvent(EventTarget* aOwner);
+  explicit StorageEvent(EventTarget* aOwner);
 
 protected:
   virtual ~StorageEvent();
 
   nsString mKey;
   nsString mOldValue;
   nsString mNewValue;
   nsString mUrl;
--- a/dom/events/test/test_focus_disabled.html
+++ b/dom/events/test/test_focus_disabled.html
@@ -9,20 +9,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=375008">Mozilla Bug 375008</a>
 <p id="display"></p>
 <div id="content">
-  <div>
-    <input id='witness'>
-  </div>
-
   <div id='not-focusable'>
     <!-- Disabled elements -->
     <button hidden disabled>foo</button>
     <input hidden disabled>
     <fieldset hidden disabled>foo</fieldset>
     <select hidden disabled><option>foo</option></select>
     <textarea hidden disabled></textarea>
     <optgroup hidden disabled><option>foo</option></optgroup>
@@ -47,16 +43,20 @@ https://bugzilla.mozilla.org/show_bug.cg
     <input hidden>
     <fieldset hidden>foo</fieldset>
     <select hidden><option>foo</option></select>
     <textarea hidden></textarea>
     <optgroup hidden><option>foo</option></optgroup>
     <option hidden>foo</option>
   </div>
 
+  <div>
+    <input id='witness'>
+  </div>
+
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 375008 **/
 
 /*
  * This test is divided in three parts:
--- a/dom/indexedDB/FileInfo.h
+++ b/dom/indexedDB/FileInfo.h
@@ -14,17 +14,17 @@
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 class FileInfo
 {
   friend class FileManager;
 
 public:
-  FileInfo(FileManager* aFileManager)
+  explicit FileInfo(FileManager* aFileManager)
   : mFileManager(aFileManager)
   { }
 
   virtual ~FileInfo()
   { }
 
   static
   FileInfo* Create(FileManager* aFileManager, int64_t aId);
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -148,18 +148,18 @@ public:
 
   IDBRequestReadyState
   ReadyState() const;
 
   IMPL_EVENT_HANDLER(success);
   IMPL_EVENT_HANDLER(error);
 
 protected:
-  IDBRequest(IDBDatabase* aDatabase);
-  IDBRequest(nsPIDOMWindow* aOwner);
+  explicit IDBRequest(IDBDatabase* aDatabase);
+  explicit IDBRequest(nsPIDOMWindow* aOwner);
   ~IDBRequest();
 
   // At most one of these three fields can be non-null.
   nsRefPtr<IDBObjectStore> mSourceAsObjectStore;
   nsRefPtr<IDBIndex> mSourceAsIndex;
   nsRefPtr<IDBCursor> mSourceAsCursor;
 
   // Check that the above condition holds.
@@ -216,17 +216,17 @@ public:
   virtual JSObject*
   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   // WebIDL
   IMPL_EVENT_HANDLER(blocked);
   IMPL_EVENT_HANDLER(upgradeneeded);
 
 protected:
-  IDBOpenDBRequest(nsPIDOMWindow* aOwner);
+  explicit IDBOpenDBRequest(nsPIDOMWindow* aOwner);
   ~IDBOpenDBRequest();
 
   // Only touched on the main thread.
   nsRefPtr<IDBFactory> mFactory;
 };
 
 END_INDEXEDDB_NAMESPACE
 
--- a/dom/indexedDB/IDBWrapperCache.h
+++ b/dom/indexedDB/IDBWrapperCache.h
@@ -30,20 +30,20 @@ public:
   void AssertIsRooted() const;
 #else
   inline void AssertIsRooted() const
   {
   }
 #endif
 
 protected:
-  IDBWrapperCache(DOMEventTargetHelper* aOwner)
+  explicit IDBWrapperCache(DOMEventTargetHelper* aOwner)
     : DOMEventTargetHelper(aOwner), mScriptOwner(nullptr)
   { }
-  IDBWrapperCache(nsPIDOMWindow* aOwner)
+  explicit IDBWrapperCache(nsPIDOMWindow* aOwner)
     : DOMEventTargetHelper(aOwner), mScriptOwner(nullptr)
   { }
 
   virtual ~IDBWrapperCache();
 
 private:
   JS::Heap<JSObject*> mScriptOwner;
 };
--- a/dom/ipc/ContentBridgeParent.h
+++ b/dom/ipc/ContentBridgeParent.h
@@ -12,17 +12,17 @@
 
 namespace mozilla {
 namespace dom {
 
 class ContentBridgeParent : public PContentBridgeParent
                           , public nsIContentParent
 {
 public:
-  ContentBridgeParent(Transport* aTransport);
+  explicit ContentBridgeParent(Transport* aTransport);
 
   NS_DECL_ISUPPORTS
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
   void DeferredDestroy();
 
   static ContentBridgeParent*
   Create(Transport* aTransport, ProcessId aOtherProcess);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3521,17 +3521,17 @@ ContentParent::DoSendAsyncMessage(JSCont
     ClonedMessageData data;
     if (!BuildClonedMessageDataForParent(this, aData, data)) {
         return false;
     }
     InfallibleTArray<CpowEntry> cpows;
     if (aCpows && !GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
         return false;
     }
-    return SendAsyncMessage(nsString(aMessage), data, cpows, aPrincipal);
+    return SendAsyncMessage(nsString(aMessage), data, cpows, Principal(aPrincipal));
 }
 
 bool
 ContentParent::CheckPermission(const nsAString& aPermission)
 {
     return AssertAppProcessPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
 }
 
--- a/dom/ipc/PermissionMessageUtils.h
+++ b/dom/ipc/PermissionMessageUtils.h
@@ -12,17 +12,17 @@
 
 namespace IPC {
 
 class Principal {
   friend struct ParamTraits<Principal>;
 
 public:
   Principal() : mPrincipal(nullptr) {}
-  Principal(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {}
+  explicit Principal(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {}
   operator nsIPrincipal*() const { return mPrincipal.get(); }
 
 private:
   // Unimplemented
   Principal& operator=(Principal&);
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2778,21 +2778,21 @@ TabChild::DoSendBlockingMessage(JSContex
   InfallibleTArray<CpowEntry> cpows;
   if (sCpowsEnabled) {
     if (!Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
   }
   if (aIsSync) {
     return SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
-                           aPrincipal, aJSONRetVal);
+                           Principal(aPrincipal), aJSONRetVal);
   }
 
   return CallRpcMessage(PromiseFlatString(aMessage), data, cpows,
-                        aPrincipal, aJSONRetVal);
+                        Principal(aPrincipal), aJSONRetVal);
 }
 
 bool
 TabChild::DoSendAsyncMessage(JSContext* aCx,
                              const nsAString& aMessage,
                              const StructuredCloneData& aData,
                              JS::Handle<JSObject *> aCpows,
                              nsIPrincipal* aPrincipal)
@@ -2803,17 +2803,17 @@ TabChild::DoSendAsyncMessage(JSContext* 
   }
   InfallibleTArray<CpowEntry> cpows;
   if (sCpowsEnabled) {
     if (!Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
   }
   return SendAsyncMessage(PromiseFlatString(aMessage), data, cpows,
-                          aPrincipal);
+                          Principal(aPrincipal));
 }
 
 TabChild*
 TabChild::GetFrom(nsIPresShell* aPresShell)
 {
   nsIDocument* doc = aPresShell->GetDocument();
   if (!doc) {
       return nullptr;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -57,17 +57,17 @@ class ClonedMessageData;
 class TabChildBase;
 
 class TabChildGlobal : public DOMEventTargetHelper,
                        public nsIContentFrameMessageManager,
                        public nsIScriptObjectPrincipal,
                        public nsIGlobalObject
 {
 public:
-  TabChildGlobal(TabChildBase* aTabChild);
+  explicit TabChildGlobal(TabChildBase* aTabChild);
   void Init();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, DOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              JS::Handle<JS::Value> aObject,
                              JS::Handle<JS::Value> aRemote,
@@ -142,17 +142,17 @@ public:
 
 protected:
   ~TabChildGlobal();
 };
 
 class ContentListener MOZ_FINAL : public nsIDOMEventListener
 {
 public:
-  ContentListener(TabChild* aTabChild) : mTabChild(aTabChild) {}
+  explicit ContentListener(TabChild* aTabChild) : mTabChild(aTabChild) {}
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMEVENTLISTENER
 protected:
   ~ContentListener() {}
   TabChild* mTabChild;
 };
 
 // This is base clase which helps to share Viewport and touch related functionality
--- a/dom/ipc/TabContext.h
+++ b/dom/ipc/TabContext.h
@@ -249,17 +249,17 @@ public:
  */
 class MaybeInvalidTabContext
 {
 public:
   /**
    * This constructor copies the information in aContext and sets IsValid() as
    * appropriate.
    */
-  MaybeInvalidTabContext(const IPCTabContext& aContext);
+  explicit MaybeInvalidTabContext(const IPCTabContext& aContext);
 
   /**
    * Was the IPCTabContext we received in our constructor valid?
    */
   bool IsValid();
 
   /**
    * If IsValid(), this function returns null.  Otherwise, it returns a
--- a/dom/media/tests/crashtests/crashtests.list
+++ b/dom/media/tests/crashtests/crashtests.list
@@ -1,16 +1,16 @@
 default-preferences  pref(media.peerconnection.enabled,true) pref(media.navigator.permission.disabled,true)
 
 load 780790.html
 load 791270.html
 load 791278.html
-load 791330.html
+skip-if(Android||B2G) load 791330.html # bug 909925
 load 799419.html
 load 802982.html
 load 812785.html
 load 834100.html
 load 836349.html
 load 837324.html
-load 855796.html
+skip-if(Android||B2G) load 855796.html # bug 909925
 load 860143.html
 load 861958.html
-load 863929.html
+skip-if(Android||B2G) load 863929.html # bug 909925
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1828,17 +1828,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
   if (!event) {
     InitializeNPCocoaEvent(&synthCocoaEvent);
     switch (anEvent.message) {
       case NS_MOUSE_MOVE:
       {
         // Ignore mouse-moved events that happen as part of a dragging
         // operation that started over another frame.  See bug 525078.
         nsRefPtr<nsFrameSelection> frameselection = mObjectFrame->GetFrameSelection();
-        if (!frameselection->GetMouseDownState() ||
+        if (!frameselection->GetDragState() ||
           (nsIPresShell::GetCapturingContent() == mObjectFrame->GetContent())) {
           synthCocoaEvent.type = NPCocoaEventMouseMoved;
           synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
           synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
           event = &synthCocoaEvent;
         }
       }
         break;
--- a/dom/tests/mochitest/bugs/iframe_bug440572.html
+++ b/dom/tests/mochitest/bugs/iframe_bug440572.html
@@ -1,17 +1,17 @@
 <html>
 <body>
 <script>
 
 var success = 0;
 
 try {
   parent[name].success = 1;
+  parent.postMessage(success ? "success" : "failure", "http://mochi.test:8888");
 } catch (e) {
-  parent.postMessage(e, "http://mochi.test:8888");
+  parent.postMessage(e.toString(), "http://mochi.test:8888");
 }
 
-parent.postMessage(success ? "success" : "failure", "http://mochi.test:8888");
 </script>
 <p>Move on, nothing to see here...</p>
 </body>
 </html>
--- a/dom/tests/mochitest/bugs/test_bug440572.html
+++ b/dom/tests/mochitest/bugs/test_bug440572.html
@@ -22,19 +22,20 @@ function receiveMessage(e)
   is(e.origin, "http://example.org", "wrong sender!");
   messages.push(e.data);
 }
 
 window.addEventListener("message", receiveMessage, false);
 
 function runtests()
 {
-  for (i in messages) {
-    is(messages[i], "success", "test in frame failed.");
-  }
+  is(messages.length, 3, "received the right number of messages.");
+  is(messages[0], "success", "test in frame failed.");
+  isnot(messages[1], "success", "parent[\"content\"] should be the WebIDL property of Window.");
+  isnot(messages[2], "success", "parent[\"dump\"] should be the WebIDL property of Window.");
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 <br>
 <iframe name="test" src="http://example.org:80/tests/dom/tests/mochitest/bugs/iframe_bug440572.html"></iframe>
--- a/dom/tests/mochitest/general/test_paste_selection.html
+++ b/dom/tests/mochitest/general/test_paste_selection.html
@@ -55,25 +55,31 @@ function selectArea()
 }
 
 var selectionPasted = false;
 var globalPasted = false;
 
 function pasteArea()
 {
   var pasteArea = document.getElementById("paste-selection-area");
+  var pasteAreaRect = pasteArea.getBoundingClientRect();
+  var pasteAreaCenterX = pasteAreaRect.left + pasteAreaRect.width/2;
+  var pasteAreaCenterY = pasteAreaRect.top + pasteAreaRect.height/2;
+  var util = SpecialPowers.getDOMWindowUtils(window);
+
   pasteArea.focus();
-  synthesizeMouse(pasteArea, 8, 8, { button: 1 });
+  util.sendMouseEventToWindow("mousedown", pasteAreaCenterX, pasteAreaCenterY, 1, 1, 0, true);
+  util.sendMouseEventToWindow("mouseup",   pasteAreaCenterX, pasteAreaCenterY, 1, 1, 0, true);
 
   var usesMouseButtonPaste = SpecialPowers.getBoolPref("middlemouse.paste");
   if (usesMouseButtonPaste) {
     // The data transfer should contain the selection data when the selection clipboard is supported,
     // not the global clipboard data.
     var expectedText = supportsSelectionClipboard ? "COPY TEXT" : "CLIPBOARD";
-    is(document.getElementById("paste-selection-area").value, expectedText, "data pasted properly from selection");
+    is(document.getElementById("paste-selection-area").value, expectedText, "In pasteArea(): data pasted properly from selection");
     ok(selectionPasted, "selection event fired");
   }
   else {
     is(pasteArea.value, "", "data not pasted when middle click not supported");
   }
 
   var pasteArea = document.getElementById("paste-global-area");
   pasteArea.focus();
@@ -87,17 +93,17 @@ function pasteArea()
 function pastedSelection(event)
 {
   ok(SpecialPowers.getBoolPref("middlemouse.paste"), "paste on middle click is valid");
 
   // Mac and Windows shouldn't get here as the middle mouse preference is false by default
   ok(navigator.platform.indexOf("Mac") == -1 && navigator.platform.indexOf("Win") == -1, "middle click enabled on right platforms");
 
   var expectedText = supportsSelectionClipboard ? "COPY TEXT" : "CLIPBOARD";
-  is(event.clipboardData.getData("text/plain"), expectedText, "data pasted properly from selection");
+  is(event.clipboardData.getData("text/plain"), expectedText, "In pastedSelection(): data pasted properly from selection");
 
   selectionPasted = true;
 }
 
 function pastedGlobal(event)
 {
   // The data transfer should contain the global data.
   is(event.clipboardData.getData("text/plain"), "CLIPBOARD", "data correct in global clipboard data transfer");
--- a/dom/webidl/Node.webidl
+++ b/dom/webidl/Node.webidl
@@ -51,17 +51,17 @@ interface Node : EventTarget {
   readonly attribute Node? lastChild;
   [Pure]
   readonly attribute Node? previousSibling;
   [Pure]
   readonly attribute Node? nextSibling;
 
   [SetterThrows, Pure]
            attribute DOMString? nodeValue;
-  [SetterThrows, Pure]
+  [Throws, Pure]
            attribute DOMString? textContent;
   [Throws]
   Node insertBefore(Node node, Node? child);
   [Throws]
   Node appendChild(Node node);
   [Throws]
   Node replaceChild(Node node, Node child);
   [Throws]
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -651,16 +651,17 @@ nsBindingManager::GetBindingImplementati
       // content in order to view the full array of methods defined in the
       // binding, some of which may not be exposed on the prototype of
       // untrusted content. We don't need to consider add-on scopes here
       // because they're chrome-only and no Xrays are involved.
       //
       // If there's no separate XBL scope, or if the reflector itself lives in
       // the XBL scope, we'll end up with the global of the reflector.
       JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, jsobj));
+      NS_ENSURE_TRUE(xblScope, NS_ERROR_UNEXPECTED);
       JSAutoCompartment ac(cx, xblScope);
       bool ok = JS_WrapObject(cx, &jsobj);
       NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
       MOZ_ASSERT_IF(js::IsWrapper(jsobj), xpc::IsXrayWrapper(jsobj));
 
       nsresult rv = xpConnect->WrapJSAggregatedToNative(aContent, cx,
                                                         jsobj, aIID, aResult);
       if (NS_FAILED(rv))
--- a/dom/xbl/nsBindingManager.h
+++ b/dom/xbl/nsBindingManager.h
@@ -42,17 +42,17 @@ class nsBindingManager MOZ_FINAL : publi
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
-  nsBindingManager(nsIDocument* aDocument);
+  explicit nsBindingManager(nsIDocument* aDocument);
 
   nsXBLBinding* GetBindingWithContent(nsIContent* aContent);
 
   void AddBoundContent(nsIContent* aContent);
   void RemoveBoundContent(nsIContent* aContent);
 
   /**
    * Notify the binding manager that an element
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -914,16 +914,17 @@ GetOrCreateMapEntryForPrototype(JSContex
   // XBL scope (prototyped to cross-compartment-wrapped content prototypes).
   const char* name = xpc::IsInContentXBLScope(proto) ? "__ContentClassObjectMap__"
                                                      : "__XBLClassObjectMap__";
 
   // Now, enter the XBL scope, since that's where we need to operate, and wrap
   // the proto accordingly. We hang the map off of the content XBL scope for
   // content, and the Window for chrome (whether add-ons are involved or not).
   JS::Rooted<JSObject*> scope(cx, xpc::GetXBLScopeOrGlobal(cx, proto));
+  NS_ENSURE_TRUE(scope, nullptr);
   JS::Rooted<JSObject*> wrappedProto(cx, proto);
   JSAutoCompartment ac(cx, scope);
   if (!JS_WrapObject(cx, &wrappedProto)) {
     return nullptr;
   }
 
   // Grab the appropriate WeakMap.
   JS::Rooted<JSObject*> map(cx, GetOrCreateClassObjectMap(cx, scope, name));
@@ -971,16 +972,17 @@ nsXBLBinding::DoInitJSClass(JSContext *c
   // end up creating a separate instance of the oddly-named XBL class object
   // and defining it as a property on the XBL scope's global. This works fine,
   // but we need to make sure never to assume that the the reflector and
   // prototype are same-compartment with the bound document.
   JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
 
   // We never store class objects in add-on scopes.
   JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, global));
+  NS_ENSURE_TRUE(xblScope, NS_ERROR_UNEXPECTED);
 
   JS::Rooted<JSObject*> parent_proto(cx);
   if (!JS_GetPrototype(cx, obj, &parent_proto)) {
     return NS_ERROR_FAILURE;
   }
 
   // Get the map entry for the parent prototype. In the one-off case that the
   // parent prototype is null, we somewhat hackily just use the WeakMap itself
--- a/dom/xbl/nsXBLBinding.h
+++ b/dom/xbl/nsXBLBinding.h
@@ -35,17 +35,17 @@ class XBLChildrenElement;
 class nsAnonymousContentList;
 
 // *********************************************************************/
 // The XBLBinding class
 
 class nsXBLBinding MOZ_FINAL
 {
 public:
-  nsXBLBinding(nsXBLPrototypeBinding* aProtoBinding);
+  explicit nsXBLBinding(nsXBLPrototypeBinding* aProtoBinding);
   nsXBLBinding(mozilla::dom::ShadowRoot* aShadowRoot, nsXBLPrototypeBinding* aProtoBinding);
 
   /**
    * XBLBindings are refcounted.  They are held onto in 3 ways:
    * 1. The binding manager's binding table holds onto all bindings that are
    *    currently attached to a content node.
    * 2. Bindings hold onto their base binding.  This is important since
    *    the base binding itself may not be attached to anything.
--- a/intl/unicharutil/nsSaveAsCharset.cpp
+++ b/intl/unicharutil/nsSaveAsCharset.cpp
@@ -351,17 +351,17 @@ nsresult nsSaveAsCharset::SetupCharsetLi
   if (!charsetList[0])
     return NS_ERROR_INVALID_ARG;
 
   if (mCharsetListIndex >= 0) {
     mCharsetList.Clear();
     mCharsetListIndex = -1;
   }
 
-  nsCWhitespaceTokenizer tokenizer = nsDependentCString(charsetList);
+  nsCWhitespaceTokenizer tokenizer((nsDependentCString(charsetList)));
   while (tokenizer.hasMoreTokens()) {
     ParseString(tokenizer.nextToken(), ',', mCharsetList);
   }
 
   return NS_OK;
 }
 
 const char * nsSaveAsCharset::GetNextCharset()
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -36,18 +36,18 @@ protected:
   typedef std::vector<std::string> StringVector;
 
 public:
   typedef base::ChildPrivileges ChildPrivileges;
   typedef base::ProcessHandle ProcessHandle;
 
   static ChildPrivileges DefaultChildPrivileges();
 
-  GeckoChildProcessHost(GeckoProcessType aProcessType,
-                        ChildPrivileges aPrivileges=base::PRIVILEGES_DEFAULT);
+  explicit GeckoChildProcessHost(GeckoProcessType aProcessType,
+                                 ChildPrivileges aPrivileges=base::PRIVILEGES_DEFAULT);
 
   ~GeckoChildProcessHost();
 
   static nsresult GetArchitecturesForBinary(const char *path, uint32_t *result);
 
   static uint32_t GetSupportedArchitecturesForProcessType(GeckoProcessType type);
 
   // Block until the IPC channel for our subprocess is initialized,
--- a/ipc/glue/MessageChannel.h
+++ b/ipc/glue/MessageChannel.h
@@ -52,17 +52,17 @@ class MessageChannel : HasResultCodes
     typedef mozilla::Monitor Monitor;
 
   public:
     static const int32_t kNoTimeout;
 
     typedef IPC::Message Message;
     typedef mozilla::ipc::Transport Transport;
 
-    MessageChannel(MessageListener *aListener);
+    explicit MessageChannel(MessageListener *aListener);
     ~MessageChannel();
 
     // "Open" from the perspective of the transport layer; the underlying
     // socketpair/pipe should already be created.
     //
     // Returns true iff the transport layer was successfully connected,
     // i.e., mChannelState == ChannelConnected.
     bool Open(Transport* aTransport, MessageLoop* aIOLoop=0, Side aSide=UnknownSide);
@@ -376,17 +376,17 @@ class MessageChannel : HasResultCodes
     typedef std::deque<Message> MessageQueue;
     typedef std::map<size_t, Message> MessageMap;
 
     // All dequeuing tasks require a single point of cancellation,
     // which is handled via a reference-counted task.
     class RefCountedTask
     {
       public:
-        RefCountedTask(CancelableTask* aTask)
+        explicit RefCountedTask(CancelableTask* aTask)
           : mTask(aTask)
         { }
       private:
         ~RefCountedTask() { delete mTask; }
       public:
         void Run() { mTask->Run(); }
         void Cancel() { mTask->Cancel(); }
 
@@ -396,17 +396,17 @@ class MessageChannel : HasResultCodes
         CancelableTask* mTask;
     };
 
     // Wrap an existing task which can be cancelled at any time
     // without the wrapper's knowledge.
     class DequeueTask : public Task
     {
       public:
-        DequeueTask(RefCountedTask* aTask)
+        explicit DequeueTask(RefCountedTask* aTask)
           : mTask(aTask)
         { }
         void Run() { mTask->Run(); }
 
       private:
         nsRefPtr<RefCountedTask> mTask;
     };
 
@@ -436,17 +436,17 @@ class MessageChannel : HasResultCodes
     // Worker-thread only; sequence numbers for messages that require
     // synchronous replies.
     int32_t mNextSeqno;
 
     static bool sIsPumpingMessages;
 
     class AutoEnterPendingReply {
       public:
-        AutoEnterPendingReply(size_t &replyVar)
+        explicit AutoEnterPendingReply(size_t &replyVar)
           : mReplyVar(replyVar)
         {
             mReplyVar++;
         }
         ~AutoEnterPendingReply() {
             mReplyVar--;
         }
       private:
@@ -482,17 +482,17 @@ class MessageChannel : HasResultCodes
     // which grow in opposite directions from child to parent.
 
     // The current transaction ID.
     int32_t mCurrentRPCTransaction;
 
     class AutoEnterRPCTransaction
     {
       public:
-       AutoEnterRPCTransaction(MessageChannel *aChan)
+       explicit AutoEnterRPCTransaction(MessageChannel *aChan)
         : mChan(aChan),
           mOldTransaction(mChan->mCurrentRPCTransaction)
        {
            mChan->mMonitor->AssertCurrentThreadOwns();
            if (mChan->mCurrentRPCTransaction == 0)
                mChan->mCurrentRPCTransaction = mChan->NextSeqno();
        }
        AutoEnterRPCTransaction(MessageChannel *aChan, Message *message)
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -555,30 +555,30 @@ jit::PatchJump(CodeLocationJump &jump_, 
 void
 Assembler::finish()
 {
     flush();
     JS_ASSERT(!isFinished);
     isFinished = true;
 
     for (unsigned int i = 0; i < tmpDataRelocations_.length(); i++) {
-        int offset = tmpDataRelocations_[i].getOffset();
-        int real_offset = offset + m_buffer.poolSizeBefore(offset);
+        size_t offset = tmpDataRelocations_[i].getOffset();
+        size_t real_offset = offset + m_buffer.poolSizeBefore(offset);
         dataRelocations_.writeUnsigned(real_offset);
     }
 
     for (unsigned int i = 0; i < tmpJumpRelocations_.length(); i++) {
-        int offset = tmpJumpRelocations_[i].getOffset();
-        int real_offset = offset + m_buffer.poolSizeBefore(offset);
+        size_t offset = tmpJumpRelocations_[i].getOffset();
+        size_t real_offset = offset + m_buffer.poolSizeBefore(offset);
         jumpRelocations_.writeUnsigned(real_offset);
     }
 
     for (unsigned int i = 0; i < tmpPreBarriers_.length(); i++) {
-        int offset = tmpPreBarriers_[i].getOffset();
-        int real_offset = offset + m_buffer.poolSizeBefore(offset);
+        size_t offset = tmpPreBarriers_[i].getOffset();
+        size_t real_offset = offset + m_buffer.poolSizeBefore(offset);
         preBarriers_.writeUnsigned(real_offset);
     }
 }
 
 void
 Assembler::executableCopy(uint8_t *buffer)
 {
     JS_ASSERT(isFinished);
--- a/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
+++ b/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
@@ -722,28 +722,28 @@ struct AssemblerBufferWithConstantPools 
 
 #ifdef DEBUG
         // Record the buffer position to allow validating maxInst when leaving
         // the region.
         canNotPlacePoolStartOffset_ = this->nextOffset().getOffset();
         canNotPlacePoolMaxInst_ = maxInst;
 #endif
 
-        canNotPlacePool_++;
+        canNotPlacePool_ = true;
     }
 
     void leaveNoPool() {
         MOZ_ASSERT(canNotPlacePool_);
         canNotPlacePool_ = false;
 
         // Validate the maxInst argument supplied to enterNoPool().
         MOZ_ASSERT(this->nextOffset().getOffset() - canNotPlacePoolStartOffset_ <= canNotPlacePoolMaxInst_ * InstSize);
     }
 
-    ptrdiff_t poolSizeBefore(ptrdiff_t offset) const {
+    size_t poolSizeBefore(size_t offset) const {
         // Linear search of the poolInfo to find the pool before the given
         // buffer offset, and then return the cumulative size of the pools
         // before this offset. This is used to convert a buffer offset to its
         // final actual offset.
         unsigned cur = 0;
         while (cur < numDumps_ && poolInfo_[cur].offset <= offset)
             cur++;
         if (cur == 0)
@@ -778,38 +778,33 @@ struct AssemblerBufferWithConstantPools 
 
         inhibitNops_ = true;
         while (sizeExcludingCurrentPool() & (alignment - 1))
             putInt(alignFillInst_);
         inhibitNops_ = false;
     }
 
   private:
-    void patchBranch(Inst *i, int curpool, BufferOffset branch) {
+    void patchBranch(Inst *i, unsigned curpool, BufferOffset branch) {
         const Inst *ci = i;
         ptrdiff_t offset = Asm::GetBranchOffset(ci);
         // If the offset is 0, then there is nothing to do.
         if (offset == 0)
             return;
-        int destOffset = branch.getOffset() + offset;
+        unsigned destOffset = branch.getOffset() + offset;
         if (offset > 0) {
             while (curpool < numDumps_ && poolInfo_[curpool].offset <= destOffset) {
                 offset += poolInfo_[curpool].size;
                 curpool++;
             }
         } else {
             // Ignore the pool that comes next, since this is a backwards
             // branch.
-            curpool--;
-            while (curpool >= 0 && poolInfo_[curpool].offset > destOffset) {
-                offset -= poolInfo_[curpool].size;
-                curpool--;
-            }
-            // Can't assert anything here, since the first pool may be after the
-            // target.
+            for (int p = curpool - 1; p >= 0 && poolInfo_[p].offset > destOffset; p--)
+                offset -= poolInfo_[p].size;
         }
         Asm::RetargetNearBranch(i, offset, false);
     }
 
   public:
     void executableCopy(uint8_t *dest_) {
         if (this->oom())
             return;
--- a/js/src/vm/SPSProfiler.cpp
+++ b/js/src/vm/SPSProfiler.cpp
@@ -316,23 +316,27 @@ SPSEntryMarker::SPSEntryMarker(JSRuntime
     : profiler(&rt->spsProfiler)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     if (!profiler->installed()) {
         profiler = nullptr;
         return;
     }
     size_before = *profiler->size_;
+    // We want to push a CPP frame so the profiler can correctly order JS and native stacks.
     profiler->push("js::RunScript", this, nullptr, nullptr, /* copy = */ false);
+    // We also want to push a JS frame so the hang monitor can catch script hangs.
+    profiler->push("js::RunScript", nullptr, script, script->code(), /* copy = */ false);
 }
 
 SPSEntryMarker::~SPSEntryMarker()
 {
     if (profiler != nullptr) {
         profiler->pop();
+        profiler->pop();
         JS_ASSERT(size_before == *profiler->size_);
     }
 }
 
 JS_FRIEND_API(jsbytecode*)
 ProfileEntry::pc() const volatile
 {
     MOZ_ASSERT(isJs());
--- a/layout/base/SelectionCarets.cpp
+++ b/layout/base/SelectionCarets.cpp
@@ -145,38 +145,38 @@ SelectionCarets::HandleEvent(WidgetEvent
 
     mActiveTouchId = nowTouchId;
     mDownPoint = ptInCanvas;
     int32_t inflateSize = SelectionCaretsInflateSize();
     if (mVisible && IsOnRect(GetStartFrameRect(), ptInCanvas, inflateSize)) {
       mDragMode = START_FRAME;
       mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInCanvas.y;
       SetSelectionDirection(false);
-      SetMouseDownState(true);
+      SetSelectionDragState(true);
       return nsEventStatus_eConsumeNoDefault;
     } else if (mVisible && IsOnRect(GetEndFrameRect(), ptInCanvas, inflateSize)) {
       mDragMode = END_FRAME;
       mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInCanvas.y;
       SetSelectionDirection(true);
-      SetMouseDownState(true);
+      SetSelectionDragState(true);
       return nsEventStatus_eConsumeNoDefault;
     } else {
       mDragMode = NONE;
       mActiveTouchId = -1;
       SetVisibility(false);
       LaunchLongTapDetector();
     }
   } else if (aEvent->message == NS_TOUCH_END ||
              aEvent->message == NS_TOUCH_CANCEL ||
              aEvent->message == NS_MOUSE_BUTTON_UP) {
     CancelLongTapDetector();
     if (mDragMode != NONE) {
       // Only care about same id
       if (mActiveTouchId == nowTouchId) {
-        SetMouseDownState(false);
+        SetSelectionDragState(false);
         mDragMode = NONE;
         mActiveTouchId = -1;
       }
       return nsEventStatus_eConsumeNoDefault;
     }
   } else if (aEvent->message == NS_TOUCH_MOVE ||
              aEvent->message == NS_MOUSE_MOVE) {
     if (mDragMode == START_FRAME || mDragMode == END_FRAME) {
@@ -516,21 +516,21 @@ SelectionCarets::SelectWord()
   nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(canvasFrame, mDownPoint,
     nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC);
   NS_ENSURE_TRUE(ptFrame, NS_OK);
   nsPoint ptInFrame = mDownPoint;
   nsLayoutUtils::TransformPoint(canvasFrame, ptFrame, ptInFrame);
 
   nsIFrame* caretFocusFrame = GetCaretFocusFrame();
   nsRefPtr<nsFrameSelection> fs = caretFocusFrame->GetFrameSelection();
-  fs->SetMouseDownState(true);
+  fs->SetDragState(true);
   nsFrame* frame = static_cast<nsFrame*>(ptFrame);
   nsresult rs = frame->SelectByTypeAtPoint(mPresShell->GetPresContext(), ptInFrame,
                                            eSelectWord, eSelectWord, 0);
-  fs->SetMouseDownState(false);
+  fs->SetDragState(false);
 
   // Clear maintain selection otherwise we cannot select less than a word
   fs->MaintainSelection();
   return rs;
 }
 
 /*
  * If we're dragging start caret, we do not want to drag over previous
@@ -690,24 +690,24 @@ SelectionCarets::GetCaretYCenterPosition
     return 0;
   }
   nsRect frameRect = theFrame->GetRectRelativeToSelf();
   nsLayoutUtils::TransformRect(theFrame, canvasFrame, frameRect);
   return frameRect.Center().y;
 }
 
 void
-SelectionCarets::SetMouseDownState(bool aState)
+SelectionCarets::SetSelectionDragState(bool aState)
 {
   nsIFrame* caretFocusFrame = GetCaretFocusFrame();
   nsRefPtr<nsFrameSelection> fs = caretFocusFrame->GetFrameSelection();
-  if (fs->GetMouseDownState() == aState) {
+  if (fs->GetDragState() == aState) {
     return;
   }
-  fs->SetMouseDownState(aState);
+  fs->SetDragState(aState);
 
   if (aState) {
     fs->StartBatchChanges();
   } else {
     fs->EndBatchChanges();
   }
 }
 
--- a/layout/base/SelectionCarets.h
+++ b/layout/base/SelectionCarets.h
@@ -113,20 +113,20 @@ private:
 
   /**
    * Get the vertical center position of selection caret relative to canvas
    * frame.
    */
   nscoord GetCaretYCenterPosition();
 
   /**
-   * Simulate mouse down state when we change the selection range.
+   * Simulate drag state when we change the selection range.
    * Hence, the selection change event will fire normally.
    */
-  void SetMouseDownState(bool aState);
+  void SetSelectionDragState(bool aState);
 
   void SetSelectionDirection(bool aForward);
 
   /**
    * Move start frame of selection caret to given position.
    * In app units.
    */
   void SetStartFramePos(const nsPoint& aPosition);
--- a/layout/base/TouchCaret.cpp
+++ b/layout/base/TouchCaret.cpp
@@ -53,17 +53,17 @@ NS_IMPL_ISUPPORTS(TouchCaret, nsISelecti
 /*static*/ int32_t TouchCaret::sTouchCaretExpirationTime = 0;
 
 TouchCaret::TouchCaret(nsIPresShell* aPresShell)
   : mState(TOUCHCARET_NONE),
     mActiveTouchId(-1),
     mCaretCenterToDownPointOffsetY(0),
     mVisible(false)
 {
-  TOUCHCARET_LOG("Constructor");
+  TOUCHCARET_LOG("Constructor, PresShell=%p", aPresShell);
   MOZ_ASSERT(NS_IsMainThread());
 
   static bool addedTouchCaretPref = false;
   if (!addedTouchCaretPref) {
     Preferences::AddIntVarCache(&sTouchCaretMaxDistance,
                                 "touchcaret.distance.threshold");
     Preferences::AddIntVarCache(&sTouchCaretExpirationTime,
                                 "touchcaret.expiration.time");
@@ -95,42 +95,44 @@ TouchCaret::GetCanvasFrame()
   }
   return presShell->GetCanvasFrame();
 }
 
 void
 TouchCaret::SetVisibility(bool aVisible)
 {
   if (mVisible == aVisible) {
-    TOUCHCARET_LOG("Visibility not changed");
+    TOUCHCARET_LOG("Set visibility %s, same as the old one",
+                   (aVisible ? "shown" : "hidden"));
     return;
   }
 
-  mVisible = aVisible;
-
   nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
   if (!presShell) {
     return;
   }
+
   mozilla::dom::Element* touchCaretElement = presShell->GetTouchCaretElement();
   if (!touchCaretElement) {
     return;
   }
 
+  mVisible = aVisible;
+
   // Set touch caret visibility.
   ErrorResult err;
   touchCaretElement->ClassList()->Toggle(NS_LITERAL_STRING("hidden"),
                                          dom::Optional<bool>(!mVisible),
                                          err);
-  TOUCHCARET_LOG("Visibility %s", (mVisible ? "shown" : "hidden"));
+  TOUCHCARET_LOG("Set visibility %s", (mVisible ? "shown" : "hidden"));
 
   // Set touch caret expiration time.
   mVisible ? LaunchExpirationTimer() : CancelExpirationTimer();
 
-  // We must call SetHasTouchCaret() in order to get APZC to wait until the
+  // We must call SetMayHaveTouchCaret() in order to get APZC to wait until the
   // event has been round-tripped and check whether it has been handled,
   // otherwise B2G will end up panning the document when the user tries to drag
   // touch caret.
   presShell->SetMayHaveTouchCaret(mVisible);
 }
 
 nsRect
 TouchCaret::GetTouchFrameRect()
@@ -324,18 +326,20 @@ TouchCaret::IsOnTouchCaret(const nsPoint
     int32_t dy = Abs(aPoint.y - posY);
     distance = dx + dy;
   }
   return (distance <= TouchCaretMaxDistance());
 }
 
 nsresult
 TouchCaret::NotifySelectionChanged(nsIDOMDocument* aDoc, nsISelection* aSel,
-                                     int16_t aReason)
+                                   int16_t aReason)
 {
+  TOUCHCARET_LOG("Reason=%d", aReason);
+
   // Hide touch caret while no caret exists.
   nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
   if (!presShell) {
     return NS_OK;
   }
 
   nsRefPtr<nsCaret> caret = presShell->GetCaret();
   if (!caret) {
@@ -344,62 +348,120 @@ TouchCaret::NotifySelectionChanged(nsIDO
   }
 
   // The same touch caret is shared amongst the document and any text widgets it
   // may contain. This means that the touch caret could get notifications from
   // multiple selections.
   // If this notification is for a selection that is not the one the
   // the caret is currently interested in , then there is nothing to do!
   if (aSel != caret->GetCaretDOMSelection()) {
+    TOUCHCARET_LOG("Return for selection mismatch!");
     return NS_OK;
   }
 
   // Update touch caret position and visibility.
   // Hide touch caret while key event causes selection change.
-  if ((aReason == nsISelectionListener::NO_REASON) ||
-      (aReason & nsISelectionListener::KEYPRESS_REASON)) {
-    UpdateTouchCaret(false);
+  if (aReason & nsISelectionListener::KEYPRESS_REASON) {
+    TOUCHCARET_LOG("KEYPRESS_REASON");
+    SetVisibility(false);
   } else {
-    UpdateTouchCaret(true);
+    SyncVisibilityWithCaret();
   }
 
   return NS_OK;
 }
 
 void
-TouchCaret::UpdateTouchCaret(bool aVisible)
+TouchCaret::SyncVisibilityWithCaret()
+{
+  TOUCHCARET_LOG("SyncVisibilityWithCaret");
+  if (IsDisplayable()) {
+    SetVisibility(true);
+    UpdatePosition();
+  } else {
+    SetVisibility(false);
+  }
+}
+
+void
+TouchCaret::UpdatePositionIfNeeded()
 {
-  // Hide touch caret while no caret exists.
+  TOUCHCARET_LOG("UpdatePositionIfNeeded");
+  if (IsDisplayable()) {
+    if (mVisible) {
+      UpdatePosition();
+    }
+  } else {
+    SetVisibility(false);
+  }
+}
+
+bool
+TouchCaret::IsDisplayable()
+{
   nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
   if (!presShell) {
-    return;
+    TOUCHCARET_LOG("PresShell is nullptr!");
+    return false;
   }
 
   nsRefPtr<nsCaret> caret = presShell->GetCaret();
   if (!caret) {
-    SetVisibility(false);
-    return;
+    TOUCHCARET_LOG("Caret is nullptr!");
+    return false;
   }
 
-  // Hide touch caret while caret is not visible.
+  nsIFrame* canvasFrame = GetCanvasFrame();
+  if (!canvasFrame) {
+    TOUCHCARET_LOG("No canvas frame!");
+    return false;
+  }
+
+  dom::Element* touchCaretElement = presShell->GetTouchCaretElement();
+  if (!touchCaretElement) {
+    TOUCHCARET_LOG("No touch caret frame element!");
+    return false;
+  }
+
   bool caretVisible = false;
   caret->GetCaretVisible(&caretVisible);
   if (!caretVisible) {
-    TOUCHCARET_LOG("Caret is not visible");
-    SetVisibility(false);
+    TOUCHCARET_LOG("Caret is not visible!");
+    return false;
+  }
+
+  nsISelection* caretSelection = caret->GetCaretDOMSelection();
+  nsRect focusRect;
+  nsIFrame* focusFrame = caret->GetGeometry(caretSelection, &focusRect);
+  if (!focusFrame) {
+    TOUCHCARET_LOG("Focus frame is not valid!");
+    return false;
+  }
+  if (focusRect.IsEmpty()) {
+    TOUCHCARET_LOG("Focus rect is empty!");
+    return false;
+  }
+
+  return true;
+}
+
+void
+TouchCaret::UpdatePosition()
+{
+  MOZ_ASSERT(mVisible);
+
+  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
+  if (!presShell) {
     return;
   }
-
-  // Caret is visible and shown, update touch caret.
+  nsRefPtr<nsCaret> caret = presShell->GetCaret();
   nsISelection* caretSelection = caret->GetCaretDOMSelection();
   nsRect focusRect;
   nsIFrame* focusFrame = caret->GetGeometry(caretSelection, &focusRect);
   if (!focusFrame || focusRect.IsEmpty()) {
-    TOUCHCARET_LOG("Focus frame not valid");
-    SetVisibility(false);
     return;
   }
 
   // Position of the touch caret relative to focusFrame.
   nsPoint pos = nsPoint(focusRect.x + (focusRect.width / 2),
                         focusRect.y + focusRect.height);
 
   // Transform the position to make it relative to canvas frame.
@@ -410,28 +472,28 @@ TouchCaret::UpdateTouchCaret(bool aVisib
   nsLayoutUtils::TransformPoint(focusFrame, canvasFrame, pos);
 
   // Clamp the touch caret position to the scrollframe boundary.
   nsIFrame* closestScrollFrame =
     nsLayoutUtils::GetClosestFrameOfType(focusFrame, nsGkAtoms::scrollFrame);
   while (closestScrollFrame) {
     nsIScrollableFrame* sf = do_QueryFrame(closestScrollFrame);
     nsRect visualRect = sf->GetScrollPortRect();
+
     // Clamp the touch caret in the scroll port.
     nsLayoutUtils::TransformRect(closestScrollFrame, canvasFrame, visualRect);
     pos = visualRect.ClampPoint(pos);
 
     // Get next ancestor scroll frame.
     closestScrollFrame =
       nsLayoutUtils::GetClosestFrameOfType(closestScrollFrame->GetParent(),
                                            nsGkAtoms::scrollFrame);
   }
 
   SetTouchFramePos(pos);
-  SetVisibility(aVisible);
 }
 
 /* static */void
 TouchCaret::DisableTouchCaretCallback(nsITimer* aTimer, void* aTouchCaret)
 {
   nsRefPtr<TouchCaret> self = static_cast<TouchCaret*>(aTouchCaret);
   NS_PRECONDITION(aTimer == self->mTouchCaretExpirationTimer,
                   "Unexpected timer");
@@ -460,16 +522,32 @@ TouchCaret::LaunchExpirationTimer()
 void
 TouchCaret::CancelExpirationTimer()
 {
   if (mTouchCaretExpirationTimer) {
     mTouchCaretExpirationTimer->Cancel();
   }
 }
 
+void
+TouchCaret::SetSelectionDragState(bool aState)
+{
+  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
+  if (!presShell) {
+    return;
+  }
+
+  nsRefPtr<nsCaret> caret = presShell->GetCaret();
+  nsISelection* caretSelection = caret->GetCaretDOMSelection();
+  nsRect focusRect;
+  nsIFrame* caretFocusFrame = caret->GetGeometry(caretSelection, &focusRect);
+  nsRefPtr<nsFrameSelection> fs = caretFocusFrame->GetFrameSelection();
+  fs->SetDragState(aState);
+}
+
 nsEventStatus
 TouchCaret::HandleEvent(WidgetEvent* aEvent)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
   if (!presShell) {
     return nsEventStatus_eIgnore;
   }
@@ -623,16 +701,17 @@ TouchCaret::HandleMouseUpEvent(WidgetMou
   nsEventStatus status = nsEventStatus_eIgnore;
 
   switch (mState) {
     case TOUCHCARET_NONE:
       break;
 
     case TOUCHCARET_MOUSEDRAG_ACTIVE:
       if (aEvent->button == WidgetMouseEvent::eLeftButton) {
+        SetSelectionDragState(false);
         LaunchExpirationTimer();
         SetState(TOUCHCARET_NONE);
         status = nsEventStatus_eConsumeNoDefault;
       }
       break;
 
     case TOUCHCARET_TOUCHDRAG_ACTIVE:
     case TOUCHCARET_TOUCHDRAG_INACTIVE:
@@ -667,16 +746,17 @@ TouchCaret::HandleTouchUpEvent(WidgetTou
 
     case TOUCHCARET_MOUSEDRAG_ACTIVE:
       // Consume touch event in mouse sequence.
       status = nsEventStatus_eConsumeNoDefault;
       break;
 
     case TOUCHCARET_TOUCHDRAG_ACTIVE:
       if (mTouchesId.Length() == 0) {
+        SetSelectionDragState(false);
         // No more finger on the screen.
         SetState(TOUCHCARET_NONE);
         LaunchExpirationTimer();
       } else {
         // Still has finger touching on the screen.
         if (aEvent->touches[0]->mIdentifier == mActiveTouchId) {
           // Remove finger from the touch caret.
           SetState(TOUCHCARET_TOUCHDRAG_INACTIVE);
@@ -712,16 +792,17 @@ TouchCaret::HandleMouseDownEvent(WidgetM
 
   nsEventStatus status = nsEventStatus_eIgnore;
 
   switch (mState) {
     case TOUCHCARET_NONE:
       if (aEvent->button == WidgetMouseEvent::eLeftButton) {
         nsPoint point = GetEventPosition(aEvent);
         if (IsOnTouchCaret(point)) {
+          SetSelectionDragState(true);
           // Cache distence of the event point to the center of touch caret.
           mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - point.y;
           // Enter TOUCHCARET_MOUSEDRAG_ACTIVE state and cancel the timer.
           SetState(TOUCHCARET_MOUSEDRAG_ACTIVE);
           CancelExpirationTimer();
           status = nsEventStatus_eConsumeNoDefault;
         } else {
           // Set touch caret invisible if HisTest fails. Bypass event.
@@ -764,16 +845,17 @@ TouchCaret::HandleTouchDownEvent(WidgetT
         status = nsEventStatus_eIgnore;
       } else {
         // Loop over all the touches and see if any of them is on the touch
         // caret.
         for (size_t i = 0; i < aEvent->touches.Length(); ++i) {
           int32_t touchId = aEvent->touches[i]->Identifier();
           nsPoint point = GetEventPosition(aEvent, touchId);
           if (IsOnTouchCaret(point)) {
+            SetSelectionDragState(true);
             // Touch start position is contained in touch caret.
             mActiveTouchId = touchId;
             // Cache distance of the event point to the center of touch caret.
             mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - point.y;
             // Enter TOUCHCARET_TOUCHDRAG_ACTIVE state and cancel the timer.
             SetState(TOUCHCARET_TOUCHDRAG_ACTIVE);
             CancelExpirationTimer();
             status = nsEventStatus_eConsumeNoDefault;
--- a/layout/base/TouchCaret.h
+++ b/layout/base/TouchCaret.h
@@ -14,26 +14,23 @@
 #include "nsITimer.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/TouchEvents.h"
 #include "Units.h"
 
 namespace mozilla {
 
 /**
- * The TouchCaret places a touch caret according to caret postion when the
+ * The TouchCaret places a touch caret according to caret position when the
  * caret is shown.
  * TouchCaret is also responsible for touch caret visibility. Touch caret
  * won't be shown when timer expires or while key event causes selection change.
  */
 class TouchCaret MOZ_FINAL : public nsISelectionListener
 {
-private:
-  ~TouchCaret();
-
 public:
   explicit TouchCaret(nsIPresShell* aPresShell);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISELECTIONLISTENER
 
   void Terminate()
   {
@@ -43,41 +40,45 @@ public:
   /**
    * Handle mouse and touch event only.
    * Depends on visibility and position of touch caret, HandleEvent may consume
    * that input event and return nsEventStatus_eConsumeNoDefault to the caller.
    * In that case, caller should stop bubble up that input event.
    */
   nsEventStatus HandleEvent(WidgetEvent* aEvent);
 
-  /**
-   * By calling this function, touch caret recalculate touch frame position and
-   * update accordingly.
-   */
-  void UpdateTouchCaret(bool aVisible);
+  void SyncVisibilityWithCaret();
 
-  /**
-   * SetVisibility will set the visibility of the touch caret.
-   * SetVisibility performs an attribute-changed notification which could, in
-   * theory, destroy frames.
-   */
-  void SetVisibility(bool aVisible);
+  void UpdatePositionIfNeeded();
 
   /**
    * GetVisibility will get the visibility of the touch caret.
    */
   bool GetVisibility() const
   {
     return mVisible;
   }
 
 private:
   // Hide default constructor.
   TouchCaret() MOZ_DELETE;
 
+  ~TouchCaret();
+
+  bool IsDisplayable();
+
+  void UpdatePosition();
+
+  /**
+   * SetVisibility will set the visibility of the touch caret.
+   * SetVisibility performs an attribute-changed notification which could, in
+   * theory, destroy frames.
+   */
+  void SetVisibility(bool aVisible);
+
   /**
    * Find the nsCanvasFrame which holds the touch caret.
    */
   nsIFrame* GetCanvasFrame();
 
   /**
    * Retrieve the bounding rectangle of the touch caret.
    *
@@ -144,16 +145,25 @@ private:
    * @param aIdentifier the mIdentifier of the touch which is to be converted.
    * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
    * for some reason the coordinates for the touch are not known (e.g.,
    * the mIdentifier touch is not found).
    */
   nsPoint GetEventPosition(WidgetTouchEvent* aEvent, int32_t aIdentifier);
 
   /**
+   * Set mouse down state in nsFrameSelection, we'll set state to true when
+   * user start dragging caret and set state to false when user release the
+   * caret. The reason for setting this state is it will fire drag reason
+   * when moving caret and fire mouseup reason when releasing caret. So that
+   * the display behavior of copy/paste menu becomes more reasonable.
+   */
+  void SetSelectionDragState(bool aState);
+
+  /**
    * Get the coordinates of a given mouse event, relative to canvas frame.
    * @param aEvent the event
    * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
    * for some reason the coordinates for the mouse are not known.
    */
   nsPoint GetEventPosition(WidgetMouseEvent* aEvent);
 
   /**
@@ -221,17 +231,16 @@ private:
     return sTouchCaretMaxDistance;
   }
 
   static int32_t TouchCaretExpirationTime()
   {
     return sTouchCaretExpirationTime;
   }
 
-protected:
   nsWeakPtr mPresShell;
 
   // Touch caret visibility
   bool mVisible;
   // Touch caret timer
   nsCOMPtr<nsITimer> mTouchCaretExpirationTimer;
 
   // Preference
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -2240,17 +2240,17 @@ NS_IMETHODIMP PresShell::SetCaretEnabled
       mCaret->SetCaretDOMSelection(domSel);
 */
 
     MOZ_ASSERT(mCaret || mTouchCaret);
     if (mCaret) {
       mCaret->SetCaretVisible(mCaretEnabled);
     }
     if (mTouchCaret) {
-      mTouchCaret->UpdateTouchCaret(mCaretEnabled);
+      mTouchCaret->SyncVisibilityWithCaret();
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP PresShell::SetCaretReadOnly(bool aReadOnly)
 {
@@ -3927,16 +3927,19 @@ PresShell::UnsuppressAndInvalidate()
   nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
   if (rootFrame) {
     // let's assume that outline on a root frame is not supported
     rootFrame->InvalidateFrame();
 
     if (mCaretEnabled && mCaret) {
       mCaret->CheckCaretDrawingState();
     }
+    if (mTouchCaret) {
+      mTouchCaret->UpdatePositionIfNeeded();
+    }
   }
 
   // now that painting is unsuppressed, focus may be set on the document
   nsPIDOMWindow *win = mDocument->GetWindow();
   if (win)
     win->SetReadyForFocus();
 
   if (!mHaveShutDown) {
@@ -5800,17 +5803,17 @@ PresShell::MarkImagesInSubtreeVisible(ns
 
   nsIScrollableFrame* scrollFrame = do_QueryFrame(aFrame);
   if (scrollFrame) {
     nsRect displayPort;
     bool usingDisplayport = nsLayoutUtils::GetDisplayPort(aFrame->GetContent(), &displayPort);
     if (usingDisplayport) {
       rect = displayPort;
     } else {
-      rect = rect.Intersect(scrollFrame->GetScrollPortRect());      
+      rect = rect.Intersect(scrollFrame->GetScrollPortRect());
     }
     rect = scrollFrame->ExpandRectToNearlyVisible(rect);
   }
 
   bool preserves3DChildren = aFrame->Preserves3DChildren();
 
   // we assume all images in popups are visible elsewhere, so we skip them here
   const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList |
@@ -8644,23 +8647,28 @@ PresShell::DidDoReflow(bool aInterruptib
   if (docShell) {
     DOMHighResTimeStamp now = GetPerformanceNow();
     docShell->NotifyReflowObservers(aInterruptible, mLastReflowStart, now);
   }
 
   if (sSynthMouseMove) {
     SynthesizeMouseMove(false);
   }
+
   if (mCaret) {
     // Update the caret's position now to account for any changes created by
     // the reflow.
     mCaret->InvalidateOutsideCaret();
     mCaret->UpdateCaretPosition();
   }
 
+  if (mTouchCaret) {
+    mTouchCaret->UpdatePositionIfNeeded();
+  }
+
   if (!aWasInterrupted) {
     ClearReflowOnZoomPending();
   }
 }
 
 DOMHighResTimeStamp
 PresShell::GetPerformanceNow()
 {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -547,17 +547,17 @@ protected:
 
   // Utility method to restore the root scrollframe state
   void RestoreRootScrollPosition();
 
   void MaybeReleaseCapturingContent()
   {
     nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
     if (frameSelection) {
-      frameSelection->SetMouseDownState(false);
+      frameSelection->SetDragState(false);
     }
     if (gCaptureInfo.mContent &&
         gCaptureInfo.mContent->OwnerDoc() == mDocument) {
       SetCapturingContent(nullptr, 0);
     }
   }
 
   nsresult HandleRetargetedEvent(mozilla::WidgetEvent* aEvent,
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/bug644768.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=644768
+-->
+<head>
+  <title>Test for Bug 644768</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="test()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=644768">Mozilla Bug 644768</a>
+<p id="display"></p>
+<div id="content">
+<!-- test text is
+== زادروزها ==
+* [[۱۳۰۷]]
+-->
+ <textarea id="testInput" dir="rtl" cols="80" rows="25">
+
+== &#x0632;&#x0627;&#x062F;&#x0631;&#x0648;&#x0632;&#x0647;&#x0627; ==
+* [[&#x06F1;&#x06F3;&#x06F0;&#x06F7;]]</textarea>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 644768 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function test() {
+  var textInput = $("testInput");
+  var s1, s2, equal, str1, str2;
+
+  textInput.focus();
+  s1 = snapshotWindow(window);
+
+  synthesizeKey("VK_UP", { });
+  synthesizeKey("VK_UP", { });
+  synthesizeKey("VK_UP", { });
+  synthesizeKey("VK_DELETE", { });
+  synthesizeKey("VK_RETURN", { });
+  // Bug 1016184: Touch caret will hide due to key event.
+  s2 = snapshotWindow(window);
+
+  [equal, str1, str2] = compareSnapshots(s1, s2, true);
+  ok(equal, "newline before bidi text shouldn't change direction: expected " +
+     str1 + " but got " + str2);
+
+  SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -45,16 +45,17 @@ support-files =
   bug570378-persian-2.html
   bug570378-persian-2-ref.html
   bug570378-persian-3.html
   bug570378-persian-3-ref.html
   bug570378-persian-4.html
   bug570378-persian-4-ref.html
   bug570378-persian-5.html
   bug570378-persian-5-ref.html
+  bug644768.html
 
 [test_preserve3d_sorting_hit_testing.html]
 [test_after_paint_pref.html]
 [test_bug993936.html]
 skip-if = e10s
 [test_border_radius_hit_testing.html]
 [test_bug66619.html]
 [test_bug93077-1.html]
--- a/layout/base/tests/test_bug644768.html
+++ b/layout/base/tests/test_bug644768.html
@@ -1,58 +1,28 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=644768
--->
-<head>
-  <title>Test for Bug 644768</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body onload="test()">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=644768">Mozilla Bug 644768</a>
-<p id="display"></p>
-<div id="content">
-<!-- test text is 
-== زادروزها ==
-* [[۱۳۰۷]]
--->
- <textarea id="testInput" dir="rtl" cols="80" rows="25">
-
-== &#x0632;&#x0627;&#x062F;&#x0631;&#x0648;&#x0632;&#x0647;&#x0627; ==
-* [[&#x06F1;&#x06F3;&#x06F0;&#x06F7;]]</textarea>
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
+<!-- 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/. -->
 
-/** Test for Bug 644768 **/
-
-SimpleTest.waitForExplicitFinish();
-
-function test() {
-  var textInput = $("testInput");
-  var s1, s2, equal, str1, str2;
-
-  textInput.focus();
-  s1 = snapshotWindow(window);
-
-  synthesizeKey("VK_UP", { });
-  synthesizeKey("VK_UP", { });
-  synthesizeKey("VK_UP", { });
-  synthesizeKey("VK_DELETE", { });
-  synthesizeKey("VK_RETURN", { });
-  s2 = snapshotWindow(window);
-
-  [equal, str1, str2] = compareSnapshots(s1, s2, true);
-  ok(equal, "newline before bidi text shouldn't change direction: expected " +
-     str1 + " but got " + str2);
-
-  SimpleTest.finish();
-}
-
-</script>
-</pre>
-</body>
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Bug 644768 test</title>
+    <style>
+      iframe {
+        width: 600px;
+        height: 400px;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="container"></div>
+  </body>
+  <script>
+  // Touch caret's pref is checked only when PresShell is initialized. To turn
+  // off the pref, we test bug 644768 in an iframe.
+  SpecialPowers.pushPrefEnv({"set": [['touchcaret.enabled', false]]}, function() {
+    var iframe = document.createElement("iframe");
+    iframe.src = "bug644768.html";
+    document.getElementById('container').appendChild(iframe);
+  });
+  </script>
 </html>
-
--- a/layout/base/tests/test_reftests_with_caret.html
+++ b/layout/base/tests/test_reftests_with_caret.html
@@ -33,16 +33,17 @@ function callbackTestCanvas(canvas)
               "RESULT=" + ret[1] + "\n" +
               "REFERENCE=" + ret[2] + "\n")));
 
   // Remove the iframes if the test was successful
   if (ret[0]) {
     result.parentNode.removeChild(result);
     reference.parentNode.removeChild(reference);
   }
+
   canvases = [];
   SimpleTest.waitForFocus(nextTest);
 }
 
 function doSnapShot(iframe) {
   iframe.snapshot = snapshotWindow(iframe.contentWindow, true);
   callbackTestCanvas(iframe);
 };
@@ -99,50 +100,55 @@ function endTest() {
 
   // finish(), yet let the test actually end first, to be safe.
   SimpleTest.executeSoon(SimpleTest.finish);
 }
 
 var tests = [
     [ 'bug106855-1.html' , 'bug106855-1-ref.html' ] ,
     [ 'bug106855-2.html' , 'bug106855-1-ref.html' ] ,
+    [ 'bug389321-2.html' , 'bug389321-2-ref.html' ] ,
+    [ 'bug389321-3.html' , 'bug389321-3-ref.html' ] ,
+    [ 'bug613807-1.html' , 'bug613807-1-ref.html' ] ,
+    // The following test cases are all involving with one sending
+    // synthesizeKey(), the other without. They ought to be failed
+    // when touch caret preference on. Test them with preference off.
+    function() {SpecialPowers.setBoolPref("touchcaret.enabled", false);} ,
     [ 'bug240933-1.html' , 'bug240933-1-ref.html' ] ,
     [ 'bug240933-2.html' , 'bug240933-1-ref.html' ] ,
     [ 'bug389321-1.html' , 'bug389321-1-ref.html' ] ,
-    [ 'bug389321-2.html' , 'bug389321-2-ref.html' ] ,
-    [ 'bug389321-3.html' , 'bug389321-3-ref.html' ] ,
     [ 'bug482484.html'   , 'bug482484-ref.html'   ] ,
     [ 'bug585922.html'   , 'bug585922-ref.html'   ] ,
     [ 'bug597519-1.html' , 'bug597519-1-ref.html' ] ,
     [ 'bug602141-1.html' , 'bug602141-1-ref.html' ] ,
     [ 'bug602141-2.html' , 'bug602141-2-ref.html' ] ,
     [ 'bug602141-3.html' , 'bug602141-3-ref.html' ] ,
     [ 'bug602141-4.html' , 'bug602141-4-ref.html' ] ,
     [ 'bug612271-1.html' , 'bug612271-ref.html' ]   ,
     [ 'bug612271-2.html' , 'bug612271-ref.html' ]   ,
     [ 'bug612271-3.html' , 'bug612271-ref.html' ]   ,
     [ 'bug613433-1.html' , 'bug613433-ref.html' ]   ,
     [ 'bug613433-2.html' , 'bug613433-ref.html' ]   ,
     [ 'bug613433-3.html' , 'bug613433-ref.html' ]   ,
-    [ 'bug613807-1.html' , 'bug613807-1-ref.html' ] ,
     [ 'bug632215-1.html' , 'bug632215-ref.html'   ] ,
     [ 'bug632215-2.html' , 'bug632215-ref.html'   ] ,
     [ 'bug633044-1.html' , 'bug633044-1-ref.html' ] ,
     [ 'bug634406-1.html' , 'bug634406-1-ref.html' ] ,
     [ 'bug644428-1.html' , 'bug644428-1-ref.html' ] ,
     function() {SpecialPowers.setBoolPref("bidi.browser.ui", true);} ,
     [ 'bug646382-1.html' , 'bug646382-1-ref.html' ] ,
     [ 'bug646382-2.html' , 'bug646382-2-ref.html' ] ,
     [ 'bug664087-1.html' , 'bug664087-1-ref.html' ] ,
     [ 'bug664087-2.html' , 'bug664087-2-ref.html' ] ,
     [ 'bug682712-1.html' , 'bug682712-1-ref.html' ] ,
     function() {SpecialPowers.clearUserPref("bidi.browser.ui");} ,
     [ 'bug746993-1.html' , 'bug746993-1-ref.html' ] ,
     [ 'bug1007065-1.html' , 'bug1007065-1-ref.html' ] ,
     [ 'bug1007067-1.html' , 'bug1007067-1-ref.html' ] ,
+    function() {SpecialPowers.clearUserPref("touchcaret.enabled");} ,
 ];
 
 if (navigator.appVersion.indexOf("Android") == -1 &&
   SpecialPowers.Services.appinfo.name != "B2G") {
   tests.push([ 'bug512295-1.html' , 'bug512295-1-ref.html' ]);
   tests.push([ 'bug512295-2.html' , 'bug512295-2-ref.html' ]);
   tests.push(function() {SpecialPowers.setBoolPref("layout.css.overflow-clip-box.enabled", true);});
   tests.push([ 'bug966992-1.html' , 'bug966992-1-ref.html' ]);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2769,17 +2769,17 @@ nsFrame::HandlePress(nsPresContext* aPre
 #else
   bool control = mouseEvent->IsControl();
 #endif
 
   nsRefPtr<nsFrameSelection> fc = const_cast<nsFrameSelection*>(frameselection);
   if (mouseEvent->clickCount > 1) {
     // These methods aren't const but can't actually delete anything,
     // so no need for nsWeakFrame.
-    fc->SetMouseDownState(true);
+    fc->SetDragState(true);
     fc->SetMouseDoubleDown(true);
     return HandleMultiplePress(aPresContext, mouseEvent, aEventStatus, control);
   }
 
   nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
   ContentOffsets offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
 
   if (!offsets.content)
@@ -2807,17 +2807,17 @@ nsFrame::HandlePress(nsPresContext* aPre
   nsCOMPtr<nsIContent>parentContent;
   int32_t  contentOffset;
   int32_t target;
   rv = GetDataForTableSelection(frameselection, shell, mouseEvent,
                                 getter_AddRefs(parentContent), &contentOffset,
                                 &target);
   if (NS_SUCCEEDED(rv) && parentContent)
   {
-    fc->SetMouseDownState(true);
+    fc->SetDragState(true);
     return fc->HandleTableSelection(parentContent, contentOffset, target,
                                     mouseEvent);
   }
 
   fc->SetDelayedCaretData(0);
 
   // Check if any part of this frame is selected, and if the
   // user clicked inside the selected region. If so, we delay
@@ -2856,23 +2856,23 @@ nsFrame::HandlePress(nsPresContext* aPre
       }
 
       SelectionDetails *nextDetail = curDetail->mNext;
       delete curDetail;
       curDetail = nextDetail;
     }
 
     if (inSelection) {
-      fc->SetMouseDownState(false);
+      fc->SetDragState(false);
       fc->SetDelayedCaretData(mouseEvent);
       return NS_OK;
     }
   }
 
-  fc->SetMouseDownState(true);
+  fc->SetDragState(true);
 
   // Do not touch any nsFrame members after this point without adding
   // weakFrame checks.
   rv = fc->HandleClick(offsets.content, offsets.StartOffset(),
                        offsets.EndOffset(), mouseEvent->IsShift(), control,
                        offsets.associateWithNext);
 
   if (NS_FAILED(rv))
@@ -2884,17 +2884,17 @@ nsFrame::HandlePress(nsPresContext* aPre
   if (isEditor && !mouseEvent->IsShift() &&
       (offsets.EndOffset() - offsets.StartOffset()) == 1)
   {
     // A single node is selected and we aren't extending an existing
     // selection, which means the user clicked directly on an object (either
     // -moz-user-select: all or a non-text node without children).
     // Therefore, disable selection extension during mouse moves.
     // XXX This is a bit hacky; shouldn't editor be able to deal with this?
-    fc->SetMouseDownState(false);
+    fc->SetDragState(false);
   }
 
   return rv;
 }
 
 /*
  * SelectByTypeAtPoint
  *
@@ -3085,17 +3085,17 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPres
   if (!selectable)
     return NS_OK;
   if (DisplaySelection(aPresContext) == nsISelectionController::SELECTION_OFF) {
     return NS_OK;
   }
   nsIPresShell *presShell = aPresContext->PresShell();
 
   nsRefPtr<nsFrameSelection> frameselection = GetFrameSelection();
-  bool mouseDown = frameselection->GetMouseDownState();
+  bool mouseDown = frameselection->GetDragState();
   if (!mouseDown)
     return NS_OK;
 
   frameselection->StopAutoScrollTimer();
 
   // Check if we are dragging in a table cell
   nsCOMPtr<nsIContent> parentContent;
   int32_t contentOffset;
@@ -3169,42 +3169,42 @@ HandleFrameSelection(nsFrameSelection*  
       // We didn't do it there to give the user an opportunity to drag
       // the text, but since they didn't drag, we want to place the
       // caret.
       // However, we'll use the mouse position from the release, since:
       //  * it's easier
       //  * that's the normal click position to use (although really, in
       //    the normal case, small movements that don't count as a drag
       //    can do selection)
-      aFrameSelection->SetMouseDownState(true);
+      aFrameSelection->SetDragState(true);
 
       rv = aFrameSelection->HandleClick(aOffsets.content,
                                         aOffsets.StartOffset(),
                                         aOffsets.EndOffset(),
                                         aFrameSelection->IsShiftDownInDelayedCaretData(),
                                         false,
                                         aOffsets.associateWithNext);
       if (NS_FAILED(rv)) {
         return rv;
       }
     } else if (aParentContentForTableSel) {
-      aFrameSelection->SetMouseDownState(false);
+      aFrameSelection->SetDragState(false);
       rv = aFrameSelection->HandleTableSelection(
                               aParentContentForTableSel,
                               aContentOffsetForTableSel,
                               aTargetForTableSel,
                               aEvent->AsMouseEvent());
       if (NS_FAILED(rv)) {
         return rv;
       }
     }
     aFrameSelection->SetDelayedCaretData(0);
   }
 
-  aFrameSelection->SetMouseDownState(false);
+  aFrameSelection->SetDragState(false);
   aFrameSelection->StopAutoScrollTimer();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsFrame::HandleRelease(nsPresContext* aPresContext,
                                      WidgetGUIEvent* aEvent,
                                      nsEventStatus* aEventStatus)
@@ -3233,17 +3233,17 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsP
 
   if (!selectionOff) {
     frameselection = GetFrameSelection();
     if (nsEventStatus_eConsumeNoDefault != *aEventStatus && frameselection) {
       // Check if the frameselection recorded the mouse going down.
       // If not, the user must have clicked in a part of the selection.
       // Place the caret before continuing!
 
-      bool mouseDown = frameselection->GetMouseDownState();
+      bool mouseDown = frameselection->GetDragState();
 
       if (!mouseDown && frameselection->HasDelayedCaretData() &&
           frameselection->GetClickCountInDelayedCaretData() < 2) {
         nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
         offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
         handleTableSelection = false;
       } else {
         GetDataForTableSelection(frameselection, PresContext()->PresShell(),
@@ -3273,17 +3273,17 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsP
       nsIPresShell* capturingShell = doc->GetShell();
       if (capturingShell && capturingShell != PresContext()->GetPresShell()) {
         frameSelection = capturingShell->FrameSelection();
       }
     }
   }
 
   if (frameSelection) {
-    frameSelection->SetMouseDownState(false);
+    frameSelection->SetDragState(false);
     frameSelection->StopAutoScrollTimer();
   }
 
   // Do not call any methods of the current object after this point!!!
   // The object is perhaps dead!
 
   return selectionOff
     ? NS_OK
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -327,28 +327,28 @@ public:
    * @param aReturnDetails linkedlist of return values for the selection. 
    * @param aSlowCheck will check using slow method with no shortcuts
    */
   SelectionDetails* LookUpSelection(nsIContent *aContent,
                                     int32_t aContentOffset,
                                     int32_t aContentLength,
                                     bool aSlowCheck) const;
 
-  /** SetMouseDownState(bool);
-   *  sets the mouse state to aState for resons of drag state.
-   * @param aState is the new state of mousedown
+  /** SetDragState(bool);
+   *  sets the drag state to aState for resons of drag state.
+   * @param aState is the new state of drag
    */
   /*unsafe*/
-  void SetMouseDownState(bool aState);
+  void SetDragState(bool aState);
 
-  /** GetMouseDownState(bool *);
-   *  gets the mouse state to aState for resons of drag state.
-   * @param aState will hold the state of mousedown
+  /** GetDragState(bool *);
+   *  gets the drag state to aState for resons of drag state.
+   * @param aState will hold the state of drag
    */
-  bool GetMouseDownState() const { return mMouseDownState; }
+  bool GetDragState() const { return mDragState; }
 
   /**
     if we are in table cell selection mode. aka ctrl click in table cell
    */
   bool GetTableCellSelection() const { return mSelectingTableCellMode != 0; }
   void ClearTableCellSelection() { mSelectingTableCellMode = 0; }
 
   /** GetSelection
@@ -713,16 +713,16 @@ private:
   int32_t mDesiredX;
   uint32_t mDelayedMouseEventClickCount;
   bool mDelayedMouseEventIsShift;
   bool mDelayedMouseEventValid;
 
   bool mChangesDuringBatching;
   bool mNotifyFrames;
   bool mDragSelectingCells;
-  bool mMouseDownState;   //for drag purposes
+  bool mDragState;   //for drag purposes
   bool mMouseDoubleDownState; //has the doubleclick down happened
   bool mDesiredXSet;
 
   int8_t mCaretMovementStyle;
 };
 
 #endif /* nsFrameSelection_h___ */
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -702,17 +702,17 @@ nsFrameSelection::GetHintForPosition(nsI
   }
   return hint;
 }
 
 void
 nsFrameSelection::Init(nsIPresShell *aShell, nsIContent *aLimiter)
 {
   mShell = aShell;
-  mMouseDownState = false;
+  mDragState = false;
   mDesiredXSet = false;
   mLimiter = aLimiter;
   mCaretMovementStyle =
     Preferences::GetInt("bidi.edit.caret_movement_style", 2);
   // Set touch caret as selection listener
   nsRefPtr<TouchCaret> touchCaret = mShell->GetTouchCaret();
   if (touchCaret) {
     int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
@@ -1647,24 +1647,24 @@ nsFrameSelection::LookUpSelection(nsICon
           aContentLength, &details, (SelectionType)(1<<j), aSlowCheck);
     }
   }
 
   return details;
 }
 
 void
-nsFrameSelection::SetMouseDownState(bool aState)
-{
-  if (mMouseDownState == aState)
+nsFrameSelection::SetDragState(bool aState)
+{
+  if (mDragState == aState)
     return;
 
-  mMouseDownState = aState;
+  mDragState = aState;
     
-  if (!mMouseDownState)
+  if (!mDragState)
   {
     mDragSelectingCells = false;
     PostReason(nsISelectionListener::MOUSEUP_REASON);
     NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL); //notify that reason is mouse up please.
   }
 }
 
 Selection*
@@ -2068,17 +2068,17 @@ nsresult
 nsFrameSelection::HandleTableSelection(nsINode* aParentContent,
                                        int32_t aContentOffset,
                                        int32_t aTarget,
                                        WidgetMouseEvent* aMouseEvent)
 {
   NS_ENSURE_TRUE(aParentContent, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(aMouseEvent, NS_ERROR_NULL_POINTER);
 
-  if (mMouseDownState && mDragSelectingCells && (aTarget & nsISelectionPrivate::TABLESELECTION_TABLE))
+  if (mDragState && mDragSelectingCells && (aTarget & nsISelectionPrivate::TABLESELECTION_TABLE))
   {
     // We were selecting cells and user drags mouse in table border or inbetween cells,
     //  just do nothing
       return NS_OK;
   }
 
   nsresult result = NS_OK;
 
@@ -2093,17 +2093,17 @@ nsFrameSelection::HandleTableSelection(n
 
   mDomSelections[index]->SetDirection(eDirNext);
 
   // Stack-class to wrap all table selection changes in 
   //  BeginBatchChanges() / EndBatchChanges()
   nsSelectionBatcher selectionBatcher(mDomSelections[index]);
 
   int32_t startRowIndex, startColIndex, curRowIndex, curColIndex;
-  if (mMouseDownState && mDragSelectingCells)
+  if (mDragState && mDragSelectingCells)
   {
     // We are drag-selecting
     if (aTarget != nsISelectionPrivate::TABLESELECTION_TABLE)
     {
       // If dragging in the same cell as last event, do nothing
       if (mEndSelectedCell == childContent)
         return NS_OK;
 
@@ -2177,17 +2177,17 @@ printf("HandleTableSelection: Dragged in
       }
     }
     // Do nothing if dragging in table, but outside a cell
     return NS_OK;
   }
   else 
   {
     // Not dragging  -- mouse event is down or up
-    if (mMouseDownState)
+    if (mDragState)
     {
 #ifdef DEBUG_TABLE_SELECTION
 printf("HandleTableSelection: Mouse down event\n");
 #endif
       // Clear cell we stored in mouse-down
       mUnselectCellOnMouseUp = nullptr;
       
       if (aTarget == nsISelectionPrivate::TABLESELECTION_CELL)
--- a/layout/reftests/font-matching/reftest.list
+++ b/layout/reftests/font-matching/reftest.list
@@ -86,10 +86,10 @@ random-if(!(cocoaWidget||/^Windows\x20NT
 random-if(!Android) skip-if(gtk2Widget) != bold-system-fallback-2.html bold-system-fallback-2-notref.html
 
 # Bug 769475 - applying 'italic' to Arabic text in Arial should NOT change family or metrics.
 # Expected to pass on MacOSX and Windows; other platforms unknown, depending on font availability.
 random-if(!(cocoaWidget||winWidget)) == arial-arabic.html arial-arabic-ref.html
 
 != syntheticbold-rotated.html syntheticbold-rotated-ref.html
 
-HTTP(..) == font-synthesis-1.html font-synthesis-1-ref.html
-HTTP(..) == font-synthesis-2.html font-synthesis-2-ref.html
+pref(layout.css.font-features.enabled,true) HTTP(..) == font-synthesis-1.html font-synthesis-1-ref.html
+pref(layout.css.font-features.enabled,true) HTTP(..) == font-synthesis-2.html font-synthesis-2-ref.html
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -328,10 +328,13 @@ div[\_moz_anonclass="mozTouchCaret"].moz
 div[\_moz_anonclass="mozTouchCaret"].moz-selectioncaret-right.tilt {
   background-image: url("resource://gre/res/caret_right.svg");
   margin-left: 0px;
 }
 
 div[\_moz_anonclass="mozTouchCaret"].moz-touchcaret.hidden,
 div[\_moz_anonclass="mozTouchCaret"].moz-selectioncaret-left.hidden,
 div[\_moz_anonclass="mozTouchCaret"].moz-selectioncaret-right.hidden {
+  width: 0px;
+  height: 0px;
+  margin: 0px;
   visibility: hidden;
 }
--- a/layout/tools/reftest/reftest-preferences.js
+++ b/layout/tools/reftest/reftest-preferences.js
@@ -41,8 +41,11 @@
     // Disable interruptible reflow since (1) it's normally not going to
     // happen, but (2) it might happen if we somehow end up with both
     // pending user events and clock skew.  So to avoid having to change
     // MakeProgress to deal with waiting for interruptible reflows to
     // complete for a rare edge case, we just disable interruptible
     // reflow so that that rare edge case doesn't lead to reftest
     // failures.
     branch.setBoolPref("layout.interruptible-reflow.enabled", false);
+    // Disable the auto-hide feature of touch caret to avoid potential
+    // intermittent issues.
+    branch.setIntPref("touchcaret.expiration.time", 0);
--- a/media/mtransport/databuffer.h
+++ b/media/mtransport/databuffer.h
@@ -18,23 +18,28 @@ namespace mozilla {
 class DataBuffer {
  public:
   DataBuffer() : data_(nullptr), len_(0) {}
   DataBuffer(const uint8_t *data, size_t len) {
     Assign(data, len);
   }
 
   void Assign(const uint8_t *data, size_t len) {
-    data_.reset(new uint8_t[len ? len : 1]);  // Don't depend on new [0].
+    Allocate(len);
     memcpy(static_cast<void *>(data_.get()),
            static_cast<const void *>(data), len);
+  }
+
+  void Allocate(size_t len) {
+    data_.reset(new uint8_t[len ? len : 1]);  // Don't depend on new [0].
     len_ = len;
   }
 
   const uint8_t *data() const { return data_.get(); }
+  uint8_t *data() { return data_.get(); }
   size_t len() const { return len_; }
   const bool empty() const { return len_ != 0; }
 
 private:
   UniquePtr<uint8_t[]> data_;
   size_t len_;
 
   DISALLOW_COPY_ASSIGN(DataBuffer);
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -4,25 +4,27 @@
  * 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/. */
 
 // Original author: ekr@rtfm.com
 
 #include <iostream>
 #include <string>
 #include <map>
+#include <algorithm>
 
 #include "mozilla/UniquePtr.h"
 
 #include "sigslot.h"
 
 #include "logging.h"
 #include "nspr.h"
 #include "nss.h"
 #include "ssl.h"
+#include "sslproto.h"
 
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 
 #include "databuffer.h"
 #include "dtlsidentity.h"
 #include "nricectx.h"
 #include "nricemediastream.h"
@@ -45,16 +47,17 @@ MOZ_MTLOG_MODULE("mtransport")
 
 MtransportTestUtils *test_utils;
 
 
 const uint8_t kTlsChangeCipherSpecType = 0x14;
 const uint8_t kTlsHandshakeType =        0x16;
 
 const uint8_t kTlsHandshakeCertificate = 0x0b;
+const uint8_t kTlsHandshakeServerKeyExchange = 0x0c;
 
 const uint8_t kTlsFakeChangeCipherSpec[] = {
   kTlsChangeCipherSpecType,  // Type
   0xfe, 0xff, // Version
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, // Fictitious sequence #
   0x00, 0x01, // Length
   0x01 // Value
 };
@@ -160,16 +163,71 @@ class TransportLayerLossy : public Trans
 
 // Process DTLS Records
 #define CHECK_LENGTH(expected) \
   do { \
     EXPECT_GE(remaining(), expected); \
     if (remaining() < expected) return false; \
   } while(0)
 
+class TlsParser {
+ public:
+  TlsParser(const unsigned char *data, size_t len)
+      : buffer_(data, len), offset_(0) {}
+
+  bool Read(unsigned char* val) {
+    if (remaining() < 1) {
+      return false;
+    }
+    *val = *ptr();
+    consume(1);
+    return true;
+  }
+
+  // Read an integral type of specified width.
+  bool Read(uint32_t *val, size_t len) {
+    if (len > sizeof(uint32_t))
+      return false;
+
+    *val = 0;
+
+    for (size_t i=0; i<len; ++i) {
+      unsigned char tmp;
+
+      if (!Read(&tmp))
+        return false;
+
+      (*val) = ((*val) << 8) + tmp;
+    }
+
+    return true;
+  }
+
+  bool Read(unsigned char* val, size_t len) {
+    if (remaining() < len) {
+      return false;
+    }
+
+    if (val) {
+      memcpy(val, ptr(), len);
+    }
+    consume(len);
+
+    return true;
+  }
+
+ private:
+  size_t remaining() const { return buffer_.len() - offset_; }
+  const uint8_t *ptr() const { return buffer_.data() + offset_; }
+  void consume(size_t len) { offset_ += len; }
+
+  DataBuffer buffer_;
+  size_t offset_;
+};
+
 class DtlsRecordParser {
  public:
   DtlsRecordParser(const unsigned char *data, size_t len)
       : buffer_(data, len), offset_(0) {}
 
   bool NextRecord(uint8_t* ct, nsAutoPtr<DataBuffer>* buffer) {
     if (!remaining())
       return false;
@@ -192,17 +250,16 @@ class DtlsRecordParser {
     return true;
   }
 
  private:
   size_t remaining() const { return buffer_.len() - offset_; }
   const uint8_t *ptr() const { return buffer_.data() + offset_; }
   void consume(size_t len) { offset_ += len; }
 
-
   DataBuffer buffer_;
   size_t offset_;
 };
 
 
 // Inspector that parses out DTLS records and passes
 // them on.
 class DtlsRecordInspector : public Inspector {
@@ -269,16 +326,120 @@ class DtlsInspectorInjector : public Dtl
  private:
   uint8_t packet_type_;
   uint8_t handshake_type_;
   bool injected_;
   UniquePtr<unsigned char[]> data_;
   size_t len_;
 };
 
+// Make a copy of the first instance of a message.
+class DtlsInspectorRecordHandshakeMessage : public DtlsRecordInspector {
+ public:
+  DtlsInspectorRecordHandshakeMessage(uint8_t handshake_type)
+      : handshake_type_(handshake_type),
+        buffer_() {}
+
+  virtual void OnRecord(TransportLayer* layer,
+                        uint8_t content_type,
+                        const unsigned char *data, size_t len) {
+    // Only do this once.
+    if (buffer_.len()) {
+      return;
+    }
+
+    // Check that the first byte is as requested.
+    if (content_type != kTlsHandshakeType) {
+      return;
+    }
+
+    TlsParser parser(data, len);
+    unsigned char message_type;
+    // Read the handshake message type.
+    if (!parser.Read(&message_type)) {
+      return;
+    }
+    if (message_type != handshake_type_) {
+      return;
+    }
+
+    uint32_t length;
+    if (!parser.Read(&length, 3)) {
+      return;
+    }
+
+    uint32_t message_seq;
+    if (!parser.Read(&message_seq, 2)) {
+      return;
+    }
+
+    uint32_t fragment_offset;
+    if (!parser.Read(&fragment_offset, 3)) {
+      return;
+    }
+
+    uint32_t fragment_length;
+    if (!parser.Read(&fragment_length, 3)) {
+      return;
+    }
+
+    if ((fragment_offset != 0) || (fragment_length != length)) {
+      // This shouldn't happen because all current tests where we
+      // are using this code don't fragment.
+      return;
+    }
+
+    buffer_.Allocate(length);
+    if (!parser.Read(buffer_.data(), length)) {
+      return;
+    }
+  }
+
+  const DataBuffer& buffer() { return buffer_; }
+
+ private:
+  uint8_t handshake_type_;
+  DataBuffer buffer_;
+};
+
+class TlsServerKeyExchangeECDHE {
+ public:
+  bool Parse(const unsigned char* data, size_t len) {
+    TlsParser parser(data, len);
+
+    uint8_t curve_type;
+    if (!parser.Read(&curve_type)) {
+      return false;
+    }
+
+    if (curve_type != 3) {  // named_curve
+      return false;
+    }
+
+    uint32_t named_curve;
+    if (!parser.Read(&named_curve, 2)) {
+      return false;
+    }
+
+    uint32_t point_length;
+    if (!parser.Read(&point_length, 1)) {
+      return false;
+    }
+
+    public_key_.Allocate(point_length);
+    if (!parser.Read(public_key_.data(), point_length)) {
+      return false;
+    }
+
+    return true;
+  }
+
+  DataBuffer public_key_;
+};
+
 namespace {
 class TransportTestPeer : public sigslot::has_slots<> {
  public:
   TransportTestPeer(nsCOMPtr<nsIEventTarget> target, std::string name)
       : name_(name), target_(target),
         received_(0), flow_(new TransportFlow(name)),
         loopback_(new TransportLayerLoopback()),
         logging_(new TransportLayerLogging()),
@@ -286,18 +447,20 @@ class TransportTestPeer : public sigslot
         dtls_(new TransportLayerDtls()),
         identity_(DtlsIdentity::Generate()),
         ice_ctx_(NrIceCtx::Create(name,
                                   name == "P2" ?
                                   TransportLayerDtls::CLIENT :
                                   TransportLayerDtls::SERVER)),
         streams_(), candidates_(),
         peer_(nullptr),
-        gathering_complete_(false)
- {
+        gathering_complete_(false),
+        enabled_cipersuites_(),
+        disabled_cipersuites_(),
+        reuse_dhe_key_(false) {
     std::vector<NrIceStunServer> stun_servers;
     UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(
         std::string((char *)"stun.services.mozilla.com"), 3478));
     stun_servers.push_back(*server);
     EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
 
     dtls_->SetIdentity(identity_);
     dtls_->SetRole(name == "P2" ?
@@ -356,32 +519,70 @@ class TransportTestPeer : public sigslot
           peer->fingerprint_len_);
 
       ASSERT_TRUE(NS_SUCCEEDED(res));
 
       mask <<= 1;
     }
   }
 
+  void SetupSrtp() {
+    // this mimics the setup we do elsewhere
+    std::vector<uint16_t> srtp_ciphers;
+    srtp_ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
+    srtp_ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
+
+    SetSrtpCiphers(srtp_ciphers);
+ }
+
+  void SetSrtpCiphers(std::vector<uint16_t>& srtp_ciphers) {
+    ASSERT_TRUE(NS_SUCCEEDED(dtls_->SetSrtpCiphers(srtp_ciphers)));
+  }
 
   void ConnectSocket_s(TransportTestPeer *peer) {
     nsresult res;
     res = loopback_->Init();
     ASSERT_EQ((nsresult)NS_OK, res);
 
     loopback_->Connect(peer->loopback_);
 
     ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(loopback_));
     ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(logging_));
     ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(lossy_));
     ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(dtls_));
 
+    if (dtls_->state() != TransportLayer::TS_ERROR) {
+      // Don't execute these blocks if DTLS didn't initialize.
+      TweakCiphers(dtls_->internal_fd());
+      if (reuse_dhe_key_) {
+        // TransportLayerDtls automatically sets this pref to false
+        // so set it back for test.
+        // This is pretty gross. Dig directly into the NSS FD. The problem
+        // is that we are testing a feature which TransaportLayerDtls doesn't
+        // expose.
+        SECStatus rv = SSL_OptionSet(dtls_->internal_fd(),
+                                     SSL_REUSE_SERVER_ECDHE_KEY, PR_TRUE);
+        ASSERT_EQ(SECSuccess, rv);
+      }
+    }
+
     flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
   }
 
+  void TweakCiphers(PRFileDesc* fd) {
+    for (auto it = enabled_cipersuites_.begin();
+         it != enabled_cipersuites_.end(); ++it) {
+      SSL_CipherPrefSet(fd, *it, PR_TRUE);
+    }
+    for (auto it = disabled_cipersuites_.begin();
+         it != disabled_cipersuites_.end(); ++it) {
+      SSL_CipherPrefSet(fd, *it, PR_FALSE);
+    }
+  }
+
   void ConnectSocket(TransportTestPeer *peer) {
     RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, & TransportTestPeer::ConnectSocket_s,
                                peer),
                   NS_DISPATCH_SYNC);
   }
 
   void InitIce() {
@@ -512,16 +713,32 @@ class TransportTestPeer : public sigslot
   void SetLoss(uint32_t loss) {
     lossy_->SetLoss(loss);
   }
 
   void SetInspector(UniquePtr<Inspector> inspector) {
     lossy_->SetInspector(Move(inspector));
   }
 
+  void SetInspector(Inspector* in) {
+    UniquePtr<Inspector> inspector(in);
+
+    lossy_->SetInspector(Move(inspector));
+  }
+
+  void SetCipherSuiteChanges(const std::vector<uint16_t>& enableThese,
+                             const std::vector<uint16_t>& disableThese) {
+    disabled_cipersuites_ = disableThese;
+    enabled_cipersuites_ = enableThese;
+  }
+
+  void SetReuseECDHEKey() {
+    reuse_dhe_key_ = true;
+  }
+
   TransportLayer::State state() {
     TransportLayer::State tstate;
 
     RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnableRet(flow_, &TransportFlow::state, &tstate));
 
     return tstate;
   }
@@ -531,16 +748,41 @@ class TransportTestPeer : public sigslot
   }
 
   bool failed() {
     return state() == TransportLayer::TS_ERROR;
   }
 
   size_t received() { return received_; }
 
+  uint16_t cipherSuite() const {
+    nsresult rv;
+    uint16_t cipher;
+    RUN_ON_THREAD(test_utils->sts_target(),
+                  WrapRunnableRet(dtls_, &TransportLayerDtls::GetCipherSuite,
+                                  &cipher, &rv));
+
+    if (NS_FAILED(rv)) {
+      return TLS_NULL_WITH_NULL_NULL; // i.e., not good
+    }
+    return cipher;
+  }
+
+  uint16_t srtpCipher() const {
+    nsresult rv;
+    uint16_t cipher;
+    RUN_ON_THREAD(test_utils->sts_target(),
+                  WrapRunnableRet(dtls_, &TransportLayerDtls::GetSrtpCipher,
+                                  &cipher, &rv));
+    if (NS_FAILED(rv)) {
+      return 0; // the SRTP equivalent of TLS_NULL_WITH_NULL_NULL
+    }
+    return cipher;
+  }
+
  private:
   std::string name_;
   nsCOMPtr<nsIEventTarget> target_;
   size_t received_;
     mozilla::RefPtr<TransportFlow> flow_;
   TransportLayerLoopback *loopback_;
   TransportLayerLogging *logging_;
   TransportLayerLossy *lossy_;
@@ -549,16 +791,19 @@ class TransportTestPeer : public sigslot
   mozilla::RefPtr<DtlsIdentity> identity_;
   mozilla::RefPtr<NrIceCtx> ice_ctx_;
   std::vector<mozilla::RefPtr<NrIceMediaStream> > streams_;
   std::map<std::string, std::vector<std::string> > candidates_;
   TransportTestPeer *peer_;
   bool gathering_complete_;
   unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
   size_t fingerprint_len_;
+  std::vector<uint16_t> enabled_cipersuites_;
+  std::vector<uint16_t> disabled_cipersuites_;
+  bool reuse_dhe_key_;
 };
 
 
 class TransportTest : public ::testing::Test {
  public:
   TransportTest() {
     fds_[0] = nullptr;
     fds_[1] = nullptr;
@@ -578,20 +823,29 @@ class TransportTest : public ::testing::
     p2_->DisconnectDestroyFlow();
   }
 
   void SetUp() {
     nsresult rv;
     target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
 
+    Reset();
+  }
+
+  void Reset() {
     p1_ = new TransportTestPeer(target_, "P1");
     p2_ = new TransportTestPeer(target_, "P2");
   }
 
+  void SetupSrtp() {
+    p1_->SetupSrtp();
+    p2_->SetupSrtp();
+  }
+
   void SetDtlsPeer(int digests = 1, unsigned int damage = 0) {
     p1_->SetDtlsPeer(p2_, digests, damage);
     p2_->SetDtlsPeer(p1_, digests, damage);
   }
 
   void SetDtlsAllowAll() {
     p1_->SetDtlsAllowAll();
     p2_->SetDtlsAllowAll();
@@ -602,16 +856,19 @@ class TransportTest : public ::testing::
       WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
       NS_DISPATCH_SYNC);
     test_utils->sts_target()->Dispatch(
       WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
       NS_DISPATCH_SYNC);
 
     ASSERT_TRUE_WAIT(p1_->connected(), 10000);
     ASSERT_TRUE_WAIT(p2_->connected(), 10000);
+
+    ASSERT_EQ(p1_->cipherSuite(), p2_->cipherSuite());
+    ASSERT_EQ(p1_->srtpCipher(), p2_->srtpCipher());
   }
 
   void ConnectSocketExpectFail() {
     test_utils->sts_target()->Dispatch(
       WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
       NS_DISPATCH_SYNC);
     test_utils->sts_target()->Dispatch(
       WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
@@ -657,18 +914,36 @@ class TransportTest : public ::testing::
 
 TEST_F(TransportTest, TestNoDtlsVerificationSettings) {
   ConnectSocketExpectFail();
 }
 
 TEST_F(TransportTest, TestConnect) {
   SetDtlsPeer();
   ConnectSocket();
+
+  // check that we got the right suite
+  ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p1_->cipherSuite());
+
+  // no SRTP on this one
+  ASSERT_EQ(0, p1_->srtpCipher());
 }
 
+TEST_F(TransportTest, TestConnectSrtp) {
+  SetupSrtp();
+  SetDtlsPeer();
+  ConnectSocket();
+
+  ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p1_->cipherSuite());
+
+  // SRTP is on
+  ASSERT_EQ(SRTP_AES128_CM_HMAC_SHA1_80, p1_->srtpCipher());
+}
+
+
 TEST_F(TransportTest, TestConnectDestroyFlowsMainThread) {
   SetDtlsPeer();
   ConnectSocket();
   DestroyPeerFlows();
 }
 
 TEST_F(TransportTest, TestConnectAllowAll) {
   SetDtlsAllowAll();
@@ -711,16 +986,69 @@ TEST_F(TransportTest, TestConnectInjectC
       kTlsHandshakeType,
       kTlsHandshakeCertificate,
       kTlsFakeChangeCipherSpec,
       sizeof(kTlsFakeChangeCipherSpec)));
 
   ConnectSocket();
 }
 
+
+TEST_F(TransportTest, TestConnectVerifyNewECDHE) {
+  SetDtlsPeer();
+  DtlsInspectorRecordHandshakeMessage *i1 = new
+    DtlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
+  p1_->SetInspector(i1);
+  ConnectSocket();
+  TlsServerKeyExchangeECDHE dhe1;
+  ASSERT_TRUE(dhe1.Parse(i1->buffer().data(), i1->buffer().len()));
+
+  Reset();
+  SetDtlsPeer();
+  DtlsInspectorRecordHandshakeMessage *i2 = new
+    DtlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
+  p1_->SetInspector(i2);
+  ConnectSocket();
+  TlsServerKeyExchangeECDHE dhe2;
+  ASSERT_TRUE(dhe2.Parse(i2->buffer().data(), i2->buffer().len()));
+
+  // Now compare these two to see if they are the same.
+  ASSERT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) &&
+               (!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(),
+                        dhe1.public_key_.len())));
+}
+
+TEST_F(TransportTest, TestConnectVerifyReusedECDHE) {
+  SetDtlsPeer();
+  DtlsInspectorRecordHandshakeMessage *i1 = new
+    DtlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
+  p1_->SetInspector(i1);
+  p1_->SetReuseECDHEKey();
+  ConnectSocket();
+  TlsServerKeyExchangeECDHE dhe1;
+  ASSERT_TRUE(dhe1.Parse(i1->buffer().data(), i1->buffer().len()));
+
+  Reset();
+  SetDtlsPeer();
+  DtlsInspectorRecordHandshakeMessage *i2 = new
+    DtlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
+
+  p1_->SetInspector(i2);
+  p1_->SetReuseECDHEKey();
+
+  ConnectSocket();
+  TlsServerKeyExchangeECDHE dhe2;
+  ASSERT_TRUE(dhe2.Parse(i2->buffer().data(), i2->buffer().len()));
+
+  // Now compare these two to see if they are the same.
+  ASSERT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len());
+  ASSERT_TRUE(!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(),
+                      dhe1.public_key_.len()));
+}
+
 TEST_F(TransportTest, TestTransfer) {
   SetDtlsPeer();
   ConnectSocket();
   TransferTest(1);
 }
 
 TEST_F(TransportTest, TestConnectLoseFirst) {
   SetDtlsPeer();
@@ -735,16 +1063,75 @@ TEST_F(TransportTest, TestConnectIce) {
 }
 
 TEST_F(TransportTest, TestTransferIce) {
   SetDtlsPeer();
   ConnectIce();
   TransferTest(1);
 }
 
+// test the default configuration against a peer that supports only
+// one of the mandatory-to-implement suites, which should succeed
+static void ConfigureOneCipher(TransportTestPeer* peer, uint16_t suite) {
+  std::vector<uint16_t> justOne;
+  justOne.push_back(suite);
+  std::vector<uint16_t> everythingElse(SSL_GetImplementedCiphers(),
+                                       SSL_GetImplementedCiphers()
+                                       + SSL_GetNumImplementedCiphers());
+  std::remove(everythingElse.begin(), everythingElse.end(), suite);
+  peer->SetCipherSuiteChanges(justOne, everythingElse);
+}
+
+TEST_F(TransportTest, TestCipherMismatch) {
+  SetDtlsPeer();
+  ConfigureOneCipher(p1_, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
+  ConfigureOneCipher(p2_, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
+  ConnectSocketExpectFail();
+}
+
+TEST_F(TransportTest, TestCipherMandatoryOnlyGcm) {
+  SetDtlsPeer();
+  ConfigureOneCipher(p1_, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
+  ConnectSocket();
+  ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p1_->cipherSuite());
+}
+
+TEST_F(TransportTest, TestCipherMandatoryOnlyCbc) {
+  SetDtlsPeer();
+  ConfigureOneCipher(p1_, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
+  ConnectSocket();
+  ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, p1_->cipherSuite());
+}
+
+TEST_F(TransportTest, TestSrtpMismatch) {
+  std::vector<uint16_t> setA;
+  setA.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
+  std::vector<uint16_t> setB;
+  setB.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
+
+  p1_->SetSrtpCiphers(setA);
+  p2_->SetSrtpCiphers(setB);
+  SetDtlsPeer();
+  ConnectSocket();
+
+  ASSERT_EQ(0, p1_->srtpCipher());
+  ASSERT_EQ(0, p2_->srtpCipher());
+}
+
+// NSS doesn't support DHE suites on the server end.
+// This checks to see if we barf when that's the only option available.
+TEST_F(TransportTest, TestDheOnlyFails) {
+  SetDtlsPeer();
+
+  // p2_ is the client
+  // setting this on p1_ (the server) causes NSS to assert
+  ConfigureOneCipher(p2_, TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
+  ConnectSocketExpectFail();
+}
+
 TEST(PushTests, LayerFail) {
   mozilla::RefPtr<TransportFlow> flow = new TransportFlow();
   nsresult rv;
   bool destroyed1, destroyed2;
 
   rv = flow->PushLayer(new TransportLayerDummy(true, &destroyed1));
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
@@ -755,17 +1142,16 @@ TEST(PushTests, LayerFail) {
   ASSERT_EQ(true, destroyed1);
   ASSERT_EQ(true, destroyed2);
 
   rv = flow->PushLayer(new TransportLayerDummy(true, &destroyed1));
   ASSERT_TRUE(NS_FAILED(rv));
   ASSERT_EQ(true, destroyed1);
 }
 
-
 TEST(PushTests, LayersFail) {
   mozilla::RefPtr<TransportFlow> flow = new TransportFlow();
   nsresult rv;
   bool destroyed1, destroyed2, destroyed3;
 
   rv = flow->PushLayer(new TransportLayerDummy(true, &destroyed1));
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
--- a/media/mtransport/transportlayer.h
+++ b/media/mtransport/transportlayer.h
@@ -24,17 +24,17 @@ class TransportFlow;
 
 typedef int TransportResult;
 
 enum {
   TE_WOULDBLOCK = -1, TE_ERROR = -2, TE_INTERNAL = -3
 };
 
 #define TRANSPORT_LAYER_ID(name) \
-  virtual const std::string id() { return name; } \
+  virtual const std::string id() const { return name; } \
   static std::string ID() { return name; }
 
 // Abstract base class for network transport layers.
 class TransportLayer : public sigslot::has_slots<> {
  public:
   // The state of the transport flow
   // We can't use "ERROR" because Windows has a macro named "ERROR"
   enum State { TS_NONE, TS_INIT, TS_CONNECTING, TS_OPEN, TS_CLOSED, TS_ERROR };
@@ -76,41 +76,41 @@ class TransportLayer : public sigslot::h
   // Event definitions that one can register for
   // State has changed
   sigslot::signal2<TransportLayer*, State> SignalStateChange;
   // Data received on the flow
   sigslot::signal3<TransportLayer*, const unsigned char *, size_t>
                          SignalPacketReceived;
 
   // Return the layer id for this layer
-  virtual const std::string id() = 0;
+  virtual const std::string id() const = 0;
 
   // The id of the flow
-  const std::string& flow_id() {
+  const std::string& flow_id() const {
     return flow_id_;
   }
 
  protected:
   virtual void WasInserted() {}
   virtual void SetState(State state, const char *file, unsigned line);
   // Check if we are on the right thread
-  void CheckThread() {
+  void CheckThread() const {
     NS_ABORT_IF_FALSE(CheckThreadInt(), "Wrong thread");
   }
 
   Mode mode_;
   State state_;
   std::string flow_id_;
   TransportLayer *downward_; // The next layer in the stack
   nsCOMPtr<nsIEventTarget> target_;
 
  private:
   DISALLOW_COPY_ASSIGN(TransportLayer);
 
-  bool CheckThreadInt() {
+  bool CheckThreadInt() const {
     bool on;
 
     if (!target_)  // OK if no thread set.
       return true;
 
     NS_ENSURE_SUCCESS(target_->IsOnCurrentThread(&on), false);
     NS_ENSURE_TRUE(on, false);
 
--- a/media/mtransport/transportlayerdtls.cpp
+++ b/media/mtransport/transportlayerdtls.cpp
@@ -495,21 +495,21 @@ bool TransportLayerDtls::Setup() {
 
     rv = SSL_OptionSet(ssl_fd, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
     if (rv != SECSuccess) {
       MOZ_MTLOG(ML_ERROR, "Couldn't require certificate");
       return false;
     }
   }
 
-  // Require TLS 1.1. Perhaps some day in the future we will allow
-  // TLS 1.0 for stream modes.
+  // Require TLS 1.1 or 1.2. Perhaps some day in the future we will allow TLS
+  // 1.0 for stream modes.
   SSLVersionRange version_range = {
     SSL_LIBRARY_VERSION_TLS_1_1,
-    SSL_LIBRARY_VERSION_TLS_1_1
+    SSL_LIBRARY_VERSION_TLS_1_2
   };
 
   rv = SSL_VersionRangeSet(ssl_fd, &version_range);
   if (rv != SECSuccess) {
     MOZ_MTLOG(ML_ERROR, "Can't disable SSLv3");
     return false;
   }
 
@@ -544,26 +544,24 @@ bool TransportLayerDtls::Setup() {
   }
 
   rv = SSL_OptionSet(ssl_fd, SSL_NO_LOCKS, PR_TRUE);
   if (rv != SECSuccess) {
     MOZ_MTLOG(ML_ERROR, "Couldn't disable locks");
     return false;
   }
 
-  // Set the SRTP ciphers
-  if (srtp_ciphers_.size()) {
-    // Note: std::vector is guaranteed to contiguous
-    rv = SSL_SetSRTPCiphers(ssl_fd, &srtp_ciphers_[0],
-                            srtp_ciphers_.size());
+  rv = SSL_OptionSet(ssl_fd, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
+  if (rv != SECSuccess) {
+    MOZ_MTLOG(ML_ERROR, "Couldn't disable ECDHE key reuse");
+    return false;
+  }
 
-    if (rv != SECSuccess) {
-      MOZ_MTLOG(ML_ERROR, "Couldn't set SRTP cipher suite");
-      return false;
-    }
+  if (!SetupCipherSuites(ssl_fd)) {
+    return false;
   }
 
   // Certificate validation
   rv = SSL_AuthCertificateHook(ssl_fd, AuthCertificateHook,
                                reinterpret_cast<void *>(this));
   if (rv != SECSuccess) {
     MOZ_MTLOG(ML_ERROR, "Couldn't set certificate validation hook");
     return false;
@@ -583,16 +581,145 @@ bool TransportLayerDtls::Setup() {
 
   if (downward_->state() == TS_OPEN) {
     Handshake();
   }
 
   return true;
 }
 
+// Ciphers we need to enable.  These are on by default in standard firefox
+// builds, but can be disabled with prefs and they aren't on in our unit tests
+// since that uses NSS default configuration.
+// Only override prefs to comply with MUST statements in the security-arch.
+static const uint32_t EnabledCiphers[] = {
+  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+};
+
+// Disalbe all NSS suites modes without PFS or with old and rusty ciphersuites.
+// Anything outside this list is governed by the usual combination of policy
+// and user preferences.
+static const uint32_t DisabledCiphers[] = {
+  TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+  TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+  TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+  TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+
+  TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+  TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+  TLS_DHE_DSS_WITH_RC4_128_SHA,
+
+  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+  TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+  TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+  TLS_ECDH_RSA_WITH_RC4_128_SHA,
+
+  TLS_RSA_WITH_AES_128_GCM_SHA256,
+  TLS_RSA_WITH_AES_128_CBC_SHA,
+  TLS_RSA_WITH_AES_128_CBC_SHA256,
+  TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+  TLS_RSA_WITH_AES_256_CBC_SHA,
+  TLS_RSA_WITH_AES_256_CBC_SHA256,
+  TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+  TLS_RSA_WITH_SEED_CBC_SHA,
+  SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
+  TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+  TLS_RSA_WITH_RC4_128_SHA,
+  TLS_RSA_WITH_RC4_128_MD5,
+
+  TLS_DHE_RSA_WITH_DES_CBC_SHA,
+  TLS_DHE_DSS_WITH_DES_CBC_SHA,
+  SSL_RSA_FIPS_WITH_DES_CBC_SHA,
+  TLS_RSA_WITH_DES_CBC_SHA,
+
+  TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
+  TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+
+  TLS_RSA_EXPORT_WITH_RC4_40_MD5,
+  TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+
+  TLS_ECDHE_ECDSA_WITH_NULL_SHA,
+  TLS_ECDHE_RSA_WITH_NULL_SHA,
+  TLS_ECDH_ECDSA_WITH_NULL_SHA,
+  TLS_ECDH_RSA_WITH_NULL_SHA,
+
+  TLS_RSA_WITH_NULL_SHA,
+  TLS_RSA_WITH_NULL_SHA256,
+  TLS_RSA_WITH_NULL_MD5,
+};
+
+bool TransportLayerDtls::SetupCipherSuites(PRFileDesc* ssl_fd) const {
+  SECStatus rv;
+
+  // Set the SRTP ciphers
+  if (!srtp_ciphers_.empty()) {
+    // Note: std::vector is guaranteed to contiguous
+    rv = SSL_SetSRTPCiphers(ssl_fd, &srtp_ciphers_[0], srtp_ciphers_.size());
+
+    if (rv != SECSuccess) {
+      MOZ_MTLOG(ML_ERROR, "Couldn't set SRTP cipher suite");
+      return false;
+    }
+  }
+
+  for (size_t i = 0; i < PR_ARRAY_SIZE(EnabledCiphers); ++i) {
+    MOZ_MTLOG(ML_INFO, LAYER_INFO << "Enabling: " << EnabledCiphers[i]);
+    rv = SSL_CipherPrefSet(ssl_fd, EnabledCiphers[i], PR_TRUE);
+    if (rv != SECSuccess) {
+      MOZ_MTLOG(ML_ERROR, LAYER_INFO <<
+                "Unable to enable suite: " << EnabledCiphers[i]);
+      return false;
+    }
+  }
+
+  for (size_t i = 0; i < PR_ARRAY_SIZE(DisabledCiphers); ++i) {
+    MOZ_MTLOG(ML_INFO, LAYER_INFO << "Disabling: " << DisabledCiphers[i]);
+
+    PRBool enabled = false;
+    rv = SSL_CipherPrefGet(ssl_fd, DisabledCiphers[i], &enabled);
+    if (rv != SECSuccess) {
+      MOZ_MTLOG(ML_NOTICE, LAYER_INFO <<
+                "Unable to check if suite is enabled: " << DisabledCiphers[i]);
+      return false;
+    }
+    if (enabled) {
+      rv = SSL_CipherPrefSet(ssl_fd, DisabledCiphers[i], PR_FALSE);
+      if (rv != SECSuccess) {
+        MOZ_MTLOG(ML_NOTICE, LAYER_INFO <<
+                  "Unable to disable suite: " << DisabledCiphers[i]);
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+nsresult TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite) const {
+  CheckThread();
+  if (!cipherSuite) {
+    MOZ_MTLOG(ML_ERROR, LAYER_INFO << "GetCipherSuite passed a nullptr");
+    return NS_ERROR_NULL_POINTER;
+  }
+  if (state_ != TS_OPEN) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  SSLChannelInfo info;
+  SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &info, sizeof(info));
+  if (rv != SECSuccess) {
+    MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "GetCipherSuite can't get channel info");
+    return NS_ERROR_FAILURE;
+  }
+  *cipherSuite = info.cipherSuite;
+  return NS_OK;
+}
 
 void TransportLayerDtls::StateChange(TransportLayer *layer, State state) {
   if (state <= state_) {
     MOZ_MTLOG(ML_ERROR, "Lower layer state is going backwards from ours");
     TL_SET_STATE(TS_ERROR);
     return;
   }
 
@@ -795,17 +922,17 @@ SECStatus TransportLayerDtls::GetClientA
 
 nsresult TransportLayerDtls::SetSrtpCiphers(std::vector<uint16_t> ciphers) {
   // TODO: We should check these
   srtp_ciphers_ = ciphers;
 
   return NS_OK;
 }
 
-nsresult TransportLayerDtls::GetSrtpCipher(uint16_t *cipher) {
+nsresult TransportLayerDtls::GetSrtpCipher(uint16_t *cipher) const {
   CheckThread();
   SECStatus rv = SSL_GetSRTPCipher(ssl_fd_, cipher);
   if (rv != SECSuccess) {
     MOZ_MTLOG(ML_DEBUG, "No SRTP cipher negotiated");
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
--- a/media/mtransport/transportlayerdtls.h
+++ b/media/mtransport/transportlayerdtls.h
@@ -68,18 +68,20 @@ class TransportLayerDtls : public Transp
   void SetIdentity(const RefPtr<DtlsIdentity>& identity) {
     identity_ = identity;
   }
   nsresult SetVerificationAllowAll();
   nsresult SetVerificationDigest(const std::string digest_algorithm,
                                  const unsigned char *digest_value,
                                  size_t digest_len);
 
+  nsresult GetCipherSuite(uint16_t* cipherSuite) const;
+
   nsresult SetSrtpCiphers(std::vector<uint16_t> ciphers);
-  nsresult GetSrtpCipher(uint16_t *cipher);
+  nsresult GetSrtpCipher(uint16_t *cipher) const;
 
   nsresult ExportKeyingMaterial(const std::string& label,
                                 bool use_context,
                                 const std::string& context,
                                 unsigned char *out,
                                 unsigned int outlen);
 
   const CERTCertificate *GetPeerCert() const {
@@ -91,16 +93,19 @@ class TransportLayerDtls : public Transp
   virtual void WasInserted();
   virtual TransportResult SendPacket(const unsigned char *data, size_t len);
 
   // Signals
   void StateChange(TransportLayer *layer, State state);
   void PacketReceived(TransportLayer* layer, const unsigned char *data,
                       size_t len);
 
+  // For testing use only.  Returns the fd.
+  PRFileDesc* internal_fd() { CheckThread(); return ssl_fd_.rwget(); }
+
   TRANSPORT_LAYER_ID("dtls")
 
   private:
   DISALLOW_COPY_ASSIGN(TransportLayerDtls);
 
   // A single digest to check
   class VerificationDigest {
    public:
@@ -121,16 +126,17 @@ class TransportLayerDtls : public Transp
 
    private:
     ~VerificationDigest() {}
     DISALLOW_COPY_ASSIGN(VerificationDigest);
   };
 
 
   bool Setup();
+  bool SetupCipherSuites(PRFileDesc* ssl_fd) const;
   void Handshake();
 
   static SECStatus GetClientAuthDataHook(void *arg, PRFileDesc *fd,
                                          CERTDistNames *caNames,
                                          CERTCertificate **pRetCert,
                                          SECKEYPrivateKey **pRetKey);
   static SECStatus AuthCertificateHook(void *arg,
                                        PRFileDesc *fd,
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_null.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_null.cc
@@ -45,22 +45,22 @@ AppCapturerNull::AppCapturerNull()
 AppCapturerNull::~AppCapturerNull() {
 }
 
 bool AppCapturerNull::GetAppList(AppList* apps) {
   // Not implemented yet: See Bug 1036653
   return false;
 }
 
-bool SelectApp(ProcessId id) {
+bool AppCapturerNull::SelectApp(ProcessId id) {
   // Not implemented yet: See Bug 1036653
   return false;
 }
 
-bool BringAppToFront() {
+bool AppCapturerNull::BringAppToFront() {
   // Not implemented yet: See Bug 1036653
   return false;
 }
 
 // DesktopCapturer interface.
 void AppCapturerNull::Start(Callback* callback) {
   assert(!callback_);
   assert(callback);
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture.gypi
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture.gypi
@@ -99,16 +99,18 @@
               '-lXext',
               '-lXfixes',
               '-lXrender',
             ],
           },
         }],
         ['OS!="win" and OS!="mac" and use_x11==0', {
           'sources': [
+            "app_capturer_null.cc",
+            "desktop_device_info_null.cc",
             "mouse_cursor_monitor_null.cc",
             "screen_capturer_null.cc",
             "window_capturer_null.cc",
           ],
         }],
         ['OS=="mac"', {
           'sources': [
             "mac/desktop_configuration.h",
new file mode 100644
--- /dev/null
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info_null.cc
@@ -0,0 +1,38 @@
+/* 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 "webrtc/modules/desktop_capture/desktop_device_info.h"
+
+namespace webrtc {
+
+class DesktopDeviceInfoNull : public DesktopDeviceInfoImpl {
+public:
+  DesktopDeviceInfoNull();
+  ~DesktopDeviceInfoNull();
+
+  virtual int32_t Init();
+};
+
+DesktopDeviceInfo * DesktopDeviceInfoImpl::Create() {
+  DesktopDeviceInfoNull * pDesktopDeviceInfo = new DesktopDeviceInfoNull();
+  if (pDesktopDeviceInfo && pDesktopDeviceInfo->Init() != 0) {
+    delete pDesktopDeviceInfo;
+    pDesktopDeviceInfo = NULL;
+  }
+  return pDesktopDeviceInfo;
+}
+
+DesktopDeviceInfoNull::DesktopDeviceInfoNull() {
+}
+
+DesktopDeviceInfoNull::~DesktopDeviceInfoNull() {
+}
+
+int32_t
+DesktopDeviceInfoNull::Init() {
+  initializeWindowList();
+  return 0;
+}
+
+} //namespace webrtc
--- a/media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/desktop_capture_impl.cc
@@ -354,26 +354,31 @@ int32_t DesktopCaptureImpl::Init(const c
 
     // processid hard-coded until implemented.  See Bug 1036653
     ProcessId processid = 0;
     pAppCapturer->SelectApp(processid);
 
     MouseCursorMonitor * pMouseCursorMonitor = MouseCursorMonitor::CreateForScreen(webrtc::DesktopCaptureOptions::CreateDefault(), webrtc::kFullDesktopScreenId);
     desktop_capturer_cursor_composer_.reset(new DesktopAndCursorComposer(pAppCapturer, pMouseCursorMonitor));
   } else if (type == Screen) {
-    ScreenCapturer *pScreenCapturer = ScreenCapturer::Create();
+
+    DesktopCaptureOptions options = DesktopCaptureOptions::CreateDefault();
+    // Leave desktop effects enabled during WebRTC captures.
+    options.set_disable_effects(false);
+
+    ScreenCapturer *pScreenCapturer = ScreenCapturer::Create(options);
     if (!pScreenCapturer) {
       return -1;
     }
 
     ScreenId screenid = webrtc::kFullDesktopScreenId;
     pScreenCapturer->SelectScreen(screenid);
     pScreenCapturer->SetMouseShapeObserver(this);
 
-    MouseCursorMonitor * pMouseCursorMonitor = MouseCursorMonitor::CreateForScreen(webrtc::DesktopCaptureOptions::CreateDefault(), screenid);
+    MouseCursorMonitor * pMouseCursorMonitor = MouseCursorMonitor::CreateForScreen(options, screenid);
     desktop_capturer_cursor_composer_.reset(new DesktopAndCursorComposer(pScreenCapturer, pMouseCursorMonitor));
   } else if (type == Window) {
     WindowCapturer *pWindowCapturer = WindowCapturer::Create();
     if (!pWindowCapturer) {
       return -1;
     }
 
     std::string idStr(uniqueId);
--- a/mfbt/WeakPtr.h
+++ b/mfbt/WeakPtr.h
@@ -178,17 +178,17 @@ public:
     *this = aOther;
   }
 
   WeakPtr& operator=(T* aOther)
   {
     return *this = aOther->SelfReferencingWeakPtr();
   }
 
-  WeakPtr(T* aOther)
+  MOZ_IMPLICIT WeakPtr(T* aOther)
   {
     *this = aOther;
   }
 
   // Ensure that mRef is dereferenceable in the uninitialized state.
   WeakPtr() : mRef(new WeakReference(nullptr)) {}
 
   operator T*() const { return mRef->get(); }
--- a/mfbt/tests/TestPair.cpp
+++ b/mfbt/tests/TestPair.cpp
@@ -24,31 +24,31 @@ using mozilla::Pair;
   static_assert(sizeof(name##_2.second()) > 0, \
                 "second method should work on Pair<" #T2 ", " #T1 ">"); \
   static_assert(sizeof(name##_2) == (size), \
                 "Pair<" #T2 ", " #T1 "> has an unexpected size");
 
 INSTANTIATE(int, int, prim1, 2 * sizeof(int));
 INSTANTIATE(int, long, prim2, 2 * sizeof(long));
 
-struct EmptyClass { EmptyClass(int) {} };
-struct NonEmpty { char mC; NonEmpty(int) {} };
+struct EmptyClass { explicit EmptyClass(int) {} };
+struct NonEmpty { char mC; explicit NonEmpty(int) {} };
 
 INSTANTIATE(int, EmptyClass, both1, sizeof(int));
 INSTANTIATE(int, NonEmpty, both2, 2 * sizeof(int));
 INSTANTIATE(EmptyClass, NonEmpty, both3, 1);
 
-struct A { char dummy; A(int) {} };
-struct B : A { B(int aI) : A(aI) {} };
+struct A { char dummy; explicit A(int) {} };
+struct B : A { explicit B(int aI) : A(aI) {} };
 
 INSTANTIATE(A, A, class1, 2);
 INSTANTIATE(A, B, class2, 2);
 INSTANTIATE(A, EmptyClass, class3, 1);
 
-struct OtherEmpty : EmptyClass { OtherEmpty(int aI) : EmptyClass(aI) {} };
+struct OtherEmpty : EmptyClass { explicit OtherEmpty(int aI) : EmptyClass(aI) {} };
 
 // C++11 requires distinct objects of the same type, within the same "most
 // derived object", to have different addresses.  Pair allocates its elements as
 // two bases, a base and a member, or two members.  If the two elements have
 // non-zero size or are unrelated, no big deal.  But if they're both empty and
 // related, something -- possibly both -- must be inflated.  Exactly which are
 // inflated depends which PairHelper specialization is used.  We could
 // potentially assert something about size for this case, but whatever we could
--- a/mfbt/tests/TestSplayTree.cpp
+++ b/mfbt/tests/TestSplayTree.cpp
@@ -84,17 +84,17 @@ static int gValues[] = {
   115, 988, 978, 762, 486, 301, 616, 10, 78, 603, 452, 965, 279, 972, 413, 895,
   591, 662, 594, 348, 423, 489, 43, 699, 433, 509, 355, 270, 66, 83, 95, 561,
   661, 562, 329, 620, 370, 64, 187, 503, 716, 856, 310, 786, 167, 71, 239, 359,
   537, 437, 305, 673, 824, 911, 681, 271
 };
 
 struct SplayInt : SplayTreeNode<SplayInt>
 {
-  SplayInt(int aValue) : mValue(aValue) {}
+  explicit SplayInt(int aValue) : mValue(aValue) {}
 
   static int compare(const SplayInt& aOne, const SplayInt& aTwo)
   {
     if (aOne.mValue < aTwo.mValue) {
       return -1;
     }
     if (aOne.mValue > aTwo.mValue) {
       return 1;
--- a/mobile/android/base/GeckoInputConnection.java
+++ b/mobile/android/base/GeckoInputConnection.java
@@ -512,17 +512,18 @@ class GeckoInputConnection
             @Override
             public void run() {
                 Looper.prepare();
                 synchronized (GeckoInputConnection.class) {
                     sBackgroundHandler = new Handler();
                     GeckoInputConnection.class.notify();
                 }
                 Looper.loop();
-                sBackgroundHandler = null;
+                // We should never be exiting the thread loop.
+                throw new IllegalThreadStateException("unreachable code");
             }
         }, LOGTAG);
         backgroundThread.setDaemon(true);
         backgroundThread.start();
         while (sBackgroundHandler == null) {
             try {
                 // wait for new thread to set sBackgroundHandler
                 GeckoInputConnection.class.wait();
@@ -557,21 +558,17 @@ class GeckoInputConnection
         return false;
     }
 
     @Override
     public Handler getHandler(Handler defHandler) {
         if (!canReturnCustomHandler()) {
             return defHandler;
         }
-        // getBackgroundHandler() is synchronized and requires locking,
-        // but if we already have our handler, we don't have to lock
-        final Handler newHandler = sBackgroundHandler != null
-                                 ? sBackgroundHandler
-                                 : getBackgroundHandler();
+        final Handler newHandler = getBackgroundHandler();
         if (mEditableClient.setInputConnectionHandler(newHandler)) {
             return newHandler;
         }
         // Setting new IC handler failed; return old IC handler
         return mEditableClient.getInputConnectionHandler();
     }
 
     @Override
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -144,17 +144,17 @@
 <!ENTITY pref_donottrack_no_pref "Do not tell sites anything about my tracking preferences">
 
 <!ENTITY pref_char_encoding "Character encoding">
 <!ENTITY pref_char_encoding_on "Show menu">
 <!ENTITY pref_char_encoding_off "Don\'t show menu">
 <!ENTITY pref_clear_private_data2 "Clear now">
 <!ENTITY pref_clear_private_data_category "Clear private data">
 <!ENTITY pref_clear_on_exit_title "Always clear when quitting">
-<!ENTITY pref_clear_on_exit_summary "&brandShortName; will automatically clear your data whenever you select &quot;Quit&quot; from the main menu">
+<!ENTITY pref_clear_on_exit_summary2 "&brandShortName; will automatically clear your data whenever you select \u0022Quit\u0022 from the main menu">
 <!ENTITY pref_clear_on_exit_dialog_title "Select which data to clear">
 <!ENTITY pref_plugins "Plugins">
 <!ENTITY pref_plugins_enabled "Enabled">
 <!ENTITY pref_plugins_tap_to_play "Tap to play">
 <!ENTITY pref_plugins_disabled "Disabled">
 <!ENTITY pref_text_size "Text size">
 <!ENTITY pref_reflow_on_zoom4 "Text reflow">
 <!ENTITY pref_restore "Tabs">
--- a/mobile/android/base/resources/xml/preferences_privacy.xml
+++ b/mobile/android/base/resources/xml/preferences_privacy.xml
@@ -46,17 +46,17 @@
         <!-- This pref is persisted in both Gecko and Java -->
         <org.mozilla.gecko.preferences.ListCheckboxPreference
                             android:key="android.not_a_preference.history.clear_on_exit"
                             gecko:entries="@array/pref_private_data_entries"
                             gecko:entryValues="@array/pref_private_data_values"
                             gecko:initialValues="@array/pref_clear_on_exit_defaults"
 
                             android:title="@string/pref_clear_on_exit_title"
-                            android:summary="@string/pref_clear_on_exit_summary"
+                            android:summary="@string/pref_clear_on_exit_summary2"
 
                             android:dialogTitle="@string/pref_clear_on_exit_dialog_title"
                             android:positiveButtonText="@string/button_set"/>
 
     </PreferenceCategory>
 
 </PreferenceScreen>
 
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -164,17 +164,17 @@
   <string name="pref_donottrack_no_pref">&pref_donottrack_no_pref;</string>
 
   <string name="pref_char_encoding">&pref_char_encoding;</string>
   <string name="pref_char_encoding_on">&pref_char_encoding_on;</string>
   <string name="pref_char_encoding_off">&pref_char_encoding_off;</string>
   <string name="pref_clear_private_data">&pref_clear_private_data2;</string>
   <string name="pref_clear_private_data_category">&pref_clear_private_data_category;</string>
   <string name="pref_clear_on_exit_title">&pref_clear_on_exit_title;</string>
-  <string name="pref_clear_on_exit_summary">&pref_clear_on_exit_summary;</string>
+  <string name="pref_clear_on_exit_summary2">&pref_clear_on_exit_summary2;</string>
   <string name="pref_clear_on_exit_dialog_title">&pref_clear_on_exit_dialog_title;</string>
   <string name="pref_plugins">&pref_plugins;</string>
   <string name="pref_plugins_enabled">&pref_plugins_enabled;</string>
   <string name="pref_plugins_tap_to_play">&pref_plugins_tap_to_play;</string>
   <string name="pref_plugins_disabled">&pref_plugins_disabled;</string>
   <string name="pref_text_size">&pref_text_size;</string>
   <string name="pref_font_size_tiny">&pref_font_size_tiny;</string>
   <string name="pref_font_size_small">&pref_font_size_small;</string>
rename from modules/libjar/zipwriter/src/StreamFunctions.cpp
rename to modules/libjar/zipwriter/StreamFunctions.cpp
rename from modules/libjar/zipwriter/src/StreamFunctions.h
rename to modules/libjar/zipwriter/StreamFunctions.h
rename from modules/libjar/zipwriter/src/ZipWriterModule.cpp
rename to modules/libjar/zipwriter/ZipWriterModule.cpp
--- a/modules/libjar/zipwriter/moz.build
+++ b/modules/libjar/zipwriter/moz.build
@@ -1,9 +1,26 @@
 # -*- 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 += ['public', 'src']
 TEST_DIRS += ['test']
 
+XPIDL_SOURCES += [
+    'nsIZipWriter.idl',
+]
+
+XPIDL_MODULE = 'zipwriter'
+
+UNIFIED_SOURCES += [
+    'nsDeflateConverter.cpp',
+    'nsZipDataStream.cpp',
+    'nsZipHeader.cpp',
+    'nsZipWriter.cpp',
+    'StreamFunctions.cpp',
+    'ZipWriterModule.cpp',
+]
+
+MSVC_ENABLE_PGO = True
+
+FINAL_LIBRARY = 'xul'
rename from modules/libjar/zipwriter/src/nsDeflateConverter.cpp
rename to modules/libjar/zipwriter/nsDeflateConverter.cpp
rename from modules/libjar/zipwriter/src/nsDeflateConverter.h
rename to modules/libjar/zipwriter/nsDeflateConverter.h
rename from modules/libjar/zipwriter/public/nsIZipWriter.idl
rename to modules/libjar/zipwriter/nsIZipWriter.idl
rename from modules/libjar/zipwriter/src/nsZipDataStream.cpp
rename to modules/libjar/zipwriter/nsZipDataStream.cpp
rename from modules/libjar/zipwriter/src/nsZipDataStream.h
rename to modules/libjar/zipwriter/nsZipDataStream.h
rename from modules/libjar/zipwriter/src/nsZipHeader.cpp
rename to modules/libjar/zipwriter/nsZipHeader.cpp
rename from modules/libjar/zipwriter/src/nsZipHeader.h
rename to modules/libjar/zipwriter/nsZipHeader.h
rename from modules/libjar/zipwriter/src/nsZipWriter.cpp
rename to modules/libjar/zipwriter/nsZipWriter.cpp
rename from modules/libjar/zipwriter/src/nsZipWriter.h
rename to modules/libjar/zipwriter/nsZipWriter.h
deleted file mode 100644
--- a/modules/libjar/zipwriter/public/moz.build
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- 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/.
-
-XPIDL_SOURCES += [
-    'nsIZipWriter.idl',
-]
-
-XPIDL_MODULE = 'zipwriter'
-
deleted file mode 100644
--- a/modules/libjar/zipwriter/src/moz.build
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- 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/.
-
-UNIFIED_SOURCES += [
-    'nsDeflateConverter.cpp',
-    'nsZipDataStream.cpp',
-    'nsZipHeader.cpp',
-    'nsZipWriter.cpp',
-    'StreamFunctions.cpp',
-    'ZipWriterModule.cpp',
-]
-
-MSVC_ENABLE_PGO = True
-
-FINAL_LIBRARY = 'xul'
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1131,17 +1131,17 @@ pref("network.http.bypass-cachelock-thre
 #else
 pref("network.http.bypass-cachelock-threshold", 250);
 #endif
 
 // Try and use SPDY when using SSL
 pref("network.http.spdy.enabled", true);
 pref("network.http.spdy.enabled.v3", true);
 pref("network.http.spdy.enabled.v3-1", true);
-pref("network.http.spdy.enabled.http2draft", false);
+pref("network.http.spdy.enabled.http2draft", true);
 pref("network.http.spdy.enforce-tls-profile", true);
 pref("network.http.spdy.chunk-size", 16000);
 pref("network.http.spdy.timeout", 180);
 pref("network.http.spdy.coalesce-hostnames", true);
 pref("network.http.spdy.persistent-settings", false);
 pref("network.http.spdy.ping-threshold", 58);
 pref("network.http.spdy.ping-timeout", 8);
 pref("network.http.spdy.send-buffer-size", 131072);
--- a/netwerk/base/public/nsAsyncRedirectVerifyHelper.h
+++ b/netwerk/base/public/nsAsyncRedirectVerifyHelper.h
@@ -87,17 +87,17 @@ private:
 };
 
 /*
  * Helper to make the call-stack handle some control-flow for us
  */
 class nsAsyncRedirectAutoCallback
 {
 public:
-    nsAsyncRedirectAutoCallback(nsIAsyncVerifyRedirectCallback* aCallback)
+    explicit nsAsyncRedirectAutoCallback(nsIAsyncVerifyRedirectCallback* aCallback)
         : mCallback(aCallback)
     {
         mResult = NS_OK;
     }
     ~nsAsyncRedirectAutoCallback()
     {
         if (mCallback)
             mCallback->OnRedirectVerifyCallback(mResult);
--- a/netwerk/base/public/nsStreamListenerWrapper.h
+++ b/netwerk/base/public/nsStreamListenerWrapper.h
@@ -12,17 +12,17 @@
 #include "mozilla/Attributes.h"
 
 // Wrapper class to make replacement of nsHttpChannel's listener
 // from JavaScript possible. It is workaround for bug 433711 and 682305.
 class nsStreamListenerWrapper MOZ_FINAL : public nsIStreamListener
                                         , public nsIThreadRetargetableStreamListener
 {
 public:
-  nsStreamListenerWrapper(nsIStreamListener *listener)
+  explicit nsStreamListenerWrapper(nsIStreamListener *listener)
     : mListener(listener)
   {
     NS_ASSERTION(mListener, "no stream listener specified");
   }
 
   NS_DECL_ISUPPORTS
   NS_FORWARD_NSIREQUESTOBSERVER(mListener->)
   NS_FORWARD_NSISTREAMLISTENER(mListener->)
--- a/netwerk/base/public/nsURIHashKey.h
+++ b/netwerk/base/public/nsURIHashKey.h
@@ -14,17 +14,17 @@
  * Hashtable key class to use with nsTHashtable/nsBaseHashtable
  */
 class nsURIHashKey : public PLDHashEntryHdr
 {
 public:
     typedef nsIURI* KeyType;
     typedef const nsIURI* KeyTypePointer;
 
-    nsURIHashKey(const nsIURI* aKey) :
+    explicit nsURIHashKey(const nsIURI* aKey) :
         mKey(const_cast<nsIURI*>(aKey)) { MOZ_COUNT_CTOR(nsURIHashKey); }
     nsURIHashKey(const nsURIHashKey& toCopy) :
         mKey(toCopy.mKey) { MOZ_COUNT_CTOR(nsURIHashKey); }
     ~nsURIHashKey() { MOZ_COUNT_DTOR(nsURIHashKey); }
 
     nsIURI* GetKey() const { return mKey; }
 
     bool KeyEquals(const nsIURI* aKey) const {
--- a/netwerk/base/public/security-prefs.js
+++ b/netwerk/base/public/security-prefs.js
@@ -10,17 +10,17 @@ pref("security.ssl.renego_unrestricted_h
 pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
 pref("security.ssl.require_safe_negotiation",  false);
 pref("security.ssl.warn_missing_rfc5746",  1);
 pref("security.ssl.enable_ocsp_stapling", true);
 pref("security.ssl.enable_false_start", true);
 pref("security.ssl.false_start.require-npn", true);
 pref("security.ssl.false_start.require-forward-secrecy", true);
 pref("security.ssl.enable_npn", true);
-pref("security.ssl.enable_alpn", false);
+pref("security.ssl.enable_alpn", true);
 
 pref("security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", true);
 pref("security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", true);
 pref("security.ssl3.ecdhe_rsa_aes_128_sha", true);
 pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", true);
 pref("security.ssl3.ecdhe_rsa_aes_256_sha", true);
 pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", true);
 pref("security.ssl3.ecdhe_rsa_des_ede3_sha", false);
--- a/netwerk/base/src/Dashboard.cpp
+++ b/netwerk/base/src/Dashboard.cpp
@@ -136,17 +136,17 @@ class ConnectionData
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSITRANSPORTEVENTSINK
     NS_DECL_NSITIMERCALLBACK
 
     void StartTimer(uint32_t aTimeout);
     void StopTimer();
 
-    ConnectionData(Dashboard *target)
+    explicit ConnectionData(Dashboard *target)
     {
         mThread = nullptr;
         mDashboard = target;
     }
 
     nsCOMPtr<nsISocketTransport> mSocket;
     nsCOMPtr<nsIInputStream> mStreamIn;
     nsCOMPtr<nsITimer> mTimer;
--- a/netwerk/base/src/EventTokenBucket.cpp
+++ b/netwerk/base/src/EventTokenBucket.cpp
@@ -29,17 +29,17 @@ namespace net {
 ////////////////////////////////////////////
 
 class TokenBucketCancelable : public nsICancelable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICANCELABLE
 
-  TokenBucketCancelable(class ATokenBucketEvent *event);
+  explicit TokenBucketCancelable(class ATokenBucketEvent *event);
   void Fire();
 
 private:
   virtual ~TokenBucketCancelable() {}
 
   friend class EventTokenBucket;
   ATokenBucketEvent *mEvent;
 };
--- a/netwerk/base/src/NetworkActivityMonitor.cpp
+++ b/netwerk/base/src/NetworkActivityMonitor.cpp
@@ -146,17 +146,17 @@ nsNetMon_AcceptRead(PRFileDesc *listenSo
   if (ret > 0)
     NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
   return ret;
 }
 
 
 class NotifyNetworkActivity : public nsRunnable {
 public:
-  NotifyNetworkActivity(NetworkActivityMonitor::Direction aDirection)
+  explicit NotifyNetworkActivity(NetworkActivityMonitor::Direction aDirection)
     : mDirection(aDirection)
   {}
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (!obs)
--- a/netwerk/base/src/Predictor.cpp
+++ b/netwerk/base/src/Predictor.cpp
@@ -798,17 +798,17 @@ Predictor::EnsureInitStorage()
   NS_DispatchToMainThread(event);
 
   return NS_OK;
 }
 
 class PredictorThreadShutdownRunner : public nsRunnable
 {
 public:
-  PredictorThreadShutdownRunner(nsIThread *ioThread)
+  explicit PredictorThreadShutdownRunner(nsIThread *ioThread)
     :mIOThread(ioThread)
   { }
 
   NS_IMETHODIMP Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(NS_IsMainThread(),
                "Shut down predictor io thread off main thread");
     mIOThread->Shutdown();
--- a/netwerk/base/src/nsAsyncStreamCopier.cpp
+++ b/netwerk/base/src/nsAsyncStreamCopier.cpp
@@ -26,17 +26,17 @@ static PRLogModuleInfo *gStreamCopierLog
  */
 class AsyncApplyBufferingPolicyEvent MOZ_FINAL: public nsRunnable
 {
 public:
     /**
      * @param aCopier
      *        The nsAsyncStreamCopier requesting the information.
      */
-    AsyncApplyBufferingPolicyEvent(nsAsyncStreamCopier* aCopier)
+    explicit AsyncApplyBufferingPolicyEvent(nsAsyncStreamCopier* aCopier)
         : mCopier(aCopier)
       , mTarget(NS_GetCurrentThread())
       { }
     NS_METHOD Run()
     {
       nsresult rv = mCopier->ApplyBufferingPolicy();
       if (NS_FAILED(rv)) {
           mCopier->Cancel(rv);
--- a/netwerk/base/src/nsBaseChannel.cpp
+++ b/netwerk/base/src/nsBaseChannel.cpp
@@ -22,17 +22,17 @@ CopyProperties(const nsAString &key, nsI
 
   bag->SetProperty(key, data);
   return PL_DHASH_NEXT;
 }
 
 // This class is used to suspend a request across a function scope.
 class ScopedRequestSuspender {
 public:
-  ScopedRequestSuspender(nsIRequest *request)
+  explicit ScopedRequestSuspender(nsIRequest *request)
     : mRequest(request) {
     if (mRequest && NS_FAILED(mRequest->Suspend())) {
       NS_WARNING("Couldn't suspend pump");
       mRequest = nullptr;
     }
   }
   ~ScopedRequestSuspender() {
     if (mRequest)
--- a/netwerk/base/src/nsBaseContentStream.h
+++ b/netwerk/base/src/nsBaseContentStream.h
@@ -35,17 +35,17 @@
 
 class nsBaseContentStream : public nsIAsyncInputStream
 {
 public: 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
-  nsBaseContentStream(bool nonBlocking)
+  explicit nsBaseContentStream(bool nonBlocking)
     : mStatus(NS_OK)
     , mNonBlocking(nonBlocking) {
   }
 
   nsresult Status() { return mStatus; }
   bool IsNonBlocking() { return mNonBlocking; }
   bool IsClosed() { return NS_FAILED(mStatus); }
 
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -492,17 +492,17 @@ nsIOService::GetProtocolFlags(const char
 
     rv = handler->GetProtocolFlags(flags);
     return rv;
 }
 
 class AutoIncrement
 {
     public:
-        AutoIncrement(uint32_t *var) : mVar(var)
+        explicit AutoIncrement(uint32_t *var) : mVar(var)
         {
             ++*var;
         }
         ~AutoIncrement()
         {
             --*mVar;
         }
     private:
--- a/netwerk/base/src/nsLoadGroup.cpp
+++ b/netwerk/base/src/nsLoadGroup.cpp
@@ -45,17 +45,17 @@ static PRLogModuleInfo* gLoadGroupLog = 
 #undef LOG
 #define LOG(args) PR_LOG(gLoadGroupLog, PR_LOG_DEBUG, args)
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class RequestMapEntry : public PLDHashEntryHdr
 {
 public:
-    RequestMapEntry(nsIRequest *aRequest) :
+    explicit RequestMapEntry(nsIRequest *aRequest) :
         mKey(aRequest)
     {
     }
 
     nsCOMPtr<nsIRequest> mKey;
 };
 
 static bool
--- a/netwerk/base/src/nsLoadGroup.h
+++ b/netwerk/base/src/nsLoadGroup.h
@@ -44,17 +44,17 @@ public:
 
     ////////////////////////////////////////////////////////////////////////////
     // nsISupportsPriority methods:
     NS_DECL_NSISUPPORTSPRIORITY
 
     ////////////////////////////////////////////////////////////////////////////
     // nsLoadGroup methods:
 
-    nsLoadGroup(nsISupports* outer);
+    explicit nsLoadGroup(nsISupports* outer);
 
     nsresult Init();
 
 protected:
     virtual ~nsLoadGroup();
 
     nsresult MergeLoadFlags(nsIRequest *aRequest, nsLoadFlags& flags);
 
--- a/netwerk/base/src/nsMediaFragmentURIParser.h
+++ b/netwerk/base/src/nsMediaFragmentURIParser.h
@@ -28,20 +28,20 @@ enum ClipUnit
   eClipUnit_Pixel,
   eClipUnit_Percent,
 };
 
 class nsMediaFragmentURIParser
 {
 public:
   // Create a parser with the provided URI.
-  nsMediaFragmentURIParser(nsIURI* aURI);
+  explicit nsMediaFragmentURIParser(nsIURI* aURI);
 
   // Create a parser with the provided URI reference portion.
-  nsMediaFragmentURIParser(nsCString& aRef);
+  explicit nsMediaFragmentURIParser(nsCString& aRef);
 
   // True if a valid temporal media fragment indicated a start time.
   bool HasStartTime() const { return !mStart.empty(); }
 
   // If a valid temporal media fragment indicated a start time, returns
   // it in units of seconds. If not, defaults to 0.
   double GetStartTime() const { return mStart.ref(); }
 
--- a/netwerk/base/src/nsNetAddr.h
+++ b/netwerk/base/src/nsNetAddr.h
@@ -14,17 +14,17 @@
 class nsNetAddr MOZ_FINAL : public nsINetAddr
 {
   ~nsNetAddr() {}
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSINETADDR
 
-  nsNetAddr(mozilla::net::NetAddr* addr);
+  explicit nsNetAddr(mozilla::net::NetAddr* addr);
 
 private:
   mozilla::net::NetAddr mAddr;
 
 protected:
   /* additional members */
 };
 
--- a/netwerk/base/src/nsPACMan.cpp
+++ b/netwerk/base/src/nsPACMan.cpp
@@ -92,17 +92,17 @@ private:
 
 // The PAC thread must be deleted from the main thread, this class
 // acts as a proxy to do that, as the PACMan is reference counted
 // and might be destroyed on either thread
 
 class ShutdownThread MOZ_FINAL : public nsRunnable
 {
 public:
-  ShutdownThread(nsIThread *thread)
+  explicit ShutdownThread(nsIThread *thread)
     : mThread(thread)
   {
   }
 
   NS_IMETHODIMP Run()
   {
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread");
     mThread->Shutdown();
@@ -117,17 +117,17 @@ private:
 
 // PACLoadComplete allows the PAC thread to tell the main thread that
 // the javascript PAC file has been installed (perhaps unsuccessfully)
 // and that there is no reason to queue executions anymore
 
 class PACLoadComplete MOZ_FINAL : public nsRunnable
 {
 public:
-  PACLoadComplete(nsPACMan *aPACMan)
+  explicit PACLoadComplete(nsPACMan *aPACMan)
     : mPACMan(aPACMan)
   {
   }
 
   NS_IMETHODIMP Run()
   {
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread");
     mPACMan->mLoader = nullptr;
@@ -144,17 +144,17 @@ private:
 // ExecutePACThreadAction is used to proxy actions from the main
 // thread onto the PAC thread. There are 3 options: process the queue,
 // cancel the queue, and setup the javascript context with a new PAC file
 
 class ExecutePACThreadAction MOZ_FINAL : public nsRunnable
 {
 public:
   // by default we just process the queue
-  ExecutePACThreadAction(nsPACMan *aPACMan)
+  explicit ExecutePACThreadAction(nsPACMan *aPACMan)
     : mPACMan(aPACMan)
     , mCancel(false)
     , mSetupPAC(false)
   { }
 
   void CancelQueue (nsresult status)
   {
     mCancel = true;
--- a/netwerk/base/src/nsProxyInfo.h
+++ b/netwerk/base/src/nsProxyInfo.h
@@ -39,17 +39,17 @@ public:
   bool IsDirect();
   bool IsHTTP();
   bool IsHTTPS();
   bool IsSOCKS();
 
 private:
   friend class nsProtocolProxyService;
 
-  nsProxyInfo(const char *type = nullptr)
+  explicit nsProxyInfo(const char *type = nullptr)
     : mType(type)
     , mPort(-1)
     , mFlags(0)
     , mResolveFlags(0)
     , mTimeout(UINT32_MAX)
     , mNext(nullptr)
   {}
 
--- a/netwerk/base/src/nsRequestObserverProxy.h
+++ b/netwerk/base/src/nsRequestObserverProxy.h
@@ -36,17 +36,17 @@ protected:
 
     friend class nsOnStartRequestEvent;
     friend class nsOnStopRequestEvent;
 };
 
 class nsARequestObserverEvent : public nsRunnable
 {
 public:
-    nsARequestObserverEvent(nsIRequest *);
+    explicit nsARequestObserverEvent(nsIRequest *);
 
 protected:
     virtual ~nsARequestObserverEvent() {}
 
     nsCOMPtr<nsIRequest>  mRequest;
 };
 
 #endif // nsRequestObserverProxy_h__
--- a/netwerk/base/src/nsServerSocket.cpp
+++ b/netwerk/base/src/nsServerSocket.cpp
@@ -405,17 +405,17 @@ nsServerSocket::Close()
 
 namespace {
 
 class ServerSocketListenerProxy MOZ_FINAL : public nsIServerSocketListener
 {
   ~ServerSocketListenerProxy() {}
 
 public:
-  ServerSocketListenerProxy(nsIServerSocketListener* aListener)
+  explicit ServerSocketListenerProxy(nsIServerSocketListener* aListener)
     : mListener(new nsMainThreadPtrHolder<nsIServerSocketListener>(aListener))
     , mTargetThread(do_GetCurrentThread())
   { }
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSISERVERSOCKETLISTENER
 
   class OnSocketAcceptedRunnable : public nsRunnable
--- a/netwerk/base/src/nsSimpleNestedURI.h
+++ b/netwerk/base/src/nsSimpleNestedURI.h
@@ -30,17 +30,17 @@ public:
     // To be used by deserialization only.  Leaves this object in an
     // uninitialized state that will throw on most accesses.
     nsSimpleNestedURI()
     {
     }
 
     // Constructor that should generally be used when constructing an object of
     // this class with |operator new|.
-    nsSimpleNestedURI(nsIURI* innerURI);
+    explicit nsSimpleNestedURI(nsIURI* innerURI);
 
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSINESTEDURI
 
     // Overrides for various methods nsSimpleURI implements follow.
   
     // nsSimpleURI overrides
     virtual nsresult EqualsInternal(nsIURI* other,
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -1189,17 +1189,17 @@ nsSocketTransport::InitiateSocket()
         if (NS_SUCCEEDED(mCondition) &&
             crashOnNonLocalConnections &&
             !(IsIPAddrAny(&mNetAddr) || IsIPAddrLocal(&mNetAddr))) {
             nsAutoCString ipaddr;
             nsRefPtr<nsNetAddr> netaddr = new nsNetAddr(&mNetAddr);
             netaddr->GetAddress(ipaddr);
             fprintf_stderr(stderr,
                            "FATAL ERROR: Non-local network connections are disabled and a connection "
-                           "attempt to %s (%s) was made.\n You should only access hostnames "
+                           "attempt to %s (%s) was made.\nYou should only access hostnames "
                            "available via the test networking proxy (if running mochitests) "
                            "or from a test-specific httpd.js server (if running xpcshell tests). "
                            "Browser services should be disabled or redirected to a local server.\n",
                            mHost.get(), ipaddr.get());
             MOZ_CRASH("Attempting to connect to non-local address!");
         }
     }
 
@@ -1603,17 +1603,17 @@ nsSocketTransport::GetFD_Locked()
         mFDref++;
 
     return mFD;
 }
 
 class ThunkPRClose : public nsRunnable
 {
 public:
-  ThunkPRClose(PRFileDesc *fd) : mFD(fd) {}
+  explicit ThunkPRClose(PRFileDesc *fd) : mFD(fd) {}
 
   NS_IMETHOD Run()
   {
     PR_Close(mFD);
     return NS_OK;
   }
 private:
   PRFileDesc *mFD;
--- a/netwerk/base/src/nsSocketTransport2.h
+++ b/netwerk/base/src/nsSocketTransport2.h
@@ -42,17 +42,17 @@ ErrorAccordingToNSPR(PRErrorCode errorCo
 
 class nsSocketInputStream : public nsIAsyncInputStream
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIINPUTSTREAM
     NS_DECL_NSIASYNCINPUTSTREAM
 
-    nsSocketInputStream(nsSocketTransport *);
+    explicit nsSocketInputStream(nsSocketTransport *);
     virtual ~nsSocketInputStream();
 
     bool     IsReferenced() { return mReaderRefCnt > 0; }
     nsresult Condition()    { return mCondition; }
     uint64_t ByteCount()    { return mByteCount; }
 
     // called by the socket transport on the socket thread...
     void OnSocketReady(nsresult condition);
@@ -72,17 +72,17 @@ private:
 
 class nsSocketOutputStream : public nsIAsyncOutputStream
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIOUTPUTSTREAM
     NS_DECL_NSIASYNCOUTPUTSTREAM
 
-    nsSocketOutputStream(nsSocketTransport *);
+    explicit nsSocketOutputStream(nsSocketTransport *);
     virtual ~nsSocketOutputStream();
 
     bool     IsReferenced() { return mWriterRefCnt > 0; }
     nsresult Condition()    { return mCondition; }
     uint64_t ByteCount()    { return mByteCount; }
 
     // called by the socket transport on the socket thread...
     void OnSocketReady(nsresult condition); 
@@ -176,18 +176,18 @@ private:
     };
 
     // Safer way to get and automatically release PRFileDesc objects.
     class MOZ_STACK_CLASS PRFileDescAutoLock
     {
     public:
       typedef mozilla::MutexAutoLock MutexAutoLock;
 
-      PRFileDescAutoLock(nsSocketTransport *aSocketTransport,
-                         nsresult *aConditionWhileLocked = nullptr)
+      explicit PRFileDescAutoLock(nsSocketTransport *aSocketTransport,
+                                  nsresult *aConditionWhileLocked = nullptr)
         : mSocketTransport(aSocketTransport)
         , mFd(nullptr)
       {
         MOZ_ASSERT(aSocketTransport);
         MutexAutoLock lock(mSocketTransport->mLock);
         if (aConditionWhileLocked) {
           *aConditionWhileLocked = mSocketTransport->mCondition;
           if (NS_FAILED(mSocketTransport->mCondition)) {
@@ -218,17 +218,17 @@ private:
       nsSocketTransport *mSocketTransport;
       PRFileDesc        *mFd;
     };
     friend class PRFileDescAutoLock;
 
     class LockedPRFileDesc
     {
     public:
-      LockedPRFileDesc(nsSocketTransport *aSocketTransport)
+      explicit LockedPRFileDesc(nsSocketTransport *aSocketTransport)
         : mSocketTransport(aSocketTransport)
         , mFd(nullptr)
       {
         MOZ_ASSERT(aSocketTransport);
       }
       ~LockedPRFileDesc() {}
       bool IsInitialized() {
         return mFd;
--- a/netwerk/base/src/nsStandardURL.h
+++ b/netwerk/base/src/nsStandardURL.h
@@ -56,17 +56,17 @@ public:
     NS_DECL_NSICLASSINFO
     NS_DECL_NSIMUTABLE
     NS_DECL_NSIIPCSERIALIZABLEURI
 
     // nsISizeOf
     virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
-    nsStandardURL(bool aSupportsFileURL = false);
+    explicit nsStandardURL(bool aSupportsFileURL = false);
 
     static void InitGlobalObjects();
     static void ShutdownGlobalObjects();
 
 public: /* internal -- HPUX compiler can't handle this being private */
     //
     // location and length of an url segment relative to mSpec
     //
@@ -106,17 +106,17 @@ public: /* internal -- HPUX compiler can
     friend class nsPrefObserver;
 
     //
     // URL segment encoder : performs charset conversion and URL escaping.
     //
     class nsSegmentEncoder
     {
     public:
-        nsSegmentEncoder(const char *charset);
+        explicit nsSegmentEncoder(const char *charset);
 
         // Encode the given segment if necessary, and return the length of
         // the encoded segment.  The encoded segment is appended to |buf|
         // if and only if encoding is required.
         int32_t EncodeSegmentCount(const char *str,
                                    const URLSegment &segment,
                                    int16_t mask,
                                    nsAFlatCString &buf,
--- a/netwerk/base/src/nsTemporaryFileInputStream.h
+++ b/netwerk/base/src/nsTemporaryFileInputStream.h
@@ -15,17 +15,17 @@ class nsTemporaryFileInputStream : publi
 {
 public:
   //used to release a PRFileDesc
   class FileDescOwner
   {
     friend class nsTemporaryFileInputStream;
   public:
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileDescOwner)
-    FileDescOwner(PRFileDesc* aFD)
+    explicit FileDescOwner(PRFileDesc* aFD)
       : mFD(aFD),
         mMutex("FileDescOwner::mMutex")
     {
       MOZ_ASSERT(aFD);
     }
   private:
     ~FileDescOwner()
     {
--- a/netwerk/base/src/nsUDPSocket.cpp
+++ b/netwerk/base/src/nsUDPSocket.cpp
@@ -680,17 +680,17 @@ namespace {
 //-----------------------------------------------------------------------------
 // SocketListenerProxy
 //-----------------------------------------------------------------------------
 class SocketListenerProxy MOZ_FINAL : public nsIUDPSocketListener
 {
   ~SocketListenerProxy() {}
 
 public:
-  SocketListenerProxy(nsIUDPSocketListener* aListener)
+  explicit SocketListenerProxy(nsIUDPSocketListener* aListener)
     : mListener(new nsMainThreadPtrHolder<nsIUDPSocketListener>(aListener))
     , mTargetThread(do_GetCurrentThread())
   { }
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIUDPSOCKETLISTENER
 
   class OnPacketReceivedRunnable : public nsRunnable
--- a/netwerk/cache/nsCacheEntry.h
+++ b/netwerk/cache/nsCacheEntry.h
@@ -233,17 +233,17 @@ private:
 /******************************************************************************
 * nsCacheEntryInfo
 *******************************************************************************/
 class nsCacheEntryInfo : public nsICacheEntryInfo {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSICACHEENTRYINFO
 
-    nsCacheEntryInfo(nsCacheEntry* entry)
+    explicit nsCacheEntryInfo(nsCacheEntry* entry)
         :   mCacheEntry(entry)
     {
     }
 
     void    DetachEntry() { mCacheEntry = nullptr; }
 
 private:
     nsCacheEntry * mCacheEntry;
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -222,17 +222,17 @@ public:
 
 NS_IMPL_ISUPPORTS(nsSetDiskSmartSizeCallback, nsITimerCallback)
 
 // Runnable sent to main thread after the cache IO thread calculates available
 // disk space, so that there is no race in setting mDiskCacheCapacity.
 class nsSetSmartSizeEvent: public nsRunnable 
 {
 public:
-    nsSetSmartSizeEvent(int32_t smartSize)
+    explicit nsSetSmartSizeEvent(int32_t smartSize)
         : mSmartSize(smartSize) {}
 
     NS_IMETHOD Run() 
     {
         NS_ASSERTION(NS_IsMainThread(), 
                      "Setting smart size data off the main thread");
 
         // Main thread may have already called nsCacheService::Shutdown
@@ -969,17 +969,17 @@ nsCacheProfilePrefObserver::CacheCompres
 }
 
 /******************************************************************************
  * nsProcessRequestEvent
  *****************************************************************************/
 
 class nsProcessRequestEvent : public nsRunnable {
 public:
-    nsProcessRequestEvent(nsCacheRequest *aRequest)
+    explicit nsProcessRequestEvent(nsCacheRequest *aRequest)
     {
         MOZ_EVENT_TRACER_NAME_OBJECT(aRequest, aRequest->mKey.get());
         MOZ_EVENT_TRACER_WAIT(aRequest, "net::cache::ProcessRequest");
         mRequest = aRequest;
     }
 
     NS_IMETHOD Run()
     {
@@ -1342,17 +1342,17 @@ nsCacheService::EvictEntriesForSession(n
                                  session->StoragePolicy());
 }
 
 namespace {
 
 class EvictionNotifierRunnable : public nsRunnable
 {
 public:
-    EvictionNotifierRunnable(nsISupports* aSubject)
+    explicit EvictionNotifierRunnable(nsISupports* aSubject)
         : mSubject(aSubject)
     { }
 
     NS_DECL_NSIRUNNABLE
 
 private:
     nsCOMPtr<nsISupports> mSubject;
 };
--- a/netwerk/cache/nsCacheService.h
+++ b/netwerk/cache/nsCacheService.h
@@ -388,17 +388,17 @@ private:
 
 #define LOCK_TELEM(x) \
   (::mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_MAINTHREAD_##x)
 
 // Instantiate this class to acquire the cache service lock for a particular
 // execution scope.
 class nsCacheServiceAutoLock {
 public:
-    nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID) {
+    explicit nsCacheServiceAutoLock(mozilla::Telemetry::ID mainThreadLockerID) {
         nsCacheService::Lock(mainThreadLockerID);
     }
     ~nsCacheServiceAutoLock() {
         nsCacheService::Unlock();
     }
 };
 
 #endif // _nsCacheService_h_
--- a/netwerk/cache/nsCacheUtils.cpp
+++ b/netwerk/cache/nsCacheUtils.cpp
@@ -7,17 +7,17 @@
 #include "nsCache.h"
 #include "nsCacheUtils.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla;
 
 class nsDestroyThreadEvent : public nsRunnable {
 public:
-  nsDestroyThreadEvent(nsIThread *thread)
+  explicit nsDestroyThreadEvent(nsIThread *thread)
     : mThread(thread)
   {}
   NS_IMETHOD Run()
   {
     mThread->Shutdown();
     return NS_OK;
   }
 private:
--- a/netwerk/cache/nsCacheUtils.h
+++ b/netwerk/cache/nsCacheUtils.h
@@ -14,17 +14,17 @@
 
 class nsIThread;
 
 /**
  * A class with utility methods for shutting down nsIThreads easily.
   */
 class nsShutdownThread : public nsRunnable {
 public:
-  nsShutdownThread(nsIThread *aThread);
+  explicit nsShutdownThread(nsIThread *aThread);
   ~nsShutdownThread();
 
   NS_IMETHOD Run();
 
 /**
  * Shutdown ensures that aThread->Shutdown() is called on a main thread
  */
   static nsresult Shutdown(nsIThread *aThread);
--- a/netwerk/cache/nsDiskCacheDevice.cpp
+++ b/netwerk/cache/nsDiskCacheDevice.cpp
@@ -79,17 +79,17 @@ private:
     bool mCanceled;
     nsCacheEntry *mEntry;
     nsDiskCacheDevice *mDevice;
     nsDiskCacheBinding *mBinding;
 };
 
 class nsEvictDiskCacheEntriesEvent : public nsRunnable {
 public:
-    nsEvictDiskCacheEntriesEvent(nsDiskCacheDevice *device)
+    explicit nsEvictDiskCacheEntriesEvent(nsDiskCacheDevice *device)
         : mDevice(device) {}
 
     NS_IMETHOD Run()
     {
         nsCacheServiceAutoLock lock(LOCK_TELEM(NSEVICTDISKCACHEENTRIESEVENT_RUN));
         mDevice->EvictDiskCacheEntries(mDevice->mCacheCapacity);
         return NS_OK;
     }
@@ -177,17 +177,17 @@ nsDiskCacheEvictor::VisitRecord(nsDiskCa
  *  nsDiskCacheDeviceInfo
  *****************************************************************************/
 
 class nsDiskCacheDeviceInfo : public nsICacheDeviceInfo {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSICACHEDEVICEINFO
 
-    nsDiskCacheDeviceInfo(nsDiskCacheDevice* device)
+    explicit nsDiskCacheDeviceInfo(nsDiskCacheDevice* device)
         :   mDevice(device)
     {
     }
 
 private:
     virtual ~nsDiskCacheDeviceInfo() {}
 
     nsDiskCacheDevice* mDevice;
--- a/netwerk/cache/nsDiskCacheDeviceSQL.cpp
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.cpp
@@ -86,17 +86,17 @@ DecomposeCacheEntryKey(const nsCString *
   *key = buf.get() + colon + 1;
 
   return true;
 }
 
 class AutoResetStatement
 {
   public:
-    AutoResetStatement(mozIStorageStatement *s)
+    explicit AutoResetStatement(mozIStorageStatement *s)
       : mStatement(s) {}
     ~AutoResetStatement() { mStatement->Reset(); }
     mozIStorageStatement *operator->() { return mStatement; }
   private:
     mozIStorageStatement *mStatement;
 };
 
 class EvictionObserver
@@ -270,17 +270,17 @@ private:
  */
 
 class nsOfflineCacheDeviceInfo MOZ_FINAL : public nsICacheDeviceInfo
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSICACHEDEVICEINFO
 
-  nsOfflineCacheDeviceInfo(nsOfflineCacheDevice* device)
+  explicit nsOfflineCacheDeviceInfo(nsOfflineCacheDevice* device)
     : mDevice(device)
   {}
 
 private:
   ~nsOfflineCacheDeviceInfo() {}
 
   nsOfflineCacheDevice* mDevice;
 };
@@ -856,17 +856,17 @@ nsApplicationCache::GetUsage(uint32_t *u
 }
 
 /******************************************************************************
  * nsCloseDBEvent
  *****************************************************************************/
 
 class nsCloseDBEvent : public nsRunnable {
 public:
-  nsCloseDBEvent(mozIStorageConnection *aDB)
+  explicit nsCloseDBEvent(mozIStorageConnection *aDB)
   {
     mDB = aDB;
   }
 
   NS_IMETHOD Run()
   {
     mDB->Close();
     return NS_OK;
--- a/netwerk/cache/nsDiskCacheDeviceSQL.h
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.h
@@ -42,17 +42,17 @@ private:
   nsCString mData;
 };
 
 class nsOfflineCacheEvictionFunction MOZ_FINAL : public mozIStorageFunction {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_MOZISTORAGEFUNCTION
 
-  nsOfflineCacheEvictionFunction(nsOfflineCacheDevice *device)
+  explicit nsOfflineCacheEvictionFunction(nsOfflineCacheDevice *device)
     : mDevice(device)
   {}
 
   void Reset() { mItems.Clear(); }
   void Apply();
 
 private:
   ~nsOfflineCacheEvictionFunction() {}
--- a/netwerk/cache/nsDiskCacheStreams.h
+++ b/netwerk/cache/nsDiskCacheStreams.h
@@ -18,17 +18,17 @@
 
 #include "mozilla/Atomics.h"
 
 class nsDiskCacheInputStream;
 class nsDiskCacheDevice;
 
 class nsDiskCacheStreamIO : public nsIOutputStream {
 public:
-    nsDiskCacheStreamIO(nsDiskCacheBinding *   binding);
+    explicit nsDiskCacheStreamIO(nsDiskCacheBinding *   binding);
     
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIOUTPUTSTREAM
 
     nsresult    GetInputStream(uint32_t offset, nsIInputStream ** inputStream);
     nsresult    GetOutputStream(uint32_t offset, nsIOutputStream ** outputStream);
 
     nsresult    ClearBinding();
--- a/netwerk/cache/nsMemoryCacheDevice.h
+++ b/netwerk/cache/nsMemoryCacheDevice.h
@@ -105,17 +105,17 @@ private:
 /******************************************************************************
  * nsMemoryCacheDeviceInfo - used to call nsIVisitor for about:cache
  ******************************************************************************/
 class nsMemoryCacheDeviceInfo : public nsICacheDeviceInfo {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSICACHEDEVICEINFO
 
-    nsMemoryCacheDeviceInfo(nsMemoryCacheDevice* device)
+    explicit nsMemoryCacheDeviceInfo(nsMemoryCacheDevice* device)
         :   mDevice(device)
     {
     }
 
 private:
     virtual ~nsMemoryCacheDeviceInfo() {}
     nsMemoryCacheDevice* mDevice;
 };
--- a/netwerk/cache2/CacheEntry.h
+++ b/netwerk/cache2/CacheEntry.h
@@ -349,17 +349,17 @@ private:
   uint32_t mUseCount;
   nsCOMPtr<nsIThread> mReleaseThread;
 };
 
 
 class CacheEntryHandle : public nsICacheEntry
 {
 public:
-  CacheEntryHandle(CacheEntry* aEntry);
+  explicit CacheEntryHandle(CacheEntry* aEntry);
   CacheEntry* Entry() const { return mEntry; }
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_FORWARD_NSICACHEENTRY(mEntry->)
 private:
   virtual ~CacheEntryHandle();
   nsRefPtr<CacheEntry> mEntry;
 };
@@ -371,17 +371,17 @@ public:
   void OnOutputClosed();
 
 private:
   friend class CacheEntry;
 
   virtual ~CacheOutputCloseListener();
 
   NS_DECL_NSIRUNNABLE
-  CacheOutputCloseListener(CacheEntry* aEntry);
+  explicit CacheOutputCloseListener(CacheEntry* aEntry);
 
 private:
   nsRefPtr<CacheEntry> mEntry;
 };
 
 } // net
 } // mozilla
 
--- a/netwerk/cache2/CacheFile.cpp
+++ b/netwerk/cache2/CacheFile.cpp
@@ -105,17 +105,17 @@ protected:
 };
 
 
 class DoomFileHelper : public CacheFileIOListener
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  DoomFileHelper(CacheFileListener *aListener)
+  explicit DoomFileHelper(CacheFileListener *aListener)
     : mListener(aListener)
   {
     MOZ_COUNT_CTOR(DoomFileHelper);
   }
 
 
   NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult)
   {
@@ -404,17 +404,17 @@ CacheFile::OnFileOpened(CacheFileHandle 
 {
   nsresult rv;
 
   // Using an 'auto' class to perform doom or fail the listener
   // outside the CacheFile's lock.
   class AutoFailDoomListener
   {
   public:
-    AutoFailDoomListener(CacheFileHandle *aHandle)
+    explicit AutoFailDoomListener(CacheFileHandle *aHandle)
       : mHandle(aHandle)
       , mAlreadyDoomed(false)
     {}
     ~AutoFailDoomListener()
     {
       if (!mListener)
         return;
 
--- a/netwerk/cache2/CacheFile.h
+++ b/netwerk/cache2/CacheFile.h
@@ -214,17 +214,17 @@ private:
   nsTArray<CacheFileInputStream*> mInputs;
   CacheFileOutputStream          *mOutput;
 
   nsTArray<nsISupports*>          mObjsToRelease;
 };
 
 class CacheFileAutoLock {
 public:
-  CacheFileAutoLock(CacheFile *aFile)
+  explicit CacheFileAutoLock(CacheFile *aFile)
     : mFile(aFile)
     , mLocked(true)
   {
     mFile->Lock();
   }
   ~CacheFileAutoLock()
   {
     if (mLocked)
--- a/netwerk/cache2/CacheFileIOManager.cpp
+++ b/netwerk/cache2/CacheFileIOManager.cpp
@@ -901,17 +901,17 @@ protected:
   nsCOMPtr<CacheFileIOListener> mCallback;
   nsCOMPtr<nsIEventTarget>      mTarget;
   nsRefPtr<CacheFileIOManager>  mIOMan;
   nsresult                      mRV;
 };
 
 class ReleaseNSPRHandleEvent : public nsRunnable {
 public:
-  ReleaseNSPRHandleEvent(CacheFileHandle *aHandle)
+  explicit ReleaseNSPRHandleEvent(CacheFileHandle *aHandle)
     : mHandle(aHandle)
   {
     MOZ_COUNT_CTOR(ReleaseNSPRHandleEvent);
   }
 
 protected:
   ~ReleaseNSPRHandleEvent()
   {
--- a/netwerk/cache2/CacheFileIOManager.h
+++ b/netwerk/cache2/CacheFileIOManager.h
@@ -107,17 +107,17 @@ public:
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
   class HandleHashKey : public PLDHashEntryHdr
   {
   public:
     typedef const SHA1Sum::Hash& KeyType;
     typedef const SHA1Sum::Hash* KeyTypePointer;
 
-    HandleHashKey(KeyTypePointer aKey)
+    explicit HandleHashKey(KeyTypePointer aKey)
     {
       MOZ_COUNT_CTOR(HandleHashKey);
       mHash = (SHA1Sum::Hash*)new uint8_t[SHA1Sum::kHashSize];
       memcpy(mHash, aKey, sizeof(SHA1Sum::Hash));
     }
     HandleHashKey(const HandleHashKey& aOther)
     {
       NS_NOTREACHED("HandleHashKey copy constructor is forbidden!");
--- a/netwerk/cache2/CacheFileInputStream.h
+++ b/netwerk/cache2/CacheFileInputStream.h
@@ -22,17 +22,17 @@ class CacheFileInputStream : public nsIA
                            , public CacheFileChunkListener
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
   NS_DECL_NSISEEKABLESTREAM
 
 public:
-  CacheFileInputStream(CacheFile *aFile);
+  explicit CacheFileInputStream(CacheFile *aFile);
 
   NS_IMETHOD OnChunkRead(nsresult aResult, CacheFileChunk *aChunk);
   NS_IMETHOD OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk);
   NS_IMETHOD OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx,
                               CacheFileChunk *aChunk);
   NS_IMETHOD OnChunkUpdated(CacheFileChunk *aChunk);
 
   // Memory reporting
--- a/netwerk/cache2/CacheHashUtils.h
+++ b/netwerk/cache2/CacheHashUtils.h
@@ -30,17 +30,17 @@ public:
 
   typedef uint16_t Hash16_t;
   typedef uint32_t Hash32_t;
 
   static Hash32_t Hash(const char* aData, uint32_t aSize, uint32_t aInitval=0);
   static Hash16_t Hash16(const char* aData, uint32_t aSize,
                          uint32_t aInitval=0);
 
-  CacheHash(uint32_t aInitval=0);
+  explicit CacheHash(uint32_t aInitval=0);
 
   void     Update(const char *aData, uint32_t aLen);
   Hash32_t GetHash();
   Hash16_t GetHash16();
 
 private:
   virtual ~CacheHash() {}
 
--- a/netwerk/cache2/CacheIndex.cpp
+++ b/netwerk/cache2/CacheIndex.cpp
@@ -161,17 +161,17 @@ private:
   bool                 mDoNotSearchInUpdates;
 };
 
 class FileOpenHelper : public CacheFileIOListener
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  FileOpenHelper(CacheIndex* aIndex)
+  explicit FileOpenHelper(CacheIndex* aIndex)
     : mIndex(aIndex)
     , mCanceled(false)
   {}
 
   void Cancel() {
     mIndex->AssertOwnsLock();
     mCanceled = true;
   }
@@ -1817,17 +1817,17 @@ CacheIndex::RemoveIndexFromDisk()
   RemoveFile(NS_LITERAL_CSTRING(kIndexName));
   RemoveFile(NS_LITERAL_CSTRING(kTempIndexName));
   RemoveFile(NS_LITERAL_CSTRING(kJournalName));
 }
 
 class WriteLogHelper
 {
 public:
-  WriteLogHelper(PRFileDesc *aFD)
+  explicit WriteLogHelper(PRFileDesc *aFD)
     : mStatus(NS_OK)
     , mFD(aFD)
     , mBufSize(kMaxBufSize)
     , mBufPos(0)
   {
     mHash = new CacheHash();
     mBuf = static_cast<char *>(moz_xmalloc(mBufSize));
   }
--- a/netwerk/cache2/CacheIndex.h
+++ b/netwerk/cache2/CacheIndex.h
@@ -82,17 +82,17 @@ struct CacheIndexRecord {
 };
 
 class CacheIndexEntry : public PLDHashEntryHdr
 {
 public:
   typedef const SHA1Sum::Hash& KeyType;
   typedef const SHA1Sum::Hash* KeyTypePointer;
 
-  CacheIndexEntry(KeyTypePointer aKey)
+  explicit CacheIndexEntry(KeyTypePointer aKey)
   {
     MOZ_COUNT_CTOR(CacheIndexEntry);
     mRec = new CacheIndexRecord();
     LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec.get()));
     memcpy(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash));
   }
   CacheIndexEntry(const CacheIndexEntry& aOther)
   {
@@ -965,17 +965,17 @@ private:
 
     void OnDiskConsumption(int64_t aSize)
     {
       mSize = aSize;
       NS_DispatchToMainThread(this);
     }
 
   private:
-    DiskConsumptionObserver(nsWeakPtr const &aWeakObserver)
+    explicit DiskConsumptionObserver(nsWeakPtr const &aWeakObserver)
       : mObserver(aWeakObserver) { }
     virtual ~DiskConsumptionObserver() { }
 
     NS_IMETHODIMP Run()
     {
       MOZ_ASSERT(NS_IsMainThread());
 
       nsCOMPtr<nsICacheStorageConsumptionObserver> observer =
@@ -993,17 +993,17 @@ private:
   };
 
   // List of async observers that want to get disk consumption information
   nsTArray<nsRefPtr<DiskConsumptionObserver> > mDiskConsumptionObservers;
 };
 
 class CacheIndexAutoLock {
 public:
-  CacheIndexAutoLock(CacheIndex *aIndex)
+  explicit CacheIndexAutoLock(CacheIndex *aIndex)
     : mIndex(aIndex)
     , mLocked(true)
   {
     mIndex->Lock();
   }
   ~CacheIndexAutoLock()
   {
     if (mLocked) {
@@ -1025,17 +1025,17 @@ public:
 
 private:
   nsRefPtr<CacheIndex> mIndex;
   bool mLocked;
 };
 
 class CacheIndexAutoUnlock {
 public:
-  CacheIndexAutoUnlock(CacheIndex *aIndex)
+  explicit CacheIndexAutoUnlock(CacheIndex *aIndex)
     : mIndex(aIndex)
     , mLocked(false)
   {
     mIndex->Unlock();
   }
   ~CacheIndexAutoUnlock()
   {
     if (!mLocked) {
--- a/netwerk/cache2/CacheStorage.h
+++ b/netwerk/cache2/CacheStorage.h
@@ -29,17 +29,17 @@ class CacheEntryTable : public TCacheEnt
 {
 public:
   enum EType
   {
     MEMORY_ONLY,
     ALL_ENTRIES
   };
 
-  CacheEntryTable(EType aType) : mType(aType) { }
+  explicit CacheEntryTable(EType aType) : mType(aType) { }
   EType Type() const
   {
     return mType;
   }
 private:
   EType const mType;
   CacheEntryTable() MOZ_DELETE;
 };
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -352,17 +352,17 @@ public:
   }
 
 private:
   // Invokes OnCacheEntryInfo callback for each single found entry.
   // There is one instance of this class per one entry.
   class OnCacheEntryInfoRunnable : public nsRunnable
   {
   public:
-    OnCacheEntryInfoRunnable(WalkDiskCacheRunnable* aWalker)
+    explicit OnCacheEntryInfoRunnable(WalkDiskCacheRunnable* aWalker)
       : mWalker(aWalker)
     {
     }
 
     NS_IMETHODIMP Run()
     {
       MOZ_ASSERT(NS_IsMainThread());
 
@@ -1493,17 +1493,17 @@ CacheStorageService::CheckStorageEntry(C
 
 namespace { // anon
 
 class CacheEntryDoomByKeyCallback : public CacheFileIOListener
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  CacheEntryDoomByKeyCallback(nsICacheEntryDoomCallback* aCallback)
+  explicit CacheEntryDoomByKeyCallback(nsICacheEntryDoomCallback* aCallback)
     : mCallback(aCallback) { }
 
 private:
   virtual ~CacheEntryDoomByKeyCallback();
 
   NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) { return NS_OK; }
   NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, nsresult aResult) { return NS_OK; }
   NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) { return NS_OK; }
@@ -1683,17 +1683,17 @@ CacheStorageService::DoomStorageEntries(
   // cache any 'doom' or 'evict' function ensures that the entry or entries
   // being doomed is/are not accessible after the function returns.  So there is
   // probably no need for a callback - has no meaning.  But for compatibility
   // with the old cache that is still in the tree we keep the API similar to be
   // able to make tests as well as other consumers work for now.
   class Callback : public nsRunnable
   {
   public:
-    Callback(nsICacheEntryDoomCallback* aCallback) : mCallback(aCallback) { }
+    explicit Callback(nsICacheEntryDoomCallback* aCallback) : mCallback(aCallback) { }
     NS_IMETHODIMP Run()
     {
       mCallback->OnCacheEntryDoomed(NS_OK);
       return NS_OK;
     }
     nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
   };
 
--- a/netwerk/cache2/CacheStorageService.h
+++ b/netwerk/cache2/CacheStorageService.h
@@ -54,17 +54,17 @@ protected:
     // which of the two disk and memory pools count this consumption at.
     MEMORY_ONLY = 1 << 0,
     // Prevent reports of this consumer at all, used for disk data chunks since
     // we throw them away as soon as the entry is not used by any consumer and
     // don't want to make them wipe the whole pool out during their short life.
     DONT_REPORT = 1 << 1
   };
 
-  CacheMemoryConsumer(uint32_t aFlags);
+  explicit CacheMemoryConsumer(uint32_t aFlags);
   ~CacheMemoryConsumer() { DoMemoryReport(0); }
   void DoMemoryReport(uint32_t aCurrentSize);
 };
 
 class CacheStorageService : public nsICacheStorageService
                           , public nsIMemoryReporter
                           , public nsITimerCallback
 {
@@ -301,17 +301,17 @@ private:
   {
   public:
     enum EType
     {
       DISK,
       MEMORY,
     } mType;
 
-    MemoryPool(EType aType);
+    explicit MemoryPool(EType aType);
     ~MemoryPool();
 
     nsTArray<nsRefPtr<CacheEntry> > mFrecencyArray;
     nsTArray<nsRefPtr<CacheEntry> > mExpirationArray;
     mozilla::Atomic<uint32_t> mMemorySize;
 
     bool OnMemoryConsumptionChange(uint32_t aSavedMemorySize,
                                    uint32_t aCurrentMemoryConsumption);
--- a/netwerk/cache2/OldWrappers.cpp
+++ b/netwerk/cache2/OldWrappers.cpp
@@ -34,17 +34,17 @@ namespace net {
 namespace { // anon
 
 // Fires the doom callback back on the main thread
 // after the cache I/O thread is looped.
 
 class DoomCallbackSynchronizer : public nsRunnable
 {
 public:
-  DoomCallbackSynchronizer(nsICacheEntryDoomCallback* cb) : mCB(cb)
+  explicit DoomCallbackSynchronizer(nsICacheEntryDoomCallback* cb) : mCB(cb)
   {
     MOZ_COUNT_CTOR(DoomCallbackSynchronizer);
   }
   nsresult Dispatch();
 
 private:
   virtual ~DoomCallbackSynchronizer()
   {
@@ -87,17 +87,17 @@ NS_IMETHODIMP DoomCallbackSynchronizer::
 
 // Receives doom callback from the old API and forwards to the new API
 
 class DoomCallbackWrapper : public nsICacheListener
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICACHELISTENER
 
-  DoomCallbackWrapper(nsICacheEntryDoomCallback* cb) : mCB(cb)
+  explicit DoomCallbackWrapper(nsICacheEntryDoomCallback* cb) : mCB(cb)
   {
     MOZ_COUNT_CTOR(DoomCallbackWrapper);
   }
 
 private:
   virtual ~DoomCallbackWrapper()
   {
     MOZ_COUNT_DTOR(DoomCallbackWrapper);
@@ -493,17 +493,17 @@ NS_IMETHODIMP _OldCacheEntryWrapper::Has
 namespace { // anon
 
 class MetaDataVisitorWrapper : public nsICacheMetaDataVisitor
 {
   virtual ~MetaDataVisitorWrapper() {}
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSICACHEMETADATAVISITOR
-  MetaDataVisitorWrapper(nsICacheEntryMetaDataVisitor* cb) : mCB(cb) {}
+  explicit MetaDataVisitorWrapper(nsICacheEntryMetaDataVisitor* cb) : mCB(cb) {}
   nsCOMPtr<nsICacheEntryMetaDataVisitor> mCB;
 };
 
 NS_IMPL_ISUPPORTS(MetaDataVisitorWrapper, nsICacheMetaDataVisitor)
 
 NS_IMETHODIMP
 MetaDataVisitorWrapper::VisitMetaDataElement(char const * key,
                                              char const * value,
--- a/netwerk/cache2/OldWrappers.h
+++ b/netwerk/cache2/OldWrappers.h
@@ -40,18 +40,18 @@ public:
   NS_IMETHOD Recreate(bool, nsICacheEntry**);
   NS_IMETHOD GetDataSize(int64_t *size);
   NS_IMETHOD OpenInputStream(int64_t offset, nsIInputStream * *_retval);
   NS_IMETHOD OpenOutputStream(int64_t offset, nsIOutputStream * *_retval);
   NS_IMETHOD MaybeMarkValid();
   NS_IMETHOD HasWriteAccess(bool aWriteOnly, bool *aWriteAccess);
   NS_IMETHOD VisitMetaData(nsICacheEntryMetaDataVisitor*);
 
-  _OldCacheEntryWrapper(nsICacheEntryDescriptor* desc);
-  _OldCacheEntryWrapper(nsICacheEntryInfo* info);
+  explicit _OldCacheEntryWrapper(nsICacheEntryDescriptor* desc);
+  explicit _OldCacheEntryWrapper(nsICacheEntryInfo* info);
 
 private:
   virtual ~_OldCacheEntryWrapper();
 
   _OldCacheEntryWrapper() MOZ_DELETE;
   nsICacheEntryDescriptor* mOldDesc; // ref holded in mOldInfo
   nsCOMPtr<nsICacheEntryInfo> mOldInfo;
 };
@@ -157,17 +157,17 @@ private:
 
 class _OldGetDiskConsumption : public nsRunnable,
                                public nsICacheVisitor
 {
 public:
   static nsresult Get(nsICacheStorageConsumptionObserver* aCallback);
 
 private:
-  _OldGetDiskConsumption(nsICacheStorageConsumptionObserver* aCallback);
+  explicit _OldGetDiskConsumption(nsICacheStorageConsumptionObserver* aCallback);
   virtual ~_OldGetDiskConsumption() {}
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSICACHEVISITOR
   NS_DECL_NSIRUNNABLE
 
   nsCOMPtr<nsICacheStorageConsumptionObserver> mCallback;
   int64_t mSize;
 };
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -352,17 +352,17 @@ LogSuccess(bool aSetCookie, nsIURI *aHos
 /******************************************************************************
  * DBListenerErrorHandler impl:
  * Parent class for our async storage listeners that handles the logging of
  * errors.
  ******************************************************************************/
 class DBListenerErrorHandler : public mozIStorageStatementCallback
 {
 protected:
-  DBListenerErrorHandler(DBState* dbState) : mDBState(dbState) { }
+  explicit DBListenerErrorHandler(DBState* dbState) : mDBState(dbState) { }
   nsRefPtr<DBState> mDBState;
   virtual const char *GetOpType() = 0;
 
 public:
   NS_IMETHOD HandleError(mozIStorageError* aError)
   {
     int32_t result = -1;
     aError->GetResult(&result);
@@ -392,17 +392,17 @@ class InsertCookieDBListener MOZ_FINAL :
 private:
   virtual const char *GetOpType() { return "INSERT"; }
 
   ~InsertCookieDBListener() {}
 
 public:
   NS_DECL_ISUPPORTS
 
-  InsertCookieDBListener(DBState* dbState) : DBListenerErrorHandler(dbState) { }
+  explicit InsertCookieDBListener(DBState* dbState) : DBListenerErrorHandler(dbState) { }
   NS_IMETHOD HandleResult(mozIStorageResultSet*)
   {
     NS_NOTREACHED("Unexpected call to InsertCookieDBListener::HandleResult");
     return NS_OK;
   }
   NS_IMETHOD HandleCompletion(uint16_t aReason)
   {
     // If we were rebuilding the db and we succeeded, make our corruptFlag say
@@ -428,17 +428,17 @@ class UpdateCookieDBListener MOZ_FINAL :
 private:
   virtual const char *GetOpType() { return "UPDATE"; }
 
   ~UpdateCookieDBListener() {}
 
 public:
   NS_DECL_ISUPPORTS
 
-  UpdateCookieDBListener(DBState* dbState) : DBListenerErrorHandler(dbState) { }
+  explicit UpdateCookieDBListener(DBState* dbState) : DBListenerErrorHandler(dbState) { }
   NS_IMETHOD HandleResult(mozIStorageResultSet*)
   {
     NS_NOTREACHED("Unexpected call to UpdateCookieDBListener::HandleResult");
     return NS_OK;
   }
   NS_IMETHOD HandleCompletion(uint16_t aReason)
   {
     return NS_OK;
@@ -456,17 +456,17 @@ class RemoveCookieDBListener MOZ_FINAL :
 private:
   virtual const char *GetOpType() { return "REMOVE"; }
 
   ~RemoveCookieDBListener() {}
 
 public:
   NS_DECL_ISUPPORTS
 
-  RemoveCookieDBListener(DBState* dbState) : DBListenerErrorHandler(dbState) { }
+  explicit RemoveCookieDBListener(DBState* dbState) : DBListenerErrorHandler(dbState) { }
   NS_IMETHOD HandleResult(mozIStorageResultSet*)
   {
     NS_NOTREACHED("Unexpected call to RemoveCookieDBListener::HandleResult");
     return NS_OK;
   }
   NS_IMETHOD HandleCompletion(uint16_t aReason)
   {
     return NS_OK;
@@ -485,17 +485,17 @@ private:
   virtual const char *GetOpType() { return "READ"; }
   bool mCanceled;
 
   ~ReadCookieDBListener() {}
 
 public:
   NS_DECL_ISUPPORTS
 
-  ReadCookieDBListener(DBState* dbState)
+  explicit ReadCookieDBListener(DBState* dbState)
     : DBListenerErrorHandler(dbState)
     , mCanceled(false)
   {
   }
 
   void Cancel() { mCanceled = true; }
 
   NS_IMETHOD HandleResult(mozIStorageResultSet *aResult)
@@ -561,17 +561,17 @@ NS_IMPL_ISUPPORTS(ReadCookieDBListener, 
  * Static mozIStorageCompletionCallback used to notify when the database is
  * successfully closed.
  ******************************************************************************/
 class CloseCookieDBListener MOZ_FINAL :  public mozIStorageCompletionCallback
 {
   ~CloseCookieDBListener() {}
 
 public:
-  CloseCookieDBListener(DBState* dbState) : mDBState(dbState) { }
+  explicit CloseCookieDBListener(DBState* dbState) : mDBState(dbState) { }
   nsRefPtr<DBState> mDBState;
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD Complete(nsresult, nsISupports*)
   {
     gCookieService->HandleDBClosed(mDBState);
     return NS_OK;
   }
@@ -1479,17 +1479,17 @@ RebuildDBCallback(nsCookieEntry *aEntry,
   mozIStorageBindingParamsArray* paramsArray =
     static_cast<mozIStorageBindingParamsArray*>(aArg);
 
   const nsCookieEntry::ArrayType &cookies = aEntry->GetCookies();
   for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ++i) {
     nsCookie* cookie = cookies[i];
 
     if (!cookie->IsSession()) {
-      bindCookieParameters(paramsArray, aEntry, cookie);
+      bindCookieParameters(paramsArray, nsCookieKey(aEntry), cookie);
     }
   }
 
   return PL_DHASH_NEXT;
 }
 
 void
 nsCookieService::RebuildCorruptDB(DBState* aDBState)
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -61,17 +61,17 @@ public:
   {}
 
   nsCookieKey(const nsCString &baseDomain, uint32_t appId, bool inBrowser)
     : mBaseDomain(baseDomain)
     , mAppId(appId)
     , mInBrowserElement(inBrowser)
   {}
 
-  nsCookieKey(KeyTypePointer other)
+  explicit nsCookieKey(KeyTypePointer other)
     : mBaseDomain(other->mBaseDomain)
     , mAppId(other->mAppId)
     , mInBrowserElement(other->mInBrowserElement)
   {}
 
   nsCookieKey(KeyType other)
     : mBaseDomain(other.mBaseDomain)
     , mAppId(other.mAppId)
@@ -117,17 +117,17 @@ public:
 // TODO: why aren't we using nsClassHashTable<nsCookieKey, ArrayType>?
 class nsCookieEntry : public nsCookieKey
 {
   public:
     // Hash methods
     typedef nsTArray< nsRefPtr<nsCookie> > ArrayType;
     typedef ArrayType::index_type IndexType;
 
-    nsCookieEntry(KeyTypePointer aKey)
+    explicit nsCookieEntry(KeyTypePointer aKey)
      : nsCookieKey(aKey)
     {}
 
     nsCookieEntry(const nsCookieEntry& toCopy)
     {
       // if we end up here, things will break. nsTHashtable shouldn't
       // allow this, since we set ALLOW_MEMMOVE to true.
       NS_NOTREACHED("nsCookieEntry copy constructor is forbidden!");
--- a/netwerk/dns/DNS.h
+++ b/netwerk/dns/DNS.h
@@ -113,17 +113,17 @@ union NetAddr {
   bool operator == (const NetAddr& other) const;
 };
 
 // This class wraps a NetAddr union to provide C++ linked list
 // capabilities and other methods. It is created from a PRNetAddr,
 // which is converted to a mozilla::dns::NetAddr.
 class NetAddrElement : public LinkedListElement<NetAddrElement> {
 public:
-  NetAddrElement(const PRNetAddr *prNetAddr);
+  explicit NetAddrElement(const PRNetAddr *prNetAddr);
   NetAddrElement(const NetAddrElement& netAddr);
   ~NetAddrElement();
 
   NetAddr mAddress;
 };
 
 class AddrInfo {
 public:
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -52,17 +52,17 @@ static const char kPrefDnsNotifyResoluti
 //-----------------------------------------------------------------------------
 
 class nsDNSRecord : public nsIDNSRecord
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIDNSRECORD
 
-    nsDNSRecord(nsHostRecord *hostRecord)
+    explicit nsDNSRecord(nsHostRecord *hostRecord)
         : mHostRecord(hostRecord)
         , mIter(nullptr)
         , mIterGenCnt(-1)
         , mDone(false) {}
 
 private:
     virtual ~nsDNSRecord() {}
 
@@ -337,17 +337,17 @@ nsDNSAsyncRequest::Cancel(nsresult reaso
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
 class nsDNSSyncRequest : public nsResolveHostCallback
 {
 public:
-    nsDNSSyncRequest(PRMonitor *mon)
+    explicit nsDNSSyncRequest(PRMonitor *mon)
         : mDone(false)
         , mStatus(NS_OK)
         , mMonitor(mon) {}
     virtual ~nsDNSSyncRequest() {}
 
     void OnLookupComplete(nsHostResolver *, nsHostRecord *, nsresult);
     bool EqualsAsyncListener(nsIDNSListener *aListener);
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const;
--- a/netwerk/dns/nsEffectiveTLDService.h
+++ b/netwerk/dns/nsEffectiveTLDService.h
@@ -31,17 +31,17 @@ struct ETLDEntry {
 class nsDomainEntry : public PLDHashEntryHdr
 {
   friend class nsEffectiveTLDService;
 public:
   // Hash methods
   typedef const char* KeyType;
   typedef const char* KeyTypePointer;
 
-  nsDomainEntry(KeyTypePointer aEntry)
+  explicit nsDomainEntry(KeyTypePointer aEntry)
   {
   }
 
   nsDomainEntry(const nsDomainEntry& toCopy)
   {
     // if we end up here, things will break. nsTHashtable shouldn't
     // allow this, since we set ALLOW_MEMMOVE to true.
     NS_NOTREACHED("nsDomainEntry copy constructor is forbidden!");
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -101,17 +101,17 @@ private:
     bool    usingAnyThread; /* true if off queue and contributing to mActiveAnyThreadCount */
     bool    mDoomed; /* explicitly expired */
 
     // a list of addresses associated with this record that have been reported
     // as unusable. the list is kept as a set of strings to make it independent
     // of gencnt.
     nsTArray<nsCString> mBlacklistedItems;
 
-    nsHostRecord(const nsHostKey *key);           /* use Create() instead */
+    explicit nsHostRecord(const nsHostKey *key);           /* use Create() instead */
    ~nsHostRecord();
 };
 
 /**
  * ResolveHost callback object.  It's PRCList members are used by
  * the nsHostResolver and should not be used by anything else.
  */
 class NS_NO_VTABLE nsResolveHostCallback : public PRCList
@@ -234,18 +234,18 @@ public:
         RES_SPECULATE     = 1 << 4,
         //RES_DISABLE_IPV6 = 1 << 5, // Not used
         RES_OFFLINE       = 1 << 6
     };
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
 private:
-    nsHostResolver(uint32_t maxCacheEntries = 50, uint32_t maxCacheLifetime = 60,
-                   uint32_t lifetimeGracePeriod = 0);
+   explicit nsHostResolver(uint32_t maxCacheEntries = 50, uint32_t maxCacheLifetime = 60,
+                            uint32_t lifetimeGracePeriod = 0);
    ~nsHostResolver();
 
     nsresult Init();
     nsresult IssueLookup(nsHostRecord *);
     bool     GetHostToLookup(nsHostRecord **m);
     void     OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
     void     DeQueue(PRCList &aQ, nsHostRecord **aResult);
     void     ClearPendingQueue(PRCList *aPendingQueue);
--- a/netwerk/ipc/ChannelEventQueue.h
+++ b/netwerk/ipc/ChannelEventQueue.h
@@ -35,17 +35,17 @@ class ChannelEvent
 
 class AutoEventEnqueuerBase;
 
 class ChannelEventQueue MOZ_FINAL
 {
   NS_INLINE_DECL_REFCOUNTING(ChannelEventQueue)
 
  public:
-  ChannelEventQueue(nsISupports *owner)
+  explicit ChannelEventQueue(nsISupports *owner)
     : mSuspendCount(0)
     , mSuspended(false)
     , mForced(false)
     , mFlushing(false)
     , mOwner(owner) {}
 
   // Checks to determine if an IPDL-generated channel event can be processed
   // immediately, or needs to be queued using Enqueue().
@@ -160,17 +160,17 @@ ChannelEventQueue::MaybeFlushQueue()
 }
 
 // Ensures that ShouldEnqueue() will be true during its lifetime (letting
 // caller know incoming IPDL msgs should be queued). Flushes the queue when it
 // goes out of scope.
 class AutoEventEnqueuer
 {
  public:
-  AutoEventEnqueuer(ChannelEventQueue *queue) : mEventQueue(queue) {
+  explicit AutoEventEnqueuer(ChannelEventQueue *queue) : mEventQueue(queue) {
     mEventQueue->StartForcedQueueing();
   }
   ~AutoEventEnqueuer() {
     mEventQueue->EndForcedQueueing();
   }
  private:
   ChannelEventQueue* mEventQueue;
 };
--- a/netwerk/ipc/RemoteOpenFileParent.h
+++ b/netwerk/ipc/RemoteOpenFileParent.h
@@ -13,17 +13,17 @@
 #include "nsIFileURL.h"
 
 namespace mozilla {
 namespace net {
 
 class RemoteOpenFileParent : public PRemoteOpenFileParent
 {
 public:
-  RemoteOpenFileParent(nsIFileURL* aURI)
+  explicit RemoteOpenFileParent(nsIFileURL* aURI)
   : mURI(aURI)
   {}
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   bool OpenSendCloseDelete();
 
 private:
--- a/netwerk/protocol/data/nsDataChannel.h
+++ b/netwerk/protocol/data/nsDataChannel.h
@@ -9,17 +9,17 @@
 #define nsDataChannel_h___
 
 #include "nsBaseChannel.h"
 
 class nsIInputStream;
 
 class nsDataChannel : public nsBaseChannel {
 public:
-    nsDataChannel(nsIURI *uri) {
+    explicit nsDataChannel(nsIURI *uri) {
         SetURI(uri);
     }
 
 protected:
     virtual nsresult OpenContentStream(bool async, nsIInputStream **result,
                                        nsIChannel** channel);
 };
 
--- a/netwerk/protocol/file/nsFileChannel.h
+++ b/netwerk/protocol/file/nsFileChannel.h
@@ -15,17 +15,17 @@ class nsFileChannel : public nsBaseChann
                     , public nsIFileChannel
                     , public nsIUploadChannel
 {
 public: 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIFILECHANNEL
   NS_DECL_NSIUPLOADCHANNEL
 
-  nsFileChannel(nsIURI *uri);
+  explicit nsFileChannel(nsIURI *uri);
 
 protected:
   ~nsFileChannel();
 
   // Called to construct a blocking file input stream for the given file.  This
   // method also returns a best guess at the content-type for the data stream.
   // NOTE: If the channel has a type hint set, contentType will be left
   // untouched. The caller should not use it in that case.
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -539,17 +539,17 @@ FTPChannelChild::DoFailedAsyncOpen(const
 
   if (mIPCOpen)
     Send__delete__(this);
 }
 
 class FTPFlushedForDiversionEvent : public ChannelEvent
 {
  public:
-  FTPFlushedForDiversionEvent(FTPChannelChild* aChild)
+  explicit FTPFlushedForDiversionEvent(FTPChannelChild* aChild)
   : mChild(aChild)
   {
     MOZ_RELEASE_ASSERT(aChild);
   }
 
   void Run()
   {
     mChild->FlushedForDiversion();
@@ -596,17 +596,17 @@ FTPChannelChild::RecvDivertMessages()
     return false;
   }
   return true;
 }
 
 class FTPDeleteSelfEvent : public ChannelEvent
 {
  public:
-  FTPDeleteSelfEvent(FTPChannelChild* aChild)
+  explicit FTPDeleteSelfEvent(FTPChannelChild* aChild)
   : mChild(aChild) {}
   void Run() { mChild->DoDeleteSelf(); }
  private:
   FTPChannelChild* mChild;
 };
 
 bool
 FTPChannelChild::RecvDeleteSelf()
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -48,17 +48,17 @@ public:
   NS_DECL_NSIPROXIEDCHANNEL
   NS_DECL_NSICHILDCHANNEL
   NS_DECL_NSIDIVERTABLECHANNEL
 
   NS_IMETHOD Cancel(nsresult status);
   NS_IMETHOD Suspend();
   NS_IMETHOD Resume();
 
-  FTPChannelChild(nsIURI* uri);
+  explicit FTPChannelChild(nsIURI* uri);
 
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
   NS_IMETHOD AsyncOpen(nsIStreamListener* listener, nsISupports* aContext);
 
   // Note that we handle this ourselves, overriding the nsBaseChannel
   // default behavior, in order to be e10s-friendly.
--- a/netwerk/protocol/ftp/nsFTPChannel.cpp
+++ b/netwerk/protocol/ftp/nsFTPChannel.cpp
@@ -131,17 +131,17 @@ nsFtpChannel::OnCallbacksChanged()
 
 namespace {
 
 class FTPEventSinkProxy MOZ_FINAL : public nsIFTPEventSink
 {
     ~FTPEventSinkProxy() {}
 
 public:
-    FTPEventSinkProxy(nsIFTPEventSink* aTarget)
+    explicit FTPEventSinkProxy(nsIFTPEventSink* aTarget)
         : mTarget(aTarget)
         , mTargetThread(do_GetCurrentThread())
     { }
         
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIFTPEVENTSINK
 
     class OnFTPControlLogRunnable : public nsRunnable
--- a/netwerk/protocol/http/Http2Compression.cpp
+++ b/netwerk/protocol/http/Http2Compression.cpp
@@ -164,169 +164,103 @@ nvFIFO::Length() const
 }
 
 uint32_t
 nvFIFO::VariableLength() const
 {
   return mTable.GetSize();
 }
 
+uint32_t
+nvFIFO::StaticLength() const
+{
+  return gStaticHeaders->GetSize();
+}
+
 void
 nvFIFO::Clear()
 {
   mByteCount = 0;
   while (mTable.GetSize())
     delete static_cast<nvPair *>(mTable.Pop());
 }
 
 const nvPair *
 nvFIFO::operator[] (int32_t index) const
 {
+  // NWGH - ensure index > 0
+  // NWGH - subtract 1 from index here
   if (index >= (mTable.GetSize() + gStaticHeaders->GetSize())) {
     MOZ_ASSERT(false);
     NS_WARNING("nvFIFO Table Out of Range");
     return nullptr;
   }
-  if (index >= mTable.GetSize()) {
-    return static_cast<nvPair *>(gStaticHeaders->ObjectAt(index - mTable.GetSize()));
+  if (index >= gStaticHeaders->GetSize()) {
+    return static_cast<nvPair *>(mTable.ObjectAt(index - gStaticHeaders->GetSize()));
   }
-  return static_cast<nvPair *>(mTable.ObjectAt(index));
+  return static_cast<nvPair *>(gStaticHeaders->ObjectAt(index));
 }
 
 Http2BaseCompressor::Http2BaseCompressor()
   : mOutput(nullptr)
   , mMaxBuffer(kDefaultMaxBuffer)
 {
 }
 
 void
 Http2BaseCompressor::ClearHeaderTable()
 {
-  uint32_t dynamicCount = mHeaderTable.VariableLength();
   mHeaderTable.Clear();
-
-  for (int32_t i = mReferenceSet.Length() - 1; i >= 0; --i) {
-    if (mReferenceSet[i] < dynamicCount) {
-      mReferenceSet.RemoveElementAt(i);
-    } else {
-      mReferenceSet[i] -= dynamicCount;
-    }
-  }
-
-  for (int32_t i = mAlternateReferenceSet.Length() - 1; i >= 0; --i) {
-    if (mAlternateReferenceSet[i] < dynamicCount) {
-      mAlternateReferenceSet.RemoveElementAt(i);
-    } else {
-      mAlternateReferenceSet[i] -= dynamicCount;
-    }
-  }
 }
 
 void
-Http2BaseCompressor::UpdateReferenceSet(int32_t delta)
+Http2BaseCompressor::MakeRoom(uint32_t amount, const char *direction)
 {
-  if (!delta)
-    return;
-
-  uint32_t headerTableSize = mHeaderTable.VariableLength();
-  uint32_t oldHeaderTableSize = headerTableSize + delta;
-
-  for (int32_t i = mReferenceSet.Length() - 1; i >= 0; --i) {
-    uint32_t indexRef = mReferenceSet[i];
-    if (indexRef >= headerTableSize) {
-      if (indexRef < oldHeaderTableSize) {
-        // This one got dropped
-        LOG(("HTTP base compressor reference to index %u removed.\n",
-             indexRef));
-        mReferenceSet.RemoveElementAt(i);
-      } else {
-        // This pointed to the static table, need to adjust
-        uint32_t newRef = indexRef - delta;
-        LOG(("HTTP base compressor reference to index %u changed to %d (%s %s)\n",
-             mReferenceSet[i], newRef, mHeaderTable[newRef]->mName.get(),
-             mHeaderTable[newRef]->mValue.get()));
-        mReferenceSet[i] = newRef;
-      }
-    }
-  }
-
-  for (int32_t i = mAlternateReferenceSet.Length() - 1; i >= 0; --i) {
-    uint32_t indexRef = mAlternateReferenceSet[i];
-    if (indexRef >= headerTableSize) {
-      if (indexRef < oldHeaderTableSize) {
-        // This one got dropped
-        LOG(("HTTP base compressor new reference to index %u removed.\n",
-             indexRef));
-        mAlternateReferenceSet.RemoveElementAt(i);
-      } else {
-        // This pointed to the static table, need to adjust
-        uint32_t newRef = indexRef - delta;
-        LOG(("HTTP base compressor new reference to index %u changed to %d (%s %s)\n",
-             mAlternateReferenceSet[i], newRef, mHeaderTable[newRef]->mName.get(),
-             mHeaderTable[newRef]->mValue.get()));
-        mAlternateReferenceSet[i] = newRef;
-      }
-    }
-  }
-}
-
-void
-Http2BaseCompressor::IncrementReferenceSetIndices()
-{
-  LOG(("Http2BaseCompressor::IncrementReferenceSetIndices"));
-  for (int32_t i = mReferenceSet.Length() - 1; i >= 0; --i) {
-    mReferenceSet[i] = mReferenceSet[i] + 1;
-  }
-
-  for (int32_t i = mAlternateReferenceSet.Length() - 1; i >= 0; --i) {
-    mAlternateReferenceSet[i] = mAlternateReferenceSet[i] + 1;
+  // make room in the header table
+  while (mHeaderTable.VariableLength() && ((mHeaderTable.ByteCount() + amount) > mMaxBuffer)) {
+    // NWGH - remove the "- 1" here
+    uint32_t index = mHeaderTable.Length() - 1;
+    LOG(("HTTP %s header table index %u %s %s removed for size.\n",
+         direction, index, mHeaderTable[index]->mName.get(),
+         mHeaderTable[index]->mValue.get()));
+    mHeaderTable.RemoveElement();
   }
 }
 
 void
 Http2BaseCompressor::DumpState()
 {
-  LOG(("Alternate Reference Set"));
+  LOG(("Header Table"));
   uint32_t i;
-  uint32_t length = mAlternateReferenceSet.Length();
-  for (i = 0; i < length; ++i) {
-    LOG(("index %u: %u", i, mAlternateReferenceSet[i]));
-  }
-
-  LOG(("Reference Set"));
-  length = mReferenceSet.Length();
-  for (i = 0; i < length; ++i) {
-    LOG(("index %u: %u", i, mReferenceSet[i]));
-  }
-
-  LOG(("Header Table"));
-  length = mHeaderTable.Length();
-  uint32_t variableLength = mHeaderTable.VariableLength();
+  uint32_t length = mHeaderTable.Length();
+  uint32_t staticLength = mHeaderTable.StaticLength();
+  // NWGH - make i = 1; i <= length; ++i
   for (i = 0; i < length; ++i) {
     const nvPair *pair = mHeaderTable[i];
-    LOG(("%sindex %u: %s %s", i < variableLength ? "" : "static ", i,
+    // NWGH - make this <= staticLength
+    LOG(("%sindex %u: %s %s", i < staticLength ? "static " : "", i,
          pair->mName.get(), pair->mValue.get()));
   }
 }
 
 nsresult
 Http2Decompressor::DecodeHeaderBlock(const uint8_t *data, uint32_t datalen,
                                      nsACString &output)
 {
-  mAlternateReferenceSet.Clear();
   mOffset = 0;
   mData = data;
   mDataLen = datalen;
   mOutput = &output;
   mOutput->Truncate();
   mHeaderStatus.Truncate();
   mHeaderHost.Truncate();
   mHeaderScheme.Truncate();
   mHeaderPath.Truncate();
   mHeaderMethod.Truncate();
+  mSeenNonColonHeader = false;
 
   nsresult rv = NS_OK;
   while (NS_SUCCEEDED(rv) && (mOffset < datalen)) {
     if (mData[mOffset] & 0x80) {
       rv = DoIndexed();
       LOG(("Decompressor state after indexed"));
     } else if (mData[mOffset] & 0x40) {
       rv = DoLiteralWithIncremental();
@@ -339,32 +273,16 @@ Http2Decompressor::DecodeHeaderBlock(con
       LOG(("Decompressor state after literal never index"));
     } else {
       rv = DoLiteralWithoutIndex();
       LOG(("Decompressor state after literal without index"));
     }
     DumpState();
   }
 
-  // after processing the input the decompressor comapres the alternate
-  // set to the inherited reference set and generates headers for
-  // anything implicit in reference - alternate.
-
-  uint32_t setLen = mReferenceSet.Length();
-  for (uint32_t index = 0; index < setLen; ++index) {
-    if (!mAlternateReferenceSet.Contains(mReferenceSet[index])) {
-      LOG(("HTTP decompressor carryover in reference set with index %u %s %s\n",
-           mReferenceSet[index],
-           mHeaderTable[mReferenceSet[index]]->mName.get(),
-           mHeaderTable[mReferenceSet[index]]->mValue.get()));
-      OutputHeader(mReferenceSet[index]);
-    }
-  }
-
-  mAlternateReferenceSet.Clear();
   return rv;
 }
 
 nsresult
 Http2Decompressor::DecodeInteger(uint32_t prefixLen, uint32_t &accum)
 {
   accum = 0;
 
@@ -468,68 +386,66 @@ Http2Decompressor::OutputHeader(const ns
     mHeaderScheme = value;
   } else if (name.EqualsLiteral(":path")) {
     mHeaderPath = value;
   } else if (name.EqualsLiteral(":method")) {
     mHeaderMethod = value;
   }
 
   // http/2 transport level headers shouldn't be gatewayed into http/1
-  if(*(name.BeginReading()) == ':') {
+  bool isColonHeader = false;
+  for (const char *cPtr = name.BeginReading();
+       cPtr && cPtr < name.EndReading();
+       ++cPtr) {
+    if (*cPtr == ':') {
+      isColonHeader = true;
+      break;
+    } else if (*cPtr != ' ' && *cPtr != '\t') {
+      isColonHeader = false;
+      break;
+    }
+  }
+  if(isColonHeader) {
+    if (mSeenNonColonHeader) {
+      LOG(("HTTP Decompressor found illegal : header %s", name.BeginReading()));
+      return NS_ERROR_ILLEGAL_VALUE;
+    }
     LOG(("HTTP Decompressor not gatewaying %s into http/1",
          name.BeginReading()));
     return NS_OK;
   }
 
+  LOG(("Http2Decompressor::OutputHeader %s %s", name.BeginReading(),
+       value.BeginReading()));
+  mSeenNonColonHeader = true;
   mOutput->Append(name);
   mOutput->AppendLiteral(": ");
-  // Special handling for set-cookie according to the spec
-  bool isSetCookie = name.EqualsLiteral("set-cookie");
-  int32_t valueLen = value.Length();
-  nsAutoCString textValue;
-  for (int32_t i = 0; i < valueLen; ++i) {
-    if (value[i] == '\0') {
-      if (isSetCookie) {
-        LOG(("Http2Decompressor::OutputHeader %s %s", name.BeginReading(),
-             textValue.get()));
-        mOutput->Append(textValue);
-        textValue.Truncate(0);
-        mOutput->AppendLiteral("\r\n");
-        mOutput->Append(name);
-        mOutput->AppendLiteral(": ");
-      } else {
-        textValue.AppendLiteral(", ");
-      }
-    } else {
-      textValue.Append(value[i]);
-    }
-  }
-  LOG(("Http2Decompressor::OutputHeader %s %s", name.BeginReading(),
-       textValue.get()));
-  mOutput->Append(textValue);
+  mOutput->Append(value);
   mOutput->AppendLiteral("\r\n");
   return NS_OK;
 }
 
 nsresult
 Http2Decompressor::OutputHeader(uint32_t index)
 {
+  // NWGH - make this < index
   // bounds check
   if (mHeaderTable.Length() <= index) {
     LOG(("Http2Decompressor::OutputHeader index too large %u", index));
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   return OutputHeader(mHeaderTable[index]->mName,
                       mHeaderTable[index]->mValue);
 }
 
 nsresult
 Http2Decompressor::CopyHeaderString(uint32_t index, nsACString &name)
 {
+  // NWGH - make this < index
   // bounds check
   if (mHeaderTable.Length() <= index)
     return NS_ERROR_ILLEGAL_VALUE;
 
   name = mHeaderTable[index]->mName;
   return NS_OK;
 }
 
@@ -710,89 +626,38 @@ Http2Decompressor::CopyHuffmanStringFrom
     }
   }
 
   val = buf;
   LOG(("CopyHuffmanStringFromInput decoded a full string!"));
   return NS_OK;
 }
 
-void
-Http2Decompressor::MakeRoom(uint32_t amount)
-{
-  // make room in the header table
-  uint32_t removedCount = 0;
-  while (mHeaderTable.VariableLength() && ((mHeaderTable.ByteCount() + amount) > mMaxBuffer)) {
-    uint32_t index = mHeaderTable.VariableLength() - 1;
-    LOG(("HTTP decompressor header table index %u %s %s removed for size.\n",
-         index, mHeaderTable[index]->mName.get(),
-         mHeaderTable[index]->mValue.get()));
-    mHeaderTable.RemoveElement();
-    ++removedCount;
-  }
-
-  // adjust references to header table
-  UpdateReferenceSet(removedCount);
-}
-
 nsresult
 Http2Decompressor::DoIndexed()
 {
   // this starts with a 1 bit pattern
   MOZ_ASSERT(mData[mOffset] & 0x80);
 
-  // Indexed entries toggle the reference set
   // This is a 7 bit prefix
 
   uint32_t index;
   nsresult rv = DecodeInteger(7, index);
   if (NS_FAILED(rv))
     return rv;
 
   LOG(("HTTP decompressor indexed entry %u\n", index));
 
   if (index == 0) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
+  // NWGH - remove this line, since we'll keep everything 1-indexed
   index--; // Internally, we 0-index everything, since this is, y'know, C++
 
-  // Toggle this in the reference set..
-  // if its not currently in the reference set then add it and
-  // also emit it. If it is currently in the reference set then just
-  // remove it from there.
-  if (mReferenceSet.RemoveElement(index)) {
-    mAlternateReferenceSet.RemoveElement(index);
-    return NS_OK;
-  }
-
-  rv = OutputHeader(index);
-  if (index >= mHeaderTable.VariableLength()) {
-    const nvPair *pair = mHeaderTable[index];
-    uint32_t room = pair->Size();
-
-    if (room > mMaxBuffer) {
-      ClearHeaderTable();
-      LOG(("HTTP decompressor index not referenced due to size %u %s %s\n",
-           room, pair->mName.get(), pair->mValue.get()));
-      LOG(("Decompressor state after ClearHeaderTable"));
-      DumpState();
-      return rv;
-    }
-
-    LOG(("HTTP decompressor inserting static entry %u %s %s into dynamic table",
-         index, pair->mName.get(), pair->mValue.get()));
-    MakeRoom(room);
-    mHeaderTable.AddElement(pair->mName, pair->mValue);
-    IncrementReferenceSetIndices();
-    index = 0;
-  }
-
-  mReferenceSet.AppendElement(index);
-  mAlternateReferenceSet.AppendElement(index);
-  return rv;
+  return OutputHeader(index);
 }
 
 nsresult
 Http2Decompressor::DoLiteralInternal(nsACString &name, nsACString &value,
                                      uint32_t namePrefixLen)
 {
   // guts of doliteralwithoutindex and doliteralwithincremental
   MOZ_ASSERT(((mData[mOffset] & 0xF0) == 0x00) ||  // withoutindex
@@ -817,16 +682,17 @@ Http2Decompressor::DoLiteralInternal(nsA
         rv = CopyHuffmanStringFromInput(nameLen, name);
       } else {
         rv = CopyStringFromInput(nameLen, name);
       }
     }
     LOG(("Http2Decompressor::DoLiteralInternal literal name %s",
          name.BeginReading()));
   } else {
+    // NWGH - make this index, not index - 1
     // name is from headertable
     rv = CopyHeaderString(index - 1, name);
     LOG(("Http2Decompressor::DoLiteralInternal indexed name %d %s",
          index, name.BeginReading()));
   }
   if (NS_FAILED(rv))
     return rv;
 
@@ -848,26 +714,22 @@ Http2Decompressor::DoLiteralInternal(nsA
 }
 
 nsresult
 Http2Decompressor::DoLiteralWithoutIndex()
 {
   // this starts with 0000 bit pattern
   MOZ_ASSERT((mData[mOffset] & 0xF0) == 0x00);
 
-  // This is not indexed so there is no adjustment to the
-  // persistent reference set
   nsAutoCString name, value;
   nsresult rv = DoLiteralInternal(name, value, 4);
 
   LOG(("HTTP decompressor literal without index %s %s\n",
        name.get(), value.get()));
 
-  // Output the header now because we don't keep void
-  // indicies in the reference set
   if (NS_SUCCEEDED(rv))
     rv = OutputHeader(name, value);
   return rv;
 }
 
 nsresult
 Http2Decompressor::DoLiteralWithIncremental()
 {
@@ -879,93 +741,74 @@ Http2Decompressor::DoLiteralWithIncremen
   if (NS_SUCCEEDED(rv))
     rv = OutputHeader(name, value);
   if (NS_FAILED(rv))
     return rv;
 
   uint32_t room = nvPair(name, value).Size();
   if (room > mMaxBuffer) {
     ClearHeaderTable();
-    LOG(("HTTP decompressor literal with index not referenced due to size %u %s %s\n",
+    LOG(("HTTP decompressor literal with index not inserted due to size %u %s %s\n",
          room, name.get(), value.get()));
     LOG(("Decompressor state after ClearHeaderTable"));
     DumpState();
     return NS_OK;
   }
 
-  MakeRoom(room);
+  MakeRoom(room, "decompressor");
 
   // Incremental Indexing implicitly adds a row to the header table.
-  // It also adds the new row to the Reference Set
   mHeaderTable.AddElement(name, value);
-  IncrementReferenceSetIndices();
-  mReferenceSet.AppendElement(0);
-  mAlternateReferenceSet.AppendElement(0);
 
   LOG(("HTTP decompressor literal with index 0 %s %s\n",
        name.get(), value.get()));
 
   return NS_OK;
 }
 
 nsresult
 Http2Decompressor::DoLiteralNeverIndexed()
 {
   // This starts with 0001 bit pattern
   MOZ_ASSERT((mData[mOffset] & 0xF0) == 0x10);
 
-  // This is not indexed so there is no adjustment to the
-  // persistent reference set
   nsAutoCString name, value;
   nsresult rv = DoLiteralInternal(name, value, 4);
 
   LOG(("HTTP decompressor literal never indexed %s %s\n",
        name.get(), value.get()));
 
-  // Output the header now because we don't keep void
-  // indicies in the reference set
   if (NS_SUCCEEDED(rv))
     rv = OutputHeader(name, value);