Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 09 Sep 2015 14:10:46 +0200
changeset 294117 6e64ea28389d117fcfd62e2902bbfa0770670e7f
parent 294116 94a35ea51e6adebb93599ab0e6f9b9b7326bb7ef (current diff)
parent 294092 dd9e40b4695909f1595814c0e79e4d55d73dc283 (diff)
child 294118 076c517796268734a28ff0b45adbd3118b6be428
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to fx-team
build/gen_mach_buildprops.py
gfx/src/gfxCore.h
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1193379 - Moving location of files under dom/bluetooth requires a clobber
+Bug 1201224 - stop unifying test package during mac universal builds needed a CLOBBER
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="067c08fb3e5744b42b68d1f861245f7d507109bc"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="067c08fb3e5744b42b68d1f861245f7d507109bc"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "e69f2c86b931b723dd405115e33a1d02e6c5f5e6", 
+        "git_revision": "60e212543329ee48f2921e0cd92aaca4b4ce2f6a", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "410ec98908ee38c636b018d3ba92e17fb338db79", 
+    "revision": "8aa25dda878ebc1b075933633b69967b930b0726", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="e69f2c86b931b723dd405115e33a1d02e6c5f5e6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="60e212543329ee48f2921e0cd92aaca4b4ce2f6a"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
--- a/browser/devtools/webide/content/webide.xul
+++ b/browser/devtools/webide/content/webide.xul
@@ -18,17 +18,17 @@
 <window id="webide" onclose="return UI.canCloseProject();"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="&windowTitle;"
         windowtype="devtools:webide"
         macanimationtype="document"
         fullscreenbutton="true"
         screenX="4" screenY="4"
-        width="640" height="480"
+        width="800" height="600"
         persist="screenX screenY width height sizemode">
 
   <script type="application/javascript" src="chrome://global/content/globalOverlay.js"></script>
   <script type="application/javascript" src="project-panel.js"></script>
   <script type="application/javascript" src="runtime-panel.js"></script>
   <script type="application/javascript" src="webide.js"></script>
 
   <commandset id="mainCommandSet">
--- a/browser/devtools/webide/modules/project-list.js
+++ b/browser/devtools/webide/modules/project-list.js
@@ -137,16 +137,17 @@ ProjectList.prototype = {
     if (this._sidebarsEnabled && this._doc !== this._parentWindow.document) {
       let span = opts.panel.querySelector("span") || this._doc.createElement("span");
       span.textContent = opts.name;
       let icon = opts.panel.querySelector("img") || this._doc.createElement("img");
       icon.className = "project-image";
       icon.setAttribute("src", opts.icon);
       opts.panel.appendChild(icon);
       opts.panel.appendChild(span);
+      opts.panel.setAttribute("title", opts.name);
     } else {
       opts.panel.setAttribute("label", opts.name);
       opts.panel.setAttribute("image", opts.icon);
     }
   },
 
   refreshTabs: function() {
     if (AppManager.connected) {
--- a/browser/devtools/webide/themes/config-view.css
+++ b/browser/devtools/webide/themes/config-view.css
@@ -18,38 +18,40 @@ html, body {
   font-family: sans-serif;
   padding-left: 6px;
   width: 100%;
   table-layout: auto;
   margin-top: 110px;
 }
 
 #custom-value-name {
-  width: 70%;
+  width: 50%;
 }
 
 header {
   background-color: rgba(255, 255, 255, 0.8);
   border-bottom: 1px solid #EEE;
   position: fixed;
   top: 0;
   left: 0;
   right: 0;
   height: 90px;
   padding: 10px 20px;
 }
 
 #device-fields td {
-  background-color: #f1f1f1;
-  border-bottom: 1px solid #ccc;
-  border-right: 1px solid #fff;
+  background-color: #F9F9F9;
+  border-bottom: 1px solid #CCC;
+  border-right: 1px solid #FFF;
+  font-size: 0.75em;
 }
 
 #device-fields td:first-child {
-  min-width: 400px;
+  max-width: 250px;
+  min-width: 150px;
 }
 
 #device-fields td.preference-name, #device-fields td.setting-name {
   width: 50%;
   min-width: 400px;
   word-break: break-all;
 }
 
@@ -60,17 +62,17 @@ header {
   white-space: nowrap;
 }
 
 #device-fields tr.hide, #device-fields button.hide {
   display: none;
 }
 
 #device-fields .custom-input {
-  width: 300px;
+  width: 130px;
 }
 
 #search {
   margin-bottom: 20px;
   width: 100%;
 }
 
 #search-bar {
--- a/browser/devtools/webide/themes/deck.css
+++ b/browser/devtools/webide/themes/deck.css
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 html {
   font: message-box;
-  font-size: 15px;
+  font-size: 0.9em;
   font-weight: normal;
   margin: 0;
   height: 100%;
   color: #737980;
   background-color: #ededed;
 }
 
 body {
@@ -23,17 +23,17 @@ body {
 }
 
 .text-input input {
   flex: 0.5;
   margin-left: 5px;
 }
 
 h1 {
-  font-size: 2.5em;
+  font-size: 2em;
   font-weight: lighter;
   line-height: 1.2;
   margin: 0;
   margin-bottom: .5em;
 }
 
 #controls {
   position: absolute;
@@ -55,17 +55,17 @@ table {
 }
 
 th, td {
   padding: 5px;
   border: 1px solid #eee;
 }
 
 th {
-  min-width: 130px;
+  min-width: 100px;
 }
 
 th:first-of-type, td:first-of-type {
   text-align: left;
 }
 
 li {
   list-style: none;
--- a/browser/devtools/webide/themes/panel-listing.css
+++ b/browser/devtools/webide/themes/panel-listing.css
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 html {
   font: message-box;
-  font-size: 12px;
+  font-size: 11px;
   font-weight: 400;
 }
 
 label,
 .panel-item,
 #project-panel-projects,
 #runtime-panel-projects {
   display: block;
@@ -48,65 +48,82 @@ label,
 }
 
 #runtime-panel-simulator,
 .panel-item-complex {
   clear: both;
   position: relative;
 }
 
+.panel-item span {
+  display: block;
+  float: left;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  width: 75%;
+  white-space: nowrap;
+}
+
 .panel-item {
   padding: 3%;
   display: block;
-  background-color: #fff;
-  border-bottom: 1px solid #ccc;
-  border-right: 1px solid #ccc;
-  border-top: 1px solid #ededed;
+  width: 94%;
+  cursor: pointer;
+  border-top: 1px solid transparent;
   border-left: 0;
-  width: 94%;
+  border-bottom: 1px solid #CCC;
+  border-right: 0;
+  background-color: transparent;
 }
 
 button.panel-item {
-  background-position: 8px 8px;
+  background-position: 5px 5px;
   background-repeat: no-repeat;
   background-size: 14px 14px;
   padding-left: 25px;
   width: 100%;
 }
 
-button.project-panel-item-refreshtabs {
+.panel-item:disabled {
+  background-color: #FFF;
+  color: #5A5A5A;
+  opacity: 0.5;
+  cursor: default;
+}
+
+#refresh-tabs {
+  background-color: #FFF;
+  border-top: 1px solid #EDEDED;
   display: inline-block;
   float: right;
   padding: 3px;
   text-transform: none;
+  border-right: 1px solid #CCC;
   width: auto;
   margin: 0 4px 5px 5px;
 }
 
-.panel-item:disabled {
-  background-color: #FFF;
-  color: #5A5A5A;
-  opacity: 0.5;
-}
-
-.panel-item:not(:disabled):hover {
+.panel-item:not(:disabled):hover,
+button.panel-item:not(:disabled):hover,
+#refresh-tabs:hover {
   background-color: #CCF0FD;
+  border-top: 1px solid #EDEDED;
 }
 
 .configure-button {
   display: inline-block;
   height: 30px;
   width: 30px;
   background-color: transparent;
   background-image: -moz-image-rect(url("icons.png"), 104, 462, 129, 438);
   background-position: center center;
   background-repeat: no-repeat;
   background-size: 14px 14px;
   position: absolute;
-  top: 0;
+  top: -2px;
   right: 0;
   border: 0;
 }
 
 .configure-button:hover {
   cursor: pointer;
 }
 
--- a/browser/devtools/webide/themes/webide.css
+++ b/browser/devtools/webide/themes/webide.css
@@ -157,20 +157,24 @@ panel > .panel-arrowcontainer > .panel-a
   padding: 12px 0;
   min-width: 200px;
   max-width: 400px;
 }
 
 .panel-list {
   display: none;
   position: relative;
-  max-width: 250px;
+  max-width: 180px;
   overflow: hidden;
 }
 
+#project-listing-panel.panel-list {
+  max-width: 165px;
+}
+
 .panel-list-wrapper {
   height: 100%;
   width: 100%;
   min-width: 100px;
   position: absolute;
   top: 0;
   bottom: 0;
   right: 0;
deleted file mode 100644
--- a/build/gen_mach_buildprops.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/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/.
-
-import sys
-import os
-import hashlib
-import json
-import re
-import errno
-from argparse import ArgumentParser
-
-def getFileHashAndSize(filename):
-    sha512Hash = 'UNKNOWN'
-    size = 'UNKNOWN'
-
-    try:
-        # open in binary mode to make sure we get consistent results
-        # across all platforms
-        f = open(filename, "rb")
-        shaObj = hashlib.sha512(f.read())
-        sha512Hash = shaObj.hexdigest()
-
-        size = os.path.getsize(filename)
-    except:
-        pass
-
-    return (sha512Hash, size)
-
-def getMarProperties(filename, partial=False):
-    if not os.path.exists(filename):
-        return {}
-    (mar_hash, mar_size) = getFileHashAndSize(filename)
-    martype = 'partial' if partial else 'complete'
-    return {
-        '%sMarFilename' % martype: os.path.basename(filename),
-        '%sMarSize' % martype: mar_size,
-        '%sMarHash' % martype: mar_hash,
-    }
-
-def getPartialInfo(props):
-    return [{
-        "from_buildid": props.get("previous_buildid"),
-        "size": props.get("partialMarSize"),
-        "hash": props.get("partialMarHash"),
-        "url": props.get("partialMarUrl"),
-    }]
-
-if __name__ == '__main__':
-    parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.')
-    parser.add_argument("--complete-mar-file", required=True,
-                        action="store", dest="complete_mar_file",
-                        help="Path to the complete MAR file, relative to the objdir.")
-    parser.add_argument("--partial-mar-file", required=False,
-                        action="store", dest="partial_mar_file",
-                        help="Path to the partial MAR file, relative to the objdir.")
-    parser.add_argument("--upload-properties", required=False,
-                        action="store", dest="upload_properties",
-                        help="Path to the properties written by 'make upload'")
-    args = parser.parse_args()
-
-    json_data = getMarProperties(args.complete_mar_file)
-    if args.upload_properties:
-        with open(args.upload_properties) as f:
-            json_data.update(json.load(f))
-    if args.partial_mar_file:
-        json_data.update(getMarProperties(args.partial_mar_file, partial=True))
-
-        # Pull the previous buildid from the partial mar filename.
-        res = re.match(r'.*\.([0-9]+)-[0-9]+.mar', args.partial_mar_file)
-        if res:
-            json_data['previous_buildid'] = res.group(1)
-
-            # Set partialInfo to be a collection of the partial mar properties
-            # useful for balrog.
-            json_data['partialInfo'] = getPartialInfo(json_data)
-
-    with open('mach_build_properties.json', 'w') as outfile:
-        json.dump(json_data, outfile, indent=4)
--- a/build/moz-automation.mk
+++ b/build/moz-automation.mk
@@ -12,21 +12,16 @@ endif
 endif
 
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 include $(topsrcdir)/toolkit/mozapps/installer/upload-files.mk
 
 # Clear out DIST_FILES if it was set by upload-files.mk (for Android builds)
 DIST_FILES =
 
-ifeq (1,$(MOZ_AUTOMATION_UPLOAD))
-# Properties from 'make upload' that are file URLs.
-AUTOMATION_UPLOAD_PROPERTIES = --upload-properties $(DIST)/upload-properties.json
-endif
-
 # Helper variables to convert from MOZ_AUTOMATION_* variables to the
 # corresponding the make target
 tier_MOZ_AUTOMATION_BUILD_SYMBOLS = buildsymbols
 tier_MOZ_AUTOMATION_L10N_CHECK = l10n-check
 tier_MOZ_AUTOMATION_PRETTY_L10N_CHECK = pretty-l10n-check
 tier_MOZ_AUTOMATION_INSTALLER = installer
 tier_MOZ_AUTOMATION_PRETTY_INSTALLER = pretty-installer
 tier_MOZ_AUTOMATION_PACKAGE = package
@@ -95,17 +90,17 @@ automation/sdk: automation/installer aut
 # conflicts in writing to the same files.
 automation/installer: automation/pretty-installer
 automation/package: automation/pretty-package
 automation/package-tests: automation/pretty-package-tests
 automation/l10n-check: automation/pretty-l10n-check
 automation/update-packaging: automation/pretty-update-packaging
 
 automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
-	$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) $(AUTOMATION_UPLOAD_PROPERTIES)
+	@echo Automation steps completed.
 
 # Note: We have to force -j1 here, at least until bug 1036563 is fixed.
 AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1
 AUTOMATION_EXTRA_CMDLINE-pretty-l10n-check = -j1
 
 # And force -j1 here until bug 1077670 is fixed.
 AUTOMATION_EXTRA_CMDLINE-package-tests = -j1
 AUTOMATION_EXTRA_CMDLINE-pretty-package-tests = -j1
--- a/build/upload.py
+++ b/build/upload.py
@@ -3,45 +3,44 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 #
 # When run directly, this script expects the following environment variables
 # to be set:
 # UPLOAD_HOST    : host to upload files to
 # UPLOAD_USER    : username on that host
+#  and one of the following:
 # UPLOAD_PATH    : path on that host to put the files in
+# UPLOAD_TO_TEMP : upload files to a new temporary directory
+#
+# If UPLOAD_HOST and UPLOAD_USER are not set, this script will simply write out
+# the properties file.
 #
 # And will use the following optional environment variables if set:
 # UPLOAD_SSH_KEY : path to a ssh private key to use
 # UPLOAD_PORT    : port to use for ssh
 # POST_UPLOAD_CMD: a commandline to run on the remote host after uploading.
 #                  UPLOAD_PATH and the full paths of all files uploaded will
 #                  be appended to the commandline.
 #
 # All files to be uploaded should be passed as commandline arguments to this
 # script. The script takes one other parameter, --base-path, which you can use
 # to indicate that files should be uploaded including their paths relative
 # to the base path.
 
 import sys, os
 import re
 import json
+import errno
+import hashlib
 from optparse import OptionParser
 from subprocess import check_call, check_output, STDOUT
 import redo
 
-def RequireEnvironmentVariable(v):
-    """Return the value of the environment variable named v, or print
-    an error and exit if it's unset (or empty)."""
-    if not v in os.environ or os.environ[v] == "":
-        print "Error: required environment variable %s not set" % v
-        sys.exit(1)
-    return os.environ[v]
-
 def OptionalEnvironmentVariable(v):
     """Return the value of the environment variable named v, or None
     if it's unset (or empty)."""
     if v in os.environ and os.environ[v] != "":
         return os.environ[v]
     return None
 
 def FixupMsysPath(path):
@@ -114,16 +113,43 @@ def GetRemotePath(path, local_file, base
     the relative path from base_path to file."""
     if base_path is None or not local_file.startswith(base_path):
         return path
     dir = os.path.dirname(local_file)
     # strip base_path + extra slash and make it unixy
     dir = dir[len(base_path)+1:].replace('\\','/')
     return path + dir
 
+def GetFileHashAndSize(filename):
+    sha512Hash = 'UNKNOWN'
+    size = 'UNKNOWN'
+
+    try:
+        # open in binary mode to make sure we get consistent results
+        # across all platforms
+        with open(filename, "rb") as f:
+            shaObj = hashlib.sha512(f.read())
+            sha512Hash = shaObj.hexdigest()
+
+        size = os.path.getsize(filename)
+    except:
+        raise Exception("Unable to get filesize/hash from file: %s" % filename)
+
+    return (sha512Hash, size)
+
+def GetMarProperties(filename):
+    if not os.path.exists(filename):
+        return {}
+    (mar_hash, mar_size) = GetFileHashAndSize(filename)
+    return {
+        'completeMarFilename': os.path.basename(filename),
+        'completeMarSize': mar_size,
+        'completeMarHash': mar_hash,
+    }
+
 def GetUrlProperties(output, package):
     # let's create a switch case using name-spaces/dict
     # rather than a long if/else with duplicate code
     property_conditions = [
         # key: property name, value: condition
         ('symbolsUrl', lambda m: m.endswith('crashreporter-symbols.zip') or
                        m.endswith('crashreporter-symbols-full.zip')),
         ('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))),
@@ -151,34 +177,42 @@ def GetUrlProperties(output, package):
                         properties.update({prop: m})
                         break
     except IOError as e:
         if e.errno != errno.ENOENT:
             raise
         properties = {prop: 'UNKNOWN' for prop, condition in property_conditions}
     return properties
 
-def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None, properties_file=None, package=None):
+def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None, package=None):
     """Upload each file in the list files to user@host:path. Optionally pass
     port and ssh_key to the ssh commands. If base_path is not None, upload
     files including their path relative to base_path. If upload_to_temp_dir is
     True files will be uploaded to a temporary directory on the remote server.
     Generally, you should have a post upload command specified in these cases
     that can move them around to their correct location(s).
     If post_upload_command is not None, execute that command on the remote host
     after uploading all files, passing it the upload path, and the full paths to
     all files uploaded.
     If verbose is True, print status updates while working."""
+    if not host or not user:
+        return {}
+    if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
+        print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
+                "defined."
+        sys.exit(1)
+
     if upload_to_temp_dir:
         path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
     if not path.endswith("/"):
         path += "/"
     if base_path is not None:
         base_path = os.path.abspath(base_path)
     remote_files = []
+    properties = {}
     try:
         for file in files:
             file = os.path.abspath(file)
             if not os.path.isfile(file):
                 raise IOError("File not found: %s" % file)
             # first ensure that path exists remotely
             remote_path = GetRemotePath(path, file, base_path)
             DoSSHCommand("mkdir -p " + remote_path, user, host, port=port, ssh_key=ssh_key)
@@ -188,43 +222,46 @@ def UploadFiles(user, host, path, files,
             remote_files.append(remote_path + '/' + os.path.basename(file))
         if post_upload_command is not None:
             if verbose:
                 print "Running post-upload command: " + post_upload_command
             file_list = '"' + '" "'.join(remote_files) + '"'
             output = DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
             # We print since mozharness may parse URLs from the output stream.
             print output
-            if properties_file:
-                with open(properties_file, 'w') as outfile:
-                    properties = GetUrlProperties(output, package)
-                    properties['packageFilename'] = package
-                    properties['uploadFiles'] = [os.path.abspath(f) for f in files]
-                    json.dump(properties, outfile, indent=4)
+            properties = GetUrlProperties(output, package)
     finally:
         if upload_to_temp_dir:
             DoSSHCommand("rm -rf %s" % path, user, host, port=port,
                          ssh_key=ssh_key)
     if verbose:
         print "Upload complete"
+    return properties
+
+def WriteProperties(files, properties_file, url_properties, package):
+    properties = url_properties
+    for file in files:
+        if file.endswith('.complete.mar'):
+            properties.update(GetMarProperties(file))
+    with open(properties_file, 'w') as outfile:
+        properties['packageFilename'] = package
+        properties['uploadFiles'] = [os.path.abspath(f) for f in files]
+        json.dump(properties, outfile, indent=4)
 
 if __name__ == '__main__':
-    host = RequireEnvironmentVariable('UPLOAD_HOST')
-    user = RequireEnvironmentVariable('UPLOAD_USER')
+    host = OptionalEnvironmentVariable('UPLOAD_HOST')
+    user = OptionalEnvironmentVariable('UPLOAD_USER')
     path = OptionalEnvironmentVariable('UPLOAD_PATH')
     upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
     port = OptionalEnvironmentVariable('UPLOAD_PORT')
     if port is not None:
         port = int(port)
     key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
     post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
-    if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
-        print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
-              "defined."
-        sys.exit(1)
+
     if sys.platform == 'win32':
         if path is not None:
             path = FixupMsysPath(path)
         if post_upload_command is not None:
             post_upload_command = FixupMsysPath(post_upload_command)
 
     parser = OptionParser(usage="usage: %prog [options] <files>")
     parser.add_option("-b", "--base-path",
@@ -235,20 +272,24 @@ if __name__ == '__main__':
                       help="Path to the properties file to store the upload properties.")
     parser.add_option("--package",
                       action="store",
                       help="Name of the main package.")
     (options, args) = parser.parse_args()
     if len(args) < 1:
         print "You must specify at least one file to upload"
         sys.exit(1)
+    if not options.properties_file:
+        print "You must specify a --properties-file"
+        sys.exit(1)
     try:
-        UploadFiles(user, host, path, args, base_path=options.base_path,
-                    port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
-                    post_upload_command=post_upload_command,
-                    properties_file=options.properties_file, package=options.package,
-                    verbose=True)
+        url_properties = UploadFiles(user, host, path, args, base_path=options.base_path,
+                                     port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
+                                     post_upload_command=post_upload_command,
+                                     package=options.package,
+                                     verbose=True)
+        WriteProperties(args, options.properties_file, url_properties, options.package)
     except IOError, (strerror):
         print strerror
         sys.exit(1)
     except Exception, (err):
         print err
         sys.exit(2)
--- a/configure.in
+++ b/configure.in
@@ -1590,16 +1590,17 @@ if test "$GNU_CXX"; then
     # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
     # -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
     # -Wint-to-pointer-cast - catches cast to pointer from integer of different size
     # -Wmissing-braces - catches aggregate initializers missing nested braces
     # -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
     # -Woverloaded-virtual - function declaration hides virtual function from base class
     # -Wparentheses - catches `if (a=b)` and operator precedence bugs
     # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
+    # -Wrange-loop-analysis - catches copies during range-based for loops.
     # -Wreturn-type - catches missing returns, zero false positives
     # -Wsequence-point - catches undefined order behavior like `a = a++`
     # -Wsign-compare - catches comparison of signed and unsigned types
     # -Wswitch - catches switches without all enum cases or default case
     # -Wtrigraphs - catches unlikely use of trigraphs
     # -Wtype-limits - catches overflow bugs, few false positives
     # -Wunused-label - catches unused goto labels
     # -Wwrite-strings - catches non-const char* pointers to string literals
@@ -1621,16 +1622,17 @@ if test "$GNU_CXX"; then
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=switch"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=uninitialized"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
 
         MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
+        MOZ_CXX_SUPPORTS_WARNING(-Werror=, range-loop-analysis, ac_cxx_has_range_loop_analysis)
         MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
     fi
 
     # Turn off the following warnings that -Wall turns on:
     # -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
     # -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc
     # -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
     #   for performance reasons, and because GCC and clang accept it (though
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -185,16 +185,40 @@ FlattenedChildIterator::Init(bool aIgnor
         MOZ_ASSERT(child->GetBindingParent());
         mXBLInvolved = true;
         break;
       }
     }
   }
 }
 
+void
+ExplicitChildIterator::Seek(nsIContent* aChildToFind)
+{
+  if (aChildToFind->GetParent() == mParent &&
+      !aChildToFind->IsRootOfAnonymousSubtree()) {
+    // Fast path: just point ourselves to aChildToFind, which is a
+    // normal DOM child of ours.
+    MOZ_ASSERT(!ShadowRoot::IsShadowInsertionPoint(aChildToFind));
+    MOZ_ASSERT(!nsContentUtils::IsContentInsertionPoint(aChildToFind));
+    mChild = aChildToFind;
+    mIndexInInserted = 0;
+    mShadowIterator = nullptr;
+    mDefaultChild = nullptr;
+    mIsFirst = false;
+    return;
+  }
+
+  // Can we add more fast paths here based on whether the parent of aChildToFind
+  // is a shadow insertion point or content insertion point?
+
+  // Slow path: just walk all our kids.
+  Seek(aChildToFind, nullptr);
+}
+
 nsIContent*
 ExplicitChildIterator::Get()
 {
   MOZ_ASSERT(!mIsFirst);
 
   if (mIndexInInserted) {
     MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild);
     return assignedChildren[mIndexInInserted - 1];
--- a/dom/base/ChildIterator.h
+++ b/dom/base/ChildIterator.h
@@ -55,26 +55,34 @@ public:
   ExplicitChildIterator(ExplicitChildIterator&& aOther)
     : mParent(aOther.mParent), mChild(aOther.mChild),
       mDefaultChild(aOther.mDefaultChild),
       mShadowIterator(Move(aOther.mShadowIterator)),
       mIndexInInserted(aOther.mIndexInInserted), mIsFirst(aOther.mIsFirst) {}
 
   nsIContent* GetNextChild();
 
-  // Looks for aChildToFind respecting insertion points until aChildToFind
+  // Looks for aChildToFind respecting insertion points until aChildToFind is
+  // found.  This version can take shortcuts that the two-argument version
+  // can't, so can be faster (and in fact can be O(1) instead of O(N) in many
+  // cases).
+  void Seek(nsIContent* aChildToFind);
+
+  // Looks for aChildToFind respecting insertion points until aChildToFind is found.
   // or aBound is found. If aBound is nullptr then the seek is unbounded. Returns
   // whether aChildToFind was found as an explicit child prior to encountering
   // aBound.
-  bool Seek(nsIContent* aChildToFind, nsIContent* aBound = nullptr)
+  bool Seek(nsIContent* aChildToFind, nsIContent* aBound)
   {
     // It would be nice to assert that we find aChildToFind, but bz thinks that
     // we might not find aChildToFind when called from ContentInserted
     // if first-letter frames are about.
 
+    // We can't easily take shortcuts here because we'd have to have a way to
+    // compare aChildToFind to aBound.
     nsIContent* child;
     do {
       child = GetNextChild();
     } while (child && child != aChildToFind && child != aBound);
 
     return child == aChildToFind;
   }
 
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -311,17 +311,17 @@ ShadowRoot::DistributeSingleNode(nsICont
         isIndexFound = true;
         break;
       }
     }
 
     if (!isIndexFound) {
       // We have still not found an index in the insertion point,
       // thus it must be at the end.
-      MOZ_ASSERT(childIterator.Seek(aContent),
+      MOZ_ASSERT(childIterator.Seek(aContent, nullptr),
                  "Trying to match a node that is not a candidate to be matched");
       insertionPoint->AppendMatchedNode(aContent);
     }
 
     // Handle the case where the parent of the insertion point is a ShadowRoot
     // that is projected into the younger ShadowRoot's shadow insertion point.
     // The node distributed into the insertion point must be reprojected
     // to the shadow insertion point.
--- a/dom/base/UseCounters.conf
+++ b/dom/base/UseCounters.conf
@@ -37,8 +37,12 @@
 // dependencies were correct would have been rather difficult, and
 // annotating the WebIDL files does nothing for identifying CSS
 // property usage, which we would also like to track.
 
 method SVGSVGElement.getElementById
 attribute SVGSVGElement.currentScale
 property Fill
 property FillOpacity
+
+// Push API
+method PushManager.subscribe
+method PushSubscription.unsubscribe
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -626,18 +626,18 @@ nsCopySupport::FireClipboardEvent(EventM
                                   nsIPresShell* aPresShell,
                                   nsISelection* aSelection,
                                   bool* aActionTaken)
 {
   if (aActionTaken) {
     *aActionTaken = false;
   }
 
-  NS_ASSERTION(aEventMessage == NS_CUT || aEventMessage == NS_COPY ||
-               aEventMessage == NS_PASTE,
+  NS_ASSERTION(aEventMessage == eCut || aEventMessage == eCopy ||
+               aEventMessage == ePaste,
                "Invalid clipboard event type");
 
   nsCOMPtr<nsIPresShell> presShell = aPresShell;
   if (!presShell)
     return false;
 
   nsCOMPtr<nsIDocument> doc = presShell->GetDocument();
   if (!doc)
@@ -683,32 +683,32 @@ nsCopySupport::FireClipboardEvent(EventM
   const bool chromeShell =
     docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome;
 
   // next, fire the cut, copy or paste event
   bool doDefault = true;
   nsRefPtr<DataTransfer> clipboardData;
   if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
     clipboardData =
-      new DataTransfer(piWindow, aEventMessage, aEventMessage == NS_PASTE,
+      new DataTransfer(piWindow, aEventMessage, aEventMessage == ePaste,
                        aClipboardType);
 
     nsEventStatus status = nsEventStatus_eIgnore;
     InternalClipboardEvent evt(true, aEventMessage);
     evt.clipboardData = clipboardData;
     EventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt,
                               nullptr, &status);
     // If the event was cancelled, don't do the clipboard operation
     doDefault = (status != nsEventStatus_eConsumeNoDefault);
   }
 
   // No need to do anything special during a paste. Either an event listener
   // took care of it and cancelled the event, or the caller will handle it.
   // Return true to indicate that the event wasn't cancelled.
-  if (aEventMessage == NS_PASTE) {
+  if (aEventMessage == ePaste) {
     // Clear and mark the clipboardData as readonly. This prevents someone
     // from reading the clipboard contents after the paste event has fired.
     if (clipboardData) {
       clipboardData->ClearAll();
       clipboardData->SetReadOnly();
     }
 
     if (aActionTaken) {
@@ -738,17 +738,17 @@ nsCopySupport::FireClipboardEvent(EventM
     if (formControl) {
       if (formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
         return false;
       }
     }
 
     // when cutting non-editable content, do nothing
     // XXX this is probably the wrong editable flag to check
-    if (aEventMessage != NS_CUT || content->IsEditable()) {
+    if (aEventMessage != eCut || content->IsEditable()) {
       // get the data from the selection if any
       bool isCollapsed;
       sel->GetIsCollapsed(&isCollapsed);
       if (isCollapsed) {
         if (aActionTaken) {
           *aActionTaken = true;
         }
         return false;
--- a/dom/base/nsCopySupport.h
+++ b/dom/base/nsCopySupport.h
@@ -59,18 +59,18 @@ class nsCopySupport
     /**
      * Returns true if a copy operation is currently permitted based on the
      * current focus and selection within the specified document.
      */
     static bool CanCopy(nsIDocument* aDocument);
 
     /**
      * Fires a cut, copy or paste event, on the given presshell, depending
-     * on the value of aEventMessage, which should be either NS_CUT, NS_COPY or
-     * NS_PASTE, and perform the default copy action if the event was not
+     * on the value of aEventMessage, which should be either eCut, eCopy or
+     * ePaste, and perform the default copy action if the event was not
      * cancelled.
      *
      * If aSelection is specified, then this selection is used as the target
      * of the operation. Otherwise, GetSelectionForCopy is used to retrieve
      * the current selection.
      *
      * This will fire a cut, copy or paste event at the node at the start
      * point of the selection. If a cut or copy event is not cancelled, the
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2021,17 +2021,17 @@ nsDOMWindowUtils::SendSelectionSetEvent(
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
-  WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
+  WidgetSelectionEvent selectionEvent(true, eSetSelection, widget);
   InitEvent(selectionEvent);
 
   selectionEvent.mOffset = aOffset;
   selectionEvent.mLength = aLength;
   selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
   selectionEvent.mUseNativeLineBreak =
     !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -8588,19 +8588,16 @@ nsDocument::RetrieveRelevantHeaders(nsIC
       if (st == PR_SUCCESS) {
         modDate = time;
       }
     }
 
     // The misspelled key 'referer' is as per the HTTP spec
     rv = httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("referer"),
                                        mReferrer);
-    if (NS_FAILED(rv)) {
-      mReferrer.Truncate();
-    }
 
     static const char *const headers[] = {
       "default-style",
       "content-style-type",
       "content-language",
       "content-disposition",
       "refresh",
       "x-dns-prefetch-control",
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6913,17 +6913,19 @@ nsGlobalWindow::AlertOrConfirm(bool aAle
                                const nsAString& aMessage,
                                mozilla::ErrorResult& aError)
 {
   // XXX This method is very similar to nsGlobalWindow::Prompt, make
   // sure any modifications here don't need to happen over there!
   MOZ_ASSERT(IsOuterWindow());
 
   if (!AreDialogsEnabled()) {
-    aError.Throw(NS_ERROR_NOT_AVAILABLE);
+    // Just silently return.  In the case of alert(), the return value is
+    // ignored.  In the case of confirm(), returning false is the same thing as
+    // would happen if the user cancels.
     return false;
   }
 
   // Reset popup state while opening a modal dialog, and firing events
   // about the dialog, to prevent the current state from being active
   // the whole time a modal dialog is open.
   nsAutoPopupStatePusher popupStatePusher(openAbused, true);
 
@@ -7053,17 +7055,17 @@ nsGlobalWindow::PromptOuter(const nsAStr
 {
   // XXX This method is very similar to nsGlobalWindow::AlertOrConfirm, make
   // sure any modifications here don't need to happen over there!
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
   SetDOMStringToNull(aReturn);
 
   if (!AreDialogsEnabled()) {
-    aError.Throw(NS_ERROR_NOT_AVAILABLE);
+    // Return null, as if the user just canceled the prompt.
     return;
   }
 
   // Reset popup state while opening a modal dialog, and firing events
   // about the dialog, to prevent the current state from being active
   // the whole time a modal dialog is open.
   nsAutoPopupStatePusher popupStatePusher(openAbused, true);
 
@@ -7491,16 +7493,18 @@ nsGlobalWindow::PrintOuter(ErrorResult& 
 
 #ifdef NS_PRINTING
   if (Preferences::GetBool("dom.disable_window_print", false)) {
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
 
   if (!AreDialogsEnabled()) {
+    // We probably want to keep throwing here; silently doing nothing is a bit
+    // weird given the typical use cases of print().
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
 
   if (ShouldPromptToBlockDialogs() && !ConfirmDialogIfNeeded()) {
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
@@ -9548,16 +9552,18 @@ nsGlobalWindow::ShowModalDialogOuter(con
   nsRefPtr<DialogValueHolder> argHolder =
     new DialogValueHolder(nsContentUtils::SubjectPrincipal(), aArgument);
 
   // Before bringing up the window/dialog, unsuppress painting and flush
   // pending reflows.
   EnsureReflowFlushAndPaint();
 
   if (!AreDialogsEnabled()) {
+    // We probably want to keep throwing here; silently doing nothing is a bit
+    // weird given the typical use cases of showModalDialog().
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
   if (ShouldPromptToBlockDialogs() && !ConfirmDialogIfNeeded()) {
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -515,19 +515,19 @@ nsClipboardCommand::DoCommand(const char
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   nsIDocShell *docShell = window->GetDocShell();
   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
-  EventMessage eventMessage = NS_COPY;
+  EventMessage eventMessage = eCopy;
   if (strcmp(aCommandName, "cmd_cut") == 0) {
-    eventMessage = NS_CUT;
+    eventMessage = eCut;
   }
 
   bool actionTaken = false;
   nsCopySupport::FireClipboardEvent(eventMessage,
                                     nsIClipboard::kGlobalClipboard,
                                     presShell, nullptr, &actionTaken);
 
   if (!strcmp(aCommandName, "cmd_copyAndCollapseToEnd")) {
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
@@ -7,16 +7,17 @@
 #include "base/basictypes.h"
 #include "BluetoothPbapManager.h"
 
 #include "BluetoothService.h"
 #include "BluetoothSocket.h"
 #include "BluetoothUuid.h"
 #include "ObexBase.h"
 
+#include "mozilla/dom/BluetoothPbapParametersBinding.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIInputStream.h"
 #include "nsIObserver.h"
@@ -522,122 +523,82 @@ BluetoothPbapManager::PullvCardEntry(con
 
 void
 BluetoothPbapManager::AppendBtNamedValueByTagId(
   const ObexHeaderSet& aHeader,
   InfallibleTArray<BluetoothNamedValue>& aValues,
   const AppParameterTag aTagId)
 {
   uint8_t buf[64];
+  if (!aHeader.GetAppParameter(aTagId, buf, 64)) {
+    return;
+  }
 
   switch (aTagId) {
     case AppParameterTag::Order: {
-      if (!aHeader.GetAppParameter(AppParameterTag::Order, buf, 64)) {
-        break;
-      }
-
-      static const nsString sOrderStr[] = {NS_LITERAL_STRING("alphanumeric"),
-                                           NS_LITERAL_STRING("indexed"),
-                                           NS_LITERAL_STRING("phonetical")};
-      uint8_t order = buf[0];
-      if (order < MOZ_ARRAY_LENGTH(sOrderStr)) {
-        BT_APPEND_NAMED_VALUE(aValues, "order", sOrderStr[order]);
-      } else {
-        BT_LOGR("Unexpected value %d of 'Order'", order);
-      }
+      using namespace mozilla::dom::vCardOrderTypeValues;
+      uint32_t order = buf[0] < ArrayLength(strings) ? (uint32_t) buf[0]
+                                                     : 0; // default: indexed
+      BT_APPEND_NAMED_VALUE(aValues, "order", order);
+      break;
+    }
+    case AppParameterTag::SearchProperty: {
+      using namespace mozilla::dom::vCardSearchKeyTypeValues;
+      uint32_t searchKey = buf[0] < ArrayLength(strings) ? (uint32_t) buf[0]
+                                                         : 0; // default: name
+      BT_APPEND_NAMED_VALUE(aValues, "searchKey", searchKey);
       break;
     }
     case AppParameterTag::SearchValue: {
-      if (!aHeader.GetAppParameter(AppParameterTag::SearchValue, buf, 64)) {
-        break;
-      }
-
       // Section 5.3.4.3 "SearchValue {<text string>}", PBAP 1.2
       // The UTF-8 character set shall be used for <text string>.
 
       // Use nsCString to store UTF-8 string here to follow the suggestion of
       // 'MDN:Internal_strings'.
       nsCString text((char *) buf);
 
       BT_APPEND_NAMED_VALUE(aValues, "searchText", text);
       break;
     }
-    case AppParameterTag::SearchProperty: {
-      if (!aHeader.GetAppParameter(AppParameterTag::SearchProperty, buf, 64)) {
-        break;
-      }
-
-      static const nsString sSearchKeyStr[] = {NS_LITERAL_STRING("name"),
-                                               NS_LITERAL_STRING("number"),
-                                               NS_LITERAL_STRING("sound")};
-      uint8_t searchKey = buf[0];
-      if (searchKey < MOZ_ARRAY_LENGTH(sSearchKeyStr)) {
-        BT_APPEND_NAMED_VALUE(aValues, "searchKey", sSearchKeyStr[searchKey]);
-      } else {
-        BT_LOGR("Unexpected value %d of 'SearchProperty'", searchKey);
-      }
-      break;
-    }
     case AppParameterTag::MaxListCount: {
-      if (!aHeader.GetAppParameter(AppParameterTag::MaxListCount, buf, 64)) {
-        break;
-      }
-
       uint16_t maxListCount = *((uint16_t *)buf);
 
       // convert big endian to little endian
       maxListCount = (maxListCount >> 8) | (maxListCount << 8);
 
       // Section 5 "Phone Book Access Profile Functions", PBAP 1.2
       // Replying 'PhonebookSize' is mandatory if 'MaxListCount' parameter is
       // present in the request with a value of 0, else it is excluded.
       mPhonebookSizeRequired = !maxListCount;
 
       BT_APPEND_NAMED_VALUE(aValues, "maxListCount", (uint32_t) maxListCount);
       break;
     }
     case AppParameterTag::ListStartOffset: {
-      if (!aHeader.GetAppParameter(AppParameterTag::ListStartOffset, buf, 64)) {
-        break;
-      }
-
       uint16_t listStartOffset = *((uint16_t *)buf);
 
       // convert big endian to little endian
       listStartOffset = (listStartOffset >> 8) | (listStartOffset << 8);
 
       BT_APPEND_NAMED_VALUE(aValues, "listStartOffset",
                            (uint32_t) listStartOffset);
       break;
     }
     case AppParameterTag::PropertySelector: {
-      if (!aHeader.GetAppParameter(
-          AppParameterTag::PropertySelector, buf, 64)) {
-        break;
-      }
-
       InfallibleTArray<uint32_t> props = PackPropertiesMask(buf, 64);
 
       BT_APPEND_NAMED_VALUE(aValues, "propSelector", props);
       break;
     }
     case AppParameterTag::Format: {
-      if (!aHeader.GetAppParameter(AppParameterTag::Format, buf, 64)) {
-        break;
-      }
-
       bool usevCard3 = buf[0];
       BT_APPEND_NAMED_VALUE(aValues, "format", usevCard3);
       break;
     }
     case AppParameterTag::vCardSelector: {
-      if (!aHeader.GetAppParameter(AppParameterTag::vCardSelector, buf, 64)) {
-        break;
-      }
-
       InfallibleTArray<uint32_t> props = PackPropertiesMask(buf, 64);
 
       bool hasVCardSelectorOperator = aHeader.GetAppParameter(
         AppParameterTag::vCardSelectorOperator, buf, 64);
 
       if (hasVCardSelectorOperator && buf[0]) {
         BT_APPEND_NAMED_VALUE(aValues, "vCardSelector_AND",
                               BluetoothValue(props));
--- a/dom/bluetooth/common/webapi/BluetoothAdapter.cpp
+++ b/dom/bluetooth/common/webapi/BluetoothAdapter.cpp
@@ -1290,21 +1290,21 @@ BluetoothAdapter::HandlePullVCardListing
   BluetoothVCardListingEventInit init;
 
   for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) {
     const nsString& name = arr[i].name();
     const BluetoothValue& value = arr[i].value();
     if (name.EqualsLiteral("name")) {
       init.mName = value.get_nsString();
     } else if (name.EqualsLiteral("order")) {
-      init.mOrder = ConvertStringToVCardOrderType(value.get_nsString());
+      init.mOrder = static_cast<vCardOrderType>(value.get_uint32_t());
+    } else if (name.EqualsLiteral("searchKey")) {
+      init.mSearchKey = static_cast<vCardSearchKeyType>(value.get_uint32_t());
     } else if (name.EqualsLiteral("searchText")) {
       init.mSearchValue = value.get_nsString();
-    } else if (name.EqualsLiteral("searchKey")) {
-      init.mSearchKey = ConvertStringToVCardSearchKeyType(value.get_nsString());
     } else if (name.EqualsLiteral("maxListCount")) {
       init.mMaxListCount = value.get_uint32_t();
     } else if (name.EqualsLiteral("listStartOffset")) {
       init.mListStartOffset = value.get_uint32_t();
     } else if (name.EqualsLiteral("vCardSelector_AND")) {
       init.mVcardSelector = getVCardProperties(value);
       init.mVcardSelectorOperator = vCardSelectorOp::AND;
     } else if (name.EqualsLiteral("vCardSelector_OR")) {
@@ -1333,50 +1333,16 @@ BluetoothAdapter::getVCardProperties(con
   for (uint32_t i = 0; i < propSelectorArr.Length(); ++i) {
     propSelector.AppendElement(
       static_cast<vCardProperties>(propSelectorArr[i]), mozilla::fallible);
   }
 
   return propSelector;
 }
 
-vCardOrderType
-BluetoothAdapter::ConvertStringToVCardOrderType(const nsAString& aString)
-{
-  using namespace mozilla::dom::vCardOrderTypeValues;
-
-  for (size_t index = 0; index < ArrayLength(strings) - 1; index++) {
-    if (aString.LowerCaseEqualsASCII(strings[index].value,
-                                     strings[index].length)) {
-      return static_cast<vCardOrderType>(index);
-    }
-  }
-
-  BT_WARNING("Treat the unexpected string '%s' as vCardOrderType::Indexed",
-    NS_ConvertUTF16toUTF8(aString).get());
-  return vCardOrderType::Indexed; // The default value is 'Indexed'.
-}
-
-vCardSearchKeyType
-BluetoothAdapter::ConvertStringToVCardSearchKeyType(const nsAString& aString)
-{
-  using namespace mozilla::dom::vCardSearchKeyTypeValues;
-
-  for (size_t index = 0; index < ArrayLength(strings) - 1; index++) {
-    if (aString.LowerCaseEqualsASCII(strings[index].value,
-                                     strings[index].length)) {
-      return static_cast<vCardSearchKeyType>(index);
-    }
-  }
-
-  BT_WARNING("Treat the unexpected string '%s' as vCardSearchKeyType::Name",
-    NS_ConvertUTF16toUTF8(aString).get());
-  return vCardSearchKeyType::Name; // The default value is 'Name'.
-}
-
 void
 BluetoothAdapter::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
 {
   MOZ_ASSERT(!aTypes.IsEmpty());
 
   BluetoothAttributeEventInit init;
   init.mAttrs = aTypes;
 
--- a/dom/bluetooth/common/webapi/BluetoothAdapter.h
+++ b/dom/bluetooth/common/webapi/BluetoothAdapter.h
@@ -338,31 +338,16 @@ private:
    *
    * @param aValue [in] a BluetoothValue with 'TArrayOfuint32_t' type
    *                    The name of BluetoothValue must be 'propSelector',
    *                    'vCardSelector_OR' or 'vCardSelector_AND'.
    */
   Sequence<vCardProperties> getVCardProperties(const BluetoothValue &aValue);
 
   /**
-   * Convert string to vCardOrderType.
-   *
-   * @param aString [in] String to convert
-   */
-  vCardOrderType ConvertStringToVCardOrderType(const nsAString& aString);
-
-  /**
-   * Convert string to vCardSearchKeyType.
-   *
-   * @param aString [in] String to convert
-   */
-  vCardSearchKeyType ConvertStringToVCardSearchKeyType(
-    const nsAString& aString);
-
-  /**
    * Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
    *
    * @param aTypes [in] Array of changed attributes. Must be non-empty.
    */
   void DispatchAttributeEvent(const Sequence<nsString>& aTypes);
 
   /**
    * Fire BluetoothDeviceEvent to trigger
--- a/dom/events/ClipboardEvent.cpp
+++ b/dom/events/ClipboardEvent.cpp
@@ -74,17 +74,17 @@ ClipboardEvent::Constructor(const Global
 
   nsRefPtr<DataTransfer> clipboardData;
   if (e->mEventIsInternal) {
     InternalClipboardEvent* event = e->mEvent->AsClipboardEvent();
     if (event) {
       // Always create a clipboardData for the copy event. If this is changed to
       // support other types of events, make sure that read/write privileges are
       // checked properly within DataTransfer.
-      clipboardData = new DataTransfer(ToSupports(e), NS_COPY, false, -1);
+      clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1);
       clipboardData->SetData(aParam.mDataType, aParam.mData);
     }
   }
 
   e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable,
                         clipboardData, aRv);
   e->SetTrusted(trusted);
   return e.forget();
@@ -100,21 +100,21 @@ ClipboardEvent::GetClipboardData(nsIDOMD
 DataTransfer*
 ClipboardEvent::GetClipboardData()
 {
   InternalClipboardEvent* event = mEvent->AsClipboardEvent();
 
   if (!event->clipboardData) {
     if (mEventIsInternal) {
       event->clipboardData =
-        new DataTransfer(ToSupports(this), NS_COPY, false, -1);
+        new DataTransfer(ToSupports(this), eCopy, false, -1);
     } else {
       event->clipboardData =
         new DataTransfer(ToSupports(this), event->mMessage,
-                         event->mMessage == NS_PASTE,
+                         event->mMessage == ePaste,
                          nsIClipboard::kGlobalClipboard);
     }
   }
 
   return event->clipboardData;
 }
 
 } // namespace dom
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -81,23 +81,23 @@ DataTransfer::DataTransfer(nsISupports* 
   , mIsCrossDomainSubFrameDrop(false)
   , mClipboardType(aClipboardType)
   , mDragImageX(0)
   , mDragImageY(0)
 {
   // For these events, we want to be able to add data to the data transfer, so
   // clear the readonly state. Otherwise, the data is already present. For
   // external usage, cache the data from the native clipboard or drag.
-  if (aEventMessage == NS_CUT ||
-      aEventMessage == NS_COPY ||
+  if (aEventMessage == eCut ||
+      aEventMessage == eCopy ||
       aEventMessage == eDragStart ||
       aEventMessage == eLegacyDragGesture) {
     mReadOnly = false;
   } else if (mIsExternal) {
-    if (aEventMessage == NS_PASTE) {
+    if (aEventMessage == ePaste) {
       CacheExternalClipboardFormats();
     } else if (aEventMessage >= eDragDropEventFirst &&
                aEventMessage <= eDragDropEventLast) {
       CacheExternalDragFormats();
     }
   }
 }
 
@@ -266,17 +266,17 @@ DataTransfer::GetMozUserCancelled(bool* 
   return NS_OK;
 }
 
 FileList*
 DataTransfer::GetFiles(ErrorResult& aRv)
 {
   if (mEventMessage != eDrop &&
       mEventMessage != eLegacyDragDrop &&
-      mEventMessage != NS_PASTE) {
+      mEventMessage != ePaste) {
     return nullptr;
   }
 
   if (!mFiles) {
     mFiles = new FileList(static_cast<nsIDOMDataTransfer*>(this));
 
     uint32_t count = mItems.Length();
 
@@ -538,18 +538,18 @@ DataTransfer::GetMozSourceNode(nsIDOMNod
   return CallQueryInterface(sourceNode, aSourceNode);
 }
 
 already_AddRefed<DOMStringList>
 DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv)
 {
   // Only the first item is valid for clipboard events
   if (aIndex > 0 &&
-      (mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
-       mEventMessage == NS_PASTE)) {
+      (mEventMessage == eCut || mEventMessage == eCopy ||
+       mEventMessage == ePaste)) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
   }
 
   nsRefPtr<DOMStringList> types = new DOMStringList();
   if (aIndex < mItems.Length()) {
     // note that you can retrieve the types regardless of their principal
     nsTArray<TransferItem>& item = mItems[aIndex];
@@ -579,18 +579,18 @@ DataTransfer::MozGetDataAt(const nsAStri
     return NS_OK;
 
   if (aIndex >= mItems.Length()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Only the first item is valid for clipboard events
   if (aIndex > 0 &&
-      (mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
-       mEventMessage == NS_PASTE)) {
+      (mEventMessage == eCut || mEventMessage == eCopy ||
+       mEventMessage == ePaste)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
 
   nsAutoString format;
   GetRealFormat(aFormat, format);
 
   nsTArray<TransferItem>& item = mItems[aIndex];
@@ -599,17 +599,17 @@ DataTransfer::MozGetDataAt(const nsAStri
   // chrome privileges can always read the data. During the
   // drop event, allow retrieving the data except in the case where the
   // source of the drag is in a child frame of the caller. In that case,
   // we only allow access to data of the same principal. During other events,
   // only allow access to the data with the same principal.
   nsIPrincipal* principal = nullptr;
   if (mIsCrossDomainSubFrameDrop ||
       (mEventMessage != eDrop && mEventMessage != eLegacyDragDrop &&
-       mEventMessage != NS_PASTE &&
+       mEventMessage != ePaste &&
        !nsContentUtils::IsCallerChrome())) {
     principal = nsContentUtils::SubjectPrincipal();
   }
 
   uint32_t count = item.Length();
   for (uint32_t i = 0; i < count; i++) {
     TransferItem& formatitem = item[i];
     if (formatitem.mFormat.Equals(format)) {
@@ -691,18 +691,18 @@ DataTransfer::MozSetDataAt(const nsAStri
   // Specifying an index less than the current length will replace an existing
   // item. Specifying an index equal to the current length will add a new item.
   if (aIndex > mItems.Length()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Only the first item is valid for clipboard events
   if (aIndex > 0 &&
-      (mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
-       mEventMessage == NS_PASTE)) {
+      (mEventMessage == eCut || mEventMessage == eCopy ||
+       mEventMessage == ePaste)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // don't allow non-chrome to add file data
   // XXX perhaps this should also limit any non-string type as well
   if ((aFormat.EqualsLiteral("application/x-moz-file-promise") ||
        aFormat.EqualsLiteral("application/x-moz-file")) &&
        !nsContentUtils::IsCallerChrome()) {
@@ -737,34 +737,34 @@ DataTransfer::MozClearDataAt(const nsASt
 
   if (aIndex >= mItems.Length()) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return;
   }
 
   // Only the first item is valid for clipboard events
   if (aIndex > 0 &&
-      (mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
-       mEventMessage == NS_PASTE)) {
+      (mEventMessage == eCut || mEventMessage == eCopy ||
+       mEventMessage == ePaste)) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return;
   }
 
   MozClearDataAtHelper(aFormat, aIndex, aRv);
 }
 
 void
 DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
                                    ErrorResult& aRv)
 {
   MOZ_ASSERT(!mReadOnly);
   MOZ_ASSERT(aIndex < mItems.Length());
   MOZ_ASSERT(aIndex == 0 ||
-             (mEventMessage != NS_CUT && mEventMessage != NS_COPY &&
-              mEventMessage != NS_PASTE));
+             (mEventMessage != eCut && mEventMessage != eCopy &&
+              mEventMessage != ePaste));
 
   nsAutoString format;
   GetRealFormat(aFormat, format);
 
   nsIPrincipal* principal = nsContentUtils::SubjectPrincipal();
 
   // if the format is empty, clear all formats
   bool clearall = format.IsEmpty();
@@ -1253,17 +1253,17 @@ DataTransfer::CacheExternalDragFormats()
       }
     }
   }
 }
 
 void
 DataTransfer::CacheExternalClipboardFormats()
 {
-  NS_ASSERTION(mEventMessage == NS_PASTE,
+  NS_ASSERTION(mEventMessage == ePaste,
                "caching clipboard data for invalid event");
 
   // Called during the constructor for paste events to cache the formats
   // available on the clipboard. As with CacheExternalDragFormats, the
   // data will only be retrieved when needed.
 
   nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
   if (!clipboard || mClipboardType < 0) {
@@ -1295,17 +1295,17 @@ DataTransfer::FillInExternalData(Transfe
 {
   NS_PRECONDITION(mIsExternal, "Not an external data transfer");
 
   if (aItem.mData) {
     return;
   }
 
   // only drag and paste events should be calling FillInExternalData
-  NS_ASSERTION(mEventMessage != NS_CUT && mEventMessage != NS_COPY,
+  NS_ASSERTION(mEventMessage != eCut && mEventMessage != eCopy,
                "clipboard event with empty data");
 
     NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat);
     const char* format = utf8format.get();
     if (strcmp(format, "text/plain") == 0)
       format = kUnicodeMime;
     else if (strcmp(format, "text/uri-list") == 0)
       format = kURLDataMime;
@@ -1313,17 +1313,17 @@ DataTransfer::FillInExternalData(Transfe
     nsCOMPtr<nsITransferable> trans =
       do_CreateInstance("@mozilla.org/widget/transferable;1");
     if (!trans)
       return;
 
   trans->Init(nullptr);
   trans->AddDataFlavor(format);
 
-  if (mEventMessage == NS_PASTE) {
+  if (mEventMessage == ePaste) {
     MOZ_ASSERT(aIndex == 0, "index in clipboard must be 0");
 
     nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
     if (!clipboard || mClipboardType < 0) {
       return;
     }
 
     clipboard->GetData(trans, mClipboardType);
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -148,21 +148,21 @@
 #define DEFINED_BEFOREUNLOAD_EVENT
 #endif /* BEFOREUNLOAD_EVENT */
 
 EVENT(abort,
       eImageAbort,
       EventNameType_All,
       eBasicEventClass)
 EVENT(canplay,
-      NS_CANPLAY,
+      eCanPlay,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(canplaythrough,
-      NS_CANPLAYTHROUGH,
+      eCanPlayThrough,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(change,
       eFormChange,
       EventNameType_HTMLXUL,
       eBasicEventClass)
 EVENT(click,
       eMouseClick,
@@ -202,25 +202,25 @@ EVENT(dragstart,
       eDragStart,
       EventNameType_HTMLXUL,
       eDragEventClass)
 EVENT(drop,
       eDrop,
       EventNameType_HTMLXUL,
       eDragEventClass)
 EVENT(durationchange,
-      NS_DURATIONCHANGE,
+      eDurationChange,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(emptied,
-      NS_EMPTIED,
+      eEmptied,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(ended,
-      NS_ENDED,
+      eEnded,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(input,
       NS_EDITOR_INPUT,
       EventNameType_HTMLXUL,
       eEditorInputEventClass)
 EVENT(invalid,
       eFormInvalid,
@@ -250,25 +250,25 @@ NON_IDL_EVENT(mozbrowserbeforekeyup,
               eBeforeKeyUp,
               EventNameType_None,
               eBeforeAfterKeyboardEventClass)
 NON_IDL_EVENT(mozbrowserafterkeyup,
               eAfterKeyUp,
               EventNameType_None,
               eBeforeAfterKeyboardEventClass)
 EVENT(loadeddata,
-      NS_LOADEDDATA,
+      eLoadedData,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(loadedmetadata,
-      NS_LOADEDMETADATA,
+      eLoadedMetaData,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(loadstart,
-      NS_LOADSTART,
+      eLoadStart,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(mousedown,
       eMouseDown,
       EventNameType_All,
       eMouseEventClass)
 EVENT(mouseenter,
       eMouseEnter,
@@ -349,93 +349,93 @@ EVENT(gotpointercapture,
 EVENT(lostpointercapture,
       ePointerLostCapture,
       EventNameType_All,
       ePointerEventClass)
 
 // Not supported yet; probably never because "wheel" is a better idea.
 // EVENT(mousewheel)
 EVENT(pause,
-      NS_PAUSE,
+      ePause,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(play,
-      NS_PLAY,
+      ePlay,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(playing,
-      NS_PLAYING,
+      ePlaying,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(progress,
-      NS_PROGRESS,
+      eProgress,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(ratechange,
-      NS_RATECHANGE,
+      eRateChange,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(reset,
       eFormReset,
       EventNameType_HTMLXUL,
       eBasicEventClass)
 EVENT(seeked,
-      NS_SEEKED,
+      eSeeked,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(seeking,
-      NS_SEEKING,
+      eSeeking,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(select,
       eFormSelect,
       EventNameType_HTMLXUL,
       eBasicEventClass)
 EVENT(show,
       NS_SHOW_EVENT,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(stalled,
-      NS_STALLED,
+      eStalled,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(submit,
       eFormSubmit,
       EventNameType_HTMLXUL,
       eBasicEventClass)
 EVENT(suspend,
-      NS_SUSPEND,
+      eSuspend,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(timeupdate,
-      NS_TIMEUPDATE,
+      eTimeUpdate,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(volumechange,
-      NS_VOLUMECHANGE,
+      eVolumeChange,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(waiting,
-      NS_WAITING,
+      eWaiting,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(wheel,
       NS_WHEEL_WHEEL,
       EventNameType_All,
       eWheelEventClass)
 EVENT(copy,
-      NS_COPY,
+      eCopy,
       EventNameType_HTMLXUL,
       eClipboardEventClass)
 EVENT(cut,
-      NS_CUT,
+      eCut,
       EventNameType_HTMLXUL,
       eClipboardEventClass)
 EVENT(paste,
-      NS_PASTE,
+      ePaste,
       EventNameType_HTMLXUL,
       eClipboardEventClass)
 // Gecko-specific extensions that apply to elements
 EVENT(beforescriptexecute,
       NS_BEFORE_SCRIPT_EXECUTE,
       EventNameType_HTMLXUL,
       eBasicEventClass)
 EVENT(afterscriptexecute,
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -738,17 +738,17 @@ EventStateManager::PreHandleEvent(nsPres
       // Init lineOrPageDelta values for line scroll events for some devices
       // on some platforms which might dispatch wheel events which don't have
       // lineOrPageDelta values.  And also, if delta values are customized by
       // prefs, this recomputes them.
       DeltaAccumulator::GetInstance()->
         InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
     }
     break;
-  case NS_SELECTION_SET:
+  case eSetSelection:
     IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
                                           aEvent->AsSelectionEvent());
     break;
   case NS_CONTENT_COMMAND_CUT:
   case NS_CONTENT_COMMAND_COPY:
   case NS_CONTENT_COMMAND_PASTE:
   case NS_CONTENT_COMMAND_DELETE:
   case NS_CONTENT_COMMAND_UNDO:
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -144,18 +144,18 @@ GetEventMessageName(EventMessage aMessag
     case NS_COMPOSITION_UPDATE:
       return "NS_COMPOSITION_UPDATE";
     case NS_COMPOSITION_CHANGE:
       return "NS_COMPOSITION_CHANGE";
     case NS_COMPOSITION_COMMIT_AS_IS:
       return "NS_COMPOSITION_COMMIT_AS_IS";
     case NS_COMPOSITION_COMMIT:
       return "NS_COMPOSITION_COMMIT";
-    case NS_SELECTION_SET:
-      return "NS_SELECTION_SET";
+    case eSetSelection:
+      return "eSetSelection";
     default:
       return "unacceptable event message";
   }
 }
 
 static const char*
 GetNotifyIMEMessageName(IMEMessage aMessage)
 {
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -286,24 +286,17 @@ MediaDecoderStateMachine::MediaDecoderSt
 
   mAudioQueueListener = AudioQueue().PopEvent().Connect(
     mTaskQueue, this, &MediaDecoderStateMachine::OnAudioPopped);
   mVideoQueueListener = VideoQueue().PopEvent().Connect(
     mTaskQueue, this, &MediaDecoderStateMachine::OnVideoPopped);
 
   mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread());
 
-  nsRefPtr<MediaDecoderStateMachine> self = this;
-  auto audioSinkCreator = [self] () {
-    MOZ_ASSERT(self->OnTaskQueue());
-    return new DecodedAudioDataSink(
-      self->mAudioQueue, self->GetMediaTime(),
-      self->mInfo.mAudio, self->mDecoder->GetAudioChannel());
-  };
-  mAudioSink = new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
+  mMediaSink = CreateAudioSink();
 }
 
 MediaDecoderStateMachine::~MediaDecoderStateMachine()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
   MOZ_COUNT_DTOR(MediaDecoderStateMachine);
 
   mReader = nullptr;
@@ -343,16 +336,29 @@ MediaDecoderStateMachine::Initialization
   mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
   mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
   mWatchManager.Watch(mSameOriginMedia, &MediaDecoderStateMachine::SameOriginMediaChanged);
 
   // Propagate mSameOriginMedia to mDecodedStream.
   SameOriginMediaChanged();
 }
 
+media::MediaSink*
+MediaDecoderStateMachine::CreateAudioSink()
+{
+  nsRefPtr<MediaDecoderStateMachine> self = this;
+  auto audioSinkCreator = [self] () {
+    MOZ_ASSERT(self->OnTaskQueue());
+    return new DecodedAudioDataSink(
+      self->mAudioQueue, self->GetMediaTime(),
+      self->mInfo.mAudio, self->mDecoder->GetAudioChannel());
+  };
+  return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
+}
+
 bool MediaDecoderStateMachine::HasFutureAudio()
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
   NS_ASSERTION(HasAudio(), "Should only call HasFutureAudio() when we have audio");
   // We've got audio ready to play if:
   // 1. We've not completed playback of audio, and
   // 2. we either have more than the threshold of decoded audio available, or
@@ -372,27 +378,26 @@ bool MediaDecoderStateMachine::HaveNextF
          (!HasVideo() || VideoQueue().GetSize() > 1);
 }
 
 int64_t MediaDecoderStateMachine::GetDecodedAudioDuration()
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
   int64_t audioDecoded = AudioQueue().Duration();
-  if (mAudioSink->IsStarted()) {
+  if (mMediaSink->IsStarted()) {
     audioDecoded += AudioEndTime() - GetMediaTime();
   }
   return audioDecoded;
 }
 
 void MediaDecoderStateMachine::DiscardStreamData()
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
-  MOZ_ASSERT(!mAudioSink->IsStarted(), "Should've been stopped in RunStateMachine()");
 
   const auto clockTime = GetClock();
   while (true) {
     const MediaData* a = AudioQueue().PeekFront();
 
     // If we discard audio samples fed to the stream immediately, we will
     // keep decoding audio samples till the end and consume a lot of memory.
     // Therefore we only discard those behind the stream clock to throttle
@@ -1072,18 +1077,17 @@ void MediaDecoderStateMachine::MaybeStar
   }
 
   DECODER_LOG("MaybeStartPlayback() starting playback");
 
   mDecoder->DispatchPlaybackStarted();
   SetPlayStartTime(TimeStamp::Now());
   MOZ_ASSERT(IsPlaying());
 
-  StartAudioSink();
-  StartDecodedStream();
+  StartMediaSink();
 
   DispatchDecodeTasksIfNeeded();
 }
 
 void MediaDecoderStateMachine::UpdatePlaybackPositionInternal(int64_t aTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   SAMPLE_LOG("UpdatePlaybackPositionInternal(%lld)", aTime);
@@ -1147,18 +1151,17 @@ void MediaDecoderStateMachine::SetState(
   // Clear state-scoped state.
   mSentPlaybackEndedEvent = false;
 }
 
 void MediaDecoderStateMachine::VolumeChanged()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  mAudioSink->SetVolume(mVolume);
-  mStreamSink->SetVolume(mVolume);
+  mMediaSink->SetVolume(mVolume);
 }
 
 void MediaDecoderStateMachine::RecomputeDuration()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   TimeUnit duration;
@@ -1268,17 +1271,17 @@ void MediaDecoderStateMachine::Shutdown(
   mCurrentSeek.RejectIfExists(__func__);
 
   if (IsPlaying()) {
     StopPlayback();
   }
 
   Reset();
 
-  mAudioSink->Shutdown();
+  mMediaSink->Shutdown();
 
   // Shut down our start time rendezvous.
   if (mStartTimeRendezvous) {
     mStartTimeRendezvous->Destroy();
   }
 
   // Put a task in the decode queue to shutdown the reader.
   // the queue to spin down.
@@ -1461,25 +1464,25 @@ MediaDecoderStateMachine::Seek(SeekTarge
 
   DECODER_LOG("Changed state to SEEKING (to %lld)", mPendingSeek.mTarget.mTime);
   SetState(DECODER_STATE_SEEKING);
   ScheduleStateMachine();
 
   return mPendingSeek.mPromise.Ensure(__func__);
 }
 
-void MediaDecoderStateMachine::StopAudioSink()
+void MediaDecoderStateMachine::StopMediaSink()
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
 
-  if (mAudioSink->IsStarted()) {
-    DECODER_LOG("Stop AudioSink");
-    mAudioSink->Stop();
-    mAudioSinkPromise.DisconnectIfExists();
+  if (mMediaSink->IsStarted()) {
+    DECODER_LOG("Stop MediaSink");
+    mMediaSink->Stop();
+    mMediaSinkPromise.DisconnectIfExists();
   }
 }
 
 void
 MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
@@ -1747,78 +1750,44 @@ MediaDecoderStateMachine::RequestVideoDa
       ->CompletionPromise()
       ->Then(OwnerThread(), __func__, this,
              &MediaDecoderStateMachine::OnVideoDecoded,
              &MediaDecoderStateMachine::OnVideoNotDecoded));
   }
 }
 
 void
-MediaDecoderStateMachine::StartAudioSink()
+MediaDecoderStateMachine::StartMediaSink()
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
-  if (mAudioCaptured) {
-    MOZ_ASSERT(!mAudioSink->IsStarted());
-    return;
-  }
-
-  if (!mAudioSink->IsStarted()) {
+
+  if (!mMediaSink->IsStarted()) {
     mAudioCompleted = false;
-    mAudioSink->Start(GetMediaTime(), mInfo);
-
-    auto promise = mAudioSink->OnEnded(TrackInfo::kAudioTrack);
+    mMediaSink->Start(GetMediaTime(), mInfo);
+
+    auto promise = mMediaSink->OnEnded(TrackInfo::kAudioTrack);
     if (promise) {
-      mAudioSinkPromise.Begin(promise->Then(
+      mMediaSinkPromise.Begin(promise->Then(
         OwnerThread(), __func__, this,
-        &MediaDecoderStateMachine::OnAudioSinkComplete,
-        &MediaDecoderStateMachine::OnAudioSinkError));
+        &MediaDecoderStateMachine::OnMediaSinkComplete,
+        &MediaDecoderStateMachine::OnMediaSinkError));
     }
   }
 }
 
-void
-MediaDecoderStateMachine::StopDecodedStream()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  AssertCurrentThreadInMonitor();
-
-  if (mStreamSink->IsStarted()) {
-    mStreamSink->Stop();
-    mDecodedStreamPromise.DisconnectIfExists();
-  }
-}
-
-void
-MediaDecoderStateMachine::StartDecodedStream()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  AssertCurrentThreadInMonitor();
-
-  // Tell DecodedStream to start playback with specified start time and media
-  // info. This is consistent with how we create AudioSink in StartAudioThread().
-  if (mAudioCaptured && !mStreamSink->IsStarted()) {
-    mStreamSink->Start(GetMediaTime(), mInfo);
-    mDecodedStreamPromise.Begin(
-      mStreamSink->OnEnded(TrackInfo::kAudioTrack)->Then(
-        OwnerThread(), __func__, this,
-        &MediaDecoderStateMachine::OnDecodedStreamFinish,
-        &MediaDecoderStateMachine::OnDecodedStreamError));
-  }
-}
-
 int64_t MediaDecoderStateMachine::AudioDecodedUsecs()
 {
   MOZ_ASSERT(OnTaskQueue());
   NS_ASSERTION(HasAudio(),
                "Should only call AudioDecodedUsecs() when we have audio");
   // The amount of audio we have decoded is the amount of audio data we've
   // already decoded and pushed to the hardware, plus the amount of audio
   // data waiting to be pushed to the hardware.
-  int64_t pushed = mAudioSink->IsStarted() ? (AudioEndTime() - GetMediaTime()) : 0;
+  int64_t pushed = mMediaSink->IsStarted() ? (AudioEndTime() - GetMediaTime()) : 0;
 
   // Currently for real time streams, AudioQueue().Duration() produce
   // wrong values (Bug 1114434), so we use frame counts to calculate duration.
   if (IsRealTime()) {
     return pushed + FramesToUsecs(AudioQueue().FrameCount(), mInfo.mAudio.mRate).value();
   }
   return pushed + AudioQueue().Duration();
 }
@@ -1837,17 +1806,17 @@ bool MediaDecoderStateMachine::HasLowDec
           static_cast<uint32_t>(VideoQueue().GetSize()) < LOW_VIDEO_FRAMES));
 }
 
 bool MediaDecoderStateMachine::OutOfDecodedAudio()
 {
     MOZ_ASSERT(OnTaskQueue());
     return IsAudioDecoding() && !AudioQueue().IsFinished() &&
            AudioQueue().GetSize() == 0 &&
-           !mAudioSink->HasUnplayedFrames(TrackInfo::kAudioTrack);
+           !mMediaSink->HasUnplayedFrames(TrackInfo::kAudioTrack);
 }
 
 bool MediaDecoderStateMachine::HasLowUndecodedData()
 {
   MOZ_ASSERT(OnTaskQueue());
   return HasLowUndecodedData(mLowDataThresholdUsecs);
 }
 
@@ -2411,18 +2380,17 @@ nsresult MediaDecoderStateMachine::RunSt
 
         nsCOMPtr<nsIRunnable> event =
           NS_NewRunnableMethod(mDecoder, &MediaDecoder::PlaybackEnded);
         AbstractThread::MainThread()->Dispatch(event.forget());
 
         mSentPlaybackEndedEvent = true;
 
         // MediaSink::GetEndTime() must be called before stopping playback.
-        StopAudioSink();
-        StopDecodedStream();
+        StopMediaSink();
       }
 
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
@@ -2438,21 +2406,20 @@ MediaDecoderStateMachine::Reset()
   // dormant state. We could also be in the process of going dormant, and have
   // just switched to exiting dormant before we finished entering dormant,
   // hence the DECODING_NONE case below.
   MOZ_ASSERT(IsShutdown() ||
              mState == DECODER_STATE_SEEKING ||
              mState == DECODER_STATE_DORMANT ||
              mState == DECODER_STATE_DECODING_NONE);
 
-  // Stop the audio thread. Otherwise, AudioSink might be accessing AudioQueue
+  // Stop the audio thread. Otherwise, MediaSink might be accessing AudioQueue
   // outside of the decoder monitor while we are clearing the queue and causes
   // crash for no samples to be popped.
-  StopAudioSink();
-  StopDecodedStream();
+  StopMediaSink();
 
   mVideoFrameEndTime = -1;
   mDecodedVideoEndTime = -1;
   mDecodedAudioEndTime = -1;
   mAudioCompleted = false;
   AudioQueue().Reset();
   VideoQueue().Reset();
   mFirstVideoFrameAfterSeek = nullptr;
@@ -2580,21 +2547,17 @@ int64_t MediaDecoderStateMachine::GetClo
   // the end of the audio, use the audio clock. However if we've finished
   // audio, or don't have audio, use the system clock. If our output is being
   // fed to a MediaStream, use that stream as the source of the clock.
   int64_t clock_time = -1;
   TimeStamp t;
   if (!IsPlaying()) {
     clock_time = mPlayDuration;
   } else {
-    if (mAudioCaptured) {
-      clock_time = mStreamSink->GetPosition(&t);
-    } else {
-      clock_time = mAudioSink->GetPosition(&t);
-    }
+    clock_time = mMediaSink->GetPosition(&t);
     NS_ASSERTION(GetMediaTime() <= clock_time, "Clock should go forwards.");
   }
   if (aTimeStamp) {
     *aTimeStamp = t.IsNull() ? TimeStamp::Now() : t;
   }
 
   return clock_time;
 }
@@ -2874,19 +2837,17 @@ void MediaDecoderStateMachine::StartBuff
               stats.mDownloadRate/1024, stats.mDownloadRateReliable ? "" : " (unreliable)");
 }
 
 void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
   mPlayStartTime = aTimeStamp;
-
-  mAudioSink->SetPlaying(!mPlayStartTime.IsNull());
-  mStreamSink->SetPlaying(!mPlayStartTime.IsNull());
+  mMediaSink->SetPlaying(!mPlayStartTime.IsNull());
 }
 
 void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   DispatchAudioDecodeTaskIfNeeded();
   DispatchVideoDecodeTaskIfNeeded();
@@ -2954,170 +2915,142 @@ MediaDecoderStateMachine::LogicalPlaybac
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   if (mLogicalPlaybackRate == 0) {
     // This case is handled in MediaDecoder by pausing playback.
     return;
   }
 
   mPlaybackRate = mLogicalPlaybackRate;
-  mAudioSink->SetPlaybackRate(mPlaybackRate);
+  mMediaSink->SetPlaybackRate(mPlaybackRate);
 
   ScheduleStateMachine();
 }
 
 void MediaDecoderStateMachine::PreservesPitchChanged()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  mAudioSink->SetPreservesPitch(mPreservesPitch);
+  mMediaSink->SetPreservesPitch(mPreservesPitch);
 }
 
 bool MediaDecoderStateMachine::IsShutdown()
 {
   MOZ_ASSERT(OnTaskQueue());
   return mIsShutdown;
 }
 
 int64_t
 MediaDecoderStateMachine::AudioEndTime() const
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
-  if (mAudioSink->IsStarted()) {
-    return mAudioSink->GetEndTime(TrackInfo::kAudioTrack);
-  } else if (mAudioCaptured) {
-    return mStreamSink->GetEndTime(TrackInfo::kAudioTrack);
+  if (mMediaSink->IsStarted()) {
+    return mMediaSink->GetEndTime(TrackInfo::kAudioTrack);
   }
   MOZ_ASSERT(!HasAudio());
   return -1;
 }
 
-void MediaDecoderStateMachine::OnAudioSinkComplete()
+void MediaDecoderStateMachine::OnMediaSinkComplete()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
-
-  mAudioSinkPromise.Complete();
-  mAudioCompleted = true;
+
+  mMediaSinkPromise.Complete();
+  // Set true only when we have audio.
+  mAudioCompleted = mInfo.HasAudio();
+  // To notify PlaybackEnded as soon as possible.
+  ScheduleStateMachine();
 }
 
-void MediaDecoderStateMachine::OnAudioSinkError()
+void MediaDecoderStateMachine::OnMediaSinkError()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
-
-  mAudioSinkPromise.Complete();
-  mAudioCompleted = true;
+
+  mMediaSinkPromise.Complete();
+  // Set true only when we have audio.
+  mAudioCompleted = mInfo.HasAudio();
 
   // Make the best effort to continue playback when there is video.
   if (HasVideo()) {
     return;
   }
 
   // Otherwise notify media decoder/element about this error for it makes
   // no sense to play an audio-only file without sound output.
   DecodeError();
 }
 
 void
-MediaDecoderStateMachine::OnDecodedStreamFinish()
+MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  MOZ_ASSERT(mAudioCaptured, "Audio should be captured.");
-
-  mDecodedStreamPromise.Complete();
-  if (mInfo.HasAudio()) {
-    mAudioCompleted = true;
+
+  if (aCaptured == mAudioCaptured) {
+    return;
   }
-  // To notify PlaybackEnded as soon as possible.
+
+  // Backup current playback parameters.
+  MediaSink::PlaybackParams params = mMediaSink->GetPlaybackParams();
+
+  // Stop and shut down the existing sink.
+  StopMediaSink();
+  mMediaSink->Shutdown();
+
+  // Create a new sink according to whether audio is captured.
+  // TODO: We can't really create a new DecodedStream until OutputStreamManager
+  //       is extracted. It is tricky that the implementation of DecodedStream
+  //       happens to allow reuse after shutdown without creating a new one.
+  mMediaSink = aCaptured ? mStreamSink : CreateAudioSink();
+
+  // Restore playback parameters.
+  mMediaSink->SetPlaybackParams(params);
+
+  // Start the sink if we are already playing. Otherwise it will be
+  // handled in MaybeStartPlayback().
+  if (IsPlaying()) {
+    StartMediaSink();
+  }
+
+  mAudioCaptured = aCaptured;
   ScheduleStateMachine();
 }
 
-void
-MediaDecoderStateMachine::OnDecodedStreamError()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  MOZ_ASSERT(mAudioCaptured, "Audio should be captured.");
-
-  mDecodedStreamPromise.Complete();
-  DecodeError();
-}
-
 uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
   return (mReader->IsAsync() && mReader->VideoIsHardwareAccelerated())
     ? std::max<uint32_t>(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE)
     : std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
 }
 
-void MediaDecoderStateMachine::DispatchAudioCaptured()
-{
-  nsRefPtr<MediaDecoderStateMachine> self = this;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
-  {
-    MOZ_ASSERT(self->OnTaskQueue());
-    ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
-    if (!self->mAudioCaptured) {
-      // Stop the audio sink if it's running.
-      self->StopAudioSink();
-      self->mAudioCaptured = true;
-      // Start DecodedStream if we are already playing. Otherwise it will be
-      // handled in MaybeStartPlayback().
-      if (self->IsPlaying()) {
-        self->StartDecodedStream();
-      }
-      self->ScheduleStateMachine();
-    }
-  });
-  OwnerThread()->Dispatch(r.forget());
-}
-
-void MediaDecoderStateMachine::DispatchAudioUncaptured()
-{
-  nsRefPtr<MediaDecoderStateMachine> self = this;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
-  {
-    MOZ_ASSERT(self->OnTaskQueue());
-    ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
-    if (self->mAudioCaptured) {
-      self->StopDecodedStream();
-      // Start again the audio sink.
-      self->mAudioCaptured = false;
-      if (self->IsPlaying()) {
-        self->StartAudioSink();
-      }
-      self->ScheduleStateMachine();
-    }
-  });
-  OwnerThread()->Dispatch(r.forget());
-}
-
 void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
                                                bool aFinishWhenEnded)
 {
   MOZ_ASSERT(NS_IsMainThread());
   DECODER_LOG("AddOutputStream aStream=%p!", aStream);
   mStreamSink->AddOutput(aStream, aFinishWhenEnded);
-  DispatchAudioCaptured();
+  nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<bool>(
+    this, &MediaDecoderStateMachine::SetAudioCaptured, true);
+  OwnerThread()->Dispatch(r.forget());
 }
 
 void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
 {
   MOZ_ASSERT(NS_IsMainThread());
   DECODER_LOG("RemoveOutputStream=%p!", aStream);
   mStreamSink->RemoveOutput(aStream);
   if (!mStreamSink->HasConsumers()) {
-    DispatchAudioUncaptured();
+    nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<bool>(
+      this, &MediaDecoderStateMachine::SetAudioCaptured, false);
+    OwnerThread()->Dispatch(r.forget());
   }
 }
 
 } // namespace mozilla
 
 // avoid redefined macro in unified build
 #undef LOG
 #undef DECODER_LOG
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -162,18 +162,17 @@ public:
   }
 
 private:
   // Initialization that needs to happen on the task queue. This is the first
   // task that gets run on the task queue, and is dispatched from the MDSM
   // constructor immediately after the task queue is created.
   void InitializationTask();
 
-  void DispatchAudioCaptured();
-  void DispatchAudioUncaptured();
+  void SetAudioCaptured(bool aCaptured);
 
   void Shutdown();
 public:
 
   void DispatchShutdown();
 
   void FinishShutdown();
 
@@ -484,29 +483,27 @@ protected:
 
   // If we have video, display a video frame if it's time for display has
   // arrived, otherwise sleep until it's time for the next frame. Update the
   // current frame time as appropriate, and trigger ready state update.  The
   // decoder monitor must be held with exactly one lock count. Called on the
   // state machine thread.
   void UpdateRenderedVideoFrames();
 
-  // Stops the audio sink and shut it down.
+  media::MediaSink* CreateAudioSink();
+
+  // Stops the media sink and shut it down.
   // The decoder monitor must be held with exactly one lock count.
   // Called on the state machine thread.
-  void StopAudioSink();
+  void StopMediaSink();
 
-  // Create and start the audio sink.
+  // Create and start the media sink.
   // The decoder monitor must be held with exactly one lock count.
   // Called on the state machine thread.
-  void StartAudioSink();
-
-  void StopDecodedStream();
-
-  void StartDecodedStream();
+  void StartMediaSink();
 
   // Notification method invoked when mPlayState changes.
   void PlayStateChanged();
 
   // Notification method invoked when mLogicallySeeking changes.
   void LogicallySeekingChanged();
 
   // Notification method invoked when mSameOriginMedia changes.
@@ -643,26 +640,22 @@ protected:
   bool IsAudioDecoding();
   bool IsVideoDecoding();
 
   // Set the time that playback started from the system clock.
   // Can only be called on the state machine thread.
   void SetPlayStartTime(const TimeStamp& aTimeStamp);
 
 private:
-  // Resolved by the AudioSink to signal that all outstanding work is complete
+  // Resolved by the MediaSink to signal that all outstanding work is complete
   // and the sink is shutting down.
-  void OnAudioSinkComplete();
+  void OnMediaSinkComplete();
 
-  // Rejected by the AudioSink to signal errors.
-  void OnAudioSinkError();
-
-  void OnDecodedStreamFinish();
-
-  void OnDecodedStreamError();
+  // Rejected by the MediaSink to signal errors.
+  void OnMediaSinkError();
 
   // Return true if the video decoder's decode speed can not catch up the
   // play time.
   bool NeedToSkipToNextKeyframe();
 
   // The decoder object that created this state machine. The state machine
   // holds a strong reference to the decoder to ensure that the decoder stays
   // alive once media element has started the decoder shutdown process, and has
@@ -972,25 +965,25 @@ private:
   SeekJob mPendingSeek;
 
   // The position that we're currently seeking to.
   SeekJob mCurrentSeek;
 
   // Media Fragment end time in microseconds. Access controlled by decoder monitor.
   int64_t mFragmentEndTime;
 
-  // The audio sink resource.  Used on the state machine thread.
-  nsRefPtr<media::MediaSink> mAudioSink;
+  // The media sink resource.  Used on the state machine thread.
+  nsRefPtr<media::MediaSink> mMediaSink;
 
   // The reader, don't call its methods with the decoder monitor held.
   // This is created in the state machine's constructor.
   nsRefPtr<MediaDecoderReader> mReader;
 
-  // The end time of the last audio frame that's been pushed onto the audio sink
-  // or DecodedStream in microseconds. This will approximately be the end time
+  // The end time of the last audio frame that's been pushed onto the media sink
+  // in microseconds. This will approximately be the end time
   // of the audio stream, unless another frame is pushed to the hardware.
   int64_t AudioEndTime() const;
 
   // The end time of the last decoded audio frame. This signifies the end of
   // decoded audio data. Used to check if we are low in decoded data.
   int64_t mDecodedAudioEndTime;
 
   // The presentation end time of the last video frame which has been displayed
@@ -1265,18 +1258,17 @@ private:
   // Only written on the main thread while holding the monitor. Therefore it
   // can be read on any thread while holding the monitor, or on the main thread
   // without holding the monitor.
   nsRefPtr<DecodedStream> mStreamSink;
 
   // Media data resource from the decoder.
   nsRefPtr<MediaResource> mResource;
 
-  MozPromiseRequestHolder<GenericPromise> mAudioSinkPromise;
-  MozPromiseRequestHolder<GenericPromise> mDecodedStreamPromise;
+  MozPromiseRequestHolder<GenericPromise> mMediaSinkPromise;
 
   MediaEventListener mAudioQueueListener;
   MediaEventListener mVideoQueueListener;
 
 private:
   // The buffered range. Mirrored from the decoder thread.
   Mirror<media::TimeIntervals> mBuffered;
 
--- a/dom/media/webaudio/test/test_mediaElementAudioSourceNodeCrossOrigin.html
+++ b/dom/media/webaudio/test/test_mediaElementAudioSourceNodeCrossOrigin.html
@@ -7,17 +7,17 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 
 // Turn off the authentication dialog blocking for this test.
-SpecialPowers.setIntPref("network.auth.allow-subresource-auth", 2)
+SpecialPowers.setIntPref("network.auth.subresource-http-auth-allow", 2)
 
 var tests = [
   // Not the same origin no CORS asked for, should have silence
   { url: "http://example.org:80/tests/dom/media/webaudio/test/small-shot.ogg",
     cors: null,
     expectSilence: true },
   // Same origin, should have sound
   { url: "small-shot.ogg",
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -31,16 +31,19 @@
 #include "nsPIDOMWindow.h"
 #include "PromiseCallback.h"
 #include "PromiseDebugging.h"
 #include "PromiseNativeHandler.h"
 #include "PromiseWorkerProxy.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "xpcpublic.h"
+#ifdef MOZ_CRASHREPORTER
+#include "nsExceptionHandler.h"
+#endif
 
 namespace mozilla {
 namespace dom {
 
 namespace {
 // Generator used by Promise::GetID.
 Atomic<uintptr_t> gIDGenerator(0);
 } // namespace
@@ -531,20 +534,20 @@ Promise::JSCallback(JSContext* aCx, unsi
   if (NS_FAILED(UNWRAP_OBJECT(Promise, &v.toObject(), promise))) {
     return Throw(aCx, NS_ERROR_UNEXPECTED);
   }
 
   v = js::GetFunctionNativeReserved(&args.callee(), SLOT_DATA);
   PromiseCallback::Task task = static_cast<PromiseCallback::Task>(v.toInt32());
 
   if (task == PromiseCallback::Resolve) {
-    promise->MaybeResolveInternal(aCx, args.get(0));
     if (!promise->CaptureStack(aCx, promise->mFullfillmentStack)) {
       return false;
     }
+    promise->MaybeResolveInternal(aCx, args.get(0));
   } else {
     promise->MaybeRejectInternal(aCx, args.get(0));
     if (!promise->CaptureStack(aCx, promise->mRejectionStack)) {
       return false;
     }
   }
 
   args.rval().setUndefined();
@@ -1337,16 +1340,39 @@ Promise::RejectInternal(JSContext* aCx,
   mResolvePending = true;
 
   MaybeSettle(aValue, Rejected);
 }
 
 void
 Promise::Settle(JS::Handle<JS::Value> aValue, PromiseState aState)
 {
+#ifdef MOZ_CRASHREPORTER
+  if (!mGlobal && mFullfillmentStack) {
+    AutoJSAPI jsapi;
+    jsapi.Init();
+    JSContext* cx = jsapi.cx();
+    JS::RootedObject stack(cx, mFullfillmentStack);
+    JSAutoCompartment ac(cx, stack);
+    JS::RootedString stackJSString(cx);
+    if (JS::BuildStackString(cx, stack, &stackJSString)) {
+      nsAutoJSString stackString;
+      if (stackString.init(cx, stackJSString)) {
+        // Put the string in the crash report here, since we're about to crash
+        CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("cced_promise_stack"),
+                                           NS_ConvertUTF16toUTF8(stackString));
+      } else {
+        JS_ClearPendingException(cx);
+      }
+    } else {
+      JS_ClearPendingException(cx);
+    }
+  }
+#endif
+
   if (mGlobal->IsDying()) {
     return;
   }
 
   mSettlementTimestamp = TimeStamp::Now();
 
   SetResult(aValue);
   SetState(aState);
--- a/dom/security/nsCORSListenerProxy.cpp
+++ b/dom/security/nsCORSListenerProxy.cpp
@@ -623,17 +623,16 @@ nsCORSListenerProxy::CheckRequestApprove
     }
     if (!foundMethod) {
       LogBlockedRequest(aRequest, "CORSMethodNotFound", nullptr);
       return NS_ERROR_DOM_BAD_URI;
     }
 
     // The "Access-Control-Allow-Headers" header contains a comma separated
     // list of header names.
-    headerVal.Truncate();
     http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
                             headerVal);
     nsTArray<nsCString> headers;
     nsCCharSeparatedTokenizer headerTokens(headerVal, ',');
     while(headerTokens.hasMoreTokens()) {
       const nsDependentCSubstring& header = headerTokens.nextToken();
       if (header.IsEmpty()) {
         continue;
@@ -1125,17 +1124,16 @@ nsCORSPreflightListener::AddResultToCach
     sPreflightCache->GetEntry(uri, mReferrerPrincipal, mWithCredentials,
                               true);
   if (!entry) {
     return;
   }
 
   // The "Access-Control-Allow-Methods" header contains a comma separated
   // list of method names.
-  headerVal.Truncate();
   http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
                           headerVal);
 
   nsCCharSeparatedTokenizer methods(headerVal, ',');
   while(methods.hasMoreTokens()) {
     const nsDependentCSubstring& method = methods.nextToken();
     if (method.IsEmpty()) {
       continue;
@@ -1156,17 +1154,16 @@ nsCORSPreflightListener::AddResultToCach
 
       newMethod->token = method;
       newMethod->expirationTime = expirationTime;
     }
   }
 
   // The "Access-Control-Allow-Headers" header contains a comma separated
   // list of method names.
-  headerVal.Truncate();
   http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
                           headerVal);
 
   nsCCharSeparatedTokenizer headers(headerVal, ',');
   while(headers.hasMoreTokens()) {
     const nsDependentCSubstring& header = headers.nextToken();
     if (header.IsEmpty()) {
       continue;
new file mode 100644
--- /dev/null
+++ b/dom/system/gonk/GeolocationUtil.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GeolocationUtil.h"
+
+double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon)
+{
+  // Use spherical law of cosines to calculate difference
+  // Not quite as correct as the Haversine but simpler and cheaper
+  const double radsInDeg = M_PI / 180.0;
+  const double rNewLat = aLat * radsInDeg;
+  const double rNewLon = aLon * radsInDeg;
+  const double rOldLat = aLastLat * radsInDeg;
+  const double rOldLon = aLastLon * radsInDeg;
+  // WGS84 equatorial radius of earth = 6378137m
+  double cosDelta = (sin(rNewLat) * sin(rOldLat)) +
+                    (cos(rNewLat) * cos(rOldLat) * cos(rOldLon - rNewLon));
+  if (cosDelta > 1.0) {
+    cosDelta = 1.0;
+  } else if (cosDelta < -1.0) {
+    cosDelta = -1.0;
+  }
+  return acos(cosDelta) * 6378137;
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/system/gonk/GeolocationUtil.h
@@ -0,0 +1,13 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GEOLOCATIONUTIL_H
+#define GEOLOCATIONUTIL_H
+
+double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon);
+
+#endif
+
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -15,16 +15,18 @@
  */
 
 #include "GonkGPSGeolocationProvider.h"
 #include "mozstumbler/MozStumbler.h"
 
 #include <pthread.h>
 #include <hardware/gps.h>
 
+#include "GeolocationUtil.h"
+#include "mozstumbler/MozStumbler.h"
 #include "mozilla/Constants.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsContentUtils.h"
 #include "nsGeoPosition.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsINetworkInterface.h"
 #include "nsIObserverService.h"
@@ -83,81 +85,16 @@ NS_IMPL_ISUPPORTS(GonkGPSGeolocationProv
 /* static */ GonkGPSGeolocationProvider* GonkGPSGeolocationProvider::sSingleton = nullptr;
 GpsCallbacks GonkGPSGeolocationProvider::mCallbacks;
 
 #ifdef MOZ_B2G_RIL
 AGpsCallbacks GonkGPSGeolocationProvider::mAGPSCallbacks;
 AGpsRilCallbacks GonkGPSGeolocationProvider::mAGPSRILCallbacks;
 #endif // MOZ_B2G_RIL
 
-double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon)
-{
-  // Use spherical law of cosines to calculate difference
-  // Not quite as correct as the Haversine but simpler and cheaper
-  const double radsInDeg = M_PI / 180.0;
-  const double rNewLat = aLat * radsInDeg;
-  const double rNewLon = aLon * radsInDeg;
-  const double rOldLat = aLastLat * radsInDeg;
-  const double rOldLon = aLastLon * radsInDeg;
-  // WGS84 equatorial radius of earth = 6378137m
-  double cosDelta = (sin(rNewLat) * sin(rOldLat)) +
-                    (cos(rNewLat) * cos(rOldLat) * cos(rOldLon - rNewLon));
-  if (cosDelta > 1.0) {
-    cosDelta = 1.0;
-  } else if (cosDelta < -1.0) {
-    cosDelta = -1.0;
-  }
-  return acos(cosDelta) * 6378137;
-}
-
-class RequestCellInfoEvent : public nsRunnable {
-  public:
-    RequestCellInfoEvent(StumblerInfo *callback)
-      : mRequestCallback(callback)
-      {}
-
-    NS_IMETHOD Run() {
-      MOZ_ASSERT(NS_IsMainThread());
-      // Get Cell Info
-      nsCOMPtr<nsIMobileConnectionService> service =
-        do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
-
-      if (!service) {
-        nsContentUtils::LogMessageToConsole("Stumbler-can not get nsIMobileConnectionService \n");
-        return NS_OK;
-      }
-      nsCOMPtr<nsIMobileConnection> connection;
-      uint32_t numberOfRilServices = 1, cellInfoNum = 0;
-
-      service->GetNumItems(&numberOfRilServices);
-      for (uint32_t rilNum = 0; rilNum < numberOfRilServices; rilNum++) {
-        service->GetItemByServiceId(rilNum /* Client Id */, getter_AddRefs(connection));
-        if (!connection) {
-          nsContentUtils::LogMessageToConsole("Stumbler-can not get nsIMobileConnection by ServiceId %d \n", rilNum);
-        } else {
-          cellInfoNum++;
-          connection->GetCellInfoList(mRequestCallback);
-        }
-      }
-      mRequestCallback->SetCellInfoResponsesExpected(cellInfoNum);
-
-      // Get Wifi AP Info
-      nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1");
-      nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir);
-      if (!wifi) {
-        mRequestCallback->SetWifiInfoResponseReceived();
-        nsContentUtils::LogMessageToConsole("Stumbler-can not get nsIWifi interface\n");
-        return NS_OK;
-      }
-      wifi->GetWifiScanResults(mRequestCallback);
-      return NS_OK;
-    }
-  private:
-    nsRefPtr<StumblerInfo> mRequestCallback;
-};
 
 void
 GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
 {
   if (gDebug_isGPSLocationIgnored) {
     return;
   }
 
@@ -206,45 +143,17 @@ GonkGPSGeolocationProvider::LocationCall
                                         location->latitude,
                                         location->longitude,
                                         location->accuracy);
   }
 
   nsRefPtr<UpdateLocationEvent> event = new UpdateLocationEvent(somewhere);
   NS_DispatchToMainThread(event);
 
-  const double kMinChangeInMeters = 30;
-  static int64_t lastTime_ms = 0;
-  static double sLastLat = 0;
-  static double sLastLon = 0;
-  double delta = -1.0;
-  int64_t timediff = (PR_Now() / PR_USEC_PER_MSEC) - lastTime_ms;
-
-  if (0 != sLastLon || 0 != sLastLat) {
-    delta = CalculateDeltaInMeter(location->latitude, location->longitude, sLastLat, sLastLon);
-  }
-  if (gDebug_isLoggingEnabled) {
-    nsContentUtils::LogMessageToConsole("Stumbler-Location. [%f , %f] time_diff:%lld, delta : %f\n",
-      location->longitude, location->latitude, timediff, delta);
-  }
-
-  // Consecutive GPS locations must be 30 meters and 3 seconds apart
-  if (lastTime_ms == 0 || ((timediff >= STUMBLE_INTERVAL_MS) && (delta > kMinChangeInMeters))){
-    lastTime_ms = (PR_Now() / PR_USEC_PER_MSEC);
-    sLastLat = location->latitude;
-    sLastLon = location->longitude;
-    nsRefPtr<StumblerInfo> requestCallback = new StumblerInfo(somewhere);
-    nsRefPtr<RequestCellInfoEvent> runnable = new RequestCellInfoEvent(requestCallback);
-    NS_DispatchToMainThread(runnable);
-  } else {
-    if (gDebug_isLoggingEnabled) {
-      nsContentUtils::LogMessageToConsole(
-        "Stumbler-GPS locations less than 30 meters and 3 seconds. Ignore!\n");
-    }
-  }
+  MozStumble(somewhere);
 }
 
 void
 GonkGPSGeolocationProvider::StatusCallback(GpsStatus* status)
 {
   if (gDebug_isLoggingEnabled) {
     switch (status->status) {
       case GPS_STATUS_NONE:
--- a/dom/system/gonk/moz.build
+++ b/dom/system/gonk/moz.build
@@ -28,26 +28,28 @@ XPIDL_SOURCES += [
     'nsIVolumeService.idl',
     'nsIVolumeStat.idl',
     'nsIWorkerHolder.idl',
 ]
 
 XPIDL_MODULE = 'dom_system_gonk'
 
 EXPORTS += [
+    'GeolocationUtil.h',
     'GonkGPSGeolocationProvider.h',
     'mozstumbler/MozStumbler.h',
     'nsVolume.h',
     'nsVolumeService.h',
 ]
 UNIFIED_SOURCES += [
     'AudioChannelManager.cpp',
     'AudioManager.cpp',
     'AutoMounter.cpp',
     'AutoMounterSetting.cpp',
+    'GeolocationUtil.cpp',
     'GonkGPSGeolocationProvider.cpp',
     'MozMtpDatabase.cpp',
     'MozMtpServer.cpp',
     'MozMtpStorage.cpp',
     'mozstumbler/MozStumbler.cpp',
     'mozstumbler/StumblerLogging.cpp',
     'mozstumbler/UploadStumbleRunnable.cpp',
     'mozstumbler/WriteStumbleOnThread.cpp',
--- a/dom/system/gonk/mozstumbler/MozStumbler.cpp
+++ b/dom/system/gonk/mozstumbler/MozStumbler.cpp
@@ -1,28 +1,133 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MozStumbler.h"
+#include "nsDataHashtable.h"
 #include "nsGeoPosition.h"
+#include "nsNetCID.h"
 #include "nsPrintfCString.h"
 #include "StumblerLogging.h"
 #include "WriteStumbleOnThread.h"
-#include "nsNetCID.h"
-#include "nsDataHashtable.h"
+#include "../GeolocationUtil.h"
+
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIMobileConnectionInfo.h"
+#include "nsIMobileConnectionService.h"
+#include "nsIMobileCellInfo.h"
+#include "nsIMobileNetworkInfo.h"
+#include "nsINetworkInterface.h"
+#include "nsIRadioInterfaceLayer.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 
 NS_IMPL_ISUPPORTS(StumblerInfo, nsICellInfoListCallback, nsIWifiScanResultsReady)
 
+class RequestCellInfoEvent : public nsRunnable {
+public:
+  RequestCellInfoEvent(StumblerInfo *callback)
+  : mRequestCallback(callback)
+  {}
+
+  NS_IMETHOD Run() {
+    MOZ_ASSERT(NS_IsMainThread());
+    // Get Cell Info
+    nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+
+    if (!service) {
+      STUMBLER_ERR("Stumbler-can not get nsIMobileConnectionService \n");
+      return NS_OK;
+    }
+    nsCOMPtr<nsIMobileConnection> connection;
+    uint32_t numberOfRilServices = 1, cellInfoNum = 0;
+
+    service->GetNumItems(&numberOfRilServices);
+    for (uint32_t rilNum = 0; rilNum < numberOfRilServices; rilNum++) {
+      service->GetItemByServiceId(rilNum /* Client Id */, getter_AddRefs(connection));
+      if (!connection) {
+        STUMBLER_ERR("Stumbler-can not get nsIMobileConnection by ServiceId %d \n", rilNum);
+      } else {
+        cellInfoNum++;
+        connection->GetCellInfoList(mRequestCallback);
+      }
+    }
+    mRequestCallback->SetCellInfoResponsesExpected(cellInfoNum);
+
+    // Get Wifi AP Info
+    nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1");
+    nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir);
+    if (!wifi) {
+      mRequestCallback->SetWifiInfoResponseReceived();
+      STUMBLER_ERR("Stumbler-can not get nsIWifi interface\n");
+      return NS_OK;
+    }
+    wifi->GetWifiScanResults(mRequestCallback);
+    return NS_OK;
+  }
+private:
+  nsRefPtr<StumblerInfo> mRequestCallback;
+};
+
+void
+MozStumble(nsGeoPosition* position)
+{
+  if (WriteStumbleOnThread::IsFileWaitingForUpload()) {
+    nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
+    MOZ_ASSERT(target);
+    // Knowing that file is waiting to upload, and no collection will take place,
+    // just trigger the thread with an empty string.
+    nsCOMPtr<nsIRunnable> event = new WriteStumbleOnThread(EmptyCString());
+    target->Dispatch(event, NS_DISPATCH_NORMAL);
+    return;
+  }
+
+  nsCOMPtr<nsIDOMGeoPositionCoords> coords;
+  position->GetCoords(getter_AddRefs(coords));
+  if (!coords) {
+    return;
+  }
+
+  double latitude, longitude;
+  coords->GetLatitude(&latitude);
+  coords->GetLongitude(&longitude);
+
+  const double kMinChangeInMeters = 30;
+  static int64_t lastTime_ms = 0;
+  static double sLastLat = 0;
+  static double sLastLon = 0;
+  double delta = -1.0;
+  int64_t timediff = (PR_Now() / PR_USEC_PER_MSEC) - lastTime_ms;
+
+  if (0 != sLastLon || 0 != sLastLat) {
+    delta = CalculateDeltaInMeter(latitude, longitude, sLastLat, sLastLon);
+  }
+  STUMBLER_DBG("Stumbler-Location. [%f , %f] time_diff:%lld, delta : %f\n",
+                                      longitude, latitude, timediff, delta);
+
+  // Consecutive GPS locations must be 30 meters and 3 seconds apart
+  if (lastTime_ms == 0 || ((timediff >= STUMBLE_INTERVAL_MS) && (delta > kMinChangeInMeters))){
+    lastTime_ms = (PR_Now() / PR_USEC_PER_MSEC);
+    sLastLat = latitude;
+    sLastLon = longitude;
+    nsRefPtr<StumblerInfo> requestCallback = new StumblerInfo(position);
+    nsRefPtr<RequestCellInfoEvent> runnable = new RequestCellInfoEvent(requestCallback);
+    NS_DispatchToMainThread(runnable);
+  } else {
+    STUMBLER_DBG("Stumbler-GPS locations less than 30 meters and 3 seconds. Ignore!\n");
+  }
+}
+
 void
 StumblerInfo::SetWifiInfoResponseReceived()
 {
   mIsWifiInfoResponseReceived = true;
 
   if (mIsWifiInfoResponseReceived && mCellInfoResponsesReceived == mCellInfoResponsesExpected) {
     STUMBLER_DBG("Call DumpStumblerInfo from SetWifiInfoResponseReceived\n");
     DumpStumblerInfo();
--- a/dom/system/gonk/mozstumbler/MozStumbler.h
+++ b/dom/system/gonk/mozstumbler/MozStumbler.h
@@ -10,16 +10,18 @@
 #include "nsIDOMEventTarget.h"
 #include "nsICellInfo.h"
 #include "nsIWifi.h"
 
 #define STUMBLE_INTERVAL_MS 3000
 
 class nsGeoPosition;
 
+void MozStumble(nsGeoPosition* position);
+
 class StumblerInfo final : public nsICellInfoListCallback,
                            public nsIWifiScanResultsReady
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSICELLINFOLISTCALLBACK
   NS_DECL_NSIWIFISCANRESULTSREADY
 
--- a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp
+++ b/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp
@@ -2,24 +2,25 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "UploadStumbleRunnable.h"
 #include "StumblerLogging.h"
 #include "mozilla/dom/Event.h"
+#include "nsIInputStream.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIURLFormatter.h"
 #include "nsIVariant.h"
 #include "nsIXMLHttpRequest.h"
 #include "nsNetUtil.h"
 
-UploadStumbleRunnable::UploadStumbleRunnable(const nsACString& aUploadData)
-: mUploadData(aUploadData)
+UploadStumbleRunnable::UploadStumbleRunnable(nsIInputStream* aUploadData)
+: mUploadInputStream(aUploadData)
 {
 }
 
 NS_IMETHODIMP
 UploadStumbleRunnable::Run()
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsresult rv = Upload();
@@ -31,17 +32,17 @@ UploadStumbleRunnable::Run()
 
 nsresult
 UploadStumbleRunnable::Upload()
 {
   nsresult rv;
   nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance("@mozilla.org/variant;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = variant->SetAsACString(mUploadData);
+  rv = variant->SetAsISupports(mUploadInputStream);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIXMLHttpRequest> xhr = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIScriptSecurityManager> secman =
     do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -58,23 +59,23 @@ UploadStumbleRunnable::Upload()
   NS_ENSURE_SUCCESS(rv, rv);
   nsString url;
   rv = formatter->FormatURLPref(NS_LITERAL_STRING("geo.stumbler.url"), url);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = xhr->Open(NS_LITERAL_CSTRING("POST"), NS_ConvertUTF16toUTF8(url), false, EmptyString(), EmptyString());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  xhr->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), NS_LITERAL_CSTRING("application/json"));
+  xhr->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), NS_LITERAL_CSTRING("gzip"));
   xhr->SetMozBackgroundRequest(true);
   // 60s timeout
   xhr->SetTimeout(60 * 1000);
 
   nsCOMPtr<EventTarget> target(do_QueryInterface(xhr));
-  nsRefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr, mUploadData.Length());
+  nsRefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr);
 
   const char* const sEventStrings[] = {
     // nsIXMLHttpRequestEventTarget event types
     "abort",
     "error",
     "load",
     "timeout"
   };
@@ -88,33 +89,33 @@ UploadStumbleRunnable::Upload()
   rv = xhr->Send(variant);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(UploadEventListener, nsIDOMEventListener)
 
-UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR, int64_t aFileSize)
-: mXHR(aXHR), mFileSize(aFileSize)
+UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR)
+: mXHR(aXHR)
 {
 }
 
 NS_IMETHODIMP
 UploadEventListener::HandleEvent(nsIDOMEvent* aEvent)
 {
   nsString type;
   if (NS_FAILED(aEvent->GetType(type))) {
     STUMBLER_ERR("Failed to get event type");
     WriteStumbleOnThread::UploadEnded(false);
     return NS_ERROR_FAILURE;
   }
 
   if (type.EqualsLiteral("load")) {
-    STUMBLER_DBG("Got load Event : size %lld", mFileSize);
+    STUMBLER_DBG("Got load Event\n");
   } else if (type.EqualsLiteral("error") && mXHR) {
     STUMBLER_ERR("Upload Error");
   } else {
     STUMBLER_DBG("Receive %s Event", NS_ConvertUTF16toUTF8(type).get());
   }
 
   uint32_t statusCode = 0;
   bool doDelete = false;
--- a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h
+++ b/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h
@@ -6,41 +6,41 @@
 
 
 #ifndef UPLOADSTUMBLERUNNABLE_H
 #define UPLOADSTUMBLERUNNABLE_H
 
 #include "nsIDOMEventListener.h"
 
 class nsIXMLHttpRequest;
+class nsIInputStream;
 
 /*
  This runnable is managed by WriteStumbleOnThread only, see that class
  for how this is scheduled.
  */
 class UploadStumbleRunnable final : public nsRunnable
 {
 public:
-  explicit UploadStumbleRunnable(const nsACString& aUploadData);
+  explicit UploadStumbleRunnable(nsIInputStream* aUploadInputStream);
 
   NS_IMETHOD Run() override;
 private:
   virtual ~UploadStumbleRunnable() {}
-  const nsCString mUploadData;
+  nsCOMPtr<nsIInputStream> mUploadInputStream;
   nsresult Upload();
 };
 
 
 class UploadEventListener : public nsIDOMEventListener
 {
 public:
-  UploadEventListener(nsIXMLHttpRequest* aXHR, int64_t aFileSize);
+  UploadEventListener(nsIXMLHttpRequest* aXHR);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMEVENTLISTENER
 
 protected:
   virtual ~UploadEventListener() {}
   nsCOMPtr<nsIXMLHttpRequest> mXHR;
-  int64_t mFileSize;
 };
 
 #endif
--- a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp
+++ b/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp
@@ -12,22 +12,22 @@
 #include "nsIFileStreams.h"
 #include "nsIInputStream.h"
 #include "nsPrintfCString.h"
 
 #define MAXFILESIZE_KB (15 * 1024)
 #define ONEDAY_IN_MSEC (24 * 60 * 60 * 1000)
 #define MAX_UPLOAD_ATTEMPTS 20
 
-mozilla::Atomic<bool> WriteStumbleOnThread::sIsUploading(false);
+mozilla::Atomic<bool> WriteStumbleOnThread::sIsFileWaitingForUpload(false);
 mozilla::Atomic<bool> WriteStumbleOnThread::sIsAlreadyRunning(false);
 WriteStumbleOnThread::UploadFreqGuard WriteStumbleOnThread::sUploadFreqGuard = {0};
 
-#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json")
-#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json")
+#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json.gz")
+#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json.gz")
 #define OUTPUT_DIR NS_LITERAL_CSTRING("mozstumbler")
 
 class DeleteRunnable : public nsRunnable
 {
   public:
     DeleteRunnable() {}
 
     NS_IMETHODIMP
@@ -37,81 +37,79 @@ class DeleteRunnable : public nsRunnable
       nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED,
                                               getter_AddRefs(tmpFile),
                                               OUTPUT_DIR,
                                               nsDumpUtils::CREATE);
       if (NS_SUCCEEDED(rv)) {
         tmpFile->Remove(true);
       }
       // critically, this sets this flag to false so writing can happen again
-      WriteStumbleOnThread::sIsUploading = false;
+      WriteStumbleOnThread::sIsAlreadyRunning = false;
+      WriteStumbleOnThread::sIsFileWaitingForUpload = false;
       return NS_OK;
     }
 
   private:
     ~DeleteRunnable() {}
 };
 
+bool
+WriteStumbleOnThread::IsFileWaitingForUpload()
+{
+  return sIsFileWaitingForUpload;
+}
+
 void
 WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
 {
   if (!deleteUploadFile) {
-    sIsUploading = false;
+    sIsAlreadyRunning = false;
     return;
   }
 
   nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
   MOZ_ASSERT(target);
   nsCOMPtr<nsIRunnable> event = new DeleteRunnable();
   target->Dispatch(event, NS_DISPATCH_NORMAL);
 }
 
-#define DUMP(o, s) \
-  do { \
-    const char* s2 = (s); \
-    uint32_t dummy; \
-    nsresult rv = (o)->Write((s2), strlen(s2), &dummy); \
-    if (NS_WARN_IF(NS_FAILED(rv))) \
-    STUMBLER_ERR("write err"); \
-  } while (0)
-
 void
 WriteStumbleOnThread::WriteJSON(Partition aPart)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   nsCOMPtr<nsIFile> tmpFile;
   nsresult rv;
   rv = nsDumpUtils::OpenTempFile(FILENAME_INPROGRESS, getter_AddRefs(tmpFile),
                                  OUTPUT_DIR, nsDumpUtils::CREATE);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     STUMBLER_ERR("Open a file for stumble failed");
     return;
   }
 
-  nsCOMPtr<nsIFileOutputStream> ostream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
-  rv = ostream->Init(tmpFile, PR_WRONLY | PR_APPEND, 0666, 0);
+  nsRefPtr<nsGZFileWriter> gzWriter = new nsGZFileWriter(nsGZFileWriter::Append);
+  rv = gzWriter->Init(tmpFile);
   if (NS_WARN_IF(NS_FAILED(rv))) {
-    STUMBLER_ERR("Open a file for stumble failed");
+    STUMBLER_ERR("gzWriter init failed");
     return;
   }
 
   /*
    The json format is like below.
    {items:[
    {item},
    {item},
    {item}
    ]}
    */
 
   // Need to add "]}" after the last item
   if (aPart == Partition::End) {
-    DUMP(ostream, "]}");
-    rv = ostream->Close();
+    gzWriter->Write("]}");
+    rv = gzWriter->Finish();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       STUMBLER_ERR("ostream finish failed");
     }
 
     nsCOMPtr<nsIFile> targetFile;
     nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(targetFile),
                                             OUTPUT_DIR, nsDumpUtils::CREATE);
     nsAutoString targetFilename;
@@ -131,24 +129,24 @@ WriteStumbleOnThread::WriteJSON(Partitio
       STUMBLER_ERR("Rename File failed");
       return;
     }
     return;
   }
 
   // Need to add "{items:[" before the first item
   if (aPart == Partition::Begining) {
-    DUMP(ostream, "{\"items\":[{");
+    gzWriter->Write("{\"items\":[{");
   } else if (aPart == Partition::Middle) {
-    DUMP(ostream, ",{");
+    gzWriter->Write(",{");
   }
-  DUMP(ostream, mDesc.get());
+  gzWriter->Write(mDesc.get());
   //  one item is ended with '}' (e.g. {item})
-  DUMP(ostream, "}");
-  rv = ostream->Close();
+  gzWriter->Write("}");
+  rv = gzWriter->Finish();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     STUMBLER_ERR("ostream finish failed");
   }
 
   // check if it is the end of this file
   int64_t fileSize = 0;
   rv = tmpFile->GetFileSize(&fileSize);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -199,27 +197,30 @@ WriteStumbleOnThread::Run()
   if (b) {
     return NS_OK;
   }
 
   UploadFileStatus status = GetUploadFileStatus();
 
   if (UploadFileStatus::NoFile != status) {
     if (UploadFileStatus::ExistsAndReadyToUpload == status) {
+      sIsFileWaitingForUpload = true;
       Upload();
+      return NS_OK;
     }
   } else {
     Partition partition = GetWritePosition();
     if (partition == Partition::Unknown) {
       STUMBLER_ERR("GetWritePosition failed, skip once");
     } else {
       WriteJSON(partition);
     }
   }
 
+  sIsFileWaitingForUpload = false;
   sIsAlreadyRunning = false;
   return NS_OK;
 }
 
 
 /*
  If the upload file exists, then check if it is one day old.
  • if it is a day old -> ExistsAndReadyToUpload
@@ -254,64 +255,50 @@ WriteStumbleOnThread::GetUploadFileStatu
   return UploadFileStatus::Exists;
 }
 
 void
 WriteStumbleOnThread::Upload()
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
-  bool b = sIsUploading.exchange(true);
-  if (b) {
-    return;
-  }
-
   time_t seconds = time(0);
   int day = seconds / (60 * 60 * 24);
 
   if (sUploadFreqGuard.daySinceEpoch < day) {
     sUploadFreqGuard.daySinceEpoch = day;
     sUploadFreqGuard.attempts = 0;
   }
 
   sUploadFreqGuard.attempts++;
   if (sUploadFreqGuard.attempts > MAX_UPLOAD_ATTEMPTS) {
     STUMBLER_ERR("Too many upload attempts today");
-    sIsUploading = false;
+    sIsAlreadyRunning = false;
     return;
   }
 
   nsCOMPtr<nsIFile> tmpFile;
   nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(tmpFile),
                                           OUTPUT_DIR, nsDumpUtils::CREATE);
   int64_t fileSize;
   rv = tmpFile->GetFileSize(&fileSize);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     STUMBLER_ERR("GetFileSize failed");
-    sIsUploading = false;
+    sIsAlreadyRunning = false;
     return;
   }
 
   if (fileSize <= 0) {
-    sIsUploading = false;
+    sIsAlreadyRunning = false;
     return;
   }
 
   // prepare json into nsIInputStream
   nsCOMPtr<nsIInputStream> inStream;
-  rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile, -1, -1,
-                                  nsIFileInputStream::DEFER_OPEN);
+  rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile);
   if (NS_FAILED(rv)) {
-    sIsUploading = false;
+    sIsAlreadyRunning = false;
     return;
   }
 
-  nsCString bufStr;
-  rv = NS_ReadInputStreamToString(inStream, bufStr, fileSize);
-
-  if (NS_FAILED(rv)) {
-    sIsUploading = false;
-    return;
-  }
-
-  nsRefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(bufStr);
+  nsRefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(inStream);
   NS_DispatchToMainThread(uploader);
 }
--- a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h
+++ b/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h
@@ -4,16 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WriteStumbleOnThread_H
 #define WriteStumbleOnThread_H
 
 #include "mozilla/Atomics.h"
 
+class DeleteRunnable;
+
 /*
  This class is the entry point to stumbling, in that it
  receives the location+cell+wifi string and writes it
  to disk, or instead, it calls UploadStumbleRunnable
  to upload the data.
 
  Writes will happen until the file is a max size, then stop.
  Uploads will happen only when the file is one day old.
@@ -38,20 +40,23 @@ class WriteStumbleOnThread : public nsRu
 public:
   explicit WriteStumbleOnThread(const nsCString& aDesc)
   : mDesc(aDesc)
   {}
 
   NS_IMETHODIMP Run() override;
 
   static void UploadEnded(bool deleteUploadFile);
-  // Don't write while uploading is happening
-  static mozilla::Atomic<bool> sIsUploading;
+
+  // Used externally to determine if cell+wifi scans should happen
+  // (returns false for that case).
+  static bool IsFileWaitingForUpload();
 
 private:
+  friend class DeleteRunnable;
 
   enum class Partition {
     Begining,
     Middle,
     End,
     Unknown
   };
 
@@ -66,16 +71,18 @@ private:
   void WriteJSON(Partition aPart);
   void Upload();
 
   nsCString mDesc;
 
   // Only run one instance of this
   static mozilla::Atomic<bool> sIsAlreadyRunning;
 
+  static mozilla::Atomic<bool> sIsFileWaitingForUpload;
+
   // Limit the upload attempts per day. If the device is rebooted
   // this resets the allowed attempts, which is acceptable.
   struct UploadFreqGuard {
     int attempts;
     int daySinceEpoch;
   };
   static UploadFreqGuard sUploadFreqGuard;
 
--- a/dom/webidl/BluetoothPbapParameters.webidl
+++ b/dom/webidl/BluetoothPbapParameters.webidl
@@ -44,18 +44,18 @@ enum vCardProperties
   "x-bt-uid"
 };
 
 /**
  * This enum holds the parameters to indicate the sorting order of vCard
  * objects.
  */
 enum vCardOrderType {
+  "indexed",  // default
   "alphabetical",
-  "indexed",  // default
   "phonetical"
 };
 
 /**
  * This enum holds the parameters to indicate the search key of the search
  * operation.
  */
 enum vCardSearchKeyType {
--- a/dom/webidl/PushManager.webidl
+++ b/dom/webidl/PushManager.webidl
@@ -22,17 +22,17 @@ interface PushManagerImpl {
     [Func="ServiceWorkerRegistration::WebPushMethodHider"] void setScope(DOMString scope);
 };
 
 [Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled"]
 interface PushManager {
   [ChromeOnly, Throws, Exposed=Window]
   void setPushManagerImpl(PushManagerImpl store);
 
-  [Throws]
+  [Throws, UseCounter]
   Promise<PushSubscription>     subscribe();
   [Throws]
   Promise<PushSubscription?>    getSubscription();
   [Throws]
   Promise<PushPermissionState> permissionState();
 };
 
 enum PushPermissionState
--- a/dom/webidl/PushSubscription.webidl
+++ b/dom/webidl/PushSubscription.webidl
@@ -9,16 +9,16 @@
 
 interface Principal;
 
 [Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled",
  ChromeConstructor(DOMString pushEndpoint, DOMString scope)]
 interface PushSubscription
 {
     readonly attribute USVString endpoint;
-    [Throws]
+    [Throws, UseCounter]
     Promise<boolean> unsubscribe();
     jsonifier;
 
     // Used to set the principal from the JS implemented PushManager.
     [Exposed=Window,ChromeOnly]
     void setPrincipal(Principal principal);
 };
--- a/editor/libeditor/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/nsHTMLDataTransfer.cpp
@@ -1318,18 +1318,19 @@ bool nsHTMLEditor::HavePrivateHTMLFlavor
     return bHavePrivateHTMLFlavor;
 
   return false;
 }
 
 
 NS_IMETHODIMP nsHTMLEditor::Paste(int32_t aSelectionType)
 {
-  if (!FireClipboardEvent(NS_PASTE, aSelectionType))
+  if (!FireClipboardEvent(ePaste, aSelectionType)) {
     return NS_OK;
+  }
 
   // Get Clipboard Service
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // find out if we have our internal html flavor on the clipboard.  We don't want to mess
   // around with cfhtml if we do.
@@ -1401,36 +1402,38 @@ NS_IMETHODIMP nsHTMLEditor::Paste(int32_
   return InsertFromTransferable(trans, nullptr, contextStr, infoStr,
                                 nullptr, 0, true);
 }
 
 NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
 {
   // Use an invalid value for the clipboard type as data comes from aTransferable
   // and we don't currently implement a way to put that in the data transfer yet.
-  if (!FireClipboardEvent(NS_PASTE, nsIClipboard::kGlobalClipboard))
+  if (!FireClipboardEvent(ePaste, nsIClipboard::kGlobalClipboard)) {
     return NS_OK;
+  }
 
   // handle transferable hooks
   nsCOMPtr<nsIDOMDocument> domdoc = GetDOMDocument();
   if (!nsEditorHookUtils::DoInsertionHook(domdoc, nullptr, aTransferable))
     return NS_OK;
 
   nsAutoString contextStr, infoStr;
   return InsertFromTransferable(aTransferable, nullptr, contextStr, infoStr,
                                 nullptr, 0, true);
 }
 
 //
 // HTML PasteNoFormatting. Ignore any HTML styles and formating in paste source
 //
 NS_IMETHODIMP nsHTMLEditor::PasteNoFormatting(int32_t aSelectionType)
 {
-  if (!FireClipboardEvent(NS_PASTE, aSelectionType))
+  if (!FireClipboardEvent(ePaste, aSelectionType)) {
     return NS_OK;
+  }
 
   ForceCompositionEnd();
 
   // Get Clipboard Service
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/editor/libeditor/nsPlaintextDataTransfer.cpp
+++ b/editor/libeditor/nsPlaintextDataTransfer.cpp
@@ -317,18 +317,19 @@ nsresult nsPlaintextEditor::InsertFromDr
   if (NS_SUCCEEDED(rv))
     ScrollSelectionIntoView(false);
 
   return rv;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::Paste(int32_t aSelectionType)
 {
-  if (!FireClipboardEvent(NS_PASTE, aSelectionType))
+  if (!FireClipboardEvent(ePaste, aSelectionType)) {
     return NS_OK;
+  }
 
   // Get Clipboard Service
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   if ( NS_FAILED(rv) )
     return rv;
 
   // Get the nsITransferable interface for getting the data from the clipboard
@@ -350,18 +351,19 @@ NS_IMETHODIMP nsPlaintextEditor::Paste(i
 
   return rv;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::PasteTransferable(nsITransferable *aTransferable)
 {
   // Use an invalid value for the clipboard type as data comes from aTransferable
   // and we don't currently implement a way to put that in the data transfer yet.
-  if (!FireClipboardEvent(NS_PASTE, -1))
+  if (!FireClipboardEvent(ePaste, -1)) {
     return NS_OK;
+  }
 
   if (!IsModifiable())
     return NS_OK;
 
   // handle transferable hooks
   nsCOMPtr<nsIDOMDocument> domdoc = GetDOMDocument();
   if (!nsEditorHookUtils::DoInsertionHook(domdoc, nullptr, aTransferable))
     return NS_OK;
--- a/editor/libeditor/nsPlaintextEditor.cpp
+++ b/editor/libeditor/nsPlaintextEditor.cpp
@@ -1168,17 +1168,17 @@ nsPlaintextEditor::CanCutOrCopy(Password
   return !selection->Collapsed();
 }
 
 bool
 nsPlaintextEditor::FireClipboardEvent(EventMessage aEventMessage,
                                       int32_t aSelectionType,
                                       bool* aActionTaken)
 {
-  if (aEventMessage == NS_PASTE) {
+  if (aEventMessage == ePaste) {
     ForceCompositionEnd();
   }
 
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   NS_ENSURE_TRUE(presShell, false);
 
   nsRefPtr<Selection> selection = GetSelection();
   if (!selection) {
@@ -1193,17 +1193,17 @@ nsPlaintextEditor::FireClipboardEvent(Ev
   // If the event handler caused the editor to be destroyed, return false.
   // Otherwise return true to indicate that the event was not cancelled.
   return !mDidPreDestroy;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::Cut()
 {
   bool actionTaken = false;
-  if (FireClipboardEvent(NS_CUT, nsIClipboard::kGlobalClipboard, &actionTaken)) {
+  if (FireClipboardEvent(eCut, nsIClipboard::kGlobalClipboard, &actionTaken)) {
     DeleteSelection(eNone, eStrip);
   }
   return actionTaken ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::CanCut(bool *aCanCut)
 {
   NS_ENSURE_ARG_POINTER(aCanCut);
@@ -1212,17 +1212,17 @@ NS_IMETHODIMP nsPlaintextEditor::CanCut(
   *aCanCut = (doc && doc->IsHTMLOrXHTML()) ||
     (IsModifiable() && CanCutOrCopy(ePasswordFieldNotAllowed));
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::Copy()
 {
   bool actionTaken = false;
-  FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, &actionTaken);
+  FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard, &actionTaken);
 
   return actionTaken ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsPlaintextEditor::CanCopy(bool *aCanCopy)
 {
   NS_ENSURE_ARG_POINTER(aCanCopy);
   // Copy is always enabled in HTML documents
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -624,16 +624,22 @@ FilterNodeSoftware::GetOutput(const IntR
     MOZ_ASSERT(mCachedOutput, "cached rect but no cached output?");
   }
   return GetDataSurfaceInRect(mCachedOutput, mCachedRect, aRect, EDGE_MODE_NONE);
 }
 
 void
 FilterNodeSoftware::RequestRect(const IntRect &aRect)
 {
+  if (mRequestedRect.Contains(aRect)) {
+    // Bail out now. Otherwise pathological filters can spend time exponential
+    // in the number of primitives, e.g. if each primitive takes the
+    // previous primitive as its two inputs.
+    return;
+  }
   mRequestedRect = mRequestedRect.Union(aRect);
   RequestFromInputsForRect(aRect);
 }
 
 void
 FilterNodeSoftware::RequestInputRect(uint32_t aInputEnumIndex, const IntRect &aRect)
 {
   if (aRect.Overflows()) {
--- a/gfx/src/DriverCrashGuard.h
+++ b/gfx/src/DriverCrashGuard.h
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef gfx_src_DriverCrashGuard_h__
 #define gfx_src_DriverCrashGuard_h__
 
-#include "gfxCore.h"
 #include "nsCOMPtr.h"
 #include "nsIGfxInfo.h"
 #include "nsIFile.h"
 #include "nsString.h"
 #include <string>
 
 namespace mozilla {
 
--- a/gfx/src/FilterSupport.cpp
+++ b/gfx/src/FilterSupport.cpp
@@ -342,38 +342,38 @@ FilterCachedColorModels::WrapForColorMod
   RefPtr<FilterNode> unpremultipliedOriginal =
     ForColorModel(ColorModel(mOriginalColorModel.mColorSpace, AlphaModel::Unpremultiplied));
   if (aColorModel.mColorSpace == ColorSpace::LinearRGB) {
     return FilterWrappers::SRGBToLinearRGB(mDT, unpremultipliedOriginal);
   }
   return FilterWrappers::LinearRGBToSRGB(mDT, unpremultipliedOriginal);
 }
 
+static const float identityMatrix[] =
+  { 1, 0, 0, 0, 0,
+    0, 1, 0, 0, 0,
+    0, 0, 1, 0, 0,
+    0, 0, 0, 1, 0 };
+
 // When aAmount == 0, the identity matrix is returned.
 // When aAmount == 1, aToMatrix is returned.
 // When aAmount > 1, an exaggerated version of aToMatrix is returned. This can
 // be useful in certain cases, such as producing a color matrix to oversaturate
 // an image.
 //
 // This function is a shortcut of a full matrix addition and a scalar multiply,
 // and it assumes that the following elements in aToMatrix are 0 and 1:
 //   x x x 0 0
 //   x x x 0 0
 //   x x x 0 0
 //   0 0 0 1 0
 static void
 InterpolateFromIdentityMatrix(const float aToMatrix[20], float aAmount,
                               float aOutMatrix[20])
 {
-  static const float identityMatrix[] =
-    { 1, 0, 0, 0, 0,
-      0, 1, 0, 0, 0,
-      0, 0, 1, 0, 0,
-      0, 0, 0, 1, 0 };
-
   PodCopy(aOutMatrix, identityMatrix, 20);
 
   float oneMinusAmount = 1 - aAmount;
 
   aOutMatrix[0] = aAmount * aToMatrix[0] + oneMinusAmount;
   aOutMatrix[1] = aAmount * aToMatrix[1];
   aOutMatrix[2] = aAmount * aToMatrix[2];
 
@@ -387,22 +387,16 @@ InterpolateFromIdentityMatrix(const floa
 }
 
 // Create a 4x5 color matrix for the different ways to specify color matrices
 // in SVG.
 static nsresult
 ComputeColorMatrix(uint32_t aColorMatrixType, const nsTArray<float>& aValues,
                    float aOutMatrix[20])
 {
-  static const float identityMatrix[] =
-    { 1, 0, 0, 0, 0,
-      0, 1, 0, 0, 0,
-      0, 0, 1, 0, 0,
-      0, 0, 0, 1, 0 };
-
   // Luminance coefficients.
   static const float lumR = 0.2126f;
   static const float lumG = 0.7152f;
   static const float lumB = 0.0722f;
 
   static const float oneMinusLumR = 1 - lumR;
   static const float oneMinusLumG = 1 - lumG;
   static const float oneMinusLumB = 1 - lumB;
@@ -755,17 +749,18 @@ FilterNodeFromPrimitiveDescription(const
       return filter.forget();
     }
 
     case PrimitiveType::ColorMatrix:
     {
       float colorMatrix[20];
       uint32_t type = atts.GetUint(eColorMatrixType);
       const nsTArray<float>& values = atts.GetFloats(eColorMatrixValues);
-      if (NS_FAILED(ComputeColorMatrix(type, values, colorMatrix))) {
+      if (NS_FAILED(ComputeColorMatrix(type, values, colorMatrix)) ||
+          PodEqual(colorMatrix, identityMatrix)) {
         RefPtr<FilterNode> filter(aSources[0]);
         return filter.forget();
       }
       Matrix5x4 matrix(colorMatrix[0], colorMatrix[5], colorMatrix[10],  colorMatrix[15],
                        colorMatrix[1], colorMatrix[6], colorMatrix[11],  colorMatrix[16],
                        colorMatrix[2], colorMatrix[7], colorMatrix[12],  colorMatrix[17],
                        colorMatrix[3], colorMatrix[8], colorMatrix[13],  colorMatrix[18],
                        colorMatrix[4], colorMatrix[9], colorMatrix[14],  colorMatrix[19]);
@@ -949,21 +944,25 @@ FilterNodeFromPrimitiveDescription(const
       return FilterWrappers::Offset(aDT, filter, atts.GetIntPoint(eTurbulenceOffset));
     }
 
     case PrimitiveType::Composite:
     {
       RefPtr<FilterNode> filter;
       uint32_t op = atts.GetUint(eCompositeOperator);
       if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
+        const nsTArray<float>& coefficients = atts.GetFloats(eCompositeCoefficients);
+        static const float allZero[4] = { 0, 0, 0, 0 };
         filter = aDT->CreateFilter(FilterType::ARITHMETIC_COMBINE);
-        if (!filter) {
+        // All-zero coefficients sometimes occur in junk filters.
+        if (!filter ||
+            (coefficients.Length() == ArrayLength(allZero) &&
+             PodEqual(coefficients.Elements(), allZero, ArrayLength(allZero)))) {
           return nullptr;
         }
-        const nsTArray<float>& coefficients = atts.GetFloats(eCompositeCoefficients);
         filter->SetAttribute(ATT_ARITHMETIC_COMBINE_COEFFICIENTS,
                              coefficients.Elements(), coefficients.Length());
         filter->SetInput(IN_ARITHMETIC_COMBINE_IN, aSources[0]);
         filter->SetInput(IN_ARITHMETIC_COMBINE_IN2, aSources[1]);
       } else {
         filter = aDT->CreateFilter(FilterType::COMPOSITE);
         if (!filter) {
           return nullptr;
--- a/gfx/src/X11Util.h
+++ b/gfx/src/X11Util.h
@@ -17,17 +17,16 @@
 #include "gfxQtPlatform.h"
 #undef CursorShape
 #  include <X11/Xlib.h>
 #else
 #  error Unknown toolkit
 #endif 
 
 #include <string.h>                     // for memset
-#include "gfxCore.h"                    // for NS_GFX
 #include "mozilla/Scoped.h"             // for SCOPED_TEMPLATE
 
 namespace mozilla {
 
 /**
  * Return the default X Display created and used by the UI toolkit.
  */
 inline Display*
@@ -86,17 +85,17 @@ SCOPED_TEMPLATE(ScopedXFree, ScopedXFree
  * Nesting is correctly handled: multiple nested ScopedXErrorHandler's don't interfere with each other's state. However,
  * if SyncAndGetError is not called on the nested ScopedXErrorHandler, then any X errors caused by X calls made while the nested
  * ScopedXErrorHandler was in place may then be caught by the other ScopedXErrorHandler. This is just a result of X being
  * asynchronous and us not doing any implicit syncing: the only method in this class what causes syncing is SyncAndGetError().
  *
  * This class is not thread-safe at all. It is assumed that only one thread is using any ScopedXErrorHandler's. Given that it's
  * not used on Mac, it should be easy to make it thread-safe by using thread-local storage with __thread.
  */
-class NS_GFX ScopedXErrorHandler
+class ScopedXErrorHandler
 {
 public:
     // trivial wrapper around XErrorEvent, just adding ctor initializing by zero.
     struct ErrorEvent
     {
         XErrorEvent mError;
 
         ErrorEvent()
deleted file mode 100644
--- a/gfx/src/gfxCore.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef gfxCore_h__
-#define gfxCore_h__
-
-#include "nscore.h"
-
-#define NS_GFX
-#define NS_GFX_(type) type
-#define NS_GFX_STATIC_MEMBER_(type) type
-
-#endif
--- a/gfx/src/gfxCrashReporterUtils.h
+++ b/gfx/src/gfxCrashReporterUtils.h
@@ -1,32 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef gfxCrashReporterUtils_h__
 #define gfxCrashReporterUtils_h__
 
-#include "gfxCore.h"
 
 namespace mozilla {
 
 /** \class ScopedGfxFeatureReporter
   *
   * On creation, adds "FeatureName?" to AppNotes
   * On destruction, adds "FeatureName-", or "FeatureName+" if you called SetSuccessful().
   *
   * Any such string is added at most once to AppNotes, and is subsequently skipped.
   *
   * This ScopedGfxFeatureReporter class is designed to be fool-proof to use in functions that
   * have many exit points. We don't want to encourage having function with many exit points.
   * It just happens that our graphics features initialization functions are like that.
   */
-class NS_GFX ScopedGfxFeatureReporter
+class ScopedGfxFeatureReporter
 {
 public:
   explicit ScopedGfxFeatureReporter(const char *aFeature, bool force = false)
     : mFeature(aFeature), mStatusChar('-')
   {
     WriteAppNote(force ? '!' : '?');
   }
   ~ScopedGfxFeatureReporter() {
--- a/gfx/src/moz.build
+++ b/gfx/src/moz.build
@@ -11,17 +11,16 @@ XPIDL_SOURCES += [
 
 XPIDL_MODULE = 'gfx'
 
 DEFINES['MOZ_APP_VERSION'] = '"%s"' % CONFIG['MOZ_APP_VERSION']
 
 EXPORTS += [
     'DriverCrashGuard.h',
     'FilterSupport.h',
-    'gfxCore.h',
     'gfxCrashReporterUtils.h',
     'gfxTelemetry.h',
     'nsBoundingMetrics.h',
     'nsColor.h',
     'nsColorNameList.h',
     'nsColorNames.h',
     'nsCoord.h',
     'nsDeviceContext.h',
--- a/gfx/src/nsColor.cpp
+++ b/gfx/src/nsColor.cpp
@@ -70,18 +70,17 @@ static int ComponentValue(const char16_t
     }
     else {  // not a hex digit, treat it like 0
       component = (component * 16);
     }
   }
   return component;
 }
 
-NS_GFX_(bool) NS_HexToRGB(const nsAString& aColorSpec,
-                                       nscolor* aResult)
+bool NS_HexToRGB(const nsAString& aColorSpec, nscolor* aResult)
 {
   const char16_t* buffer = aColorSpec.BeginReading();
 
   int nameLen = aColorSpec.Length();
   if ((nameLen == 3) || (nameLen == 6)) {
     // Make sure the digits are legal
     for (int i = 0; i < nameLen; i++) {
       char16_t ch = buffer[i];
@@ -116,17 +115,17 @@ NS_GFX_(bool) NS_HexToRGB(const nsAStrin
   }
 
   // Improperly formatted color value
   return false;
 }
 
 // This implements part of the algorithm for legacy behavior described in
 // http://www.whatwg.org/specs/web-apps/current-work/complete/common-microsyntaxes.html#rules-for-parsing-a-legacy-color-value
-NS_GFX_(bool) NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
+bool NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
 {
   if (aColorSpec.EqualsLiteral("transparent")) {
     return false;
   }
 
   int nameLen = aColorSpec.Length();
   const char16_t* colorSpec = aColorSpec.get();
   if (nameLen > 128) {
@@ -180,17 +179,17 @@ NS_GFX_(bool) NS_LooseHexToRGB(const nsS
   NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
   NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
   NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
 
   *aResult = NS_RGB(r, g, b);
   return true;
 }
 
-NS_GFX_(bool) NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
+bool NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
 {
   if (!gColorTable) return false;
 
   int32_t id = gColorTable->Lookup(aColorName);
   if (eColorName_UNKNOWN < id) {
     NS_ASSERTION(uint32_t(id) < eColorName_COUNT,
                  "gColorTable->Lookup messed up");
     if (aResult) {
@@ -198,29 +197,29 @@ NS_GFX_(bool) NS_ColorNameToRGB(const ns
     }
     return true;
   }
   return false;
 }
 
 // Returns kColorNames, an array of all possible color names, and sets
 // *aSizeArray to the size of that array. Do NOT call free() on this array.
-NS_GFX_(const char * const *) NS_AllColorNames(size_t *aSizeArray)
+const char * const * NS_AllColorNames(size_t *aSizeArray)
 {
   *aSizeArray = ArrayLength(kColorNames);
   return kColorNames;
 }
 
 // Macro to blend two colors
 //
 // equivalent to target = (bg*(255-fgalpha) + fg*fgalpha)/255
 #define MOZ_BLEND(target, bg, fg, fgalpha)       \
   FAST_DIVIDE_BY_255(target, (bg)*(255-fgalpha) + (fg)*(fgalpha))
 
-NS_GFX_(nscolor)
+nscolor
 NS_ComposeColors(nscolor aBG, nscolor aFG)
 {
   // This function uses colors that are non premultiplied alpha.
   int r, g, b, a;
 
   int bgAlpha = NS_GET_A(aBG);
   int fgAlpha = NS_GET_A(aFG);
 
@@ -259,34 +258,34 @@ HSL_HueToRGB(float m1, float m2, float h
   if (h < (float)(1.0/2.0))
     return m2;
   if (h < (float)(2.0/3.0))
     return m1 + (m2 - m1)*((float)(2.0/3.0) - h)*6.0f;
   return m1;      
 }
 
 // The float parameters are all expected to be in the range 0-1
-NS_GFX_(nscolor)
+nscolor
 NS_HSL2RGB(float h, float s, float l)
 {
   uint8_t r, g, b;
   float m1, m2;
   if (l <= 0.5f) {
     m2 = l*(s+1);
   } else {
     m2 = l + s - l*s;
   }
   m1 = l*2 - m2;
   r = uint8_t(255 * HSL_HueToRGB(m1, m2, h + 1.0f/3.0f));
   g = uint8_t(255 * HSL_HueToRGB(m1, m2, h));
   b = uint8_t(255 * HSL_HueToRGB(m1, m2, h - 1.0f/3.0f));
   return NS_RGB(r, g, b);  
 }
 
-NS_GFX_(const char*)
+const char*
 NS_RGBToColorName(nscolor aColor)
 {
   for (size_t idx = 0; idx < ArrayLength(kColors); ++idx) {
     if (kColors[idx] == aColor) {
       return kColorNames[idx];
     }
   }
 
--- a/gfx/src/nsColor.h
+++ b/gfx/src/nsColor.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsColor_h___
 #define nsColor_h___
 
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint8_t, uint32_t
-#include "gfxCore.h"                    // for NS_GFX_
 #include "nscore.h"                     // for nsAString
 
 class nsAString;
 class nsString;
 
 // A color is a 32 bit unsigned integer with four components: R, G, B
 // and A.
 typedef uint32_t nscolor;
@@ -48,42 +47,42 @@ typedef uint32_t nscolor;
   PR_BEGIN_MACRO                                   \
     unsigned tmp_ = v;                             \
     target = ((tmp_ << 8) + tmp_ + 255) >> 16;     \
   PR_END_MACRO
 
 // Translate a hex string to a color. Return true if it parses ok,
 // otherwise return false.
 // This accepts only 3 or 6 digits
-NS_GFX_(bool) NS_HexToRGB(const nsAString& aBuf, nscolor* aResult);
+bool NS_HexToRGB(const nsAString& aBuf, nscolor* aResult);
 
 // Compose one NS_RGB color onto another. The result is what
 // you get if you draw aFG on top of aBG with operator OVER.
-NS_GFX_(nscolor) NS_ComposeColors(nscolor aBG, nscolor aFG);
+nscolor NS_ComposeColors(nscolor aBG, nscolor aFG);
 
 // Translate a hex string to a color. Return true if it parses ok,
 // otherwise return false.
 // This version accepts 1 to 9 digits (missing digits are 0)
-NS_GFX_(bool) NS_LooseHexToRGB(const nsString& aBuf, nscolor* aResult);
+bool NS_LooseHexToRGB(const nsString& aBuf, nscolor* aResult);
 
 // There is no function to translate a color to a hex string, because
 // the hex-string syntax does not support transparency.
 
 // Translate a color name to a color. Return true if it parses ok,
 // otherwise return false.
-NS_GFX_(bool) NS_ColorNameToRGB(const nsAString& aBuf, nscolor* aResult);
+bool NS_ColorNameToRGB(const nsAString& aBuf, nscolor* aResult);
 
 // Returns an array of all possible color names, and sets
 // *aSizeArray to the size of that array. Do NOT call |free()| on this array.
-NS_GFX_(const char * const *) NS_AllColorNames(size_t *aSizeArray);
+const char * const * NS_AllColorNames(size_t *aSizeArray);
 
 // function to convert from HSL color space to RGB color space
 // the float parameters are all expected to be in the range 0-1
-NS_GFX_(nscolor) NS_HSL2RGB(float h, float s, float l);
+nscolor NS_HSL2RGB(float h, float s, float l);
 
 // Return a color name for the given nscolor.  If there is no color
 // name for it, returns null.  If there are multiple possible color
 // names for the given color, the first one in nsColorNameList.h
 // (which is generally the first one in alphabetical order) will be
 // returned.
-NS_GFX_(const char*) NS_RGBToColorName(nscolor aColor);
+const char* NS_RGBToColorName(nscolor aColor);
 
 #endif /* nsColor_h___ */
--- a/gfx/src/nsColorNames.h
+++ b/gfx/src/nsColorNames.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsColorNames_h___
 #define nsColorNames_h___
 
-#include "gfxCore.h"
 
-class NS_GFX nsColorNames {
+class nsColorNames {
 public:
   static void AddRefTable(void);
   static void ReleaseTable(void);
 };
 
 #endif /* nsColorNames_h___ */
--- a/gfx/src/nsFont.h
+++ b/gfx/src/nsFont.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsFont_h___
 #define nsFont_h___
 
 #include <stdint.h>                     // for uint8_t, uint16_t
 #include <sys/types.h>                  // for int16_t
-#include "gfxCore.h"                    // for NS_GFX
 #include "gfxFontFamilyList.h"
 #include "gfxFontFeatures.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCoord.h"                    // for nscoord
 #include "nsStringFwd.h"                // for nsSubstring
 #include "nsString.h"               // for nsString
 #include "nsTArray.h"                   // for nsTArray
 
@@ -35,17 +34,17 @@ const uint8_t kGenericFont_moz_fixed    
 // CSS
 const uint8_t kGenericFont_serif        = 0x02;
 const uint8_t kGenericFont_sans_serif   = 0x04;
 const uint8_t kGenericFont_monospace    = 0x08;
 const uint8_t kGenericFont_cursive      = 0x10;
 const uint8_t kGenericFont_fantasy      = 0x20;
 
 // Font structure.
-struct NS_GFX nsFont {
+struct nsFont {
 
   // list of font families, either named or generic
   mozilla::FontFamilyList fontlist;
 
   // The style of font (normal, italic, oblique; see gfxFontConstants.h)
   uint8_t style;
 
   // Force this font to not be considered a 'generic' font, even if
--- a/gfx/src/nsMargin.h
+++ b/gfx/src/nsMargin.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NSMARGIN_H
 #define NSMARGIN_H
 
 #include "nsCoord.h"
 #include "nsPoint.h"
-#include "gfxCore.h"
 #include "mozilla/gfx/BaseMargin.h"
 
 struct nsMargin : public mozilla::gfx::BaseMargin<nscoord, nsMargin> {
   typedef mozilla::gfx::BaseMargin<nscoord, nsMargin> Super;
 
   // Constructors
   nsMargin() : Super() {}
   nsMargin(const nsMargin& aMargin) : Super(aMargin) {}
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -5,31 +5,30 @@
 
 
 #ifndef NSRECT_H
 #define NSRECT_H
 
 #include <stdio.h>                      // for FILE
 #include <stdint.h>                     // for int32_t, int64_t
 #include <algorithm>                    // for min/max
-#include "gfxCore.h"                    // for NS_GFX
 #include "mozilla/Likely.h"             // for MOZ_UNLIKELY
 #include "mozilla/gfx/Rect.h"
 #include "nsCoord.h"                    // for nscoord, etc
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsPoint.h"                    // for nsIntPoint, nsPoint
 #include "nsSize.h"                     // for IntSize, nsSize
 #include "nscore.h"                     // for NS_BUILD_REFCNT_LOGGING
 
 struct nsMargin;
 struct nsIntMargin;
 
 typedef mozilla::gfx::IntRect nsIntRect;
 
-struct NS_GFX nsRect :
+struct nsRect :
   public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
   typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
 
   static void VERIFY_COORD(nscoord aValue) { ::VERIFY_COORD(aValue); }
 
   // Constructors
   nsRect() : Super()
   {
@@ -285,12 +284,12 @@ nsRect::ToInsidePixels(nscoord aAppUnits
 const mozilla::gfx::IntRect& GetMaxSizedIntRect();
 
 // app units are integer multiples of pixels, so no rounding needed
 nsRect
 ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel);
 
 #ifdef DEBUG
 // Diagnostics
-extern NS_GFX FILE* operator<<(FILE* out, const nsRect& rect);
+extern FILE* operator<<(FILE* out, const nsRect& rect);
 #endif // DEBUG
 
 #endif /* NSRECT_H */
--- a/gfx/src/nsRegion.h
+++ b/gfx/src/nsRegion.h
@@ -4,17 +4,16 @@
 
 
 #ifndef nsRegion_h__
 #define nsRegion_h__
 
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint32_t, uint64_t
 #include <sys/types.h>                  // for int32_t
-#include "gfxCore.h"                    // for NS_GFX
 #include "mozilla/ToString.h"           // for mozilla::ToString
 #include "nsCoord.h"                    // for nscoord
 #include "nsError.h"                    // for nsresult
 #include "nsPoint.h"                    // for nsIntPoint, nsPoint
 #include "nsRect.h"                     // for mozilla::gfx::IntRect, nsRect
 #include "nsMargin.h"                   // for nsIntMargin
 #include "nsStringGlue.h"               // for nsCString
 #include "xpcom-config.h"               // for CPP_THROW_NEW
@@ -415,17 +414,17 @@ private:
   pixman_region32_t* Impl() const
   {
     return const_cast<pixman_region32_t*>(&mImpl);
   }
 
 };
 
 
-class NS_GFX nsRegionRectIterator
+class nsRegionRectIterator
 {
   const nsRegion*  mRegion;
   int i;
   int n;
   nsRect rect;
   pixman_box32_t *boxes;
 
 public:
@@ -469,17 +468,17 @@ public:
 
 namespace mozilla {
 namespace gfx {
 
 /**
  * BaseIntRegions use int32_t coordinates.
  */
 template <typename Derived, typename Rect, typename Point, typename Margin>
-class NS_GFX BaseIntRegion
+class BaseIntRegion
 {
   friend class ::nsRegion;
 
 public:
   typedef Rect RectType;
   typedef Point PointType;
   typedef Margin MarginType;
 
@@ -758,17 +757,17 @@ public:
   typedef void (*visitFn)(void *closure, VisitSide side, int x1, int y1, int x2, int y2);
   void VisitEdges (visitFn visit, void *closure)
   {
     mImpl.VisitEdges (visit, closure);
   }
 
   nsCString ToString() const { return mImpl.ToString(); }
 
-  class NS_GFX RectIterator
+  class RectIterator
   {
     nsRegionRectIterator mImpl;
     Rect mTmp;
 
   public:
     explicit RectIterator (const BaseIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
 
     const Rect* Next ()
@@ -820,17 +819,17 @@ private:
   {
     return *static_cast<const Derived*>(this);
   }
 };
 
 } // namespace gfx
 } // namespace mozilla
 
-class NS_GFX nsIntRegion : public mozilla::gfx::BaseIntRegion<nsIntRegion, mozilla::gfx::IntRect, nsIntPoint, nsIntMargin>
+class nsIntRegion : public mozilla::gfx::BaseIntRegion<nsIntRegion, mozilla::gfx::IntRect, nsIntPoint, nsIntMargin>
 {
 public:
   // Forward constructors.
   nsIntRegion() {}
   MOZ_IMPLICIT nsIntRegion(const mozilla::gfx::IntRect& aRect) : BaseIntRegion(aRect) {}
   nsIntRegion(const nsIntRegion& aRegion) : BaseIntRegion(aRegion) {}
   nsIntRegion(nsIntRegion&& aRegion) : BaseIntRegion(mozilla::Move(aRegion)) {}
 
--- a/gfx/src/nsScriptableRegion.h
+++ b/gfx/src/nsScriptableRegion.h
@@ -3,22 +3,21 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsScriptableRegion_h
 #define nsScriptableRegion_h
 
 #include "nsIScriptableRegion.h"
-#include "gfxCore.h"
 #include "nsISupports.h"
 #include "nsRegion.h"
 #include "mozilla/Attributes.h"
 
-class NS_GFX nsScriptableRegion final : public nsIScriptableRegion {
+class nsScriptableRegion final : public nsIScriptableRegion {
 public:
 	nsScriptableRegion();
 
 	NS_DECL_ISUPPORTS
 
 	NS_DECL_NSISCRIPTABLEREGION
 
 private:
--- a/gfx/src/nsTransform2D.h
+++ b/gfx/src/nsTransform2D.h
@@ -1,20 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTransform2D_h___
 #define nsTransform2D_h___
 
-#include "gfxCore.h"
 #include "nsCoord.h"
 
-class NS_GFX nsTransform2D
+class nsTransform2D
 {
 private:
  /**
   * This represents the following matrix (note that the order of row/column
   * indices is opposite to usual notation)
   *
   *      / m00   0   m20  \
   * M =  |  0   m11  m21  |
--- a/gfx/ycbcr/QuellGccWarnings.patch
+++ b/gfx/ycbcr/QuellGccWarnings.patch
@@ -1,12 +1,12 @@
 diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
 --- a/gfx/ycbcr/yuv_convert.cpp
 +++ b/gfx/ycbcr/yuv_convert.cpp
-@@ -337,16 +337,17 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const ui
+@@ -337,16 +337,17 @@ void ScaleYCbCrToRGB32(const uint* yplan
                                           source_dx_uv >> kFractionBits);
          }
        }
        else {
          ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
                               dest_pixel, width, source_dx);
        }
  #else
--- a/gfx/ycbcr/TypeFromSize.patch
+++ b/gfx/ycbcr/TypeFromSize.patch
@@ -5,54 +5,54 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b
  
  namespace gfx {
   
  // 16.16 fixed point arithmetic
  const int kFractionBits = 16;
  const int kFractionMax = 1 << kFractionBits;
  const int kFractionMask = ((1 << kFractionBits) - 1);
  
-+NS_GFX_(YUVType) TypeFromSize(int ywidth, 
-+                              int yheight, 
-+                              int cbcrwidth, 
-+                              int cbcrheight)
++YUVType TypeFromSize(int ywidth, 
++                     int yheight, 
++                     int cbcrwidth, 
++                     int cbcrheight)
 +{
 +  if (ywidth == cbcrwidth && yheight == cbcrheight) {
 +    return YV24;
 +  }
 +  else if (ywidth / 2 == cbcrwidth && yheight == cbcrheight) {
 +    return YV16;
 +  }
 +  else {
 +    return YV12;
 +  }
 +}
 +
  // Convert a frame of YUV to 32 bit ARGB.
- NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
-                                   const uint8* u_buf,
-                                   const uint8* v_buf,
-                                   uint8* rgb_buf,
-                                   int pic_x,
-                                   int pic_y,
-                                   int pic_width,
+ void ConvertYCbCrToRGB32(const uint8* y_buf,
+                          const uint8* u_buf,
+                          const uint8* v_buf,
+                          uint8* rgb_buf,
+                          int pic_x,
+                          int pic_y,
+                          int pic_width,
 diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
 --- a/gfx/ycbcr/yuv_convert.h
 +++ b/gfx/ycbcr/yuv_convert.h
 @@ -36,16 +36,18 @@ enum Rotate {
  // Filter affects how scaling looks.
  enum ScaleFilter {
    FILTER_NONE = 0,        // No filter (point sampled).
    FILTER_BILINEAR_H = 1,  // Bilinear horizontal filter.
    FILTER_BILINEAR_V = 2,  // Bilinear vertical filter.
    FILTER_BILINEAR = 3     // Bilinear filter.
  };
  
-+NS_GFX_(YUVType) TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
++YUVType TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
 +
  // Convert a frame of YUV to 32 bit ARGB.
  // Pass in YV16/YV12 depending on source format
- NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
-                                   const uint8* uplane,
-                                   const uint8* vplane,
-                                   uint8* rgbframe,
-                                   int pic_x,
-                                   int pic_y,
+ void ConvertYCbCrToRGB32(const uint8* yplane,
+                          const uint8* uplane,
+                          const uint8* vplane,
+                          uint8* rgbframe,
+                          int pic_x,
+                          int pic_y,
--- a/gfx/ycbcr/convert.patch
+++ b/gfx/ycbcr/convert.patch
@@ -66,28 +66,28 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b
 -    const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch;
 -
 -    FastConvertYUVToRGB32Row(y_ptr,
 -                             u_ptr,
 -                             v_ptr,
 -                             rgb_row,
 -                             width);
 -  }
-+NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
-+                                  const uint8* u_buf,
-+                                  const uint8* v_buf,
-+                                  uint8* rgb_buf,
-+                                  int pic_x,
-+                                  int pic_y,
-+                                  int pic_width,
-+                                  int pic_height,
-+                                  int y_pitch,
-+                                  int uv_pitch,
-+                                  int rgb_pitch,
-+                                  YUVType yuv_type) {
++void ConvertYCbCrToRGB32(const uint8* y_buf,
++                         const uint8* u_buf,
++                         const uint8* v_buf,
++                         uint8* rgb_buf,
++                         int pic_x,
++                         int pic_y,
++                         int pic_width,
++                         int pic_height,
++                         int y_pitch,
++                         int uv_pitch,
++                         int rgb_pitch,
++                         YUVType yuv_type) {
 +  unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
 +  unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
 +  // Test for SSE because the optimized code uses movntq, which is not part of MMX.
 +  bool has_sse = supports_mmx() && supports_sse();
 +  // There is no optimized YV24 SSE routine so we check for this and
 +  // fall back to the C code.
 +  has_sse &= yuv_type != YV24;
 +  bool odd_pic_x = yuv_type != YV24 && pic_x % 2 != 0;
@@ -270,30 +270,30 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b
 -                     int width,
 -                     int height,
 -                     int y_pitch,
 -                     int uv_pitch,
 -                     int rgb_pitch,
 -                     YUVType yuv_type,
 -                     Rotate view_rotate,
 -                     ScaleFilter filter) {
-+NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf,
-+                                const uint8* u_buf,
-+                                const uint8* v_buf,
-+                                uint8* rgb_buf,
-+                                int source_width,
-+                                int source_height,
-+                                int width,
-+                                int height,
-+                                int y_pitch,
-+                                int uv_pitch,
-+                                int rgb_pitch,
-+                                YUVType yuv_type,
-+                                Rotate view_rotate,
-+                                ScaleFilter filter) {
++void ScaleYCbCrToRGB32(const uint8* y_buf,
++                       const uint8* u_buf,
++                       const uint8* v_buf,
++                       uint8* rgb_buf,
++                       int source_width,
++                       int source_height,
++                       int width,
++                       int height,
++                       int y_pitch,
++                       int uv_pitch,
++                       int rgb_pitch,
++                       YUVType yuv_type,
++                       Rotate view_rotate,
++                       ScaleFilter filter) {
 +  bool has_mmx = supports_mmx();
 +
    // 4096 allows 3 buffers to fit in 12k.
    // Helps performance on CPU with 16K L1 cache.
    // Large enough for 3830x2160 and 30" displays which are 2560x1600.
    const int kFilterBufferSize = 4096;
    // Disable filtering if the screen is too big (to avoid buffer overflows).
    // This should never happen to regular users: they don't have monitors
@@ -464,28 +464,28 @@ diff --git a/gfx/ycbcr/yuv_convert.h b/g
 -                       const uint8* vplane,
 -                       uint8* rgbframe,
 -                       int width,
 -                       int height,
 -                       int ystride,
 -                       int uvstride,
 -                       int rgbstride,
 -                       YUVType yuv_type);
-+NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
-+                                  const uint8* uplane,
-+                                  const uint8* vplane,
-+                                  uint8* rgbframe,
-+                                  int pic_x,
-+                                  int pic_y,
-+                                  int pic_width,
-+                                  int pic_height,
-+                                  int ystride,
-+                                  int uvstride,
-+                                  int rgbstride,
-+                                  YUVType yuv_type);
++void ConvertYCbCrToRGB32(const uint8* yplane,
++                         const uint8* uplane,
++                         const uint8* vplane,
++                         uint8* rgbframe,
++                         int pic_x,
++                         int pic_y,
++                         int pic_width,
++                         int pic_height,
++                         int ystride,
++                         int uvstride,
++                         int rgbstride,
++                         YUVType yuv_type);
  
  // Scale a frame of YUV to 32 bit ARGB.
  // Supports rotation and mirroring.
 -void ScaleYUVToRGB32(const uint8* yplane,
 -                     const uint8* uplane,
 -                     const uint8* vplane,
 -                     uint8* rgbframe,
 -                     int source_width,
@@ -496,30 +496,30 @@ diff --git a/gfx/ycbcr/yuv_convert.h b/g
 -                     int uvstride,
 -                     int rgbstride,
 -                     YUVType yuv_type,
 -                     Rotate view_rotate,
 -                     ScaleFilter filter);
 -
 -}  // namespace media
 -
-+NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane,
-+                                const uint8* uplane,
-+                                const uint8* vplane,
-+                                uint8* rgbframe,
-+                                int source_width,
-+                                int source_height,
-+                                int width,
-+                                int height,
-+                                int ystride,
-+                                int uvstride,
-+                                int rgbstride,
-+                                YUVType yuv_type,
-+                                Rotate view_rotate,
-+                                ScaleFilter filter);
++void ScaleYCbCrToRGB32(const uint8* yplane,
++                       const uint8* uplane,
++                       const uint8* vplane,
++                       uint8* rgbframe,
++                       int source_width,
++                       int source_height,
++                       int width,
++                       int height,
++                       int ystride,
++                       int uvstride,
++                       int rgbstride,
++                       YUVType yuv_type,
++                       Rotate view_rotate,
++                       ScaleFilter filter);
 +
 +}  // namespace gfx
 +}  // namespace mozilla
 + 
  #endif  // MEDIA_BASE_YUV_CONVERT_H_
 diff --git a/gfx/ycbcr/yuv_convert_mmx.cpp b/gfx/ycbcr/yuv_convert_mmx.cpp
 new file mode 100644
 --- /dev/null
--- a/gfx/ycbcr/ycbcr_to_rgb565.cpp
+++ b/gfx/ycbcr/ycbcr_to_rgb565.cpp
@@ -276,17 +276,17 @@ static void ScaleYCbCr444ToRGB565_Neares
     y = ctx->y_row[source_x];
     u = ctx->u_row[source_x];
     v = ctx->v_row[source_x];
     ctx->rgb_row[x] = yu2rgb565(y, u, v, dither);
     dither ^= 3;
   }
 }
 
-NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *y_buf,
+void ScaleYCbCrToRGB565(const uint8_t *y_buf,
                                  const uint8_t *u_buf,
                                  const uint8_t *v_buf,
                                  uint8_t *rgb_buf,
                                  int source_x0,
                                  int source_y0,
                                  int source_width,
                                  int source_height,
                                  int width,
@@ -532,17 +532,17 @@ NS_GFX_(void) ScaleYCbCrToRGB565(const u
       ctx.y_yweight = yweight;
       ctx.uv_yweight = uvweight;
       (*scale_row)(&ctx, dither);
       dither ^= 2;
     }
   }
 }
 
-NS_GFX_(bool) IsScaleYCbCrToRGB565Fast(int source_x0,
+bool IsScaleYCbCrToRGB565Fast(int source_x0,
                                        int source_y0,
                                        int source_width,
                                        int source_height,
                                        int width,
                                        int height,
                                        YUVType yuv_type,
                                        ScaleFilter filter)
 {
@@ -594,17 +594,17 @@ void yuv_to_rgb565_row_c(uint16 *dst,
   {
     dst[x] = yu2rgb565(y[pic_x+x],
                        u[(pic_x+x)>>x_shift],
                        v[(pic_x+x)>>x_shift],
                        2); // Disable dithering for now.
   }
 }
 
-NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* y_buf,
+void ConvertYCbCrToRGB565(const uint8* y_buf,
                                    const uint8* u_buf,
                                    const uint8* v_buf,
                                    uint8* rgb_buf,
                                    int pic_x,
                                    int pic_y,
                                    int pic_width,
                                    int pic_height,
                                    int y_pitch,
@@ -647,17 +647,17 @@ NS_GFX_(void) ConvertYCbCrToRGB565(const
                           v_buf + uvoffs,
                           x_shift,
                           pic_x,
                           pic_width);
     }
   }
 }
 
-NS_GFX_(bool) IsConvertYCbCrToRGB565Fast(int pic_x,
+bool IsConvertYCbCrToRGB565Fast(int pic_x,
                                          int pic_y,
                                          int pic_width,
                                          int pic_height,
                                          YUVType yuv_type)
 {
 #  if defined(MOZILLA_MAY_SUPPORT_NEON)
   return (yuv_type != YV24 && supports_neon());
 #  else
--- a/gfx/ycbcr/ycbcr_to_rgb565.h
+++ b/gfx/ycbcr/ycbcr_to_rgb565.h
@@ -12,55 +12,55 @@
 #endif
 
 namespace mozilla {
 
 namespace gfx {
 
 #ifdef HAVE_YCBCR_TO_RGB565
 // Convert a frame of YUV to 16 bit RGB565.
-NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* yplane,
+void ConvertYCbCrToRGB565(const uint8* yplane,
                                    const uint8* uplane,
                                    const uint8* vplane,
                                    uint8* rgbframe,
                                    int pic_x,
                                    int pic_y,
                                    int pic_width,
                                    int pic_height,
                                    int ystride,
                                    int uvstride,
                                    int rgbstride,
                                    YUVType yuv_type);
 
 // Used to test if we have an accelerated version.
-NS_GFX_(bool) IsConvertYCbCrToRGB565Fast(int pic_x,
+bool IsConvertYCbCrToRGB565Fast(int pic_x,
                                          int pic_y,
                                          int pic_width,
                                          int pic_height,
                                          YUVType yuv_type);
 
 // Scale a frame of YUV to 16 bit RGB565.
-NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *yplane,
+void ScaleYCbCrToRGB565(const uint8_t *yplane,
                                  const uint8_t *uplane,
                                  const uint8_t *vplane,
                                  uint8_t *rgbframe,
                                  int source_x0,
                                  int source_y0,
                                  int source_width,
                                  int source_height,
                                  int width,
                                  int height,
                                  int ystride,
                                  int uvstride,
                                  int rgbstride,
                                  YUVType yuv_type,
                                  ScaleFilter filter);
 
 // Used to test if we have an accelerated version.
-NS_GFX_(bool) IsScaleYCbCrToRGB565Fast(int source_x0,
+bool IsScaleYCbCrToRGB565Fast(int source_x0,
                                        int source_y0,
                                        int source_width,
                                        int source_height,
                                        int width,
                                        int height,
                                        YUVType yuv_type,
                                        ScaleFilter filter);
 #endif // HAVE_YCBCR_TO_RGB565
--- a/gfx/ycbcr/yuv_convert.cpp
+++ b/gfx/ycbcr/yuv_convert.cpp
@@ -26,45 +26,45 @@ namespace mozilla {
 
 namespace gfx {
  
 // 16.16 fixed point arithmetic
 const int kFractionBits = 16;
 const int kFractionMax = 1 << kFractionBits;
 const int kFractionMask = ((1 << kFractionBits) - 1);
 
-NS_GFX_(YUVType) TypeFromSize(int ywidth, 
+YUVType TypeFromSize(int ywidth, 
                               int yheight, 
                               int cbcrwidth, 
                               int cbcrheight)
 {
   if (ywidth == cbcrwidth && yheight == cbcrheight) {
     return YV24;
   }
   else if (ywidth / 2 == cbcrwidth && yheight == cbcrheight) {
     return YV16;
   }
   else {
     return YV12;
   }
 }
 
 // Convert a frame of YUV to 32 bit ARGB.
-NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
-                                  const uint8* u_buf,
-                                  const uint8* v_buf,
-                                  uint8* rgb_buf,
-                                  int pic_x,
-                                  int pic_y,
-                                  int pic_width,
-                                  int pic_height,
-                                  int y_pitch,
-                                  int uv_pitch,
-                                  int rgb_pitch,
-                                  YUVType yuv_type) {
+void ConvertYCbCrToRGB32(const uint8* y_buf,
+                         const uint8* u_buf,
+                         const uint8* v_buf,
+                         uint8* rgb_buf,
+                         int pic_x,
+                         int pic_y,
+                         int pic_width,
+                         int pic_height,
+                         int y_pitch,
+                         int uv_pitch,
+                         int rgb_pitch,
+                         YUVType yuv_type) {
   unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
   unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
   // Test for SSE because the optimized code uses movntq, which is not part of MMX.
   bool has_sse = supports_mmx() && supports_sse();
   // There is no optimized YV24 SSE routine so we check for this and
   // fall back to the C code.
   has_sse &= yuv_type != YV24;
   bool odd_pic_x = yuv_type != YV24 && pic_x % 2 != 0;
@@ -158,30 +158,30 @@ static inline void FilterRows(uint8* ybu
   }
 #endif
 
   FilterRows_C(ybuf, y0_ptr, y1_ptr, source_width, source_y_fraction);
 }
 
 
 // Scale a frame of YUV to 32 bit ARGB.
-NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf,
-                                const uint8* u_buf,
-                                const uint8* v_buf,
-                                uint8* rgb_buf,
-                                int source_width,
-                                int source_height,
-                                int width,
-                                int height,
-                                int y_pitch,
-                                int uv_pitch,
-                                int rgb_pitch,
-                                YUVType yuv_type,
-                                Rotate view_rotate,
-                                ScaleFilter filter) {
+void ScaleYCbCrToRGB32(const uint8* y_buf,
+                       const uint8* u_buf,
+                       const uint8* v_buf,
+                       uint8* rgb_buf,
+                       int source_width,
+                       int source_height,
+                       int width,
+                       int height,
+                       int y_pitch,
+                       int uv_pitch,
+                       int rgb_pitch,
+                       YUVType yuv_type,
+                       Rotate view_rotate,
+                       ScaleFilter filter) {
   bool has_mmx = supports_mmx();
 
   // 4096 allows 3 buffers to fit in 12k.
   // Helps performance on CPU with 16K L1 cache.
   // Large enough for 3830x2160 and 30" displays which are 2560x1600.
   const int kFilterBufferSize = 4096;
   // Disable filtering if the screen is too big (to avoid buffer overflows).
   // This should never happen to regular users: they don't have monitors
--- a/gfx/ycbcr/yuv_convert.h
+++ b/gfx/ycbcr/yuv_convert.h
@@ -1,17 +1,16 @@
 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef MEDIA_BASE_YUV_CONVERT_H_
 #define MEDIA_BASE_YUV_CONVERT_H_
 
 #include "chromium_types.h"
-#include "gfxCore.h"
 
 namespace mozilla {
 
 namespace gfx {
  
 // Type of YUV surface.
 // The value of these enums matter as they are used to shift vertical indices.
 enum YUVType {
@@ -36,46 +35,46 @@ enum Rotate {
 // Filter affects how scaling looks.
 enum ScaleFilter {
   FILTER_NONE = 0,        // No filter (point sampled).
   FILTER_BILINEAR_H = 1,  // Bilinear horizontal filter.
   FILTER_BILINEAR_V = 2,  // Bilinear vertical filter.
   FILTER_BILINEAR = 3     // Bilinear filter.
 };
 
-NS_GFX_(YUVType) TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
+YUVType TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
 
 // Convert a frame of YUV to 32 bit ARGB.
 // Pass in YV16/YV12 depending on source format
-NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
-                                  const uint8* uplane,
-                                  const uint8* vplane,
-                                  uint8* rgbframe,
-                                  int pic_x,
-                                  int pic_y,
-                                  int pic_width,
-                                  int pic_height,
-                                  int ystride,
-                                  int uvstride,
-                                  int rgbstride,
-                                  YUVType yuv_type);
+void ConvertYCbCrToRGB32(const uint8* yplane,
+                         const uint8* uplane,
+                         const uint8* vplane,
+                         uint8* rgbframe,
+                         int pic_x,
+                         int pic_y,
+                         int pic_width,
+                         int pic_height,
+                         int ystride,
+                         int uvstride,
+                         int rgbstride,
+                         YUVType yuv_type);
 
 // Scale a frame of YUV to 32 bit ARGB.
 // Supports rotation and mirroring.
-NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane,
-                                const uint8* uplane,
-                                const uint8* vplane,
-                                uint8* rgbframe,
-                                int source_width,
-                                int source_height,
-                                int width,
-                                int height,
-                                int ystride,
-                                int uvstride,
-                                int rgbstride,
-                                YUVType yuv_type,
-                                Rotate view_rotate,
-                                ScaleFilter filter);
+void ScaleYCbCrToRGB32(const uint8* yplane,
+                       const uint8* uplane,
+                       const uint8* vplane,
+                       uint8* rgbframe,
+                       int source_width,
+                       int source_height,
+                       int width,
+                       int height,
+                       int ystride,
+                       int uvstride,
+                       int rgbstride,
+                       YUVType yuv_type,
+                       Rotate view_rotate,
+                       ScaleFilter filter);
 
 } // namespace gfx
 } // namespace mozilla
  
 #endif  // MEDIA_BASE_YUV_CONVERT_H_
--- a/image/Decoder.cpp
+++ b/image/Decoder.cpp
@@ -413,19 +413,20 @@ void
 Decoder::PostIsAnimated(int32_t aFirstFrameTimeout)
 {
   mProgress |= FLAG_IS_ANIMATED;
   mImageMetadata.SetHasAnimation();
   mImageMetadata.SetFirstFrameTimeout(aFirstFrameTimeout);
 }
 
 void
-Decoder::PostFrameStop(Opacity aFrameOpacity    /* = Opacity::TRANSPARENT */,
+Decoder::PostFrameStop(Opacity aFrameOpacity
+                         /* = Opacity::SOME_TRANSPARENCY */,
                        DisposalMethod aDisposalMethod
-                                                /* = DisposalMethod::KEEP */,
+                         /* = DisposalMethod::KEEP */,
                        int32_t aTimeout         /* = 0 */,
                        BlendMethod aBlendMethod /* = BlendMethod::OVER */)
 {
   // We should be mid-frame
   MOZ_ASSERT(!IsMetadataDecode(), "Stopping frame during metadata decode");
   MOZ_ASSERT(mInFrame, "Stopping frame when we didn't start one");
   MOZ_ASSERT(mCurrentFrame, "Stopping frame when we don't have one");
 
--- a/image/Downscaler.cpp
+++ b/image/Downscaler.cpp
@@ -22,16 +22,17 @@ namespace image {
 
 Downscaler::Downscaler(const nsIntSize& aTargetSize)
   : mTargetSize(aTargetSize)
   , mOutputBuffer(nullptr)
   , mXFilter(MakeUnique<skia::ConvolutionFilter1D>())
   , mYFilter(MakeUnique<skia::ConvolutionFilter1D>())
   , mWindowCapacity(0)
   , mHasAlpha(true)
+  , mFlipVertically(false)
 {
   MOZ_ASSERT(gfxPrefs::ImageDownscaleDuringDecodeEnabled(),
              "Downscaling even though downscale-during-decode is disabled?");
   MOZ_ASSERT(mTargetSize.width > 0 && mTargetSize.height > 0,
              "Invalid target size");
 }
 
 Downscaler::~Downscaler()
@@ -52,33 +53,35 @@ Downscaler::ReleaseWindow()
 
   mWindow = nullptr;
   mWindowCapacity = 0;
 }
 
 nsresult
 Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
                        uint8_t* aOutputBuffer,
-                       bool aHasAlpha)
+                       bool aHasAlpha,
+                       bool aFlipVertically /* = false */)
 {
   MOZ_ASSERT(aOutputBuffer);
   MOZ_ASSERT(mTargetSize != aOriginalSize,
              "Created a downscaler, but not downscaling?");
   MOZ_ASSERT(mTargetSize.width <= aOriginalSize.width,
              "Created a downscaler, but width is larger");
   MOZ_ASSERT(mTargetSize.height <= aOriginalSize.height,
              "Created a downscaler, but height is larger");
   MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
              "Invalid original size");
 
   mOriginalSize = aOriginalSize;
   mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width,
                    double(mOriginalSize.height) / mTargetSize.height);
   mOutputBuffer = aOutputBuffer;
   mHasAlpha = aHasAlpha;
+  mFlipVertically = aFlipVertically;
 
   ResetForNextProgressivePass();
   ReleaseWindow();
 
   auto resizeMethod = skia::ImageOperations::RESIZE_LANCZOS3;
 
   skia::resize::ComputeFilters(resizeMethod,
                                mOriginalSize.width, mTargetSize.width,
@@ -141,16 +144,26 @@ GetFilterOffsetAndLength(UniquePtr<skia:
 {
   MOZ_ASSERT(aOutputImagePosition < aFilter->num_values());
   aFilter->FilterForValue(aOutputImagePosition,
                           aFilterOffsetOut,
                           aFilterLengthOut);
 }
 
 void
+Downscaler::ClearRow(uint32_t aStartingAtCol)
+{
+  MOZ_ASSERT(int64_t(mOriginalSize.width) > int64_t(aStartingAtCol));
+  uint32_t bytesToClear = (mOriginalSize.width - aStartingAtCol)
+                        * sizeof(uint32_t);
+  memset(mRowBuffer.get() + (aStartingAtCol * sizeof(uint32_t)),
+         0, bytesToClear);
+}
+
+void
 Downscaler::CommitRow()
 {
   MOZ_ASSERT(mOutputBuffer, "Should have a current frame");
   MOZ_ASSERT(mCurrentInLine < mOriginalSize.height, "Past end of input");
   MOZ_ASSERT(mCurrentOutLine < mTargetSize.height, "Past end of output");
 
   int32_t filterOffset = 0;
   int32_t filterLength = 0;
@@ -193,19 +206,28 @@ Downscaler::TakeInvalidRect()
 {
   if (MOZ_UNLIKELY(!HasInvalidation())) {
     return DownscalerInvalidRect();
   }
 
   DownscalerInvalidRect invalidRect;
 
   // Compute the target size invalid rect.
-  invalidRect.mTargetSizeRect =
-    nsIntRect(0, mPrevInvalidatedLine,
+  if (mFlipVertically) {
+    // We need to flip it. This will implicitly flip the original size invalid
+    // rect, since we compute it by scaling this rect.
+    invalidRect.mTargetSizeRect =
+      IntRect(0, mTargetSize.height - mCurrentOutLine,
               mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
+  } else {
+    invalidRect.mTargetSizeRect =
+      IntRect(0, mPrevInvalidatedLine,
+              mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
+  }
+
   mPrevInvalidatedLine = mCurrentOutLine;
 
   // Compute the original size invalid rect.
   invalidRect.mOriginalSizeRect = invalidRect.mTargetSizeRect;
   invalidRect.mOriginalSizeRect.ScaleRoundOut(mScale.width, mScale.height);
 
   return invalidRect;
 }
@@ -220,18 +242,23 @@ Downscaler::DownscaleInputLine()
              "Writing past end of output");
 
   int32_t filterOffset = 0;
   int32_t filterLength = 0;
   MOZ_ASSERT(mCurrentOutLine < mYFilter->num_values());
   auto filterValues =
     mYFilter->FilterForValue(mCurrentOutLine, &filterOffset, &filterLength);
 
+  int32_t currentOutLine = mFlipVertically
+                         ? mTargetSize.height - (mCurrentOutLine + 1)
+                         : mCurrentOutLine;
+  MOZ_ASSERT(currentOutLine >= 0);
+
   uint8_t* outputLine =
-    &mOutputBuffer[mCurrentOutLine * mTargetSize.width * sizeof(uint32_t)];
+    &mOutputBuffer[currentOutLine * mTargetSize.width * sizeof(uint32_t)];
   skia::ConvolveVertically(static_cast<const FilterValue*>(filterValues),
                            filterLength, mWindow.get(), mXFilter->num_values(),
                            outputLine, mHasAlpha, supports_sse2());
 
   mCurrentOutLine += 1;
 
   if (mCurrentOutLine == mTargetSize.height) {
     // We're done.
--- a/image/Downscaler.h
+++ b/image/Downscaler.h
@@ -65,24 +65,31 @@ public:
    *
    * @param aOriginalSize The original size of this frame, before scaling.
    * @param aOutputBuffer The buffer to which the Downscaler should write its
    *                      output; this is the same buffer where the Decoder
    *                      would write its output when not downscaling during
    *                      decode.
    * @param aHasAlpha Whether or not this frame has an alpha channel.
    *                  Performance is a little better if it doesn't have one.
+   * @param aFlipVertically If true, output rows will be written to the output
+   *                        buffer in reverse order vertically, which matches
+   *                        the way they are stored in some image formats.
    */
   nsresult BeginFrame(const nsIntSize& aOriginalSize,
                       uint8_t* aOutputBuffer,
-                      bool aHasAlpha);
+                      bool aHasAlpha,
+                      bool aFlipVertically = false);
 
   /// Retrieves the buffer into which the Decoder should write each row.
   uint8_t* RowBuffer() { return mRowBuffer.get(); }
 
+  /// Clears the current row buffer (optionally starting at @aStartingAtCol).
+  void ClearRow(uint32_t aStartingAtCol = 0);
+
   /// Signals that the decoder has finished writing a row into the row buffer.
   void CommitRow();
 
   /// Returns true if there is a non-empty invalid rect available.
   bool HasInvalidation() const;
 
   /// Takes the Downscaler's current invalid rect and resets it.
   DownscalerInvalidRect TakeInvalidRect();
@@ -112,17 +119,18 @@ private:
 
   int32_t mWindowCapacity;
 
   int32_t mLinesInBuffer;
   int32_t mPrevInvalidatedLine;
   int32_t mCurrentOutLine;
   int32_t mCurrentInLine;
 
-  bool mHasAlpha;
+  bool mHasAlpha : 1;
+  bool mFlipVertically : 1;
 };
 
 #else
 
 /**
  * Downscaler requires Skia to work, so we provide a dummy implementation if
  * Skia is disabled that asserts if constructed.
  */
@@ -134,22 +142,23 @@ public:
   {
     MOZ_RELEASE_ASSERT(false, "Skia is not enabled");
   }
 
   const nsIntSize& OriginalSize() const { return nsIntSize(); }
   const nsIntSize& TargetSize() const { return nsIntSize(); }
   const gfxSize& Scale() const { return gfxSize(1.0, 1.0); }
 
-  nsresult BeginFrame(const nsIntSize&, uint8_t*, bool)
+  nsresult BeginFrame(const nsIntSize&, uint8_t*, bool, bool = false)
   {
     return NS_ERROR_FAILURE;
   }
 
   uint8_t* RowBuffer() { return nullptr; }
+  void ClearRow(uint32_t = 0);
   void CommitRow() { }
   bool HasInvalidation() const { return false; }
   DownscalerInvalidRect TakeInvalidRect() { return DownscalerInvalidRect(); }
   void ResetForNextProgressivePass() { }
 };
 
 #endif // MOZ_ENABLE_SKIA
 
--- a/image/ImageFactory.cpp
+++ b/image/ImageFactory.cpp
@@ -31,17 +31,20 @@ namespace image {
 /*static*/ void
 ImageFactory::Initialize()
 { }
 
 static bool
 ShouldDownscaleDuringDecode(const nsCString& aMimeType)
 {
   DecoderType type = DecoderFactory::GetDecoderType(aMimeType.get());
-  return type == DecoderType::JPEG || type == DecoderType::PNG;
+  return type == DecoderType::JPEG ||
+         type == DecoderType::ICON ||
+         type == DecoderType::PNG ||
+         type == DecoderType::BMP;
 }
 
 static uint32_t
 ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
 {
   nsresult rv;
 
   // We default to the static globals.
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -14,16 +14,18 @@
 #include "mozilla/Endian.h"
 #include "mozilla/Likely.h"
 #include "nsBMPDecoder.h"
 
 #include "nsIInputStream.h"
 #include "RasterImage.h"
 #include <algorithm>
 
+using namespace mozilla::gfx;
+
 namespace mozilla {
 namespace image {
 
 static PRLogModuleInfo*
 GetBMPLog()
 {
   static PRLogModuleInfo* sBMPLog;
   if (!sBMPLog) {
@@ -57,16 +59,30 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* 
 nsBMPDecoder::~nsBMPDecoder()
 {
   delete[] mColors;
   if (mRow) {
       free(mRow);
   }
 }
 
+nsresult
+nsBMPDecoder::SetTargetSize(const nsIntSize& aSize)
+{
+  // Make sure the size is reasonable.
+  if (MOZ_UNLIKELY(aSize.width <= 0 || aSize.height <= 0)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Create a downscaler that we'll filter our output through.
+  mDownscaler.emplace(aSize);
+
+  return NS_OK;
+}
+
 // Sets whether or not the BMP will use alpha data
 void
 nsBMPDecoder::SetUseAlphaData(bool useAlphaData)
 {
   mUseAlphaData = useAlphaData;
 }
 
 // Obtains the bits per pixel from the internal BIH header
@@ -117,42 +133,33 @@ nsBMPDecoder::GetCompressedImageSize() c
   }
 
   // The height should be the absolute value of what the height is in the BIH.
   // If positive the bitmap is stored bottom to top, otherwise top to bottom
   int32_t pixelArraySize = rowSize * GetHeight();
   return pixelArraySize;
 }
 
-// Obtains whether or not a BMP file had alpha data in its 4th byte
-// for 32BPP bitmaps.  Only use after the bitmap has been processed.
-bool
-nsBMPDecoder::HasAlphaData() const
-{
-  return mHaveAlphaData;
-}
-
-
 void
 nsBMPDecoder::FinishInternal()
 {
     // We shouldn't be called in error cases
     MOZ_ASSERT(!HasError(), "Can't call FinishInternal on error!");
 
     // We should never make multiple frames
     MOZ_ASSERT(GetFrameCount() <= 1, "Multiple BMP frames?");
 
     // Send notifications if appropriate
     if (!IsMetadataDecode() && HasSize()) {
 
         // Invalidate
         nsIntRect r(0, 0, mBIH.width, GetHeight());
         PostInvalidation(r);
 
-        if (mUseAlphaData) {
+        if (mUseAlphaData && mHaveAlphaData) {
           PostFrameStop(Opacity::SOME_TRANSPARENCY);
         } else {
           PostFrameStop(Opacity::OPAQUE);
         }
         PostDecodeDone();
     }
 }
 
@@ -367,19 +374,20 @@ nsBMPDecoder::WriteInternal(const char* 
       if (HasError()) {
         // Setting the size led to an error.
         return;
       }
 
       // We treat BMPs as transparent if they're 32bpp and alpha is enabled, but
       // also if they use RLE encoding, because the 'delta' mode can skip pixels
       // and cause implicit transparency.
-      if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
-          (mBIH.compression == BMPINFOHEADER::RLE4) ||
-          (mBIH.bpp == 32 && mUseAlphaData)) {
+      bool hasTransparency = (mBIH.compression == BMPINFOHEADER::RLE8) ||
+                             (mBIH.compression == BMPINFOHEADER::RLE4) ||
+                             (mBIH.bpp == 32 && mUseAlphaData);
+      if (hasTransparency) {
         PostHasTransparency();
       }
 
       // We have the size. If we're doing a metadata decode, we're done.
       if (IsMetadataDecode()) {
         return;
       }
 
@@ -448,28 +456,35 @@ nsBMPDecoder::WriteInternal(const char* 
         // Also, it compensates rounding error.
         if (!mRow) {
           PostDataError();
           return;
         }
       }
 
       MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
-      nsresult rv = AllocateBasicFrame();
+      IntSize targetSize = mDownscaler ? mDownscaler->TargetSize()
+                                       : GetSize();
+      nsresult rv = AllocateFrame(/* aFrameNum = */ 0, targetSize,
+                                  IntRect(IntPoint(), targetSize),
+                                  SurfaceFormat::B8G8R8A8);
       if (NS_FAILED(rv)) {
           return;
       }
 
       MOZ_ASSERT(mImageData, "Should have a buffer now");
 
-      // Prepare for transparency
-      if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
-          (mBIH.compression == BMPINFOHEADER::RLE4)) {
-        // Clear the image, as the RLE may jump over areas
-        memset(mImageData, 0, mImageDataLength);
+      if (mDownscaler) {
+        // BMPs store their rows in reverse order, so the downscaler needs to
+        // reverse them again when writing its output.
+        rv = mDownscaler->BeginFrame(GetSize(), mImageData, hasTransparency,
+                                     /* aFlipVertically = */ true);
+        if (NS_FAILED(rv)) {
+          return;
+        }
       }
   }
 
   if (mColors && mPos >= mLOH) {
     // OS/2 Bitmaps have no padding byte
     uint8_t bytesPerColor = (mBFH.bihsize == BIH_LENGTH::OS2) ? 3 : 4;
     if (mPos < (mLOH + mNumColors * bytesPerColor)) {
       // Number of bytes already received
@@ -601,18 +616,20 @@ nsBMPDecoder::WriteInternal(const char* 
             memcpy(mRow + mRowBytes, aBuffer, toCopy);
             aCount -= toCopy;
             aBuffer += toCopy;
             mRowBytes += toCopy;
         }
         if (rowSize == mRowBytes) {
           // Collected a whole row into mRow, process it
           uint8_t* p = mRow;
-          uint32_t* d = reinterpret_cast<uint32_t*>(mImageData) +
-                        PIXEL_OFFSET(mCurLine, 0);
+          uint32_t* d = mDownscaler
+                      ? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
+                      : reinterpret_cast<uint32_t*>(mImageData)
+                        + PIXEL_OFFSET(mCurLine, 0);
           uint32_t lpos = mBIH.width;
           switch (mBIH.bpp) {
             case 1:
               while (lpos > 0) {
                 int8_t bit;
                 uint8_t idx;
                 for (bit = 7; bit >= 0 && lpos > 0; bit--) {
                   idx = (*p >> bit) & 1;
@@ -659,49 +676,37 @@ nsBMPDecoder::WriteInternal(const char* 
                 p += 2;
                 --lpos;
                 ++p;
               }
               break;
             case 32:
               while (lpos > 0) {
                 if (mUseAlphaData) {
-                  if (!mHaveAlphaData && p[3]) {
-                    // Non-zero alpha byte detected! Clear previous
-                    // pixels that we have already processed.
-                    // This works because we know that if we
-                    // are reaching here then the alpha data in byte
-                    // 4 has been right all along.  And we know it
-                    // has been set to 0 the whole time, so that
-                    // means that everything is transparent so far.
-                    uint32_t* start = reinterpret_cast<uint32_t*>
-                                      (mImageData) + GetWidth() *
-                                      (mCurLine - 1);
-                    uint32_t heightDifference = GetHeight() -
-                                                mCurLine + 1;
-                    uint32_t pixelCount = GetWidth() *
-                                          heightDifference;
-
-                    memset(start, 0, pixelCount * sizeof(uint32_t));
-
+                  if (MOZ_UNLIKELY(!mHaveAlphaData && p[3])) {
                     PostHasTransparency();
                     mHaveAlphaData = true;
                   }
-                  SetPixel(d, p[2], p[1], p[0], mHaveAlphaData ?  p[3] : 0xFF);
+                  SetPixel(d, p[2], p[1], p[0], p[3]);
                 } else {
                   SetPixel(d, p[2], p[1], p[0]);
                 }
                 p += 4;
                 --lpos;
               }
               break;
             default:
               NS_NOTREACHED("Unsupported color depth,"
                             " but earlier check didn't catch it");
           }
+
+          if (mDownscaler) {
+            mDownscaler->CommitRow();
+          }
+          
           mCurLine --;
           if (mCurLine == 0) { // Finished last line
             break;
           }
           mRowBytes = 0;
         }
       } while (aCount > 0);
     } else if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
@@ -736,18 +741,22 @@ nsBMPDecoder::WriteInternal(const char* 
               // number of consecutive pixels to be drawn
               // using the color index contained in
               // the second byte
               // Work around bitmaps that specify too many pixels
               mState = eRLEStateInitial;
               uint32_t pixelsNeeded = std::min<uint32_t>(mBIH.width - mCurPos,
                                     mStateData);
               if (pixelsNeeded) {
-                uint32_t* d = reinterpret_cast<uint32_t*>
-                              (mImageData) + PIXEL_OFFSET(mCurLine, mCurPos);
+                uint32_t* d = mDownscaler
+                  ? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
+                      + mCurPos
+                  : reinterpret_cast<uint32_t*>(mImageData)
+                      + PIXEL_OFFSET(mCurLine, mCurPos);
+
                 mCurPos += pixelsNeeded;
                 if (mBIH.compression == BMPINFOHEADER::RLE8) {
                   do {
                     SetPixel(d, byte, mColors);
                     pixelsNeeded --;
                   } while (pixelsNeeded);
                 } else {
                     do {
@@ -756,16 +765,20 @@ nsBMPDecoder::WriteInternal(const char* 
                 }
               }
               continue;
             }
 
             switch(byte) {
               case RLE::ESCAPE_EOL:
                 // End of Line: Go to next row
+                if (mDownscaler) {
+                  mDownscaler->CommitRow();
+                }
+
                 mCurLine --;
                 mCurPos = 0;
                 mState = eRLEStateInitial;
                 break;
 
               case RLE::ESCAPE_EOF: // EndOfFile
                 mCurPos = mCurLine = 0;
                 break;
@@ -805,54 +818,82 @@ nsBMPDecoder::WriteInternal(const char* 
               continue;
             }
             break;
 
           case eRLEStateNeedXDelta:
             // Handle the XDelta and proceed to get Y Delta
             byte = *aBuffer++;
             aCount--;
+
+            if (mDownscaler) {
+              // Clear the skipped pixels. (This clears to the end of the row,
+              // which is perfect if there's a Y delta and harmless if not).
+              mDownscaler->ClearRow(/* aStartingAtCol = */ mCurPos);
+            }
+
             mCurPos += byte;
+
             // Delta encoding makes it possible to skip pixels
             // making the image transparent.
             if (MOZ_UNLIKELY(!mHaveAlphaData)) {
                 PostHasTransparency();
+                mHaveAlphaData = true;
             }
             mUseAlphaData = mHaveAlphaData = true;
             if (mCurPos > mBIH.width) {
                 mCurPos = mBIH.width;
             }
 
             mState = eRLEStateNeedYDelta;
             continue;
 
-          case eRLEStateNeedYDelta:
+          case eRLEStateNeedYDelta: {
             // Get the Y Delta and then "handle" the move
             byte = *aBuffer++;
             aCount--;
             mState = eRLEStateInitial;
             // Delta encoding makes it possible to skip pixels
             // making the image transparent.
             if (MOZ_UNLIKELY(!mHaveAlphaData)) {
                 PostHasTransparency();
+                mHaveAlphaData = true;
             }
             mUseAlphaData = mHaveAlphaData = true;
-            mCurLine -= std::min<int32_t>(byte, mCurLine);
+
+            int32_t yDelta = std::min<int32_t>(byte, mCurLine);
+            mCurLine -= yDelta;
+
+            if (mDownscaler && yDelta > 0) {
+              // Commit the current row (the first of the skipped rows).
+              mDownscaler->CommitRow();
+
+              // Clear and commit the remaining skipped rows. 
+              for (int32_t line = 1 ; line < yDelta ; ++line) {
+                mDownscaler->ClearRow();
+                mDownscaler->CommitRow();
+              }
+            }
+
             break;
+          }
 
           case eRLEStateAbsoluteMode: // Absolute Mode
           case eRLEStateAbsoluteModePadded:
             if (mStateData) {
               // In absolute mode, the second byte (mStateData)
               // represents the number of pixels
               // that follow, each of which contains
               // the color index of a single pixel.
-              uint32_t* d = reinterpret_cast<uint32_t*>
-                            (mImageData) +
-                            PIXEL_OFFSET(mCurLine, mCurPos);
+              uint32_t* d = mDownscaler
+                ? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
+                    + mCurPos
+                : reinterpret_cast<uint32_t*>(mImageData)
+                    + PIXEL_OFFSET(mCurLine, mCurPos);
+
               uint32_t* oldPos = d;
               if (mBIH.compression == BMPINFOHEADER::RLE8) {
                   while (aCount > 0 && mStateData > 0) {
                     byte = *aBuffer++;
                     aCount--;
                     SetPixel(d, byte, mColors);
                     mStateData--;
                   }
@@ -898,19 +939,25 @@ nsBMPDecoder::WriteInternal(const char* 
         }
       }
     }
   }
 
   const uint32_t rows = mOldLine - mCurLine;
   if (rows) {
     // Invalidate
-    nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
-                mBIH.width, rows);
-    PostInvalidation(r);
+    if (!mDownscaler) {
+      nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
+                  mBIH.width, rows);
+      PostInvalidation(r);
+    } else if (mDownscaler->HasInvalidation()) {
+      DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
+      PostInvalidation(invalidRect.mOriginalSizeRect,
+                       Some(invalidRect.mTargetSizeRect));
+    }
 
     mOldLine = mCurLine;
   }
 
   return;
 }
 
 void
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -4,31 +4,34 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #ifndef mozilla_image_decoders_nsBMPDecoder_h
 #define mozilla_image_decoders_nsBMPDecoder_h
 
 #include "BMPFileHeaders.h"
 #include "Decoder.h"
+#include "Downscaler.h"
 #include "gfxColor.h"
 #include "nsAutoPtr.h"
 
 namespace mozilla {
 namespace image {
 
 class RasterImage;
 
 /// Decoder for BMP-Files, as used by Windows and OS/2
 
 class nsBMPDecoder : public Decoder
 {
 public:
     ~nsBMPDecoder();
 
+    nsresult SetTargetSize(const nsIntSize& aSize) override;
+
     // Specifies whether or not the BMP file will contain alpha data
     // If set to true and the BMP is 32BPP, the alpha data will be
     // retrieved from the 4th byte of image data per pixel
     void SetUseAlphaData(bool useAlphaData);
 
     // Obtains the bits per pixel from the internal BIH header
     int32_t GetBitsPerPixel() const;
 
@@ -41,17 +44,20 @@ public:
     // Obtains the internal output image buffer
     uint32_t* GetImageData();
 
     // Obtains the size of the compressed image resource
     int32_t GetCompressedImageSize() const;
 
     // Obtains whether or not a BMP file had alpha data in its 4th byte
     // for 32BPP bitmaps.  Only use after the bitmap has been processed.
-    bool HasAlphaData() const;
+    bool HasAlphaData() const { return mHaveAlphaData; }
+
+    /// Marks this BMP as having alpha data (due to e.g. an ICO alpha mask).
+    void SetHasAlphaData() { mHaveAlphaData = true; }
 
     virtual void WriteInternal(const char* aBuffer,
                                uint32_t aCount) override;
     virtual void FinishInternal() override;
 
 private:
     friend class DecoderFactory;
     friend class nsICODecoder;
@@ -66,16 +72,18 @@ private:
 
     uint32_t mPos; //< Number of bytes read from aBuffer in WriteInternal()
 
     BMPFILEHEADER mBFH;
     BITMAPV5HEADER mBIH;
     char mRawBuf[BIH_INTERNAL_LENGTH::WIN_V3]; //< If this is changed,
                                                // WriteInternal() MUST be updated
 
+    Maybe<Downscaler> mDownscaler;
+
     uint32_t mLOH; //< Length of the header
 
     uint32_t mNumColors; //< The number of used colors, i.e. the number of
                          // entries in mColors
     colorTable* mColors;
 
     bitFields mBitFields;
 
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -527,24 +527,24 @@ nsICODecoder::WriteInternal(const char* 
       mPos += toFeed;
       aCount -= toFeed;
       aBuffer += toFeed;
     }
 
     // If the bitmap is fully processed, treat any left over data as the ICO's
     // 'AND buffer mask' which appears after the bitmap resource.
     if (!mIsPNG && mPos >= bmpDataEnd) {
+      nsRefPtr<nsBMPDecoder> bmpDecoder =
+        static_cast<nsBMPDecoder*>(mContainedDecoder.get());
+
       // There may be an optional AND bit mask after the data.  This is
       // only used if the alpha data is not already set. The alpha data
       // is used for 32bpp bitmaps as per the comment in ICODecoder.h
       // The alpha mask should be checked in all other cases.
-      if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
-            GetBitsPerPixel() != 32 ||
-          !static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
-            HasAlphaData()) {
+      if (bmpDecoder->GetBitsPerPixel() != 32 || !bmpDecoder->HasAlphaData()) {
         uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
         if (mPos == bmpDataEnd) {
           mPos++;
           mRowBytes = 0;
           mCurLine = GetRealHeight();
           mRow = (uint8_t*)realloc(mRow, rowSize);
           if (!mRow) {
             PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
@@ -568,19 +568,17 @@ nsICODecoder::WriteInternal(const char* 
             aCount -= toCopy;
             aBuffer += toCopy;
             mRowBytes += toCopy;
           }
           if (rowSize == mRowBytes) {
             mCurLine--;
             mRowBytes = 0;
 
-            uint32_t* imageData =
-              static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
-                                           GetImageData();
+            uint32_t* imageData = bmpDecoder->GetImageData();
             if (!imageData) {
               PostDataError();
               return;
             }
             uint32_t* decoded = imageData + mCurLine * GetRealWidth();
             uint32_t* decoded_end = decoded + GetRealWidth();
             uint8_t* p = mRow;
             uint8_t* p_end = mRow + rowSize;
@@ -596,17 +594,18 @@ nsICODecoder::WriteInternal(const char* 
               }
             }
           }
         }
 
         // If any bits are set in sawTransparency, then we know at least one
         // pixel was transparent.
         if (sawTransparency) {
-            PostHasTransparency();
+          PostHasTransparency();
+          bmpDecoder->SetHasAlphaData();
         }
       }
     }
   }
 }
 
 bool
 nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount)
--- a/image/decoders/nsIconDecoder.cpp
+++ b/image/decoders/nsIconDecoder.cpp
@@ -7,41 +7,56 @@
 #include "nsIconDecoder.h"
 #include "nsIInputStream.h"
 #include "nspr.h"
 #include "nsRect.h"
 #include "nsError.h"
 #include "RasterImage.h"
 #include <algorithm>
 
+using namespace mozilla::gfx;
+
+using std::min;
+
 namespace mozilla {
 namespace image {
 
 nsIconDecoder::nsIconDecoder(RasterImage* aImage)
- : Decoder(aImage),
-   mWidth(-1),
-   mHeight(-1),
-   mPixBytesRead(0),
-   mState(iconStateStart)
+ : Decoder(aImage)
+ , mExpectedDataLength(0)
+ , mPixBytesRead(0)
+ , mState(iconStateStart)
+ , mWidth(-1)
+ , mHeight(-1)
 {
   // Nothing to do
 }
 
 nsIconDecoder::~nsIconDecoder()
 { }
 
+nsresult
+nsIconDecoder::SetTargetSize(const nsIntSize& aSize)
+{
+  // Make sure the size is reasonable.
+  if (MOZ_UNLIKELY(aSize.width <= 0 || aSize.height <= 0)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Create a downscaler that we'll filter our output through.
+  mDownscaler.emplace(aSize);
+
+  return NS_OK;
+}
+
 void
 nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
 {
   MOZ_ASSERT(!HasError(), "Shouldn't call WriteInternal after error!");
 
-  // We put this here to avoid errors about crossing initialization with case
-  // jumps on linux.
-  uint32_t bytesToRead = 0;
-
   // Loop until the input data is gone
   while (aCount > 0) {
     switch (mState) {
       case iconStateStart:
 
         // Grab the width
         mWidth = (uint8_t)*aBuffer;
 
@@ -68,55 +83,107 @@ nsIconDecoder::WriteInternal(const char*
         }
 
         // If we're doing a metadata decode, we're done.
         if (IsMetadataDecode()) {
           mState = iconStateFinished;
           break;
         }
 
+        // The input is 32bpp, so we expect 4 bytes of data per pixel.
+        mExpectedDataLength = mWidth * mHeight * 4;
+
         {
           MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
-          nsresult rv = AllocateBasicFrame();
+          IntSize targetSize = mDownscaler ? mDownscaler->TargetSize()
+                                           : GetSize();
+          nsresult rv = AllocateFrame(0, targetSize,
+                                      IntRect(IntPoint(), targetSize),
+                                      gfx::SurfaceFormat::B8G8R8A8);
           if (NS_FAILED(rv)) {
             mState = iconStateFinished;
             return;
           }
         }
 
         MOZ_ASSERT(mImageData, "Should have a buffer now");
 
+        if (mDownscaler) {
+          nsresult rv = mDownscaler->BeginFrame(GetSize(),
+                                                mImageData,
+                                                /* aHasAlpha = */ true);
+          if (NS_FAILED(rv)) {
+            mState = iconStateFinished;
+            return;
+          }
+        }
+
         // Book Keeping
         aBuffer++;
         aCount--;
         mState = iconStateReadPixels;
         break;
 
       case iconStateReadPixels: {
 
         // How many bytes are we reading?
-        bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
+        uint32_t bytesToRead = min(aCount, mExpectedDataLength - mPixBytesRead);
+
+        if (mDownscaler) {
+          uint8_t* row = mDownscaler->RowBuffer();
+          const uint32_t bytesPerRow = mWidth * 4;
+          const uint32_t rowOffset = mPixBytesRead % bytesPerRow;
 
-        // Copy the bytes
-        memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
+          // Update global state; we're about to read |bytesToRead| bytes.
+          aCount -= bytesToRead;
+          mPixBytesRead += bytesToRead;
+
+          if (rowOffset > 0) {
+            // Finish the current row.
+            const uint32_t remaining = bytesPerRow - rowOffset;
+            memcpy(row + rowOffset, aBuffer, remaining);
+            aBuffer += remaining;
+            bytesToRead -= remaining;
+            mDownscaler->CommitRow();
+          }
 
-        // Performance isn't critical here, so our update rectangle is
-        // always the full icon
-        nsIntRect r(0, 0, mWidth, mHeight);
+          // Copy the bytes a row at a time.
+          while (bytesToRead > bytesPerRow) {
+            memcpy(row, aBuffer, bytesPerRow);
+            aBuffer += bytesPerRow;
+            bytesToRead -= bytesPerRow;
+            mDownscaler->CommitRow();
+          }
+
+          // Copy any leftover bytes. (Leaving the current row incomplete.)
+          if (bytesToRead > 0) {
+            memcpy(row, aBuffer, bytesToRead);
+            aBuffer += bytesPerRow;
+            bytesToRead -= bytesPerRow;
+          }
 
-        // Invalidate
-        PostInvalidation(r);
+          if (mDownscaler->HasInvalidation()) {
+            DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
+            PostInvalidation(invalidRect.mOriginalSizeRect,
+                             Some(invalidRect.mTargetSizeRect));
+          }
+        } else {
+          // Copy all the bytes at once.
+          memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
+          aBuffer += bytesToRead;
+          aCount -= bytesToRead;
+          mPixBytesRead += bytesToRead;
 
-        // Book Keeping
-        aBuffer += bytesToRead;
-        aCount -= bytesToRead;
-        mPixBytesRead += bytesToRead;
+          // Invalidate. Performance isn't critical here, so our update
+          // rectangle is always the full icon.
+          PostInvalidation(IntRect(0, 0, mWidth, mHeight));
+        }
 
         // If we've got all the pixel bytes, we're finished
-        if (mPixBytesRead == mImageDataLength) {
+        if (mPixBytesRead == mExpectedDataLength) {
           PostFrameStop();
           PostDecodeDone();
           mState = iconStateFinished;
         }
         break;
       }
 
       case iconStateFinished:
--- a/image/decoders/nsIconDecoder.h
+++ b/image/decoders/nsIconDecoder.h
@@ -34,29 +34,33 @@ class RasterImage;
 //
 ////////////////////////////////////////////////////////////////////////////////
 
 class nsIconDecoder : public Decoder
 {
 public:
   virtual ~nsIconDecoder();
 
+  virtual nsresult SetTargetSize(const nsIntSize& aSize) override;
+
   virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
 
 private:
   friend class DecoderFactory;
 
   // Decoders should only be instantiated via DecoderFactory.
   explicit nsIconDecoder(RasterImage* aImage);
 
-public:
+  Maybe<Downscaler> mDownscaler;
+
+  uint32_t mExpectedDataLength;
+  uint32_t mPixBytesRead;
+  uint32_t mState;
   uint8_t mWidth;
   uint8_t mHeight;
-  uint32_t mPixBytesRead;
-  uint32_t mState;
 };
 
 enum {
   iconStateStart      = 0,
   iconStateHaveHeight = 1,
   iconStateReadPixels = 2,
   iconStateFinished   = 3
 };
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1309,16 +1309,17 @@ if test "$GNU_CXX"; then
     # -Wignored-qualifiers - catches returns types with qualifiers like const
     # -Wint-to-pointer-cast - catches cast to pointer from integer of different size
     # -Wmissing-braces - catches aggregate initializers missing nested braces
     # -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
     # -Woverloaded-virtual - function declaration hides virtual function from base class
     # -Wparentheses - catches `if (a=b)` and operator precedence bugs
     # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
     # -Wpointer-to-int-cast - catches casts from pointer to different sized int
+    # -Wrange-loop-analysis - catches copies during range-based for loops.
     # -Wreorder - catches ctor initializer list not matching class definition order
     # -Wreturn-type - catches missing returns, zero false positives
     # -Wsequence-point - catches undefined order behavior like `a = a++`
     # -Wsign-compare - catches comparison of signed and unsigned types
     # -Wswitch - catches switches without all enum cases or default case
     # -Wtrigraphs - catches unlikely use of trigraphs
     # -Wtype-limits - catches overflow bugs, few false positives
     # -Wunknown-pragmas - catches unexpected #pragma directives
@@ -1349,16 +1350,17 @@ if test "$GNU_CXX"; then
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=uninitialized"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unknown-pragmas"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-value"
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=write-strings"
 
         MOZ_CXX_SUPPORTS_WARNING(-Werror=, conversion-null, ac_cxx_has_werror_conversion_null)
         MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
+        MOZ_CXX_SUPPORTS_WARNING(-Werror=, range-loop-analysis, ac_cxx_has_range_loop_analysis)
         MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
     fi
 
     # Turn off the following warnings that -Wall turns on:
     # -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
     # -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
     #
     _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2615,17 +2615,18 @@ NS_IMETHODIMP nsDocumentViewer::SelectAl
 
   mozilla::dom::Selection::AutoApplyUserSelectStyle userSelection(selection);
   rv = selection->SelectAllChildren(bodyNode);
   return rv;
 }
 
 NS_IMETHODIMP nsDocumentViewer::CopySelection()
 {
-  nsCopySupport::FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, mPresShell, nullptr);
+  nsCopySupport::FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard,
+                                    mPresShell, nullptr);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocumentViewer::CopyLinkLocation()
 {
   NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
   nsCOMPtr<nsIDOMNode> node;
   GetPopupLinkNode(getter_AddRefs(node));
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5315,17 +5315,17 @@ bool PresShell::AsyncPanZoomEnabled()
 {
   NS_ASSERTION(mViewManager, "Should have view manager");
   nsView* rootView = mViewManager->GetRootView();
   if (rootView) {
     if (nsIWidget* widget = rootView->GetWidget()) {
       return widget->AsyncPanZoomEnabled();
     }
   }
-  return false;
+  return gfxPlatform::AsyncPanZoomEnabled();
 }
 
 void PresShell::SetIgnoreViewportScrolling(bool aIgnore)
 {
   if (IgnoringViewportScrolling() == aIgnore) {
     return;
   }
   RenderingState state(this);
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -366,16 +366,21 @@ CommonAnimationManager::FlushAnimations(
 {
   TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
   for (AnimationCollection* collection = mElementCollections.getFirst();
        collection; collection = collection->getNext()) {
     if (collection->mStyleRuleRefreshTime == now) {
       continue;
     }
 
+    MOZ_ASSERT(collection->mElement->GetComposedDoc() ==
+                 mPresContext->Document(),
+               "Should not have a transition/animations collection for an "
+               "element that is not part of the document tree");
+
     collection->RequestRestyle(AnimationCollection::RestyleType::Standard);
   }
 }
 
 nsIStyleRule*
 CommonAnimationManager::GetAnimationRule(mozilla::dom::Element* aElement,
                                          nsCSSPseudoElements::Type aPseudoType)
 {
@@ -878,20 +883,16 @@ AnimationCollection::RequestRestyle(Rest
              "Unexpected mElementProperty; might restyle too much");
 
   nsPresContext* presContext = mManager->PresContext();
   if (!presContext) {
     // Pres context will be null after the manager is disconnected.
     return;
   }
 
-  MOZ_ASSERT(mElement->GetCrossShadowCurrentDoc() == presContext->Document(),
-             "Element::UnbindFromTree should have destroyed the element "
-             "transition/animations object");
-
   // Steps for Restyle::Layer:
 
   if (aRestyleType == RestyleType::Layer) {
     mStyleRuleRefreshTime = TimeStamp();
     // FIXME: We should be able to remove these two lines once we move
     // ticking to animation timelines as part of bug 1151731.
     mNeedsRefreshes = true;
     mManager->MaybeStartObservingRefreshDriver();
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1200568-1.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<style>
+.anim { animation: anim 2s infinite linear }
+@keyframes anim { }
+</style>
+</head>
+<body>
+<script>
+var i = document.createElement('i');
+i.setAttribute('class', 'anim');
+getComputedStyle(i).display;
+</script>
+</body>
+</html>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -115,10 +115,11 @@ pref(layout.css.expensive-style-struct-a
 pref(layout.css.expensive-style-struct-assertions.enabled,true) load 1146101-1.html
 load 1153693-1.html
 load 1161320-1.html
 pref(dom.animations-api.core.enabled,true) load 1161320-2.html
 load 1161366-1.html
 load 1163446-1.html
 load 1164813-1.html
 load 1167782-1.html
+load 1200568-1.html
 load large_border_image_width.html
 load border-image-visited-link.html
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -366,18 +366,19 @@ nsAnimationManager::SizeOfIncludingThis(
 {
   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
 }
 
 nsIStyleRule*
 nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
                                        mozilla::dom::Element* aElement)
 {
-  if (!mPresContext->IsDynamic()) {
-    // For print or print preview, ignore animations.
+  // Ignore animations for print or print preview, and for elements
+  // that are not attached to the document tree.
+  if (!mPresContext->IsDynamic() || !aElement->IsInComposedDoc()) {
     return nullptr;
   }
 
   // Everything that causes our animation data to change triggers a
   // style change, which in turn triggers a non-animation restyle.
   // Likewise, when we initially construct frames, we're not in a
   // style change, but also not in an animation restyle.
 
--- a/mfbt/PodOperations.h
+++ b/mfbt/PodOperations.h
@@ -175,11 +175,22 @@ PodEqual(const T* one, const T* two, siz
       }
     }
     return true;
   }
 
   return !memcmp(one, two, len * sizeof(T));
 }
 
+/*
+ * Determine whether the |N| elements at |one| are memory-identical to the
+ * |N| elements at |two|.
+ */
+template <class T, size_t N>
+static MOZ_ALWAYS_INLINE bool
+PodEqual(const T (&one)[N], const T (&two)[N])
+{
+  return PodEqual(one, two, N);
+}
+
 } // namespace mozilla
 
 #endif /* mozilla_PodOperations_h */
--- a/mobile/android/tests/browser/robocop/robocop_autophone.ini
+++ b/mobile/android/tests/browser/robocop/robocop_autophone.ini
@@ -1,84 +1,1 @@
-[testAboutPage]
-
-#[testAddonManager]
-# fails on gs2, nexus one, lg revolution, droid pro, nexus s
-
-[testAwesomebarSwipes]
-
-[testAwesomebar]
-
-#[testAxisLocking]
-# fails on gs2, nexus one, lg revolution, droid pro, nexus s
-
-[testBookmark]
-# fails on gs2 4.0.3
-
-[testBookmarklets]
-
-[testBrowserProvider]
-# fails on gs2 4.0.3
-
-#[testClearPrivateData]
-# fails on gs2, nexus-one, lg revolution, droid pro, nexus s
-
-#[testDoorHanger]
-# fails on gs2, nexus-one, lg revolution, droid pro, nexus s
-
-#[testFlingCorrectness]
-# fails on gs2, nexus one, lg revolution, droid pro, nexus s
-
-[testFormHistory]
-
-#[testHistory]
-# fails on gs2, nexus one,lg revolution, droid pro, nexus s
-
-#[testJarReader]
-# fails on gs2, nexus one, lg revolution, droid pro, nexus s
-
-#[testLoad]
-# fails on gs2, nexus one, lg revolution, droid pro, nexus s
-
-[testNewTab]
-# fails on nexus s random crash [@ libpvrANDROID_WSEGL.so + 0x73c]
-
-#[testPanCorrectness]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testPasswordEncrypt]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-[testPasswordProvider]
-
-#[testPermissions]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testSearchSuggestions]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testSettingsMenuItems]
-# fails on nexus one, lg revolution, nexus s
-
-#[testShareLink]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-[testSystemPages]
-
-#[testTabHistory]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testTabsLayoutMenu]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testThumbnails]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testVkbOverlap]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[testWebContentContextMenu]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-#[test_bug720538]
-# fails on gs2, nexus one, lg revolution, nexus s
-
-[testBrowserSearchVisibility]
+[testAdobeFlash]
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1781,17 +1781,17 @@ pref("network.automatic-ntlm-auth.truste
 pref("network.generic-ntlm-auth.workstation", "WORKSTATION");
 
 // Sub-resources HTTP-authentication:
 //   0 - don't allow sub-resources to open HTTP authentication credentials
 //       dialogs
 //   1 - allow sub-resources to open HTTP authentication credentials dialogs,
 //       but don't allow it for cross-origin sub-resources
 //   2 - allow the cross-origin authentication as well.
-pref("network.auth.allow-subresource-auth", 2);
+pref("network.auth.subresource-http-auth-allow", 2);
 
 pref("permissions.default.image",           1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
 
 pref("network.proxy.type",                  5);
 pref("network.proxy.ftp",                   "");
 pref("network.proxy.ftp_port",              0);
 pref("network.proxy.http",                  "");
 pref("network.proxy.http_port",             0);
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1283,16 +1283,18 @@ HttpBaseChannel::GetProxyURI(nsIURI **aO
   result.forget(aOut);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
                                   nsACString& aValue)
 {
+  aValue.Truncate();
+
   // XXX might be better to search the header list directly instead of
   // hitting the http atom hash table.
   nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
   if (!atom)
     return NS_ERROR_NOT_AVAILABLE;
 
   return mRequestHead.GetHeader(atom, aValue);
 }
@@ -1328,16 +1330,18 @@ NS_IMETHODIMP
 HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *visitor)
 {
   return mRequestHead.Headers().VisitHeaders(visitor);
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetResponseHeader(const nsACString &header, nsACString &value)
 {
+  value.Truncate();
+
   if (!mResponseHead)
     return NS_ERROR_NOT_AVAILABLE;
 
   nsHttpAtom atom = nsHttp::ResolveAtom(header);
   if (!atom)
     return NS_ERROR_NOT_AVAILABLE;
 
   return mResponseHead->GetHeader(atom, value);
--- a/netwerk/protocol/http/NullHttpChannel.cpp
+++ b/netwerk/protocol/http/NullHttpChannel.cpp
@@ -90,16 +90,17 @@ NS_IMETHODIMP
 NullHttpChannel::SetReferrerWithPolicy(nsIURI *referrer, uint32_t referrerPolicy)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::GetRequestHeader(const nsACString & aHeader, nsACString & _retval)
 {
+  _retval.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::SetRequestHeader(const nsACString & aHeader, const nsACString & aValue, bool aMerge)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -162,16 +163,17 @@ NS_IMETHODIMP
 NullHttpChannel::GetRequestSucceeded(bool *aRequestSucceeded)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::GetResponseHeader(const nsACString & header, nsACString & _retval)
 {
+  _retval.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullHttpChannel::SetResponseHeader(const nsACString & header, const nsACString & value, bool merge)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -70,25 +70,25 @@ nsHttpChannelAuthProvider::nsHttpChannel
 }
 
 nsHttpChannelAuthProvider::~nsHttpChannelAuthProvider()
 {
     MOZ_ASSERT(!mAuthChannel, "Disconnect wasn't called");
 }
 
 uint32_t nsHttpChannelAuthProvider::sAuthAllowPref =
-    SUBRESOURCE_AUTH_DIALOG_DISALLOW_CROSS_ORIGIN;
+    SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL;
 
 void
 nsHttpChannelAuthProvider::InitializePrefs()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mozilla::Preferences::AddUintVarCache(&sAuthAllowPref,
-                                        "network.auth.allow-subresource-auth",
-                                        SUBRESOURCE_AUTH_DIALOG_DISALLOW_CROSS_ORIGIN);
+                                        "network.auth.subresource-http-auth-allow",
+                                        SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL);
 }
 
 NS_IMETHODIMP
 nsHttpChannelAuthProvider::Init(nsIHttpAuthenticableChannel *channel)
 {
     MOZ_ASSERT(channel, "channel expected!");
 
     mAuthChannel = channel;
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -4,17 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttpNTLMAuth.h"
 #include "nsIAuthModule.h"
 #include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
 #include "plbase64.h"
+#include "plstr.h"
 #include "prnetdb.h"
 
 //-----------------------------------------------------------------------------
 
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsIURI.h"
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -728,16 +728,17 @@ nsViewSourceChannel::SetReferrerWithPoli
     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
         mHttpChannel->SetReferrerWithPolicy(aReferrer, aReferrerPolicy);
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
                                       nsACString & aValue)
 {
+    aValue.Truncate();
     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
         mHttpChannel->GetRequestHeader(aHeader, aValue);
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::SetRequestHeader(const nsACString & aHeader,
                                       const nsACString & aValue,
                                       bool aMerge)
@@ -815,31 +816,31 @@ nsViewSourceChannel::GetRequestSucceeded
     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
         mHttpChannel->GetRequestSucceeded(aRequestSucceeded);
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
                                        nsACString & aValue)
 {
+    aValue.Truncate();
     if (!mHttpChannel)
         return NS_ERROR_NULL_POINTER;
 
     if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"),
                         nsCaseInsensitiveCStringComparator()) &&
         !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"),
                         nsCaseInsensitiveCStringComparator()) &&
         !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"),
                         nsCaseInsensitiveCStringComparator()) &&
         !aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
                         nsCaseInsensitiveCStringComparator())) {
-        aValue.Truncate();
         return NS_OK;
     }
-        
+
     return mHttpChannel->GetResponseHeader(aHeader, aValue);
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::SetResponseHeader(const nsACString & header,
                                        const nsACString & value, bool merge)
 {
     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
--- a/netwerk/test/unit/test_auth_dialog_permission.js
+++ b/netwerk/test/unit/test_auth_dialog_permission.js
@@ -1,10 +1,10 @@
 // This file tests authentication prompt depending on pref
-// network.auth.allow-subresource-auth:
+// network.auth.subresource-http-auth-allow:
 //   0 - don't allow sub-resources to open HTTP authentication credentials
 //       dialogs
 //   1 - allow sub-resources to open HTTP authentication credentials dialogs,
 //       but don't allow it for cross-origin sub-resources
 //   2 - allow the cross-origin authentication as well.
 
 Cu.import("resource://testing-common/httpd.js");
 
@@ -125,27 +125,27 @@ function makeChan(loadingUrl, url, conte
                              null,
                              Ci.nsILoadInfo.SEC_NORMAL,
                              contentPolicy)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   return chan;
 }
 
-function Test(allow_subresource_auth_pref, loadingUri, uri, contentPolicy,
+function Test(subresource_http_auth_allow_pref, loadingUri, uri, contentPolicy,
               expectedCode) {
-  this._allow_subresource_auth_pref = allow_subresource_auth_pref;
+  this._subresource_http_auth_allow_pref = subresource_http_auth_allow_pref;
   this._loadingUri = loadingUri;
   this._uri = uri;
   this._contentPolicy = contentPolicy;
   this._expectedCode = expectedCode;
 }
 
 Test.prototype = {
-  _allow_subresource_auth_pref: 1,
+  _subresource_http_auth_allow_pref: 1,
   _loadingUri: null,
   _uri: null,
   _contentPolicy: Ci.nsIContentPolicy.TYPE_OTHER,
   _expectedCode: 200,
 
   onStartRequest: function(request, ctx) {
     try {
       if (!Components.isSuccessCode(request.status)) {
@@ -178,24 +178,24 @@ Test.prototype = {
     Components.classes["@mozilla.org/network/http-auth-manager;1"]
               .getService(Components.interfaces.nsIHttpAuthManager)
               .clearAll();
 
     do_timeout(0, run_next_test);
   },
 
   run: function() {
-    dump("Run test: " + this._allow_subresource_auth_pref
+    dump("Run test: " + this._subresource_http_auth_allow_pref
                       + this._loadingUri
                       + this._uri
                       + this._contentPolicy
                       + this._expectedCode + " \n");
 
-    prefs.setIntPref("network.auth.allow-subresource-auth",
-                     this._allow_subresource_auth_pref);
+    prefs.setIntPref("network.auth.subresource-http-auth-allow",
+                     this._subresource_http_auth_allow_pref);
     let chan = makeChan(this._loadingUri, this._uri, this._contentPolicy);
     chan.notificationCallbacks = new Requestor(this._expectedCode == 200);
     chan.asyncOpen(this, null);
   }
 };
 
 var tests = [
   // For the next 3 tests the preference is set to 2 - allow the cross-origin
--- a/netwerk/test/unit/test_auth_proxy.js
+++ b/netwerk/test/unit/test_auth_proxy.js
@@ -240,17 +240,17 @@ function run_test() {
   const prefs = Cc["@mozilla.org/preferences-service;1"]
                          .getService(Ci.nsIPrefBranch);
   prefs.setCharPref("network.proxy.http", "localhost");
   prefs.setIntPref("network.proxy.http_port", httpserv.identity.primaryPort);
   prefs.setCharPref("network.proxy.no_proxies_on", "");
   prefs.setIntPref("network.proxy.type", 1);
 
   // Turn off the authentication dialog blocking for this test.
-  prefs.setIntPref("network.auth.allow-subresource-auth", 2);
+  prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
 
   tests[current_test]();
 }
 
 function test_proxy_returnfalse() {
   dump("\ntest: proxy returnfalse\n");
   var chan = makeChan();
   chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 0);
--- a/netwerk/test/unit/test_authentication.js
+++ b/netwerk/test/unit/test_authentication.js
@@ -2,17 +2,17 @@
 // TODO NIT use do_check_eq(expected, actual) consistently, not sometimes eq(actual, expected)
 
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Turn off the authentication dialog blocking for this test.
 var prefs = Cc["@mozilla.org/preferences-service;1"].
               getService(Ci.nsIPrefBranch);
-prefs.setIntPref("network.auth.allow-subresource-auth", 2);
+prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserv.identity.primaryPort;
 });
 
 XPCOMUtils.defineLazyGetter(this, "PORT", function() {
   return httpserv.identity.primaryPort;
 });
--- a/testing/mozharness/mozharness/base/vcs/hgtool.py
+++ b/testing/mozharness/mozharness/base/vcs/hgtool.py
@@ -74,20 +74,20 @@ class HgtoolVCS(ScriptMixin, LogMixin, T
         env = {'PATH': os.environ.get('PATH')}
         if c.get('env'):
             env.update(c['env'])
         if share_base is not None:
             env['HG_SHARE_BASE_DIR'] = share_base
         if self._is_windows():
             # SYSTEMROOT is needed for 'import random'
             if 'SYSTEMROOT' not in env:
-                env['SYSTEMROOT'] = os.environ.get('SYSTEMROOT')
+                env['SYSTEMROOT'] = os.environ.get('SYSTEMROOT', '')
             # HOME is needed for the 'hg help share' check
             if 'HOME' not in env:
-                env['HOME'] = os.environ.get('HOME')
+                env['HOME'] = os.environ.get('HOME', '')
 
         cmd = self.hgtool[:]
 
         if clone_by_rev:
             cmd.append('--clone-by-revision')
         if branch:
             cmd.extend(['-b', branch])
         if revision:
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -1236,17 +1236,17 @@ or run without that action (ie: --no-{ac
         else:
             # capitalize every word in between '-'
             branch_list = self.branch.split('-')
             branch_list = [elem.capitalize() for elem in branch_list]
             return '-'.join(branch_list)
 
     def _query_props_set_by_mach(self, console_output=True, error_level=FATAL):
         mach_properties_path = os.path.join(
-            self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json'
+            self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json'
         )
         self.info("setting properties set by mach build. Looking in path: %s"
                   % mach_properties_path)
         if os.path.exists(mach_properties_path):
             with self.opened(mach_properties_path, error_level=error_level) as (fh, err):
                 build_props = json.load(fh)
                 if err:
                     self.log("%s exists but there was an error reading the "
@@ -1257,19 +1257,17 @@ or run without that action (ie: --no-{ac
                              error_level)
                 if console_output:
                     self.info("Properties set from 'mach build'")
                     self.info(pprint.pformat(build_props))
             for key, prop in build_props.iteritems():
                 if prop != 'UNKNOWN':
                     self.set_buildbot_property(key, prop, write_to_file=True)
         else:
-            self.log("Could not determine path for build properties. "
-                     "Does this exist: `%s` ?" % mach_properties_path,
-                     level=error_level)
+            self.info("No mach_build_properties.json found - not importing properties.")
 
     def generate_build_props(self, console_output=True, halt_on_failure=False):
         """sets props found from mach build and, in addition, buildid,
         sourcestamp,  appVersion, and appName."""
 
         error_level = ERROR
         if halt_on_failure:
             error_level = FATAL
@@ -1639,17 +1637,17 @@ or run without that action (ie: --no-{ac
             # the old package should live in source dir so we don't need to do
             # this for nighties since we clobber the whole work_dir in
             # clobber()
             self._rm_old_package()
         self._get_mozconfig()
         self._run_tooltool()
         self._create_mozbuild_dir()
         mach_props = os.path.join(
-            self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json'
+            self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json'
         )
         if os.path.exists(mach_props):
             self.info("Removing previous mach property file: %s" % mach_props)
             self.rmtree(mach_props)
 
     def build(self):
         """builds application."""
         env = self.query_build_env()
--- a/testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
+++ b/testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
@@ -160,16 +160,23 @@ class FirefoxUITests(VCSToolsScript, Vir
                 return symbols_url
 
             except urllib2.HTTPError, e:
                 self.warning('{} - {}'.format(str(e), symbols_url))
                 return None
         else:
             self.fatal('Can\'t find symbols_url from installer_url: {}!'.format(installer_url))
 
+    @PreScriptAction('checkout')
+    def _pre_checkout(self, action):
+        if not self.firefox_ui_branch:
+            self.fatal(
+                'Please specify --firefox-ui-branch. Valid values can be found '
+                'in here https://github.com/mozilla/firefox-ui-tests/branches')
+
     def checkout(self):
         """
         We checkout firefox_ui_tests and update to the right branch
         for it.
         """
         dirs = self.query_abs_dirs()
 
         self.vcs_checkout(
@@ -198,23 +205,24 @@ class FirefoxUITests(VCSToolsScript, Vir
         """
         return []
 
     def run_test(self, installer_path, script_name, env=None, symbols_url=None,
                  cleanup=True, marionette_port=2828):
         """All required steps for running the tests against an installer."""
         dirs = self.query_abs_dirs()
 
-        bin_dir = os.path.dirname(self.query_python_path())
-        fx_ui_tests_bin = os.path.join(bin_dir, script_name)
+        venv_python_path = self.query_python_path()
+        update_script = os.path.join(dirs['fx_ui_dir'], 'firefox_ui_harness', 'cli_update.py')
         gecko_log = os.path.join(dirs['abs_log_dir'], 'gecko.log')
 
         # Build the command
         cmd = [
-            fx_ui_tests_bin,
+            venv_python_path,
+            update_script,
             '--installer', installer_path,
             # Log to stdout until tests are stable.
             '--gecko-log=-',
             '--address', 'localhost:{}'.format(marionette_port),
             # Use the work dir to get temporary data stored
             '--workspace', dirs['abs_work_dir'],
         ]
 
--- a/testing/mozharness/scripts/firefox_ui_tests/update_release.py
+++ b/testing/mozharness/scripts/firefox_ui_tests/update_release.py
@@ -209,18 +209,19 @@ class ReleaseFirefoxUIUpdateTests(Firefo
             chunks=int(self.config['total_chunks']),
             thisChunk=int(self.config['this_chunk'])
         )
 
         self.releases = chunked_config.releases
 
     @PreScriptAction('run-tests')
     def _pre_run_tests(self, action):
-        assert 'release_update_config' in self.config, \
-            'You have to specify --release-update-config.'
+        assert ('release_update_config' in self.config or
+                self.installer_url or self.installer_path),
+                'Either specify --update-verify-config, --installer-url or --installer-path.'
 
     def run_tests(self):
         dirs = self.query_abs_dirs()
 
         # We don't want multiple outputs of the same environment information. To prevent
         # that, we can't make it an argument of run_command and have to print it on our own.
         self.info('Using env: {}'.format(pprint.pformat(self.query_env())))
 
--- a/toolkit/components/passwordmgr/test/test_prompt_async.html
+++ b/toolkit/components/passwordmgr/test/test_prompt_async.html
@@ -9,17 +9,17 @@
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 
     <script class="testbody" type="text/javascript">
         SimpleTest.waitForExplicitFinish();
         SimpleTest.requestFlakyTimeout("untriaged");
 
         var prefs = Cc["@mozilla.org/preferences-service;1"].
                         getService(Ci.nsIPrefBranch);
-        prefs.setIntPref("network.auth.allow-subresource-auth", 2);
+        prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
         // Class monitoring number of open dialog windows
         // It checks there is always open just a single dialog per application
         function dialogMonitor() {
             var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                                .getService(Ci.nsIObserverService);
             observerService.addObserver(this, "domwindowopened", false);
             observerService.addObserver(this, "domwindowclosed", false);
         }
--- a/toolkit/content/widgets/tree.xml
+++ b/toolkit/content/widgets/tree.xml
@@ -367,17 +367,17 @@
             var topadj = parseInt(style.borderTopWidth) + parseInt(style.paddingTop);
             input.top = textRect.y - topadj;
 
             // The leftside of the textbox is aligned to the left side of the text
             // in LTR mode, and left side of the cell in RTL mode.
             var left, widthdiff;
             if (style.direction == "rtl") {
               left = cellRect.x;
-              widthdiff = cellRect.x + cellRect.width - textRect.x - textRect.width;
+              widthdiff = cellRect.x - textRect.x;
             } else {
               left = textRect.x;
               widthdiff = textRect.x - cellRect.x;
             }
 
             input.left = left;
             input.height = textRect.height + topadj +
                            parseInt(style.borderBottomWidth) +
--- a/toolkit/crashreporter/tools/upload_symbols.py
+++ b/toolkit/crashreporter/tools/upload_symbols.py
@@ -75,17 +75,17 @@ def main():
             r = requests.post(
                 url,
                 files={'symbols.zip': open(sys.argv[1], 'rb')},
                 headers={'Auth-Token': auth_token},
                 allow_redirects=False,
                 timeout=120)
             # 500 is likely to be a transient failure.
             # Break out for success or other error codes.
-            if r.status_code  != 500:
+            if r.status_code < 500:
                 break
             print_error(r)
         except requests.exceptions.RequestException as e:
             print('Error: {0}'.format(e))
         print('Retrying...')
     else:
         print('Maximum retries hit, giving up!')
         return 1
--- a/toolkit/mozapps/extensions/test/xpinstall/browser_auth.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_auth.js
@@ -5,17 +5,17 @@ function test() {
   Harness.authenticationCallback = get_auth_info;
   Harness.downloadFailedCallback = download_failed;
   Harness.installEndedCallback = install_ended;
   Harness.installsCompletedCallback = finish_test;
   Harness.setup();
 
   var prefs = Cc["@mozilla.org/preferences-service;1"].
                         getService(Ci.nsIPrefBranch);
-  prefs.setIntPref("network.auth.allow-subresource-auth", 2);
+  prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "Unsigned XPI": TESTROOT + "authRedirect.sjs?" + TESTROOT + "unsigned.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -204,17 +204,17 @@ checksum:
 	@cat $(CHECKSUM_FILE)
 	@echo 'CHECKSUM FILE END'
 	$(SIGN_CHECKSUM_CMD)
 
 
 upload: checksum
 	$(PYTHON) $(MOZILLA_DIR)/build/upload.py --base-path $(DIST) \
 		--package $(PACKAGE) \
-		--properties-file $(DIST)/upload-properties.json \
+		--properties-file $(DIST)/mach_build_properties.json \
 		$(UPLOAD_FILES) \
 		$(CHECKSUM_FILES)
 
 # source-package creates a source tarball from the files in MOZ_PKG_SRCDIR,
 # which is either set to a clean checkout or defaults to $topsrcdir
 source-package:
 	@echo 'Packaging source tarball...'
 	$(MKDIR) -p $(DIST)/$(PKG_SRCPACK_PATH)
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -753,17 +753,17 @@ nsViewManager::DispatchEvent(WidgetGUIEv
        mouseEvent->reason == WidgetMouseEvent::eReal &&
        // Ignore mouse exit and enter (we'll get moves if the user
        // is really moving the mouse) since we get them when we
        // create and destroy widgets.
        mouseEvent->mMessage != eMouseExitFromWidget &&
        mouseEvent->mMessage != eMouseEnterIntoWidget) ||
       aEvent->HasKeyEventMessage() ||
       aEvent->HasIMEEventMessage() ||
-      aEvent->mMessage == NS_PLUGIN_INPUT_EVENT) {
+      aEvent->mMessage == ePluginInputEvent) {
     gLastUserEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
   }
 
   // Find the view whose coordinates system we're in.
   nsView* view = aView;
   bool dispatchUsingCoordinates = aEvent->IsUsingCoordinates();
   if (dispatchUsingCoordinates) {
     // Will dispatch using coordinates. Pretty bogus but it's consistent
--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -34,18 +34,18 @@ GetEventMessageName(EventMessage aMessag
     case NS_COMPOSITION_UPDATE:
       return "NS_COMPOSITION_UPDATE";
     case NS_COMPOSITION_CHANGE:
       return "NS_COMPOSITION_CHANGE";
     case NS_COMPOSITION_COMMIT_AS_IS:
       return "NS_COMPOSITION_COMMIT_AS_IS";
     case NS_COMPOSITION_COMMIT:
       return "NS_COMPOSITION_COMMIT";
-    case NS_SELECTION_SET:
-      return "NS_SELECTION_SET";
+    case eSetSelection:
+      return "eSetSelection";
     default:
       return "unacceptable event message";
   }
 }
 
 static const char*
 GetNotificationName(const IMENotification* aNotification)
 {
--- a/widget/EventMessageList.h
+++ b/widget/EventMessageList.h
@@ -201,20 +201,20 @@ NS_EVENT_MESSAGE(eSVGScroll,            
 NS_EVENT_MESSAGE(eSVGZoomEventFirst,    2900)
 NS_EVENT_MESSAGE(eSVGZoom,              eSVGZoomEventFirst)
 
 // XUL command events
 NS_EVENT_MESSAGE(eXULCommandEventFirst, 3000)
 NS_EVENT_MESSAGE(eXULCommand,           eXULCommandEventFirst)
 
 // Cut, copy, paste events
-NS_EVENT_MESSAGE(NS_CUTCOPYPASTE_EVENT_START, 3100)
-NS_EVENT_MESSAGE(NS_COPY,               NS_CUTCOPYPASTE_EVENT_START)
-NS_EVENT_MESSAGE(NS_CUT,                NS_CUTCOPYPASTE_EVENT_START + 1)
-NS_EVENT_MESSAGE(NS_PASTE,              NS_CUTCOPYPASTE_EVENT_START + 2)
+NS_EVENT_MESSAGE(eClipboardEventFirst,  3100)
+NS_EVENT_MESSAGE(eCopy,                 eClipboardEventFirst)
+NS_EVENT_MESSAGE(eCut,                  eClipboardEventFirst + 1)
+NS_EVENT_MESSAGE(ePaste,                eClipboardEventFirst + 2)
 
 // Query the content information
 NS_EVENT_MESSAGE(NS_QUERY_CONTENT_EVENT_START,       3200)
 // Query for the selected text information, it return the selection offset,
 // selection length and selected text.
 NS_EVENT_MESSAGE(NS_QUERY_SELECTED_TEXT,             NS_QUERY_CONTENT_EVENT_START)
 // Query for the text content of specified range, it returns actual lengh (if
 // the specified range is too long) and the text of the specified range.
@@ -239,38 +239,37 @@ NS_EVENT_MESSAGE(NS_QUERY_SELECTION_AS_T
 // rect and also tentative caret point if the point is clicked.  The point is
 // specified by Event::refPoint.
 NS_EVENT_MESSAGE(NS_QUERY_CHARACTER_AT_POINT,        NS_QUERY_CONTENT_EVENT_START + 8)
 // Query if the DOM element under Event::refPoint belongs to our widget
 // or not.
 NS_EVENT_MESSAGE(NS_QUERY_DOM_WIDGET_HITTEST,        NS_QUERY_CONTENT_EVENT_START + 9)
 
 // Video events
-NS_EVENT_MESSAGE(NS_MEDIA_EVENT_START,  3300)
-NS_EVENT_MESSAGE(NS_LOADSTART,          NS_MEDIA_EVENT_START)
-NS_EVENT_MESSAGE(NS_PROGRESS,           NS_MEDIA_EVENT_START + 1)
-NS_EVENT_MESSAGE(NS_SUSPEND,            NS_MEDIA_EVENT_START + 2)
-NS_EVENT_MESSAGE(NS_EMPTIED,            NS_MEDIA_EVENT_START + 3)
-NS_EVENT_MESSAGE(NS_STALLED,            NS_MEDIA_EVENT_START + 4)
-NS_EVENT_MESSAGE(NS_PLAY,               NS_MEDIA_EVENT_START + 5)
-NS_EVENT_MESSAGE(NS_PAUSE,              NS_MEDIA_EVENT_START + 6)
-NS_EVENT_MESSAGE(NS_LOADEDMETADATA,     NS_MEDIA_EVENT_START + 7)
-NS_EVENT_MESSAGE(NS_LOADEDDATA,         NS_MEDIA_EVENT_START + 8)
-NS_EVENT_MESSAGE(NS_WAITING,            NS_MEDIA_EVENT_START + 9)
-NS_EVENT_MESSAGE(NS_PLAYING,            NS_MEDIA_EVENT_START + 10)
-NS_EVENT_MESSAGE(NS_CANPLAY,            NS_MEDIA_EVENT_START + 11)
-NS_EVENT_MESSAGE(NS_CANPLAYTHROUGH,     NS_MEDIA_EVENT_START + 12)
-NS_EVENT_MESSAGE(NS_SEEKING,            NS_MEDIA_EVENT_START + 13)
-NS_EVENT_MESSAGE(NS_SEEKED,             NS_MEDIA_EVENT_START + 14)
-NS_EVENT_MESSAGE(NS_TIMEUPDATE,         NS_MEDIA_EVENT_START + 15)
-NS_EVENT_MESSAGE(NS_ENDED,              NS_MEDIA_EVENT_START + 16)
-NS_EVENT_MESSAGE(NS_RATECHANGE,         NS_MEDIA_EVENT_START + 17)
-NS_EVENT_MESSAGE(NS_DURATIONCHANGE,     NS_MEDIA_EVENT_START + 18)
-NS_EVENT_MESSAGE(NS_VOLUMECHANGE,       NS_MEDIA_EVENT_START + 19)
-NS_EVENT_MESSAGE(NS_NEED_KEY,           NS_MEDIA_EVENT_START + 20)
+NS_EVENT_MESSAGE(eMediaEventFirst,      3300)
+NS_EVENT_MESSAGE(eLoadStart,            eMediaEventFirst)
+NS_EVENT_MESSAGE(eProgress,             eMediaEventFirst + 1)
+NS_EVENT_MESSAGE(eSuspend,              eMediaEventFirst + 2)
+NS_EVENT_MESSAGE(eEmptied,              eMediaEventFirst + 3)
+NS_EVENT_MESSAGE(eStalled,              eMediaEventFirst + 4)
+NS_EVENT_MESSAGE(ePlay,                 eMediaEventFirst + 5)
+NS_EVENT_MESSAGE(ePause,                eMediaEventFirst + 6)
+NS_EVENT_MESSAGE(eLoadedMetaData,       eMediaEventFirst + 7)
+NS_EVENT_MESSAGE(eLoadedData,           eMediaEventFirst + 8)
+NS_EVENT_MESSAGE(eWaiting,              eMediaEventFirst + 9)
+NS_EVENT_MESSAGE(ePlaying,              eMediaEventFirst + 10)
+NS_EVENT_MESSAGE(eCanPlay,              eMediaEventFirst + 11)
+NS_EVENT_MESSAGE(eCanPlayThrough,       eMediaEventFirst + 12)
+NS_EVENT_MESSAGE(eSeeking,              eMediaEventFirst + 13)
+NS_EVENT_MESSAGE(eSeeked,               eMediaEventFirst + 14)
+NS_EVENT_MESSAGE(eTimeUpdate,           eMediaEventFirst + 15)
+NS_EVENT_MESSAGE(eEnded,                eMediaEventFirst + 16)
+NS_EVENT_MESSAGE(eRateChange,           eMediaEventFirst + 17)
+NS_EVENT_MESSAGE(eDurationChange,       eMediaEventFirst + 18)
+NS_EVENT_MESSAGE(eVolumeChange,         eMediaEventFirst + 19)
 
 // paint notification events
 NS_EVENT_MESSAGE(NS_NOTIFYPAINT_START,  3400)
 NS_EVENT_MESSAGE(NS_AFTERPAINT,         NS_NOTIFYPAINT_START)
 
 // Simple gesture events
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_EVENT_START,    3500)
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_SWIPE_MAY_START,NS_SIMPLE_GESTURE_EVENT_START)
@@ -286,24 +285,23 @@ NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_ROTAT
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_ROTATE,         NS_SIMPLE_GESTURE_EVENT_START + 10)
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_TAP,            NS_SIMPLE_GESTURE_EVENT_START + 11)
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_PRESSTAP,       NS_SIMPLE_GESTURE_EVENT_START + 12)
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_EDGE_STARTED,   NS_SIMPLE_GESTURE_EVENT_START + 13)
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_EDGE_CANCELED,  NS_SIMPLE_GESTURE_EVENT_START + 14)
 NS_EVENT_MESSAGE(NS_SIMPLE_GESTURE_EDGE_COMPLETED, NS_SIMPLE_GESTURE_EVENT_START + 15)
 
 // These are used to send native events to plugins.
-NS_EVENT_MESSAGE(NS_PLUGIN_EVENT_START, 3600)
-NS_EVENT_MESSAGE(NS_PLUGIN_INPUT_EVENT, NS_PLUGIN_EVENT_START)
-NS_EVENT_MESSAGE(NS_PLUGIN_FOCUS_EVENT, NS_PLUGIN_EVENT_START + 1)
+NS_EVENT_MESSAGE(ePluginEventFirst,     3600)
+NS_EVENT_MESSAGE(ePluginInputEvent,     ePluginEventFirst)
 
 // Events to manipulate selection (WidgetSelectionEvent)
-NS_EVENT_MESSAGE(NS_SELECTION_EVENT_START, 3700)
+NS_EVENT_MESSAGE(eSelectionEventFirst,  3700)
 // Clear any previous selection and set the given range as the selection
-NS_EVENT_MESSAGE(NS_SELECTION_SET,      NS_SELECTION_EVENT_START)
+NS_EVENT_MESSAGE(eSetSelection,         eSelectionEventFirst)
 
 // Events of commands for the contents
 NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_EVENT_START,        3800)
 NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_CUT,                NS_CONTENT_COMMAND_EVENT_START)
 NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_COPY,               NS_CONTENT_COMMAND_EVENT_START + 1)
 NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_PASTE,              NS_CONTENT_COMMAND_EVENT_START + 2)
 NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_DELETE,             NS_CONTENT_COMMAND_EVENT_START + 3)
 NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_UNDO,               NS_CONTENT_COMMAND_EVENT_START + 4)
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1803,17 +1803,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
                     composition->String().Length()) {
 
                 // Only start a new composition if we have key events,
                 // if we don't have an existing composition, or
                 // the replaced text does not match our composition.
                 RemoveIMEComposition();
 
                 {
-                    WidgetSelectionEvent event(true, NS_SELECTION_SET, this);
+                    WidgetSelectionEvent event(true, eSetSelection, this);
                     InitEvent(event, nullptr);
                     event.mOffset = uint32_t(ae->Start());
                     event.mLength = uint32_t(ae->End() - ae->Start());
                     event.mExpandToClusterBoundary = false;
                     DispatchEvent(&event);
                 }
 
                 if (!mIMEKeyEvents.IsEmpty()) {
@@ -1883,17 +1883,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             /*
                 Set Gecko selection to ae->Start() to ae->End()
 
                 Selection updates are masked to prevent Java from being
                   notified of the new selection
             */
             AutoIMEMask selMask(mIMEMaskSelectionUpdate);
             RemoveIMEComposition();
-            WidgetSelectionEvent selEvent(true, NS_SELECTION_SET, this);
+            WidgetSelectionEvent selEvent(true, eSetSelection, this);
             InitEvent(selEvent, nullptr);
 
             int32_t start = ae->Start(), end = ae->End();
 
             if (start < 0 || end < 0) {
                 WidgetQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT,
                                               this);
                 InitEvent(event, nullptr);
@@ -1962,17 +1962,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
                     composition->NativeOffsetOfStartComposition() +
                     composition->String().Length()) {
 
                 // Only start new composition if we don't have an existing one,
                 // or if the existing composition doesn't match the new one.
                 RemoveIMEComposition();
 
                 {
-                    WidgetSelectionEvent event(true, NS_SELECTION_SET, this);
+                    WidgetSelectionEvent event(true, eSetSelection, this);
                     InitEvent(event, nullptr);
                     event.mOffset = uint32_t(ae->Start());
                     event.mLength = uint32_t(ae->End() - ae->Start());
                     event.mExpandToClusterBoundary = false;
                     DispatchEvent(&event);
                 }
 
                 {
--- a/widget/cocoa/TextInputHandler.h
+++ b/widget/cocoa/TextInputHandler.h
@@ -349,17 +349,17 @@ public:
    *
    * @param aEvent                An event which you want to dispatch.
    * @return                      TRUE if the event is consumed by web contents
    *                              or chrome contents.  Otherwise, FALSE.
    */
   bool DispatchEvent(WidgetGUIEvent& aEvent);
 
   /**
-   * SetSelection() dispatches NS_SELECTION_SET event for the aRange.
+   * SetSelection() dispatches eSetSelection event for the aRange.
    *
    * @param aRange                The range which will be selected.
    * @return                      TRUE if setting selection is succeeded and
    *                              the widget hasn't been destroyed.
    *                              Otherwise, FALSE.
    */
   bool SetSelection(NSRange& aRange);
 
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -3960,17 +3960,17 @@ TextInputHandlerBase::AttachNativeKeyEve
 }
 
 bool
 TextInputHandlerBase::SetSelection(NSRange& aRange)
 {
   MOZ_ASSERT(!Destroyed());
 
   nsRefPtr<TextInputHandlerBase> kungFuDeathGrip(this);
-  WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, mWidget);
+  WidgetSelectionEvent selectionEvent(true, eSetSelection, mWidget);
   selectionEvent.mOffset = aRange.location;
   selectionEvent.mLength = aRange.length;
   selectionEvent.mReversed = false;
   selectionEvent.mExpandToClusterBoundary = false;
   DispatchEvent(selectionEvent);
   NS_ENSURE_TRUE(selectionEvent.mSucceeded, false);
   return !Destroyed();
 }
--- a/widget/gtk/IMContextWrapper.cpp
+++ b/widget/gtk/IMContextWrapper.cpp
@@ -2048,17 +2048,17 @@ IMContextWrapper::DeleteText(GtkIMContex
     }
 
     gchar* charAtOffset =
         g_utf8_offset_to_pointer(utf8Str.get(), offsetInUTF8Characters);
     gchar* charAtEnd =
         g_utf8_offset_to_pointer(utf8Str.get(), endInUTF8Characters);
 
     // Set selection to delete
-    WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET,
+    WidgetSelectionEvent selectionEvent(true, eSetSelection,
                                         mLastFocusedWindow);
 
     nsDependentCSubstring utf8StrBeforeOffset(utf8Str, 0,
                                               charAtOffset - utf8Str.get());
     selectionEvent.mOffset =
         NS_ConvertUTF8toUTF16(utf8StrBeforeOffset).Length();
 
     nsDependentCSubstring utf8DeletingStr(utf8Str,
--- a/widget/nsPrintSession.h
+++ b/widget/nsPrintSession.h
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPrintSession_h__
 #define nsPrintSession_h__
 
 #include "nsIPrintSession.h" 
 #include "nsWeakReference.h"
-#include "gfxCore.h"
 
 //*****************************************************************************
 //***    nsPrintSession
 //*****************************************************************************
 
 class nsPrintSession : public nsIPrintSession,
                        public nsSupportsWeakReference
 {
--- a/widget/nsPrintSettingsImpl.h
+++ b/widget/nsPrintSettingsImpl.h
@@ -2,17 +2,16 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPrintSettingsImpl_h__
 #define nsPrintSettingsImpl_h__
 
-#include "gfxCore.h"
 #include "nsIPrintSettings.h"  
 #include "nsMargin.h"  
 #include "nsString.h"
 #include "nsWeakReference.h"  
 
 #define NUM_HEAD_FOOT 3
 
 //*****************************************************************************
--- a/widget/tests/TestWinTSF.cpp
+++ b/widget/tests/TestWinTSF.cpp
@@ -1884,19 +1884,19 @@ bool
 TestApp::TestSelection(void)
 {
   bool succeeded = true;
 
   /* If these fail the cause is probably one or more of:
    * nsTextStore::GetSelection not sending NS_QUERY_SELECTED_TEXT
    * NS_QUERY_SELECTED_TEXT not handled by ContentEventHandler
    * Bug in NS_QUERY_SELECTED_TEXT handler
-   * nsTextStore::SetSelection not sending NS_SELECTION_SET
-   * NS_SELECTION_SET not handled by ContentEventHandler
-   * Bug in NS_SELECTION_SET handler
+   * nsTextStore::SetSelection not sending eSetSelection
+   * eSetSelection not handled by ContentEventHandler
+   * Bug in eSetSelection handler
    */
 
   TS_SELECTION_ACP testSel;
   ULONG selFetched;
 
   if (!mMgr->GetFocusedStore()) {
     fail("TestSelection: GetFocusedStore returns null");
     return false;
@@ -1960,17 +1960,17 @@ TestApp::TestText(void)
   HRESULT hr;
 
   /* If these fail the cause is probably one or more of:
    * nsTextStore::GetText not sending NS_QUERY_TEXT_CONTENT
    * NS_QUERY_TEXT_CONTENT not handled by ContentEventHandler
    * Bug in NS_QUERY_TEXT_CONTENT handler
    * nsTextStore::SetText not calling SetSelection or InsertTextAtSelection
    * Bug in SetSelection or InsertTextAtSelection
-   *  NS_SELECTION_SET bug or NS_COMPOSITION_* / NS_COMPOSITION_CHANGE bug
+   *  eSetSelection bug or NS_COMPOSITION_* / NS_COMPOSITION_CHANGE bug
    */
 
   if (!mMgr->GetFocusedStore()) {
     fail("TestText: GetFocusedStore returns null #1");
     return false;
   }
 
   // Get all text
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -1684,26 +1684,26 @@ TSFTextStore::FlushPendingActions()
         MOZ_LOG(sTextStoreLog, LogLevel::Debug,
                ("TSF: 0x%p   TSFTextStore::FlushPendingActions() "
                 "flushing COMPOSITION_START={ mSelectionStart=%d, "
                 "mSelectionLength=%d }",
                 this, action.mSelectionStart, action.mSelectionLength));
 
         if (action.mAdjustSelection) {
           // Select composition range so the new composition replaces the range
-          WidgetSelectionEvent selectionSet(true, NS_SELECTION_SET, mWidget);
+          WidgetSelectionEvent selectionSet(true, eSetSelection, mWidget);
           mWidget->InitEvent(selectionSet);
           selectionSet.mOffset = static_cast<uint32_t>(action.mSelectionStart);
           selectionSet.mLength = static_cast<uint32_t>(action.mSelectionLength);
           selectionSet.mReversed = false;
           DispatchEvent(selectionSet);
           if (!selectionSet.mSucceeded) {
             MOZ_LOG(sTextStoreLog, LogLevel::Error,
                    ("TSF: 0x%p   TSFTextStore::FlushPendingActions() "
-                    "FAILED due to NS_SELECTION_SET failure", this));
+                    "FAILED due to eSetSelection failure", this));
             break;
           }
         }
         MOZ_LOG(sTextStoreLog, LogLevel::Debug,
                ("TSF: 0x%p   TSFTextStore::FlushPendingActions() "
                 "dispatching compositionstart event...", this));
         WidgetCompositionEvent compositionStart(true, NS_COMPOSITION_START,
                                                 mWidget);
@@ -1810,25 +1810,25 @@ TSFTextStore::FlushPendingActions()
           mDeferClearingLockedContent = true;
         }
         DispatchEvent(compositionCommit);
         if (!mWidget || mWidget->Destroyed()) {
           break;
         }
         break;
       }
-      case PendingAction::SELECTION_SET: {
+      case PendingAction::SET_SELECTION: {
         MOZ_LOG(sTextStoreLog, LogLevel::Debug,
                ("TSF: 0x%p   TSFTextStore::FlushPendingActions() "
-                "flushing SELECTION_SET={ mSelectionStart=%d, "
+                "flushing SET_SELECTION={ mSelectionStart=%d, "
                 "mSelectionLength=%d, mSelectionReversed=%s }",
                 this, action.mSelectionStart, action.mSelectionLength,
                 GetBoolName(action.mSelectionReversed)));
 
-        WidgetSelectionEvent selectionSet(true, NS_SELECTION_SET, mWidget);
+        WidgetSelectionEvent selectionSet(true, eSetSelection, mWidget);
         selectionSet.mOffset = 
           static_cast<uint32_t>(action.mSelectionStart);
         selectionSet.mLength =
           static_cast<uint32_t>(action.mSelectionLength);
         selectionSet.mReversed = action.mSelectionReversed;
         break;
       }
       default:
@@ -2707,17 +2707,17 @@ TSFTextStore::SetSelectionInternal(const
         return hr;
       }
     }
     return S_OK;
   }
 
   CompleteLastActionIfStillIncomplete();
   PendingAction* action = mPendingActions.AppendElement();
-  action->mType = PendingAction::SELECTION_SET;
+  action->mType = PendingAction::SET_SELECTION;
   action->mSelectionStart = pSelection->acpStart;
   action->mSelectionLength = pSelection->acpEnd - pSelection->acpStart;
   action->mSelectionReversed = (pSelection->style.ase == TS_AE_START);
 
   currentSel.SetSelection(*pSelection);
 
   return S_OK;
 }
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -506,17 +506,17 @@ protected:
 
   struct PendingAction final
   {
     enum ActionType : uint8_t
     {
       COMPOSITION_START,
       COMPOSITION_UPDATE,
       COMPOSITION_END,
-      SELECTION_SET
+      SET_SELECTION
     };
     ActionType mType;
     // For compositionstart and selectionset
     LONG mSelectionStart;
     LONG mSelectionLength;
     // For compositionupdate and compositionend
     nsString mData;
     // For compositionupdate
--- a/widget/windows/nsWindowBase.cpp
+++ b/widget/windows/nsWindowBase.cpp
@@ -18,17 +18,17 @@ bool nsWindowBase::sTouchInjectInitializ
 InjectTouchInputPtr nsWindowBase::sInjectTouchFuncPtr;
 
 bool
 nsWindowBase::DispatchPluginEvent(const MSG& aMsg)
 {
   if (!PluginHasFocus()) {
     return false;
   }
-  WidgetPluginEvent pluginEvent(true, NS_PLUGIN_INPUT_EVENT, this);
+  WidgetPluginEvent pluginEvent(true, ePluginInputEvent, this);
   nsIntPoint point(0, 0);
   InitEvent(pluginEvent, &point);
   NPEvent npEvent;
   npEvent.event = aMsg.message;
   npEvent.wParam = aMsg.wParam;
   npEvent.lParam = aMsg.lParam;
   pluginEvent.mPluginEvent.Copy(npEvent);
   pluginEvent.retargetToFocusedDocument = true;
--- a/xpcom/threads/TaskQueue.cpp
+++ b/xpcom/threads/TaskQueue.cpp
@@ -58,17 +58,17 @@ TaskQueue::DispatchLocked(already_AddRef
   if (mIsShutdown) {
     return NS_ERROR_FAILURE;
   }
   mTasks.push(r.forget());
   if (mIsRunning) {
     return NS_OK;
   }
   nsRefPtr<nsIRunnable> runner(new Runner(this));
-  nsresult rv = mPool->Dispatch(runner, NS_DISPATCH_NORMAL);
+  nsresult rv = mPool->Dispatch(runner.forget(), NS_DISPATCH_NORMAL);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch runnable to run TaskQueue");
     return rv;
   }
   mIsRunning = true;
 
   return NS_OK;
 }
@@ -150,17 +150,17 @@ TaskQueue::Runner::Run()
     MonitorAutoLock mon(mQueue->mQueueMonitor);
     MOZ_ASSERT(mQueue->mIsRunning);
     if (mQueue->mTasks.size() == 0) {
       mQueue->mIsRunning = false;
       mQueue->MaybeResolveShutdown();
       mon.NotifyAll();
       return NS_OK;
     }
-    event = mQueue->mTasks.front();
+    event = mQueue->mTasks.front().forget();
     mQueue->mTasks.pop();
   }
   MOZ_ASSERT(event);
 
   // Note that dropping the queue monitor before running the task, and
   // taking the monitor again after the task has run ensures we have memory
   // fences enforced. This means that if the object we're calling wasn't
   // designed to be threadsafe, it will be, provided we're only calling it
--- a/xpcom/threads/TimerThread.cpp
+++ b/xpcom/threads/TimerThread.cpp
@@ -26,18 +26,17 @@ NS_IMPL_ISUPPORTS(TimerThread, nsIRunnab
 
 TimerThread::TimerThread() :
   mInitInProgress(false),
   mInitialized(false),
   mMonitor("TimerThread.mMonitor"),
   mShutdown(false),
   mWaiting(false),
   mNotified(false),
-  mSleeping(false),
-  mLastTimerEventLoopRun(TimeStamp::Now())
+  mSleeping(false)
 {
 }
 
 TimerThread::~TimerThread()
 {
   mThread = nullptr;
 
   NS_ASSERTION(mTimers.IsEmpty(), "Timers remain in TimerThread::~TimerThread");
@@ -436,17 +435,16 @@ TimerThread::Run()
       uint32_t milliseconds = 100;
       if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) {
         milliseconds = ChaosMode::randomUint32LessThan(200);
       }
       waitFor = PR_MillisecondsToInterval(milliseconds);
     } else {
       waitFor = PR_INTERVAL_NO_TIMEOUT;
       TimeStamp now = TimeStamp::Now();
-      mLastTimerEventLoopRun = now;
       nsTimerImpl* timer = nullptr;
 
       if (!mTimers.IsEmpty()) {
         timer = mTimers[0];
 
         if (now >= timer->mTimeout || forceRunThisTimer) {
     next:
           // NB: AddRef before the Release under RemoveTimerInternal to avoid
@@ -742,46 +740,29 @@ TimerThread::PostTimerEvent(already_AddR
   return nullptr;
 }
 
 void
 TimerThread::DoBeforeSleep()
 {
   // Mainthread
   MonitorAutoLock lock(mMonitor);
-  mLastTimerEventLoopRun = TimeStamp::Now();
   mSleeping = true;
 }
 
 // Note: wake may be notified without preceding sleep notification
 void
 TimerThread::DoAfterSleep()
 {
   // Mainthread
-  TimeStamp now = TimeStamp::Now();
-
   MonitorAutoLock lock(mMonitor);
-
-  // an over-estimate of time slept, usually small
-  TimeDuration slept = now - mLastTimerEventLoopRun;
+  mSleeping = false;
 
-  // Adjust all old timers to expire roughly similar times in the future
-  // compared to when we went to sleep, by adding the time we slept to the
-  // target time. It's slightly possible a few will end up slightly in the
-  // past and fire immediately, but ordering should be preserved.  All
-  // timers retain the exact same order (and relative times) as before
-  // going to sleep.
-  for (uint32_t i = 0; i < mTimers.Length(); i ++) {
-    nsTimerImpl* timer = mTimers[i];
-    timer->mTimeout += slept;
-  }
-  mSleeping = false;
-  mLastTimerEventLoopRun = now;
-
-  // Wake up the timer thread to process the updated array
+  // Wake up the timer thread to re-process the array to ensure the sleep delay is correct,
+  // and fire any expired timers (perhaps quite a few)
   mNotified = true;
   mMonitor.Notify();
 }
 
 
 NS_IMETHODIMP
 TimerThread::Observe(nsISupports* /* aSubject */, const char* aTopic,
                      const char16_t* /* aData */)
--- a/xpcom/threads/TimerThread.h
+++ b/xpcom/threads/TimerThread.h
@@ -72,17 +72,16 @@ private:
 
   nsCOMPtr<nsIThread> mThread;
   Monitor mMonitor;
 
   bool mShutdown;
   bool mWaiting;
   bool mNotified;
   bool mSleeping;
-  TimeStamp mLastTimerEventLoopRun;
 
   nsTArray<nsTimerImpl*> mTimers;
 };
 
 struct TimerAdditionComparator
 {
   TimerAdditionComparator(const mozilla::TimeStamp& aNow,
                           nsTimerImpl* aTimerToInsert) :