Merge m-c to fxteam
authorWes Kocher <wkocher@mozilla.com>
Tue, 22 Oct 2013 18:46:56 -0400
changeset 166531 43ab56722bb675cfab6a54a15331d927d1ca2879
parent 166528 1b166374191c0953a1b3846579b98fdb0dc451cc (current diff)
parent 166423 31382b5fa51e14ce2e8c37e307a900fe8889ff84 (diff)
child 166532 8f8964ee7d123c167081ed66fd77f310ee40160b
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.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 m-c to fxteam
browser/installer/package-manifest.in
ipc/glue/AsyncChannel.cpp
xulrunner/examples/simple/components/public/Makefile.in
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/AccessibleWrap.cpp
@@ -891,17 +891,17 @@ AccessibleWrap::accNavigate(
   Accessible* accessible = GetXPAccessibleFor(varStart);
   if (!accessible)
     return E_INVALIDARG;
 
   if (accessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* navAccessible = nullptr;
-  int32_t xpRelation = -1;
+  Maybe<RelationType> xpRelation;
 
   switch(navDir) {
     case NAVDIR_FIRSTCHILD:
       if (!nsAccUtils::MustPrune(accessible))
         navAccessible = accessible->FirstChild();
       break;
     case NAVDIR_LASTCHILD:
       if (!nsAccUtils::MustPrune(accessible))
@@ -916,75 +916,75 @@ AccessibleWrap::accNavigate(
     case NAVDIR_DOWN:
     case NAVDIR_LEFT:
     case NAVDIR_RIGHT:
     case NAVDIR_UP:
       return E_NOTIMPL;
 
     // MSAA relationship extensions to accNavigate
     case NAVRELATION_CONTROLLED_BY:
-      xpRelation = static_cast<int32_t>(RelationType::CONTROLLED_BY);
+      xpRelation.construct(RelationType::CONTROLLED_BY);
       break;
     case NAVRELATION_CONTROLLER_FOR:
-      xpRelation = static_cast<int32_t>(RelationType::CONTROLLER_FOR);
+      xpRelation.construct(RelationType::CONTROLLER_FOR);
       break;
     case NAVRELATION_LABEL_FOR:
-      xpRelation = static_cast<int32_t>(RelationType::LABEL_FOR);
+      xpRelation.construct(RelationType::LABEL_FOR);
       break;
     case NAVRELATION_LABELLED_BY:
-      xpRelation = static_cast<int32_t>(RelationType::LABELLED_BY);
+      xpRelation.construct(RelationType::LABELLED_BY);
       break;
     case NAVRELATION_MEMBER_OF:
-      xpRelation = static_cast<int32_t>(RelationType::MEMBER_OF);
+      xpRelation.construct(RelationType::MEMBER_OF);
       break;
     case NAVRELATION_NODE_CHILD_OF:
-      xpRelation = static_cast<int32_t>(RelationType::NODE_CHILD_OF);
+      xpRelation.construct(RelationType::NODE_CHILD_OF);
       break;
     case NAVRELATION_FLOWS_TO:
-      xpRelation = static_cast<int32_t>(RelationType::FLOWS_TO);
+      xpRelation.construct(RelationType::FLOWS_TO);
       break;
     case NAVRELATION_FLOWS_FROM:
-      xpRelation = static_cast<int32_t>(RelationType::FLOWS_FROM);
+      xpRelation.construct(RelationType::FLOWS_FROM);
       break;
     case NAVRELATION_SUBWINDOW_OF:
-      xpRelation = static_cast<int32_t>(RelationType::SUBWINDOW_OF);
+      xpRelation.construct(RelationType::SUBWINDOW_OF);
       break;
     case NAVRELATION_EMBEDS:
-      xpRelation = static_cast<int32_t>(RelationType::EMBEDS);
+      xpRelation.construct(RelationType::EMBEDS);
       break;
     case NAVRELATION_EMBEDDED_BY:
-      xpRelation = static_cast<int32_t>(RelationType::EMBEDDED_BY);
+      xpRelation.construct(RelationType::EMBEDDED_BY);
       break;
     case NAVRELATION_POPUP_FOR:
-      xpRelation = static_cast<int32_t>(RelationType::POPUP_FOR);
+      xpRelation.construct(RelationType::POPUP_FOR);
       break;
     case NAVRELATION_PARENT_WINDOW_OF:
-      xpRelation = static_cast<int32_t>(RelationType::PARENT_WINDOW_OF);
+      xpRelation.construct(RelationType::PARENT_WINDOW_OF);
       break;
     case NAVRELATION_DEFAULT_BUTTON:
-      xpRelation = static_cast<int32_t>(RelationType::DEFAULT_BUTTON);
+      xpRelation.construct(RelationType::DEFAULT_BUTTON);
       break;
     case NAVRELATION_DESCRIBED_BY:
-      xpRelation = static_cast<int32_t>(RelationType::DESCRIBED_BY);
+      xpRelation.construct(RelationType::DESCRIBED_BY);
       break;
     case NAVRELATION_DESCRIPTION_FOR:
-      xpRelation = static_cast<int32_t>(RelationType::DESCRIPTION_FOR);
+      xpRelation.construct(RelationType::DESCRIPTION_FOR);
       break;
     case NAVRELATION_NODE_PARENT_OF:
-      xpRelation = static_cast<int32_t>(RelationType::NODE_PARENT_OF);
+      xpRelation.construct(RelationType::NODE_PARENT_OF);
       break;
 
     default:
       return E_INVALIDARG;
   }
 
   pvarEndUpAt->vt = VT_EMPTY;
 
-  if (xpRelation >= 0) {
-    Relation rel = RelationByType(static_cast<RelationType>(xpRelation));
+  if (!xpRelation.empty()) {
+    Relation rel = RelationByType(xpRelation.ref());
     navAccessible = rel.Next();
   }
 
   if (!navAccessible)
     return E_FAIL;
 
   pvarEndUpAt->pdispVal = NativeAccessible(navAccessible);
   pvarEndUpAt->vt = VT_DISPATCH;
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -744,17 +744,17 @@ pref("webgl.can-lose-context-in-foregrou
 // Allow nsMemoryInfoDumper to create a fifo in the temp directory.  We use
 // this fifo to trigger about:memory dumps, among other things.
 pref("memory_info_dumper.watch_fifo.enabled", true);
 pref("memory_info_dumper.watch_fifo.directory", "/data/local");
 
 pref("general.useragent.enable_overrides", true);
 // See ua-update.json.in for the packaged UA override list
 pref("general.useragent.updates.enabled", true);
-pref("general.useragent.updates.url", "");
+pref("general.useragent.updates.url", "https://dynamicua.cdn.mozilla.net/0/%APP_ID%");
 pref("general.useragent.updates.interval", 604800); // 1 week
 pref("general.useragent.updates.retry", 86400); // 1 day
 
 // Make <audio> and <video> talk to the AudioChannelService.
 pref("media.useAudioChannelService", true);
 
 pref("b2g.version", @MOZ_B2G_VERSION@);
 
--- a/b2g/app/ua-update.json.in
+++ b/b2g/app/ua-update.json.in
@@ -1,19 +1,15 @@
 // Comments must be on their own lines and must start with "//"
 
 // Send these sites a custom user-agent. Bugs to remove each override after
 // evangelism are included.
 {
-  // bug 802981, maps.google.com
-  "maps.google.com": "\\(Mobile#(Android; Mobile",
   // bug 826330, uol.com.br
   "uol.com.br": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
-  // bug 826332, live.com
-  "live.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
   // bug 826335, globo.com
   "globo.com": "\\(Mobile#(Android; Mobile",
   // bug 826338, yahoo.com
   "yahoo.com": "\\(Mobile#(Android; Mobile",
   // bug 826342, mercadolivre.com.br
   "mercadolivre.com.br": "\\(Mobile#(Android; Mobile",
   // bug 826343, ig.com.br
   "ig.com.br": "\\(Mobile#(Android; Mobile",
@@ -36,18 +32,16 @@
   // bug 826711, bb.com.br
   "bb.com.br": "\\(Mobile#(Android; Mobile",
   // bug 826712, orkut.com
   "orkut.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
   // bug 826715, noticias.uol.com.br
   "noticias.uol.com.br": "\\(Mobile#(Android; Mobile",
   // bug 826720, olx.com.br
   "olx.com.br": "\\(Mobile#(Android; Mobile",
-  // bug 826736, bancobrasil.com.br
-  "bancobrasil.com.br": "\\(Mobile#(Android; Mobile",
   // bug 826845, techtudo.com.br
   "techtudo.com.br": "\\(Mobile#(Android; Mobile",
   // bug 826958, ebay.com
   "ebay.com": "\\(Mobile#(Android; Mobile",
   // bug 827622, bing.com
   "bing.com": "\\(Mobile#(Android; Mobile",
   // bug 827625, pagseguro.uol.com.br
   "pagseguro.uol.com.br": "\\(Mobile#(Android; Mobile",
@@ -90,18 +84,16 @@
   // bug 828364, nk.pl
   "nk.pl": "\\(Mobile#(Android; Mobile",
   // bug 828366, wyborcza.biz
   "wyborcza.biz": "\\(Mobile#(Android; Mobile",
   // bug 828369, money.pl
   "money.pl": "\\(Mobile#(Android; Mobile",
   // bug 828371, ingbank.pl
   "ingbank.pl": "\\(Mobile#(Android; Mobile",
-  // bug 828376, plotek.pl
-  "plotek.pl": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
   // bug 828378, wyborcza.pl
   "wyborcza.pl": "\\(Mobile#(Android; Mobile",
   // bug 828380, deser.pl
   "deser.pl": "\\(Mobile#(Android; Mobile",
   // bug 828386, ebay.es
   "ebay.es": "\\(Mobile#(Android; Mobile",
   // bug 828392, infojobs.net
   "infojobs.net": "\\(Mobile#(Android; Mobile",
@@ -126,20 +118,16 @@
   // bug 828433, olx.com.ve
   "olx.com.ve": "\\(Mobile#(Android; Mobile",
   // bug 828439, movistar.com.ve
   "movistar.com.ve": "\\(Mobile#(Android; Mobile",
   // bug 828445, bumeran.com.ve
   "bumeran.com.ve": "\\(Mobile#(Android; Mobile",
   // bug 828448, petardas.com
   "petardas.com": "\\(Mobile#(Android; Mobile",
-  // bug 827869, mail.google.com
-  "mail.google.com": "\\(Mobile#(Android; Mobile",
-  // bug 843109, enfemenino.com
-  "enfemenino.com": "\\(Mobile#(Android; Mobile",
   // bug 843112, movil.bankinter.es
   "movil.bankinter.es": "\\(Mobile#(Android; Mobile",
   // bug 843114, einforma.com
   "einforma.com": "\\(Mobile#(Android; Mobile",
   // bug 843116, wwwhatsnew.com
   "wwwhatsnew.com": "\\(Mobile#(Android; Mobile",
   // bug 843119, askthebuilder.com
   "askthebuilder.com": "\\(Mobile#(Android; Mobile",
@@ -150,28 +138,22 @@
   // bug 843126, es.playstation.com
   "es.playstation.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
   // bug 843129, 11870.com
   "11870.com": "\\(Mobile#(Android; Mobile",
   // bug 843200, iphonejuegosgratis.com
   "iphonejuegosgratis.com": "\\(Mobile#(Android; Mobile",
   // bug 843132, comunio.es
   "comunio.es": "\\(Mobile#(Android; Mobile",
-  // bug 843134, news.google.com
-  "news.google.com": "\\(Mobile#(Android; Mobile",
   // bug 843136, deviantart.com
   "deviantart.com": "\\(Mobile#(Android; Mobile",
-  // bug 843137, nytimes.com
-  "nytimes.com": "\\(Mobile#(Android; Mobile",
   // bug 843139, consumersearch.com
   "consumersearch.com": "\\(Mobile#(Android; Mobile",
   // bug 843141, foodily.com
   "foodily.com": "\\(Mobile#(Android; Mobile",
-  // bug 843197, icanhas.cheezburger.com
-  "icanhas.cheezburger.com": "\\(Mobile#(Android; Mobile",
   // bug 843151, citibank.com
   "citibank.com": "\\(Mobile#(Android; Mobile",
   // bug 843153, games.com
   "games.com": "\\(Mobile#(Android; Mobile",
   // bug 843156, orbitz.com
   "orbitz.com": "\\(Mobile#(Android; Mobile",
   // bug 843158, starwoodhotels.com
   "starwoodhotels.com": "\\(Mobile#(Android; Mobile",
@@ -220,18 +202,16 @@
   // bug 878246, port.hu
   "port.hu": "\\(Mobile#(Android; Mobile",
   // bug 878249, portfolio.hu
   "portfolio.hu": "\\(Mobile#(Android; Mobile",
   // bug 878253, vatera.hu
   "vatera.hu": "\\(Mobile#(Android; Mobile",
   // bug 878255, 24sata.hr
   "24sata.hr": "\\(Mobile#(Android; Mobile",
-  // bug 878256, bet365.com
-  "bet365.com": "\\(Mobile#(Android; Mobile",
   // bug 878258, blackhatteam.com
   "blackhatteam.com": "\\(Mobile#(Android; Mobile",
   // bug 878260, cdm.me
   "cdm.me": "\\(Mobile#(Android; Mobile",
   // bug 878262, download.com
   "download.com": "\\(Mobile#(Android; Mobile",
   // bug 878264, haber.ba
   "haber.ba": "\\(Mobile#(Android; Mobile",
@@ -250,18 +230,16 @@
   // bug 878286, yandex.ru
   "yandex.ru": "\\(Mobile#(Android; Mobile",
   // bug 878630, ask.com
   "ask.com": "\\(Mobile#(Android; Mobile",
   // bug 878632, banorte.com
   "banorte.com": "\\(Mobile#(Android; Mobile",
   // bug 878634, buenastareas.com
   "buenastareas.com": "\\(Mobile#(Android; Mobile",
-  // bug 878635, cnn.com
-  "cnn.com": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
   // bug 878637, eluniversal.com.mx
   "eluniversal.com.mx": "\\(Mobile#(Android; Mobile",
   // bug 878640, hootsuite.com
   "hootsuite.com": "\\(Mobile#(Android; Mobile",
   // bug 878642, mercadolibre.com.mx
   "mercadolibre.com.mx": "\\(Mobile#(Android; Mobile",
   // bug 878645, olx.com.mx
   "olx.com.mx": "\\(Mobile#(Android; Mobile",
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "175b7a89aa5f39aa2b2263029ab086ac1833a636", 
+    "revision": "ef355aa8244d698a5b226ac4ef2408a2eb0812bb", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/branding/aurora/moz.build
+++ b/browser/branding/aurora/moz.build
@@ -1,8 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['content', 'locales']
 
+DIST_SUBDIR = 'browser'
+export('DIST_SUBDIR')
--- a/browser/branding/nightly/moz.build
+++ b/browser/branding/nightly/moz.build
@@ -1,7 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['content', 'locales']
+
+DIST_SUBDIR = 'browser'
+export('DIST_SUBDIR')
--- a/browser/branding/official/moz.build
+++ b/browser/branding/official/moz.build
@@ -1,8 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['content', 'locales']
 
+DIST_SUBDIR = 'browser'
+export('DIST_SUBDIR')
--- a/browser/branding/unofficial/moz.build
+++ b/browser/branding/unofficial/moz.build
@@ -1,8 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['content', 'locales']
 
+DIST_SUBDIR = 'browser'
+export('DIST_SUBDIR')
--- a/browser/defs.mk
+++ b/browser/defs.mk
@@ -1,2 +1,1 @@
-DIST_SUBDIR=browser
 XPI_ROOT_APPID=$(MOZ_APP_ID)
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -1,13 +1,14 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 STANDALONE_MAKEFILE := 1
+DIST_SUBDIR := browser
 
 include $(topsrcdir)/config/rules.mk
 
 MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in
 
 MOZ_PKG_MANIFEST_P = $(srcdir)/package-manifest.in
 # Some files have been already bundled with xulrunner
 ifndef SYSTEM_LIBXUL
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -170,23 +170,16 @@
 @BINPATH@/components/content_xslt.xpt
 @BINPATH@/components/cookie.xpt
 @BINPATH@/components/directory.xpt
 @BINPATH@/components/docshell.xpt
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 @BINPATH@/components/dom_system.xpt
-#ifdef MOZ_B2G_RIL
-@BINPATH@/components/dom_voicemail.xpt
-@BINPATH@/components/dom_wifi.xpt
-@BINPATH@/components/dom_system_gonk.xpt
-@BINPATH@/components/dom_icc.xpt
-@BINPATH@/components/dom_wappush.xpt
-#endif
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_camera.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_alarm.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
@@ -443,29 +436,16 @@
 @BINPATH@/components/nsFormAutoComplete.js
 @BINPATH@/components/nsFormHistory.js
 @BINPATH@/components/FormHistoryStartup.js
 @BINPATH@/components/nsInputListAutoComplete.js
 @BINPATH@/components/contentSecurityPolicy.manifest
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
-#ifdef MOZ_B2G_RIL
-@BINPATH@/components/RadioInterfaceLayer.manifest
-@BINPATH@/components/RadioInterfaceLayer.js
-@BINPATH@/components/MmsService.manifest
-@BINPATH@/components/MmsService.js
-@BINPATH@/components/RILContentHelper.js
-@BINPATH@/components/MobileMessageDatabaseService.manifest
-@BINPATH@/components/MobileMessageDatabaseService.js
-@BINPATH@/components/WifiWorker.js
-@BINPATH@/components/WifiWorker.manifest
-@BINPATH@/components/DOMWifiManager.js
-@BINPATH@/components/DOMWifiManager.manifest
-#endif
 @BINPATH@/browser/components/BrowserProfileMigrators.manifest
 @BINPATH@/browser/components/ProfileMigrator.js
 @BINPATH@/browser/components/ChromeProfileMigrator.js
 @BINPATH@/browser/components/FirefoxProfileMigrator.js
 #ifdef XP_WIN
 @BINPATH@/browser/components/IEProfileMigrator.js
 @BINPATH@/browser/components/SafariProfileMigrator.js
 #endif
--- a/browser/metro/base/Makefile.in
+++ b/browser/metro/base/Makefile.in
@@ -1,12 +1,10 @@
 # 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 $(topsrcdir)/config/config.mk
 
-DIST_SUBDIR=metro
-
 DEFINES += -DAB_CD=$(MOZ_UI_LOCALE) \
            -DPACKAGE=browser \
            -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
            $(NULL)
--- a/browser/metro/base/moz.build
+++ b/browser/metro/base/moz.build
@@ -1,8 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 METRO_CHROME_MANIFESTS += ['tests/mochiperf/metro.ini', 'tests/mochitest/metro.ini']
 XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
+
+DIST_SUBDIR = 'metro'
--- a/browser/metro/defs.mk
+++ b/browser/metro/defs.mk
@@ -1,2 +1,1 @@
-DIST_SUBDIR=metro
 XPI_ROOT_APPID={99bceaaa-e3c6-48c1-b981-ef9b46b67d60}
--- a/browser/metro/moz.build
+++ b/browser/metro/moz.build
@@ -10,8 +10,10 @@ DIRS += [
     'modules',
     'theme',
     'profile',
     'locales',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     DIRS += ['shell']
+
+DIST_SUBDIR = 'metro'
--- a/browser/metro/shell/commandexecutehandler/Makefile.in
+++ b/browser/metro/shell/commandexecutehandler/Makefile.in
@@ -1,19 +1,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/.
 
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 
 include $(topsrcdir)/config/config.mk
 
-# We want this exe in dist/bin
-DIST_SUBDIR =
-
 DIST_PROGRAM = CommandExecuteHandler$(BIN_SUFFIX)
 
 # Don't link against mozglue.dll
 MOZ_GLUE_LDFLAGS =
 MOZ_GLUE_PROGRAM_LDFLAGS =
 
 OS_LIBS = \
 	kernel32.lib \
--- a/browser/metro/shell/commandexecutehandler/moz.build
+++ b/browser/metro/shell/commandexecutehandler/moz.build
@@ -5,8 +5,11 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 PROGRAM = 'CommandExecuteHandler'
 
 CPP_SOURCES += [
     'CEHHelper.cpp',
     'CommandExecuteHandler.cpp',
 ]
+
+# We want this exe in dist/bin
+DIST_SUBDIR = ''
--- a/browser/metro/shell/linktool/Makefile.in
+++ b/browser/metro/shell/linktool/Makefile.in
@@ -1,18 +1,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/.
 
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 
 include $(topsrcdir)/config/config.mk
 
-DIST_SUBDIR = metro/install
-
 OS_LIBS = \
 	kernel32.lib \
 	user32.lib \
 	ole32.lib \
 	shlwapi.lib \
 	shell32.lib \
 	propsys.lib \
 	$(NULL)
--- a/browser/metro/shell/linktool/moz.build
+++ b/browser/metro/shell/linktool/moz.build
@@ -4,8 +4,10 @@
 # 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/.
 
 PROGRAM = 'linktool'
 
 CPP_SOURCES += [
     'linktool.cpp',
 ]
+
+DIST_SUBDIR = 'metro/install'
--- a/browser/metro/shell/testing/Makefile.in
+++ b/browser/metro/shell/testing/Makefile.in
@@ -8,19 +8,16 @@ USE_STATIC_LIBS = 1
 # don't use moz glue libs
 MOZ_GLUE_LDFLAGS =
 MOZ_GLUE_PROGRAM_LDFLAGS =
 
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 
 include $(topsrcdir)/config/config.mk
 
-# We want this exe in dist/bin
-DIST_SUBDIR =
-
 OS_LIBS = \
 	kernel32.lib \
 	user32.lib \
 	ole32.lib \
 	shlwapi.lib \
 	propsys.lib \
 	advapi32.lib \
 	$(NULL)
--- a/browser/metro/shell/testing/moz.build
+++ b/browser/metro/shell/testing/moz.build
@@ -4,8 +4,11 @@
 # 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/.
 
 PROGRAM = 'metrotestharness'
 
 CPP_SOURCES += [
     'metrotestharness.cpp',
 ]
+
+# We want this exe in dist/bin
+DIST_SUBDIR = ''
--- a/browser/moz.build
+++ b/browser/moz.build
@@ -22,8 +22,10 @@ DIRS += [
 ]
 
 if CONFIG['MOZ_METRO']:
     DIRS += ['metro']
 
 if CONFIG['MAKENSISU']:
     DIRS += ['installer/windows']
 
+DIST_SUBDIR = 'browser'
+export('DIST_SUBDIR')
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -170,17 +170,17 @@ fi
 ])
 
 dnl A high level macro for selecting compiler options.
 AC_DEFUN([MOZ_COMPILER_OPTS],
 [
   if test "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
     dnl Don't enable on pymake, because of bug 918652. Bug 912979 is an annoyance
     dnl with pymake, too.
-    MOZ_PSEUDO_DERECURSE=no-pymake,no-skip
+    MOZ_PSEUDO_DERECURSE=no-pymake
   fi
 
   MOZ_DEBUGGING_OPTS
   MOZ_RTTI
 if test "$CLANG_CXX"; then
     ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
     ## returned by C functions. This is possible because we use knowledge about the ABI
     ## to typedef it to a C type with the same layout when the headers are included
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -444,16 +444,22 @@ def environment(xrePath, env=None, crash
   env['R_LOG_LEVEL'] = '5'
   env['R_LOG_DESTINATION'] = 'stderr'
   env['R_LOG_VERBOSE'] = '1'
 
   # ASan specific environment stuff
   asan = bool(mozinfo.info.get("asan"))
   if asan and (mozinfo.isLinux or mozinfo.isMac):
     try:
+      # Symbolizer support
+      llvmsym = os.path.join(xrePath, "llvm-symbolizer")
+      if os.path.isfile(llvmsym):
+        env["ASAN_SYMBOLIZER_PATH"] = llvmsym
+        log.info("ASan using symbolizer at %s", llvmsym)
+
       totalMemory = systemMemory()
 
       # Only 2 GB RAM or less available? Use custom ASan options to reduce
       # the amount of resources required to do the tests. Standard options
       # will otherwise lead to OOM conditions on the current test slaves.
       #
       # If we have more than 2 GB or RAM but still less than 4 GB, we need
       # another set of options to prevent OOM in some memory-intensive
--- a/build/unix/elfhack/Makefile.in
+++ b/build/unix/elfhack/Makefile.in
@@ -51,9 +51,8 @@ libs:: dummy
 	# Will either crash or return exit code 1 if elfhack is broken
 	LD_PRELOAD=$(CURDIR)/test-array$(DLL_SUFFIX) $(CURDIR)/dummy
 	LD_PRELOAD=$(CURDIR)/test-ctors$(DLL_SUFFIX) $(CURDIR)/dummy
 
 GARBAGE += dummy
 endif
 
 test.$(OBJ_SUFFIX): CFLAGS := -O0
-host_elf.$(OBJ_SUFFIX) host_elfhack.$(OBJ_SUFFIX): elfxx.h
--- a/config/config.mk
+++ b/config/config.mk
@@ -24,16 +24,91 @@ topsrcdir	= $(DEPTH)
 endif
 
 ifndef INCLUDED_AUTOCONF_MK
 include $(DEPTH)/config/autoconf.mk
 endif
 
 -include $(DEPTH)/.mozconfig.mk
 
+# Integrate with mozbuild-generated make files. We first verify that no
+# variables provided by the automatically generated .mk files are
+# present. If they are, this is a violation of the separation of
+# responsibility between Makefile.in and mozbuild files.
+_MOZBUILD_EXTERNAL_VARIABLES := \
+  ANDROID_GENERATED_RESFILES \
+  ANDROID_RESFILES \
+  CMMSRCS \
+  CPP_UNIT_TESTS \
+  DIRS \
+  EXTRA_PP_COMPONENTS \
+  EXTRA_PP_JS_MODULES \
+  GTEST_CMMSRCS \
+  GTEST_CPPSRCS \
+  GTEST_CSRCS \
+  HOST_CSRCS \
+  HOST_LIBRARY_NAME \
+  IS_COMPONENT \
+  JS_MODULES_PATH \
+  LIBRARY_NAME \
+  LIBXUL_LIBRARY \
+  MODULE \
+  MSVC_ENABLE_PGO \
+  NO_DIST_INSTALL \
+  PARALLEL_DIRS \
+  SDK_HEADERS \
+  SIMPLE_PROGRAMS \
+  TEST_DIRS \
+  TIERS \
+  TOOL_DIRS \
+  XPCSHELL_TESTS \
+  XPIDL_MODULE \
+  $(NULL)
+
+_DEPRECATED_VARIABLES := \
+  MOCHITEST_FILES_PARTS \
+  MOCHITEST_BROWSER_FILES_PARTS \
+  $(NULL)
+
+ifndef EXTERNALLY_MANAGED_MAKE_FILE
+# Using $(firstword) may not be perfect. But it should be good enough for most
+# scenarios.
+_current_makefile = $(CURDIR)/$(firstword $(MAKEFILE_LIST))
+
+$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
+    $(error Variable $(var) is defined in $(_current_makefile). It should only be defined in moz.build files),\
+    ))
+
+$(foreach var,$(_DEPRECATED_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
+    $(error Variable $(var) is defined in $(_current_makefile). This variable has been deprecated. It does nothing. It must be removed in order to build)\
+    ))
+
+# Import the automatically generated backend file. If this file doesn't exist,
+# the backend hasn't been properly configured. We want this to be a fatal
+# error, hence not using "-include".
+ifndef STANDALONE_MAKEFILE
+GLOBAL_DEPS += backend.mk
+include backend.mk
+endif
+
+# Freeze the values specified by moz.build to catch them if they fail.
+
+$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
+$(foreach var,$(_DEPRECATED_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
+
+CHECK_MOZBUILD_VARIABLES = $(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES), \
+  $(if $(subst $($(var)_FROZEN),,'$($(var))'), \
+	  $(error Variable $(var) is defined in $(_current_makefile). It should only be defined in moz.build files),\
+  )) $(foreach var,$(_DEPRECATED_VARIABLES), \
+	$(if $(subst $($(var)_FROZEN),,'$($(var))'), \
+    $(error Variable $(var) is defined in $(_current_makefile). This variable has been deprecated. It does nothing. It must be removed in order to build),\
+    ))
+
+endif
+
 space = $(NULL) $(NULL)
 
 # Include defs.mk files that can be found in $(srcdir)/$(DEPTH),
 # $(srcdir)/$(DEPTH-1), $(srcdir)/$(DEPTH-2), etc., and $(srcdir)
 # where $(DEPTH-1) is one level less of depth, $(DEPTH-2), two, etc.
 # i.e. for DEPTH=../../.., DEPTH-1 is ../.. and DEPTH-2 is ..
 # These defs.mk files are used to define variables in a directory
 # and all its subdirectories, recursively.
@@ -69,22 +144,26 @@ include $(topsrcdir)/config/makefiles/fu
 endif
 
 RM = rm -f
 
 # LIBXUL_DIST is not defined under js/src, thus we make it mean DIST there.
 LIBXUL_DIST ?= $(DIST)
 
 # FINAL_TARGET specifies the location into which we copy end-user-shipped
-# build products (typelibs, components, chrome).
+# build products (typelibs, components, chrome). It may already be specified by
+# a moz.build file.
 #
 # If XPI_NAME is set, the files will be shipped to $(DIST)/xpi-stage/$(XPI_NAME)
 # instead of $(DIST)/bin. In both cases, if DIST_SUBDIR is set, the files will be
 # shipped to a $(DIST_SUBDIR) subdirectory.
-FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
+FINAL_TARGET ?= $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
+# Override the stored value for the check to make sure that the variable is not
+# redefined in the Makefile.in value.
+FINAL_TARGET_FROZEN := '$(FINAL_TARGET)'
 
 ifdef XPI_NAME
 DEFINES += -DXPI_NAME=$(XPI_NAME)
 endif
 
 # The VERSION_NUMBER is suffixed onto the end of the DLLs we ship.
 VERSION_NUMBER		= 50
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -11,82 +11,19 @@ ifndef topsrcdir
 endif
 
 # Define an include-at-most-once flag
 ifdef INCLUDED_RULES_MK
 $(error Do not include rules.mk twice!)
 endif
 INCLUDED_RULES_MK = 1
 
-# Integrate with mozbuild-generated make files. We first verify that no
-# variables provided by the automatically generated .mk files are
-# present. If they are, this is a violation of the separation of
-# responsibility between Makefile.in and mozbuild files.
-_MOZBUILD_EXTERNAL_VARIABLES := \
-  ANDROID_GENERATED_RESFILES \
-  ANDROID_RESFILES \
-  CMMSRCS \
-  CPP_UNIT_TESTS \
-  DIRS \
-  EXTRA_PP_COMPONENTS \
-  EXTRA_PP_JS_MODULES \
-  GTEST_CMMSRCS \
-  GTEST_CPPSRCS \
-  GTEST_CSRCS \
-  HOST_CSRCS \
-  HOST_LIBRARY_NAME \
-  IS_COMPONENT \
-  JS_MODULES_PATH \
-  LIBRARY_NAME \
-  LIBXUL_LIBRARY \
-  MODULE \
-  MSVC_ENABLE_PGO \
-  NO_DIST_INSTALL \
-  PARALLEL_DIRS \
-  SDK_HEADERS \
-  SIMPLE_PROGRAMS \
-  TEST_DIRS \
-  TIERS \
-  TOOL_DIRS \
-  XPCSHELL_TESTS \
-  XPIDL_MODULE \
-  $(NULL)
-
-_DEPRECATED_VARIABLES := \
-  XPIDL_FLAGS \
-  MOCHITEST_FILES_PARTS \
-  MOCHITEST_BROWSER_FILES_PARTS \
-  MOCHITEST_WEBAPPRT_CHROME_FILES \
-  $(NULL)
-
-ifndef EXTERNALLY_MANAGED_MAKE_FILE
-# Using $(firstword) may not be perfect. But it should be good enough for most
-# scenarios.
-_current_makefile = $(CURDIR)/$(firstword $(MAKEFILE_LIST))
-
-$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
-    $(error Variable $(var) is defined in $(_current_makefile). It should only be defined in moz.build files),\
-    ))
-
-$(foreach var,$(_DEPRECATED_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
-    $(error Variable $(var) is defined in $(_current_makefile). This variable has been deprecated. It does nothing. It must be removed in order to build)\
-    ))
-
-ifneq (,$(XPIDLSRCS)$(SDK_XPIDLSRCS))
-    $(error XPIDLSRCS and SDK_XPIDLSRCS have been merged and moved to moz.build files as the XPIDL_SOURCES variable. You must move these variables out of $(_current_makefile))
-endif
-
-# Import the automatically generated backend file. If this file doesn't exist,
-# the backend hasn't been properly configured. We want this to be a fatal
-# error, hence not using "-include".
-ifndef STANDALONE_MAKEFILE
-GLOBAL_DEPS += backend.mk
-include backend.mk
-endif
-endif
+# Make sure that anything that needs to be defined in moz.build wasn't
+# overwritten.
+_eval_for_side_effects := $(CHECK_MOZBUILD_VARIABLES)
 
 ifndef MOZILLA_DIR
 MOZILLA_DIR = $(topsrcdir)
 endif
 
 ifndef INCLUDED_CONFIG_MK
 include $(topsrcdir)/config/config.mk
 endif
@@ -377,22 +314,22 @@ CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUF
 CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
 ASOBJS = $(notdir $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
 ifndef OBJS
 _OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
 OBJS = $(strip $(_OBJS))
 endif
 
 HOST_COBJS = $(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX)))
-HOST_CCOBJS = $(addprefix host_,$(patsubst %.cc,%.$(OBJ_SUFFIX),$(filter %.cc,$(HOST_CPPSRCS))))
-HOST_CPPOBJS = $(addprefix host_,$(patsubst %.cpp,%.$(OBJ_SUFFIX),$(filter %.cpp,$(HOST_CPPSRCS))))
+# HOST_CPPOBJS can have different extensions (eg: .cpp, .cc)
+HOST_CPPOBJS = $(addprefix host_,$(addsuffix .$(OBJ_SUFFIX),$(basename $(HOST_CPPSRCS))))
 HOST_CMOBJS = $(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX)))
 HOST_CMMOBJS = $(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
 ifndef HOST_OBJS
-_HOST_OBJS = $(HOST_COBJS) $(HOST_CCOBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
+_HOST_OBJS = $(HOST_COBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
 HOST_OBJS = $(strip $(_HOST_OBJS))
 endif
 
 ALL_TRASH = \
 	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
 	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
 	$(OBJS:.$(OBJ_SUFFIX)=.i) $(OBJS:.$(OBJ_SUFFIX)=.i_o) \
 	$(HOST_PROGOBJS) $(HOST_OBJS) $(IMPORT_LIBRARY) $(DEF_FILE)\
@@ -874,36 +811,36 @@ ifdef ENABLE_STRIP
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
 
 $(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
 	$(REPORT_BUILD)
 ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		if test -f "$(srcdir)/$@.manifest"; then \
 			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		else \
 			echo "Embedding manifest from $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		fi; \
 	elif test -f "$(srcdir)/$@.manifest"; then \
 		echo "Embedding manifest from $(srcdir)/$@.manifest"; \
 		mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" -OUTPUTRESOURCE:$@\;1; \
 	fi
 endif	# MSVC with manifest tool
 else
 ifeq ($(HOST_CPP_PROG_LINK),1)
-	$(HOST_CXX) -o $@ $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CXX) -o $@ $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 else
-	$(HOST_CC) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CC) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 endif # HOST_CPP_PROG_LINK
 endif
 
 #
 # This is an attempt to support generation of multiple binaries
 # in one directory, it assumes everything to compile Foo is in
 # Foo.o (from either Foo.c or Foo.cpp).
 #
@@ -930,22 +867,22 @@ ifdef ENABLE_STRIP
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
 
 $(HOST_SIMPLE_PROGRAMS): host_%$(HOST_BIN_SUFFIX): host_%.$(OBJ_SUFFIX) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
 	$(REPORT_BUILD)
 ifeq (WINNT_,$(HOST_OS_ARCH)_$(GNU_CC))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 else
 ifneq (,$(HOST_CPPSRCS)$(USE_HOST_CXX))
-	$(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXXFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXXFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 else
-	$(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_CFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_CFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 endif
 endif
 
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 OBJS += $(DTRACE_PROBE_OBJ)
 endif
 
@@ -988,17 +925,17 @@ ifeq ($(OS_ARCH),OS2)
 	$(RM) $@
 	$(IMPLIB) $@ $^
 	$(RANLIB) $@
 endif # OS/2
 
 $(HOST_LIBRARY): $(HOST_OBJS) Makefile
 	$(REPORT_BUILD)
 	$(RM) $@
-	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
+	$(EXPAND_LIBS_EXEC) --extract -- $(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
 	$(HOST_RANLIB) $@
 
 ifdef HAVE_DTRACE
 ifndef XP_MACOSX
 ifdef DTRACE_PROBE_OBJ
 ifndef DTRACE_LIB_DEPENDENT
 NON_DTRACE_OBJS := $(filter-out $(DTRACE_PROBE_OBJ),$(OBJS))
 $(DTRACE_PROBE_OBJ): $(NON_DTRACE_OBJS)
@@ -1074,37 +1011,34 @@ endif # Sun Studio on Solaris
 # relative path. This macro adds the dependency obj: src for each source file.
 # This dependency must be first for the $< flag to work correctly, and the
 # rules that have commands for these targets must not list any other
 # prerequisites, or they will override the $< variable.
 define src_objdep
 $(basename $(notdir $1)).$(OBJ_SUFFIX): $1 $(call mkdir_deps,$(MDDEPDIR))
 endef
 $(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f))))
+$(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval host_$(call src_objdep,$(f))))
 
 $(OBJS) $(HOST_OBJS) $(PROGOBJS) $(HOST_PROGOBJS): $(GLOBAL_DEPS)
 
 # Rules for building native targets must come first because of the host_ prefix
-$(HOST_COBJS): host_%.$(OBJ_SUFFIX): %.c
+$(HOST_COBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
-$(HOST_CPPOBJS): host_%.$(OBJ_SUFFIX): %.cpp
+$(HOST_CPPOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
-$(HOST_CCOBJS): host_%.$(OBJ_SUFFIX): %.cc
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-$(HOST_CMOBJS): host_%.$(OBJ_SUFFIX): %.m
+$(HOST_CMOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
-$(HOST_CMMOBJS): host_%.$(OBJ_SUFFIX): %.mm
+$(HOST_CMMOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 $(COBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
--- a/config/tests/src-simple/Makefile.in
+++ b/config/tests/src-simple/Makefile.in
@@ -1,18 +1,18 @@
 #
 # 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/.
 
 LOCALE_SRCDIR = $(srcdir)/l10n
 
-include $(topsrcdir)/config/config.mk
+STANDALONE_MAKEFILE := 1
 
-STANDALONE_MAKEFILE := 1
+include $(topsrcdir)/config/config.mk
 
 XPI_NAME = test_jar_mn
 
 DEFINES += \
 	-DAB_CD=ab-X-stuff \
 	$(NULL)
 
 MY_MANIFEST = $(if $(USE_EXTENSION_MANIFEST), $(FINAL_TARGET)/chrome.manifest, $(FINAL_TARGET)/chrome/test.manifest)
--- a/configure.in
+++ b/configure.in
@@ -8481,16 +8481,24 @@ COMPILE_CFLAGS=`echo \
 	$_DEPEND_CFLAGS \
     $COMPILE_CFLAGS`
 
 COMPILE_CXXFLAGS=`echo \
     $_DEFINES_CXXFLAGS \
 	$_DEPEND_CFLAGS \
     $COMPILE_CXXFLAGS`
 
+HOST_CFLAGS=`echo \
+    $HOST_CFLAGS \
+    $_DEPEND_CFLAGS`
+
+HOST_CXXFLAGS=`echo \
+    $HOST_CXXFLAGS \
+    $_DEPEND_CFLAGS`
+
 AC_SUBST(SYSTEM_LIBXUL)
 AC_SUBST(MOZ_NATIVE_JPEG)
 AC_SUBST(MOZ_NATIVE_PNG)
 AC_SUBST(MOZ_NATIVE_BZ2)
 
 AC_SUBST(MOZ_JPEG_CFLAGS)
 AC_SUBST(MOZ_JPEG_LIBS)
 AC_SUBST(MOZ_BZ2_CFLAGS)
--- a/content/base/public/nsContentCreatorFunctions.h
+++ b/content/base/public/nsContentCreatorFunctions.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsContentCreatorFunctions_h__
 #define nsContentCreatorFunctions_h__
 
-#include "nscore.h"
+#include "nsError.h"
 #include "nsCOMPtr.h"
 #include "mozilla/dom/FromParser.h"
 
 /**
  * Functions to create content, to be used only inside Gecko
  * (mozilla/content and mozilla/layout).
  */
 
--- a/content/base/public/nsContentPolicyUtils.h
+++ b/content/base/public/nsContentPolicyUtils.h
@@ -10,27 +10,27 @@
  * XXXbz it would be nice if some of this stuff could be out-of-lined in
  * nsContentUtils.  That would work for almost all the callers...
  */
 
 #ifndef __nsContentPolicyUtils_h__
 #define __nsContentPolicyUtils_h__
 
 #include "nsIContentPolicy.h"
-#include "nsIServiceManager.h"
 #include "nsIContent.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsIPrincipal.h"
 #include "nsIURI.h"
+#include "nsServiceManagerUtils.h"
 
 //XXXtw sadly, this makes consumers of nsContentPolicyUtils depend on widget
 #include "nsIDocument.h"
 #include "nsPIDOMWindow.h"
 
 class nsACString;
+class nsIPrincipal;
 
 #define NS_CONTENTPOLICY_CONTRACTID   "@mozilla.org/layout/content-policy;1"
 #define NS_CONTENTPOLICY_CATEGORY "content-policy"
 #define NS_CONTENTPOLICY_CID                              \
   {0x0e3afd3d, 0xeb60, 0x4c2b,                            \
      { 0x96, 0x3b, 0x56, 0xd7, 0xc4, 0x39, 0xf1, 0x24 }}
 
 /**
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -4,29 +4,27 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* A namespace class for static content utilities. */
 
 #ifndef nsContentUtils_h___
 #define nsContentUtils_h___
 
-#include <math.h>
 #if defined(XP_WIN) || defined(XP_OS2)
 #include <float.h>
 #endif
 
 #if defined(SOLARIS)
 #include <ieeefp.h>
 #endif
 
 #include "js/TypeDecls.h"
 #include "js/Value.h"
 #include "js/RootingAPI.h"
-#include "mozilla/Assertions.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/TimeStamp.h"
 #include "nsContentListDeclarations.h"
 #include "nsMathUtils.h"
 #include "Units.h"
 
 class imgICache;
--- a/content/base/public/nsINameSpaceManager.h
+++ b/content/base/public/nsINameSpaceManager.h
@@ -2,20 +2,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsINameSpaceManager_h___
 #define nsINameSpaceManager_h___
 
 #include "nsISupports.h"
-#include "nsStringGlue.h"
 
 class nsIAtom;
-class nsString;
+class nsAString;
 
 #define kNameSpaceID_Unknown -1
 // 0 is special at C++, so use a static const int32_t for
 // kNameSpaceID_None to keep if from being cast to pointers
 // Note that the XBL cache assumes (and asserts) that it can treat a
 // single-byte value higher than kNameSpaceID_LastBuiltin specially. 
 static const int32_t kNameSpaceID_None = 0;
 #define kNameSpaceID_XMLNS    1 // not really a namespace, but it needs to play the game
--- a/content/base/public/nsViewportInfo.h
+++ b/content/base/public/nsViewportInfo.h
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsViewportInfo_h___
 #define nsViewportInfo_h___
 
 #include <stdint.h>
-#include "nscore.h"
+#include "mozilla/Attributes.h"
 #include "Units.h"
 
 /**
  * Default values for the nsViewportInfo class.
  */
 static const mozilla::LayoutDeviceToScreenScale kViewportMinScale(0.0f);
 static const mozilla::LayoutDeviceToScreenScale kViewportMaxScale(10.0f);
 static const mozilla::CSSIntSize kViewportMinSize(200, 223);
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -1446,20 +1446,21 @@ Element::DispatchClickEvent(nsPresContex
   NS_PRECONDITION(aStatus, "Null out param?");
 
   WidgetMouseEvent event(aSourceEvent->mFlags.mIsTrusted, NS_MOUSE_CLICK,
                          aSourceEvent->widget, WidgetMouseEvent::eReal);
   event.refPoint = aSourceEvent->refPoint;
   uint32_t clickCount = 1;
   float pressure = 0;
   uint16_t inputSource = 0;
-  if (aSourceEvent->eventStructType == NS_MOUSE_EVENT) {
-    clickCount = static_cast<WidgetMouseEvent*>(aSourceEvent)->clickCount;
-    pressure = static_cast<WidgetMouseEvent*>(aSourceEvent)->pressure;
-    inputSource = static_cast<WidgetMouseEvent*>(aSourceEvent)->inputSource;
+  WidgetMouseEvent* sourceMouseEvent = aSourceEvent->AsMouseEvent();
+  if (sourceMouseEvent) {
+    clickCount = sourceMouseEvent->clickCount;
+    pressure = sourceMouseEvent->pressure;
+    inputSource = sourceMouseEvent->inputSource;
   } else if (aSourceEvent->eventStructType == NS_KEY_EVENT) {
     inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
   }
   event.pressure = pressure;
   event.clickCount = clickCount;
   event.inputSource = inputSource;
   event.modifiers = aSourceEvent->modifiers;
   if (aExtraEventFlags) {
@@ -2220,18 +2221,17 @@ Element::PostHandleEventForLinks(nsEvent
     return NS_OK;
   }
 
   nsresult rv = NS_OK;
 
   switch (aVisitor.mEvent->message) {
   case NS_MOUSE_BUTTON_DOWN:
     {
-      if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-          static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
+      if (aVisitor.mEvent->AsMouseEvent()->button ==
             WidgetMouseEvent::eLeftButton) {
         // don't make the link grab the focus if there is no link handler
         nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler();
         nsIDocument *document = GetCurrentDoc();
         if (handler && document) {
           nsIFocusManager* fm = nsFocusManager::GetFocusManager();
           if (fm) {
             aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -689,18 +689,17 @@ nsIContent::PreHandleEvent(nsEventChainP
   if ((aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH ||
        aVisitor.mEvent->message == NS_MOUSE_EXIT_SYNTH) &&
       // Check if we should stop event propagation when event has just been
       // dispatched or when we're about to propagate from
       // chrome access only subtree.
       ((this == aVisitor.mEvent->originalTarget &&
         !ChromeOnlyAccess()) || isAnonForEvents)) {
      nsCOMPtr<nsIContent> relatedTarget =
-       do_QueryInterface(
-         static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->relatedTarget);
+       do_QueryInterface(aVisitor.mEvent->AsMouseEvent()->relatedTarget);
     if (relatedTarget &&
         relatedTarget->OwnerDoc() == OwnerDoc()) {
 
       // If current target is anonymous for events or we know that related
       // target is descendant of an element which is anonymous for events,
       // we may want to stop event propagation.
       // If this is the original target, aVisitor.mRelatedTargetIsInAnon
       // must be updated.
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1092,16 +1092,17 @@ GK_ATOM(treeitem, "treeitem")
 GK_ATOM(treerow, "treerow")
 GK_ATOM(treeseparator, "treeseparator")
 GK_ATOM(triple, "triple")
 GK_ATOM(_true, "true")
 GK_ATOM(tt, "tt")
 GK_ATOM(tty, "tty")
 GK_ATOM(tv, "tv")
 GK_ATOM(type, "type")
+GK_ATOM(typemustmatch, "typemustmatch")
 GK_ATOM(u, "u")
 GK_ATOM(ul, "ul")
 GK_ATOM(underflow, "underflow")
 GK_ATOM(undetermined, "undetermined")
 GK_ATOM(undoscope, "undoscope")
 GK_ATOM(unload, "unload")
 GK_ATOM(unparsedEntityUri, "unparsed-entity-uri")
 GK_ATOM(upperFirst, "upper-first")
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1,14 +1,13 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:set et cin sw=2 sts=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/. */
-
 /*
  * A base class implementing nsIObjectLoadingContent for use by
  * various content nodes that want to provide plugin/document/image
  * loading functionality (eg <embed>, <object>, <applet>, etc).
  */
 
 // Interface headers
 #include "imgLoader.h"
@@ -1375,16 +1374,17 @@ nsObjectLoadingContent::UpdateObjectPara
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   NS_ASSERTION(thisContent, "Must be an instance of content");
 
   uint32_t caps = GetCapabilities();
   LOG(("OBJLC [%p]: Updating object parameters", this));
 
   nsresult rv;
   nsAutoCString newMime;
+  nsAutoString typeAttr;
   nsCOMPtr<nsIURI> newURI;
   nsCOMPtr<nsIURI> newBaseURI;
   ObjectType newType;
   bool isJava = false;
   // Set if this state can't be used to load anything, forces eType_Null
   bool stateInvalid = false;
   // Indicates what parameters changed.
   // eParamChannelChanged - means parameters that affect channel opening
@@ -1401,20 +1401,21 @@ nsObjectLoadingContent::UpdateObjectPara
 
   ///
   /// Initial MIME Type
   ///
   if (aJavaURI || thisContent->NodeInfo()->Equals(nsGkAtoms::applet)) {
     newMime.AssignLiteral("application/x-java-vm");
     isJava = true;
   } else {
-    nsAutoString typeAttr;
-    thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, typeAttr);
-    if (!typeAttr.IsEmpty()) {
-      CopyUTF16toUTF8(typeAttr, newMime);
+    nsAutoString rawTypeAttr;
+    thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, rawTypeAttr);
+    if (!rawTypeAttr.IsEmpty()) {
+      typeAttr = rawTypeAttr;
+      CopyUTF16toUTF8(rawTypeAttr, newMime);
       isJava = nsPluginHost::IsJavaMIMEType(newMime.get());
     }
   }
 
   ///
   /// classID
   ///
 
@@ -1641,29 +1642,33 @@ nsObjectLoadingContent::UpdateObjectPara
     }
 
     ObjectType typeHint = newMime.IsEmpty() ?
                           eType_Null : GetTypeOfContent(newMime);
 
     //
     // In order of preference:
     //
-    // 1) Use our type hint if it matches a plugin
-    // 2) If we have eAllowPluginSkipChannel, use the uri file extension if
+    // 1) Perform typemustmatch check.
+    //    If check is sucessful use type without further checks.
+    //    If check is unsuccessful set stateInvalid to true
+    // 2) Use our type hint if it matches a plugin
+    // 3) If we have eAllowPluginSkipChannel, use the uri file extension if
     //    it matches a plugin
-    // 3) If the channel returns a binary stream type:
-    //    3a) If we have a type non-null non-document type hint, use that
-    //    3b) If the uri file extension matches a plugin type, use that
-    // 4) Use the channel type
-    //
-    //    XXX(johns): HTML5's "typesmustmatch" attribute would need to be
-    //                honored here if implemented
+    // 4) If the channel returns a binary stream type:
+    //    4a) If we have a type non-null non-document type hint, use that
+    //    4b) If the uri file extension matches a plugin type, use that
+    // 5) Use the channel type
 
     bool overrideChannelType = false;
-    if (typeHint == eType_Plugin) {
+    if (thisContent->HasAttr(kNameSpaceID_None, nsGkAtoms::typemustmatch)) {
+      if (!typeAttr.LowerCaseEqualsASCII(channelType.get())) {
+        stateInvalid = true;
+      }
+    } else if (typeHint == eType_Plugin) {
       LOG(("OBJLC [%p]: Using plugin type hint in favor of any channel type",
            this));
       overrideChannelType = true;
     } else if ((caps & eAllowPluginSkipChannel) &&
                IsPluginEnabledByExtension(newURI, newMime)) {
       LOG(("OBJLC [%p]: Using extension as type hint for "
            "eAllowPluginSkipChannel tag (%s)", this, newMime.get()));
       overrideChannelType = true;
--- a/content/base/test/mochitest.ini
+++ b/content/base/test/mochitest.ini
@@ -501,16 +501,17 @@ support-files =
 [test_bug809003.html]
 [test_bug810494.html]
 [test_bug811701.html]
 [test_bug811701.xhtml]
 [test_bug813919.html]
 [test_bug814576.html]
 [test_bug819051.html]
 [test_bug820909.html]
+[test_bug827160.html]
 [test_bug840098.html]
 [test_bug868999.html]
 [test_bug869000.html]
 [test_bug869002.html]
 [test_bug869006.html]
 [test_bug876282.html]
 [test_bug890580.html]
 [test_bug894874.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug827160.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=827160
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 827160</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SpecialPowers.js"></script>
+  <script type="application/javascript" src="utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href=https://bugzilla.mozilla.org/show_bug.cgi?id=827160">Mozilla Bug 827160</a>
+
+<script type="application/javascript">
+
+// Make sure the test plugin is not click-to-play
+var pluginHost = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
+                              .getService(SpecialPowers.Ci.nsIPluginHost);
+var pluginTags = pluginHost.getPluginTags();
+for (var tag of pluginTags) {
+  if (tag.name == "Test Plug-in" || tag.name == "Second Test Plug-in") {
+    var oldEnabledState = tag.enabledState;
+    tag.enabledState = SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED;
+    SimpleTest.registerCleanupFunction(function() {
+      tag.enabledState = oldEnabledState;
+    });
+  }
+}
+
+</script>
+
+<!-- Should load test plugin application/x-test -->
+<object id="shouldLoad" data="data:application/x-test,foo"></object>
+<!-- Should load test plugin application/x-test2, ignoring type="" -->
+<object id="shouldIgnoreType" type="application/x-test" data="data:application/x-test2,foo"></object>
+<!-- Should load nothing, channel type does not match type and typeMustMatch is present -->
+<object id="shouldNotLoad" type="application/x-test" data="data:application/x-test2,foo" typemustmatch></object>
+<!-- Should not load test plugin application/x-test2, no type field is present  -->
+<object id="shouldNotLoadMissingType" data="data:application/x-test2,foo" typemustmatch></object>
+<!-- Should load, no data field is present  -->
+<object id="shouldLoadMissingData" type="application/x-test" typemustmatch></object>
+<pre id="test">
+
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+window.addEventListener("load", function () {
+  const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
+  is(SpecialPowers.wrap(document.getElementById("shouldLoad")).displayedType, OBJLC.TYPE_PLUGIN, "Testing object load without type, failed expected load");
+  is(SpecialPowers.wrap(document.getElementById("shouldIgnoreType")).displayedType, OBJLC.TYPE_PLUGIN, "Testing object load with type, failed expected load");
+  is(SpecialPowers.wrap(document.getElementById("shouldNotLoad")).displayedType, OBJLC.TYPE_NULL, "Testing object load with typemustmatch, load success even though failure expected");
+  is(SpecialPowers.wrap(document.getElementById("shouldNotLoadMissingType")).displayedType, OBJLC.TYPE_NULL, "Testing object load with typemustmatch and with type, load success even though failure expected");
+  is(SpecialPowers.wrap(document.getElementById("shouldLoadMissingData")).displayedType, OBJLC.TYPE_PLUGIN, "Testing object load with typemustmatch and without data, failed expected load");
+  SimpleTest.finish();
+}, false);
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -15,16 +15,17 @@
 #include "nsTArray.h"
 #include "nsCycleCollectionNoteChild.h"
 
 #include "nsIDOMWebGLRenderingContext.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsWrapperCache.h"
 #include "nsIObserver.h"
+#include "nsLayoutUtils.h"
 
 #include "GLContextProvider.h"
 #include "gfxImageSurface.h"
 
 #include "mozilla/LinkedList.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Scoped.h"
 
--- a/content/events/src/DOMWheelEvent.cpp
+++ b/content/events/src/DOMWheelEvent.cpp
@@ -19,18 +19,17 @@ DOMWheelEvent::DOMWheelEvent(EventTarget
                                   new WidgetWheelEvent(false, 0, nullptr))
 {
   if (aWheelEvent) {
     mEventIsInternal = false;
   } else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
-    static_cast<WidgetWheelEvent*>(mEvent)->inputSource =
-      nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
+    mEvent->AsWheelEvent()->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
   }
 }
 
 NS_IMPL_ADDREF_INHERITED(DOMWheelEvent, nsDOMMouseEvent)
 NS_IMPL_RELEASE_INHERITED(DOMWheelEvent, nsDOMMouseEvent)
 
 NS_INTERFACE_MAP_BEGIN(DOMWheelEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWheelEvent)
@@ -56,52 +55,76 @@ DOMWheelEvent::InitWheelEvent(const nsAS
 {
   nsresult rv =
     nsDOMMouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView,
                                     aDetail, aScreenX, aScreenY,
                                     aClientX, aClientY, aButton,
                                     aRelatedTarget, aModifiersList);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  WidgetWheelEvent* wheelEvent = static_cast<WidgetWheelEvent*>(mEvent);
+  WidgetWheelEvent* wheelEvent = mEvent->AsWheelEvent();
   wheelEvent->deltaX = aDeltaX;
   wheelEvent->deltaY = aDeltaY;
   wheelEvent->deltaZ = aDeltaZ;
   wheelEvent->deltaMode = aDeltaMode;
 
   return NS_OK;
 }
 
+double
+DOMWheelEvent::DeltaX()
+{
+  return mEvent->AsWheelEvent()->deltaX;
+}
+
 NS_IMETHODIMP
 DOMWheelEvent::GetDeltaX(double* aDeltaX)
 {
   NS_ENSURE_ARG_POINTER(aDeltaX);
 
   *aDeltaX = DeltaX();
   return NS_OK;
 }
 
+double
+DOMWheelEvent::DeltaY()
+{
+  return mEvent->AsWheelEvent()->deltaY;
+}
+
 NS_IMETHODIMP
 DOMWheelEvent::GetDeltaY(double* aDeltaY)
 {
   NS_ENSURE_ARG_POINTER(aDeltaY);
 
   *aDeltaY = DeltaY();
   return NS_OK;
 }
 
+double
+DOMWheelEvent::DeltaZ()
+{
+  return mEvent->AsWheelEvent()->deltaZ;
+}
+
 NS_IMETHODIMP
 DOMWheelEvent::GetDeltaZ(double* aDeltaZ)
 {
   NS_ENSURE_ARG_POINTER(aDeltaZ);
 
   *aDeltaZ = DeltaZ();
   return NS_OK;
 }
 
+uint32_t
+DOMWheelEvent::DeltaMode()
+{
+  return mEvent->AsWheelEvent()->deltaMode;
+}
+
 NS_IMETHODIMP
 DOMWheelEvent::GetDeltaMode(uint32_t* aDeltaMode)
 {
   NS_ENSURE_ARG_POINTER(aDeltaMode);
 
   *aDeltaMode = DeltaMode();
   return NS_OK;
 }
@@ -148,17 +171,17 @@ DOMWheelEvent::Constructor(const GlobalO
                   modifierList);
   aRv = e->InitWheelEvent(aType, aParam.mBubbles, aParam.mCancelable,
                           aParam.mView, aParam.mDetail,
                           aParam.mScreenX, aParam.mScreenY,
                           aParam.mClientX, aParam.mClientY,
                           aParam.mButton, aParam.mRelatedTarget,
                           modifierList, aParam.mDeltaX,
                           aParam.mDeltaY, aParam.mDeltaZ, aParam.mDeltaMode);
-  static_cast<WidgetWheelEvent*>(e->mEvent)->buttons = aParam.mButtons;
+  e->mEvent->AsWheelEvent()->buttons = aParam.mButtons;
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
--- a/content/events/src/DOMWheelEvent.h
+++ b/content/events/src/DOMWheelEvent.h
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_DOMWheelEvent_h__
 #define mozilla_dom_DOMWheelEvent_h__
 
 #include "nsIDOMWheelEvent.h"
 #include "nsDOMMouseEvent.h"
-#include "mozilla/MouseEvents.h"
+#include "mozilla/EventForwards.h"
 #include "mozilla/dom/WheelEventBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 class DOMWheelEvent : public nsDOMMouseEvent,
                       public nsIDOMWheelEvent
 {
@@ -38,33 +38,18 @@ public:
                                               mozilla::ErrorResult& aRv);
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE
   {
     return mozilla::dom::WheelEventBinding::Wrap(aCx, aScope, this);
   }
 
-  double DeltaX()
-  {
-    return static_cast<WidgetWheelEvent*>(mEvent)->deltaX;
-  }
-
-  double DeltaY()
-  {
-    return static_cast<WidgetWheelEvent*>(mEvent)->deltaY;
-  }
-
-  double DeltaZ()
-  {
-    return static_cast<WidgetWheelEvent*>(mEvent)->deltaZ;
-  }
-
-  uint32_t DeltaMode()
-  {
-    return static_cast<WidgetWheelEvent*>(mEvent)->deltaMode;
-  }
+  double DeltaX();
+  double DeltaY();
+  double DeltaZ();
+  uint32_t DeltaMode();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_DOMWheelEvent_h__
--- a/content/events/src/nsDOMDragEvent.cpp
+++ b/content/events/src/nsDOMDragEvent.cpp
@@ -19,18 +19,17 @@ nsDOMDragEvent::nsDOMDragEvent(mozilla::
 {
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
-    static_cast<WidgetMouseEvent*>(mEvent)->inputSource =
-      nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
+    mEvent->AsMouseEvent()->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
   }
 }
 
 NS_IMPL_ADDREF_INHERITED(nsDOMDragEvent, nsDOMMouseEvent)
 NS_IMPL_RELEASE_INHERITED(nsDOMDragEvent, nsDOMMouseEvent)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMDragEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent)
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -512,17 +512,17 @@ nsDOMEvent::DuplicatePrivateData()
     case NS_EVENT:
     {
       newEvent = new WidgetEvent(false, msg);
       newEvent->AssignEventData(*mEvent, true);
       break;
     }
     case NS_GUI_EVENT:
     {
-      WidgetGUIEvent* oldGUIEvent = static_cast<WidgetGUIEvent*>(mEvent);
+      WidgetGUIEvent* oldGUIEvent = mEvent->AsGUIEvent();
       // Not copying widget, it is a weak reference.
       WidgetGUIEvent* guiEvent = new WidgetGUIEvent(false, msg, nullptr);
       guiEvent->AssignGUIEventData(*oldGUIEvent, true);
       newEvent = guiEvent;
       break;
     }
     case NS_INPUT_EVENT:
     {
@@ -538,17 +538,17 @@ nsDOMEvent::DuplicatePrivateData()
       WidgetKeyboardEvent* keyEvent =
         new WidgetKeyboardEvent(false, msg, nullptr);
       keyEvent->AssignKeyEventData(*oldKeyEvent, true);
       newEvent = keyEvent;
       break;
     }
     case NS_MOUSE_EVENT:
     {
-      WidgetMouseEvent* oldMouseEvent = static_cast<WidgetMouseEvent*>(mEvent);
+      WidgetMouseEvent* oldMouseEvent = mEvent->AsMouseEvent();
       WidgetMouseEvent* mouseEvent =
         new WidgetMouseEvent(false, msg, nullptr, oldMouseEvent->reason);
       mouseEvent->AssignMouseEventData(*oldMouseEvent, true);
       newEvent = mouseEvent;
       break;
     }
     case NS_DRAG_EVENT:
     {
@@ -602,17 +602,17 @@ nsDOMEvent::DuplicatePrivateData()
       WidgetMouseScrollEvent* mouseScrollEvent =
         new WidgetMouseScrollEvent(false, msg, nullptr);
       mouseScrollEvent->AssignMouseScrollEventData(*oldMouseScrollEvent, true);
       newEvent = mouseScrollEvent;
       break;
     }
     case NS_WHEEL_EVENT:
     {
-      WidgetWheelEvent* oldWheelEvent = static_cast<WidgetWheelEvent*>(mEvent);
+      WidgetWheelEvent* oldWheelEvent = mEvent->AsWheelEvent();
       WidgetWheelEvent* wheelEvent = new WidgetWheelEvent(false, msg, nullptr);
       wheelEvent->AssignWheelEventData(*oldWheelEvent, true);
       newEvent = wheelEvent;
       break;
     }
     case NS_SCROLLPORT_EVENT:
     {
       InternalScrollPortEvent* oldScrollPortEvent = mEvent->AsScrollPortEvent();
@@ -672,17 +672,17 @@ nsDOMEvent::DuplicatePrivateData()
       InternalUIEvent* uiEvent =
         new InternalUIEvent(false, msg, oldUIEvent->detail);
       uiEvent->AssignUIEventData(*oldUIEvent, true);
       newEvent = uiEvent;
       break;
     }
     case NS_SVGZOOM_EVENT:
     {
-      WidgetGUIEvent* oldGUIEvent = static_cast<WidgetGUIEvent*>(mEvent);
+      WidgetGUIEvent* oldGUIEvent = mEvent->AsGUIEvent();
       WidgetGUIEvent* guiEvent = new WidgetGUIEvent(false, msg, nullptr);
       guiEvent->eventStructType = NS_SVGZOOM_EVENT;
       guiEvent->AssignGUIEventData(*oldGUIEvent, true);
       newEvent = guiEvent;
       break;
     }
     case NS_SMIL_TIME_EVENT:
     {
@@ -920,18 +920,17 @@ nsDOMEvent::GetEventPopupControlState(Wi
           abuse = openControlled;
         }
         break;
       }
     }
     break;
   case NS_MOUSE_EVENT :
     if (aEvent->mFlags.mIsTrusted &&
-        static_cast<WidgetMouseEvent*>(aEvent)->button ==
-          WidgetMouseEvent::eLeftButton) {
+        aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
       switch(aEvent->message) {
       case NS_MOUSE_BUTTON_UP :
         if (::PopupAllowedForEvent("mouseup"))
           abuse = openControlled;
         break;
       case NS_MOUSE_BUTTON_DOWN :
         if (::PopupAllowedForEvent("mousedown"))
           abuse = openControlled;
@@ -1022,17 +1021,17 @@ nsDOMEvent::GetScreenCoords(nsPresContex
         aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
         aEvent->eventStructType != NS_WHEEL_EVENT &&
         aEvent->eventStructType != NS_TOUCH_EVENT &&
         aEvent->eventStructType != NS_DRAG_EVENT &&
         aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT)) {
     return nsIntPoint(0, 0);
   }
 
-  WidgetGUIEvent* guiEvent = static_cast<WidgetGUIEvent*>(aEvent);
+  WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
   if (!guiEvent->widget) {
     return LayoutDeviceIntPoint::ToUntyped(aPoint);
   }
 
   LayoutDeviceIntPoint offset = aPoint +
     LayoutDeviceIntPoint::FromUntyped(guiEvent->widget->WidgetToScreenOffset());
   nscoord factor = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
   return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
@@ -1077,17 +1076,17 @@ nsDOMEvent::GetClientCoords(nsPresContex
   if (!aEvent ||
       (aEvent->eventStructType != NS_MOUSE_EVENT &&
        aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
        aEvent->eventStructType != NS_WHEEL_EVENT &&
        aEvent->eventStructType != NS_TOUCH_EVENT &&
        aEvent->eventStructType != NS_DRAG_EVENT &&
        aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT) ||
       !aPresContext ||
-      !static_cast<WidgetGUIEvent*>(aEvent)->widget) {
+      !aEvent->AsGUIEvent()->widget) {
     return aDefaultPoint;
   }
 
   nsIPresShell* shell = aPresContext->GetPresShell();
   if (!shell) {
     return CSSIntPoint(0, 0);
   }
 
--- a/content/events/src/nsDOMMouseEvent.cpp
+++ b/content/events/src/nsDOMMouseEvent.cpp
@@ -16,38 +16,32 @@ nsDOMMouseEvent::nsDOMMouseEvent(mozilla
                                  WidgetMouseEventBase* aEvent)
   : nsDOMUIEvent(aOwner, aPresContext, aEvent ? aEvent :
                  new WidgetMouseEvent(false, 0, nullptr,
                                       WidgetMouseEvent::eReal))
 {
   // There's no way to make this class' ctor allocate an WidgetMouseScrollEvent.
   // It's not that important, though, since a scroll event is not a real
   // DOM event.
-  
+
+  WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
   if (aEvent) {
     mEventIsInternal = false;
   }
   else {
     mEventIsInternal = true;
     mEvent->time = PR_Now();
     mEvent->refPoint.x = mEvent->refPoint.y = 0;
-    static_cast<WidgetMouseEvent*>(mEvent)->inputSource =
-      nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
+    mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
   }
 
-  switch (mEvent->eventStructType)
-  {
-    case NS_MOUSE_EVENT:
-      NS_ASSERTION(static_cast<WidgetMouseEvent*>(mEvent)->reason
-                     != WidgetMouseEvent::eSynthesized,
-                   "Don't dispatch DOM events from synthesized mouse events");
-      mDetail = static_cast<WidgetMouseEvent*>(mEvent)->clickCount;
-      break;
-    default:
-      break;
+  if (mouseEvent) {
+    MOZ_ASSERT(mouseEvent->reason != WidgetMouseEvent::eSynthesized,
+               "Don't dispatch DOM events from synthesized mouse events");
+    mDetail = mouseEvent->clickCount;
   }
 }
 
 NS_IMPL_ADDREF_INHERITED(nsDOMMouseEvent, nsDOMUIEvent)
 NS_IMPL_RELEASE_INHERITED(nsDOMMouseEvent, nsDOMUIEvent)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMMouseEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMouseEvent)
@@ -73,18 +67,18 @@ nsDOMMouseEvent::InitMouseEvent(const ns
       mouseEventBase->relatedTarget = aRelatedTarget;
       mouseEventBase->button = aButton;
       mouseEventBase->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
       mClientPoint.x = aClientX;
       mClientPoint.y = aClientY;
       mouseEventBase->refPoint.x = aScreenX;
       mouseEventBase->refPoint.y = aScreenY;
 
-      if (mEvent->eventStructType == NS_MOUSE_EVENT) {
-        WidgetMouseEvent* mouseEvent = static_cast<WidgetMouseEvent*>(mEvent);
+      WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
+      if (mouseEvent) {
         mouseEvent->clickCount = aDetail;
       }
       break;
     }
     default:
        break;
   }
 
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -115,17 +115,17 @@ nsDOMUIEvent::GetMovementPoint()
   }
 
   if (!mEvent ||
       (mEvent->eventStructType != NS_MOUSE_EVENT &&
        mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
        mEvent->eventStructType != NS_WHEEL_EVENT &&
        mEvent->eventStructType != NS_DRAG_EVENT &&
        mEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT) ||
-       !(static_cast<WidgetGUIEvent*>(mEvent)->widget)) {
+       !mEvent->AsGUIEvent()->widget) {
     return nsIntPoint(0, 0);
   }
 
   // Calculate the delta between the last screen point and the current one.
   nsIntPoint current = DevPixelsToCSSPixels(mEvent->refPoint, mPresContext);
   nsIntPoint last = DevPixelsToCSSPixels(mEvent->lastRefPoint, mPresContext);
   return current - last;
 }
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -45,18 +45,17 @@ public:
         (aEvent->eventStructType != NS_MOUSE_EVENT &&
          aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
          aEvent->eventStructType != NS_WHEEL_EVENT &&
          aEvent->eventStructType != NS_DRAG_EVENT &&
          aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT)) {
       return nsIntPoint(0, 0);
     }
 
-    mozilla::WidgetGUIEvent* event =
-      static_cast<mozilla::WidgetGUIEvent*>(aEvent);
+    mozilla::WidgetGUIEvent* event = aEvent->AsGUIEvent();
     if (!event->widget) {
       return mozilla::LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint);
     }
 
     mozilla::LayoutDeviceIntPoint offset = aEvent->refPoint +
       mozilla::LayoutDeviceIntPoint::FromUntyped(event->widget->WidgetToScreenOffset());
     nscoord factor = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
     return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
@@ -69,17 +68,17 @@ public:
   {
     if (!aEvent ||
         (aEvent->eventStructType != NS_MOUSE_EVENT &&
          aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
          aEvent->eventStructType != NS_WHEEL_EVENT &&
          aEvent->eventStructType != NS_DRAG_EVENT &&
          aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT) ||
         !aPresContext ||
-        !static_cast<mozilla::WidgetGUIEvent*>(aEvent)->widget) {
+        !aEvent->AsGUIEvent()->widget) {
       return aDefaultClientPoint
              ? *aDefaultClientPoint
              : CSSIntPoint(0, 0);
     }
 
     nsIPresShell* shell = aPresContext->GetPresShell();
     if (!shell) {
       return CSSIntPoint(0, 0);
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -692,17 +692,17 @@ nsEventDispatcher::CreateEvent(mozilla::
     switch(aEvent->eventStructType) {
     case NS_MUTATION_EVENT:
       return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext,
                                     aEvent->AsMutationEvent());
     case NS_GUI_EVENT:
     case NS_SCROLLPORT_EVENT:
     case NS_UI_EVENT:
       return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext,
-                              static_cast<WidgetGUIEvent*>(aEvent));
+                              aEvent->AsGUIEvent());
     case NS_SCROLLAREA_EVENT:
       return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext,
                                       aEvent->AsScrollAreaEvent());
     case NS_KEY_EVENT:
       return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext,
                                     aEvent->AsKeyboardEvent());
     case NS_COMPOSITION_EVENT:
       return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext,
@@ -713,29 +713,29 @@ nsEventDispatcher::CreateEvent(mozilla::
     case NS_FOCUS_EVENT:
       return NS_NewDOMFocusEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsFocusEvent());
     case NS_MOUSE_SCROLL_EVENT:
       return NS_NewDOMMouseScrollEvent(aDOMEvent, aOwner, aPresContext,
                                        aEvent->AsMouseScrollEvent());
     case NS_WHEEL_EVENT:
       return NS_NewDOMWheelEvent(aDOMEvent, aOwner, aPresContext,
-                                 static_cast<WidgetWheelEvent*>(aEvent));
+                                 aEvent->AsWheelEvent());
     case NS_DRAG_EVENT:
       return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext,
                                 aEvent->AsDragEvent());
     case NS_TEXT_EVENT:
       return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext,
                                 aEvent->AsTextEvent());
     case NS_CLIPBOARD_EVENT:
       return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext,
                                      aEvent->AsClipboardEvent());
     case NS_SVGZOOM_EVENT:
       return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext,
-                                   static_cast<WidgetGUIEvent*>(aEvent));
+                                   aEvent->AsGUIEvent());
     case NS_SMIL_TIME_EVENT:
       return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, aEvent);
 
     case NS_COMMAND_EVENT:
       return NS_NewDOMCommandEvent(aDOMEvent, aOwner, aPresContext,
                                    aEvent->AsCommandEvent());
     case NS_SIMPLE_GESTURE_EVENT:
       return NS_NewDOMSimpleGestureEvent(aDOMEvent, aOwner, aPresContext,
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -131,18 +131,17 @@ RoundDown(double aDouble)
                          static_cast<int32_t>(ceil(aDouble));
 }
 
 static inline bool
 IsMouseEventReal(WidgetEvent* aEvent)
 {
   NS_ABORT_IF_FALSE(aEvent->IsMouseDerivedEvent(), "Not a mouse event");
   // Return true if not synthesized.
-  return static_cast<WidgetMouseEvent*>(aEvent)->reason ==
-           WidgetMouseEvent::eReal;
+  return aEvent->AsMouseEvent()->reason == WidgetMouseEvent::eReal;
 }
 
 #ifdef DEBUG_DOCSHELL_FOCUS
 static void
 PrintDocTree(nsIDocShellTreeItem* aParentItem, int aLevel)
 {
   for (int32_t i=0;i<aLevel;i++) printf("  ");
 
@@ -497,17 +496,17 @@ nsMouseWheelTransaction::OnEvent(WidgetE
         EndTransaction();
       }
       return;
     case NS_MOUSE_MOVE:
     case NS_DRAGDROP_OVER:
       if (IsMouseEventReal(aEvent)) {
         // If the cursor is moving to be outside the frame,
         // terminate the scrollwheel transaction.
-        nsIntPoint pt = GetScreenPoint(static_cast<WidgetGUIEvent*>(aEvent));
+        nsIntPoint pt = GetScreenPoint(aEvent->AsGUIEvent());
         nsIntRect r = sTargetFrame->GetScreenRectExternal();
         if (!r.Contains(pt)) {
           EndTransaction();
           return;
         }
 
         // If the cursor is moving inside the frame, and it is less than
         // ignoremovedelay milliseconds since the last scroll operation, ignore
@@ -1038,114 +1037,111 @@ nsEventStateManager::PreHandleEvent(nsPr
     ++gMouseOrKeyboardEventCounter;
   }
 
   *aStatus = nsEventStatus_eIgnore;
 
   nsMouseWheelTransaction::OnEvent(aEvent);
 
   switch (aEvent->message) {
-  case NS_MOUSE_BUTTON_DOWN:
-    switch (static_cast<WidgetMouseEvent*>(aEvent)->button) {
+  case NS_MOUSE_BUTTON_DOWN: {
+    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+    switch (mouseEvent->button) {
     case WidgetMouseEvent::eLeftButton:
 #ifndef XP_OS2
-      BeginTrackingDragGesture(aPresContext,
-                               static_cast<WidgetMouseEvent*>(aEvent),
-                               aTargetFrame);
+      BeginTrackingDragGesture(aPresContext, mouseEvent, aTargetFrame);
 #endif
-      mLClickCount = static_cast<WidgetMouseEvent*>(aEvent)->clickCount;
-      SetClickCount(aPresContext, static_cast<WidgetMouseEvent*>(aEvent),
-                    aStatus);
+      mLClickCount = mouseEvent->clickCount;
+      SetClickCount(aPresContext, mouseEvent, aStatus);
       sNormalLMouseEventInProcess = true;
       break;
     case WidgetMouseEvent::eMiddleButton:
-      mMClickCount = static_cast<WidgetMouseEvent*>(aEvent)->clickCount;
-      SetClickCount(aPresContext, static_cast<WidgetMouseEvent*>(aEvent),
-                    aStatus);
+      mMClickCount = mouseEvent->clickCount;
+      SetClickCount(aPresContext, mouseEvent, aStatus);
       break;
     case WidgetMouseEvent::eRightButton:
 #ifdef XP_OS2
-      BeginTrackingDragGesture(aPresContext,
-                               static_cast<WidgetMouseEvent*>(aEvent),
-                               aTargetFrame);
+      BeginTrackingDragGesture(aPresContext, mouseEvent, aTargetFrame);
 #endif
-      mRClickCount = static_cast<WidgetMouseEvent*>(aEvent)->clickCount;
-      SetClickCount(aPresContext, static_cast<WidgetMouseEvent*>(aEvent),
-                    aStatus);
+      mRClickCount = mouseEvent->clickCount;
+      SetClickCount(aPresContext, mouseEvent, aStatus);
       break;
     }
     break;
-  case NS_MOUSE_BUTTON_UP:
-    switch (static_cast<WidgetMouseEvent*>(aEvent)->button) {
+  }
+  case NS_MOUSE_BUTTON_UP: {
+    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+    switch (mouseEvent->button) {
       case WidgetMouseEvent::eLeftButton:
         if (Prefs::ClickHoldContextMenu()) {
           KillClickHoldTimer();
         }
 #ifndef XP_OS2
         StopTrackingDragGesture();
 #endif
         sNormalLMouseEventInProcess = false;
         // then fall through...
       case WidgetMouseEvent::eRightButton:
 #ifdef XP_OS2
         StopTrackingDragGesture();
 #endif
         // then fall through...
       case WidgetMouseEvent::eMiddleButton:
-        SetClickCount(aPresContext, static_cast<WidgetMouseEvent*>(aEvent),
-                      aStatus);
+        SetClickCount(aPresContext, mouseEvent, aStatus);
         break;
     }
     break;
+  }
   case NS_MOUSE_EXIT:
     // If the event is not a top-level window exit, then it's not
     // really an exit --- we may have traversed widget boundaries but
     // we're still in our toplevel window.
     {
-      WidgetMouseEvent* mouseEvent = static_cast<WidgetMouseEvent*>(aEvent);
+      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
       if (mouseEvent->exit != WidgetMouseEvent::eTopLevel) {
         // Treat it as a synthetic move so we don't generate spurious
         // "exit" or "move" events.  Any necessary "out" or "over" events
         // will be generated by GenerateMouseEnterExit
         mouseEvent->message = NS_MOUSE_MOVE;
         mouseEvent->reason = WidgetMouseEvent::eSynthesized;
         // then fall through...
       } else {
-        GenerateMouseEnterExit(static_cast<WidgetGUIEvent*>(aEvent));
+        GenerateMouseEnterExit(mouseEvent);
         //This is a window level mouse exit event and should stop here
         aEvent->message = 0;
         break;
       }
     }
-  case NS_MOUSE_MOVE:
+  case NS_MOUSE_MOVE: {
     // on the Mac, GenerateDragGesture() may not return until the drag
     // has completed and so |aTargetFrame| may have been deleted (moving
     // a bookmark, for example).  If this is the case, however, we know
     // that ClearFrameRefs() has been called and it cleared out
     // |mCurrentTarget|. As a result, we should pass |mCurrentTarget|
     // into UpdateCursor().
-    GenerateDragGesture(aPresContext, static_cast<WidgetMouseEvent*>(aEvent));
+    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+    GenerateDragGesture(aPresContext, mouseEvent);
     UpdateCursor(aPresContext, aEvent, mCurrentTarget, aStatus);
-    GenerateMouseEnterExit(static_cast<WidgetGUIEvent*>(aEvent));
+    GenerateMouseEnterExit(mouseEvent);
     // Flush pending layout changes, so that later mouse move events
     // will go to the right nodes.
     FlushPendingEvents(aPresContext);
     break;
+  }
   case NS_DRAGDROP_GESTURE:
     if (Prefs::ClickHoldContextMenu()) {
       // an external drag gesture event came in, not generated internally
       // by Gecko. Make sure we get rid of the click-hold timer.
       KillClickHoldTimer();
     }
     break;
   case NS_DRAGDROP_OVER:
     // NS_DRAGDROP_DROP is fired before NS_DRAGDROP_DRAGDROP so send
     // the enter/exit events before NS_DRAGDROP_DROP.
-    GenerateDragDropEnterExit(aPresContext,
-                              static_cast<WidgetGUIEvent*>(aEvent));
+    GenerateDragDropEnterExit(aPresContext, aEvent->AsDragEvent());
     break;
 
   case NS_KEY_PRESS:
     {
       WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
 
       int32_t modifierMask = 0;
       if (keyEvent->IsShift())
@@ -1187,17 +1183,17 @@ nsEventStateManager::PreHandleEvent(nsPr
       if (content) {
         mCurrentTargetContent = content;
       }
 
       if (aEvent->message != NS_WHEEL_WHEEL) {
         break;
       }
 
-      WidgetWheelEvent* wheelEvent = static_cast<WidgetWheelEvent*>(aEvent);
+      WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
       WheelPrefs::GetInstance()->ApplyUserPrefsToDelta(wheelEvent);
 
       // If we won't dispatch a DOM event for this event, nothing to do anymore.
       if (!wheelEvent->IsAllowedToDispatchDOMEvent()) {
         break;
       }
 
       // Init lineOrPageDelta values for line scroll events for some devices
@@ -1592,25 +1588,23 @@ nsEventStateManager::DispatchCrossProces
   PBrowserParent* remoteBrowser = aFrameLoader->GetRemoteBrowser();
   TabParent* remote = static_cast<TabParent*>(remoteBrowser);
   if (!remote) {
     return false;
   }
 
   switch (aEvent->eventStructType) {
   case NS_MOUSE_EVENT: {
-    WidgetMouseEvent* mouseEvent = static_cast<WidgetMouseEvent*>(aEvent);
-    return remote->SendRealMouseEvent(*mouseEvent);
+    return remote->SendRealMouseEvent(*aEvent->AsMouseEvent());
   }
   case NS_KEY_EVENT: {
     return remote->SendRealKeyEvent(*aEvent->AsKeyboardEvent());
   }
   case NS_WHEEL_EVENT: {
-    WidgetWheelEvent* wheelEvent = static_cast<WidgetWheelEvent*>(aEvent);
-    return remote->SendMouseWheelEvent(*wheelEvent);
+    return remote->SendMouseWheelEvent(*aEvent->AsWheelEvent());
   }
   case NS_TOUCH_EVENT: {
     // Let the child process synthesize a mouse event if needed, and
     // ensure we don't synthesize one in this process.
     *aStatus = nsEventStatus_eConsumeNoDefault;
     return remote->SendRealTouchEvent(*aEvent->AsTouchEvent());
   }
   default: {
@@ -3175,18 +3169,18 @@ nsEventStateManager::PostHandleEvent(nsP
 
   //Keep the prescontext alive, we might need it after event dispatch
   nsRefPtr<nsPresContext> presContext = aPresContext;
   nsresult ret = NS_OK;
 
   switch (aEvent->message) {
   case NS_MOUSE_BUTTON_DOWN:
     {
-      if (static_cast<WidgetMouseEvent*>(aEvent)->button ==
-            WidgetMouseEvent::eLeftButton &&
+      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+      if (mouseEvent->button == WidgetMouseEvent::eLeftButton &&
           !sNormalLMouseEventInProcess) {
         // We got a mouseup event while a mousedown event was being processed.
         // Make sure that the capturing content is cleared.
         nsIPresShell::SetCapturingContent(nullptr, 0);
         break;
       }
 
       nsCOMPtr<nsIContent> activeContent;
@@ -3305,19 +3299,19 @@ nsEventStateManager::PostHandleEvent(nsP
 #endif
                 fm->ClearFocus(mDocument->GetWindow());
               fm->SetFocusedWindow(mDocument->GetWindow());
             }
           }
         }
 
         // The rest is left button-specific.
-        if (static_cast<WidgetMouseEvent*>(aEvent)->button !=
-              WidgetMouseEvent::eLeftButton)
+        if (mouseEvent->button != WidgetMouseEvent::eLeftButton) {
           break;
+        }
 
         if (activeContent) {
           // The nearest enclosing element goes into the
           // :active state.  If we fail the QI to DOMElement,
           // then we know we're only a node, and that we need
           // to obtain our parent element and put it into :active
           // instead.
           nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(activeContent));
@@ -3364,18 +3358,17 @@ nsEventStateManager::PostHandleEvent(nsP
     {
       ClearGlobalActiveContent(this);
       if (IsMouseEventReal(aEvent)) {
         if (!mCurrentTarget) {
           GetEventTarget();
         }
         // Make sure to dispatch the click even if there is no frame for
         // the current target element. This is required for Web compatibility.
-        ret = CheckForAndDispatchClick(presContext,
-                                       static_cast<WidgetMouseEvent*>(aEvent),
+        ret = CheckForAndDispatchClick(presContext, aEvent->AsMouseEvent(),
                                        aStatus);
       }
 
       nsIPresShell *shell = presContext->GetPresShell();
       if (shell) {
         nsRefPtr<nsFrameSelection> frameSelection = shell->FrameSelection();
         frameSelection->SetMouseDownState(false);
       }
@@ -3392,17 +3385,17 @@ nsEventStateManager::PostHandleEvent(nsP
     {
       MOZ_ASSERT(aEvent->mFlags.mIsTrusted);
 
       if (*aStatus == nsEventStatus_eConsumeNoDefault) {
         nsScrollbarsForWheel::Inactivate();
         break;
       }
 
-      WidgetWheelEvent* wheelEvent = static_cast<WidgetWheelEvent*>(aEvent);
+      WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
       switch (WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent)) {
         case WheelPrefs::ACTION_SCROLL: {
           // For scrolling of default action, we should honor the mouse wheel
           // transaction.
 
           nsScrollbarsForWheel::PrepareToScrollText(this, aTargetFrame, wheelEvent);
 
           if (aEvent->message != NS_WHEEL_WHEEL ||
@@ -3594,17 +3587,17 @@ nsEventStateManager::PostHandleEvent(nsP
         nsCOMPtr<nsIContent> targetContent;
         mCurrentTarget->GetContentForEvent(aEvent,
                                            getter_AddRefs(targetContent));
 
         nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetNearestWidget();
         WidgetDragEvent event(aEvent->mFlags.mIsTrusted,
                               NS_DRAGDROP_DRAGDROP, widget);
 
-        WidgetMouseEvent* mouseEvent = static_cast<WidgetMouseEvent*>(aEvent);
+        WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
         event.refPoint = mouseEvent->refPoint;
         if (mouseEvent->widget) {
           event.refPoint += LayoutDeviceIntPoint::FromUntyped(mouseEvent->widget->WidgetToScreenOffset());
         }
         event.refPoint -= LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset());
         event.modifiers = mouseEvent->modifiers;
         event.buttons = mouseEvent->buttons;
         event.inputSource = mouseEvent->inputSource;
@@ -3618,18 +3611,17 @@ nsEventStateManager::PostHandleEvent(nsP
       }
       sLastDragOverFrame = nullptr;
       ClearGlobalActiveContent(this);
       break;
     }
   case NS_DRAGDROP_EXIT:
      // make sure to fire the enter and exit_synth events after the
      // NS_DRAGDROP_EXIT event, otherwise we'll clean up too early
-    GenerateDragDropEnterExit(presContext,
-                              static_cast<WidgetGUIEvent*>(aEvent));
+    GenerateDragDropEnterExit(presContext, aEvent->AsDragEvent());
     break;
 
   case NS_KEY_UP:
     break;
 
   case NS_KEY_PRESS:
     if (nsEventStatus_eConsumeNoDefault != *aStatus) {
       WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
@@ -3999,17 +3991,17 @@ public:
   nsESMEventCB(nsIContent* aTarget) : mTarget(aTarget) {}
 
   virtual void HandleEvent(nsEventChainPostVisitor& aVisitor)
   {
     if (aVisitor.mPresContext) {
       nsIFrame* frame = aVisitor.mPresContext->GetPrimaryFrameFor(mTarget);
       if (frame) {
         frame->HandleEvent(aVisitor.mPresContext,
-                           static_cast<WidgetGUIEvent*>(aVisitor.mEvent),
+                           aVisitor.mEvent->AsGUIEvent(),
                            &aVisitor.mEventStatus);
       }
     }
   }
 
   nsCOMPtr<nsIContent> mTarget;
 };
 
@@ -4021,17 +4013,17 @@ nsEventStateManager::IsHandlingUserInput
   }
 
   TimeDuration timeout = nsContentUtils::HandlingUserInputTimeout();
   return timeout <= TimeDuration(0) ||
          (TimeStamp::Now() - sHandlingInputStart) <= timeout;
 }
 
 nsIFrame*
-nsEventStateManager::DispatchMouseEvent(WidgetGUIEvent* aEvent,
+nsEventStateManager::DispatchMouseEvent(WidgetMouseEvent* aMouseEvent,
                                         uint32_t aMessage,
                                         nsIContent* aTargetContent,
                                         nsIContent* aRelatedContent)
 {
   // http://dvcs.w3.org/hg/webevents/raw-file/default/mouse-lock.html#methods
   // "[When the mouse is locked on an element...e]vents that require the concept
   // of a mouse cursor must not be dispatched (for example: mouseover, mouseout).
   if (sIsPointerLocked &&
@@ -4047,24 +4039,24 @@ nsEventStateManager::DispatchMouseEvent(
       return nullptr;
     }
     nsCOMPtr<nsIContent> content = do_QueryInterface(pointerLockedElement);
     return mPresContext->GetPrimaryFrameFor(content);
   }
 
   PROFILER_LABEL("Input", "DispatchMouseEvent");
   nsEventStatus status = nsEventStatus_eIgnore;
-  WidgetMouseEvent event(aEvent->mFlags.mIsTrusted, aMessage, aEvent->widget,
-                         WidgetMouseEvent::eReal);
-  event.refPoint = aEvent->refPoint;
-  event.modifiers = static_cast<WidgetMouseEvent*>(aEvent)->modifiers;
-  event.buttons = static_cast<WidgetMouseEvent*>(aEvent)->buttons;
-  event.pluginEvent = static_cast<WidgetMouseEvent*>(aEvent)->pluginEvent;
+  WidgetMouseEvent event(aMouseEvent->mFlags.mIsTrusted, aMessage,
+                         aMouseEvent->widget, WidgetMouseEvent::eReal);
+  event.refPoint = aMouseEvent->refPoint;
+  event.modifiers = aMouseEvent->modifiers;
+  event.buttons = aMouseEvent->buttons;
+  event.pluginEvent = aMouseEvent->pluginEvent;
   event.relatedTarget = aRelatedContent;
-  event.inputSource = static_cast<WidgetMouseEvent*>(aEvent)->inputSource;
+  event.inputSource = aMouseEvent->inputSource;
 
   nsWeakFrame previousTarget = mCurrentTarget;
 
   mCurrentTargetContent = aTargetContent;
 
   nsIFrame* targetFrame = nullptr;
   if (aTargetContent) {
     nsESMEventCB callback(aTargetContent);
@@ -4085,18 +4077,18 @@ nsEventStateManager::DispatchMouseEvent(
   return targetFrame;
 }
 
 class MouseEnterLeaveDispatcher
 {
 public:
   MouseEnterLeaveDispatcher(nsEventStateManager* aESM,
                             nsIContent* aTarget, nsIContent* aRelatedTarget,
-                            WidgetGUIEvent* aEvent, uint32_t aType)
-  : mESM(aESM), mEvent(aEvent), mType(aType)
+                            WidgetMouseEvent* aMouseEvent, uint32_t aType)
+  : mESM(aESM), mMouseEvent(aMouseEvent), mType(aType)
   {
     nsPIDOMWindow* win =
       aTarget ? aTarget->OwnerDoc()->GetInnerWindow() : nullptr;
     if (win && win->HasMouseEnterLeaveEventListeners()) {
       mRelatedTarget = aRelatedTarget ?
         aRelatedTarget->FindFirstNonChromeOnlyAccessContent() : nullptr;
       nsINode* commonParent = nullptr;
       if (aTarget && aRelatedTarget) {
@@ -4114,34 +4106,36 @@ public:
       }
     }
   }
 
   ~MouseEnterLeaveDispatcher()
   {
     if (mType == NS_MOUSEENTER) {
       for (int32_t i = mTargets.Count() - 1; i >= 0; --i) {
-        mESM->DispatchMouseEvent(mEvent, mType, mTargets[i], mRelatedTarget);
+        mESM->DispatchMouseEvent(mMouseEvent, mType, mTargets[i],
+                                 mRelatedTarget);
       }
     } else {
       for (int32_t i = 0; i < mTargets.Count(); ++i) {
-        mESM->DispatchMouseEvent(mEvent, mType, mTargets[i], mRelatedTarget);
+        mESM->DispatchMouseEvent(mMouseEvent, mType, mTargets[i],
+                                 mRelatedTarget);
       }
     }
   }
 
   nsEventStateManager*   mESM;
   nsCOMArray<nsIContent> mTargets;
   nsCOMPtr<nsIContent>   mRelatedTarget;
-  WidgetGUIEvent*        mEvent;
+  WidgetMouseEvent*      mMouseEvent;
   uint32_t               mType;
 };
 
 void
-nsEventStateManager::NotifyMouseOut(WidgetGUIEvent* aEvent,
+nsEventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent,
                                     nsIContent* aMovingInto)
 {
   if (!mLastMouseOverElement)
     return;
   // Before firing mouseout, check for recursion
   if (mLastMouseOverElement == mFirstMouseOutEventElement)
     return;
 
@@ -4154,17 +4148,17 @@ nsEventStateManager::NotifyMouseOut(Widg
       subdocFrame->GetDocShell(getter_AddRefs(docshell));
       if (docshell) {
         nsRefPtr<nsPresContext> presContext;
         docshell->GetPresContext(getter_AddRefs(presContext));
 
         if (presContext) {
           nsEventStateManager* kidESM = presContext->EventStateManager();
           // Not moving into any element in this subdocument
-          kidESM->NotifyMouseOut(aEvent, nullptr);
+          kidESM->NotifyMouseOut(aMouseEvent, nullptr);
         }
       }
     }
   }
   // That could have caused DOM events which could wreak havoc. Reverify
   // things and be careful.
   if (!mLastMouseOverElement)
     return;
@@ -4178,31 +4172,31 @@ nsEventStateManager::NotifyMouseOut(Widg
   // two nearby elements both deep in the DOM tree that would be defeated by
   // switching the hover state to null here.
   if (!aMovingInto) {
     // Unset :hover
     SetContentState(nullptr, NS_EVENT_STATE_HOVER);
   }
 
   MouseEnterLeaveDispatcher leaveDispatcher(this, mLastMouseOverElement, aMovingInto,
-                                            aEvent, NS_MOUSELEAVE);
+                                            aMouseEvent, NS_MOUSELEAVE);
 
   // Fire mouseout
-  DispatchMouseEvent(aEvent, NS_MOUSE_EXIT_SYNTH,
+  DispatchMouseEvent(aMouseEvent, NS_MOUSE_EXIT_SYNTH,
                      mLastMouseOverElement, aMovingInto);
   
   mLastMouseOverFrame = nullptr;
   mLastMouseOverElement = nullptr;
   
   // Turn recursion protection back off
   mFirstMouseOutEventElement = nullptr;
 }
 
 void
-nsEventStateManager::NotifyMouseOver(WidgetGUIEvent* aEvent,
+nsEventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent,
                                      nsIContent* aContent)
 {
   NS_ASSERTION(aContent, "Mouse must be over something");
 
   if (mLastMouseOverElement == aContent)
     return;
 
   // Before firing mouseover, check for recursion
@@ -4215,42 +4209,42 @@ nsEventStateManager::NotifyMouseOver(Wid
   EnsureDocument(mPresContext);
   nsIDocument *parentDoc = mDocument->GetParentDocument();
   if (parentDoc) {
     nsIContent *docContent = parentDoc->FindContentForSubDocument(mDocument);
     if (docContent) {
       nsIPresShell *parentShell = parentDoc->GetShell();
       if (parentShell) {
         nsEventStateManager* parentESM = parentShell->GetPresContext()->EventStateManager();
-        parentESM->NotifyMouseOver(aEvent, docContent);
+        parentESM->NotifyMouseOver(aMouseEvent, docContent);
       }
     }
   }
   // Firing the DOM event in the parent document could cause all kinds
   // of havoc.  Reverify and take care.
   if (mLastMouseOverElement == aContent)
     return;
 
   // Remember mLastMouseOverElement as the related content for the
   // DispatchMouseEvent() call below, since NotifyMouseOut() resets it, bug 298477.
   nsCOMPtr<nsIContent> lastMouseOverElement = mLastMouseOverElement;
 
   MouseEnterLeaveDispatcher enterDispatcher(this, aContent, lastMouseOverElement,
-                                            aEvent, NS_MOUSEENTER);
+                                            aMouseEvent, NS_MOUSEENTER);
   
-  NotifyMouseOut(aEvent, aContent);
+  NotifyMouseOut(aMouseEvent, aContent);
 
   // Store the first mouseOver event we fire and don't refire mouseOver
   // to that element while the first mouseOver is still ongoing.
   mFirstMouseOverEventElement = aContent;
   
   SetContentState(aContent, NS_EVENT_STATE_HOVER);
   
   // Fire mouseover
-  mLastMouseOverFrame = DispatchMouseEvent(aEvent, NS_MOUSE_ENTER_SYNTH,
+  mLastMouseOverFrame = DispatchMouseEvent(aMouseEvent, NS_MOUSE_ENTER_SYNTH,
                                            aContent, lastMouseOverElement);
   mLastMouseOverElement = aContent;
   
   // Turn recursion protection back off
   mFirstMouseOverEventElement = nullptr;
 }
 
 // Returns the center point of the window's inner content area.
@@ -4292,103 +4286,104 @@ GetWindowInnerRectCenter(nsPIDOMWindow* 
   int32_t cssScreenY = aContext->DevPixelsToIntCSSPixels(screen.y);
 
   return LayoutDeviceIntPoint(
     aContext->CSSPixelsToDevPixels(innerX - cssScreenX + innerWidth / 2),
     aContext->CSSPixelsToDevPixels(innerY - cssScreenY + innerHeight / 2));
 }
 
 void
-nsEventStateManager::GenerateMouseEnterExit(WidgetGUIEvent* aEvent)
+nsEventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
 {
   EnsureDocument(mPresContext);
   if (!mDocument)
     return;
 
   // Hold onto old target content through the event and reset after.
   nsCOMPtr<nsIContent> targetBeforeEvent = mCurrentTargetContent;
 
-  switch(aEvent->message) {
+  switch(aMouseEvent->message) {
   case NS_MOUSE_MOVE:
     {
       // Mouse movement is reported on the MouseEvent.movement{X,Y} fields.
       // Movement is calculated in nsDOMUIEvent::GetMovementPoint() as:
       //   previous_mousemove_refPoint - current_mousemove_refPoint.
-      if (sIsPointerLocked && aEvent->widget) {
+      if (sIsPointerLocked && aMouseEvent->widget) {
         // The pointer is locked. If the pointer is not located at the center of
         // the window, dispatch a synthetic mousemove to return the pointer there.
         // Doing this between "real" pointer moves gives the impression that the
         // (locked) pointer can continue moving and won't stop at the screen
         // boundary. We cancel the synthetic event so that we don't end up
         // dispatching the centering move event to content.
         LayoutDeviceIntPoint center =
-          GetWindowInnerRectCenter(mDocument->GetWindow(), aEvent->widget,
+          GetWindowInnerRectCenter(mDocument->GetWindow(), aMouseEvent->widget,
                                    mPresContext);
-        aEvent->lastRefPoint = center;
-        if (aEvent->refPoint != center) {
+        aMouseEvent->lastRefPoint = center;
+        if (aMouseEvent->refPoint != center) {
           // Mouse move doesn't finish at the center of the window. Dispatch a
           // synthetic native mouse event to move the pointer back to the center
           // of the window, to faciliate more movement. But first, record that
           // we've dispatched a synthetic mouse movement, so we can cancel it
           // in the other branch here.
           sSynthCenteringPoint = center;
-          aEvent->widget->SynthesizeNativeMouseMove(
-            LayoutDeviceIntPoint::ToUntyped(center) + aEvent->widget->WidgetToScreenOffset());
-        } else if (aEvent->refPoint == sSynthCenteringPoint) {
+          aMouseEvent->widget->SynthesizeNativeMouseMove(
+            LayoutDeviceIntPoint::ToUntyped(center) +
+              aMouseEvent->widget->WidgetToScreenOffset());
+        } else if (aMouseEvent->refPoint == sSynthCenteringPoint) {
           // This is the "synthetic native" event we dispatched to re-center the
           // pointer. Cancel it so we don't expose the centering move to content.
-          aEvent->mFlags.mPropagationStopped = true;
+          aMouseEvent->mFlags.mPropagationStopped = true;
           // Clear sSynthCenteringPoint so we don't cancel other events
           // targeted at the center.
           sSynthCenteringPoint = kInvalidRefPoint;
         }
       } else if (sLastRefPoint == kInvalidRefPoint) {
         // We don't have a valid previous mousemove refPoint. This is either
         // the first move we've encountered, or the mouse has just re-entered
         // the application window. We should report (0,0) movement for this
         // case, so make the current and previous refPoints the same.
-        aEvent->lastRefPoint = aEvent->refPoint;
+        aMouseEvent->lastRefPoint = aMouseEvent->refPoint;
       } else {
-        aEvent->lastRefPoint = sLastRefPoint;
+        aMouseEvent->lastRefPoint = sLastRefPoint;
       }
 
       // Update the last known refPoint with the current refPoint.
-      sLastRefPoint = aEvent->refPoint;
+      sLastRefPoint = aMouseEvent->refPoint;
 
       // Get the target content target (mousemove target == mouseover target)
-      nsCOMPtr<nsIContent> targetElement = GetEventTargetContent(aEvent);
+      nsCOMPtr<nsIContent> targetElement = GetEventTargetContent(aMouseEvent);
       if (!targetElement) {
         // We're always over the document root, even if we're only
         // over dead space in a page (whose frame is not associated with
         // any content) or in print preview dead space
         targetElement = mDocument->GetRootElement();
       }
       if (targetElement) {
-        NotifyMouseOver(aEvent, targetElement);
+        NotifyMouseOver(aMouseEvent, targetElement);
       }
     }
     break;
   case NS_MOUSE_EXIT:
     {
       // This is actually the window mouse exit event. We're not moving
       // into any new element.
 
       if (mLastMouseOverFrame &&
-          nsContentUtils::GetTopLevelWidget(aEvent->widget) !=
+          nsContentUtils::GetTopLevelWidget(aMouseEvent->widget) !=
           nsContentUtils::GetTopLevelWidget(mLastMouseOverFrame->GetNearestWidget())) {
         // the MouseOut event widget doesn't have same top widget with
         // mLastMouseOverFrame, it's a spurious event for mLastMouseOverFrame
         break;
       }
 
       // Reset sLastRefPoint, so that we'll know not to report any
       // movement the next time we re-enter the window.
       sLastRefPoint = kInvalidRefPoint;
 
-      NotifyMouseOut(aEvent, nullptr);
+      NotifyMouseOut(aMouseEvent, nullptr);
     }
     break;
   }
 
   // reset mCurretTargetContent to what it was
   mCurrentTargetContent = targetBeforeEvent;
 }
 
@@ -4446,68 +4441,71 @@ nsEventStateManager::SetPointerLock(nsIW
     if (dragService) {
       dragService->Unsuppress();
     }
   }
 }
 
 void
 nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
-                                               WidgetGUIEvent* aEvent)
+                                               WidgetDragEvent* aDragEvent)
 {
   //Hold onto old target content through the event and reset after.
   nsCOMPtr<nsIContent> targetBeforeEvent = mCurrentTargetContent;
 
-  switch(aEvent->message) {
+  switch(aDragEvent->message) {
   case NS_DRAGDROP_OVER:
     {
       // when dragging from one frame to another, events are fired in the
       // order: dragexit, dragenter, dragleave
       if (sLastDragOverFrame != mCurrentTarget) {
         //We'll need the content, too, to check if it changed separately from the frames.
         nsCOMPtr<nsIContent> lastContent;
         nsCOMPtr<nsIContent> targetContent;
-        mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
+        mCurrentTarget->GetContentForEvent(aDragEvent,
+                                           getter_AddRefs(targetContent));
 
         if (sLastDragOverFrame) {
           //The frame has changed but the content may not have. Check before dispatching to content
-          sLastDragOverFrame->GetContentForEvent(aEvent, getter_AddRefs(lastContent));
+          sLastDragOverFrame->GetContentForEvent(aDragEvent,
+                                                 getter_AddRefs(lastContent));
 
           FireDragEnterOrExit(sLastDragOverFrame->PresContext(),
-                              aEvent, NS_DRAGDROP_EXIT_SYNTH,
+                              aDragEvent, NS_DRAGDROP_EXIT_SYNTH,
                               targetContent, lastContent, sLastDragOverFrame);
         }
 
-        FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_ENTER,
+        FireDragEnterOrExit(aPresContext, aDragEvent, NS_DRAGDROP_ENTER,
                             lastContent, targetContent, mCurrentTarget);
 
         if (sLastDragOverFrame) {
           FireDragEnterOrExit(sLastDragOverFrame->PresContext(),
-                              aEvent, NS_DRAGDROP_LEAVE_SYNTH,
+                              aDragEvent, NS_DRAGDROP_LEAVE_SYNTH,
                               targetContent, lastContent, sLastDragOverFrame);
         }
 
         sLastDragOverFrame = mCurrentTarget;
       }
     }
     break;
 
   case NS_DRAGDROP_EXIT:
     {
       //This is actually the window mouse exit event.
       if (sLastDragOverFrame) {
         nsCOMPtr<nsIContent> lastContent;
-        sLastDragOverFrame->GetContentForEvent(aEvent, getter_AddRefs(lastContent));
+        sLastDragOverFrame->GetContentForEvent(aDragEvent,
+                                               getter_AddRefs(lastContent));
 
         nsRefPtr<nsPresContext> lastDragOverFramePresContext = sLastDragOverFrame->PresContext();
         FireDragEnterOrExit(lastDragOverFramePresContext,
-                            aEvent, NS_DRAGDROP_EXIT_SYNTH,
+                            aDragEvent, NS_DRAGDROP_EXIT_SYNTH,
                             nullptr, lastContent, sLastDragOverFrame);
         FireDragEnterOrExit(lastDragOverFramePresContext,
-                            aEvent, NS_DRAGDROP_LEAVE_SYNTH,
+                            aDragEvent, NS_DRAGDROP_LEAVE_SYNTH,
                             nullptr, lastContent, sLastDragOverFrame);
 
         sLastDragOverFrame = nullptr;
       }
     }
     break;
   }
 
@@ -4515,29 +4513,30 @@ nsEventStateManager::GenerateDragDropEnt
   mCurrentTargetContent = targetBeforeEvent;
 
   // Now flush all pending notifications, for better responsiveness.
   FlushPendingEvents(aPresContext);
 }
 
 void
 nsEventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
-                                         WidgetGUIEvent* aEvent,
+                                         WidgetDragEvent* aDragEvent,
                                          uint32_t aMsg,
                                          nsIContent* aRelatedTarget,
                                          nsIContent* aTargetContent,
                                          nsWeakFrame& aTargetFrame)
 {
   nsEventStatus status = nsEventStatus_eIgnore;
-  WidgetDragEvent event(aEvent->mFlags.mIsTrusted, aMsg, aEvent->widget);
-  event.refPoint = aEvent->refPoint;
-  event.modifiers = static_cast<WidgetMouseEvent*>(aEvent)->modifiers;
-  event.buttons = static_cast<WidgetMouseEvent*>(aEvent)->buttons;
+  WidgetDragEvent event(aDragEvent->mFlags.mIsTrusted, aMsg,
+                        aDragEvent->widget);
+  event.refPoint = aDragEvent->refPoint;
+  event.modifiers = aDragEvent->modifiers;
+  event.buttons = aDragEvent->buttons;
   event.relatedTarget = aRelatedTarget;
-  event.inputSource = static_cast<WidgetMouseEvent*>(aEvent)->inputSource;
+  event.inputSource = aDragEvent->inputSource;
 
   mCurrentTargetContent = aTargetContent;
 
   if (aTargetContent != aRelatedTarget) {
     //XXX This event should still go somewhere!!
     if (aTargetContent)
       nsEventDispatcher::Dispatch(aTargetContent, aPresContext, &event,
                                   nullptr, &status);
@@ -5088,18 +5087,17 @@ nsEventStateManager::ContentRemoved(nsID
     mLastMouseOverElement = nullptr;
   }
 }
 
 bool
 nsEventStateManager::EventStatusOK(WidgetGUIEvent* aEvent)
 {
   return !(aEvent->message == NS_MOUSE_BUTTON_DOWN &&
-           static_cast<WidgetMouseEvent*>(aEvent)->button ==
-             WidgetMouseEvent::eLeftButton &&
+           aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
            !sNormalLMouseEventInProcess);
 }
 
 //-------------------------------------------
 // Access Key Registration
 //-------------------------------------------
 void
 nsEventStateManager::RegisterAccessKey(nsIContent* aContent, uint32_t aKey)
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -251,52 +251,54 @@ protected:
                     mozilla::WidgetEvent* aEvent,
                     nsIFrame* aTargetFrame,
                     nsEventStatus* aStatus);
   /**
    * Turn a GUI mouse event into a mouse event targeted at the specified
    * content.  This returns the primary frame for the content (or null
    * if it goes away during the event).
    */
-  nsIFrame* DispatchMouseEvent(mozilla::WidgetGUIEvent* aEvent,
+  nsIFrame* DispatchMouseEvent(mozilla::WidgetMouseEvent* aMouseEvent,
                                uint32_t aMessage,
                                nsIContent* aTargetContent,
                                nsIContent* aRelatedContent);
   /**
    * Synthesize DOM and frame mouseover and mouseout events from this
    * MOUSE_MOVE or MOUSE_EXIT event.
    */
-  void GenerateMouseEnterExit(mozilla::WidgetGUIEvent* aEvent);
+  void GenerateMouseEnterExit(mozilla::WidgetMouseEvent* aMouseEvent);
   /**
    * Tell this ESM and ESMs in parent documents that the mouse is
    * over some content in this document.
    */
-  void NotifyMouseOver(mozilla::WidgetGUIEvent* aEvent, nsIContent* aContent);
+  void NotifyMouseOver(mozilla::WidgetMouseEvent* aMouseEvent,
+                       nsIContent* aContent);
   /**
    * Tell this ESM and ESMs in affected child documents that the mouse
    * has exited this document's currently hovered content.
-   * @param aEvent the event that triggered the mouseout
+   * @param aMouseEvent the event that triggered the mouseout
    * @param aMovingInto the content node we've moved into.  This is used to set
    *        the relatedTarget for mouseout events.  Also, if it's non-null
    *        NotifyMouseOut will NOT change the current hover content to null;
    *        in that case the caller is responsible for updating hover state.
    */
-  void NotifyMouseOut(mozilla::WidgetGUIEvent* aEvent, nsIContent* aMovingInto);
+  void NotifyMouseOut(mozilla::WidgetMouseEvent* aMouseEvent,
+                      nsIContent* aMovingInto);
   void GenerateDragDropEnterExit(nsPresContext* aPresContext,
-                                 mozilla::WidgetGUIEvent* aEvent);
+                                 mozilla::WidgetDragEvent* aDragEvent);
   /**
    * Fire the dragenter and dragexit/dragleave events when the mouse moves to a
    * new target.
    *
    * @param aRelatedTarget relatedTarget to set for the event
    * @param aTargetContent target to set for the event
    * @param aTargetFrame target frame for the event
    */
   void FireDragEnterOrExit(nsPresContext* aPresContext,
-                           mozilla::WidgetGUIEvent* aEvent,
+                           mozilla::WidgetDragEvent* aDragEvent,
                            uint32_t aMsg,
                            nsIContent* aRelatedTarget,
                            nsIContent* aTargetContent,
                            nsWeakFrame& aTargetFrame);
   /**
    * Update the initial drag session data transfer with any changes that occur
    * on cloned data transfer objects used for events.
    */
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -529,17 +529,17 @@ nsIMEStateManager::DispatchCompositionEv
   MOZ_ASSERT(aEvent->eventStructType == NS_COMPOSITION_EVENT ||
              aEvent->eventStructType == NS_TEXT_EVENT);
   if (!aEvent->mFlags.mIsTrusted || aEvent->mFlags.mPropagationStopped) {
     return;
   }
 
   EnsureTextCompositionArray();
 
-  WidgetGUIEvent* GUIEvent = static_cast<WidgetGUIEvent*>(aEvent);
+  WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent();
 
   TextComposition* composition =
     sTextCompositions->GetCompositionFor(GUIEvent->widget);
   if (!composition) {
     MOZ_ASSERT(GUIEvent->message == NS_COMPOSITION_START);
     TextComposition newComposition(aPresContext, aEventTargetNode, GUIEvent);
     composition = sTextCompositions->AppendElement(newComposition);
   }
--- a/content/html/content/public/HTMLAudioElement.h
+++ b/content/html/content/public/HTMLAudioElement.h
@@ -2,21 +2,22 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef mozilla_dom_HTMLAudioElement_h
 #define mozilla_dom_HTMLAudioElement_h
 
 #include "mozilla/Attributes.h"
-#include "nsITimer.h"
 #include "nsIDOMHTMLAudioElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/TypedArray.h"
 
+class nsITimer;
+
 typedef uint16_t nsMediaNetworkState;
 typedef uint16_t nsMediaReadyState;
 
 namespace mozilla {
 namespace dom {
 
 class HTMLAudioElement MOZ_FINAL : public HTMLMediaElement,
                                    public nsITimerCallback,
--- a/content/html/content/public/HTMLCanvasElement.h
+++ b/content/html/content/public/HTMLCanvasElement.h
@@ -7,20 +7,18 @@
 #define mozilla_dom_HTMLCanvasElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsSize.h"
 #include "nsError.h"
-#include "nsNodeInfoManager.h"
 
 #include "nsICanvasElementExternal.h"
-#include "nsLayoutUtils.h"
 #include "mozilla/gfx/Rect.h"
 
 class nsICanvasRenderingContextInternal;
 class nsIDOMFile;
 class nsITimerCallback;
 
 namespace mozilla {
 
--- a/content/html/content/public/HTMLMediaElement.h
+++ b/content/html/content/public/HTMLMediaElement.h
@@ -4,47 +4,46 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef mozilla_dom_HTMLMediaElement_h
 #define mozilla_dom_HTMLMediaElement_h
 
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsGenericHTMLElement.h"
 #include "MediaDecoderOwner.h"
-#include "nsIChannel.h"
-#include "nsIHttpChannel.h"
-#include "nsIDOMRange.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsILoadGroup.h"
 #include "nsIObserver.h"
-#include "AudioStream.h"
-#include "VideoFrameContainer.h"
 #include "mozilla/CORSMode.h"
 #include "DOMMediaStream.h"
-#include "mozilla/Mutex.h"
-#include "mozilla/dom/TimeRanges.h"
-#include "nsIDOMWakeLock.h"
 #include "AudioChannelCommon.h"
 #include "DecoderTraits.h"
-#include "MediaMetadataManager.h"
-#include "AudioChannelAgent.h"
+#include "nsIAudioChannelAgent.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/TextTrack.h"
 #include "mozilla/dom/TextTrackList.h"
-#include "mozilla/ErrorResult.h"
 
 // Define to output information on decoding and painting framerate
 /* #define DEBUG_FRAME_RATE 1 */
 
+class nsIChannel;
+class nsIHttpChannel;
+class nsILoadGroup;
+
 typedef uint16_t nsMediaNetworkState;
 typedef uint16_t nsMediaReadyState;
 
 namespace mozilla {
+class AudioStream;
+class ErrorResult;
 class MediaResource;
 class MediaDecoder;
+class VideoFrameContainer;
+namespace dom {
+class TextTrack;
+class TimeRanges;
+}
 }
 
 class nsITimer;
 class nsRange;
 class nsIRunnable;
 
 namespace mozilla {
 namespace dom {
--- a/content/html/content/public/HTMLVideoElement.h
+++ b/content/html/content/public/HTMLVideoElement.h
@@ -5,22 +5,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_HTMLVideoElement_h
 #define mozilla_dom_HTMLVideoElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsIDOMHTMLVideoElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/dom/VideoPlaybackQuality.h"
-#include "nsPerformance.h"
 
 namespace mozilla {
 namespace dom {
 
+class VideoPlaybackQuality;
+
 class HTMLVideoElement MOZ_FINAL : public HTMLMediaElement,
                                    public nsIDOMHTMLVideoElement
 {
 public:
   HTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~HTMLVideoElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLVideoElement, video)
--- a/content/html/content/public/nsFormSubmission.h
+++ b/content/html/content/public/nsFormSubmission.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 nsIFormSubmission_h___
 #define nsIFormSubmission_h___
 
 #include "mozilla/Attributes.h"
-#include "nsISupports.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 
 class nsIURI;
 class nsIInputStream;
 class nsGenericHTMLElement;
 class nsILinkHandler;
 class nsIContent;
--- a/content/html/content/public/nsIFormProcessor.h
+++ b/content/html/content/public/nsIFormProcessor.h
@@ -9,20 +9,20 @@
  * @created  kmcclusk 10/19/99
  * 
  */
 
 #ifndef nsIFormProcessor_h__
 #define nsIFormProcessor_h__
 
 #include "nsISupports.h"
-#include "nsIDOMHTMLInputElement.h"
-#include "nsTArray.h"
+#include "nsTArrayForwardDeclare.h"
 
 class nsString;
+class nsIDOMHTMLElement;
 
 // {0ae53c0f-8ea2-4916-bedc-717443c3e185}
 #define NS_FORMPROCESSOR_CID \
 { 0x0ae53c0f, 0x8ea2, 0x4916, { 0xbe, 0xdc, 0x71, 0x74, 0x43, 0xc3, 0xe1, 0x85 } }
 
 #define NS_FORMPROCESSOR_CONTRACTID "@mozilla.org/layout/form-processor;1"
 
 // 6d4ea1aa-a6b2-43bd-a19d-3f0f26750df3
--- a/content/html/content/src/HTMLAudioElement.cpp
+++ b/content/html/content/src/HTMLAudioElement.cpp
@@ -14,16 +14,19 @@
 #include "jsfriendapi.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "AudioSampleFormat.h"
 #include "AudioChannelCommon.h"
 #include <algorithm>
 #include "mozilla/Preferences.h"
 #include "nsComponentManagerUtils.h"
+#include "nsIHttpChannel.h"
+#include "mozilla/dom/TimeRanges.h"
+#include "AudioStream.h"
 
 static bool
 IsAudioAPIEnabled()
 {
   return mozilla::Preferences::GetBool("media.audio_data.enabled", true);
 }
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Audio)
--- a/content/html/content/src/HTMLButtonElement.cpp
+++ b/content/html/content/src/HTMLButtonElement.cpp
@@ -276,56 +276,49 @@ HTMLButtonElement::PostHandleEvent(nsEve
                                         &status);
             aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
           }
         }
         break;// NS_KEY_PRESS
 
       case NS_MOUSE_BUTTON_DOWN:
         {
-          if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT) {
-            if (static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                  WidgetMouseEvent::eLeftButton) {
-              if (aVisitor.mEvent->mFlags.mIsTrusted) {
-                nsEventStateManager* esm =
-                  aVisitor.mPresContext->EventStateManager();
-                nsEventStateManager::SetActiveManager(
-                  static_cast<nsEventStateManager*>(esm), this);
-              }
-              nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-              if (fm)
-                fm->SetFocus(this, nsIFocusManager::FLAG_BYMOUSE |
-                                   nsIFocusManager::FLAG_NOSCROLL);
-              aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
-            } else if (
-              static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                WidgetMouseEvent::eMiddleButton ||
-              static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                WidgetMouseEvent::eRightButton) {
-              // cancel all of these events for buttons
-              //XXXsmaug What to do with these events? Why these should be cancelled?
-              if (aVisitor.mDOMEvent) {
-                aVisitor.mDOMEvent->StopPropagation();
-              }
+          WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+          if (mouseEvent->button == WidgetMouseEvent::eLeftButton) {
+            if (mouseEvent->mFlags.mIsTrusted) {
+              nsEventStateManager* esm =
+                aVisitor.mPresContext->EventStateManager();
+              nsEventStateManager::SetActiveManager(
+                static_cast<nsEventStateManager*>(esm), this);
+            }
+            nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+            if (fm)
+              fm->SetFocus(this, nsIFocusManager::FLAG_BYMOUSE |
+                                 nsIFocusManager::FLAG_NOSCROLL);
+            mouseEvent->mFlags.mMultipleActionsPrevented = true;
+          } else if (mouseEvent->button == WidgetMouseEvent::eMiddleButton ||
+                     mouseEvent->button == WidgetMouseEvent::eRightButton) {
+            // cancel all of these events for buttons
+            //XXXsmaug What to do with these events? Why these should be cancelled?
+            if (aVisitor.mDOMEvent) {
+              aVisitor.mDOMEvent->StopPropagation();
             }
           }
         }
         break;
 
       // cancel all of these events for buttons
       //XXXsmaug What to do with these events? Why these should be cancelled?
       case NS_MOUSE_BUTTON_UP:
       case NS_MOUSE_DOUBLECLICK:
         {
-          if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-              aVisitor.mDOMEvent &&
-              (static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                 WidgetMouseEvent::eMiddleButton ||
-               static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                 WidgetMouseEvent::eRightButton)) {
+          WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+          if (aVisitor.mDOMEvent &&
+              (mouseEvent->button == WidgetMouseEvent::eMiddleButton ||
+               mouseEvent->button == WidgetMouseEvent::eRightButton)) {
             aVisitor.mDOMEvent->StopPropagation();
           }
         }
         break;
 
       case NS_MOUSE_ENTER_SYNTH:
         {
           aVisitor.mPresContext->EventStateManager()->
--- a/content/html/content/src/HTMLImageElement.cpp
+++ b/content/html/content/src/HTMLImageElement.cpp
@@ -368,20 +368,17 @@ HTMLImageElement::AfterSetAttr(int32_t a
 
 nsresult
 HTMLImageElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   // If we are a map and get a mouse click, don't let it be handled by
   // the Generic Element as this could cause a click event to fire
   // twice, once by the image frame for the map and once by the Anchor
   // element. (bug 39723)
-  if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-      aVisitor.mEvent->message == NS_MOUSE_CLICK &&
-      static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-        WidgetMouseEvent::eLeftButton) {
+  if (aVisitor.mEvent->IsLeftClickEvent()) {
     bool isMap = false;
     GetIsMap(&isMap);
     if (isMap) {
       aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
     }
   }
   return nsGenericHTMLElement::PreHandleEvent(aVisitor);
 }
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -3167,18 +3167,17 @@ HTMLInputElement::PreHandleEvent(nsEvent
   // If mNoContentDispatch is true we will not allow content to handle
   // this event.  But to allow middle mouse button paste to work we must allow
   // middle clicks to go to text fields anyway.
   if (aVisitor.mEvent->mFlags.mNoContentDispatch) {
     aVisitor.mItemFlags |= NS_NO_CONTENT_DISPATCH;
   }
   if (IsSingleLineTextControl(false) &&
       aVisitor.mEvent->message == NS_MOUSE_CLICK &&
-      aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-      static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
+      aVisitor.mEvent->AsMouseEvent()->button ==
         WidgetMouseEvent::eMiddleButton) {
     aVisitor.mEvent->mFlags.mNoContentDispatch = false;
   }
 
   // We must cache type because mType may change during JS event (bug 2369)
   aVisitor.mItemFlags |= mType;
 
   // Fire onchange (if necessary), before we do the blur, bug 357684.
@@ -3669,21 +3668,19 @@ HTMLInputElement::PostHandleEvent(nsEven
         } break; // NS_KEY_PRESS || NS_KEY_UP
 
         case NS_MOUSE_BUTTON_DOWN:
         case NS_MOUSE_BUTTON_UP:
         case NS_MOUSE_DOUBLECLICK:
         {
           // cancel all of these events for buttons
           //XXXsmaug Why?
-          if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-              (static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                 WidgetMouseEvent::eMiddleButton ||
-               static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
-                 WidgetMouseEvent::eRightButton)) {
+          WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+          if (mouseEvent->button == WidgetMouseEvent::eMiddleButton ||
+              mouseEvent->button == WidgetMouseEvent::eRightButton) {
             if (mType == NS_FORM_INPUT_BUTTON ||
                 mType == NS_FORM_INPUT_RESET ||
                 mType == NS_FORM_INPUT_SUBMIT) {
               if (aVisitor.mDOMEvent) {
                 aVisitor.mDOMEvent->StopPropagation();
               } else {
                 rv = NS_ERROR_FAILURE;
               }
@@ -3792,19 +3789,18 @@ HTMLInputElement::PostHandleEventForRang
       WidgetInputEvent* inputEvent = aVisitor.mEvent->AsInputEvent();
       if (inputEvent->IsShift() || inputEvent->IsControl() ||
           inputEvent->IsAlt() || inputEvent->IsMeta() ||
           inputEvent->IsAltGraph() || inputEvent->IsFn() ||
           inputEvent->IsOS()) {
         break; // ignore
       }
       if (aVisitor.mEvent->message == NS_MOUSE_BUTTON_DOWN) {
-        WidgetMouseEvent* mouseEvent =
-          static_cast<WidgetMouseEvent*>(aVisitor.mEvent);
-        if (mouseEvent->buttons == WidgetMouseEvent::eLeftButtonFlag) {
+        if (aVisitor.mEvent->AsMouseEvent()->buttons ==
+              WidgetMouseEvent::eLeftButtonFlag) {
           StartRangeThumbDrag(inputEvent);
         } else if (mIsDraggingRange) {
           CancelRangeThumbDrag();
         }
       } else {
         if (aVisitor.mEvent->AsTouchEvent()->touches.Length() == 1) {
           StartRangeThumbDrag(inputEvent);
         } else if (mIsDraggingRange) {
--- a/content/html/content/src/HTMLLabelElement.cpp
+++ b/content/html/content/src/HTMLLabelElement.cpp
@@ -126,59 +126,56 @@ HTMLLabelElement::PostHandleEvent(nsEven
 
   // Strong ref because event dispatch is going to happen.
   nsRefPtr<Element> content = GetLabeledElement();
 
   if (content && !EventTargetIn(aVisitor.mEvent, content, this)) {
     mHandlingEvent = true;
     switch (aVisitor.mEvent->message) {
       case NS_MOUSE_BUTTON_DOWN:
-        NS_ASSERTION(aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT,
-                     "wrong event struct for event");
-        if (static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
+        if (aVisitor.mEvent->AsMouseEvent()->button ==
               WidgetMouseEvent::eLeftButton) {
           // We reset the mouse-down point on every event because there is
           // no guarantee we will reach the NS_MOUSE_CLICK code below.
           LayoutDeviceIntPoint* curPoint =
             new LayoutDeviceIntPoint(aVisitor.mEvent->refPoint);
           SetProperty(nsGkAtoms::labelMouseDownPtProperty,
                       static_cast<void*>(curPoint),
                       DestroyMouseDownPoint);
         }
         break;
 
       case NS_MOUSE_CLICK:
         if (aVisitor.mEvent->IsLeftClickEvent()) {
-          const WidgetMouseEvent* event =
-            static_cast<const WidgetMouseEvent*>(aVisitor.mEvent);
+          WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
           LayoutDeviceIntPoint* mouseDownPoint =
             static_cast<LayoutDeviceIntPoint*>(
               GetProperty(nsGkAtoms::labelMouseDownPtProperty));
 
           bool dragSelect = false;
           if (mouseDownPoint) {
             LayoutDeviceIntPoint dragDistance = *mouseDownPoint;
             DeleteProperty(nsGkAtoms::labelMouseDownPtProperty);
 
-            dragDistance -= aVisitor.mEvent->refPoint;
+            dragDistance -= mouseEvent->refPoint;
             const int CLICK_DISTANCE = 2;
             dragSelect = dragDistance.x > CLICK_DISTANCE ||
                          dragDistance.x < -CLICK_DISTANCE ||
                          dragDistance.y > CLICK_DISTANCE ||
                          dragDistance.y < -CLICK_DISTANCE;
           }
           // Don't click the for-content if we did drag-select text or if we
           // have a kbd modifier (which adjusts a selection).
-          if (dragSelect || event->IsShift() || event->IsControl() ||
-              event->IsAlt() || event->IsMeta()) {
+          if (dragSelect || mouseEvent->IsShift() || mouseEvent->IsControl() ||
+              mouseEvent->IsAlt() || mouseEvent->IsMeta()) {
             break;
           }
           // Only set focus on the first click of multiple clicks to prevent
           // to prevent immediate de-focus.
-          if (event->clickCount <= 1) {
+          if (mouseEvent->clickCount <= 1) {
             nsIFocusManager* fm = nsFocusManager::GetFocusManager();
             if (fm) {
               // Use FLAG_BYMOVEFOCUS here so that the label is scrolled to.
               // Also, within HTMLInputElement::PostHandleEvent, inputs will
               // be selected only when focused via a key or when the navigation
               // flag is used and we want to select the text on label clicks as
               // well.
               nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(content);
@@ -191,22 +188,21 @@ HTMLLabelElement::PostHandleEvent(nsEven
           //    would do nothing.  If we wanted to do something
           //    sensible, we might send more events through like
           //    this.)  See bug 7554, bug 49897, and bug 96813.
           nsEventStatus status = aVisitor.mEventStatus;
           // Ok to use aVisitor.mEvent as parameter because DispatchClickEvent
           // will actually create a new event.
           EventFlags eventFlags;
           eventFlags.mMultipleActionsPrevented = true;
-          DispatchClickEvent(aVisitor.mPresContext,
-                             aVisitor.mEvent->AsInputEvent(),
+          DispatchClickEvent(aVisitor.mPresContext, mouseEvent,
                              content, false, &eventFlags, &status);
           // Do we care about the status this returned?  I don't think we do...
           // Don't run another <label> off of this click
-          aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
+          mouseEvent->mFlags.mMultipleActionsPrevented = true;
         }
         break;
     }
     mHandlingEvent = false;
   }
   return NS_OK;
 }
 
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -70,16 +70,17 @@
 #include "mozilla/dom/MediaSource.h"
 #include "MediaMetadataManager.h"
 #include "MediaSourceDecoder.h"
 
 #include "AudioChannelService.h"
 
 #include "nsCSSParser.h"
 #include "nsIMediaList.h"
+#include "nsIDOMWakeLock.h"
 
 #include "ImageContainer.h"
 #include "nsIPowerManagerService.h"
 #include "nsRange.h"
 #include <algorithm>
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gMediaElementLog;
@@ -1131,24 +1132,24 @@ nsresult HTMLMediaElement::LoadResource(
     if (NS_FAILED(rv)) {
       nsCString specUTF8;
       mLoadingSrc->GetSpec(specUTF8);
       NS_ConvertUTF8toUTF16 spec(specUTF8);
       const PRUnichar* params[] = { spec.get() };
       ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
       return rv;
     }
-    mMediaSource = source.forget();
     nsRefPtr<MediaSourceDecoder> decoder = new MediaSourceDecoder(this);
-    if (!mMediaSource->Attach(decoder)) {
+    if (!source->Attach(decoder)) {
       // TODO: Handle failure: run "If the media data cannot be fetched at
       // all, due to network errors, causing the user agent to give up
       // trying to fetch the resource" section of resource fetch algorithm.
       return NS_ERROR_FAILURE;
     }
+    mMediaSource = source.forget();
     nsRefPtr<MediaResource> resource = new MediaSourceResource();
     return FinishDecoderSetup(decoder, resource, nullptr, nullptr);
   }
 
   nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
 
   // check for a Content Security Policy to pass down to the channel
   // created to load the media content
--- a/content/html/content/src/HTMLObjectElement.h
+++ b/content/html/content/src/HTMLObjectElement.h
@@ -92,16 +92,24 @@ public:
   void GetType(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::type, aValue);
   }
   void SetType(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::type, aValue, aRv);
   }
+  bool TypeMustMatch()
+  {
+    return GetBoolAttr(nsGkAtoms::typemustmatch);
+  }
+  void SetTypeMustMatch(bool aValue, ErrorResult& aRv)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::typemustmatch, aValue, aRv);
+  }
   void GetName(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::name, aValue);
   }
   void SetName(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::name, aValue, aRv);
   }
--- a/content/html/content/src/HTMLTextAreaElement.cpp
+++ b/content/html/content/src/HTMLTextAreaElement.cpp
@@ -472,18 +472,17 @@ HTMLTextAreaElement::PreHandleEvent(nsEv
 
   // If noContentDispatch is true we will not allow content to handle
   // this event.  But to allow middle mouse button paste to work we must allow 
   // middle clicks to go to text fields anyway.
   if (aVisitor.mEvent->mFlags.mNoContentDispatch) {
     aVisitor.mItemFlags |= NS_NO_CONTENT_DISPATCH;
   }
   if (aVisitor.mEvent->message == NS_MOUSE_CLICK &&
-      aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
-      static_cast<WidgetMouseEvent*>(aVisitor.mEvent)->button ==
+      aVisitor.mEvent->AsMouseEvent()->button ==
         WidgetMouseEvent::eMiddleButton) {
     aVisitor.mEvent->mFlags.mNoContentDispatch = false;
   }
 
   // Fire onchange (if necessary), before we do the blur, bug 370521.
   if (aVisitor.mEvent->message == NS_BLUR_CONTENT) {
     FireChangeEventIfNeeded();
   }
--- a/content/html/content/src/HTMLVideoElement.cpp
+++ b/content/html/content/src/HTMLVideoElement.cpp
@@ -29,16 +29,19 @@
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsIPowerManagerService.h"
 #include "MediaError.h"
 #include "MediaDecoder.h"
 #include "mozilla/Preferences.h"
+#include "nsIDOMWakeLock.h"
+#include "nsPerformance.h"
+#include "mozilla/dom/VideoPlaybackQuality.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
 
 namespace mozilla {
 namespace dom {
 
 static bool sVideoStatsEnabled;
 
new file mode 100644
--- /dev/null
+++ b/content/media/test/crashtests/926665.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<meta charset="UTF-8">
+<script style="display: none;" id="fuzz1" type="text/javascript;version=1.7">
+
+function boom()
+{
+    var mediaSource = new window.MediaSource();
+    var mediaSourceURL = URL.createObjectURL(mediaSource);
+    var v1 = document.createElement('video');
+    v1.src = mediaSourceURL;
+    mediaSource.addEventListener("sourceopen", function (e) {
+        var v2 = document.createElement('video');
+        v2.src = mediaSourceURL;
+        setTimeout(function () {
+            v2.src = "data:text/plain,1";
+            v1.src = "data:text/plain,2";
+        }, 0);
+    });
+}
+
+</script>
+</head>
+
+<body onload="boom();"></body>
+</html>
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -54,8 +54,9 @@ test-pref(media.webvtt.enabled,true) loa
 load 907986-1.html
 load 907986-2.html
 load 907986-3.html
 load 907986-4.html
 load 910171-1.html
 load 920987.html
 skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338
 skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338
+test-pref(media.mediasource.enabled,true) load 926665.html
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -157,16 +157,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Exception)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mThrownJSVal);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+  tmp->mThrownJSVal.setNull();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CI_INTERFACE_GETTER1(Exception, nsIXPCException)
 
 Exception::Exception(const char *aMessage,
                      nsresult aResult,
                      const char *aName,
                      nsIStackFrame *aLocation,
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -32,35 +32,33 @@
 #include "mozilla/Hal.h"
 #include "nsISiteSpecificUserAgent.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "Connection.h"
 #include "nsDOMEvent.h"
 #include "nsGlobalWindow.h"
 #ifdef MOZ_B2G_RIL
-#include "IccManager.h"
+#include "mozilla/dom/IccManager.h"
 #include "MobileConnection.h"
 #include "mozilla/dom/CellBroadcast.h"
+#include "mozilla/dom/Telephony.h"
 #include "mozilla/dom/Voicemail.h"
 #endif
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
 #include "TimeManager.h"
 #include "DeviceStorage.h"
 #include "nsIDOMNavigatorSystemMessages.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "MediaManager.h"
 #endif
-#ifdef MOZ_B2G_RIL
-#include "mozilla/dom/Telephony.h"
-#endif
 #ifdef MOZ_B2G_BT
 #include "BluetoothManager.h"
 #endif
 #include "DOMCameraManager.h"
 
 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
 #include "AudioChannelManager.h"
 #endif
@@ -135,25 +133,23 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlugins)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMimeTypes)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileMessageManager)
-#ifdef MOZ_B2G_RIL
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail)
-#endif
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection)
 #ifdef MOZ_B2G_RIL
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnection)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCellBroadcast)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail)
 #endif
 #ifdef MOZ_B2G_BT
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBluetooth)
 #endif
 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager)
 #endif
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCameraManager)
@@ -208,26 +204,16 @@ Navigator::Invalidate()
     mPowerManager = nullptr;
   }
 
   if (mMobileMessageManager) {
     mMobileMessageManager->Shutdown();
     mMobileMessageManager = nullptr;
   }
 
-#ifdef MOZ_B2G_RIL
-  if (mTelephony) {
-    mTelephony = nullptr;
-  }
-
-  if (mVoicemail) {
-    mVoicemail = nullptr;
-  }
-#endif
-
   if (mConnection) {
     mConnection->Shutdown();
     mConnection = nullptr;
   }
 
 #ifdef MOZ_B2G_RIL
   if (mMobileConnection) {
     mMobileConnection->Shutdown();
@@ -237,16 +223,24 @@ Navigator::Invalidate()
   if (mCellBroadcast) {
     mCellBroadcast = nullptr;
   }
 
   if (mIccManager) {
     mIccManager->Shutdown();
     mIccManager = nullptr;
   }
+
+  if (mTelephony) {
+    mTelephony = nullptr;
+  }
+
+  if (mVoicemail) {
+    mVoicemail = nullptr;
+  }
 #endif
 
 #ifdef MOZ_B2G_BT
   if (mBluetooth) {
     mBluetooth = nullptr;
   }
 #endif
 
@@ -1224,17 +1218,17 @@ Navigator::GetMozIccManager(ErrorResult&
 {
   if (!mIccManager) {
     if (!mWindow) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return nullptr;
     }
     NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
 
-    mIccManager = new icc::IccManager();
+    mIccManager = new IccManager();
     mIccManager->Init(mWindow);
   }
 
   return mIccManager;
 }
 
 #endif // MOZ_B2G_RIL
 
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -65,37 +65,32 @@ class MozIdleObserver;
 class Gamepad;
 #endif // MOZ_GAMEPAD
 #ifdef MOZ_MEDIA_NAVIGATOR
 class NavigatorUserMediaSuccessCallback;
 class NavigatorUserMediaErrorCallback;
 class MozGetUserMediaDevicesSuccessCallback;
 #endif // MOZ_MEDIA_NAVIGATOR
 
-namespace icc {
-#ifdef MOZ_B2G_RIL
-class IccManager;
-#endif
-}
-
 namespace network {
 class Connection;
 #ifdef MOZ_B2G_RIL
 class MobileConnection;
 #endif
 } // namespace Connection;
 
 #ifdef MOZ_B2G_BT
 namespace bluetooth {
 class BluetoothManager;
 } // namespace bluetooth
 #endif // MOZ_B2G_BT
 
 #ifdef MOZ_B2G_RIL
 class CellBroadcast;
+class IccManager;
 class Telephony;
 class Voicemail;
 #endif
 
 class PowerManager;
 
 namespace time {
 class TimeManager;
@@ -326,25 +321,23 @@ private:
   nsRefPtr<Geolocation> mGeolocation;
   nsRefPtr<DesktopNotificationCenter> mNotification;
   nsRefPtr<battery::BatteryManager> mBatteryManager;
 #ifdef MOZ_B2G_FM
   nsRefPtr<FMRadio> mFMRadio;
 #endif
   nsRefPtr<PowerManager> mPowerManager;
   nsRefPtr<MobileMessageManager> mMobileMessageManager;
-#ifdef MOZ_B2G_RIL
-  nsRefPtr<Telephony> mTelephony;
-  nsRefPtr<Voicemail> mVoicemail;
-#endif
   nsRefPtr<network::Connection> mConnection;
 #ifdef MOZ_B2G_RIL
   nsRefPtr<network::MobileConnection> mMobileConnection;
   nsRefPtr<CellBroadcast> mCellBroadcast;
-  nsRefPtr<icc::IccManager> mIccManager;
+  nsRefPtr<IccManager> mIccManager;
+  nsRefPtr<Telephony> mTelephony;
+  nsRefPtr<Voicemail> mVoicemail;
 #endif
 #ifdef MOZ_B2G_BT
   nsCOMPtr<bluetooth::BluetoothManager> mBluetooth;
 #endif
 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
   nsRefPtr<system::AudioChannelManager> mAudioChannelManager;
 #endif
   nsRefPtr<nsDOMCameraManager> mCameraManager;
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11791,22 +11791,20 @@ nsGlobalChromeWindow::BeginWindowMove(ns
   }
 #endif
 
   if (!widget) {
     return NS_OK;
   }
 
   NS_ENSURE_TRUE(aMouseDownEvent, NS_ERROR_FAILURE);
-  WidgetEvent* internalEvent = aMouseDownEvent->GetInternalNSEvent();
-  NS_ENSURE_TRUE(internalEvent &&
-                 internalEvent->eventStructType == NS_MOUSE_EVENT,
+  WidgetMouseEvent* mouseEvent =
+    aMouseDownEvent->GetInternalNSEvent()->AsMouseEvent();
+  NS_ENSURE_TRUE(mouseEvent && mouseEvent->eventStructType == NS_MOUSE_EVENT,
                  NS_ERROR_FAILURE);
-  WidgetMouseEvent* mouseEvent = static_cast<WidgetMouseEvent*>(internalEvent);
-
   return widget->BeginMoveDrag(mouseEvent);
 }
 
 //Note: This call will lock the cursor, it will not change as it moves.
 //To unlock, the cursor must be set back to CURSOR_AUTO.
 NS_IMETHODIMP
 nsGlobalChromeWindow::SetCursor(const nsAString& aCursor)
 {
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -321,32 +321,32 @@ enum {
 };
 
 static bool
 InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
 {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   JS::Rooted<JSObject*> callee(cx, &args.callee());
 
-  if (!args.computeThis(cx).isObject()) {
+  if (!args.thisv().isObject()) {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
                          "null", "object");
     return false;
   }
 
   JS::Value v = js::GetFunctionNativeReserved(callee,
                                               TOSTRING_CLASS_RESERVED_SLOT);
   const JSClass* clasp = static_cast<const JSClass*>(v.toPrivate());
 
   v = js::GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT);
   JSString* jsname = static_cast<JSString*>(JSVAL_TO_STRING(v));
   size_t length;
   const jschar* name = JS_GetInternedStringCharsAndLength(jsname, &length);
 
-  if (js::GetObjectJSClass(&args.computeThis(cx).toObject()) != clasp) {
+  if (js::GetObjectJSClass(&args.thisv().toObject()) != clasp) {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
                          NS_ConvertUTF16toUTF8(name).get(), "toString",
                          "object");
     return false;
   }
 
   nsString str;
   str.AppendLiteral("function ");
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -778,18 +778,17 @@ DOMInterfaces = {
     'nativeType': 'nsDOMAttributeMap',
 },
 
 'MozPowerManager': {
     'nativeType': 'mozilla::dom::PowerManager',
 },
 
 'MozStkCommandEvent' : {
-    'nativeType': 'mozilla::dom::icc::StkCommandEvent',
-    'headerFile': 'StkCommandEvent.h',
+    'nativeType': 'mozilla::dom::StkCommandEvent',
 },
 
 'MozTimeManager': {
     'nativeType': 'mozilla::dom::time::TimeManager',
 },
 
 'MozVoicemail': {
     'nativeType': 'mozilla::dom::Voicemail',
@@ -1867,9 +1866,9 @@ addExternalIface('CameraCapabilities', n
 addExternalIface('CameraAutoFocusCallback', nativeType='nsICameraAutoFocusCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraShutterCallback', nativeType='nsICameraShutterCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraClosedCallback', nativeType='nsICameraClosedCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraTakePictureCallback', nativeType='nsICameraTakePictureCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraReleaseCallback', nativeType='nsICameraReleaseCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraStartRecordingCallback', nativeType='nsICameraStartRecordingCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraPreviewStateChange', nativeType='nsICameraPreviewStateChange', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraPreviewStreamCallback', nativeType='nsICameraPreviewStreamCallback', headerFile='nsIDOMCameraManager.h')
-addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')
\ No newline at end of file
+addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -90,22 +90,16 @@ LOCAL_INCLUDES += -I$(topsrcdir)/js/xpco
   $(NULL)
 
 ifdef MOZ_AUDIO_CHANNEL_MANAGER
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/system/gonk \
   $(NULL)
 endif
 
-ifdef MOZ_B2G_RIL
-LOCAL_INCLUDES += \
-  -I$(topsrcdir)/dom/icc/src \
-  $(NULL)
-endif
-
 ABS_DIST := $(abspath $(DIST))
 
 EXTRA_EXPORT_MDDEPEND_FILES := $(addsuffix .pp,$(binding_dependency_trackers))
 
 EXPORTS_GENERATED_FILES := $(exported_binding_headers) $(exported_generated_events_headers)
 EXPORTS_GENERATED_DEST := $(ABS_DIST)/include/$(binding_include_path)
 EXPORTS_GENERATED_TARGET := export
 INSTALL_TARGETS += EXPORTS_GENERATED
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -36,17 +36,16 @@ DOM_SRCDIRS = \
   layout/xul/tree \
   dom/camera \
   $(NULL)
 
 ifdef MOZ_B2G_RIL
 DOM_SRCDIRS += \
   dom/system/gonk \
   dom/wifi \
-  dom/icc/src \
   $(NULL)
 endif
 
 ifdef MOZ_B2G_FM
 DOM_SRCDIRS += \
   dom/fmradio \
   $(NULL)
 endif
--- a/dom/icc/interfaces/SimToolKit.idl
+++ b/dom/icc/interfaces/SimToolKit.idl
@@ -618,16 +618,33 @@ dictionary MozStkLanguageSelectionEvent
    * Language Information
    *
    * @see ISO 639-1, Alpha-2 code
    *      "de" for German, "en" for English, "zh" for Chinese, etc.
    */
   DOMString language;
 };
 
+dictionary MozStkBrowserTerminationEvent
+{
+  /**
+   * The type of this event.
+   * It shall be nsIDOMMozIccManager.STK_EVENT_TYPE_BROWSER_TERMINATION
+   */
+  unsigned short eventType;
+
+  /**
+   * This object shall contain the browser termination cause.
+   * See TZ 102 223 8.51. It shall be one of following:
+   * - nsIDOMMozIccManager.STK_BROWSER_TERMINATION_CAUSE_USER
+   * - nsIDOMMozIccManager.STK_BROWSER_TERMINATION_CAUSE_ERROR
+   */
+  unsigned short terminationCause;
+};
+
 dictionary MozStkGeneralEvent
 {
   /**
    * The type of this event, MozStkGeneralEvent can be used for all Stk Event
    * requires no more parameter than event type, including
    * nsIDOMMozIccManager.STK_EVENT_TYPE_USER_ACTIVITY.
    * nsIDOMMozIccManager.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE.
    * HCI Connectivity Event(Not defined in interface yet).
--- a/dom/icc/interfaces/nsIDOMIccManager.idl
+++ b/dom/icc/interfaces/nsIDOMIccManager.idl
@@ -4,17 +4,17 @@
 
 #include "nsIDOMEventTarget.idl"
 #include "SimToolKit.idl"
 
 interface nsIDOMDOMRequest;
 interface nsIDOMEventListener;
 interface nsIDOMMozIccInfo;
 
-[scriptable, builtinclass, uuid(6b5875dc-de44-4681-84a1-9ea12d60fbe2)]
+[scriptable, builtinclass, uuid(b403e307-e4ff-47a0-ac1e-c97b042b4595)]
 interface nsIDOMMozIccManager : nsIDOMEventTarget
 {
   /**
    * STK Menu Presentation types.
    */
   const unsigned short STK_MENU_TYPE_NOT_SPECIFIED      = 0x00;
   const unsigned short STK_MENU_TYPE_DATA_VALUES        = 0x01;
   const unsigned short STK_MENU_TYPE_NAVIGATION_OPTIONS = 0x03;
@@ -211,16 +211,22 @@ interface nsIDOMMozIccManager : nsIDOMEv
    /**
    * Timer Management
    */
   const unsigned short STK_TIMER_START             = 0x00;
   const unsigned short STK_TIMER_DEACTIVATE        = 0x01;
   const unsigned short STK_TIMER_GET_CURRENT_VALUE = 0x02;
 
   /**
+   * Browser Termination Cause
+   */
+  const unsigned short STK_BROWSER_TERMINATION_CAUSE_USER  = 0x00;
+  const unsigned short STK_BROWSER_TERMINATION_CAUSE_ERROR = 0x01;
+
+  /**
    * Send the response back to ICC after an attempt to execute STK Proactive
    * Command.
    *
    * @param command
    *        Command received from ICC. See MozStkCommand.
    * @param response
    *        The response that will be sent to ICC.
    * @see MozStkResponse for the detail of response.
@@ -255,16 +261,17 @@ interface nsIDOMMozIccManager : nsIDOMEv
    * ICC will not respond with any data for this command.
    *
    * @param event
    *        one of events below:
    *        - MozStkLocationEvent
    *        - MozStkCallEvent
    *        - MozStkLanguageSelectionEvent
    *        - MozStkGeneralEvent
+   *        - MozStkBrowserTerminationEvent
    */
   void sendStkEventDownload(in jsval event);
 
   /**
    * The 'stkcommand' event is notified whenever STK Proactive Command is
    * issued from ICC.
    */
   [implicit_jscontext] attribute jsval onstkcommand;
--- a/dom/icc/src/IccManager.cpp
+++ b/dom/icc/src/IccManager.cpp
@@ -1,23 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "mozilla/dom/IccManager.h"
+
+#include "GeneratedEvents.h"
+#include "mozilla/dom/StkCommandEvent.h"
 #include "mozilla/Services.h"
 #include "nsIDOMClassInfo.h"
 #include "nsIDOMIccInfo.h"
-#include "GeneratedEvents.h"
-#include "IccManager.h"
 #include "SimToolKit.h"
-#include "StkCommandEvent.h"
 
 #define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
 
-using namespace mozilla::dom::icc;
+using namespace mozilla::dom;
 
 class IccManager::Listener : public nsIIccListener
 {
   IccManager* mIccManager;
 
 public:
   NS_DECL_ISUPPORTS
   NS_FORWARD_SAFE_NSIICCLISTENER(mIccManager)
@@ -33,17 +34,17 @@ public:
   {
     MOZ_ASSERT(mIccManager);
     mIccManager = nullptr;
   }
 };
 
 NS_IMPL_ISUPPORTS1(IccManager::Listener, nsIIccListener)
 
-DOMCI_DATA(MozIccManager, mozilla::dom::icc::IccManager)
+DOMCI_DATA(MozIccManager, IccManager)
 
 NS_INTERFACE_MAP_BEGIN(IccManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozIccManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozIccManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(IccManager, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(IccManager, nsDOMEventTargetHelper)
@@ -272,9 +273,9 @@ IccManager::NotifyCardStateChanged()
 {
   return DispatchTrustedEvent(NS_LITERAL_STRING("cardstatechange"));
 }
 
 NS_IMETHODIMP
 IccManager::NotifyIccInfoChanged()
 {
   return DispatchTrustedEvent(NS_LITERAL_STRING("iccinfochange"));
-}
\ No newline at end of file
+}
--- a/dom/icc/src/IccManager.h
+++ b/dom/icc/src/IccManager.h
@@ -1,23 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef mozilla_dom_icc_IccManager_h
-#define mozilla_dom_icc_IccManager_h
+#ifndef mozilla_dom_IccManager_h
+#define mozilla_dom_IccManager_h
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIDOMIccManager.h"
 #include "nsIIccProvider.h"
 
 namespace mozilla {
 namespace dom {
-namespace icc {
 
 class IccManager : public nsDOMEventTargetHelper
                  , public nsIDOMMozIccManager
 {
   /**
    * Class IccManager doesn't actually inherit nsIIccListener. Instead, it owns
    * an nsIIccListener derived instance mListener and passes it to
    * nsIIccProvider. The onreceived events are first delivered to mListener and
@@ -37,13 +36,12 @@ public:
   void Init(nsPIDOMWindow *aWindow);
   void Shutdown();
 
 private:
   nsCOMPtr<nsIIccProvider> mProvider;
   nsRefPtr<Listener> mListener;
 };
 
-} // namespace icc
 } // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_dom_icc_IccManager_h
+#endif // mozilla_dom_IccManager_h
--- a/dom/icc/src/StkCommandEvent.cpp
+++ b/dom/icc/src/StkCommandEvent.cpp
@@ -1,25 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "SimToolKit.h"
-#include "StkCommandEvent.h"
+#include "mozilla/dom/StkCommandEvent.h"
 
-#include "nsJSON.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
+#include "nsJSON.h"
+#include "SimToolKit.h"
 
 namespace mozilla {
 namespace dom {
-namespace icc {
 
 already_AddRefed<StkCommandEvent>
-StkCommandEvent::Create(mozilla::dom::EventTarget* aOwner,
+StkCommandEvent::Create(EventTarget* aOwner,
                         const nsAString& aMessage)
 {
   nsRefPtr<StkCommandEvent> event = new StkCommandEvent(aOwner);
   event->mCommand = aMessage;
   return event.forget();
 }
 
 NS_IMPL_ADDREF_INHERITED(StkCommandEvent, nsDOMEvent)
@@ -40,11 +39,10 @@ StkCommandEvent::GetCommand(JSContext* a
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     *aCommand = JSVAL_VOID;
   }
 
   return NS_OK;
 }
 
-}
-}
-}
+} // namespace dom
+} // namespace mozilla
--- a/dom/icc/src/StkCommandEvent.h
+++ b/dom/icc/src/StkCommandEvent.h
@@ -1,22 +1,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 mozilla_dom_icc_stkcommandevent_h
-#define mozilla_dom_icc_stkcommandevent_h
+#ifndef mozilla_dom_StkCommandEvent_h
+#define mozilla_dom_StkCommandEvent_h
 
+#include "mozilla/dom/MozStkCommandEventBinding.h"
 #include "nsDOMEvent.h"
 #include "SimToolKit.h"
-#include "mozilla/dom/MozStkCommandEventBinding.h"
 
 namespace mozilla {
 namespace dom {
-namespace icc {
 
 class StkCommandEvent : public nsDOMEvent,
                         public nsIDOMMozStkCommandEvent
 {
   nsString mCommand;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
@@ -44,34 +43,33 @@ public:
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE
   {
-    return mozilla::dom::MozStkCommandEventBinding::Wrap(aCx, aScope, this);
+    return MozStkCommandEventBinding::Wrap(aCx, aScope, this);
   }
 
-  JS::Value GetCommand(JSContext* aCx, mozilla::ErrorResult& aRv)
+  JS::Value GetCommand(JSContext* aCx, ErrorResult& aRv)
   {
     JS::Rooted<JS::Value> retVal(aCx);
     aRv = GetCommand(aCx, retVal.address());
     return retVal;
   }
 
 private:
-  StkCommandEvent(mozilla::dom::EventTarget* aOwner)
+  StkCommandEvent(EventTarget* aOwner)
   : nsDOMEvent(aOwner, nullptr, nullptr)
   {
     SetIsDOMBinding();
   }
 
   ~StkCommandEvent()
   { }
 };
 
-}
-}
-}
+} // namespace dom
+} // namespace mozilla
 
-#endif // mozilla_dom_icc_stkcommandevent_h
+#endif // mozilla_dom_StkCommandEvent_h
--- a/dom/icc/src/moz.build
+++ b/dom/icc/src/moz.build
@@ -1,15 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-EXPORTS.mozilla.dom.icc += [
+EXPORTS.mozilla.dom += [
+    'IccManager.h',
     'StkCommandEvent.h',
 ]
 
 CPP_SOURCES += [
     'IccManager.cpp',
     'StkCommandEvent.cpp',
 ]
 
--- a/dom/indexedDB/test/extensions/Makefile.in
+++ b/dom/indexedDB/test/extensions/Makefile.in
@@ -1,14 +1,12 @@
 # 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/.
 
-XPI_NAME = indexedDB
-
 DIST_FILES = \
   bootstrap.js \
   install.rdf \
   $(NULL)
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
 
 GENERATED_DIRS = $(TEST_EXTENSIONS_DIR)
--- a/dom/indexedDB/test/extensions/moz.build
+++ b/dom/indexedDB/test/extensions/moz.build
@@ -1,6 +1,7 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+XPI_NAME = 'indexedDB'
--- a/dom/media/tests/mochitest/test_peerConnection_toJSON.html
+++ b/dom/media/tests/mochitest/test_peerConnection_toJSON.html
@@ -1,34 +1,46 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=872377
 -->
 <head>
   <meta charset="utf-8">
-  <title>Test for Bug 872377</title>
+  <title>Test for Bug 872377 and Bug 928304</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
   /** Test for Bug 872377 **/
 
   var rtcSession = new mozRTCSessionDescription({ sdp: "Picklechips!",
                                                   type: "offer" });
   var jsonCopy = JSON.parse(JSON.stringify(rtcSession));
   for (key in rtcSession) {
     if (typeof(rtcSession[key]) == "function") continue;
     is(rtcSession[key], jsonCopy[key], "key " + key + " should match.");
   }
 
+  /** Test for Bug 928304 **/
+
+  var rtcIceCandidate = new mozRTCIceCandidate({ candidate: "dummy",
+                                                 sdpMid: "test",
+                                                 sdpMLineIndex: 3 });
+  jsonCopy = JSON.parse(JSON.stringify(rtcIceCandidate));
+  for (key in rtcIceCandidate) {
+    if (typeof(rtcIceCandidate[key]) == "function") continue;
+    is(rtcIceCandidate[key], jsonCopy[key], "key " + key + " should match.");
+  }
+
   </script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=872377">Mozilla Bug 872377</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=928304">Mozilla Bug 928304</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 </pre>
 </body>
 </html>
--- a/dom/network/src/Makefile.in
+++ b/dom/network/src/Makefile.in
@@ -1,23 +1,14 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 VPATH            = $(srcdir)
 
-ifdef MOZ_B2G_RIL
-endif
-
 include $(topsrcdir)/dom/dom-config.mk
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
-ifdef MOZ_B2G_RIL
-LOCAL_INCLUDES += \
-  -I$(topsrcdir)/dom/icc/src \
-  $(NULL)
-endif
-
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1825,19 +1825,20 @@ nsresult nsPluginInstanceOwner::Dispatch
 {
 #if !defined(XP_MACOSX)
   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
     return aKeyEvent->PreventDefault(); // consume event
   // continue only for cases without child window
 #endif
 
   if (mInstance) {
-    WidgetEvent* event = aKeyEvent->GetInternalNSEvent();
-    if (event && event->eventStructType == NS_KEY_EVENT) {
-      nsEventStatus rv = ProcessEvent(*static_cast<WidgetGUIEvent*>(event));
+    WidgetKeyboardEvent* keyEvent =
+      aKeyEvent->GetInternalNSEvent()->AsKeyboardEvent();
+    if (keyEvent && keyEvent->eventStructType == NS_KEY_EVENT) {
+      nsEventStatus rv = ProcessEvent(*keyEvent);
       if (nsEventStatus_eConsumeNoDefault == rv) {
         aKeyEvent->PreventDefault();
         aKeyEvent->StopPropagation();
       }   
     }
   }
 
   return NS_OK;
@@ -1859,20 +1860,21 @@ nsPluginInstanceOwner::ProcessMouseDown(
     
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     if (fm) {
       nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mContent);
       fm->SetFocus(elem, 0);
     }
   }
 
-  WidgetEvent* event = aMouseEvent->GetInternalNSEvent();
-  if (event && event->eventStructType == NS_MOUSE_EVENT) {
-    mLastMouseDownButtonType = static_cast<WidgetMouseEvent*>(event)->button;
-    nsEventStatus rv = ProcessEvent(*static_cast<WidgetGUIEvent*>(event));
+  WidgetMouseEvent* mouseEvent =
+    aMouseEvent->GetInternalNSEvent()->AsMouseEvent();
+  if (mouseEvent && mouseEvent->eventStructType == NS_MOUSE_EVENT) {
+    mLastMouseDownButtonType = mouseEvent->button;
+    nsEventStatus rv = ProcessEvent(*mouseEvent);
     if (nsEventStatus_eConsumeNoDefault == rv) {
       return aMouseEvent->PreventDefault(); // consume event
     }
   }
   
   return NS_OK;
 }
 
@@ -1882,24 +1884,25 @@ nsresult nsPluginInstanceOwner::Dispatch
   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
     return aMouseEvent->PreventDefault(); // consume event
   // continue only for cases without child window
 #endif
   // don't send mouse events if we are hidden
   if (!mWidgetVisible)
     return NS_OK;
 
-  WidgetEvent* event = aMouseEvent->GetInternalNSEvent();
-  if (event && event->eventStructType == NS_MOUSE_EVENT) {
-    nsEventStatus rv = ProcessEvent(*static_cast<WidgetGUIEvent*>(event));
+  WidgetMouseEvent* mouseEvent =
+    aMouseEvent->GetInternalNSEvent()->AsMouseEvent();
+  if (mouseEvent && mouseEvent->eventStructType == NS_MOUSE_EVENT) {
+    nsEventStatus rv = ProcessEvent(*mouseEvent);
     if (nsEventStatus_eConsumeNoDefault == rv) {
       aMouseEvent->PreventDefault();
       aMouseEvent->StopPropagation();
     }
-    if (event->message == NS_MOUSE_BUTTON_UP) {
+    if (mouseEvent->message == NS_MOUSE_BUTTON_UP) {
       mLastMouseDownButtonType = -1;
     }
   }
   return NS_OK;
 }
 
 nsresult
 nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent)
@@ -1921,19 +1924,19 @@ nsPluginInstanceOwner::HandleEvent(nsIDO
   }
   if (eventType.EqualsLiteral("mouseup")) {
     // Don't send a mouse-up event to the plugin if its button type doesn't
     // match that of the preceding mouse-down event (if any).  This kind of
     // mismatch can happen if the previous mouse-down event was sent to a DOM
     // element above the plugin, the mouse is still above the plugin, and the
     // mouse-down event caused the element to disappear.  See bug 627649 and
     // bug 909678.
-    WidgetMouseEvent *event =
-      static_cast<WidgetMouseEvent*>(aEvent->GetInternalNSEvent());
-    if (event && ((int) event->button != mLastMouseDownButtonType)) {
+    WidgetMouseEvent* mouseEvent = aEvent->GetInternalNSEvent()->AsMouseEvent();
+    if (mouseEvent &&
+        static_cast<int>(mouseEvent->button) != mLastMouseDownButtonType) {
       aEvent->PreventDefault();
       return NS_OK;
     }
     return DispatchMouseToPlugin(aEvent);
   }
   if (eventType.EqualsLiteral("mousemove") ||
       eventType.EqualsLiteral("click") ||
       eventType.EqualsLiteral("dblclick") ||
@@ -2033,18 +2036,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
         synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
         synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
         event = &synthCocoaEvent;
         break;
       case NS_MOUSE_BUTTON_UP:
         // If we're in a dragging operation that started over another frame,
         // convert it into a mouse-entered event (in the Cocoa Event Model).
         // See bug 525078.
-        if ((static_cast<const WidgetMouseEvent&>(anEvent).button ==
-               WidgetMouseEvent::eLeftButton) &&
+        if (anEvent.AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
             (nsIPresShell::GetCapturingContent() != mObjectFrame->GetContent())) {
           synthCocoaEvent.type = NPCocoaEventMouseEntered;
           synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
           synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
           event = &synthCocoaEvent;
         } else {
           synthCocoaEvent.type = NPCocoaEventMouseUp;
           synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
@@ -2069,39 +2071,37 @@ nsEventStatus nsPluginInstanceOwner::Pro
     mInstance->HandleEvent(event, &response, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
   }
 
   if (eventModel == NPEventModelCocoa && response == kNPEventStartIME) {
     pluginWidget->StartComplexTextInputForCurrentEvent();
   }
 
   if ((response == kNPEventHandled || response == kNPEventStartIME) &&
-      !(anEvent.eventStructType == NS_MOUSE_EVENT &&
-        anEvent.message == NS_MOUSE_BUTTON_DOWN &&
-        static_cast<const WidgetMouseEvent&>(anEvent).button ==
-          WidgetMouseEvent::eLeftButton &&
-        !mContentFocused))
+      !(anEvent.message == NS_MOUSE_BUTTON_DOWN &&
+        anEvent.AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
+        !mContentFocused)) {
     rv = nsEventStatus_eConsumeNoDefault;
+  }
 
   pluginWidget->EndDrawPlugin();
 #endif
 
 #ifdef XP_WIN
   // this code supports windowless plugins
   NPEvent *pPluginEvent = (NPEvent*)anEvent.pluginEvent;
   // we can get synthetic events from the nsEventStateManager... these
   // have no pluginEvent
   NPEvent pluginEvent;
   if (anEvent.eventStructType == NS_MOUSE_EVENT) {
     if (!pPluginEvent) {
       // XXX Should extend this list to synthesize events for more event
       // types
       pluginEvent.event = 0;
-      const WidgetMouseEvent* mouseEvent =
-        static_cast<const WidgetMouseEvent*>(&anEvent);
+      const WidgetMouseEvent* mouseEvent = anEvent.AsMouseEvent();
       switch (anEvent.message) {
       case NS_MOUSE_MOVE:
         pluginEvent.event = WM_MOUSEMOVE;
         break;
       case NS_MOUSE_BUTTON_DOWN: {
         static const int downMsgs[] =
           { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
         static const int dblClickMsgs[] =
@@ -2210,18 +2210,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
 
         // Get reference point relative to plugin origin.
         const nsPresContext* presContext = mObjectFrame->PresContext();
         nsPoint appPoint =
           nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
           mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
                                presContext->AppUnitsToDevPixels(appPoint.y));
-        const WidgetMouseEvent& mouseEvent =
-          static_cast<const WidgetMouseEvent&>(anEvent);
+        const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent();
         // Get reference point relative to screen:
         LayoutDeviceIntPoint rootPoint(-1, -1);
         if (widget)
           rootPoint = anEvent.refPoint +
             LayoutDeviceIntPoint::FromUntyped(widget->WidgetToScreenOffset());
 #ifdef MOZ_WIDGET_GTK
         Window root = GDK_ROOT_WINDOW();
 #elif defined(MOZ_WIDGET_QT)
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -707,16 +707,17 @@ this.COMPREHENSIONTLV_TAG_EVENT_LIST = 0
 this.COMPREHENSIONTLV_TAG_ICON_ID = 0x1e;
 this.COMPREHENSIONTLV_TAG_ICON_ID_LIST = 0x1f;
 this.COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER = 0x24;
 this.COMPREHENSIONTLV_TAG_TIMER_VALUE = 0x25;
 this.COMPREHENSIONTLV_TAG_DATE_TIME_ZONE = 0x26;
 this.COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE = 0x2b;
 this.COMPREHENSIONTLV_TAG_LANGUAGE = 0x2d;
 this.COMPREHENSIONTLV_TAG_URL = 0x31;
+this.COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE = 0x34;
 this.COMPREHENSIONTLV_TAG_ACCESS_TECH = 0x3f;
 this.COMPREHENSIONTLV_TAG_SERVICE_RECORD = 0x41;
 this.COMPREHENSIONTLV_TAG_IMEISV = 0x62;
 this.COMPREHENSIONTLV_TAG_BATTERY_STATE = 0x63;
 this.COMPREHENSIONTLV_TAG_NETWORK_SEARCH_MODE = 0x65;
 this.COMPREHENSIONTLV_TAG_MEID = 0x6d;
 this.COMPREHENSIONTLV_TAG_BROADCAST_NETWORK_INFO = 0x7a;
 
@@ -959,16 +960,20 @@ this.STK_LOCAL_INFO_MULTIPLE_ACCESS_TECH
 this.STK_LOCAL_INFO_INFO_FOR_MULTIPLE_ACCESS_TECH = 0x0F;
 this.STK_LOCAL_INFO_NMR_FOR_MULTIPLE_ACCESS_TECH = 0x10;
 
 // Timer Management.
 this.STK_TIMER_START = 0x00;
 this.STK_TIMER_DEACTIVATE = 0x01;
 this.STK_TMIER_GET_CURRENT_VALUE = 0x02;
 
+// Browser Termination Cause.
+this.STK_BROWSER_TERMINATION_CAUSE_USER = 0x00;
+this.STK_BROWSER_TERMINATION_CAUSE_ERROR = 0x01;
+
 /**
  * Supported Terminal Facilities.
  *
  * value = 1, supported.
  *         0, not supported.
  */
 this.STK_TERMINAL_SUPPORT_PROFILE_DOWNLOAD             = 1;
 this.STK_TERMINAL_SUPPORT_SMS_PP_DOWNLOAD              = 1;
@@ -1011,17 +1016,17 @@ this.STK_TERMINAL_SUPPORT_EVENT_MT_CALL 
 this.STK_TERMINAL_SUPPORT_EVENT_CALL_CONNECTED         = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_CALL_DISCONNECTED      = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_LOCATION_STATUS        = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_USER_ACTIVITY          = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_IDLE_SCREEN_AVAILABLE  = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_CARD_READER_STATUS     = 0;
 
 this.STK_TERMINAL_SUPPORT_EVENT_LANGUAGE_SELECTION     = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_BROWSER_TERMINATION    = 0;
+this.STK_TERMINAL_SUPPORT_EVENT_BROWSER_TERMINATION    = 1;
 this.STK_TERMINAL_SUPPORT_EVENT_DATA_AVAILABLE         = 0;
 this.STK_TERMINAL_SUPPORT_EVENT_CHANNEL_STATUS         = 0;
 
 this.STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_START_STOP   = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_GET_CURRENT  = 1;
 this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_DATE    = 1;
 this.STK_TERMINAL_SUPPORT_GET_INKEY                    = 1;
 this.STK_TERMINAL_SUPPORT_SET_UP_IDLE_MODE_TEXT        = 1;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -2722,16 +2722,23 @@ let RIL = {
         break;
       case STK_EVENT_TYPE_LANGUAGE_SELECTION:
         command.deviceId = {
           sourceId: STK_DEVICE_ID_ME,
           destinationId: STK_DEVICE_ID_SIM
         };
         command.language = command.event.language;
         break;
+      case STK_EVENT_TYPE_BROWSER_TERMINATION:
+        command.deviceId = {
+          sourceId: STK_DEVICE_ID_ME,
+          destinationId: STK_DEVICE_ID_SIM
+        };
+        command.terminationCause = command.event.terminationCause;
+        break;
     }
     this.sendICCEnvelopeCommand(command);
   },
 
   /**
    * Send REQUEST_STK_SEND_ENVELOPE_COMMAND to ICC.
    *
    * @param tag
@@ -2741,16 +2748,17 @@ let RIL = {
    * @param [optional] eventList
    * @param [optional] locationStatus
    * @param [optional] locationInfo
    * @param [optional] address
    * @param [optional] transactionId
    * @param [optional] cause
    * @param [optional] timerId
    * @param [optional] timerValue
+   * @param [optional] terminationCause
    */
   sendICCEnvelopeCommand: function sendICCEnvelopeCommand(options) {
     if (DEBUG) {
       debug("Stk Envelope " + JSON.stringify(options));
     }
     Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_COMMAND);
 
     // 1st mark for Parcel size
@@ -2848,16 +2856,24 @@ let RIL = {
         ComprehensionTlvHelper.writeTimerValueTlv(options.timerValue, true);
     }
 
     // Language
     if (options.language) {
       ComprehensionTlvHelper.writeLanguageTlv(options.language);
     }
 
+    // Browser Termination
+    if (options.terminationCause != null) {
+      GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE |
+                                 COMPREHENSIONTLV_FLAG_CR);
+      GsmPDUHelper.writeHexOctet(1);
+      GsmPDUHelper.writeHexOctet(options.terminationCause);
+    }
+
     // Calculate and write BER length to 2nd mark
     Buf.stopCalOutgoingSize();
 
     // Calculate and write Parcel size to 1st mark
     Buf.stopCalOutgoingSize();
 
     Buf.writeInt32(0);
     Buf.sendParcel();
--- a/dom/system/gonk/tests/test_ril_worker_stk.js
+++ b/dom/system/gonk/tests/test_ril_worker_stk.js
@@ -968,8 +968,65 @@ add_test(function test_stk_event_downloa
 
   let event = {
     eventType: STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE
   };
   worker.RIL.sendStkEventDownload({
     event: event
   });
 });
+
+/**
+ * Verify Event Downloaded Command :Browser Termination
+ */
+add_test(function test_stk_event_download_browser_termination() {
+  let worker = newUint8SupportOutgoingIndexWorker();
+  let buf = worker.Buf;
+  let pduHelper = worker.GsmPDUHelper;
+
+  buf.sendParcel = function () {
+    // Type
+    do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
+
+    // Token : we don't care
+    this.readInt32();
+
+    // Data Size, 24 = 2 * ( 2+TLV_DEVICE_ID(4)+TLV_EVENT_LIST_SIZE(3)
+    //                        +TLV_BROWSER_TERMINATION_CAUSE(3) )
+    do_check_eq(this.readInt32(), 24);
+
+    // BER tag
+    do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
+
+    // BER length, 10 = TLV_DEVICE_ID(4)+TLV_EVENT_LIST_SIZE(3)
+    //                  ++TLV_BROWSER_TERMINATION_CAUSE(3)
+    do_check_eq(pduHelper.readHexOctet(), 10);
+
+    // Device Identities, Type-Length-Value(Source ID-Destination ID)
+    do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
+                                          COMPREHENSIONTLV_FLAG_CR);
+    do_check_eq(pduHelper.readHexOctet(), 2);
+    do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
+    do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
+
+    // Event List, Type-Length-Value
+    do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
+                                          COMPREHENSIONTLV_FLAG_CR);
+    do_check_eq(pduHelper.readHexOctet(), 1);
+    do_check_eq(pduHelper.readHexOctet(), STK_EVENT_TYPE_BROWSER_TERMINATION);
+
+    // Browser Termination Case, Type-Length-Value
+    do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE |
+                                          COMPREHENSIONTLV_FLAG_CR);
+    do_check_eq(pduHelper.readHexOctet(), 1);
+    do_check_eq(pduHelper.readHexOctet(), STK_BROWSER_TERMINATION_CAUSE_USER);
+
+    run_next_test();
+  };
+
+  let event = {
+    eventType: STK_EVENT_TYPE_BROWSER_TERMINATION,
+    terminationCause: STK_BROWSER_TERMINATION_CAUSE_USER
+  };
+  worker.RIL.sendStkEventDownload({
+    event: event
+  });
+});
--- a/dom/webidl/HTMLObjectElement.webidl
+++ b/dom/webidl/HTMLObjectElement.webidl
@@ -14,17 +14,18 @@
 
 // http://www.whatwg.org/specs/web-apps/current-work/#the-object-element
 [NeedNewResolve]
 interface HTMLObjectElement : HTMLElement {
   [Pure, SetterThrows]
            attribute DOMString data;
   [Pure, SetterThrows]
            attribute DOMString type;
-//           attribute boolean typeMustMatch;
+  [Pure, SetterThrows]
+           attribute boolean typeMustMatch;
   [Pure, SetterThrows]
            attribute DOMString name;
   [Pure, SetterThrows]
            attribute DOMString useMap;
   [Pure]
   readonly attribute HTMLFormElement? form;
   [Pure, SetterThrows]
            attribute DOMString width;
--- a/dom/webidl/RTCIceCandidate.webidl
+++ b/dom/webidl/RTCIceCandidate.webidl
@@ -16,12 +16,10 @@ dictionary RTCIceCandidateInit {
 [Pref="media.peerconnection.enabled",
  JSImplementation="@mozilla.org/dom/rtcicecandidate;1",
  Constructor(optional RTCIceCandidateInit candidateInitDict)]
 interface mozRTCIceCandidate {
   attribute DOMString?      candidate;
   attribute DOMString?      sdpMid;
   attribute unsigned short? sdpMLineIndex;
 
-  // Bug 863402 serializer support
-  //
-  //serializer = {attribute};
+  jsonifier;
 };
--- a/dom/workers/test/extensions/bootstrap/Makefile.in
+++ b/dom/workers/test/extensions/bootstrap/Makefile.in
@@ -1,14 +1,12 @@
 # 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/.
 
-XPI_NAME = workerbootstrap
-
 DIST_FILES = \
   bootstrap.js \
   install.rdf \
   worker.js \
   $(NULL)
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
 
--- a/dom/workers/test/extensions/bootstrap/moz.build
+++ b/dom/workers/test/extensions/bootstrap/moz.build
@@ -1,6 +1,7 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+XPI_NAME = 'workerbootstrap'
--- a/dom/workers/test/extensions/traditional/Makefile.in
+++ b/dom/workers/test/extensions/traditional/Makefile.in
@@ -1,13 +1,12 @@
 # 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/.
 
-XPI_NAME = worker
 DIST_FILES = \
   install.rdf \
   worker.js \
   $(NULL)
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
 
 GENERATED_DIRS = $(TEST_EXTENSIONS_DIR)
--- a/dom/workers/test/extensions/traditional/moz.build
+++ b/dom/workers/test/extensions/traditional/moz.build
@@ -9,8 +9,10 @@ XPIDL_SOURCES += [
 ]
 
 XPIDL_MODULE = 'WorkerTest'
 
 EXTRA_COMPONENTS += [
     'WorkerTest.js',
     'WorkerTest.manifest',
 ]
+
+XPI_NAME = 'worker'
--- a/embedding/tests/winEmbed/Makefile.in
+++ b/embedding/tests/winEmbed/Makefile.in
@@ -22,18 +22,16 @@
 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 #
 # Contributor(s):
 #
 # ***** END LICENSE BLOCK *****
 
-XPI_NAME	= winembed
-
 RESFILE		= winEmbed.res
 
 LIBS = \
 	$(DEPTH)/profile/dirserviceprovider/standalone/$(LIB_PREFIX)profdirserviceprovidersa_s.$(LIB_SUFFIX) \
 	$(XPCOM_STANDALONE_GLUE_LDOPTS) \
 	$(NULL)
 
 LOCAL_INCLUDES	= -I$(srcdir)
--- a/embedding/tests/winEmbed/moz.build
+++ b/embedding/tests/winEmbed/moz.build
@@ -8,8 +8,10 @@ MODULE = 'winEmbed'
 
 PROGRAM = 'winEmbed'
 
 CPP_SOURCES += [
     'WebBrowserChrome.cpp',
     'WindowCreator.cpp',
     'winEmbed.cpp',
 ]
+
+XPI_NAME = 'winembed'
--- a/extensions/widgetutils/Makefile.in
+++ b/extensions/widgetutils/Makefile.in
@@ -1,15 +1,13 @@
 # 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/.
 
 
-XPI_NAME = widgetutils
-
 INSTALL_EXTENSION_ID = widgetutils@extensions.mozilla.org
 DIST_FILES = install.rdf
 NO_JAR_AUTO_REG        = 1
 USE_EXTENSION_MANIFEST = 1
 XPI_PKGNAME            = widgetutils-$(MOZ_APP_VERSION)
 
 XULAPP_DEFINES = \
 	-DTHUNDERBIRD_VERSION=$(THUNDERBIRD_VERSION) \
--- a/extensions/widgetutils/moz.build
+++ b/extensions/widgetutils/moz.build
@@ -3,8 +3,9 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['src']
 
 MODULE = 'widgetutils'
 
+XPI_NAME = 'widgetutils'
--- a/extensions/widgetutils/src/Makefile.in
+++ b/extensions/widgetutils/src/Makefile.in
@@ -1,18 +1,13 @@
 # vim:set ts=8 sw=8 sts=8 noet:
 # 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/.
 
-XPI_NAME	= widgetutils
 SHORT_LIBNAME = widgetutils
 FORCE_SHARED_LIB = 1
 
 EXTRA_DSO_LDOPTS = \
   $(XPCOM_GLUE_LDOPTS) \
   $(NSPR_LIBS) \
   $(MOZ_COMPONENT_LIBS) \
   $(NULL)
-
-ifdef TARGET_XPCOM_ABI
-FINAL_TARGET=$(DIST)/xpi-stage/$(XPI_NAME)/platform/$(OS_TARGET)_$(TARGET_XPCOM_ABI)
-endif
--- a/extensions/widgetutils/src/moz.build
+++ b/extensions/widgetutils/src/moz.build
@@ -9,8 +9,12 @@ MODULE = 'widgetutils'
 CPP_SOURCES += [
     'nsWidgetUtils.cpp',
 ]
 
 LIBRARY_NAME = 'widgetutils'
 
 IS_COMPONENT = True
 
+XPI_NAME = 'widgetutils'
+
+if CONFIG['TARGET_XPCOM_ABI']:
+    FINAL_TARGET += '/platform/%(OS_TARGET)s_%(TARGET_XPCOM_ABI)s' % CONFIG
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -98,18 +98,26 @@ public:
     {
         SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
     }
 
     ~GLContextCGL()
     {
         MarkDestroyed();
 
-        if (mContext)
+        if (mContext) {
+            if ([NSOpenGLContext currentContext] == mContext) {
+                // Clear the current context before releasing. If we don't do
+                // this, the next time we call [NSOpenGLContext currentContext],
+                // "invalid context" will be printed to the console.
+                [NSOpenGLContext clearCurrentContext];
+            }
             [mContext release];
+        }
+
     }
 
     GLContextType GetContextType() {
         return ContextTypeCGL;
     }
 
     bool Init()
     {
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -38,16 +38,17 @@ namespace layers {
 ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
   : mPhase(PHASE_NONE)
   , mWidget(aWidget) 
   , mTargetRotation(ROTATION_0)
   , mRepeatTransaction(false)
   , mIsRepeatTransaction(false)
   , mTransactionIncomplete(false)
   , mCompositorMightResample(false)
+  , mNeedsComposite(false)
 {
   MOZ_COUNT_CTOR(ClientLayerManager);
 }
 
 ClientLayerManager::~ClientLayerManager()
 {
   mRoot = nullptr;
 
@@ -294,18 +295,19 @@ ClientLayerManager::FlushRendering()
 }
 
 void
 ClientLayerManager::ForwardTransaction()
 {
   mPhase = PHASE_FORWARD;
 
   // forward this transaction's changeset to our LayerManagerComposite
+  bool sent;
   AutoInfallibleTArray<EditReply, 10> replies;
-  if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies)) {
+  if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies, &sent)) {
     for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
       const EditReply& reply = replies[i];
 
       switch (reply.type()) {
       case EditReply::TOpContentBufferSwap: {
         MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
 
         const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
@@ -344,16 +346,20 @@ ClientLayerManager::ForwardTransaction()
         compositable->OnReplyTextureRemoved(rep.textureId());
         break;
       }
 
       default:
         NS_RUNTIMEABORT("not reached");
       }
     }
+
+    if (sent) {
+      mNeedsComposite = false;
+    }
   } else if (HasShadowManager()) {
     NS_WARNING("failed to forward Layers transaction");
   }
 
   mPhase = PHASE_NONE;
 
   // this may result in Layers being deleted, which results in
   // PLayer::Send__delete__() and DeallocShmem()
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -137,16 +137,22 @@ public:
 
 #ifdef DEBUG
   bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
   bool InDrawing() { return mPhase == PHASE_DRAWING; }
   bool InForward() { return mPhase == PHASE_FORWARD; }
 #endif
   bool InTransaction() { return mPhase != PHASE_NONE; }
 
+  void SetNeedsComposite(bool aNeedsComposite)
+  {
+    mNeedsComposite = aNeedsComposite;
+  }
+  bool NeedsComposite() const { return mNeedsComposite; }
+
 protected:
   enum TransactionPhase {
     PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
   };
   TransactionPhase mPhase;
 
 private:
   /**
@@ -195,16 +201,17 @@ private:
   ScreenRotation mTargetRotation;
 
   // Used to repeat the transaction right away (to avoid rebuilding
   // a display list) to support progressive drawing.
   bool mRepeatTransaction;
   bool mIsRepeatTransaction;
   bool mTransactionIncomplete;
   bool mCompositorMightResample;
+  bool mNeedsComposite;
 };
 
 class ClientLayer : public ShadowableLayer
 {
 public:
   ClientLayer()
   {
     MOZ_COUNT_CTOR(ClientLayer);
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -367,18 +367,17 @@ APZCTreeManager::ProcessMouseEvent(const
     return nsEventStatus_eIgnore;
   }
   gfx3DMatrix transformToApzc;
   gfx3DMatrix transformToScreen;
   GetInputTransforms(apzc, transformToApzc, transformToScreen);
   MultiTouchInput inputForApzc(aEvent);
   ApplyTransform(&(inputForApzc.mTouches[0].mScreenPoint), transformToApzc);
   gfx3DMatrix outTransform = transformToApzc * transformToScreen;
-  ApplyTransform(&(static_cast<WidgetMouseEvent*>(aOutEvent)->refPoint),
-                 outTransform);
+  ApplyTransform(&aOutEvent->refPoint, outTransform);
   return apzc->ReceiveInputEvent(inputForApzc);
 }
 
 nsEventStatus
 APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent,
                               WidgetInputEvent* aOutEvent)
 {
   // Transform the refPoint
@@ -413,20 +412,19 @@ APZCTreeManager::ReceiveInputEvent(const
       }
       if (!mApzcForInputBlock) {
         return nsEventStatus_eIgnore;
       }
       return ProcessTouchEvent(touchEvent, aOutEvent->AsTouchEvent());
     }
     case NS_MOUSE_EVENT: {
       // For b2g emulation
-      const WidgetMouseEvent& mouseEvent =
-        static_cast<const WidgetMouseEvent&>(aEvent);
-      WidgetMouseEvent* outEvent = static_cast<WidgetMouseEvent*>(aOutEvent);
-      return ProcessMouseEvent(mouseEvent, outEvent);
+      const WidgetMouseEvent& mouseEvent = *aEvent.AsMouseEvent();
+      WidgetMouseEvent* outMouseEvent = aOutEvent->AsMouseEvent();
+      return ProcessMouseEvent(mouseEvent, outMouseEvent);
     }
     default: {
       return ProcessEvent(aEvent, aOutEvent);
     }
   }
 }
 
 nsEventStatus
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -321,17 +321,19 @@ LayerManagerComposite::Render()
 
   if (mComposer2D && mComposer2D->TryRender(mRoot, mWorldMatrix)) {
     mCompositor->EndFrameForExternalComposition(mWorldMatrix);
     return;
   }
 
   {
     PROFILER_LABEL("LayerManagerComposite", "PreRender");
-    mCompositor->GetWidget()->PreRender(this);
+    if (!mCompositor->GetWidget()->PreRender(this)) {
+      return;
+    }
   }
 
   nsIntRect clipRect;
   Rect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height);
   Rect actualBounds;
   if (mRoot->GetClipRect()) {
     clipRect = *mRoot->GetClipRect();
     WorldTransformRect(clipRect);
@@ -339,16 +341,17 @@ LayerManagerComposite::Render()
     mCompositor->BeginFrame(&rect, mWorldMatrix, bounds, nullptr, &actualBounds);
   } else {
     gfx::Rect rect;
     mCompositor->BeginFrame(nullptr, mWorldMatrix, bounds, &rect, &actualBounds);
     clipRect = nsIntRect(rect.x, rect.y, rect.width, rect.height);
   }
 
   if (actualBounds.IsEmpty()) {
+    mCompositor->GetWidget()->PostRender(this);
     return;
   }
 
   // Allow widget to render a custom background.
   mCompositor->SaveState();
   mCompositor->GetWidget()->DrawWindowUnderlay(this, nsIntRect(actualBounds.x,
                                                                actualBounds.y,
                                                                actualBounds.width,
@@ -368,16 +371,18 @@ LayerManagerComposite::Render()
 
   // Debugging
   RenderDebugOverlay(actualBounds);
 
   {
     PROFILER_LABEL("LayerManagerComposite", "EndFrame");
     mCompositor->EndFrame();
   }
+
+  mCompositor->GetWidget()->PostRender(this);
 }
 
 void
 LayerManagerComposite::SetWorldTransform(const gfxMatrix& aMatrix)
 {
   NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
                "SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
   NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -462,18 +462,20 @@ void
 ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable,
                                  TextureClient* aTexture)
 {
   mTxn->AddEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
                              aTexture->GetID()));
 }
 
 bool
-ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
+ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, bool* aSent)
 {
+  *aSent = false;
+
   PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation");
   RenderTraceScope rendertrace("Foward Transaction", "000091");
   NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
   NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?");
 
   DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes();
   if (mDiagnosticTypes != diagnostics) {
     mDiagnosticTypes = diagnostics;
@@ -577,16 +579,17 @@ ShadowLayerForwarder::EndTransaction(Inf
     MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction..."));
     RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093");
     if (!mShadowManager->SendUpdateNoSwap(cset, targetConfig, mIsFirstPaint)) {
       MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
       return false;
     }
   }
 
+  *aSent = true;
   mIsFirstPaint = false;
   MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
   return true;
 }
 
 bool
 ShadowLayerForwarder::AllocShmem(size_t aSize,
                                  ipc::SharedMemory::SharedMemoryType aType,
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -329,17 +329,17 @@ public:
   virtual void UseTexture(CompositableClient* aCompositable,
                           TextureClient* aClient) MOZ_OVERRIDE;
 
   /**
    * End the current transaction and forward it to LayerManagerComposite.
    * |aReplies| are directions from the LayerManagerComposite to the
    * caller of EndTransaction().
    */
-  bool EndTransaction(InfallibleTArray<EditReply>* aReplies);
+  bool EndTransaction(InfallibleTArray<EditReply>* aReplies, bool* aSent);
 
   /**
    * Set an actor through which layer updates will be pushed.
    */
   void SetShadowManager(PLayerTransactionChild* aShadowManager)
   {
     mShadowManager = aShadowManager;
   }
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -895,28 +895,50 @@ private:
 /**
  * Sentry helper class for functions with multiple return points that need to
  * back up the current matrix of a context and have it automatically restored
  * before they return.
  */
 class gfxContextMatrixAutoSaveRestore
 {
 public:
+    gfxContextMatrixAutoSaveRestore() :
+        mContext(nullptr)
+    {
+    }
+
     gfxContextMatrixAutoSaveRestore(gfxContext *aContext) :
         mContext(aContext), mMatrix(aContext->CurrentMatrix())
     {
     }
 
     ~gfxContextMatrixAutoSaveRestore()
     {
-        mContext->SetMatrix(mMatrix);
+        if (mContext) {
+            mContext->SetMatrix(mMatrix);
+        }
+    }
+
+    void SetContext(gfxContext *aContext)
+    {
+        NS_ASSERTION(!mContext, "Not going to restore the matrix on some context!");
+        mContext = aContext;
+        mMatrix = aContext->CurrentMatrix();
+    }
+
+    void Restore()
+    {
+        if (mContext) {
+            mContext->SetMatrix(mMatrix);
+        }
     }
 
     const gfxMatrix& Matrix()
     {
+        MOZ_ASSERT(mContext, "mMatrix doesn't contain a useful matrix");
         return mMatrix;
     }
 
 private:
     gfxContext *mContext;
     gfxMatrix   mMatrix;
 };
 
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -424,22 +424,17 @@ gfxPlatformMac::UseAcceleratedCanvas()
 {
   // Lion or later is required
   return OSXVersion() >= 0x1070 && Preferences::GetBool("gfx.canvas.azure.accelerated", false);
 }
 
 bool
 gfxPlatformMac::SupportsOffMainThreadCompositing()
 {
-  // 10.6.X has crashes on tinderbox with OMTC, so disable it
-  // for now.
-  if (OSXVersion() >= 0x1070) {
-    return true;
-  }
-  return GetPrefLayersOffMainThreadCompositionForceEnabled();
+  return true;
 }
 
 qcms_profile *
 gfxPlatformMac::GetPlatformCMSOutputProfile()
 {
     CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
     if (!cspace) {
         cspace = ::CGColorSpaceCreateDeviceRGB();
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -34,20 +34,16 @@ endif
 endif
 
 # This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
 # shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/config.mk
 
-ifeq (android,$(MOZ_WIDGET_TOOLKIT))
-FINAL_TARGET = $(DIST)/bin/lib
-endif
-
 ifdef _MSC_VER
 # Always enter a Windows program through wmain, whether or not we're
 # a console application.
 WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
 endif
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/ipc/app/moz.build
+++ b/ipc/app/moz.build
@@ -7,12 +7,13 @@
 MODULE = 'ipc'
 
 PROGRAM = CONFIG['MOZ_CHILD_PROCESS_NAME']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     CPP_SOURCES += [
         'MozillaRuntimeMainAndroid.cpp',
     ]
+    FINAL_TARGET = 'dist/bin/lib'
 else:
     CPP_SOURCES += [
         'MozillaRuntimeMain.cpp',
     ]
deleted file mode 100644
--- a/ipc/glue/AsyncChannel.cpp
+++ /dev/null
@@ -1,923 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: sw=4 ts=4 et :
- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/ipc/AsyncChannel.h"
-#include "mozilla/ipc/BrowserProcessSubThread.h"
-#include "mozilla/ipc/ProtocolUtils.h"
-
-#include "nsDebug.h"
-#include "nsTraceRefcnt.h"
-#include "nsXULAppAPI.h"
-
-using namespace mozilla;
-using namespace std;
-
-template<>
-struct RunnableMethodTraits<mozilla::ipc::AsyncChannel>
-{
-    static void RetainCallee(mozilla::ipc::AsyncChannel* obj) { }
-    static void ReleaseCallee(mozilla::ipc::AsyncChannel* obj) { }
-};
-
-template<>
-struct RunnableMethodTraits<mozilla::ipc::AsyncChannel::ProcessLink>
-{
-    static void RetainCallee(mozilla::ipc::AsyncChannel::ProcessLink* obj) { }
-    static void ReleaseCallee(mozilla::ipc::AsyncChannel::ProcessLink* obj) { }
-};
-
-// We rely on invariants about the lifetime of the transport:
-//
-//  - outlives this AsyncChannel
-//  - deleted on the IO thread
-//
-// These invariants allow us to send messages directly through the
-// transport without having to worry about orphaned Send() tasks on
-// the IO thread touching AsyncChannel memory after it's been deleted
-// on the worker thread.  We also don't need to refcount the
-// Transport, because whatever task triggers its deletion only runs on
-// the IO thread, and only runs after this AsyncChannel is done with
-// the Transport.
-template<>
-struct RunnableMethodTraits<mozilla::ipc::AsyncChannel::Transport>
-{
-    static void RetainCallee(mozilla::ipc::AsyncChannel::Transport* obj) { }
-    static void ReleaseCallee(mozilla::ipc::AsyncChannel::Transport* obj) { }
-};
-
-namespace {
-
-// This is an async message
-class GoodbyeMessage : public IPC::Message
-{
-public:
-    enum { ID = GOODBYE_MESSAGE_TYPE };
-    GoodbyeMessage() :
-        IPC::Message(MSG_ROUTING_NONE, ID, PRIORITY_NORMAL)
-    {
-    }
-    // XXX not much point in implementing this; maybe could help with
-    // debugging?
-    static bool Read(const Message* msg)
-    {
-        return true;
-    }
-    void Log(const std::string& aPrefix,
-             FILE* aOutf) const
-    {
-        fputs("(special `Goodbye' message)", aOutf);
-    }
-};
-
-} // namespace <anon>
-
-namespace mozilla {
-namespace ipc {
-
-AsyncChannel::Link::Link(AsyncChannel *aChan)
-    : mChan(aChan)
-{
-}
-
-AsyncChannel::Link::~Link()
-{
-    mChan = 0;
-}
-
-AsyncChannel::ProcessLink::ProcessLink(AsyncChannel *aChan)
-    : Link(aChan)
-    , mExistingListener(nullptr)
-{
-}
-
-AsyncChannel::ProcessLink::~ProcessLink()
-{
-    mIOLoop = 0;
-    if (mTransport) {
-        mTransport->set_listener(0);
-        
-        // we only hold a weak ref to the transport, which is "owned"
-        // by GeckoChildProcess/GeckoThread
-        mTransport = 0;
-    }
-}
-
-void 
-AsyncChannel::ProcessLink::Open(mozilla::ipc::Transport* aTransport,
-                                MessageLoop *aIOLoop,
-                                Side aSide)
-{
-    NS_PRECONDITION(aTransport, "need transport layer");
-
-    // FIXME need to check for valid channel
-
-    mTransport = aTransport;
-
-    // FIXME figure out whether we're in parent or child, grab IO loop
-    // appropriately
-    bool needOpen = true;
-    if(aIOLoop) {
-        // We're a child or using the new arguments.  Either way, we
-        // need an open.
-        needOpen = true;
-        mChan->mChild = (aSide == AsyncChannel::Unknown) || (aSide == AsyncChannel::Child);
-    } else {
-        NS_PRECONDITION(aSide == Unknown, "expected default side arg");
-
-        // parent
-        mChan->mChild = false;
-        needOpen = false;
-        aIOLoop = XRE_GetIOMessageLoop();
-    }
-
-    mIOLoop = aIOLoop;
-
-    NS_ASSERTION(mIOLoop, "need an IO loop");
-    NS_ASSERTION(mChan->mWorkerLoop, "need a worker loop");
-
-    {
-        MonitorAutoLock lock(*mChan->mMonitor);
-
-        if (needOpen) {
-            // Transport::Connect() has not been called.  Call it so
-            // we start polling our pipe and processing outgoing
-            // messages.
-            mIOLoop->PostTask(
-                FROM_HERE,
-                NewRunnableMethod(this, &ProcessLink::OnChannelOpened));
-        } else {
-            // Transport::Connect() has already been called.  Take
-            // over the channel from the previous listener and process
-            // any queued messages.
-            mIOLoop->PostTask(
-                FROM_HERE,
-                NewRunnableMethod(this, &ProcessLink::OnTakeConnectedChannel));
-        }
-
-        // Should not wait here if something goes wrong with the channel.
-        while (!mChan->Connected() &&
-               mChan->mChannelState != AsyncChannel::ChannelError) {
-            mChan->mMonitor->Wait();
-        }
-    }
-}
-
-void
-AsyncChannel::ProcessLink::EchoMessage(Message *msg)
-{
-    mChan->AssertWorkerThread();
-    mChan->mMonitor->AssertCurrentThreadOwns();
-
-    // NB: Go through this OnMessageReceived indirection so that
-    // echoing this message does the right thing for SyncChannel
-    // and RPCChannel too
-    mIOLoop->PostTask(
-        FROM_HERE,
-        NewRunnableMethod(this, &ProcessLink::OnEchoMessage, msg));
-    // OnEchoMessage takes ownership of |msg|
-}
-
-void
-AsyncChannel::ProcessLink::SendMessage(Message *msg)
-{
-    mChan->AssertWorkerThread();
-    mChan->mMonitor->AssertCurrentThreadOwns();
-
-    mIOLoop->PostTask(
-        FROM_HERE,
-        NewRunnableMethod(mTransport, &Transport::Send, msg));
-}
-
-void
-AsyncChannel::ProcessLink::SendClose()
-{
-    mChan->AssertWorkerThread();
-    mChan->mMonitor->AssertCurrentThreadOwns();
-
-    mIOLoop->PostTask(
-        FROM_HERE, NewRunnableMethod(this, &ProcessLink::OnCloseChannel));
-}
-
-AsyncChannel::ThreadLink::ThreadLink(AsyncChannel *aChan,
-                                     AsyncChannel *aTargetChan)
-    : Link(aChan),
-      mTargetChan(aTargetChan)
-{
-}
-
-AsyncChannel::ThreadLink::~ThreadLink()
-{
-    MonitorAutoLock lock(*mChan->mMonitor);
-    // Bug 848949: We need to prevent the other side
-    // from sending us any more messages to avoid Use-After-Free.
-    // The setup here is as shown:
-    //
-    //          (Us)         (Them)
-    //       AsyncChannel  AsyncChannel
-    //         |  ^     \ /     ^ |
-    //         |  |      X      | |
-    //         v  |     / \     | v
-    //        ThreadLink   ThreadLink
-    //
-    // We want to null out the diagonal link from their ThreadLink
-    // to our AsyncChannel.  Note that we must hold the monitor so
-    // that we do this atomically with respect to them trying to send
-    // us a message.
-    if (mTargetChan) {
-        static_cast<ThreadLink*>(mTargetChan->mLink)->mTargetChan = 0;
-    }
-    mTargetChan = 0;
-}
-
-void
-AsyncChannel::ThreadLink::EchoMessage(Message *msg)
-{
-    mChan->AssertWorkerThread();
-    mChan->mMonitor->AssertCurrentThreadOwns();
-
-    mChan->OnMessageReceivedFromLink(*msg);
-    delete msg;
-}
-
-void
-AsyncChannel::ThreadLink::SendMessage(Message *msg)
-{
-    mChan->AssertWorkerThread();
-    mChan->mMonitor->AssertCurrentThreadOwns();
-
-    if (mTargetChan)
-        mTargetChan->OnMessageReceivedFromLink(*msg);
-    delete msg;
-}
-
-void
-AsyncChannel::ThreadLink::SendClose()
-{
-    mChan->AssertWorkerThread();
-    mChan->mMonitor->AssertCurrentThreadOwns();
-
-    mChan->mChannelState = ChannelClosed;
-
-    // In a ProcessLink, we would close our half the channel.  This
-    // would show up on the other side as an error on the I/O thread.
-    // The I/O thread would then invoke OnChannelErrorFromLink().
-    // As usual, we skip that process and just invoke the
-    // OnChannelErrorFromLink() method directly.
-    if (mTargetChan)
-        mTargetChan->OnChannelErrorFromLink();
-}
-
-bool
-AsyncChannel::ThreadLink::Unsound_IsClosed() const
-{
-    MonitorAutoLock lock(*mChan->mMonitor);
-    return mChan->mChannelState == ChannelClosed;
-}
-
-uint32_t
-AsyncChannel::ThreadLink::Unsound_NumQueuedMessages() const
-{
-    // ThreadLinks don't have a message queue.
-    return 0;
-}
-
-AsyncChannel::AsyncChannel(AsyncListener* aListener)
-  : mListener(aListener->asWeakPtr()),
-    mChannelState(ChannelClosed),
-    mWorkerLoop(),
-    mChild(false),
-    mChannelErrorTask(nullptr),
-    mLink(nullptr),
-    mWorkerLoopID(-1)
-{
-    MOZ_COUNT_CTOR(AsyncChannel);
-}
-
-AsyncChannel::~AsyncChannel()
-{
-    MOZ_COUNT_DTOR(AsyncChannel);
-    Clear();
-}
-
-bool
-AsyncChannel::Open(Transport* aTransport,
-                   MessageLoop* aIOLoop,
-                   AsyncChannel::Side aSide)
-{
-    ProcessLink *link;
-    NS_PRECONDITION(!mLink, "Open() called > once");
-    mMonitor = new RefCountedMonitor();
-    mWorkerLoop = MessageLoop::current();
-    mWorkerLoopID = mWorkerLoop->id();
-    mLink = link = new ProcessLink(this);
-    link->Open(aTransport, aIOLoop, aSide); // n.b.: sets mChild
-    return true;
-}
-
-/* Opens a connection to another thread in the same process.
-
-   This handshake proceeds as follows:
-   - Let A be the thread initiating the process (either child or parent)
-     and B be the other thread.
-   - A spawns thread for B, obtaining B's message loop
-   - A creates ProtocolChild and ProtocolParent instances.
-     Let PA be the one appropriate to A and PB the side for B.
-   - A invokes PA->Open(PB, ...):
-     - set state to mChannelOpening
-     - this will place a work item in B's worker loop (see next bullet)
-       and then spins until PB->mChannelState becomes mChannelConnected
-     - meanwhile, on PB's worker loop, the work item is removed and:
-       - invokes PB->SlaveOpen(PA, ...):
-         - sets its state and that of PA to Connected
- */
-bool
-AsyncChannel::Open(AsyncChannel *aTargetChan, 
-                   MessageLoop *aTargetLoop,
-                   AsyncChannel::Side aSide)
-{
-    NS_PRECONDITION(aTargetChan, "Need a target channel");
-    NS_PRECONDITION(ChannelClosed == mChannelState, "Not currently closed");
-
-    CommonThreadOpenInit(aTargetChan, aSide);
-
-    Side oppSide = Unknown;
-    switch(aSide) {
-      case Child: oppSide = Parent; break;
-      case Parent: oppSide = Child; break;
-      case Unknown: break;
-    }
-
-    mMonitor = new RefCountedMonitor();
-
-    MonitorAutoLock lock(*mMonitor);
-    mChannelState = ChannelOpening;
-    aTargetLoop->PostTask(
-        FROM_HERE,
-        NewRunnableMethod(aTargetChan, &AsyncChannel::OnOpenAsSlave,
-                          this, oppSide));
-
-    while (ChannelOpening == mChannelState)
-        mMonitor->Wait();
-    NS_ASSERTION(ChannelConnected == mChannelState, "not connected when awoken");
-    return (ChannelConnected == mChannelState);
-}
-
-void 
-AsyncChannel::CommonThreadOpenInit(AsyncChannel *aTargetChan, Side aSide)
-{
-    mWorkerLoop = MessageLoop::current();
-    mWorkerLoopID = mWorkerLoop->id();
-    mLink = new ThreadLink(this, aTargetChan);
-    mChild = (aSide == Child); 
-}
-
-// Invoked when the other side has begun the open.
-void
-AsyncChannel::OnOpenAsSlave(AsyncChannel *aTargetChan, Side aSide)
-{
-    NS_PRECONDITION(ChannelClosed == mChannelState, 
-                    "Not currently closed");
-    NS_PRECONDITION(ChannelOpening == aTargetChan->mChannelState,
-                    "Target channel not in the process of opening");
-    
-    CommonThreadOpenInit(aTargetChan, aSide);
-    mMonitor = aTargetChan->mMonitor;
-
-    MonitorAutoLock lock(*mMonitor);
-    NS_ASSERTION(ChannelOpening == aTargetChan->mChannelState,
-                 "Target channel not in the process of opening");
-    mChannelState = ChannelConnected;
-    aTargetChan->mChannelState = ChannelConnected;
-    aTargetChan->mMonitor->Notify();
-}
-
-void
-AsyncChannel::Close()
-{
-    AssertWorkerThread();
-
-    {
-        MonitorAutoLock lock(*mMonitor);
-
-        if (ChannelError == mChannelState ||
-            ChannelTimeout == mChannelState) {
-            // See bug 538586: if the listener gets deleted while the
-            // IO thread's NotifyChannelError event is still enqueued
-            // and subsequently deletes us, then the error event will
-            // also be deleted and the listener will never be notified
-            // of the channel error.
-            if (mListener) {
-                MonitorAutoUnlock unlock(*mMonitor);
-                NotifyMaybeChannelError();
-            }
-            return;
-        }
-
-        if (ChannelConnected != mChannelState)
-            // XXX be strict about this until there's a compelling reason
-            // to relax
-            NS_RUNTIMEABORT("Close() called on closed channel!");
-
-        AssertWorkerThread();
-
-        // notify the other side that we're about to close our socket
-        SendSpecialMessage(new GoodbyeMessage());
-
-        SynchronouslyClose();
-    }
-
-    NotifyChannelClosed();
-}
-
-void 
-AsyncChannel::SynchronouslyClose()
-{
-    AssertWorkerThread();
-    mMonitor->AssertCurrentThreadOwns();
-    mLink->SendClose();
-    while (ChannelClosed != mChannelState)
-        mMonitor->Wait();
-}
-
-bool
-AsyncChannel::Send(Message* _msg)
-{
-    nsAutoPtr<Message> msg(_msg);
-    AssertWorkerThread();
-    mMonitor->AssertNotCurrentThreadOwns();
-    NS_ABORT_IF_FALSE(MSG_ROUTING_NONE != msg->routing_id(), "need a route");
-
-    {
-        MonitorAutoLock lock(*mMonitor);
-
-        if (!Connected()) {
-            ReportConnectionError("AsyncChannel");
-            return false;
-        }
-
-        mLink->SendMessage(msg.forget());
-    }
-
-    return true;
-}
-
-bool
-AsyncChannel::Echo(Message* _msg)
-{
-    nsAutoPtr<Message> msg(_msg);
-    AssertWorkerThread();
-    mMonitor->AssertNotCurrentThreadOwns();
-    NS_ABORT_IF_FALSE(MSG_ROUTING_NONE != msg->routing_id(), "need a route");
-
-    {
-        MonitorAutoLock lock(*mMonitor);
-
-        if (!Connected()) {
-            ReportConnectionError("AsyncChannel");
-            return false;
-        }
-
-        mLink->EchoMessage(msg.forget());
-    }
-
-    return true;
-}
-
-void
-AsyncChannel::OnDispatchMessage(const Message& msg)
-{
-    AssertWorkerThread();
-    NS_ASSERTION(!msg.is_reply(), "can't process replies here");
-    NS_ASSERTION(!(msg.is_sync() || msg.is_rpc()), "async dispatch only");
-
-    if (MSG_ROUTING_NONE == msg.routing_id()) {
-        if (!OnSpecialMessage(msg.type(), msg))
-            // XXX real error handling
-            NS_RUNTIMEABORT("unhandled special message!");
-        return;
-    }
-
-    // it's OK to dispatch messages if the channel is closed/error'd,
-    // since we don't have a reply to send back
-
-    (void)MaybeHandleError(mListener->OnMessageReceived(msg), "AsyncChannel");
-}
-
-bool
-AsyncChannel::OnSpecialMessage(uint16_t id, const Message& msg)
-{
-    return false;
-}
-
-void
-AsyncChannel::SendSpecialMessage(Message* msg) const
-{
-    AssertWorkerThread();
-    mLink->SendMessage(msg);
-}
-
-void
-AsyncChannel::OnNotifyMaybeChannelError()
-{
-    AssertWorkerThread();
-    mMonitor->AssertNotCurrentThreadOwns();
-
-    mChannelErrorTask = nullptr;
-
-    // OnChannelError holds mMonitor when it posts this task and this
-    // task cannot be allowed to run until OnChannelError has
-    // exited. We enforce that order by grabbing the mutex here which
-    // should only continue once OnChannelError has completed.
-    {
-        MonitorAutoLock lock(*mMonitor);
-        // nothing to do here
-    }
-
-    if (ShouldDeferNotifyMaybeError()) {
-        mChannelErrorTask =
-            NewRunnableMethod(this, &AsyncChannel::OnNotifyMaybeChannelError);
-        // 10 ms delay is completely arbitrary
-        mWorkerLoop->PostDelayedTask(FROM_HERE, mChannelErrorTask, 10);
-        return;
-    }
-
-    NotifyMaybeChannelError();
-}
-
-void
-AsyncChannel::NotifyChannelClosed()
-{
-    mMonitor->AssertNotCurrentThreadOwns();
-
-    if (ChannelClosed != mChannelState)
-        NS_RUNTIMEABORT("channel should have been closed!");
-
-    // OK, the IO thread just closed the channel normally.  Let the
-    // listener know about it.
-    mListener->OnChannelClose();
-
-    Clear();
-}
-
-void
-AsyncChannel::NotifyMaybeChannelError()
-{
-    mMonitor->AssertNotCurrentThreadOwns();
-
-    // TODO sort out Close() on this side racing with Close() on the
-    // other side
-    if (ChannelClosing == mChannelState) {
-        // the channel closed, but we received a "Goodbye" message
-        // warning us about it. no worries
-        mChannelState = ChannelClosed;
-        NotifyChannelClosed();
-        return;
-    }
-
-    // Oops, error!  Let the listener know about it.
-    mChannelState = ChannelError;
-    mListener->OnChannelError();
-
-    Clear();
-}
-
-void
-AsyncChannel::Clear()
-{
-    // Don't clear mWorkerLoopID; we use it in AssertLinkThread() and
-    // AssertWorkerThread().
-    //
-    // Also don't clear mListener.  If we clear it, then sending a message
-    // through this channel after it's Clear()'ed can cause this process to
-    // crash.
-    //
-    // In practice, mListener owns the channel, so the channel gets deleted
-    // before mListener.  But just to be safe, mListener is a weak pointer.
-
-    mWorkerLoop = 0;
-
-    delete mLink;
-    mLink = 0;
-
-    if (mChannelErrorTask) {
-        mChannelErrorTask->Cancel();
-        mChannelErrorTask = nullptr;
-    }
-}
-
-static void
-PrintErrorMessage(bool isChild, const char* channelName, const char* msg)
-{
-    printf_stderr("\n###!!! [%s][%s] Error: %s\n\n",
-                  isChild ? "Child" : "Parent", channelName, msg);
-}
-
-bool
-AsyncChannel::MaybeHandleError(Result code, const char* channelName)
-{
-    if (MsgProcessed == code)
-        return true;
-
-    const char* errorMsg = nullptr;
-    switch (code) {
-    case MsgNotKnown:
-        errorMsg = "Unknown message: not processed";
-        break;
-    case MsgNotAllowed:
-        errorMsg = "Message not allowed: cannot be sent/recvd in this state";
-        break;
-    case MsgPayloadError:
-        errorMsg = "Payload error: message could not be deserialized";
-        break;
-    case MsgProcessingError:
-        errorMsg = "Processing error: message was deserialized, but the handler returned false (indicating failure)";
-        break;
-    case MsgRouteError:
-        errorMsg = "Route error: message sent to unknown actor ID";
-        break;
-    case MsgValueError:
-        errorMsg = "Value error: message was deserialized, but contained an illegal value";
-        break;
-
-    default:
-        NS_RUNTIMEABORT("unknown Result code");
-        return false;
-    }
-
-    PrintErrorMessage(mChild, channelName, errorMsg);
-
-    mListener->OnProcessingError(code);
-
-    return false;
-}
-
-void
-AsyncChannel::ReportConnectionError(const char* channelName) const
-{
-    const char* errorMsg = nullptr;
-    switch (mChannelState) {
-    case ChannelClosed:
-        errorMsg = "Closed channel: cannot send/recv";
-        break;
-    case ChannelOpening:
-        errorMsg = "Opening channel: not yet ready for send/recv";
-        break;
-    case ChannelTimeout:
-        errorMsg = "Channel timeout: cannot send/recv";
-        break;
-    case ChannelClosing:
-        errorMsg = "Channel closing: too late to send/recv, messages will be lost";
-        break;
-    case ChannelError:
-        errorMsg = "Channel error: cannot send/recv";
-        break;
-
-    default:
-        NS_RUNTIMEABORT("unreached");
-    }
-
-    PrintErrorMessage(mChild, channelName, errorMsg);
-
-    mListener->OnProcessingError(MsgDropped);
-}
-
-void
-AsyncChannel::DispatchOnChannelConnected(int32_t peer_pid)
-{
-    AssertWorkerThread();
-    if (mListener)
-        mListener->OnChannelConnected(peer_pid);
-}
-
-bool
-AsyncChannel::Unsound_IsClosed() const
-{
-    if (!mLink) {
-        return true;
-    }
-
-    return mLink->Unsound_IsClosed();
-}
-
-uint32_t
-AsyncChannel::Unsound_NumQueuedMessages() const
-{
-    if (!mLink) {
-        return 0;
-    }
-
-    return mLink->Unsound_NumQueuedMessages();
-}
-
-//
-// The methods below run in the context of the IO thread
-//
-
-void
-AsyncChannel::ProcessLink::OnMessageReceived(const Message& msg)
-{
-    AssertIOThread();
-    NS_ASSERTION(mChan->mChannelState != ChannelError, "Shouldn't get here!");
-    MonitorAutoLock lock(*mChan->mMonitor);
-    mChan->OnMessageReceivedFromLink(msg);
-}
-
-void
-AsyncChannel::ProcessLink::OnEchoMessage(Message* msg)
-{
-    AssertIOThread();
-    OnMessageReceived(*msg);
-    delete msg;
-}
-
-void
-AsyncChannel::ProcessLink::OnChannelOpened()
-{
-    mChan->AssertLinkThread();
-    {
-        MonitorAutoLock lock(*mChan->mMonitor);
-
-        mExistingListener = mTransport->set_listener(this);
-#ifdef DEBUG
-        if (mExistingListener) {
-            queue<Message> pending;
-            mExistingListener->GetQueuedMessages(pending);
-            MOZ_ASSERT(pending.empty());
-        }
-#endif  // DEBUG
-
-        mChan->mChannelState = ChannelOpening;
-        lock.Notify();
-    }
-    /*assert*/mTransport->Connect();
-}
-
-void
-AsyncChannel::ProcessLink::OnTakeConnectedChannel()
-{
-    AssertIOThread();
-
-    queue<Message> pending;
-    {
-        MonitorAutoLock lock(*mChan->mMonitor);
-
-        mChan->mChannelState = ChannelConnected;
-
-        mExistingListener = mTransport->set_listener(this);
-        if (mExistingListener) {
-            mExistingListener->GetQueuedMessages(pending);
-        }
-        lock.Notify();
-    }
-
-    // Dispatch whatever messages the previous listener had queued up.
-    while (!pending.empty()) {
-        OnMessageReceived(pending.front());
-        pending.pop();
-    }
-}
-
-void
-AsyncChannel::ProcessLink::OnChannelConnected(int32_t peer_pid)
-{
-    AssertIOThread();
-
-    {
-        MonitorAutoLock lock(*mChan->mMonitor);
-        mChan->mChannelState = ChannelConnected;
-        mChan->mMonitor->Notify();
-    }
-
-    if(mExistingListener)
-        mExistingListener->OnChannelConnected(peer_pid);
-
-    mChan->mWorkerLoop->PostTask(
-        FROM_HERE, 
-        NewRunnableMethod(mChan, 
-                          &AsyncChannel::DispatchOnChannelConnected, 
-                          peer_pid));
-}
-
-void
-AsyncChannel::ProcessLink::OnChannelError()
-{
-    AssertIOThread();
-    MonitorAutoLock lock(*mChan->mMonitor);
-    mChan->OnChannelErrorFromLink();
-}
-
-void
-AsyncChannel::ProcessLink::OnCloseChannel()
-{
-    AssertIOThread();
-
-    mTransport->Close();
-
-    MonitorAutoLock lock(*mChan->mMonitor);
-    mChan->mChannelState = ChannelClosed;
-    mChan->mMonitor->Notify();
-}
-
-bool
-AsyncChannel::ProcessLink::Unsound_IsClosed() const
-{
-    return mTransport->Unsound_IsClosed();
-}
-
-uint32_t
-AsyncChannel::ProcessLink::Unsound_NumQueuedMessages() const
-{
-    return mTransport->Unsound_NumQueuedMessages();
-}
-
-//
-// The methods below run in the context of the link thread
-//
-
-void
-AsyncChannel::OnMessageReceivedFromLink(const Message& msg)
-{
-    AssertLinkThread();
-    mMonitor->AssertCurrentThreadOwns();
-
-    if (!MaybeInterceptSpecialIOMessage(msg))
-        // wake up the worker, there's work to do
-        mWorkerLoop->PostTask(
-            FROM_HERE,
-            NewRunnableMethod(this, &AsyncChannel::OnDispatchMessage, msg));
-}
-
-void
-AsyncChannel::OnChannelErrorFromLink()
-{
-    AssertLinkThread();
-    mMonitor->AssertCurrentThreadOwns();
-
-    if (ChannelClosing != mChannelState) {
-        mChannelState = ChannelError;
-        mMonitor->Notify();
-    }
-
-    PostErrorNotifyTask();
-}
-
-void
-AsyncChannel::CloseWithError()
-{
-    AssertWorkerThread();
-
-    MonitorAutoLock lock(*mMonitor);
-    if (ChannelConnected != mChannelState) {
-        return;
-    }
-    SynchronouslyClose();
-    mChannelState = ChannelError;
-    PostErrorNotifyTask();
-}
-
-void
-AsyncChannel::PostErrorNotifyTask()
-{
-    mMonitor->AssertCurrentThreadOwns();
-
-    if (mChannelErrorTask)
-        return;
-
-    // This must be the last code that runs on this thread!
-    mChannelErrorTask =
-        NewRunnableMethod(this, &AsyncChannel::OnNotifyMaybeChannelError);
-    mWorkerLoop->PostTask(FROM_HERE, mChannelErrorTask);
-}
-
-bool
-AsyncChannel::MaybeInterceptSpecialIOMessage(const Message& msg)
-{
-    AssertLinkThread();
-    mMonitor->AssertCurrentThreadOwns();
-
-    if (MSG_ROUTING_NONE == msg.routing_id()
-        && GOODBYE_MESSAGE_TYPE == msg.type()) {
-        ProcessGoodbyeMessage();
-        return true;
-    }
-    return false;
-}
-
-void
-AsyncChannel::ProcessGoodbyeMessage()
-{
-    AssertLinkThread();
-    mMonitor->AssertCurrentThreadOwns();
-
-    // TODO sort out Close() on this side racing with Close() on the
-    // other side
-    mChannelState = ChannelClosing;
-}
-
-
-} // namespace ipc
-} // namespace mozilla
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -76,16 +76,17 @@ MessageChannel::MessageChannel(MessageLi
 MessageChannel::~MessageChannel()
 {
     MOZ_COUNT_DTOR(ipc::MessageChannel);
     IPC_ASSERT(mCxxStackFrames.empty(), "mismatched CxxStackFrame ctor/dtors");
 #ifdef OS_WIN
     DebugOnly<BOOL> ok = CloseHandle(mEvent);
     MOZ_ASSERT(ok);
 #endif
+    Clear();
 }
 
 bool
 MessageChannel::Connected() const
 {
     mMonitor->AssertCurrentThreadOwns();
 
     // The transport layer allows us to send messages before
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -450,23 +450,26 @@ class MOZ_NONHEAP_CLASS Handle : public 
      * takes a |const T&| is not a GC hazard.
      */
     operator const T&() const { return get(); }
     T operator->() const { return get(); }
 
     bool operator!=(const T &other) const { return *ptr != other; }
     bool operator==(const T &other) const { return *ptr == other; }
 
+    /* Change this handle to point to the same rooted location RHS does. */
+    void repoint(const Handle &rhs) { ptr = rhs.address(); }
+
   private:
     Handle() {}
 
     const T *ptr;
 
-    template <typename S>
-    void operator=(S v) MOZ_DELETE;
+    template <typename S> void operator=(S) MOZ_DELETE;
+    void operator=(Handle) MOZ_DELETE;
 };
 
 /*
  * Similar to a handle, but the underlying storage can be changed. This is
  * useful for outparams.
  *
  * If you want to add additional methods to MutableHandle for a specific
  * specialization, define a MutableHandleBase<T> specialization containing
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -131,41 +131,41 @@ PrintBacktrace()
         } \
     } while (0)
 
 # else
 #  define JS_OOM_POSSIBLY_FAIL() do {} while(0)
 #  define JS_OOM_POSSIBLY_FAIL_REPORT(cx) do {} while(0)
 # endif /* DEBUG */
 
-static JS_INLINE void* js_malloc(size_t bytes)
+static inline void* js_malloc(size_t bytes)
 {
     JS_OOM_POSSIBLY_FAIL();
     return malloc(bytes);
 }
 
-static JS_INLINE void* js_calloc(size_t bytes)
+static inline void* js_calloc(size_t bytes)
 {
     JS_OOM_POSSIBLY_FAIL();
     return calloc(bytes, 1);
 }
 
-static JS_INLINE void* js_calloc(size_t nmemb, size_t size)
+static inline void* js_calloc(size_t nmemb, size_t size)
 {
     JS_OOM_POSSIBLY_FAIL();
     return calloc(nmemb, size);
 }
 
-static JS_INLINE void* js_realloc(void* p, size_t bytes)
+static inline void* js_realloc(void* p, size_t bytes)
 {
     JS_OOM_POSSIBLY_FAIL();
     return realloc(p, bytes);
 }
 
-static JS_INLINE void js_free(void* p)
+static inline void js_free(void* p)
 {
     free(p);
 }
 #endif/* JS_USE_CUSTOM_ALLOCATOR */
 
 /*
  * JS_ROTATE_LEFT32
  *
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -598,26 +598,21 @@ endif
 ifneq (,$(SHARED_LIBRARY))
 	$(SYSINSTALL) $(SHARED_LIBRARY) $(DESTDIR)$(libdir)
 endif
 ifneq (,$(IMPORT_LIBRARY))
 	$(SYSINSTALL) $(IMPORT_LIBRARY) $(DESTDIR)$(libdir)
 endif
 	$(MAKE) -C shell install
 
-# Extra dependencies and rules for auto-generated headers
-host_jskwgen.$(OBJ_SUFFIX): jsversion.h vm/Keywords.h
-
 # Use CURDIR to avoid finding a jsautokw.h in the source tree (from a
 # previous build?) via VPATH when we're building in a separate tree.
 $(CURDIR)/jsautokw.h: host_jskwgen$(HOST_BIN_SUFFIX)
 	./host_jskwgen$(HOST_BIN_SUFFIX) $@
 
-host_jsoplengen.$(OBJ_SUFFIX): jsopcode.tbl
-
 # Use CURDIR to avoid finding a jsautooplen.h in the source tree (from
 # a previous build?) via VPATH when we're building in a separate tree.
 $(CURDIR)/jsautooplen.h: host_jsoplengen$(HOST_BIN_SUFFIX)
 	./host_jsoplengen$(HOST_BIN_SUFFIX) $@
 
 # Force auto-header generation before compiling any source that may use them
 $(OBJS): $(CURDIR)/jsautokw.h $(CURDIR)/jsautooplen.h
 
--- a/js/src/build/autoconf/compiler-opts.m4
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -170,17 +170,17 @@ fi
 ])
 
 dnl A high level macro for selecting compiler options.
 AC_DEFUN([MOZ_COMPILER_OPTS],
 [
   if test "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
     dnl Don't enable on pymake, because of bug 918652. Bug 912979 is an annoyance
     dnl with pymake, too.
-    MOZ_PSEUDO_DERECURSE=no-pymake,no-skip
+    MOZ_PSEUDO_DERECURSE=no-pymake
   fi
 
   MOZ_DEBUGGING_OPTS
   MOZ_RTTI
 if test "$CLANG_CXX"; then
     ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
     ## returned by C functions. This is possible because we use knowledge about the ABI
     ## to typedef it to a C type with the same layout when the headers are included
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -24,16 +24,91 @@ topsrcdir	= $(DEPTH)
 endif
 
 ifndef INCLUDED_AUTOCONF_MK
 include $(DEPTH)/config/autoconf.mk
 endif
 
 -include $(DEPTH)/.mozconfig.mk
 
+# Integrate with mozbuild-generated make files. We first verify that no
+# variables provided by the automatically generated .mk files are
+# present. If they are, this is a violation of the separation of
+# responsibility between Makefile.in and mozbuild files.
+_MOZBUILD_EXTERNAL_VARIABLES := \
+  ANDROID_GENERATED_RESFILES \
+  ANDROID_RESFILES \
+  CMMSRCS \
+  CPP_UNIT_TESTS \
+  DIRS \
+  EXTRA_PP_COMPONENTS \
+  EXTRA_PP_JS_MODULES \
+  GTEST_CMMSRCS \
+  GTEST_CPPSRCS \
+  GTEST_CSRCS \
+  HOST_CSRCS \
+  HOST_LIBRARY_NAME \
+  IS_COMPONENT \
+  JS_MODULES_PATH \
+  LIBRARY_NAME \
+  LIBXUL_LIBRARY \
+  MODULE \
+  MSVC_ENABLE_PGO \
+  NO_DIST_INSTALL \
+  PARALLEL_DIRS \
+  SDK_HEADERS \
+  SIMPLE_PROGRAMS \
+  TEST_DIRS \
+  TIERS \
+  TOOL_DIRS \
+  XPCSHELL_TESTS \
+  XPIDL_MODULE \
+  $(NULL)
+
+_DEPRECATED_VARIABLES := \
+  MOCHITEST_FILES_PARTS \
+  MOCHITEST_BROWSER_FILES_PARTS \
+  $(NULL)
+
+ifndef EXTERNALLY_MANAGED_MAKE_FILE
+# Using $(firstword) may not be perfect. But it should be good enough for most
+# scenarios.
+_current_makefile = $(CURDIR)/$(firstword $(MAKEFILE_LIST))
+
+$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
+    $(error Variable $(var) is defined in $(_current_makefile). It should only be defined in moz.build files),\
+    ))
+
+$(foreach var,$(_DEPRECATED_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
+    $(error Variable $(var) is defined in $(_current_makefile). This variable has been deprecated. It does nothing. It must be removed in order to build)\
+    ))
+
+# Import the automatically generated backend file. If this file doesn't exist,
+# the backend hasn't been properly configured. We want this to be a fatal
+# error, hence not using "-include".
+ifndef STANDALONE_MAKEFILE
+GLOBAL_DEPS += backend.mk
+include backend.mk
+endif
+
+# Freeze the values specified by moz.build to catch them if they fail.
+
+$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
+$(foreach var,$(_DEPRECATED_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
+
+CHECK_MOZBUILD_VARIABLES = $(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES), \
+  $(if $(subst $($(var)_FROZEN),,'$($(var))'), \
+	  $(error Variable $(var) is defined in $(_current_makefile). It should only be defined in moz.build files),\
+  )) $(foreach var,$(_DEPRECATED_VARIABLES), \
+	$(if $(subst $($(var)_FROZEN),,'$($(var))'), \
+    $(error Variable $(var) is defined in $(_current_makefile). This variable has been deprecated. It does nothing. It must be removed in order to build),\
+    ))
+
+endif
+
 space = $(NULL) $(NULL)
 
 # Include defs.mk files that can be found in $(srcdir)/$(DEPTH),
 # $(srcdir)/$(DEPTH-1), $(srcdir)/$(DEPTH-2), etc., and $(srcdir)
 # where $(DEPTH-1) is one level less of depth, $(DEPTH-2), two, etc.
 # i.e. for DEPTH=../../.., DEPTH-1 is ../.. and DEPTH-2 is ..
 # These defs.mk files are used to define variables in a directory
 # and all its subdirectories, recursively.
@@ -69,22 +144,26 @@ include $(topsrcdir)/config/makefiles/fu
 endif
 
 RM = rm -f
 
 # LIBXUL_DIST is not defined under js/src, thus we make it mean DIST there.
 LIBXUL_DIST ?= $(DIST)
 
 # FINAL_TARGET specifies the location into which we copy end-user-shipped
-# build products (typelibs, components, chrome).
+# build products (typelibs, components, chrome). It may already be specified by
+# a moz.build file.
 #
 # If XPI_NAME is set, the files will be shipped to $(DIST)/xpi-stage/$(XPI_NAME)
 # instead of $(DIST)/bin. In both cases, if DIST_SUBDIR is set, the files will be
 # shipped to a $(DIST_SUBDIR) subdirectory.
-FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
+FINAL_TARGET ?= $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
+# Override the stored value for the check to make sure that the variable is not
+# redefined in the Makefile.in value.
+FINAL_TARGET_FROZEN := '$(FINAL_TARGET)'
 
 ifdef XPI_NAME
 DEFINES += -DXPI_NAME=$(XPI_NAME)
 endif
 
 # The VERSION_NUMBER is suffixed onto the end of the DLLs we ship.
 VERSION_NUMBER		= 50
 
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -11,82 +11,19 @@ ifndef topsrcdir
 endif
 
 # Define an include-at-most-once flag
 ifdef INCLUDED_RULES_MK
 $(error Do not include rules.mk twice!)
 endif
 INCLUDED_RULES_MK = 1
 
-# Integrate with mozbuild-generated make files. We first verify that no
-# variables provided by the automatically generated .mk files are
-# present. If they are, this is a violation of the separation of
-# responsibility between Makefile.in and mozbuild files.
-_MOZBUILD_EXTERNAL_VARIABLES := \
-  ANDROID_GENERATED_RESFILES \
-  ANDROID_RESFILES \
-  CMMSRCS \
-  CPP_UNIT_TESTS \
-  DIRS \
-  EXTRA_PP_COMPONENTS \
-  EXTRA_PP_JS_MODULES \
-  GTEST_CMMSRCS \
-  GTEST_CPPSRCS \
-  GTEST_CSRCS \
-  HOST_CSRCS \
-  HOST_LIBRARY_NAME \
-  IS_COMPONENT \
-  JS_MODULES_PATH \
-  LIBRARY_NAME \
-  LIBXUL_LIBRARY \
-  MODULE \
-  MSVC_ENABLE_PGO \
-  NO_DIST_INSTALL \
-  PARALLEL_DIRS \
-  SDK_HEADERS \
-  SIMPLE_PROGRAMS \
-  TEST_DIRS \
-  TIERS \
-  TOOL_DIRS \
-  XPCSHELL_TESTS \
-  XPIDL_MODULE \
-  $(NULL)
-
-_DEPRECATED_VARIABLES := \
-  XPIDL_FLAGS \
-  MOCHITEST_FILES_PARTS \
-  MOCHITEST_BROWSER_FILES_PARTS \
-  MOCHITEST_WEBAPPRT_CHROME_FILES \
-  $(NULL)
-
-ifndef EXTERNALLY_MANAGED_MAKE_FILE
-# Using $(firstword) may not be perfect. But it should be good enough for most
-# scenarios.
-_current_makefile = $(CURDIR)/$(firstword $(MAKEFILE_LIST))
-
-$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
-    $(error Variable $(var) is defined in $(_current_makefile). It should only be defined in moz.build files),\
-    ))
-
-$(foreach var,$(_DEPRECATED_VARIABLES),$(if $(filter file override,$(subst $(NULL) ,_,$(origin $(var)))),\
-    $(error Variable $(var) is defined in $(_current_makefile). This variable has been deprecated. It does nothing. It must be removed in order to build)\
-    ))
-
-ifneq (,$(XPIDLSRCS)$(SDK_XPIDLSRCS))
-    $(error XPIDLSRCS and SDK_XPIDLSRCS have been merged and moved to moz.build files as the XPIDL_SOURCES variable. You must move these variables out of $(_current_makefile))
-endif
-
-# Import the automatically generated backend file. If this file doesn't exist,
-# the backend hasn't been properly configured. We want this to be a fatal
-# error, hence not using "-include".
-ifndef STANDALONE_MAKEFILE
-GLOBAL_DEPS += backend.mk
-include backend.mk
-endif
-endif
+# Make sure that anything that needs to be defined in moz.build wasn't
+# overwritten.
+_eval_for_side_effects := $(CHECK_MOZBUILD_VARIABLES)
 
 ifndef MOZILLA_DIR
 MOZILLA_DIR = $(topsrcdir)
 endif
 
 ifndef INCLUDED_CONFIG_MK
 include $(topsrcdir)/config/config.mk
 endif
@@ -377,22 +314,22 @@ CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUF
 CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
 ASOBJS = $(notdir $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
 ifndef OBJS
 _OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
 OBJS = $(strip $(_OBJS))
 endif
 
 HOST_COBJS = $(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX)))
-HOST_CCOBJS = $(addprefix host_,$(patsubst %.cc,%.$(OBJ_SUFFIX),$(filter %.cc,$(HOST_CPPSRCS))))
-HOST_CPPOBJS = $(addprefix host_,$(patsubst %.cpp,%.$(OBJ_SUFFIX),$(filter %.cpp,$(HOST_CPPSRCS))))
+# HOST_CPPOBJS can have different extensions (eg: .cpp, .cc)
+HOST_CPPOBJS = $(addprefix host_,$(addsuffix .$(OBJ_SUFFIX),$(basename $(HOST_CPPSRCS))))
 HOST_CMOBJS = $(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX)))
 HOST_CMMOBJS = $(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
 ifndef HOST_OBJS
-_HOST_OBJS = $(HOST_COBJS) $(HOST_CCOBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
+_HOST_OBJS = $(HOST_COBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
 HOST_OBJS = $(strip $(_HOST_OBJS))
 endif
 
 ALL_TRASH = \
 	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
 	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
 	$(OBJS:.$(OBJ_SUFFIX)=.i) $(OBJS:.$(OBJ_SUFFIX)=.i_o) \
 	$(HOST_PROGOBJS) $(HOST_OBJS) $(IMPORT_LIBRARY) $(DEF_FILE)\
@@ -874,36 +811,36 @@ ifdef ENABLE_STRIP
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
 
 $(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
 	$(REPORT_BUILD)
 ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		if test -f "$(srcdir)/$@.manifest"; then \
 			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		else \
 			echo "Embedding manifest from $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		fi; \
 	elif test -f "$(srcdir)/$@.manifest"; then \
 		echo "Embedding manifest from $(srcdir)/$@.manifest"; \
 		mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" -OUTPUTRESOURCE:$@\;1; \
 	fi
 endif	# MSVC with manifest tool
 else
 ifeq ($(HOST_CPP_PROG_LINK),1)
-	$(HOST_CXX) -o $@ $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CXX) -o $@ $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 else
-	$(HOST_CC) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CC) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 endif # HOST_CPP_PROG_LINK
 endif
 
 #
 # This is an attempt to support generation of multiple binaries
 # in one directory, it assumes everything to compile Foo is in
 # Foo.o (from either Foo.c or Foo.cpp).
 #
@@ -930,22 +867,22 @@ ifdef ENABLE_STRIP
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
 
 $(HOST_SIMPLE_PROGRAMS): host_%$(HOST_BIN_SUFFIX): host_%.$(OBJ_SUFFIX) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
 	$(REPORT_BUILD)
 ifeq (WINNT_,$(HOST_OS_ARCH)_$(GNU_CC))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 else
 ifneq (,$(HOST_CPPSRCS)$(USE_HOST_CXX))
-	$(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXXFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXXFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 else
-	$(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_CFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+	$(EXPAND_LIBS_EXEC) --uselist -- $(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_CFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
 endif
 endif
 
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 OBJS += $(DTRACE_PROBE_OBJ)
 endif
 
@@ -988,17 +925,17 @@ ifeq ($(OS_ARCH),OS2)
 	$(RM) $@
 	$(IMPLIB) $@ $^
 	$(RANLIB) $@
 endif # OS/2
 
 $(HOST_LIBRARY): $(HOST_OBJS) Makefile
 	$(REPORT_BUILD)
 	$(RM) $@
-	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
+	$(EXPAND_LIBS_EXEC) --extract -- $(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
 	$(HOST_RANLIB) $@
 
 ifdef HAVE_DTRACE
 ifndef XP_MACOSX
 ifdef DTRACE_PROBE_OBJ
 ifndef DTRACE_LIB_DEPENDENT
 NON_DTRACE_OBJS := $(filter-out $(DTRACE_PROBE_OBJ),$(OBJS))
 $(DTRACE_PROBE_OBJ): $(NON_DTRACE_OBJS)
@@ -1074,37 +1011,34 @@ endif # Sun Studio on Solaris
 # relative path. This macro adds the dependency obj: src for each source file.
 # This dependency must be first for the $< flag to work correctly, and the
 # rules that have commands for these targets must not list any other
 # prerequisites, or they will override the $< variable.
 define src_objdep
 $(basename $(notdir $1)).$(OBJ_SUFFIX): $1 $(call mkdir_deps,$(MDDEPDIR))
 endef
 $(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f))))
+$(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval host_$(call src_objdep,$(f))))
 
 $(OBJS) $(HOST_OBJS) $(PROGOBJS) $(HOST_PROGOBJS): $(GLOBAL_DEPS)
 
 # Rules for building native targets must come first because of the host_ prefix
-$(HOST_COBJS): host_%.$(OBJ_SUFFIX): %.c
+$(HOST_COBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
-$(HOST_CPPOBJS): host_%.$(OBJ_SUFFIX): %.cpp
+$(HOST_CPPOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
-$(HOST_CCOBJS): host_%.$(OBJ_SUFFIX): %.cc
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-$(HOST_CMOBJS): host_%.$(OBJ_SUFFIX): %.m
+$(HOST_CMOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
-$(HOST_CMMOBJS): host_%.$(OBJ_SUFFIX): %.mm
+$(HOST_CMMOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 $(COBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -3941,16 +3941,24 @@ COMPILE_CFLAGS=`echo \
 	$_DEPEND_CFLAGS \
     $COMPILE_CFLAGS`
 
 COMPILE_CXXFLAGS=`echo \
     $_DEFINES_CXXFLAGS \
 	$_DEPEND_CFLAGS \
     $COMPILE_CXXFLAGS`
 
+HOST_CFLAGS=`echo \
+    $HOST_CFLAGS \
+    $_DEPEND_CFLAGS`
+
+HOST_CXXFLAGS=`echo \
+    $HOST_CXXFLAGS \
+    $_DEPEND_CFLAGS`
+
 AC_SUBST(NSPR_CFLAGS)
 AC_SUBST(NSPR_LIBS)
 AC_SUBST(MOZ_NATIVE_NSPR)
 
 if test -n "$MOZ_NUWA_PROCESS"; then
     AC_DEFINE(MOZ_NUWA_PROCESS)
 fi
 
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.h
@@ -15,52 +15,54 @@ namespace js {
 namespace gc {
 
 void
 MarkRuntime(JSTracer *trc, bool useSavedRoots = false);
 
 void
 BufferGrayRoots(GCMarker *gcmarker);
 
-class AutoCopyFreeListToArenas {
+class AutoCopyFreeListToArenas
+{
     JSRuntime *runtime;
 
   public:
     AutoCopyFreeListToArenas(JSRuntime *rt);
     ~AutoCopyFreeListToArenas();
 };
 
 struct AutoFinishGC
 {
     AutoFinishGC(JSRuntime *rt);
 };
 
 /*
  * This class should be used by any code that needs to exclusive access to the
  * heap in order to trace through it...
  */
-class AutoTraceSession {
+class AutoTraceSession
+{
   public:
     AutoTraceSession(JSRuntime *rt, HeapState state = Tracing);
     ~AutoTraceSession();
 
   protected:
     JSRuntime *runtime;
 
   private:
     AutoTraceSession(const AutoTraceSession&) MOZ_DELETE;
     void operator=(const AutoTraceSession&) MOZ_DELETE;
 
     js::HeapState prevState;
-    AutoPauseWorkersForGC pause;
 };
 
 struct AutoPrepareForTracing
 {
     AutoFinishGC finish;
+    AutoPauseWorkersForTracing pause;
     AutoTraceSession session;
     AutoCopyFreeListToArenas copy;
 
     AutoPrepareForTracing(JSRuntime *rt);
 };
 
 class IncrementalSafety
 {
--- a/js/src/gc/Iteration.cpp
+++ b/js/src/gc/Iteration.cpp
@@ -99,13 +99,14 @@ js::IterateGrayObjects(Zone *zone, GCThi
 }
 
 JS_PUBLIC_API(void)
 JS_IterateCompartments(JSRuntime *rt, void *data,
                        JSIterateCompartmentCallback compartmentCallback)
 {
     JS_ASSERT(!rt->isHeapBusy());
 
+    AutoPauseWorkersForTracing pause(rt);
     AutoTraceSession session(rt);
 
     for (CompartmentsIter c(rt); !c.done(); c.next())
         (*compartmentCallback)(rt, data, c);
 }
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/bug927389.js
@@ -0,0 +1,6 @@
+(function() {
+    "use asm"
+    function f() {
+        +~~1.1
+    }
+})()
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/bug928450.js
@@ -0,0 +1,6 @@
+(function() {
+    "use asm"
+    function f() {
+        i((1.5 != 2.) ? 3 : 0)
+    }
+})()
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug927389.js
@@ -0,0 +1,4 @@
+(function () {
+    var x = 0 || 1.1;
+    x >> x;
+})();
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -1319,17 +1319,17 @@ class MOZ_STACK_CLASS ModuleCompiler
         JS_ASSERT(errorOffset_ == UINT32_MAX);
         JS_ASSERT(str);
         errorOffset_ = offset;
         errorString_ = strdup(str);
         return false;
     }
 
     bool fail(ParseNode *pn, const char *str) {
-        return failOffset(pn ? pn->pn_pos.begin : parser_.tokenStream.currentToken().pos.end, str);
+        return failOffset(pn ? pn->pn_pos.begin : parser_.tokenStream.peekTokenPos().begin, str);
     }
 
     bool failfVA(ParseNode *pn, const char *fmt, va_list ap) {
         JS_ASSERT(!errorString_);
         JS_ASSERT(errorOffset_ == UINT32_MAX);
         JS_ASSERT(fmt);
         errorOffset_ = pn ? pn->pn_pos.begin : parser_.tokenStream.currentToken().pos.end;
         errorString_ = JS_vsmprintf(fmt, ap);
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -6010,17 +6010,17 @@ DoGetPropFallback(JSContext *cx, Baselin
     if (!obj)
         return false;
 
     if (!JSObject::getGeneric(cx, obj, obj, id, res))
         return false;
 
 #if JS_HAS_NO_SUCH_METHOD
     // Handle objects with __noSuchMethod__.
-    if (op == JSOP_CALLPROP && JS_UNLIKELY(res.isPrimitive()) && val.isObject()) {
+    if (op == JSOP_CALLPROP && JS_UNLIKELY(res.isUndefined()) && val.isObject()) {
         if (!OnUnknownMethod(cx, obj, IdToValue(id), res))
             return false;
     }
 #endif
 
     types::TypeScript::Monitor(cx, script, pc, res);
 
     // Add a type monitor stub for the resulting value.
--- a/js/src/jit/C1Spewer.cpp
+++ b/js/src/jit/C1Spewer.cpp
@@ -26,17 +26,17 @@ C1Spewer::init(const char *path)
 
 void
 C1Spewer::beginFunction(MIRGraph *graph, HandleScript script)
 {
     if (!spewout_)
         return;
 
     this->graph  = graph;
-    this->script = script;
+    this->script.repoint(script);
 
     fprintf(spewout_, "begin_compilation\n");
     if (script) {
         fprintf(spewout_, "  name \"%s:%d\"\n", script->filename(), script->lineno);
         fprintf(spewout_, "  method \"%s:%d\"\n", script->filename(), script->lineno);
     } else {
         fprintf(spewout_, "  name \"asm.js compilation\"\n");
         fprintf(spewout_, "  method \"asm.js compilation\"\n");
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1581,16 +1581,19 @@ IonCompile(JSContext *cx, JSScript *scri
 
     if (!cx->compartment()->ensureIonCompartmentExists(cx))
         return AbortReason_Alloc;
 
     if (!cx->compartment()->ionCompartment()->ensureIonStubsExist(cx))
         return AbortReason_Alloc;
 
     MIRGraph *graph = alloc->new_<MIRGraph>(temp);
+    if (!graph)
+        return AbortReason_Alloc;
+
     CompileInfo *info = alloc->new_<CompileInfo>(script, script->function(), osrPc, constructing,
                                                  executionMode);
     if (!info)
         return AbortReason_Alloc;
 
     BaselineInspector inspector(cx, script);
 
     AutoFlushCache afc("IonCompile", cx->runtime()->ionRuntime());
--- a/js/src/jit/IonAllocPolicy.h
+++ b/js/src/jit/IonAllocPolicy.h
@@ -85,17 +85,18 @@ class AutoTempAllocatorRooter : private 
 class IonAllocPolicy
 {
   public:
     void *malloc_(size_t bytes) {
         return GetIonContext()->temp->allocate(bytes);
     }
     void *calloc_(size_t bytes) {
         void *p = GetIonContext()->temp->allocate(bytes);
-        memset(p, 0, bytes);
+        if (p)
+            memset(p, 0, bytes);
         return p;
     }
     void *realloc_(void *p, size_t oldBytes, size_t bytes) {
         void *n = malloc_(bytes);
         if (!n)
             return n;
         memcpy(n, p, Min(oldBytes, bytes));
         return n;
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1776,17 +1776,17 @@ GetPropertyIC::update(JSContext *cx, siz
         jsbytecode *pc;
         cache.getScriptedLocation(&script, &pc);
 
         // If the cache is idempotent, the property exists so we don't have to
         // call __noSuchMethod__.
 
 #if JS_HAS_NO_SUCH_METHOD
         // Handle objects with __noSuchMethod__.
-        if (JSOp(*pc) == JSOP_CALLPROP && JS_UNLIKELY(vp.isPrimitive())) {
+        if (JSOp(*pc) == JSOP_CALLPROP && JS_UNLIKELY(vp.isUndefined())) {
             if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
                 return false;
         }
 #endif
 
         // Monitor changes to cache entry.
         types::TypeScript::Monitor(cx, script, pc, vp);
     }
--- a/js/src/jit/IonSpewer.cpp
+++ b/js/src/jit/IonSpewer.cpp
@@ -156,17 +156,17 @@ IonSpewer::beginFunction(MIRGraph *graph
     if (!FilterContainsLocation(function)) {
         JS_ASSERT(!this->graph);
         // filter out logs during the compilation.
         filteredOutCompilations++;
         return;
     }
 
     this->graph = graph;
-    this->function = function;
+    this->function.repoint(function);
 
     c1Spewer.beginFunction(graph, function);
     jsonSpewer.beginFunction(function);
 }
 
 void
 IonSpewer::spewPass(const char *pass)
 {
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -384,24 +384,25 @@ Range::intersect(const Range *lhs, const
     // possible that we will have computed a newExponent that's more precise
     // than our newLower and newUpper. This is unusual, so we handle it here
     // instead of in optimize().
     //
     // For example, when the floating-point range has an actual maximum value
     // of 1.5, it may have a range like [0,2] and the max_exponent may be zero.
     // When intersecting such a range with an integer range, the fractional part
     // of the range is dropped, but the max exponent of 0 remains valid.
-    if (lhs->canHaveFractionalPart_ != rhs->canHaveFractionalPart_ &&
-        newExponent < MaxInt32Exponent)
-    {
-        // pow(2, newExponent+1)-1 to compute the maximum value for newExponent.
-        int32_t limit = (uint32_t(1) << (newExponent + 1)) - 1;
-        if (limit != INT32_MIN) {
-            newUpper = Min(newUpper, limit);
-            newLower = Max(newLower, -limit);
+    if (lhs->canHaveFractionalPart_ != rhs->canHaveFractionalPart_) {
+        refineInt32BoundsByExponent(newExponent, &newLower, &newUpper);
+
+        // If we're intersecting two ranges that don't overlap, this could also
+        // push the bounds past each other, since the actual intersection is
+        // the empty set.
+        if (newLower > newUpper) {
+            *emptyRange = true;
+            return nullptr;
         }
     }
 
     return new Range(newLower, newHasInt32LowerBound, newUpper, newHasInt32UpperBound,
                      newFractional, newExponent);
 }
 
 void
@@ -1936,20 +1937,27 @@ Range::clampToInt32()
     int32_t l = hasInt32LowerBound() ? lower() : JSVAL_INT_MIN;
     int32_t h = hasInt32UpperBound() ? upper() : JSVAL_INT_MAX;
     setInt32(l, h);
 }
 
 void
 Range::wrapAroundToInt32()
 {
-    if (!hasInt32Bounds())
+    if (!hasInt32Bounds()) {
         setInt32(JSVAL_INT_MIN, JSVAL_INT_MAX);
-    else if (canHaveFractionalPart())
+    } else if (canHaveFractionalPart()) {
         canHaveFractionalPart_ = false;
+
+        // Clearing the fractional field may provide an opportunity to refine
+        // lower_ or upper_.
+        refineInt32BoundsByExponent(max_exponent_, &lower_, &upper_);
+
+        assertInvariants();
+    }
 }
 
 void
 Range::wrapAroundToShiftCount()
 {
     wrapAroundToInt32();
     if (lower() < 0 || upper() >= 32)
         setInt32(0, 31);
--- a/js/src/jit/RangeAnalysis.h
+++ b/js/src/jit/RangeAnalysis.h
@@ -249,16 +249,34 @@ class Range : public TempObject {
     uint16_t exponentImpliedByInt32Bounds() const {
          // The number of bits needed to encode |max| is the power of 2 plus one.
          uint32_t max = Max(mozilla::Abs(lower()), mozilla::Abs(upper()));
          uint16_t result = mozilla::FloorLog2(max);
          JS_ASSERT(result == (max == 0 ? 0 : mozilla::ExponentComponent(double(max))));
          return result;
     }
 
+    // When converting a range which contains fractional values to a range
+    // containing only integers, the old max_exponent_ value may imply a better
+    // lower and/or upper bound than was previously available, because they no
+    // longer need to be conservative about fractional offsets and the ends of
+    // the range.
+    //
+    // Given an exponent value and pointers to the lower and upper bound values,
+    // this function refines the lower and upper bound values to the tighest
+    // bound for integer values implied by the exponent.
+    static void refineInt32BoundsByExponent(uint16_t e, int32_t *l, int32_t *h) {
+       if (e < MaxInt32Exponent) {
+           // pow(2, max_exponent_+1)-1 to compute a maximum absolute value.
+           int32_t limit = (uint32_t(1) << (e + 1)) - 1;
+           *h = Min(*h, limit);
+           *l = Max(*l, -limit);
+       }
+    }
+
     // If the value of any of the fields implies a stronger possible value for
     // any other field, update that field to the stronger value. The range must
     // be completely valid before and it is guaranteed to be kept valid.
     void optimize() {
         assertInvariants();
 
         if (hasInt32Bounds()) {
             // Examine lower() and upper(), and if they imply a better exponent
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4461,17 +4461,17 @@ JS::Compile(JSContext *cx, HandleObject 
 }
 
 JSScript *
 JS::Compile(JSContext *cx, HandleObject obj, CompileOptions options, const char *filename)
 {
     AutoFile file;
     if (!file.open(cx, filename))
         return nullptr;
-    options = options.setFileAndLine(filename, 1);
+    options.setFileAndLine(filename, 1);
     JSScript *script = Compile(cx, obj, options, file.fp());
     return script;
 }
 
 JS_PUBLIC_API(bool)
 JS::CanCompileOffThread(JSContext *cx, const CompileOptions &options)
 {
 #ifdef JS_WORKER_THREADS
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3464,17 +3464,17 @@ class JS_PUBLIC_API(CompileOptions)
     CompileOptions &setOriginPrincipals(JSPrincipals *p) { originPrincipals_ = p; return *this; }
     CompileOptions &setVersion(JSVersion v) { version = v; versionSet = true; return *this; }
     CompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
     CompileOptions &setFileAndLine(const char *f, unsigned l) {
         filename = f; lineno = l; return *this;
     }
     CompileOptions &setSourceMapURL(const jschar *s) { sourceMapURL = s; return *this; }
     CompileOptions &setColumn(unsigned c) { column = c; return *this; }
-    CompileOptions &setElement(Handle<JSObject*> e) { element = e; return *this; }
+    CompileOptions &setElement(Handle<JSObject*> e) { element.repoint(e); return *this; }
     CompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
     CompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
     CompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
     CompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
     CompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
     CompileOptions &setSourcePolicy(SourcePolicy sp) { sourcePolicy = sp; return *this; }
 };
 
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -64,17 +64,17 @@ js_GetLocalizedErrorMessage(js::Exclusiv
  * cx must be in the same compartment as scope. errobj may be in a different
  * compartment, but it must be an Error object (not a wrapper of one) and it
  * must not be one of the prototype objects created by js_InitExceptionClasses
  * (errobj->getPrivate() must not be nullptr).
  */
 extern JSObject *
 js_CopyErrorObject(JSContext *cx, js::HandleObject errobj, js::HandleObject scope);
 
-static JS_INLINE JSProtoKey
+static inline JSProtoKey
 GetExceptionProtoKey(int exn)
 {
     JS_ASSERT(JSEXN_ERR <= exn);
     JS_ASSERT(exn < JSEXN_LIMIT);
     return JSProtoKey(JSProto_Error + exn);
 }
 
 #endif /* jsexn_h */
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -4071,44 +4071,50 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocat
     FinishMarkingValidation(rt);
 
     rt->gcLastGCTime = PRMJ_Now();
 }
 
 namespace {
 
 /* ...while this class is to be used only for garbage collection. */
-class AutoGCSession : AutoTraceSession {
+class AutoGCSession
+{
+    JSRuntime *runtime;
+    AutoPauseWorkersForTracing pause;
+    AutoTraceSession session;
+
   public:
     explicit AutoGCSession(JSRuntime *rt);
     ~AutoGCSession();
 };
 
 } /* anonymous namespace */
 
 /* Start a new heap session. */
 AutoTraceSession::AutoTraceSession(JSRuntime *rt, js::HeapState heapState)
   : runtime(rt),
-    prevState(rt->heapState),
-    pause(rt)
+    prevState(rt->heapState)
 {
     JS_ASSERT(!rt->noGCOrAllocationCheck);
     JS_ASSERT(!rt->isHeapBusy());
     JS_ASSERT(heapState != Idle);
     rt->heapState = heapState;
 }
 
 AutoTraceSession::~AutoTraceSession()
 {
     JS_ASSERT(runtime->isHeapBusy());
     runtime->heapState = prevState;
 }
 
 AutoGCSession::AutoGCSession(JSRuntime *rt)
-  : AutoTraceSession(rt, MajorCollecting)
+  : runtime(rt),
+    pause(rt),
+    session(rt, MajorCollecting)
 {
     runtime->gcIsNeeded = false;
     runtime->gcInterFrameGC = true;
 
     runtime->gcNumber++;
 
 #ifdef DEBUG
     // Threads with an exclusive context should never pause while they are in
@@ -4783,16 +4789,17 @@ AutoFinishGC::AutoFinishGC(JSRuntime *rt
         JS::FinishIncrementalGC(rt, JS::gcreason::API);
     }
 
     gc::FinishBackgroundFinalize(rt);
 }
 
 AutoPrepareForTracing::AutoPrepareForTracing(JSRuntime *rt)
   : finish(rt),
+    pause(rt),
     session(rt),
     copy(rt)
 {
     RecordNativeStackTopForGC(rt);
 }
 
 JSCompartment *
 js::NewCompartment(JSContext *cx, Zone *zone, JSPrincipals *principals,
--- a/js/src/jstypes.h
+++ b/js/src/jstypes.h
@@ -84,20 +84,16 @@
 #define JS_FASTCALL __fastcall
 #elif defined(__GNUC__) && defined(__i386__)
 #define JS_FASTCALL __attribute__((fastcall))
 #else
 #define JS_FASTCALL
 #define JS_NO_FASTCALL
 #endif
 
-#ifndef JS_INLINE
-#define JS_INLINE MOZ_INLINE
-#endif
-
 #ifndef JS_ALWAYS_INLINE
 #define JS_ALWAYS_INLINE MOZ_ALWAYS_INLINE
 #endif
 
 #ifndef JS_NEVER_INLINE
 #define JS_NEVER_INLINE MOZ_NEVER_INLINE
 #endif
 
--- a/js/src/jsworkers.cpp
+++ b/js/src/jsworkers.cpp
@@ -922,17 +922,18 @@ WorkerThread::threadLoop()
             handleParseWorkload(state);
         else if (state.canStartCompressionTask())
             handleCompressionWorkload(state);
         else
             MOZ_ASSUME_UNREACHABLE("No task to perform");
     }
 }
 
-AutoPauseWorkersForGC::AutoPauseWorkersForGC(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+AutoPauseWorkersForTracing::AutoPauseWorkersForTracing(JSRuntime *rt
+                                                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : runtime(rt), needsUnpause(false), oldExclusiveThreadsPaused(rt->exclusiveThreadsPaused)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
     rt->exclusiveThreadsPaused = true;
 
     if (!runtime->workerThreadState)
         return;
@@ -940,33 +941,33 @@ AutoPauseWorkersForGC::AutoPauseWorkersF
     JS_ASSERT(CurrentThreadCanAccessRuntime(runtime));
 
     WorkerThreadState &state = *runtime->workerThreadState;
     if (!state.numThreads)
         return;
 
     AutoLockWorkerThreadState lock(state);
 
-    // Tolerate reentrant use of AutoPauseWorkersForGC.
+    // Tolerate reentrant use of AutoPauseWorkersForTracing.
     if (state.shouldPause) {
         JS_ASSERT(state.numPaused == state.numThreads);
         return;
     }
 
     needsUnpause = true;
 
     state.shouldPause = 1;
 
     while (state.numPaused != state.numThreads) {
         state.notifyAll(WorkerThreadState::PRODUCER);
         state.wait(WorkerThreadState::CONSUMER);
     }
 }
 
-AutoPauseWorkersForGC::~AutoPauseWorkersForGC()
+AutoPauseWorkersForTracing::~AutoPauseWorkersForTracing()
 {
     runtime->exclusiveThreadsPaused = oldExclusiveThreadsPaused;
 
     if (!needsUnpause)
         return;
 
     WorkerThreadState &state = *runtime->workerThreadState;
     AutoLockWorkerThreadState lock(state);
@@ -981,17 +982,17 @@ AutoPauseCurrentWorkerThread::AutoPauseC
                                                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : cx(cx)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
     // If the current thread is a worker thread, treat it as paused while
     // the caller is waiting for another worker thread to complete. Otherwise
     // we will not wake up and mark this as paused due to the loop in
-    // AutoPauseWorkersForGC.
+    // AutoPauseWorkersForTracing.
     if (cx->workerThread()) {
         WorkerThreadState &state = *cx->workerThreadState();
         JS_ASSERT(state.isLocked());
 
         state.numPaused++;
         if (state.numPaused == state.numThreads)
             state.notifyAll(WorkerThreadState::CONSUMER);
     }
@@ -1081,22 +1082,23 @@ SourceCompressionTask::complete()
 
 const jschar *
 ScriptSource::getOffThreadCompressionChars(ExclusiveContext *cx)
 {
     JS_ASSERT(ready());
     return nullptr;
 }
 
-AutoPauseWorkersForGC::AutoPauseWorkersForGC(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+AutoPauseWorkersForTracing::AutoPauseWorkersForTracing(JSRuntime *rt
+                                                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 }
 
-AutoPauseWorkersForGC::~AutoPauseWorkersForGC()
+AutoPauseWorkersForTracing::~AutoPauseWorkersForTracing()
 {
 }
 
 AutoPauseCurrentWorkerThread::AutoPauseCurrentWorkerThread(ExclusiveContext *cx
                                                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 }
--- a/js/src/jsworkers.h
+++ b/js/src/jsworkers.h
@@ -323,28 +323,28 @@ WorkerThread::maybePause()
         AutoLockWorkerThreadState lock(*runtime->workerThreadState);
         pause();
     }
 }
 
 #endif // JS_WORKER_THREADS
 
 /* Pause any threads that are running jobs off thread during GC activity. */
-class AutoPauseWorkersForGC
+class AutoPauseWorkersForTracing
 {
 #ifdef JS_WORKER_THREADS
     JSRuntime *runtime;
     bool needsUnpause;
     mozilla::DebugOnly<bool> oldExclusiveThreadsPaused;
 #endif
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 
   public:
-    AutoPauseWorkersForGC(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
-    ~AutoPauseWorkersForGC();
+    AutoPauseWorkersForTracing(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    ~AutoPauseWorkersForTracing();
 };
 
 /*
  * If the current thread is a worker thread, treat it as paused during this
  * class's lifetime. This should be used at any time the current thread is
  * waiting for a worker to complete.
  */
 class AutoPauseCurrentWorkerThread
--- a/js/src/tests/js1_5/extensions/regress-564577.js
+++ b/js/src/tests/js1_5/extensions/regress-564577.js
@@ -38,28 +38,40 @@ function test()
   };
 
   status = summary + ' ' + inSection(1) + ' ';
   actual = o.aaa();
   expect = 'aaa() undefined';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(2) + ' ';
-  actual = o.bbb();
-  expect = 'bbb() null';
+  try {
+    actual = o.bbb();
+  } catch(e) {
+    actual = e + '';
+  }
+  expect = 'TypeError: o.bbb is not a function';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(3) + ' ';
-  actual = o.ccc();
-  expect = 'ccc() 77';
+  try {
+    actual = o.ccc();
+  } catch(e) {
+    actual = e + '';
+  }
+  expect = 'TypeError: o.ccc is not a function';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(4) + ' ';
-  actual = o.ddd();
-  expect = 'ddd() foo';
+  try {
+    actual = o.ddd();
+  } catch(e) {
+    actual = e + '';
+  }
+  expect = 'TypeError: o.ddd is not a function';
   reportCompare(expect, actual, status);
 
   status = summary + ' ' + inSection(5) + ' ';
   try {
     actual = o.eee();
   } catch(e) {
     actual = e + '';
   }
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -386,17 +386,17 @@ GetObjectElementOperation(JSContext *cx,
             if (!JSObject::getProperty(cx, obj, obj, name->asPropertyName(), res))
                 return false;
         }
 
         objArg = obj;
     } while (0);
 
 #if JS_HAS_NO_SUCH_METHOD
-    if (op == JSOP_CALLELEM && JS_UNLIKELY(res.isPrimitive()) && wasObject) {
+    if (op == JSOP_CALLELEM && JS_UNLIKELY(res.isUndefined()) && wasObject) {
         RootedObject obj(cx, objArg);
         if (!OnUnknownMethod(cx, obj, rref, res))
             return false;
     }
 #endif
 
     assertSameCompartmentDebugOnly(cx, res);
     return true;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -261,17 +261,17 @@ GetPropertyOperation(JSContext *cx, Stac
 
     bool wasObject = lval.isObject();
 
     if (!JSObject::getGeneric(cx, obj, obj, id, vp))
         return false;
 
 #if JS_HAS_NO_SUCH_METHOD
     if (op == JSOP_CALLPROP &&
-        JS_UNLIKELY(vp.isPrimitive()) &&
+        JS_UNLIKELY(vp.isUndefined()) &&
         wasObject)
     {
         if (!OnUnknownMethod(cx, obj, IdToValue(id), vp))
             return false;
     }
 #endif
 
     return true;
@@ -3448,17 +3448,17 @@ js::GetProperty(JSContext *cx, HandleVal
 
 bool
 js::CallProperty(JSContext *cx, HandleValue v, HandlePropertyName name, MutableHandleValue vp)
 {
     if (!GetProperty(cx, v, name, vp))
         return false;
 
 #if JS_HAS_NO_SUCH_METHOD
-    if (JS_UNLIKELY(vp.isPrimitive()) && v.isObject())
+    if (JS_UNLIKELY(vp.isUndefined()) && v.isObject())
     {
         RootedObject obj(cx, &v.toObject());
         if (!OnUnknownMethod(cx, obj, StringValue(name), vp))
             return false;
     }
 #endif
 
     return true;
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -670,17 +670,17 @@ struct MallocProvider
 
 namespace gc {
 class MarkingValidator;
 } // namespace gc
 
 typedef Vector<JS::Zone *, 4, SystemAllocPolicy> ZoneVector;
 
 class AutoLockForExclusiveAccess;
-class AutoPauseWorkersForGC;
+class AutoPauseWorkersForTracing;
 class ThreadDataIter;
 
 void RecomputeStackLimit(JSRuntime *rt, StackKind kind);
 
 } // namespace js
 
 struct JSRuntime : public JS::shadow::Runtime,
                    public js::MallocProvider<JSRuntime>
@@ -784,17 +784,17 @@ struct JSRuntime : public JS::shadow::Ru
     mozilla::DebugOnly<PRThread *> exclusiveAccessOwner;
     mozilla::DebugOnly<bool> mainThreadHasExclusiveAccess;
     mozilla::DebugOnly<bool> exclusiveThreadsPaused;
 
     /* Number of non-main threads with an ExclusiveContext. */
     size_t numExclusiveThreads;
 
     friend class js::AutoLockForExclusiveAccess;
-    friend class js::AutoPauseWorkersForGC;
+    friend class js::AutoPauseWorkersForTracing;
     friend class js::ThreadDataIter;
 
   public:
     void setUsedByExclusiveThread(JS::Zone *zone);
     void clearUsedByExclusiveThread(JS::Zone *zone);
 
 #endif // JS_THREADSAFE && JS_ION
 
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -342,19 +342,19 @@ FindFrameTargetedByInputEvent(const Widg
   if (!prefs || !prefs->mEnabled || (target && IsElementClickable(target, nsGkAtoms::body))) {
     return target;
   }
 
   // Do not modify targeting for actual mouse hardware; only for mouse
   // events generated by touch-screen hardware.
   if (aEvent->eventStructType == NS_MOUSE_EVENT &&
       prefs->mTouchOnly &&
-      static_cast<const WidgetMouseEvent*>(aEvent)->inputSource !=
-          nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
-      return target;
+      aEvent->AsMouseEvent()->inputSource !=
+        nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
+    return target;
   }
 
   nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame, prefs);
   nsAutoTArray<nsIFrame*,8> candidates;
   nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect, candidates, flags);
   if (NS_FAILED(rv)) {
     return target;
   }
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -3662,43 +3662,33 @@ nsDisplayScrollLayer::GetScrollLayerCoun
   // that it is processed last.
   NS_ABORT_IF_FALSE(hasCount, "nsDisplayScrollLayer should always be defined");
   return result;
 #else
   return reinterpret_cast<intptr_t>(props.Get(nsIFrame::ScrollLayerCount()));
 #endif
 }
 
-intptr_t
-nsDisplayScrollLayer::RemoveScrollLayerCount()
-{
-  intptr_t result = GetScrollLayerCount();
-  FrameProperties props = mScrolledFrame->Properties();
-  props.Remove(nsIFrame::ScrollLayerCount());
-  return result;
-}
-
-
 nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
   nsDisplayListBuilder* aBuilder,
   nsIFrame* aScrolledFrame,
   nsIFrame* aScrollFrame)
   : nsDisplayScrollLayer(aBuilder, aScrollFrame, aScrolledFrame, aScrollFrame)
 {
 #ifdef NS_BUILD_REFCNT_LOGGING
   MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer);
 #endif
 }
 
-#ifdef NS_BUILD_REFCNT_LOGGING
 nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer()
 {
+  FrameProperties props = mScrolledFrame->Properties();
+  props.Remove(nsIFrame::ScrollLayerCount());
   MOZ_COUNT_DTOR(nsDisplayScrollInfoLayer);
 }
-#endif
 
 LayerState
 nsDisplayScrollInfoLayer::GetLayerState(nsDisplayListBuilder* aBuilder,
                                         LayerManager* aManager,
                                         const ContainerParameters& aParameters)
 {
   return LAYER_ACTIVE_EMPTY;
 }
@@ -3712,17 +3702,17 @@ nsDisplayScrollInfoLayer::TryMerge(nsDis
 
 bool
 nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
 {
   // Layer metadata for a particular scroll frame needs to be unique. Only
   // one nsDisplayScrollLayer (with rendered content) or one
   // nsDisplayScrollInfoLayer (with only the metadata) should survive the
   // visibility computation.
-  return RemoveScrollLayerCount() == 1;
+  return GetScrollLayerCount() == 1;
 }
 
 nsDisplayZoom::nsDisplayZoom(nsDisplayListBuilder* aBuilder,
                              nsIFrame* aFrame, nsDisplayList* aList,
                              int32_t aAPD, int32_t aParentAPD,
                              uint32_t aFlags)
     : nsDisplayOwnLayer(aBuilder, aFrame, aList, aFlags)
     , mAPD(aAPD), mParentAPD(aParentAPD) {
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2723,21 +2723,20 @@ public:
                           nsDisplayItem* aItem) MOZ_OVERRIDE;
 
   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
 
   // Get the number of nsDisplayScrollLayers for a scroll frame. Note that this
   // number does not include nsDisplayScrollInfoLayers. If this number is not 1
   // after merging, all the nsDisplayScrollLayers should flatten away.
   intptr_t GetScrollLayerCount();
-  intptr_t RemoveScrollLayerCount();
 
   virtual nsIFrame* GetScrolledFrame() { return mScrolledFrame; }
 
-private:
+protected:
   nsIFrame* mScrollFrame;
   nsIFrame* mScrolledFrame;
 };
 
 /**
  * Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This
  * creates a layer that has no Thebes child layer, but still allows the
  * compositor process to know of the scroll frame's existence.
@@ -2750,19 +2749,17 @@ private:
  */
 class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer
 {
 public:
   nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
                            nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame);
   NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
 
-#ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayScrollInfoLayer();
-#endif
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerParameters& aParameters) MOZ_OVERRIDE;
   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   { return true; }
   virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
                           nsDisplayItem* aItem) MOZ_OVERRIDE;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1318,33 +1318,31 @@ nsLayoutUtils::GetEventCoordinatesRelati
                   aEvent->eventStructType != NS_WHEEL_EVENT &&
                   aEvent->eventStructType != NS_DRAG_EVENT &&
                   aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT &&
                   aEvent->eventStructType != NS_GESTURENOTIFY_EVENT &&
                   aEvent->eventStructType != NS_TOUCH_EVENT &&
                   aEvent->eventStructType != NS_QUERY_CONTENT_EVENT))
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
 
-  const WidgetGUIEvent* GUIEvent = static_cast<const WidgetGUIEvent*>(aEvent);
   return GetEventCoordinatesRelativeTo(aEvent,
-                                       LayoutDeviceIntPoint::ToUntyped(GUIEvent->refPoint),
-                                       aFrame);
+           LayoutDeviceIntPoint::ToUntyped(aEvent->AsGUIEvent()->refPoint),
+           aFrame);
 }
 
 nsPoint
 nsLayoutUtils::GetEventCoordinatesRelativeTo(const WidgetEvent* aEvent,
                                              const nsIntPoint aPoint,
                                              nsIFrame* aFrame)
 {
   if (!aFrame) {
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
   }
 
-  const WidgetGUIEvent* GUIEvent = static_cast<const WidgetGUIEvent*>(aEvent);
-  nsIWidget* widget = GUIEvent->widget;
+  nsIWidget* widget = aEvent->AsGUIEvent()->widget;
   if (!widget) {
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
   }
 
   return GetEventCoordinatesRelativeTo(widget, aPoint, aFrame);
 }
 
 nsPoint
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -456,31 +456,31 @@ public:
         if (frame) {
           // chrome (including addons) should be able to know if content
           // handles both D3E "wheel" event and legacy mouse scroll events.
           // We should dispatch legacy mouse events before dispatching the
           // "wheel" event into system group.
           nsRefPtr<nsEventStateManager> esm =
             aVisitor.mPresContext->EventStateManager();
           esm->DispatchLegacyMouseScrollEvents(frame,
-                 static_cast<WidgetWheelEvent*>(aVisitor.mEvent),
-                 &aVisitor.mEventStatus);
+                                               aVisitor.mEvent->AsWheelEvent(),
+                                               &aVisitor.mEventStatus);
         }
       }
       nsIFrame* frame = mPresShell->GetCurrentEventFrame();
       if (!frame &&
           (aVisitor.mEvent->message == NS_MOUSE_BUTTON_UP ||
            aVisitor.mEvent->message == NS_TOUCH_END)) {
         // Redirect BUTTON_UP and TOUCH_END events to the root frame to ensure
         // that capturing is released.
         frame = mPresShell->GetRootFrame();
       }
       if (frame) {
         frame->HandleEvent(aVisitor.mPresContext,
-                           static_cast<WidgetGUIEvent*>(aVisitor.mEvent),
+                           aVisitor.mEvent->AsGUIEvent(),
                            &aVisitor.mEventStatus);
       }
     }
   }
 
   nsRefPtr<PresShell> mPresShell;
 };
 
@@ -5883,18 +5883,17 @@ PresShell::RecordMouseLocation(WidgetGUI
     PresShell* rootPresShell = GetRootPresShell();
     if (rootPresShell) {
       rootPresShell->RecordMouseLocation(aEvent);
     }
     return;
   }
 
   if ((aEvent->message == NS_MOUSE_MOVE &&
-       static_cast<WidgetMouseEvent*>(aEvent)->reason ==
-         WidgetMouseEvent::eReal) ||
+       aEvent->AsMouseEvent()->reason == WidgetMouseEvent::eReal) ||
       aEvent->message == NS_MOUSE_ENTER ||
       aEvent->message == NS_MOUSE_BUTTON_DOWN ||
       aEvent->message == NS_MOUSE_BUTTON_UP) {
     nsIFrame* rootFrame = GetRootFrame();
     if (!rootFrame) {
       nsView* rootView = mViewManager->GetRootView();
       mMouseLocation = nsLayoutUtils::TranslateWidgetToView(mPresContext,
         aEvent->widget, LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint),
@@ -6180,19 +6179,19 @@ PresShell::HandleEvent(nsIFrame* aFrame,
     }
 
     // all touch events except for touchstart use a captured target
     if (aEvent->eventStructType == NS_TOUCH_EVENT &&
         aEvent->message != NS_TOUCH_START) {
       captureRetarget = true;
     }
 
+    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
     bool isWindowLevelMouseExit = (aEvent->message == NS_MOUSE_EXIT) &&
-      (static_cast<WidgetMouseEvent*>(aEvent)->exit ==
-         WidgetMouseEvent::eTopLevel);
+      (mouseEvent && mouseEvent->exit == WidgetMouseEvent::eTopLevel);
 
     // Get the frame at the event point. However, don't do this if we're
     // capturing and retargeting the event because the captured frame will
     // be used instead below. Also keep using the root frame if we're dealing
     // with a window-level mouse exit event since we want to start sending
     // mouse out events at the root EventStateManager.
     if (!captureRetarget && !isWindowLevelMouseExit) {
       nsPoint eventPoint;
@@ -6273,18 +6272,18 @@ PresShell::HandleEvent(nsIFrame* aFrame,
             if (oldTouch) {
               touch->SetTarget(oldTouch->mTarget);
             }
           }
         }
       } else {
         eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
       }
-      if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-          static_cast<WidgetMouseEvent*>(aEvent)->ignoreRootScrollFrame) {
+      if (mouseEvent && mouseEvent->eventStructType == NS_MOUSE_EVENT &&
+          mouseEvent->ignoreRootScrollFrame) {
         flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
       }
       nsIFrame* target =
         FindFrameTargetedByInputEvent(aEvent, frame, eventPoint, flags);
       if (target) {
         frame = target;
       }
     }
@@ -6309,18 +6308,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
 
     // Suppress mouse event if it's being targeted at an element inside
     // a document which needs events suppressed
     if (aEvent->eventStructType == NS_MOUSE_EVENT &&
         frame->PresContext()->Document()->EventHandlingSuppressed()) {
       if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
         mNoDelayedMouseEvents = true;
       } else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) {
-        nsDelayedEvent* event =
-          new nsDelayedMouseEvent(static_cast<WidgetMouseEvent*>(aEvent));
+        nsDelayedEvent* event = new nsDelayedMouseEvent(aEvent->AsMouseEvent());
         if (!mDelayedEvents.AppendElement(event)) {
           delete event;
         }
       }
 
       return NS_OK;
     }
 
@@ -6829,25 +6827,25 @@ PresShell::HandleEventInternal(WidgetEve
             aEvent->mFlags.mOnlyChromeDispatch = true;
           }
         }
         break;
       }
     }
 
     if (aEvent->message == NS_CONTEXTMENU) {
-      WidgetMouseEvent* me = static_cast<WidgetMouseEvent*>(aEvent);
-      if (!CanHandleContextMenuEvent(me, GetCurrentEventFrame())) {
+      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+      if (!CanHandleContextMenuEvent(mouseEvent, GetCurrentEventFrame())) {
         return NS_OK;
       }
-      if (me->context == WidgetMouseEvent::eContextMenuKey &&
-          !AdjustContextMenuKeyEvent(me)) {
+      if (mouseEvent->context == WidgetMouseEvent::eContextMenuKey &&
+          !AdjustContextMenuKeyEvent(mouseEvent)) {
         return NS_OK;
       }
-      if (me->IsShift()) {
+      if (mouseEvent->IsShift()) {
         aEvent->mFlags.mOnlyChromeDispatch = true;
         aEvent->mFlags.mRetargetToNonNativeAnonymous = true;
       }
     }
 
     nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput,
                                                           aEvent, mDocument);
 
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -579,23 +579,24 @@ protected:
   };
 
   class nsDelayedMouseEvent : public nsDelayedInputEvent
   {
   public:
     nsDelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent) :
       nsDelayedInputEvent()
     {
-      mEvent = new mozilla::WidgetMouseEvent(aEvent->mFlags.mIsTrusted,
-                                             aEvent->message,
-                                             aEvent->widget,
-                                             aEvent->reason,
-                                             aEvent->context);
-      static_cast<mozilla::WidgetMouseEvent*>(mEvent)->
-        AssignMouseEventData(*aEvent, false);
+      mozilla::WidgetMouseEvent* mouseEvent =
+        new mozilla::WidgetMouseEvent(aEvent->mFlags.mIsTrusted,
+                                      aEvent->message,
+                                      aEvent->widget,
+                                      aEvent->reason,
+                                      aEvent->context);
+      mouseEvent->AssignMouseEventData(*aEvent, false);
+      mEvent = mouseEvent;
     }
   };
 
   class nsDelayedKeyEvent : public nsDelayedInputEvent
   {
   public:
     nsDelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent) :
       nsDelayedInputEvent()
--- a/layout/forms/nsImageControlFrame.cpp
+++ b/layout/forms/nsImageControlFrame.cpp
@@ -164,20 +164,18 @@ nsImageControlFrame::HandleEvent(nsPresC
     return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) { // XXX cache disabled
     return NS_OK;
   }
 
   *aEventStatus = nsEventStatus_eIgnore;
 
-  if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-      aEvent->message == NS_MOUSE_BUTTON_UP &&
-      static_cast<WidgetMouseEvent*>(aEvent)->button ==
-        WidgetMouseEvent::eLeftButton) {
+  if (aEvent->message == NS_MOUSE_BUTTON_UP &&
+      aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
     // Store click point for HTMLInputElement::SubmitNamesValues
     // Do this on MouseUp because the specs don't say and that's what IE does
     nsIntPoint* lastClickPoint =
       static_cast<nsIntPoint*>
                  (mContent->GetProperty(nsGkAtoms::imageClickedPoint));
     if (lastClickPoint) {
       // normally lastClickedPoint is not null, as it's allocated in Init()
       nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -1603,17 +1603,17 @@ nsListControlFrame::MouseUp(nsIDOMEvent*
     // And then NOT get an "onclick" event when when you click down on the select
     // and then up outside of the select
     // the EventStateManager tracks the content of the mouse down and the mouse up
     // to make sure they are the same, and the onclick is sent in the PostHandleEvent
     // depeneding on whether the clickCount is non-zero.
     // So we cheat here by either setting or unsetting the clcikCount in the native event
     // so the right thing happens for the onclick event
     WidgetMouseEvent* mouseEvent =
-      static_cast<WidgetMouseEvent*>(aMouseEvent->GetInternalNSEvent());
+      aMouseEvent->GetInternalNSEvent()->AsMouseEvent();
 
     int32_t selectedIndex;
     if (NS_SUCCEEDED(GetIndexFromDOMEvent(aMouseEvent, selectedIndex))) {
       // If it's disabled, disallow the click and leave.
       bool isDisabled = false;
       IsOptionDisabled(selectedIndex, isDisabled);
       if (isDisabled) {
         aMouseEvent->PreventDefault();
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2340,22 +2340,23 @@ nsFrame::FireDOMEvent(const nsAString& a
 
 NS_IMETHODIMP
 nsFrame::HandleEvent(nsPresContext* aPresContext, 
                      WidgetGUIEvent* aEvent,
                      nsEventStatus* aEventStatus)
 {
 
   if (aEvent->message == NS_MOUSE_MOVE) {
+    // XXX If the second argument of HandleDrag() is WidgetMouseEvent,
+    //     the implementation becomes simpler.
     return HandleDrag(aPresContext, aEvent, aEventStatus);
   }
 
   if ((aEvent->eventStructType == NS_MOUSE_EVENT &&
-      static_cast<WidgetMouseEvent*>(aEvent)->button ==
-        WidgetMouseEvent::eLeftButton) ||
+       aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) ||
       aEvent->eventStructType == NS_TOUCH_EVENT) {
     if (aEvent->message == NS_MOUSE_BUTTON_DOWN || aEvent->message == NS_TOUCH_START) {
       HandlePress(aPresContext, aEvent, aEventStatus);
     } else if (aEvent->message == NS_MOUSE_BUTTON_UP || aEvent->message == NS_TOUCH_END) {
       HandleRelease(aPresContext, aEvent, aEventStatus);
     }
   }
   return NS_OK;
@@ -2580,25 +2581,28 @@ nsFrame::HandlePress(nsPresContext* aPre
 
   // if we are in Navigator and the click is in a draggable node, we don't want
   // to start selection because we don't want to interfere with a potential
   // drag of said node and steal all its glory.
   int16_t isEditor = shell->GetSelectionFlags();
   //weaaak. only the editor can display frame selection not just text and images
   isEditor = isEditor == nsISelectionDisplay::DISPLAY_ALL;
 
-  if (!aEvent->AsInputEvent()->IsAlt()) {
+  WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+
+  if (!mouseEvent->IsAlt()) {
     for (nsIContent* content = mContent; content;
          content = content->GetParent()) {
       if (nsContentUtils::ContentIsDraggable(content) &&
           !content->IsEditable()) {
         // coordinate stuff is the fix for bug #55921
         if ((mRect - GetPosition()).Contains(
-               nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this)))
+              nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this))) {
           return NS_OK;
+        }
       }
     }
   }
 
   // check whether style allows selection
   // if not, don't tell selection the mouse event even occurred.  
   bool    selectable;
   uint8_t selectStyle;
@@ -2636,37 +2640,34 @@ nsFrame::HandlePress(nsPresContext* aPre
   if (useFrameSelection)
     frameselection = GetConstFrameSelection();
   else
     frameselection = shell->ConstFrameSelection();
 
   if (!frameselection || frameselection->GetDisplaySelection() == nsISelectionController::SELECTION_OFF)
     return NS_OK;//nothing to do we cannot affect selection from here
 
-  WidgetMouseEvent* me = static_cast<WidgetMouseEvent*>(aEvent);
-
 #ifdef XP_MACOSX
-  if (me->IsControl())
+  if (mouseEvent->IsControl())
     return NS_OK;//short circuit. hard coded for mac due to time restraints.
-  bool control = me->IsMeta();
+  bool control = mouseEvent->IsMeta();
 #else
-  bool control = me->IsControl();
+  bool control = mouseEvent->IsControl();
 #endif
 
   nsRefPtr<nsFrameSelection> fc = const_cast<nsFrameSelection*>(frameselection);
-  if (me->clickCount > 1)
-  {
+  if (mouseEvent->clickCount > 1) {
     // These methods aren't const but can't actually delete anything,
     // so no need for nsWeakFrame.
     fc->SetMouseDownState(true);
     fc->SetMouseDoubleDown(true);
-    return HandleMultiplePress(aPresContext, aEvent, aEventStatus, control);
-  }
-
-  nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
+    return HandleMultiplePress(aPresContext, mouseEvent, aEventStatus, control);
+  }
+
+  nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
   ContentOffsets offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
 
   if (!offsets.content)
     return NS_ERROR_FAILURE;
 
   // On touchables devices, touch the screen is usually a pan action,
   // so let's reposition the caret if needed but do not select text
   // if the touch did not happen over an editable element.  Otherwise,
@@ -2677,21 +2678,24 @@ nsFrame::HandlePress(nsPresContext* aPre
                            offsets.EndOffset(), false, false,
                            offsets.associateWithNext);
   }
 
   // Let Ctrl/Cmd+mouse down do table selection instead of drag initiation
   nsCOMPtr<nsIContent>parentContent;
   int32_t  contentOffset;
   int32_t target;
-  rv = GetDataForTableSelection(frameselection, shell, me, getter_AddRefs(parentContent), &contentOffset, &target);
+  rv = GetDataForTableSelection(frameselection, shell, mouseEvent,
+                                getter_AddRefs(parentContent), &contentOffset,
+                                &target);
   if (NS_SUCCEEDED(rv) && parentContent)
   {
     fc->SetMouseDownState(true);
-    return fc->HandleTableSelection(parentContent, contentOffset, target, me);
+    return fc->HandleTableSelection(parentContent, contentOffset, target,
+                                    mouseEvent);
   }
 
   fc->SetDelayedCaretData(0);
 
   // Check if any part of this frame is selected, and if the
   // user clicked inside the selected region. If so, we delay
   // starting a new selection since the user may be trying to
   // drag the selected region to some other app.
@@ -2729,36 +2733,36 @@ nsFrame::HandlePress(nsPresContext* aPre
 
       SelectionDetails *nextDetail = curDetail->mNext;
       delete curDetail;
       curDetail = nextDetail;
     }
 
     if (inSelection) {
       fc->SetMouseDownState(false);
-      fc->SetDelayedCaretData(me);
+      fc->SetDelayedCaretData(mouseEvent);
       return NS_OK;
     }
   }
 
   fc->SetMouseDownState(true);
 
   // Do not touch any nsFrame members after this point without adding
   // weakFrame checks.
   rv = fc->HandleClick(offsets.content, offsets.StartOffset(),
-                       offsets.EndOffset(), me->IsShift(), control,
+                       offsets.EndOffset(), mouseEvent->IsShift(), control,
                        offsets.associateWithNext);
 
   if (NS_FAILED(rv))
     return rv;
 
   if (offsets.offset != offsets.secondaryOffset)
     fc->MaintainSelection();
 
-  if (isEditor && !me->IsShift() &&
+  if (isEditor && !mouseEvent->IsShift() &&
       (offsets.EndOffset() - offsets.StartOffset()) == 1)
   {
     // A single node is selected and we aren't extending an existing
     // selection, which means the user clicked directly on an object (either
     // -moz-user-select: all or a non-text node without children).
     // Therefore, disable selection extension during mouse moves.
     // XXX This is a bit hacky; shouldn't editor be able to deal with this?
     fc->SetMouseDownState(false);
@@ -2833,36 +2837,39 @@ nsFrame::HandleMultiplePress(nsPresConte
     return NS_OK;
   }
 
   // Find out whether we're doing line or paragraph selection.
   // If browser.triple_click_selects_paragraph is true, triple-click selects paragraph.
   // Otherwise, triple-click selects line, and quadruple-click selects paragraph
   // (on platforms that support quadruple-click).
   nsSelectionAmount beginAmount, endAmount;
-  WidgetMouseEvent* me = static_cast<WidgetMouseEvent*>(aEvent);
-  if (!me) return NS_OK;
-
-  if (me->clickCount == 4) {
+  WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+  if (!mouseEvent) {
+    return NS_OK;
+  }
+
+  if (mouseEvent->clickCount == 4) {
     beginAmount = endAmount = eSelectParagraph;
-  } else if (me->clickCount == 3) {
+  } else if (mouseEvent->clickCount == 3) {
     if (Preferences::GetBool("browser.triple_click_selects_paragraph")) {
       beginAmount = endAmount = eSelectParagraph;
     } else {
       beginAmount = eSelectBeginLine;
       endAmount = eSelectEndLine;
     }
-  } else if (me->clickCount == 2) {
+  } else if (mouseEvent->clickCount == 2) {
     // We only want inline frames; PeekBackwardAndForward dislikes blocks
     beginAmount = endAmount = eSelectWord;
   } else {
     return NS_OK;
   }
 
-  nsPoint relPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
+  nsPoint relPoint =
+    nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
   return SelectByTypeAtPoint(aPresContext, relPoint, beginAmount, endAmount,
                              (aControlHeld ? SELECT_ACCUMULATE : 0));
 }
 
 nsresult
 nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
                                 nsSelectionAmount aAmountForward,
                                 int32_t aStartPos,
@@ -2963,27 +2970,28 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPres
     return NS_OK;
 
   frameselection->StopAutoScrollTimer();
 
   // Check if we are dragging in a table cell
   nsCOMPtr<nsIContent> parentContent;
   int32_t contentOffset;
   int32_t target;
-  WidgetMouseEvent* me = static_cast<WidgetMouseEvent*>(aEvent);
+  WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   nsresult result;
-  result = GetDataForTableSelection(frameselection, presShell, me,
+  result = GetDataForTableSelection(frameselection, presShell, mouseEvent,
                                     getter_AddRefs(parentContent),
                                     &contentOffset, &target);      
 
   nsWeakFrame weakThis = this;
   if (NS_SUCCEEDED(result) && parentContent) {
-    frameselection->HandleTableSelection(parentContent, contentOffset, target, me);
+    frameselection->HandleTableSelection(parentContent, contentOffset, target,
+                                         mouseEvent);
   } else {
-    nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
+    nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent, this);
     frameselection->HandleDrag(this, pt);
   }
 
   // The frameselection object notifies selection listeners synchronously above
   // which might have killed us.
   if (!weakThis.IsAlive()) {
     return NS_OK;
   }
@@ -2992,18 +3000,18 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsPres
   nsIScrollableFrame* scrollFrame =
     nsLayoutUtils::GetNearestScrollableFrame(this,
         nsLayoutUtils::SCROLLABLE_SAME_DOC |
         nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
 
   if (scrollFrame) {
     nsIFrame* capturingFrame = scrollFrame->GetScrolledFrame();
     if (capturingFrame) {
-      nsPoint pt =
-        nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, capturingFrame);
+      nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mouseEvent,
+                                                                capturingFrame);
       frameselection->StartAutoScrollTimer(capturingFrame, pt, 30);
     }
   }
 
   return NS_OK;
 }
 
 /**
@@ -3053,17 +3061,17 @@ HandleFrameSelection(nsFrameSelection*  
         return rv;
       }
     } else if (aParentContentForTableSel) {
       aFrameSelection->SetMouseDownState(false);
       rv = aFrameSelection->HandleTableSelection(
                               aParentContentForTableSel,
                               aContentOffsetForTableSel,
                               aTargetForTableSel,
-                              static_cast<WidgetMouseEvent*>(aEvent));
+                              aEvent->AsMouseEvent());
       if (NS_FAILED(rv)) {
         return rv;
       }
     }
     aFrameSelection->SetDelayedCaretData(0);
   }
 
   aFrameSelection->SetMouseDownState(false);
@@ -3109,17 +3117,17 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsP
 
       if (!mouseDown && frameselection->HasDelayedCaretData() &&
           frameselection->GetClickCountInDelayedCaretData() < 2) {
         nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
         offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
         handleTableSelection = false;
       } else {
         GetDataForTableSelection(frameselection, PresContext()->PresShell(),
-                                 static_cast<WidgetMouseEvent*>(aEvent),
+                                 aEvent->AsMouseEvent(),
                                  getter_AddRefs(parentContent),
                                  &contentOffsetForTableSel,
                                  &targetForTableSel);
       }
     }
   }
 
   // We might be capturing in some other document and the event just happened to
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -687,19 +687,17 @@ NS_METHOD nsHTMLFramesetFrame::HandleEve
   NS_ENSURE_ARG_POINTER(aEventStatus);
   if (mDragger) {
     // the nsFramesetBorderFrame has captured NS_MOUSE_DOWN
     switch (aEvent->message) {
       case NS_MOUSE_MOVE:
         MouseDrag(aPresContext, aEvent);
 	      break;
       case NS_MOUSE_BUTTON_UP:
-        if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-            static_cast<WidgetMouseEvent*>(aEvent)->button ==
-              WidgetMouseEvent::eLeftButton) {
+        if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
           EndMouseDrag(aPresContext);
         }
 	      break;
     }
     *aEventStatus = nsEventStatus_eConsumeNoDefault;
   } else {
     *aEventStatus = nsEventStatus_eIgnore;
   }
@@ -1585,20 +1583,18 @@ nsHTMLFramesetBorderFrame::HandleEvent(n
   NS_ENSURE_ARG_POINTER(aEventStatus);
   *aEventStatus = nsEventStatus_eIgnore;
 
   //XXX Mouse setting logic removed.  The remaining logic should also move.
   if (!mCanResize) {
     return NS_OK;
   }
 
-  if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-      aEvent->message == NS_MOUSE_BUTTON_DOWN &&
-      static_cast<WidgetMouseEvent*>(aEvent)->button ==
-        WidgetMouseEvent::eLeftButton) {
+  if (aEvent->message == NS_MOUSE_BUTTON_DOWN &&
+      aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
     nsHTMLFramesetFrame* parentFrame = do_QueryFrame(GetParent());
     if (parentFrame) {
       parentFrame->StartMouseDrag(aPresContext, this, aEvent);
       *aEventStatus = nsEventStatus_eConsumeNoDefault;
     }
   }
   return NS_OK;
 }
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1631,20 +1631,18 @@ nsImageFrame::GetContentForEvent(WidgetE
 // XXX what should clicks on transparent pixels do?
 NS_IMETHODIMP
 nsImageFrame::HandleEvent(nsPresContext* aPresContext,
                           WidgetGUIEvent* aEvent,
                           nsEventStatus* aEventStatus)
 {
   NS_ENSURE_ARG_POINTER(aEventStatus);
 
-  if ((aEvent->eventStructType == NS_MOUSE_EVENT &&
-       aEvent->message == NS_MOUSE_BUTTON_UP && 
-       static_cast<WidgetMouseEvent*>(aEvent)->button ==
-         WidgetMouseEvent::eLeftButton) ||
+  if ((aEvent->message == NS_MOUSE_BUTTON_UP && 
+       aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) ||
       aEvent->message == NS_MOUSE_MOVE) {
     nsImageMap* map = GetImageMap();
     bool isServerMap = IsServerImageMap();
     if ((nullptr != map) || isServerMap) {
       nsIntPoint p;
       TranslateEventCoords(
         nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this), p);
       bool inside = false;
--- a/layout/style/test/Makefile.in
+++ b/layout/style/test/Makefile.in
@@ -232,20 +232,16 @@ MOCHITEST_FILES =	test_acid3_test46.html
 		$(topsrcdir)/layout/reftests/svg/as-image/svg-image-visited-1-helper.svg \
 		$(topsrcdir)/layout/reftests/svg/as-image/svg-image-visited-2-helper.svg \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += -DMOZILLA_INTERNAL_API
 
-# FIXME: We don't seem to do auto-generated dependencies here.
-host_ListCSSProperties.$(OBJ_SUFFIX): $(srcdir)/../nsCSSPropList.h
-TestCSSPropertyLookup.$(OBJ_SUFFIX): $(srcdir)/../nsCSSProps.h $(srcdir)/../nsCSSKeywords.h
-
 css_properties.js: host_ListCSSProperties$(HOST_BIN_SUFFIX) css_properties_like_longhand.js Makefile
 	$(RM) $@
 	./host_ListCSSProperties$(HOST_BIN_SUFFIX) > $@
 	cat $(srcdir)/css_properties_like_longhand.js >> $@
 
 GARBAGE += css_properties.js
 
 libs:: $(_VISITED_REFTEST_FILES)
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -420,63 +420,57 @@ nsMenuFrame::HandleEvent(nsPresContext* 
     // On other platforms, toggle menulist on unmodified F4 or Alt arrow
     if ((keyCode == NS_VK_F4 && !keyEvent->IsAlt()) ||
         ((keyCode == NS_VK_UP || keyCode == NS_VK_DOWN) && keyEvent->IsAlt())) {
       *aEventStatus = nsEventStatus_eConsumeNoDefault;
       ToggleMenuState();
     }
 #endif
   }
-  else if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-           aEvent->message == NS_MOUSE_BUTTON_DOWN &&
-           static_cast<WidgetMouseEvent*>(aEvent)->button ==
-             WidgetMouseEvent::eLeftButton &&
+  else if (aEvent->message == NS_MOUSE_BUTTON_DOWN &&
+           aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
            !IsDisabled() && IsMenu()) {
     // The menu item was selected. Bring up the menu.
     // We have children.
     // Don't prevent the default action here, since that will also cancel
     // potential drag starts.
     if (!mMenuParent || mMenuParent->IsMenuBar()) {
       ToggleMenuState();
     }
     else {
       if (!IsOpen()) {
         OpenMenu(false);
       }
     }
   }
   else if (
 #ifndef NSCONTEXTMENUISMOUSEUP
-           (aEvent->eventStructType == NS_MOUSE_EVENT &&
-            aEvent->message == NS_MOUSE_BUTTON_UP &&
-            static_cast<WidgetMouseEvent*>(aEvent)->button ==
-              WidgetMouseEvent::eRightButton) &&
+           (aEvent->message == NS_MOUSE_BUTTON_UP &&
+            aEvent->AsMouseEvent()->button == WidgetMouseEvent::eRightButton) &&
 #else
-            aEvent->message == NS_CONTEXTMENU &&
+           aEvent->message == NS_CONTEXTMENU &&
 #endif
-            onmenu && !IsMenu() && !IsDisabled()) {
+           onmenu && !IsMenu() && !IsDisabled()) {
     // if this menu is a context menu it accepts right-clicks...fire away!
     // Make sure we cancel default processing of the context menu event so
     // that it doesn't bubble and get seen again by the popuplistener and show
     // another context menu.
     //
     // Furthermore (there's always more, isn't there?), on some platforms (win32
     // being one of them) we get the context menu event on a mouse up while
     // on others we get it on a mouse down. For the ones where we get it on a
     // mouse down, we must continue listening for the right button up event to
     // dismiss the menu.
     if (mMenuParent->IsContextMenu()) {
       *aEventStatus = nsEventStatus_eConsumeNoDefault;
       Execute(aEvent);
     }
   }
-  else if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-           aEvent->message == NS_MOUSE_BUTTON_UP &&
-           static_cast<WidgetMouseEvent*>(aEvent)->button ==
-             WidgetMouseEvent::eLeftButton &&
+  else if (aEvent->message == NS_MOUSE_BUTTON_UP &&
+           aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
            !IsMenu() && !IsDisabled()) {
     // Execute the execute event handler.
     *aEventStatus = nsEventStatus_eConsumeNoDefault;
     Execute(aEvent);
   }
   else if (aEvent->message == NS_MOUSE_EXIT_SYNTH) {
     // Kill our timer if one is active.
     if (mOpenTimer) {
--- a/layout/xul/base/src/nsResizerFrame.cpp
+++ b/layout/xul/base/src/nsResizerFrame.cpp
@@ -62,19 +62,17 @@ nsResizerFrame::HandleEvent(nsPresContex
   nsWeakFrame weakFrame(this);
   bool doDefault = true;
 
   switch (aEvent->message) {
     case NS_TOUCH_START:
     case NS_MOUSE_BUTTON_DOWN: {
       if (aEvent->eventStructType == NS_TOUCH_EVENT ||
           (aEvent->eventStructType == NS_MOUSE_EVENT &&
-        static_cast<WidgetMouseEvent*>(aEvent)->button ==
-          WidgetMouseEvent::eLeftButton))
-      {
+           aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton)) {
         nsCOMPtr<nsIBaseWindow> window;
         nsIPresShell* presShell = aPresContext->GetPresShell();
         nsIContent* contentToResize =
           GetContentToResize(presShell, getter_AddRefs(window));
         if (contentToResize) {
           nsIFrame* frameToResize = contentToResize->GetPrimaryFrame();
           if (!frameToResize)
             break;
@@ -127,22 +125,19 @@ nsResizerFrame::HandleEvent(nsPresContex
 
         nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
       }
     }
     break;
 
   case NS_TOUCH_END:
   case NS_MOUSE_BUTTON_UP: {
-
-      if (aEvent->eventStructType == NS_TOUCH_EVENT ||
-          (aEvent->eventStructType == NS_MOUSE_EVENT &&
-           static_cast<WidgetMouseEvent*>(aEvent)->button ==
-             WidgetMouseEvent::eLeftButton))
-    {
+    if (aEvent->eventStructType == NS_TOUCH_EVENT ||
+        (aEvent->eventStructType == NS_MOUSE_EVENT &&
+         aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton)) {
       // we're done tracking.
       mTrackingMouseMove = false;
 
       nsIPresShell::SetCapturingContent(nullptr, 0);
 
       doDefault = false;
     }
   }
@@ -291,20 +286,17 @@ nsResizerFrame::HandleEvent(nsPresContex
   case NS_MOUSE_CLICK:
     if (aEvent->IsLeftClickEvent())
     {
       MouseClicked(aPresContext, aEvent);
     }
     break;
 
   case NS_MOUSE_DOUBLECLICK:
-    if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-        static_cast<WidgetMouseEvent*>(aEvent)->button ==
-          WidgetMouseEvent::eLeftButton)
-    {
+    if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
       nsCOMPtr<nsIBaseWindow> window;
       nsIPresShell* presShell = aPresContext->GetPresShell();
       nsIContent* contentToResize =
         GetContentToResize(presShell, getter_AddRefs(window));
       if (contentToResize) {
         nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(contentToResize->GetPrimaryFrame());
         if (menuPopupFrame)
           break; // Don't restore original sizing for menupopup frames until
--- a/layout/xul/base/src/nsScrollbarButtonFrame.cpp
+++ b/layout/xul/base/src/nsScrollbarButtonFrame.cpp
@@ -81,17 +81,17 @@ nsScrollbarButtonFrame::HandleEvent(nsPr
 
 bool
 nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
                                           WidgetGUIEvent* aEvent,
                                           nsEventStatus* aEventStatus)
 {
   // Get the desired action for the scrollbar button.
   LookAndFeel::IntID tmpAction;
-  uint16_t button = static_cast<WidgetMouseEvent*>(aEvent)->button;
+  uint16_t button = aEvent->AsMouseEvent()->button;
   if (button == WidgetMouseEvent::eLeftButton) {
     tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
   } else if (button == WidgetMouseEvent::eMiddleButton) {
     tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
   } else if (button == WidgetMouseEvent::eRightButton) {
     tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
   } else {
     return false;
--- a/layout/xul/base/src/nsSliderFrame.cpp
+++ b/layout/xul/base/src/nsSliderFrame.cpp
@@ -818,18 +818,17 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aE
 {
 #ifdef DEBUG_SLIDER
   printf("Begin dragging\n");
 #endif
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
                             nsGkAtoms::_true, eCaseMatters))
     return NS_OK;
 
-  WidgetGUIEvent *event =
-    static_cast<WidgetGUIEvent*>(aEvent->GetInternalNSEvent());
+  WidgetGUIEvent* event = aEvent->GetInternalNSEvent()->AsGUIEvent();
 
   if (!ShouldScrollForEvent(event)) {
     return NS_OK;
   }
 
   nsPoint pt;
   if (!GetEventPoint(event, pt)) {
     return NS_OK;
@@ -942,17 +941,17 @@ bool
 nsSliderFrame::ShouldScrollForEvent(WidgetGUIEvent* aEvent)
 {
   switch (aEvent->message) {
     case NS_TOUCH_START:
     case NS_TOUCH_END:
       return true;
     case NS_MOUSE_BUTTON_DOWN:
     case NS_MOUSE_BUTTON_UP: {
-      uint16_t button = static_cast<WidgetMouseEvent*>(aEvent)->button;
+      uint16_t button = aEvent->AsMouseEvent()->button;
       return (button == WidgetMouseEvent::eLeftButton) ||
              (button == WidgetMouseEvent::eMiddleButton && gMiddlePref);
     }
     default:
       return false;
   }
 }
 
@@ -973,17 +972,17 @@ nsSliderFrame::ShouldScrollToClickForEve
 
 #ifdef XP_MACOSX
   // On Mac, clicking the scrollbar thumb should never scroll to click.
   if (IsEventOverThumb(aEvent)) {
     return false;
   }
 #endif
 
-  WidgetMouseEvent* mouseEvent = static_cast<WidgetMouseEvent*>(aEvent);
+  WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   if (mouseEvent->button == WidgetMouseEvent::eLeftButton) {
 #ifdef XP_MACOSX
     bool invertPref = mouseEvent->IsAlt();
 #else
     bool invertPref = mouseEvent->IsShift();
 #endif
     return GetScrollToClick() != invertPref;
   }
--- a/layout/xul/base/src/nsSplitterFrame.cpp
+++ b/layout/xul/base/src/nsSplitterFrame.cpp
@@ -387,19 +387,17 @@ nsSplitterFrame::HandleEvent(nsPresConte
   nsWeakFrame weakFrame(this);
   nsRefPtr<nsSplitterFrameInner> kungFuDeathGrip(mInner);
   switch (aEvent->message) {
     case NS_MOUSE_MOVE: 
       mInner->MouseDrag(aPresContext, aEvent);
     break;
   
     case NS_MOUSE_BUTTON_UP:
-      if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-          static_cast<WidgetMouseEvent*>(aEvent)->button ==
-            WidgetMouseEvent::eLeftButton) {
+      if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
         mInner->MouseUp(aPresContext, aEvent);
       }
     break;
   }
 
   NS_ENSURE_STATE(weakFrame.IsAlive());
   return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
 }
--- a/layout/xul/base/src/nsTitleBarFrame.cpp
+++ b/layout/xul/base/src/nsTitleBarFrame.cpp
@@ -65,19 +65,17 @@ nsTitleBarFrame::HandleEvent(nsPresConte
     return NS_OK;
   }
 
   bool doDefault = true;
 
   switch (aEvent->message) {
 
    case NS_MOUSE_BUTTON_DOWN:  {
-       if (aEvent->eventStructType == NS_MOUSE_EVENT &&
-           static_cast<WidgetMouseEvent*>(aEvent)->button ==
-             WidgetMouseEvent::eLeftButton) {
+       if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
          // titlebar has no effect in non-chrome shells
          nsCOMPtr<nsISupports> cont = aPresContext->GetContainer();
          nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont);
          if (dsti) {
            int32_t type = -1;
            if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
                type == nsIDocShellTreeItem::typeChrome) {
              // we're tracking.
@@ -94,19 +92,18 @@ nsTitleBarFrame::HandleEvent(nsPresConte
          *aEventStatus = nsEventStatus_eConsumeNoDefault;
          doDefault = false;
        }
      }
      break;
 
 
    case NS_MOUSE_BUTTON_UP: {
-       if(mTrackingMouseMove && aEvent->eventStructType == NS_MOUSE_EVENT &&
-          static_cast<WidgetMouseEvent*>(aEvent)->button ==
-            WidgetMouseEvent::eLeftButton) {
+       if (mTrackingMouseMove &&
+           aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
          // we're done tracking.
          mTrackingMouseMove = false;
 
          // end capture
          nsIPresShell::SetCapturingContent(nullptr, 0);
 
          *aEventStatus = nsEventStatus_eConsumeNoDefault;
          doDefault = false;
--- a/layout/xul/base/src/nsXULPopupManager.cpp
+++ b/layout/xul/base/src/nsXULPopupManager.cpp
@@ -493,17 +493,17 @@ nsXULPopupManager::InitTriggerEvent(nsID
             presContext->GetRootPresContext();
           if (!rootDocPresContext)
             return;
           nsIFrame* rootDocumentRootFrame = rootDocPresContext->
               PresShell()->FrameManager()->GetRootFrame();
           if ((event->eventStructType == NS_MOUSE_EVENT || 
                event->eventStructType == NS_MOUSE_SCROLL_EVENT ||
                event->eventStructType == NS_WHEEL_EVENT) &&
-               !(static_cast<WidgetGUIEvent*>(event))->widget) {
+               !event->AsGUIEvent()->widget) {
             // no widget, so just use the client point if available
             nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent);
             nsIntPoint clientPt;
             mouseEvent->GetClientX(&clientPt.x);
             mouseEvent->GetClientY(&clientPt.y);
 
             // XXX this doesn't handle IFRAMEs in transforms
             nsPoint thisDocToRootDocOffset = presShell->FrameManager()->
@@ -1764,39 +1764,31 @@ nsXULPopupManager::CancelMenuTimer(nsMen
 {
   if (mCloseTimer && mTimerMenu == aMenuParent) {
     mCloseTimer->Cancel();
     mCloseTimer = nullptr;
     mTimerMenu = nullptr;
   }
 }
 
-static WidgetGUIEvent*
-DOMKeyEventToGUIEvent(nsIDOMEvent* aEvent)
-{
-  WidgetEvent* evt = aEvent ? aEvent->GetInternalNSEvent() : nullptr;
-  return evt && evt->eventStructType == NS_KEY_EVENT ?
-         static_cast<WidgetGUIEvent*>(evt) : nullptr;
-}
-
 bool
 nsXULPopupManager::HandleShortcutNavigation(nsIDOMKeyEvent* aKeyEvent,
                                             nsMenuPopupFrame* aFrame)
 {
   nsMenuChainItem* item = GetTopVisibleMenu();
   if (!aFrame && item)
     aFrame = item->Frame();
 
   if (aFrame) {
     bool action;
     nsMenuFrame* result = aFrame->FindMenuWithShortcut(aKeyEvent, action);
     if (result) {
       aFrame->ChangeMenuItem(result, false);
       if (action) {
-        WidgetGUIEvent* evt = DOMKeyEventToGUIEvent(aKeyEvent);
+        WidgetGUIEvent* evt = aKeyEvent->GetInternalNSEvent()->AsGUIEvent();
         nsMenuFrame* menuToOpen = result->Enter(evt);
         if (menuToOpen) {
           nsCOMPtr<nsIContent> content = menuToOpen->GetContent();
           ShowMenu(content, true, false);
         }
       }
       return true;
     }
@@ -2019,17 +2011,17 @@ nsXULPopupManager::HandleKeyboardEventWi
       break;
 
     case nsIDOMKeyEvent::DOM_VK_ENTER:
     case nsIDOMKeyEvent::DOM_VK_RETURN: {
       // If there is a popup open, check if the current item needs to be opened.
       // Otherwise, tell the active menubar, if any, to activate the menu. The
       // Enter method will return a menu if one needs to be opened as a result.
       nsMenuFrame* menuToOpen = nullptr;
-      WidgetGUIEvent* GUIEvent = DOMKeyEventToGUIEvent(aKeyEvent);
+      WidgetGUIEvent* GUIEvent = aKeyEvent->GetInternalNSEvent()->AsGUIEvent();
       if (aTopVisibleMenuItem) {
         menuToOpen = aTopVisibleMenuItem->Frame()->Enter(GUIEvent);
       } else if (mActiveMenuBar) {
         menuToOpen = mActiveMenuBar->Enter(GUIEvent);
       }
       if (menuToOpen) {
         nsCOMPtr<nsIContent> content = menuToOpen->GetContent();
         ShowMenu(content, true, false);
--- a/layout/xul/tree/nsTreeColumns.h
+++ b/layout/xul/tree/nsTreeColumns.h
@@ -8,16 +8,17 @@
 
 #include "nsITreeColumns.h"
 #include "nsITreeBoxObject.h"
 #include "mozilla/Attributes.h"
 #include "nsCoord.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
 #include "nsWrapperCache.h"
+#include "nsString.h"
 
 class nsTreeBodyFrame;
 class nsTreeColumns;
 class nsIFrame;
 class nsIContent;
 struct nsRect;
 
 namespace mozilla {
--- a/media/libcubeb/src/cubeb_sndio.c
+++ b/media/libcubeb/src/cubeb_sndio.c
@@ -4,16 +4,17 @@
  * This program is made available under an ISC-style license.  See the
  * accompanying file LICENSE for details.
  */
 #include <poll.h>
 #include <pthread.h>
 #include <sndio.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <assert.h>
 #include "cubeb/cubeb.h"
 #include "cubeb-internal.h"
 
 #if defined(CUBEB_SNDIO_DEBUG)
 #define DPR(...) fprintf(stderr, __VA_ARGS__);
 #else
 #define DPR(...) do {} while(0)
 #endif
--- a/media/libcubeb/src/cubeb_winmm.c
+++ b/media/libcubeb/src/cubeb_winmm.c
@@ -524,33 +524,29 @@ winmm_get_min_latency(cubeb * ctx, cubeb
 {
   // 100ms minimum, if we are not in a bizarre configuration.
   *latency = ctx->minimum_latency;
 
   return CUBEB_OK;
 }
 
 static int
-winmm_get_preferred_sample_rate(cubeb * ctx, cubeb_stream_params params, uint32_t * rate)
+winmm_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
 {
-  LPWAVEOUTCAPS pwoc;
-  UINT cbwoc;
+  WAVEOUTCAPS woc;
   MMRESULT r;
 
-  cbwoc = sizeof(WAVEOUTCAPS);
-
-  r = waveOutGetDevCaps(WAVE_MAPPER, pwoc, cbwoc);
-
+  r = waveOutGetDevCaps(WAVE_MAPPER, &woc, sizeof(WAVEOUTCAPS));
   if (r != MMSYSERR_NOERROR) {
     return CUBEB_ERROR;
   }
 
   /* Check if we support 48kHz, but not 44.1kHz. */
-  if (!(pwoc->dwFormats & WAVE_FORMAT_4S16) &&
-      pwoc->dwFormats & WAVE_FORMAT_48S16) {
+  if (!(woc.dwFormats & WAVE_FORMAT_4S16) &&
+      woc.dwFormats & WAVE_FORMAT_48S16) {
     *rate = 48000;
     return CUBEB_OK;
   }
   /* Prefer 44.1kHz between 44.1kHz and 48kHz. */
   *rate = 44100;
 
   return CUBEB_OK;
 }
--- a/memory/build/mozmemory.h
+++ b/memory/build/mozmemory.h
@@ -33,17 +33,17 @@ MOZ_BEGIN_EXTERN_C
 #  include <malloc/malloc.h>
 #else
 MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size);
 
 /* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning
  * the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API
  * to use weak imports. */
 
-static MOZ_INLINE size_t _malloc_good_size(size_t size) {
+static inline size_t _malloc_good_size(size_t size) {
 #  if defined(MOZ_GLUE_IN_PROGRAM) && !defined(IMPL_MFBT)
   if (!malloc_good_size)
     return size;
 #  endif
   return malloc_good_size_impl(size);
 }
 
 #  define malloc_good_size _malloc_good_size
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -7,53 +7,39 @@
 /* Implementations of various class and method modifier attributes. */
 
 #ifndef mozilla_Attributes_h
 #define mozilla_Attributes_h
 
 #include "mozilla/Compiler.h"
 
 /*
- * MOZ_INLINE is a macro which expands to tell the compiler that the method
- * decorated with it should be inlined.  This macro is usable from C and C++
- * code, even though C89 does not support the |inline| keyword.  The compiler
- * may ignore this directive if it chooses.
- */
-#if defined(__cplusplus)
-#  define MOZ_INLINE            inline
-#elif defined(_MSC_VER)
-#  define MOZ_INLINE            __inline
-#elif defined(__GNUC__)
-#  define MOZ_INLINE            __inline__
-#else
-#  define MOZ_INLINE            inline
-#endif
-
-/*
  * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
  * method decorated with it must be inlined, even if the compiler thinks
- * otherwise.  This is only a (much) stronger version of the MOZ_INLINE hint:
+ * otherwise.  This is only a (much) stronger version of the inline hint:
  * compilers are not guaranteed to respect it (although they're much more likely
  * to do so).
  *
  * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the
  * compiler to inline even in DEBUG builds. It should be used very rarely.
  */
 #if defined(_MSC_VER)
 #  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     __forceinline
 #elif defined(__GNUC__)
-#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     __attribute__((always_inline)) MOZ_INLINE
+#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     __attribute__((always_inline)) inline
 #else
-#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     MOZ_INLINE
+#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     inline
 #endif
 
-#if defined(DEBUG)
-#  define MOZ_ALWAYS_INLINE     MOZ_INLINE
+#if !defined(DEBUG)
+#  define MOZ_ALWAYS_INLINE     MOZ_ALWAYS_INLINE_EVEN_DEBUG
+#elif defined(_MSC_VER) && !defined(__cplusplus)
+#  define MOZ_ALWAYS_INLINE     __inline
 #else
-#  define MOZ_ALWAYS_INLINE     MOZ_ALWAYS_INLINE_EVEN_DEBUG
+#  define MOZ_ALWAYS_INLINE     inline
 #endif
 
 /*
  * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
  * without warnings (functionality used by the macros below).  These modes are
  * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
  * standardly, by checking whether __cplusplus has a C++11 or greater value.
  * Current versions of g++ do not correctly set __cplusplus, so we check both
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -41,14 +41,15 @@
 [testFindInPage]
 [testInputUrlBar]
 [testAddSearchEngine]
 [testImportFromAndroid]
 [testMasterPassword]
 [testDeviceSearchEngine]
 [testPrivateBrowsing]
 [testReaderMode]
+[testGetUserMedia]
 
 # Used for Talos, please don't use in mochitest
 #[testPan]
 #[testCheck]
 #[testCheck2]
 #[testBrowserProviderPerf]
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/robocop_getusermedia.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html><head>
+  <title>gUM Test Page</title>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8" charset="utf-8">
+</head>
+<body>
+  <script type="application/javascript">
+  var video_status = false;
+  var video = document.createElement("video");
+  video.setAttribute("width", 640);
+  video.setAttribute("height", 480);
+
+  var audio_status = false;
+  var audio = document.createElement("audio");
+  audio.setAttribute("controls", true);
+
+  startAudioVideo();
+
+  function startAudioVideo() {
+    video_status = true;
+    audio_status = true;
+    startMedia({video:true, audio:true});
+  }
+
+  function stopMedia() {
+    if (video_status) {
+      video.mozSrcObject.stop();
+      video.mozSrcObject = null;
+      content.removeChild(video);
+      capturing = false;
+      video_status = false;
+    }
+    if (audio_status) {
+      audio.mozSrcObject.stop();
+      audio.mozSrcObject = null;
+      content.removeChild(audio);
+      audio_status = false;
+    }
+  }
+
+  function startMedia(param) {
+    try {
+      window.navigator.mozGetUserMedia(param, function(stream) {
+        message.innerHTML = "<p>Success!</p>";
+        if (video_status) {
+          content.appendChild(video);
+          video.mozSrcObject = stream;
+          video.play();
+        }
+        if (audio_status) {
+          content.appendChild(audio);
+          audio.mozSrcObject = stream;
+          audio.play();
+        }
+      }, function(err) {
+        stopMedia();
+      });
+    } catch(e) {
+      stopMedia();
+    }
+  }
+</script>
+</body></html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testGetUserMedia.java.in
@@ -0,0 +1,40 @@
+#filter substitution
+package @ANDROID_PACKAGE_NAME@.tests;
+
+import @ANDROID_PACKAGE_NAME@.*;
+
+import android.app.Activity;
+import android.hardware.Camera;
+import android.os.Build;
+import java.lang.reflect.Method;
+
+public class testGetUserMedia extends BaseTest {
+    @Override
+    protected int getTestType() {
+        return TEST_MOCHITEST;
+    }
+
+    public void testGetUserMedia() {
+        String GUM_URL = getAbsoluteUrl("/robocop/robocop_getusermedia.html");
+
+        String GUM_MESSAGE = "Would you like to share your camera and microphone with";
+        String GUM_ALLOW = "Share";
+        String GUM_DENY = "Don't share";
+
+        blockForGeckoReady();
+
+        // Only try GUM test if the device has a camera. If there's a working Camera,
+        // we'll assume there is a working audio device as well.
+        // getNumberOfCameras is Gingerbread/9+
+        // We could avoid that requirement by trying to open a Camera but we
+        // already know our 2.2/Tegra test devices don't have them.
+        if (Build.VERSION.SDK_INT >= 9) {
+            if (Camera.getNumberOfCameras() > 0) {
+                // Test GUM notification
+                inputAndLoadUrl(GUM_URL);
+                waitForText(GUM_MESSAGE);
+                mAsserter.is(mSolo.searchText(GUM_MESSAGE), true, "GetUserMedia doorhanger has been displayed");
+            }
+        }
+    }
+}
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -9,16 +9,17 @@
 #include <dlfcn.h>
 #include <unistd.h>
 #include <algorithm>
 #include <fcntl.h>
 #include "ElfLoader.h"
 #include "CustomElf.h"
 #include "Mappable.h"
 #include "Logging.h"
+#include <inttypes.h>
 
 #if defined(ANDROID)
 #include <sys/syscall.h>
 
 #include <android/api-level.h>
 #if __ANDROID_API__ < 8
 /* Android API < 8 doesn't provide sigaltstack */
 
@@ -903,49 +904,82 @@ Divert(T func, T new_func)
 template <typename T>
 static bool
 Divert(T func, T new_func)
 {
   return false;
 }
 #endif
 
+namespace {
+
+/* Clock that only accounts for time spent in the current process. */
+static uint64_t ProcessTimeStamp_Now()
+{
+  struct timespec ts;
+  int rv = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
+
+  if (rv != 0) {
+    return 0;
+  }
+
+  uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
+  return baseNs + (uint64_t)ts.tv_nsec;
+}
+
+}
+
+/* Data structure used to pass data to the temporary signal handler,
+ * as well as triggering a test crash. */
+struct TmpData {
+  volatile int crash_int;
+  volatile uint64_t crash_timestamp;
+};
+
 SEGVHandler::SEGVHandler()
 : registeredHandler(false), signalHandlingBroken(false)
+, signalHandlingSlow(false)
 {
   /* Initialize oldStack.ss_flags to an invalid value when used to set
    * an alternative stack, meaning we haven't got information about the
    * original alternative stack and thus don't mean to restore it */
   oldStack.ss_flags = SS_ONSTACK;
   if (!Divert(sigaction, __wrap_sigaction))
     return;
 
   /* Get the current segfault signal handler. */
   sys_sigaction(SIGSEGV, NULL, &this->action);
 
   /* Some devices don't provide useful information to their SIGSEGV handlers,
    * making it impossible for on-demand decompression to work. To check if
    * we're on such a device, setup a temporary handler and deliberately
    * trigger a segfault. The handler will set signalHandlingBroken if the
-   * provided information is bogus. */
+   * provided information is bogus.
+   * Some other devices have a kernel option enabled that makes SIGSEGV handler
+   * have an overhead so high that it affects how on-demand decompression
+   * performs. The handler will also set signalHandlingSlow if the triggered
+   * SIGSEGV took too much time. */
   struct sigaction action;
   action.sa_sigaction = &SEGVHandler::test_handler;
   sigemptyset(&action.sa_mask);
   action.sa_flags = SA_SIGINFO | SA_NODEFER;
   action.sa_restorer = NULL;
   if (sys_sigaction(SIGSEGV, &action, NULL))
     return;
-  stackPtr.Assign(MemoryRange::mmap(NULL, PageSize(), PROT_NONE,
+  stackPtr.Assign(MemoryRange::mmap(NULL, PageSize(), PROT_READ | PROT_WRITE,
                                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
   if (stackPtr.get() == MAP_FAILED)
     return;
 
-  *((volatile int*)stackPtr.get()) = 123;
+  TmpData *data = reinterpret_cast<TmpData*>(stackPtr.get());
+  data->crash_timestamp = ProcessTimeStamp_Now();
+  mprotect(stackPtr, stackPtr.GetLength(), PROT_NONE);
+  data->crash_int = 123;
   stackPtr.Assign(MAP_FAILED, 0);
-  if (signalHandlingBroken) {
+  if (signalHandlingBroken || signalHandlingSlow) {
     /* Restore the original segfault signal handler. */
     sys_sigaction(SIGSEGV, &this->action, NULL);
     return;
   }
 
   /* Setup an alternative stack if the already existing one is not big
    * enough, or if there is none. */
   if (sigaltstack(NULL, &oldStack) == 0) {
@@ -978,23 +1012,32 @@ SEGVHandler::~SEGVHandler()
     sigaltstack(&oldStack, NULL);
   /* Restore original signal handler */
   if (registeredHandler)
     sys_sigaction(SIGSEGV, &this->action, NULL);
 }
 
 /* Test handler for a deliberately triggered SIGSEGV that determines whether
  * useful information is provided to signal handlers, particularly whether
- * si_addr is filled in properly. */
+ * si_addr is filled in properly, and whether the segfault handler is called
+ * quickly enough. */
 void SEGVHandler::test_handler(int signum, siginfo_t *info, void *context)
 {
   SEGVHandler &that = ElfLoader::Singleton;
   if (signum != SIGSEGV || info == NULL || info->si_addr != that.stackPtr.get())
     that.signalHandlingBroken = true;
   mprotect(that.stackPtr, that.stackPtr.GetLength(), PROT_READ | PROT_WRITE);
+  TmpData *data = reinterpret_cast<TmpData*>(that.stackPtr.get());
+  uint64_t latency = ProcessTimeStamp_Now() - data->crash_timestamp;
+  DEBUG_LOG("SEGVHandler latency: %" PRIu64, latency);
+  /* See bug 886736 for timings on different devices, 150 ┬Ás is reasonably above
+   * the latency on "working" devices and seems to be reasonably fast to incur
+   * a huge overhead to on-demand decompression. */
+  if (latency > 150000)
+    that.signalHandlingSlow = true;
 }
 
 /* TODO: "properly" handle signal masks and flags */
 void SEGVHandler::handler(int signum, siginfo_t *info, void *context)
 {
   //ASSERT(signum == SIGSEGV);
   DEBUG_LOG("Caught segmentation fault @%p", info->si_addr);
 
--- a/mozglue/linker/ElfLoader.h
+++ b/mozglue/linker/ElfLoader.h
@@ -339,16 +339,17 @@ private:
   /**
    * Pointer to an alternative stack for signals. Only set if oldStack is
    * not set or not big enough.
    */
   MappedPtr stackPtr;
 
   bool registeredHandler;
   bool signalHandlingBroken;
+  bool signalHandlingSlow;
 };
 
 /**
  * Elf Loader class in charge of loading and bookkeeping libraries.
  */
 class ElfLoader: public SEGVHandler
 {
 public:
--- a/other-licenses/bsdiff/Makefile.in
+++ b/other-licenses/bsdiff/Makefile.in
@@ -35,9 +35,9 @@ endif
 ifeq ($(HOST_OS_ARCH),WINNT)
 HOST_EXTRA_LIBS += $(call EXPAND_LIBNAME,Ws2_32)
 endif
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/mozapps/update/updater
 
 include $(topsrcdir)/config/rules.mk
 
-HOST_CXXFLAGS += $(MOZ_BZ2_CFLAGS)</textarea>
+HOST_CXXFLAGS += $(MOZ_BZ2_CFLAGS)
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -23,16 +23,17 @@ import mozpack.path as mozpath
 from .common import CommonBackend
 from ..frontend.data import (
     ConfigFileSubstitution,
     Defines,
     DirectoryTraversal,
     Exports,
     GeneratedEventWebIDLFile,
     GeneratedWebIDLFile,
+    InstallationTarget,
     IPDLFile,
     LocalInclude,
     PreprocessedTestWebIDLFile,
     PreprocessedWebIDLFile,
     Program,
     SandboxDerived,
     TestWebIDLFile,
     VariablePassthru,
@@ -404,16 +405,19 @@ class RecursiveMakeBackend(CommonBackend
             self._process_program(obj.program, backend_file)
 
         elif isinstance(obj, TestManifest):
             self._process_test_manifest(obj, backend_file)
 
         elif isinstance(obj, LocalInclude):
             self._process_local_include(obj.path, backend_file)
 
+        elif isinstance(obj, InstallationTarget):
+            self._process_installation_target(obj, backend_file)
+
         self._backend_files[obj.srcdir] = backend_file
 
     def _fill_root_mk(self):
         """
         Create two files, root.mk and root-deps.mk, the first containing
         convenience variables, and the other dependency definitions for a
         hopefully proper directory traversal.
         """
@@ -868,16 +872,32 @@ class RecursiveMakeBackend(CommonBackend
             if not os.path.exists(source):
                 raise Exception('File listed in EXPORTS does not exist: %s' % source)
 
         children = exports.get_children()
         for subdir in sorted(children):
             self._process_exports(obj, children[subdir], backend_file,
                 namespace=namespace + subdir)
 
+    def _process_installation_target(self, obj, backend_file):
+        # A few makefiles need to be able to override the following rules via
+        # make XPI_NAME=blah commands, so we default to the lazy evaluation as
+        # much as possible here to avoid breaking things.
+        if obj.xpiname:
+            backend_file.write('XPI_NAME = %s\n' % (obj.xpiname))
+        if obj.subdir:
+            backend_file.write('DIST_SUBDIR = %s\n' % (obj.subdir))
+        if obj.target and not obj.is_custom():
+            backend_file.write('FINAL_TARGET = $(DEPTH)/%s\n' % (obj.target))
+        else:
+            backend_file.write('FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)\n')
+
+        if not obj.enabled:
+            backend_file.write('NO_DIST_INSTALL := 1\n')
+
     def _handle_idl_manager(self, manager):
         build_files = self._install_manifests['xpidl']
 
         for p in ('Makefile', 'backend.mk', '.deps/.mkdir.done',
             'xpt/.mkdir.done'):
             build_files.add_optional_exists(p)
 
         for idl in manager.idls.values():
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -15,16 +15,17 @@ contains the code for converting execute
 structures.
 """
 
 from __future__ import unicode_literals
 
 import os
 
 from collections import OrderedDict
+from .sandbox_symbols import compute_final_target
 
 
 class TreeMetadata(object):
     """Base class for all data being captured."""
 
 
 class ReaderSummary(TreeMetadata):
     """A summary of what the reader did."""
@@ -348,8 +349,34 @@ class LocalInclude(SandboxDerived):
     __slots__ = (
         'path',
     )
 
     def __init__(self, sandbox, path):
         SandboxDerived.__init__(self, sandbox)
 
         self.path = path
+
+class InstallationTarget(SandboxDerived):
+    """Describes the rules that affect where files get installed to."""
+
+    __slots__ = (
+        'xpiname',
+        'subdir',
+        'target',
+        'enabled'
+    )
+
+    def __init__(self, sandbox):
+        SandboxDerived.__init__(self, sandbox)
+
+        self.xpiname = sandbox.get('XPI_NAME', '')
+        self.subdir = sandbox.get('DIST_SUBDIR', '')
+        self.target = sandbox['FINAL_TARGET']
+        self.enabled = not sandbox.get('NO_DIST_INSTALL', False)
+
+    def is_custom(self):
+        """Returns whether or not the target is not derived from the default
+        given xpiname and subdir."""
+
+        return compute_final_target(dict(
+            XPI_NAME=self.xpiname,
+            DIST_SUBDIR=self.subdir)) == self.target
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -19,16 +19,17 @@ from mozpack.files import FileFinder
 
 from .data import (
     ConfigFileSubstitution,
     Defines,
     DirectoryTraversal,
     Exports,
     GeneratedEventWebIDLFile,
     GeneratedWebIDLFile,
+    InstallationTarget,
     IPDLFile,
     LocalInclude,
     PreprocessedTestWebIDLFile,
     PreprocessedWebIDLFile,
     Program,
     ReaderSummary,
     TestWebIDLFile,
     TestManifest,
@@ -203,16 +204,20 @@ class TreeMetadataEmitter(LoggingMixin):
             ('PREPROCESSED_WEBIDL_FILES', PreprocessedWebIDLFile),
             ('TEST_WEBIDL_FILES', TestWebIDLFile),
             ('WEBIDL_FILES', WebIDLFile),
         ]
         for sandbox_var, klass in simple_lists:
             for name in sandbox.get(sandbox_var, []):
                 yield klass(sandbox, name)
 
+        if sandbox.get('FINAL_TARGET') or sandbox.get('XPI_NAME') or \
+                sandbox.get('DIST_SUBDIR'):
+            yield InstallationTarget(sandbox)
+
         # While there are multiple test manifests, the behavior is very similar
         # across them. We enforce this by having common handling of all
         # manifests and outputting a single class type with the differences
         # described inside the instance.
         #
         # Keys are variable prefixes and values are tuples describing how these
         # manifests should be handled:
         #
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -176,16 +176,20 @@ class MozbuildSandbox(Sandbox):
             var = metadata.get('var', None)
             if var and var in ['TOOL_DIRS', 'TEST_TOOL_DIRS']:
                 d['IS_TOOL_DIR'] = True
 
             # Register functions.
             for name, func in FUNCTIONS.items():
                 d[name] = getattr(self, func[0])
 
+        # Initialize the exports that we need in the global.
+        extra_vars = self.metadata.get('exports', dict())
+        self._globals.update(extra_vars)
+
     def exec_file(self, path, filesystem_absolute=False):
         """Override exec_file to normalize paths and restrict file loading.
 
         If the path is absolute, behavior is governed by filesystem_absolute.
         If filesystem_absolute is True, the path is interpreted as absolute on
         the actual filesystem. If it is false, the path is treated as absolute
         within the current topsrcdir.
 
@@ -237,16 +241,40 @@ class MozbuildSandbox(Sandbox):
 
         for path in reldir:
             if path in self['TIERS'][tier][key]:
                 raise Exception('Directory has already been registered with '
                     'tier: %s' % path)
 
             self['TIERS'][tier][key].append(path)
 
+    def _export(self, varname):
+        """Export the variable to all subdirectories of the current path."""
+
+        exports = self.metadata.setdefault('exports', dict())
+        if varname in exports:
+            raise Exception('Variable has already been exported: %s' % varname)
+
+        try:
+            # Doing a regular self._globals[varname] causes a set as a side
+            # effect. By calling the dict method instead, we don't have any
+            # side effects.
+            exports[varname] = dict.__getitem__(self._globals, varname)
+        except KeyError:
+            self.last_name_error = KeyError('global_ns', 'get_unknown', varname)
+            raise self.last_name_error
+
+    def recompute_exports(self):
+        """Recompute the variables to export to subdirectories with the current
+        values in the subdirectory."""
+
+        if 'exports' in self.metadata:
+            for key in self.metadata['exports']:
+                self.metadata['exports'][key] = self[key]
+
     def _include(self, path):
         """Include and exec another file within the context of this one."""
 
         # exec_file() handles normalization and verification of the path.
         self.exec_file(path)
 
     def _warning(self, message):
         # FUTURE consider capturing warnings in a variable instead of printing.
@@ -675,16 +703,19 @@ class BuildReader(object):
                 if d in recurse_info:
                     raise SandboxValidationError(
                         'Directory (%s) registered multiple times in %s' % (
                             d, var))
 
                 recurse_info[d] = {'tier': metadata.get('tier', None),
                                    'parent': sandbox['RELATIVEDIR'],
                                    'var': var}
+                if 'exports' in sandbox.metadata:
+                    sandbox.recompute_exports()
+                    recurse_info[d]['exports'] = dict(sandbox.metadata['exports'])
 
         # We also have tiers whose members are directories.
         if 'TIERS' in sandbox:
             if not read_tiers:
                 raise SandboxValidationError(
                     'TIERS defined but it should not be')
 
             for tier, values in sandbox['TIERS'].items():
--- a/python/mozbuild/mozbuild/frontend/sandbox.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox.py
@@ -109,17 +109,24 @@ class GlobalNamespace(dict):
             pass
 
         # The variable isn't present yet. Fall back to VARIABLES.
         default = self._allowed_variables.get(name, None)
         if default is None:
             self.last_name_error = KeyError('global_ns', 'get_unknown', name)
             raise self.last_name_error
 
-        dict.__setitem__(self, name, copy.deepcopy(default[2]))
+        # If the default is specifically a lambda (or, rather, any function--but
+        # not a class that can be called), then it is actually a rule to
+        # generate the default that should be used.
+        default_rule = default[2]
+        if isinstance(default_rule, type(lambda: None)):
+            default_rule = default_rule(self)
+
+        dict.__setitem__(self, name, copy.deepcopy(default_rule))
         return dict.__getitem__(self, name)
 
     def __setitem__(self, name, value):
         if self._allow_all_writes:
             dict.__setitem__(self, name, value)
             return
 
         # We don't need to check for name.isupper() here because LocalNamespace
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
@@ -19,16 +19,28 @@ from __future__ import unicode_literals
 
 from collections import OrderedDict
 from mozbuild.util import (
     HierarchicalStringList,
     StrictOrderingOnAppendList,
 )
 
 
+def compute_final_target(variables):
+    """Convert the default value for FINAL_TARGET"""
+    basedir = 'dist/'
+    if variables['XPI_NAME']:
+        basedir += 'xpi-stage/' + variables['XPI_NAME']
+    else:
+        basedir += 'bin'
+    if variables['DIST_SUBDIR']:
+        basedir += '/' + variables['DIST_SUBDIR']
+    return basedir
+ 
+ 
 # This defines the set of mutable global variables.
 #
 # Each variable is a tuple of:
 #
 #   (storage_type, input_types, default_value, docs, tier)
 #
 # Tier says for which specific tier the variable has an effect.
 # Valid tiers are:
@@ -493,16 +505,42 @@ VARIABLES = {
 
     'WEBRTC_SIGNALLING_TEST_MANIFESTS': (StrictOrderingOnAppendList, list, [],
         """List of manifest files defining WebRTC signalling tests.
         """, None),
 
     'XPCSHELL_TESTS_MANIFESTS': (StrictOrderingOnAppendList, list, [],
         """List of manifest files defining xpcshell tests.
         """, None),
+
+    # The following variables are used to control the target of installed files.
+    'XPI_NAME': (unicode, unicode, "",
+        """The name of an extension XPI to generate.
+
+        When this variable is present, the results of this directory will end up
+        being packaged into an extension instead of the main dist/bin results.
+        """, 'libs'),
+
+    'DIST_SUBDIR': (unicode, unicode, "",
+        """The name of an alternate directory to install files to.
+
+        When this variable is present, the results of this directory will end up
+        being placed in the $(DIST_SUBDIR) subdirectory of where it would
+        otherwise be placed.
+        """, 'libs'),
+
+    'FINAL_TARGET': (unicode, unicode, compute_final_target,
+        """The name of the directory to install targets to.
+
+        The directory is relative to the top of the object directory. The
+        default value is dependent on the values of XPI_NAME and DIST_SUBDIR. If
+        neither are present, the result is dist/bin. If XPI_NAME is present, the
+        result is dist/xpi-stage/$(XPI_NAME). If DIST_SUBDIR is present, then
+        the $(DIST_SUBDIR) directory of the otherwise default value is used.
+        """, 'libs'),
 }
 
 # The set of functions exposed to the sandbox.
 #
 # Each entry is a tuple of:
 #
 #  (method attribute, (argument types), docs)
 #
@@ -570,16 +608,44 @@ FUNCTIONS = {
            add_tier_dir('base', 'foo', static=True)
 
         Register a directory as having external content (same as static
         content, but traversed with export, libs, and tools subtiers::
 
            add_tier_dir('base', 'bar', external=True)
         """),
 
+    'export': ('_export', (str,),
+        """Make the specified variable available to all child directories.
+
+        The variable specified by the argument string is added to the
+        environment of all directories specified in the DIRS, PARALLEL_DIRS,
+        TOOL_DIRS, TEST_DIRS, and TEST_TOOL_DIRS variables. If those directories
+        themselves have child directories, the variable will be exported to all
+        of them.
+
+        The value used for the variable is the final value at the end of the
+        moz.build file, so it is possible (but not recommended style) to place
+        the export before the definition of the variable.
+
+        This function is limited to the upper-case variables that have special
+        meaning in moz.build files.
+
+        NOTE: Please consult with a build peer before adding a new use of this
+        function.
+
+        Example usage
+        ^^^^^^^^^^^^^
+
+        To make all children directories install as the given extension::
+
+          XPI_NAME = 'cool-extension'
+          export('XPI_NAME')
+        """),
+
     'warning': ('_warning', (str,),
         """Issue a warning.
 
         Warnings are string messages that are printed during execution.
 
         Warnings are ignored during execution.
         """),
 
--- a/python/mozbuild/mozbuild/test/backend/common.py
+++ b/python/mozbuild/mozbuild/test/backend/common.py
@@ -83,16 +83,21 @@ CONFIGS = {
         'non_global_defines': [],
         'substs': [],
     },
     'local_includes': {
         'defines': [],
         'non_global_defines': [],
         'substs': [],
     },
+    'final_target': {
+        'defines': [],
+        'non_global_defines': [],
+        'substs': [],
+    },
 }
 
 
 class BackendTester(unittest.TestCase):
     def _get_environment(self, name):
         """Obtain a new instance of a ConfigEnvironment for a known profile.
 
         A new temporary object directory is created for the environment. The
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/both/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+XPI_NAME = 'mycrazyxpi'
+DIST_SUBDIR = 'asubdir'
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/dist-subdir/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_SUBDIR = 'asubdir'
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/final-target/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET = 'random-final-target'
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ['xpi-name', 'dist-subdir', 'both', 'final-target']
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/xpi-name/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+XPI_NAME = 'mycrazyxpi'
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -500,10 +500,43 @@ class TestRecursiveMakeBackend(BackendTe
         expected = [
             'LOCAL_INCLUDES += -I$(topsrcdir)/bar/baz',
             'LOCAL_INCLUDES += -I$(srcdir)/foo',
         ]
 
         found = [str for str in lines if str.startswith('LOCAL_INCLUDES')]
         self.assertEqual(found, expected)
 
+    def test_final_target(self):
+        """Test that FINAL_TARGET is written to backend.mk correctly."""
+        env = self._consume('final_target', RecursiveMakeBackend)
+
+        final_target_rule = "FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)"
+        print([x for x in os.walk(env.topobjdir)])
+        expected = dict()
+        expected[env.topobjdir] = []
+        expected[os.path.join(env.topobjdir, 'both')] = [
+            'XPI_NAME = mycrazyxpi',
+            'DIST_SUBDIR = asubdir',
+            final_target_rule
+        ]
+        expected[os.path.join(env.topobjdir, 'dist-subdir')] = [
+            'DIST_SUBDIR = asubdir',
+            final_target_rule
+        ]
+        expected[os.path.join(env.topobjdir, 'xpi-name')] = [
+            'XPI_NAME = mycrazyxpi',
+            final_target_rule
+        ]
+        expected[os.path.join(env.topobjdir, 'final-target')] = [
+            'FINAL_TARGET = $(DEPTH)/random-final-target'
+        ]
+        for key, expected_rules in expected.iteritems():
+            backend_path = os.path.join(key, 'backend.mk')
+            lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
+            found = [str for str in lines if
+                str.startswith('FINAL_TARGET') or str.startswith('XPI_NAME') or
+                str.startswith('DIST_SUBDIR')]
+            self.assertEqual(found, expected_rules)
+
+
 if __name__ == '__main__':
     main()
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/inheriting-variables/bar/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_MODULE = 'bazbar'
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/inheriting-variables/foo/baz/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/inheriting-variables/foo/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ['baz']
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/inheriting-variables/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_MODULE = 'foobar'
+export("XPIDL_MODULE")
+
+DIRS += ['foo', 'bar']
--- a/python/mozbuild/mozbuild/test/frontend/test_reader.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_reader.py
@@ -248,10 +248,21 @@ class TestBuildReader(unittest.TestCase)
         reader = self.reader('reader-error-traversal-tools')
 
         with self.assertRaises(BuildReaderError) as bre:
             list(reader.read_topsrcdir())
 
         e = bre.exception
         self.assertIn('The DIRS variable is not allowed in such directories.', str(e))
 
+    def test_inheriting_variables(self):
+        reader = self.reader('inheriting-variables')
+
+        sandboxes = list(reader.read_topsrcdir())
+
+        self.assertEqual(len(sandboxes), 4)
+        self.assertEqual([sandbox['RELATIVEDIR'] for sandbox in sandboxes],
+            ['', 'foo', 'foo/baz', 'bar'])
+        self.assertEqual([sandbox['XPIDL_MODULE'] for sandbox in sandboxes],
+            ['foobar', 'foobar', 'foobar', 'bazbar'])
+
 if __name__ == '__main__':
     main()
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -929,16 +929,22 @@ void nsNSSComponent::setValidationOption
   PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
 
   setNonPkixOcspEnabled(ocspEnabled);
 
   CERT_SetOCSPFailureMode( ocspRequired ?
                            ocspMode_FailureIsVerificationFailure
                            : ocspMode_FailureIsNotAVerificationFailure);
 
+  int OCSPTimeoutSeconds = 3;
+  if (ocspRequired || anyFreshRequired) {
+    OCSPTimeoutSeconds = 10;
+  }
+  CERT_SetOCSPTimeout(OCSPTimeoutSeconds);
+
   mDefaultCertVerifier = new CertVerifier(
       aiaDownloadEnabled ? 
         CertVerifier::missing_cert_download_on : CertVerifier::missing_cert_download_off,
       crlDownloading ?
         CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
       ocspEnabled ? 
         CertVerifier::ocsp_on : CertVerifier::ocsp_off,
       ocspRequired ? 
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -1186,16 +1186,24 @@ class Marionette(object):
           marionette.import_script(js)
           assert "i'm a test function!" == self.marionette.execute_script("return testFunc();")
         '''
         js = ''
         with open(js_file, 'r') as f:
             js = f.read()
         return self._send_message('importScript', 'ok', script=js)
 
+    def clear_imported_scripts(self):
+        '''
+        Clears all imported scripts in this context, ie: calling clear_imported_scripts in chrome
+        context will clear only scripts you imported in chrome, and will leave the scripts
+        you imported in content context.
+        '''
+        return self._send_message('clearImportedScripts', 'ok')
+
     def add_cookie(self, cookie):
         """
         Adds a cookie to your current session.
 
         :param cookie: A dictionary object, with required keys - "name" and
          "value"; optional keys - "path", "domain", "secure", "expiry".
 
         Usage example:
--- a/testing/marionette/client/marionette/runtests.py
+++ b/testing/marionette/client/marionette/runtests.py
@@ -628,23 +628,23 @@ class MarionetteTestRunner(object):
     def cleanup(self):
         if self.httpd:
             self.httpd.stop()
 
     __del__ = cleanup
 
     def generate_xml(self, results_list):
 
-        def _extract_xml(test, text='', result='passed'):
-            cls_name = test.__class__.__name__
-
+        def _extract_xml(test, class_name, text='', result='passed'):
             testcase = doc.createElement('testcase')
-            testcase.setAttribute('classname', cls_name)
+            testcase.setAttribute('classname', class_name)
             testcase.setAttribute('name', unicode(test).split()[0])
-            testcase.setAttribute('time', str(test.duration))
+            # XXX - Bug 927606
+            # testcase.setAttribute('time', str(test.duration))
+            testcase.setAttribute('time', '0')
             testsuite.appendChild(testcase)
 
             if result in ['failure', 'error', 'skipped']:
                 f = doc.createElement(result)
                 f.setAttribute('message', 'test %s' % result)
                 f.appendChild(doc.createTextNode(text))
                 testcase.appendChild(f)
 
@@ -668,37 +668,37 @@ class MarionetteTestRunner(object):
                                              for results in results_list])))
         if hasattr(results, 'skipped'):
             testsuite.setAttribute('skips', str(sum([len(results.skipped) +
                                                      len(results.expectedFailures)
                                                      for results in results_list])))
 
         for results in results_list:
 
-            for tup in results.errors:
-                _extract_xml(tup[0], text=tup[1], result='error')
+            for result in results.errors:
+                _extract_xml(result.name, result.test_class, text=result.reason, result='error')
 
-            for tup in results.failures:
-                _extract_xml(tup[0], text=tup[1], result='failure')
+            for result in results.failures:
+                _extract_xml(result.name, result.test_class, text=result.reason, result='failure')
 
             if hasattr(results, 'unexpectedSuccesses'):
                 for test in results.unexpectedSuccesses:
                     # unexpectedSuccesses is a list of Testcases only, no tuples
-                    _extract_xml(test, text='TEST-UNEXPECTED-PASS', result='failure')
+                    _extract_xml(test, result.test_class, text='TEST-UNEXPECTED-PASS', result='failure')
 
             if hasattr(results, 'skipped'):
-                for tup in results.skipped:
-                    _extract_xml(tup[0], text=tup[1], result='skipped')
+                for result in results.skipped:
+                    _extract_xml(result.name, result.test_class, text=result.reason, result='skipped')
 
             if hasattr(results, 'expectedFailures'):
-                for tup in results.expectedFailures:
-                    _extract_xml(tup[0], text=tup[1], result='skipped')
+                for result in results.expectedFailures:
+                    _extract_xml(result.name, result.test_class, text=result.reason, result='skipped')
 
-            for test in results.tests_passed:
-                _extract_xml(test)
+            for result in results.tests_passed:
+                _extract_xml(result.name, result.test_class)
 
         doc.appendChild(testsuite)
         return doc.toprettyxml(encoding='utf-8')
 
 
 class MarionetteTestOptions(OptionParser):
 
     def __init__(self, **kwargs):
--- a/testing/marionette/client/marionette/tests/unit/test_import_script.py
+++ b/testing/marionette/client/marionette/tests/unit/test_import_script.py
@@ -1,23 +1,110 @@
-
 # 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 os
 from marionette_test import MarionetteTestCase
+from errors import JavascriptException
 
 class TestImportScript(MarionetteTestCase):
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+
+    def clear_other_context(self):
+        self.marionette.set_context("chrome")
+        self.marionette.clear_imported_scripts()
+        self.marionette.set_context("content")
+
+    def check_file_exists(self):
+        return self.marionette.execute_script("""
+          let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
+          let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); 
+          return importedScripts.exists();
+        """, special_powers=True)
+
+    def get_file_size(self):
+        return self.marionette.execute_script("""
+          let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
+          let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); 
+          return importedScripts.fileSize;
+        """, special_powers=True)
+
     def test_import_script(self):
         js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
         self.marionette.import_script(js)
         self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
         self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
 
+    def test_import_script_twice(self):
+        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
+        self.marionette.import_script(js)
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+        self.assertTrue(self.check_file_exists())
+        file_size = self.get_file_size()
+        self.assertNotEqual(file_size, None)
+        self.marionette.import_script(js)
+        file_size = self.get_file_size()
+        self.assertEqual(file_size, self.get_file_size())
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+
+    def test_import_two_scripts_twice(self):
+        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
+        self.marionette.import_script(js)
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+        self.assertTrue(self.check_file_exists())
+        file_size = self.get_file_size()
+        self.assertNotEqual(file_size, None)
+        self.marionette.import_script(js)
+        # same script should not append to file
+        self.assertEqual(file_size, self.get_file_size())
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
+        self.marionette.import_script(js)
+        new_size = self.get_file_size()
+        # new script should append to file
+        self.assertNotEqual(file_size, new_size)
+        file_size = new_size
+        self.assertEqual("i'm yet another test function!",
+                    self.marionette.execute_script("return testAnotherFunc();"))
+        self.assertEqual("i'm yet another test function!",
+                    self.marionette.execute_async_script("marionetteScriptFinished(testAnotherFunc());"))
+        self.marionette.import_script(js)
+        # same script should not append to file
+        self.assertEqual(file_size, self.get_file_size())
+
+    def test_import_script_and_clear(self):
+        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
+        self.marionette.import_script(js)
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+        self.marionette.clear_imported_scripts()
+        self.assertFalse(self.check_file_exists())
+        self.assertRaises(JavascriptException, self.marionette.execute_script, "return testFunc();")
+        self.assertRaises(JavascriptException, self.marionette.execute_async_script, "marionetteScriptFinished(testFunc());")
+
+    def test_import_script_and_clear_in_chrome(self):
+        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
+        self.marionette.import_script(js)
+        self.assertTrue(self.check_file_exists())
+        file_size = self.get_file_size()
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+        self.clear_other_context()
+        # clearing other context's script file should not affect ours
+        self.assertTrue(self.check_file_exists())
+        self.assertEqual(file_size, self.get_file_size())
+        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
+        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
+
     def test_importing_another_script_and_check_they_append(self):
         firstjs = os.path.abspath(
                 os.path.join(__file__, os.path.pardir, "importscript.js"))
         secondjs = os.path.abspath(
                 os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
 
         self.marionette.import_script(firstjs)
         self.marionette.import_script(secondjs)
@@ -26,9 +113,30 @@ class TestImportScript(MarionetteTestCas
                 self.marionette.execute_script("return testFunc();"))
 
         self.assertEqual("i'm yet another test function!",
                     self.marionette.execute_script("return testAnotherFunc();"))
 
 class TestImportScriptChrome(TestImportScript):
     def setUp(self):
         MarionetteTestCase.setUp(self)
+        self.marionette.set_script_timeout(30000)
         self.marionette.set_context("chrome")
+
+    def clear_other_context(self):
+        self.marionette.set_context("content")
+        self.marionette.clear_imported_scripts()
+        self.marionette.set_context("chrome")
+
+    def check_file_exists(self):
+        return self.marionette.execute_async_script("""
+          let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
+          let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); 
+          marionetteScriptFinished(importedScripts.exists());
+        """)
+
+    def get_file_size(self):
+        return self.marionette.execute_async_script("""
+          let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
+          let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); 
+          marionetteScriptFinished(importedScripts.fileSize);
+        """)
+
--- a/testing/marionette/mach_commands.py
+++ b/testing/marionette/mach_commands.py
@@ -110,10 +110,11 @@ class MachCommands(MachCommandBase):
     @CommandArgument('tests', nargs='*', metavar='TESTS',
         help='Path to test(s) to run.')
     def run_marionette_test(self, tests, address=None, testtype=None):
         if self.substs.get('ENABLE_MARIONETTE') != '1':
             print(MARIONETTE_DISABLED % ('marionette-test',
                                          self.mozconfig['path']))
             return 1
 
+        bin = self.get_binary_path('app')
         return run_marionette(tests, bin=bin, testtype=testtype,
             topsrcdir=self.topsrcdir, address=address)
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -93,17 +93,17 @@ let modalHandler = function() {
  * If the actor returns an ID, we start the listeners. Otherwise, nothing happens.
  */
 function registerSelf() {
   let msg = {value: winUtil.outerWindowID, href: content.location.href};
   let register = sendSyncMessage("Marionette:register", msg);
 
   if (register[0]) {
     listenerId = register[0].id;
-    importedScripts = FileUtils.File(register[0].importedScripts);
+    importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
     startListeners();
   }
 }
 
 /**
  * Add a message listener that's tied to our listenerId.
  */
 function addMessageListenerId(messageName, handler) {
--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -129,17 +129,18 @@ function MarionetteServerConnection(aPre
   this.pageTimeout = null;
   this.timer = null;
   this.inactivityTimer = null;
   this.heartbeatCallback = function () {}; // called by simpletest methods
   this.marionetteLog = new MarionetteLogObj();
   this.command_id = null;
   this.mainFrame = null; //topmost chrome frame
   this.curFrame = null; // chrome iframe that currently has focus
-  this.importedScripts = FileUtils.getFile('TmpD', ['marionettescriptchrome']);
+  this.importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
+  this.importedScriptHashes = {"chrome" : [], "content": []};
   this.currentFrameElement = null;
   this.testName = null;
   this.mozBrowserClose = null;
 }
 
 MarionetteServerConnection.prototype = {
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
@@ -461,16 +462,26 @@ MarionetteServerConnection.prototype = {
     }
   },
 
   getCommandId: function MDA_getCommandId() {
     return this.uuidGen.generateUUID().toString();
   },
 
   /**
+    * Given a file name, this will delete the file from the temp directory if it exists
+    */
+  deleteFile: function(filename) {
+    let file = FileUtils.getFile('TmpD', [filename.toString()]);
+    if (file.exists()) {
+      file.remove(true);
+    }
+  },
+
+  /**
    * Marionette API:
    *
    * All methods implementing a command from the client should create a
    * command_id, and then use this command_id in all messages exchanged with
    * the frame scripts and with responses sent to the client.  This prevents
    * commands and responses from getting out-of-sync, which can happen in
    * the case of execute_async calls that timeout and then later send a
    * response, and other situations.  See bug 779011. See setScriptTimeout()
@@ -1942,17 +1953,23 @@ MarionetteServerConnection.prototype = {
       let winEnum = this.getWinEnumerator();
       while (winEnum.hasMoreElements()) {
         numOpenWindows += 1;
         winEnum.getNext();
       }
 
       // if there is only 1 window left, delete the session
       if (numOpenWindows === 1){
-        this.sessionTearDown();
+        try {
+          this.sessionTearDown();
+        }
+        catch (e) {
+          this.sendError("Could not clear session", 500, e.name + ": " + e.message, command_id);
+          return;
+        }
         this.sendOk(command_id);
         return;
       }
 
       try{
         this.messageManager.removeDelayedFrameScript(FRAME_SCRIPT); 
         this.getCurrentWindow().close();
         this.sendOk(command_id);
@@ -1999,30 +2016,33 @@ MarionetteServerConnection.prototype = {
       this.curBrowser.frameManager.removeMessageManagerListeners(this.globalMessageManager);
     }
     this.switchToGlobalMessageManager();
     // reset frame to the top-most frame
     this.curFrame = null;
     if (this.mainFrame) {
       this.mainFrame.focus();
     }
-    try {
-      this.importedScripts.remove(false);
-    }
-    catch (e) {
-    }
+    this.deleteFile('marionetteChromeScripts');
+    this.deleteFile('marionetteContentScripts');
   },
 
   /**
    * Processes the 'deleteSession' request from the client by tearing down
    * the session and responding 'ok'.
    */
-  deleteSession: function MDA_sessionTearDown() {
+  deleteSession: function MDA_deleteSession() {
     let command_id = this.command_id = this.getCommandId();
-    this.sessionTearDown();
+    try {
+      this.sessionTearDown();
+    }
+    catch (e) {
+      this.sendError("Could not delete session", 500, e.name + ": " + e.message, command_id);
+      return;
+    }
     this.sendOk(command_id);
   },
 
   /**
    * Returns the current status of the Application Cache
    */
   getAppCacheStatus: function MDA_getAppCacheStatus(aRequest) {
     this.command_id = this.getCommandId();
@@ -2063,16 +2083,33 @@ MarionetteServerConnection.prototype = {
     catch(e) {
       this.sendError(e.message, e.code, e.stack, -1);
       return;
     }
   },
   
   importScript: function MDA_importScript(aRequest) {
     let command_id = this.command_id = this.getCommandId();
+    let converter =
+      Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
+          createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+    converter.charset = "UTF-8";
+    let result = {};
+    let data = converter.convertToByteArray(aRequest.parameters.script, result);
+    let ch = Components.classes["@mozilla.org/security/hash;1"]
+                       .createInstance(Components.interfaces.nsICryptoHash);
+    ch.init(ch.MD5);
+    ch.update(data, data.length);
+    let hash = ch.finish(true);
+    if (this.importedScriptHashes[this.context].indexOf(hash) > -1) {
+        //we have already imported this script
+        this.sendOk(command_id);
+        return;
+    }
+    this.importedScriptHashes[this.context].push(hash);
     if (this.context == "chrome") {
       let file;
       if (this.importedScripts.exists()) {
         file = FileUtils.openFileOutputStream(this.importedScripts,
             FileUtils.MODE_APPEND | FileUtils.MODE_WRONLY);
       }
       else {
         //Note: The permission bits here don't actually get set (bug 804563)
@@ -2088,16 +2125,33 @@ MarionetteServerConnection.prototype = {
     }
     else {
       this.sendAsync("importScript",
                      { script: aRequest.parameters.script },
                      command_id);
     }
   },
 
+  clearImportedScripts: function MDA_clearImportedScripts(aRequest) {
+    let command_id = this.command_id = this.getCommandId();
+    try {
+      if (this.context == "chrome") {
+        this.deleteFile('marionetteChromeScripts');
+      }
+      else {
+        this.deleteFile('marionetteContentScripts');
+      }
+    }
+    catch (e) {
+      this.sendError("Could not clear imported scripts", 500, e.name + ": " + e.message, command_id);
+      return;
+    }
+    this.sendOk(command_id);
+  },
+
   /**
    * Takes a screenshot of a DOM node. If there is no node given a screenshot
    * of the window will be taken.
    */
   screenShot: function MDA_saveScreenshot(aRequest) {
     this.command_id = this.getCommandId();
     this.sendAsync("screenShot",
                    {
@@ -2205,17 +2259,16 @@ MarionetteServerConnection.prototype = {
         }
         let reg = {};
         if (!browserType || browserType != "content") {
           //curBrowser holds all the registered frames in knownFrames
           reg.id = this.curBrowser.register(this.generateFrameId(message.json.value),
                                             listenerWindow);
         }
         this.curBrowser.elementManager.seenItems[reg.id] = Cu.getWeakReference(listenerWindow);
-        reg.importedScripts = this.importedScripts.path;
         if (nullPrevious && (this.curBrowser.curFrameId != null)) {
           if (!this.sendAsync("newSession",
                               { B2G: (appName == "B2G") },
                               this.newSessionCommandId)) {
             return;
           }
           if (this.curBrowser.newSession) {
             this.sendResponse(reg.id, this.newSessionCommandId);
@@ -2271,16 +2324,17 @@ MarionetteServerConnection.prototype.req
   "getWindow":  MarionetteServerConnection.prototype.getWindow,
   "getWindows":  MarionetteServerConnection.prototype.getWindows,
   "getActiveFrame": MarionetteServerConnection.prototype.getActiveFrame,
   "switchToFrame": MarionetteServerConnection.prototype.switchToFrame,
   "switchToWindow": MarionetteServerConnection.prototype.switchToWindow,
   "deleteSession": MarionetteServerConnection.prototype.deleteSession,
   "emulatorCmdResult": MarionetteServerConnection.prototype.emulatorCmdResult,
   "importScript": MarionetteServerConnection.prototype.importScript,
+  "clearImportedScripts": MarionetteServerConnection.prototype.clearImportedScripts,
   "getAppCacheStatus": MarionetteServerConnection.prototype.getAppCacheStatus,
   "closeWindow": MarionetteServerConnection.prototype.closeWindow,
   "setTestName": MarionetteServerConnection.prototype.setTestName,
   "screenShot": MarionetteServerConnection.prototype.screenShot,
   "addCookie": MarionetteServerConnection.prototype.addCookie,
   "getAllCookies": MarionetteServerConnection.prototype.getAllCookies,
   "deleteAllCookies": MarionetteServerConnection.prototype.deleteAllCookies,
   "deleteCookie": MarionetteServerConnection.prototype.deleteCookie,
--- a/testing/mochitest/Makefile.in
+++ b/testing/mochitest/Makefile.in
@@ -5,18 +5,16 @@
 
 NO_JS_MANIFEST = 1
 MOZ_CHROME_FILE_FORMAT = jar
 DIST_FILES = install.rdf
 
 # Used in install.rdf
 USE_EXTENSION_MANIFEST = 1
 
-XPI_NAME = mochijar
-
 # we turn this off for UNIVERSAL_BINARY
 CHROME_JAR = 1
 
 include $(topsrcdir)/config/rules.mk
 # We're installing to _tests/testing/mochitest, so this is the depth
 # necessary for relative objdir paths.
 TARGET_DEPTH = ../../..
 include $(topsrcdir)/build/automation-build.mk
@@ -52,16 +50,17 @@ include $(topsrcdir)/build/automation-bu
 		redirect.html \
 		$(topsrcdir)/build/pgo/server-locations.txt \
 		$(topsrcdir)/netwerk/test/httpserver/httpd.js \
 		pywebsocket_wrapper.py \
 		android.json \
 		androidx86.json \
 		b2g.json \
 		b2g-desktop.json \
+		b2g-debug.json \
 		b2g_start_script.js \
 		root-ev-tester.crl \
 		intermediate-ev-tester.crl \
 		$(NULL)	
 
 ifeq ($(MOZ_BUILD_APP),mobile/android)
 _SERV_FILES += \
   $(topsrcdir)/mobile/android/base/tests/robocop.ini \
--- a/testing/mochitest/android.json
+++ b/testing/mochitest/android.json
@@ -5,16 +5,17 @@
  "content/base/test/test_bug338583.html": "",
  "content/base/test/test_bug466080.html": "",
  "content/base/test/test_bug475156.html": "bug 855762",
  "content/base/test/test_bug482935.html": "bug 855762",
  "content/base/test/test_bug503481.html": "TIMED_OUT",
  "content/base/test/test_bug503481b.html": "TIMED_OUT",
  "content/base/test/test_bug505783.html": "TIMED_OUT",
  "content/base/test/test_bug590812.html": "bug 687032",
+ "content/base/test/test_bug827160.html": "needs plugin support",
  "content/base/test/test_copypaste.html": "bug 904183",
  "content/base/test/test_copypaste.xhtml": "bug 904183",
  "content/base/test/test_copypaste.xul": "bug 904183",
  "content/base/test/test_CrossSiteXHR.html": "",
  "content/base/test/test_CrossSiteXHR_cache.html": "",
  "content/base/test/test_CrossSiteXHR_origin.html": "",
  "content/base/test/csp/test_CSP.html": "TIMED_OUT",
  "content/base/test/csp/test_CSP_frameancestors.html": "",
--- a/testing/mochitest/androidx86.json
+++ b/testing/mochitest/androidx86.json
@@ -6,16 +6,17 @@
  "content/base/test/test_bug338583.html": "",
  "content/base/test/test_bug466080.html": "",
  "content/base/test/test_bug475156.html": "bug 855762",
  "content/base/test/test_bug482935.html": "bug 855762",
  "content/base/test/test_bug503481.html": "TIMED_OUT",
  "content/base/test/test_bug503481b.html": "TIMED_OUT",
  "content/base/test/test_bug505783.html": "TIMED_OUT",
  "content/base/test/test_bug590812.html": "bug 687032",
+ "content/base/test/test_bug827160.html": "needs plugin support",
  "content/base/test/test_copypaste.html": "bug 904183",
  "content/base/test/test_copypaste.xhtml": "bug 904183",
  "content/base/test/test_copypaste.xul": "bug 904183",
  "content/base/test/test_CrossSiteXHR.html": "",
  "content/base/test/test_CrossSiteXHR_cache.html": "",
  "content/base/test/test_CrossSiteXHR_origin.html": "",
  "content/base/test/csp/test_CSP.html": "TIMED_OUT",
  "content/base/test/csp/test_CSP_frameancestors.html": "",
copy from testing/mochitest/b2g.json
copy to testing/mochitest/b2g-debug.json
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -193,16 +193,17 @@
     "docshell/test/navigation/test_popup-navigates-children.html":"Needs multiple window.open support, also uses docshelltreenode",
     "docshell/test/test_bug590573.html":"queryinterfaces into webnavigation, might suffer from something similar as bug 823022",
     "dom/devicestorage/ipc/test_ipc.html":"nested ipc not working",
 
     "dom/indexedDB/ipc/test_ipc.html":"nested ipc not working",
     "dom/indexedDB/test/test_lowDiskSpace.html":"this needs probably modification for notifyObserversInParentProcess to be similar as pushPermissions",
 
     "content/base/test/test_object.html":"needs plugin support",
+    "content/base/test/test_bug827160.html": "needs plugin support",
 
     "content/base/test/csp/test_CSP_evalscript.html":"observer not working",
     "content/base/test/csp/test_CSP_evalscript_getCRMFRequest.html":"observer not working",
     "content/base/test/csp/test_CSP_frameancestors.html":"observer not working",
     "content/base/test/csp/test_CSP.html":"observer not working",
     "content/base/test/csp/test_bug836922_npolicies.html":"observer not working",
     "content/base/test/csp/test_CSP_bug916446.html":"observer not working",
 
--- a/testing/mochitest/b2g.json
+++ b/testing/mochitest/b2g.json
@@ -196,16 +196,17 @@
     "docshell/test/navigation/test_popup-navigates-children.html":"Needs multiple window.open support, also uses docshelltreenode",
     "docshell/test/test_bug590573.html":"queryinterfaces into webnavigation, might suffer from something similar as bug 823022",
     "dom/devicestorage/ipc/test_ipc.html":"nested ipc not working",
 
     "dom/indexedDB/ipc/test_ipc.html":"nested ipc not working",
     "dom/indexedDB/test/test_lowDiskSpace.html":"this needs probably modification for notifyObserversInParentProcess to be similar as pushPermissions",
 
     "content/base/test/test_object.html":"needs plugin support",
+    "content/base/test/test_bug827160.html": "needs plugin support",
 
     "content/base/test/csp/test_CSP_evalscript.html":"observer not working",
     "content/base/test/csp/test_CSP_evalscript_getCRMFRequest.html":"observer not working",
     "content/base/test/csp/test_CSP_frameancestors.html":"observer not working",
     "content/base/test/csp/test_CSP.html":"observer not working",
     "content/base/test/csp/test_bug836922_npolicies.html":"observer not working",
     "content/base/test/csp/test_CSP_bug916446.html":"observer not working",
 
--- a/testing/mochitest/chrome/Makefile.in
+++ b/testing/mochitest/chrome/Makefile.in
@@ -1,18 +1,19 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-include $(topsrcdir)/config/rules.mk
+INSTALL_TARGETS += _STATIC _STATIC_DIR
 
 _STATIC_FILES = test_sample.xul \
 		test_sanityChromeUtils.xul \
 		test_sanityPluginUtils.html \
 		test_sanityException.xul \
 		test_sanityException2.xul \
 		test_chromeGetTestFile.xul \
-		test-dir/ \
 		$(NULL)
 
-libs:: $(_STATIC_FILES)
-	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/$(relativesrcdir)
+_STATIC_DEST := $(DEPTH)/_tests/$(relativesrcdir)
+
+_STATIC_DIR_FILES := test-dir/test-file
+_STATIC_DIR_DEST := $(DEPTH)/_tests/$(relativesrcdir)/test-dir
--- a/testing/mochitest/moz.build
+++ b/testing/mochitest/moz.build
@@ -10,8 +10,10 @@ DIRS += [
     'dynamic',
     'tests',
     'chrome',
     'ssltunnel',
 ]
 
 if CONFIG['MOZ_BUILD_APP'] == 'mobile/android':
     DIRS += ['roboextender']
+
+XPI_NAME = 'mochijar'
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -894,19 +894,21 @@ class Mochitest(MochitestUtilsMixin):
     outputHandler.finish(didTimeout)
 
     # handle timeout
     if didTimeout:
       browserProcessId = outputHandler.browserProcessId
       self.handleTimeout(timeout, proc, utilityPath, debuggerInfo, browserProcessId)
 
     # record post-test information
-    if not status:
+    if status:
+      log.info("TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s", self.lastTestSeen, status)
+    else:
       self.lastTestSeen = 'Main app process exited normally'
-    log.info("INFO | runtests.py | exit %s", status)
+
     log.info("INFO | runtests.py | Application ran for: %s", str(datetime.now() - startTime))
 
     # Do a final check for zombie child processes.
     zombieProcesses = self.checkForZombies(processLog, utilityPath, debuggerInfo)
 
     # check for crashes
     minidump_path = os.path.join(self.profile.profile, "minidumps")
     crashed = mozcrash.check_for_crashes(minidump_path,
--- a/testing/specialpowers/Makefile.in
+++ b/testing/specialpowers/Makefile.in
@@ -4,18 +4,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 NO_JS_MANIFEST = 1
 MOZ_CHROME_FILE_FORMAT = flat
 DIST_FILES = \
   install.rdf \
   $(NULL)
 
-XPI_NAME=specialpowers
-
 # Used in install.rdf
 USE_EXTENSION_MANIFEST=1
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/testing/specialpowers
 
 include $(topsrcdir)/config/rules.mk
 
 libs-preqs = \
--- a/testing/specialpowers/moz.build
+++ b/testing/specialpowers/moz.build
@@ -2,8 +2,10 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXTRA_COMPONENTS += [
     'components/SpecialPowersObserver.js',
 ]
+
+XPI_NAME = 'specialpowers'
--- a/toolkit/crashreporter/google-breakpad/src/client/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/Makefile.in
@@ -1,10 +1,8 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-XPI_NAME 	= crashreporter
-
 LOCAL_INCLUDES 	= -I$(srcdir)/..
 
 # need static lib
 FORCE_STATIC_LIB = 1
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/Makefile.in
@@ -11,18 +11,16 @@ ifdef MOZ_THUMB2 #{
 # as a clobbered register yet gcc error's.  The generated assembly for
 # sys_clone() looks OK, so we chalk this up to a gcc/gas quirk and
 # work around it by telling gcc that the THUMB frame pointer is a
 # vanilla callee-save register.
 OS_CXXFLAGS += -fomit-frame-pointer
 MOZ_FRAMEPTR_FLAGS := -fomit-frame-pointer
 endif #}
 
-XPI_NAME 	= crashreporter
-
 VPATH += $(srcdir)/../log
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/toolkit/crashreporter/google-breakpad/src \
   $(NULL)
 
 # need static lib
 FORCE_STATIC_LIB = 1
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/moz.build
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/moz.build
@@ -9,8 +9,9 @@ MODULE = 'handler'
 CPP_SOURCES += [
     'exception_handler.cc',
     '../log/log.cc',
     'minidump_descriptor.cc',
 ]
 
 LIBRARY_NAME = 'exception_handler_s'
 
+XPI_NAME = 'crashreporter'
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/Makefile.in
@@ -1,14 +1,12 @@
 # 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/.
 
-XPI_NAME 	= crashreporter
-
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/toolkit/crashreporter/google-breakpad/src \
   $(NULL)
 
 # need static lib
 FORCE_STATIC_LIB = 1
 
 ifeq ($(OS_TARGET),Android)
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/moz.build
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/moz.build
@@ -9,8 +9,9 @@ MODULE = 'writer'
 CPP_SOURCES += [
     'linux_dumper.cc',
     'linux_ptrace_dumper.cc',
     'minidump_writer.cc',
 ]
 
 LIBRARY_NAME = 'minidump_writer_s'
 
+XPI_NAME = 'crashreporter'
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Makefile.in
@@ -1,10 +1,8 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-XPI_NAME 	= crashreporter
-
 LOCAL_INCLUDES 	= -I$(srcdir)/../../..
 
 # need static lib
 FORCE_STATIC_LIB = 1
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/moz.build
+++ b/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/moz.build
@@ -8,8 +8,9 @@ MODULE = 'crash_generation'
 
 CPP_SOURCES += [
     'crash_generation_client.cc',
     'crash_generation_server.cc',
 ]
 
 LIBRARY_NAME = 'crash_generation_s'
 
+XPI_NAME = 'crashreporter'
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/Makefile.in
@@ -1,10 +1,8 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-XPI_NAME 	= crashreporter
-
 LOCAL_INCLUDES 	= -I$(srcdir)/../../..
 
 # need static lib
 FORCE_STATIC_LIB = 1
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/handler/moz.build
+++ b/toolkit/crashreporter/google-breakpad/src/client/mac/handler/moz.build
@@ -10,8 +10,9 @@ CPP_SOURCES += [
     'breakpad_nlist_64.cc',
     'dynamic_images.cc',
     'exception_handler.cc',
     'minidump_generator.cc',
 ]
 
 LIBRARY_NAME = 'exception_handler_s'
 
+XPI_NAME = 'crashreporter'
--- a/toolkit/crashreporter/google-breakpad/src/client/moz.build
+++ b/toolkit/crashreporter/google-breakpad/src/client/moz.build
@@ -7,8 +7,9 @@
 MODULE = 'minidump_file_writer'
 
 CPP_SOURCES += [
     'minidump_file_writer.cc',
 ]
 
 LIBRARY_NAME = 'minidump_file_writer_s'
 
+XPI_NAME = 'crashreporter'
--- a/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/solaris/handler/Makefile.in
@@ -1,10 +1,8 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this