Merge m-c to inbound.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 10 Jul 2013 09:45:16 -0400
changeset 137975 468b35185c44a32fdb61d97c02cbdb4dc04731de
parent 137890 ad0550c091866af5f5abc5845d25b6fdd9b7c8d2 (current diff)
parent 137974 b3ff36cb6a1af8e0f01db0ef3f4eac985340a282 (diff)
child 137976 6064e0c9f89e18fc056ba3e3a28357706bd81d86
child 138005 dde4dcd6fa4678032cad2b65ae364f4f56d2b9e5
push id30765
push userryanvm@gmail.com
push dateWed, 10 Jul 2013 13:45:17 +0000
treeherdermozilla-inbound@468b35185c44 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone25.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 inbound.
browser/base/content/test/Makefile.in
browser/devtools/shared/test/browser_telemetry_toolboxtabs.js
browser/themes/linux/devtools/checkbox-dark.png
browser/themes/linux/devtools/checkbox-light.png
browser/themes/linux/devtools/dark-theme.css
browser/themes/linux/devtools/light-theme.css
browser/themes/linux/devtools/markup-view.css
browser/themes/osx/devtools/checkbox-dark.png
browser/themes/osx/devtools/checkbox-light.png
browser/themes/osx/devtools/dark-theme.css
browser/themes/osx/devtools/light-theme.css
browser/themes/osx/devtools/markup-view.css
browser/themes/windows/devtools/checkbox-dark.png
browser/themes/windows/devtools/checkbox-light.png
browser/themes/windows/devtools/dark-theme.css
browser/themes/windows/devtools/light-theme.css
browser/themes/windows/devtools/markup-view.css
content/base/src/nsDocument.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/test/test_bug571981.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/bindings/Bindings.conf
dom/imptests/failures/html/html/dom/documents/dta/test_document.body-getter.html.json
dom/imptests/failures/html/html/semantics/tabular-data/the-table-element/test_createTBody.html.json
dom/interfaces/events/nsIDOMPaintRequestList.idl
dom/webidl/WebIDL.mk
gfx/layers/ipc/AsyncPanZoomController.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/reftests/forms/button-first-letter-1-noref.html
layout/reftests/forms/button-first-letter-1-ref.html
layout/reftests/forms/button-first-letter-1.html
layout/reftests/forms/button-max-height-ref.html
layout/reftests/forms/button-max-height.html
layout/reftests/forms/checkbox-checked-native-notref.html
layout/reftests/forms/checkbox-checked-native.html
layout/reftests/forms/checkbox-checked-notref.html
layout/reftests/forms/checkbox-checked.html
layout/reftests/forms/checkbox-label-dynamic-ref.html
layout/reftests/forms/checkbox-label-dynamic.html
layout/reftests/forms/checkbox-radio-stretched-ref.html
layout/reftests/forms/checkbox-radio-stretched.html
layout/reftests/forms/indeterminate-checked-notref.html
layout/reftests/forms/indeterminate-checked.html
layout/reftests/forms/indeterminate-native-checked-notref.html
layout/reftests/forms/indeterminate-native-checked.html
layout/reftests/forms/indeterminate-native-unchecked-notref.html
layout/reftests/forms/indeterminate-native-unchecked.html
layout/reftests/forms/indeterminate-selector-ref.html
layout/reftests/forms/indeterminate-selector.html
layout/reftests/forms/indeterminate-unchecked-notref.html
layout/reftests/forms/indeterminate-unchecked.html
layout/reftests/forms/input-hidden-border.html
layout/reftests/forms/input-percentage-padding-ref.html
layout/reftests/forms/input-percentage-padding.html
layout/reftests/forms/input-text-baseline-1-ref.html
layout/reftests/forms/input-text-baseline-1.html
layout/reftests/forms/input-text-bounds-1-ref.html
layout/reftests/forms/input-text-bounds-1.html
layout/reftests/forms/input-text-centering-1-ref.xul
layout/reftests/forms/input-text-centering-1.xul
layout/reftests/forms/input-text-dynamic-height-1-ref.xul
layout/reftests/forms/input-text-dynamic-height-1.xul
layout/reftests/forms/input-text-size-1-ref.html
layout/reftests/forms/input-text-size-1.html
layout/reftests/forms/input-text-size-2-ref.html
layout/reftests/forms/input-text-size-2.html
layout/reftests/forms/input/email/input-email-1.html
layout/reftests/forms/input/email/input-email-2.html
layout/reftests/forms/input/email/input-email-3.html
layout/reftests/forms/input/email/input-email-ref.html
layout/reftests/forms/input/file/input-file-background-ref.xul
layout/reftests/forms/input/file/input-file-background.html
layout/reftests/forms/input/file/input-file-color-inherit-ref.html
layout/reftests/forms/input/file/input-file-color-inherit.html
layout/reftests/forms/input/file/input-file-rtl-ref.xul
layout/reftests/forms/input/file/input-file-rtl.html
layout/reftests/forms/input/file/input-file-simple-ref.xul
layout/reftests/forms/input/file/input-file-simple.html
layout/reftests/forms/input/file/input-file-size.html
layout/reftests/forms/input/file/input-file-style-ref.xul
layout/reftests/forms/input/file/input-file-style.html
layout/reftests/forms/input/file/input-file-width-clip-ref.html
layout/reftests/forms/input/file/input-file-width-clip.html
layout/reftests/forms/input/range/input-75pct-common-ref.html
layout/reftests/forms/input/range/input-75pct-unthemed-common-ref.html
layout/reftests/forms/input/range/input-from-range-to-other-type-unthemed-1-ref.html
layout/reftests/forms/input/range/input-from-range-to-other-type-unthemed-1.html
layout/reftests/forms/input/range/input-range-different-fraction-of-range-unthemed-1-notref.html
layout/reftests/forms/input/range/input-range-different-fraction-of-range-unthemed-1.html
layout/reftests/forms/input/range/input-range-direction-unthemed-1-ref.html
layout/reftests/forms/input/range/input-range-direction-unthemed-1.html
layout/reftests/forms/input/range/input-range-moz-range-progress-1-ref.html
layout/reftests/forms/input/range/input-range-moz-range-progress-1.html
layout/reftests/forms/input/range/input-range-moz-range-progress-2-ref.html
layout/reftests/forms/input/range/input-range-moz-range-progress-2.html
layout/reftests/forms/input/range/input-range-moz-range-progress-3-ref.html
layout/reftests/forms/input/range/input-range-moz-range-progress-3.html
layout/reftests/forms/input/range/input-range-not-other-type-unthemed-1.html
layout/reftests/forms/input/range/input-range-not-other-type-unthemed-1a-notref.html
layout/reftests/forms/input/range/input-range-not-other-type-unthemed-1b-notref.html
layout/reftests/forms/input/range/input-range-not-other-type-unthemed-1c-notref.html
layout/reftests/forms/input/range/input-range-same-fraction-of-range-unthemed-1-ref.html
layout/reftests/forms/input/range/input-range-same-fraction-of-range-unthemed-1.html
layout/reftests/forms/input/range/input-stepDown-unthemed.html
layout/reftests/forms/input/range/input-stepDown.html
layout/reftests/forms/input/range/input-stepUp-unthemed.html
layout/reftests/forms/input/range/input-stepUp.html
layout/reftests/forms/input/range/input-to-range-from-other-type-unthemed-1-ref.html
layout/reftests/forms/input/range/input-to-range-from-other-type-unthemed-1.html
layout/reftests/forms/input/range/input-value-prop-unthemed.html
layout/reftests/forms/input/range/input-value-prop.html
layout/reftests/forms/input/range/input-valueAsNumber-prop-unthemed.html
layout/reftests/forms/input/range/input-valueAsNumber-prop.html
layout/reftests/forms/input/search/input-search-1.html
layout/reftests/forms/input/search/input-search-2.html
layout/reftests/forms/input/search/input-search-3.html
layout/reftests/forms/input/search/input-search-ref.html
layout/reftests/forms/input/tel/input-tel-1.html
layout/reftests/forms/input/tel/input-tel-2.html
layout/reftests/forms/input/tel/input-tel-3.html
layout/reftests/forms/input/tel/input-tel-ref.html
layout/reftests/forms/input/url/input-url-1.html
layout/reftests/forms/input/url/input-url-2.html
layout/reftests/forms/input/url/input-url-3.html
layout/reftests/forms/input/url/input-url-ref.html
layout/reftests/forms/legend-ref.html
layout/reftests/forms/legend.html
layout/reftests/forms/out-of-bounds-selectedindex-ref.html
layout/reftests/forms/out-of-bounds-selectedindex.html
layout/reftests/forms/radio-checked-native-notref.html
layout/reftests/forms/radio-checked-native.html
layout/reftests/forms/radio-checked-notref.html
layout/reftests/forms/radio-checked.html
layout/reftests/forms/radio-label-dynamic-ref.html
layout/reftests/forms/radio-label-dynamic.html
layout/reftests/forms/select-boguskids-ref.html
layout/reftests/forms/select-boguskids.html
layout/reftests/forms/select-dynamic-boguskids.html
layout/reftests/forms/select-multiple-ref.html
layout/reftests/forms/select-multiple.html
layout/reftests/forms/select-option-children-ref.html
layout/reftests/forms/select-option-children.html
layout/reftests/forms/textarea-in-dynamic-rtl-doc.html
layout/reftests/forms/textarea-in-ltr-doc-scrollbar.html
layout/reftests/forms/textarea-in-rtl-doc-scrollbar.html
layout/reftests/forms/textarea-ltr-scrollbar.html
layout/reftests/forms/textarea-ltr.html
layout/reftests/forms/textarea-no-resize.html
layout/reftests/forms/textarea-resize-background-ref.html
layout/reftests/forms/textarea-resize-background.html
layout/reftests/forms/textarea-resize-ref.html
layout/reftests/forms/textarea-resize.html
layout/reftests/forms/textarea-rtl-dynamic-attr.html
layout/reftests/forms/textarea-rtl-dynamic-style.html
layout/reftests/forms/textarea-rtl-scrollbar.html
layout/reftests/forms/textarea-rtl.html
layout/reftests/forms/textarea-setvalue-framereconstruction-1.html
layout/reftests/forms/textarea-setvalue-framereconstruction-ref.html
layout/reftests/forms/textbox-accesskey-1-notref.xul
layout/reftests/forms/textbox-accesskey-1.xul
layout/reftests/forms/textbox-accesskey-2-ref.xul
layout/reftests/forms/textbox-accesskey-2.xul
layout/reftests/forms/textbox-accesskey-3-notref.xul
layout/reftests/forms/textbox-accesskey-3-ref.xul
layout/reftests/forms/textbox-accesskey-3.xul
layout/reftests/forms/textbox-accesskey-4-notref.xul
layout/reftests/forms/textbox-accesskey-4-ref.xul
layout/reftests/forms/textbox-accesskey-4.xul
layout/reftests/forms/textbox-align-baseline-1-ref.xul
layout/reftests/forms/textbox-align-baseline-1.xul
layout/reftests/forms/textbox-setsize-ref.xul
layout/reftests/forms/textbox-setsize.xul
testing/testsuite-targets.mk
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "58d73404571f7619b478116dfec8faced97be13d", 
+    "revision": "5e60cb6fc0e09cefe242a6fb0159fbd09360cc1a", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1079,16 +1079,19 @@ pref("devtools.debugger.ui.panes-instrum
 pref("devtools.debugger.ui.panes-visible-on-startup", false);
 pref("devtools.debugger.ui.variables-sorting-enabled", true);
 pref("devtools.debugger.ui.variables-only-enum-visible", false);
 pref("devtools.debugger.ui.variables-searchbox-visible", false);
 
 // Enable the Profiler
 pref("devtools.profiler.enabled", true);
 
+// The default Profiler UI settings
+pref("devtools.profiler.ui.show-platform-data", false);
+
 // Enable the Network Monitor
 pref("devtools.netmonitor.enabled", true);
 
 // The default Network Monitor UI settings
 pref("devtools.netmonitor.panes-network-details-width", 450);
 pref("devtools.netmonitor.panes-network-details-height", 450);
 
 // Enable the Tilt inspector
@@ -1118,31 +1121,33 @@ pref("devtools.theme", "light");
 pref("devtools.gcli.hideIntro", false);
 
 // How eager are we to show help: never=1, sometimes=2, always=3
 pref("devtools.gcli.eagerHelper", 2);
 
 // Remember the Web Console filters
 pref("devtools.webconsole.filter.network", true);
 pref("devtools.webconsole.filter.networkinfo", true);
+pref("devtools.webconsole.filter.netwarn", true);
 pref("devtools.webconsole.filter.csserror", true);
 pref("devtools.webconsole.filter.cssparser", true);
 pref("devtools.webconsole.filter.exception", true);
 pref("devtools.webconsole.filter.jswarn", true);
 pref("devtools.webconsole.filter.jslog", true);
 pref("devtools.webconsole.filter.error", true);
 pref("devtools.webconsole.filter.warn", true);
 pref("devtools.webconsole.filter.info", true);
 pref("devtools.webconsole.filter.log", true);
 pref("devtools.webconsole.filter.secerror", true);
 pref("devtools.webconsole.filter.secwarn", true);
 
 // Remember the Browser Console filters
 pref("devtools.browserconsole.filter.network", true);
 pref("devtools.browserconsole.filter.networkinfo", true);
+pref("devtools.browserconsole.filter.netwarn", true);
 pref("devtools.browserconsole.filter.csserror", true);
 pref("devtools.browserconsole.filter.cssparser", true);
 pref("devtools.browserconsole.filter.exception", true);
 pref("devtools.browserconsole.filter.jswarn", true);
 pref("devtools.browserconsole.filter.jslog", true);
 pref("devtools.browserconsole.filter.error", true);
 pref("devtools.browserconsole.filter.warn", true);
 pref("devtools.browserconsole.filter.info", true);
copy from browser/config/tooltool-manifests/linux32/clang.manifest
copy to browser/config/tooltool-manifests/linux32/asan.manifest
copy from browser/config/tooltool-manifests/linux64/clang.manifest
copy to browser/config/tooltool-manifests/linux64/asan.manifest
copy from browser/config/tooltool-manifests/macosx64/releng.manifest
copy to browser/config/tooltool-manifests/macosx64/asan.manifest
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -309,17 +309,18 @@ let DebuggerController = {
     }, { useSourceMaps: Prefs.sourceMapsEnabled });
   },
 
   /**
    * Detach and reattach to the thread actor with useSourceMaps true, blow
    * away old scripts and get sources again.
    */
   reconfigureThread: function(aUseSourceMaps) {
-    this.client.reconfigureThread(aUseSourceMaps, (aResponse) => {
+    this.client.reconfigureThread({ useSourceMaps: aUseSourceMaps },
+                                  (aResponse) => {
       if (aResponse.error) {
         let msg = "Couldn't reconfigure thread: " + aResponse.message;
         Cu.reportError(msg);
         dumpn(msg);
         return;
       }
 
       DebuggerView._handleTabNavigation();
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -93,16 +93,17 @@ MOCHITEST_BROWSER_TESTS = \
 	browser_dbg_bug727429_watch-expressions-02.js \
 	browser_dbg_bug731394_editor-contextmenu.js \
 	browser_dbg_bug737803_editor_actual_location.js \
 	browser_dbg_bug786070_hide_nonenums.js \
 	browser_dbg_bug868163_highight_on_pause.js \
 	browser_dbg_bug883220_raise_on_pause.js \
 	browser_dbg_displayName.js \
 	browser_dbg_pause-exceptions.js \
+	browser_dbg_pause-exceptions-reload.js \
 	browser_dbg_multiple-windows.js \
 	browser_dbg_iframes.js \
 	browser_dbg_bfcache.js \
 	browser_dbg_progress-listener-bug.js \
 	browser_dbg_chrome-debugging.js \
 	browser_dbg_source_maps-01.js \
 	browser_dbg_source_maps-02.js \
 	browser_dbg_step-out.js \
@@ -139,16 +140,17 @@ MOCHITEST_BROWSER_PAGES = \
 	test-function-search-03.js \
 	binary_search.html \
 	binary_search.coffee \
 	binary_search.js \
 	binary_search.map \
 	test-location-changes-bp.js \
 	test-location-changes-bp.html \
 	test-step-out.html \
+	test-pause-exceptions-reload.html \
 	$(NULL)
 
 ifneq (Linux,$(OS_ARCH))
 MOCHITEST_BROWSER_TESTS += \
 	browser_dbg_createChrome.js \
 	$(NULL)
 else
 $(browser_dbg_createChrome.js disabled to fix for ubuntu hangs, bug 847558)
--- a/browser/devtools/debugger/test/browser_dbg_bfcache.js
+++ b/browser/devtools/debugger/test/browser_dbg_bfcache.js
@@ -48,17 +48,17 @@ function testLocationChange()
         gDebugger.removeEventListener(aEvent.type, _onEvent);
 
         executeSoon(function() {
           validateSecondPage();
           testBack();
         });
       });
     });
-    content.location = STACK_URL;
+    gDebugger.DebuggerController.client.activeTab.navigateTo(STACK_URL);
   });
 }
 
 function testBack()
 {
   gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
     ok(true, "tabNavigated event was fired after going back.");
     info("Still attached to the tab.");
--- a/browser/devtools/debugger/test/browser_dbg_bug740825_conditional-breakpoints-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug740825_conditional-breakpoints-01.js
@@ -288,17 +288,17 @@ function test()
       is(gSources._conditionalPopupVisible, false,
         "The breakpoint conditional expression popup should not be shown.");
 
         closeDebuggerAndFinish();
       });
     });
 
     finalCheck();
-    gDebuggee.location.reload();
+    gDebugger.DebuggerController.client.activeTab.reload();
   }
 
   function finalCheck() {
     isnot(gEditor.getText().indexOf("ermahgerd"), -1,
       "The correct script is still loaded.");
     is(gSources.selectedValue, gSources.values[0],
       "The correct script is still selected");
   }
--- a/browser/devtools/debugger/test/browser_dbg_location-changes-blank.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-blank.js
@@ -90,17 +90,17 @@ function testLocationChange()
         is(menulist.getAttribute("label"), noScripts,
           "The menulist should display a notice that there are no scripts availalble.");
         is(menulist.getAttribute("tooltiptext"), "",
           "The menulist shouldn't have any tooltip text attributed when there are no scripts available.");
 
         closeDebuggerAndFinish();
       });
     });
-    content.location = "about:blank";
+    gDebugger.DebuggerController.client.activeTab.navigateTo("about:blank");
   });
 }
 
 registerCleanupFunction(function() {
   removeTab(gTab);
   gPane = null;
   gTab = null;
   gDebuggee = null;
--- a/browser/devtools/debugger/test/browser_dbg_location-changes-bp.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-bp.js
@@ -98,17 +98,17 @@ function testReloadPage()
   });
 
   gDebugger.addEventListener("Debugger:SourceShown", function onSourcesShown() {
     sourcesShown = true;
     gDebugger.removeEventListener("Debugger:SourceShown", onSourcesShown);
     clickAgain();
   });
 
-  content.location.reload();
+  gDebugger.DebuggerController.client.activeTab.reload();
 }
 
 function clickAgain()
 {
   if (!sourcesShown || !tabNavigated) {
     return;
   }
 
--- a/browser/devtools/debugger/test/browser_dbg_location-changes-new.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes-new.js
@@ -90,17 +90,18 @@ function testLocationChange()
         isnot(menulist.getAttribute("label"), noScripts,
           "The menulist should not display a notice that there are no scripts availalble.");
         isnot(menulist.getAttribute("tooltiptext"), "",
           "The menulist should have a tooltip text attributed.");
 
         closeDebuggerAndFinish();
       });
     });
-    content.location = EXAMPLE_URL + "browser_dbg_iframes.html";
+    let newLocation = EXAMPLE_URL + "browser_dbg_iframes.html";
+    gDebugger.DebuggerController.client.activeTab.navigateTo(newLocation);
   });
 }
 
 registerCleanupFunction(function() {
   removeTab(gTab);
   gPane = null;
   gTab = null;
   gDebuggee = null;
--- a/browser/devtools/debugger/test/browser_dbg_location-changes.js
+++ b/browser/devtools/debugger/test/browser_dbg_location-changes.js
@@ -51,17 +51,17 @@ function testLocationChange()
 {
   gDebugger.DebuggerController.activeThread.resume(function() {
     gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
       ok(true, "tabNavigated event was fired.");
       info("Still attached to the tab.");
 
       closeDebuggerAndFinish();
     });
-    content.location = TAB1_URL;
+    gDebugger.DebuggerController.client.activeTab.navigateTo(TAB1_URL);
   });
 }
 
 registerCleanupFunction(function() {
   removeTab(gTab);
   gPane = null;
   gTab = null;
   gDebuggee = null;
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_pause-exceptions-reload.js
@@ -0,0 +1,122 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Make sure that pausing on exceptions works after reload.
+ */
+
+const TAB_URL = EXAMPLE_URL + "test-pause-exceptions-reload.html";
+
+var gPane = null;
+var gTab = null;
+var gDebugger = null;
+var gPrevPref = null;
+
+function test()
+{
+  gPrevPref = Services.prefs.getBoolPref(
+    "devtools.debugger.pause-on-exceptions");
+  Services.prefs.setBoolPref(
+    "devtools.debugger.pause-on-exceptions", true);
+
+  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gPane = aPane;
+    gDebugger = gPane.panelWin;
+
+    gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
+    gDebugger.DebuggerView.Variables.nonEnumVisible = false;
+    testWithFrame();
+  });
+}
+
+function testWithFrame()
+{
+  // Pause on exceptions should be already enabled.
+  is(gDebugger.Prefs.pauseOnExceptions, true,
+    "The pause-on-exceptions pref should be true from startup.");
+  is(gDebugger.DebuggerView.Options._pauseOnExceptionsItem.getAttribute("checked"), "true",
+    "Pause on exceptions should be enabled from startup. ")
+
+  let count = 0;
+  gPane.panelWin.gClient.addOneTimeListener("paused", function() {
+    gDebugger.addEventListener("Debugger:FetchedVariables", function testA() {
+      // We expect 2 Debugger:FetchedVariables events, one from the global object
+      // scope and the regular one.
+      if (++count < 2) {
+        is(count, 1, "A. First Debugger:FetchedVariables event received.");
+        return;
+      }
+      is(count, 2, "A. Second Debugger:FetchedVariables event received.");
+      gDebugger.removeEventListener("Debugger:FetchedVariables", testA, false);
+
+      is(gDebugger.DebuggerController.activeThread.state, "paused",
+        "Should be paused now.");
+
+      count = 0;
+      gPane.panelWin.gClient.addOneTimeListener("paused", function() {
+        gDebugger.addEventListener("Debugger:FetchedVariables", function testB() {
+          // We expect 2 Debugger:FetchedVariables events, one from the global object
+          // scope and the regular one.
+          if (++count < 2) {
+            is(count, 1, "B. First Debugger:FetchedVariables event received.");
+            return;
+          }
+          is(count, 2, "B. Second Debugger:FetchedVariables event received.");
+          gDebugger.removeEventListener("Debugger:FetchedVariables", testB, false);
+          Services.tm.currentThread.dispatch({ run: function() {
+
+            var frames = gDebugger.DebuggerView.StackFrames.widget._list,
+                scopes = gDebugger.DebuggerView.Variables._list,
+                innerScope = scopes.firstChild,
+                innerNodes = innerScope.querySelector(".variables-view-element-details").childNodes;
+
+            is(gDebugger.DebuggerController.activeThread.state, "paused",
+              "Should be paused again.");
+
+            is(frames.querySelectorAll(".dbg-stackframe").length, 2,
+              "Should have two frames.");
+
+            is(scopes.children.length, 2, "Should have 2 variable scopes.");
+
+            is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
+              "Should have the right property name for the exception.");
+
+            is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
+              "Should have the right property value for the exception.");
+
+            resumeAndFinish();
+
+          }}, 0);
+        }, false);
+      });
+
+      content.window.location.reload();
+    }, false);
+  });
+
+  content.window.location.reload();
+}
+
+function resumeAndFinish() {
+  // Disable pause on exceptions.
+  gDebugger.DebuggerView.Options._pauseOnExceptionsItem.setAttribute("checked", "false");
+  gDebugger.DebuggerView.Options._togglePauseOnExceptions();
+
+  is(gDebugger.Prefs.pauseOnExceptions, false,
+    "The pause-on-exceptions pref should have been set to false.");
+
+  gPane.panelWin.gClient.addOneTimeListener("resumed", function() {
+    Services.tm.currentThread.dispatch({ run: closeDebuggerAndFinish }, 0);
+  });
+
+  // Resume to let the exception reach it's catch clause.
+  gDebugger.DebuggerController.activeThread.resume();
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gPane = null;
+  gTab = null;
+  gDebugger = null;
+});
--- a/browser/devtools/debugger/test/browser_dbg_reload-same-script.js
+++ b/browser/devtools/debugger/test/browser_dbg_reload-same-script.js
@@ -199,17 +199,17 @@ function test()
 
   function switchScript(index)
   {
     gView.Sources.selectedValue = gView.Sources.values[index];
   }
 
   function reloadPage()
   {
-    gDebuggee.location.reload();
+    gDebugger.DebuggerController.client.activeTab.reload();
   }
 
   registerCleanupFunction(function() {
     removeTab(gTab);
     gPane = null;
     gTab = null;
     gDebuggee = null;
     gDebugger = null;
--- a/browser/devtools/debugger/test/browser_dbg_scripts-searching-05.js
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-searching-05.js
@@ -122,17 +122,17 @@ function testLocationChange()
         "The global search pane shouldn't be visible after a page navigation.");
       is(gSearchView._splitter.hidden, true,
         "The global search pane splitter shouldn't be visible after a page navigation.");
 
       closeDebuggerAndFinish();
     });
   });
 
-  content.location = TAB1_URL;
+  gDebugger.DebuggerController.client.activeTab.navigateTo(TAB1_URL);
 }
 
 function clear() {
   gSearchBox.focus();
   gSearchBox.value = "";
 }
 
 function write(text) {
--- a/browser/devtools/debugger/test/browser_dbg_sources-cache.js
+++ b/browser/devtools/debugger/test/browser_dbg_sources-cache.js
@@ -103,17 +103,17 @@ function performReload(callback) {
   gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
     ok(true, "tabNavigated event was fired.");
     info("Still attached to the tab.");
 
     testStateAfterReload();
     callback();
   });
 
-  gDebuggee.location.reload();
+  gDebugger.DebuggerController.client.activeTab.reload();
 }
 
 function testStateBeforeReload() {
   is(gSources.itemCount, 0,
     "There should be no sources present in the sources list during reload.");
   is(gControllerSources.getCache().length, 0,
     "The sources cache should be empty during reload.");
   is(gDebugger.SourceUtils._labelsCache, gPrevLabelsCache,
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/test-pause-exceptions-reload.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'/>
+    <title>Debugger Pause on Exceptions After Reload Test</title>
+    <!-- Any copyright is dedicated to the Public Domain.
+         http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <ul></ul>
+  </body>
+  <script type="text/javascript">
+    window.addEventListener("load", function() {
+      function load() {
+        try {
+          throw new Error("boom");
+        } catch (e) {
+          var list = document.querySelector("ul");
+          var item = document.createElement("li");
+          item.innerHTML = e.message;
+          list.appendChild(item);
+        }
+      }
+      load();
+    });
+  </script>
+</html>
--- a/browser/devtools/framework/toolbox-options.xul
+++ b/browser/devtools/framework/toolbox-options.xul
@@ -32,16 +32,22 @@
           <radio value="dark" label="&options.darkTheme.label;"/>
         </radiogroup>
         <label value="&options.webconsole.label;"/>
         <vbox id="webconsole-options" class="options-groupbox">
           <checkbox label="&options.enablePersistentLogging.label;"
                     tooltiptext="&options.enablePersistentLogging.tooltip;"
                     data-pref="devtools.webconsole.persistlog"/>
         </vbox>
+        <label value="&options.profiler.label;"/>
+        <vbox id="profiler-options" class="options-groupbox">
+          <checkbox label="&options.showPlatformData.label;"
+                    tooltiptext="&options.showPlatformData.tooltip;"
+                    data-pref="devtools.profiler.ui.show-platform-data"/>
+        </vbox>
         <label value="&options.context.advancedSettings;"/>
         <vbox id="context-options" class="options-groupbox">
           <hbox>
             <checkbox id="devtools-disable-javascript"
                       label="&options.disableJavaScript.label2;"
                       tooltiptext="&options.disableJavaScript.tooltip;"/>
             <label class="options-citation-label"
                    value="(&options.context.triggersPageRefresh2;)"/>
--- a/browser/devtools/markupview/markup-view.xhtml
+++ b/browser/devtools/markupview/markup-view.xhtml
@@ -13,17 +13,17 @@
 
   <script type="application/javascript;version=1.8" src="theme-switching.js"/>
 
 </head>
 <body class="theme-body devtools-monospace" role="application">
   <div id="root"></div>
   <div id="templates" style="display:none">
     <ul>
-      <li id="template-container" save="${elt}" class="container"><span save="${expander}" class="theme-twisty expander"></span><span save="${codeBox}" class="codebox"><ul save="${children}" class="children"></ul></span></li>
+      <li id="template-container" save="${elt}" class="container"><span save="${codeBox}" class="codebox"><span save="${expander}" class="theme-twisty expander"></span><ul save="${children}" class="children"></ul></span></li>
 
       <li id="template-more-nodes" class="more-nodes devtools-class-comment" save="${elt}"><span>${showing}</span> <button href="#" onclick="${allButtonClick}">${showAll}</button></li>
     </ul>
 
     <span id="template-element" save="${elt}" class="editor"><span>&lt;</span><span save="${tag}" class="tagname theme-fg-color3"></span><span save="${attrList}"></span><span save="${newAttr}" class="newattr" tabindex="0"></span>&gt;</span>
 
     <span id="template-attribute" save="${attr}" data-attr="${attrName}" class="attreditor" style="display:none"> <span class="editable" save="${inner}" tabindex="0"><span save="${name}" class="attrname theme-fg-color2"></span>=&quot;<span save="${val}" class="attrvalue theme-fg-color6"></span>&quot;</span></span>
 
--- a/browser/devtools/netmonitor/NetMonitorPanel.jsm
+++ b/browser/devtools/netmonitor/NetMonitorPanel.jsm
@@ -13,23 +13,24 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource:///modules/devtools/shared/event-emitter.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
   "resource://gre/modules/commonjs/sdk/core/promise.js");
 
 this.NetMonitorPanel = function NetMonitorPanel(iframeWindow, toolbox) {
   this.panelWin = iframeWindow;
   this._toolbox = toolbox;
+  this._destroyer = null;
 
   this._view = this.panelWin.NetMonitorView;
   this._controller = this.panelWin.NetMonitorController;
   this._controller._target = this.target;
 
   EventEmitter.decorate(this);
-}
+};
 
 NetMonitorPanel.prototype = {
   /**
    * Open is effectively an asynchronous constructor.
    *
    * @return object
    *         A Promise that is resolved when the NetMonitor completes opening.
    */
@@ -48,19 +49,27 @@ NetMonitorPanel.prototype = {
       .then(() => this._controller.connect())
       .then(() => {
         this.isReady = true;
         this.emit("ready");
         return this;
       })
       .then(null, function onError(aReason) {
         Cu.reportError("NetMonitorPanel open failed. " +
-                       reason.error + ": " + reason.message);
+                       aReason.error + ": " + aReason.message);
       });
   },
 
   // DevToolPanel API
+
   get target() this._toolbox.target,
 
   destroy: function() {
-    this._controller.shutdownNetMonitor().then(() => this.emit("destroyed"));
+    // Make sure this panel is not already destroyed.
+    if (this._destroyer) {
+      return this._destroyer;
+    }
+
+    return this._destroyer = this._controller.shutdownNetMonitor().then(() => {
+      this.emit("destroyed");
+    });
   }
 };
--- a/browser/devtools/netmonitor/netmonitor-controller.js
+++ b/browser/devtools/netmonitor/netmonitor-controller.js
@@ -32,71 +32,60 @@ const NET_PREFS = { "NetworkMonitor.save
 let NetMonitorController = {
   /**
    * Initializes the view.
    *
    * @return object
    *         A promise that is resolved when the monitor finishes startup.
    */
   startupNetMonitor: function() {
-    if (this._isInitialized) {
-      return this._startup.promise;
+    if (this._startup) {
+      return this._startup;
     }
-    this._isInitialized = true;
-
-    let deferred = this._startup = Promise.defer();
 
-    NetMonitorView.initialize(() => {
-      NetMonitorView._isInitialized = true;
-      deferred.resolve();
-    });
+    NetMonitorView.initialize();
 
-    return deferred.promise;
+    // Startup is synchronous, for now.
+    return this._startup = Promise.resolve();
   },
 
   /**
    * Destroys the view and disconnects the monitor client from the server.
    *
    * @return object
    *         A promise that is resolved when the monitor finishes shutdown.
    */
   shutdownNetMonitor: function() {
-    if (this._isDestroyed) {
-      return this._shutdown.promise;
+    if (this._shutdown) {
+      return this._shutdown;
     }
-    this._isDestroyed = true;
-    this._startup = null;
-
-    let deferred = this._shutdown = Promise.defer();
 
-    NetMonitorView.destroy(() => {
-      NetMonitorView._isDestroyed = true;
-      this.TargetEventsHandler.disconnect();
-      this.NetworkEventsHandler.disconnect();
+    NetMonitorView.destroy();
+    this.TargetEventsHandler.disconnect();
+    this.NetworkEventsHandler.disconnect();
+    this.disconnect();
 
-      this.disconnect();
-      deferred.resolve();
-    });
-
-    return deferred.promise;
+    // Shutdown is synchronous, for now.
+    return this._shutdown = Promise.resolve();
   },
 
   /**
    * Initiates remote or chrome network monitoring based on the current target,
    * wiring event handlers as necessary.
    *
    * @return object
    *         A promise that is resolved when the monitor finishes connecting.
    */
   connect: function() {
     if (this._connection) {
-      return this._connection.promise;
+      return this._connection;
     }
 
-    let deferred = this._connection = Promise.defer();
+    let deferred = Promise.defer();
+    this._connection = deferred.promise;
 
     let target = this._target;
     let { client, form } = target;
     if (target.chrome) {
       this._startChromeMonitoring(client, form.consoleActor, deferred.resolve);
     } else {
       this._startMonitoringTab(client, form, deferred.resolve);
     }
@@ -187,18 +176,16 @@ let NetMonitorController = {
 
         if (aCallback) {
           aCallback();
         }
       });
     });
   },
 
-  _isInitialized: false,
-  _isDestroyed: false,
   _startup: null,
   _shutdown: null,
   _connection: null,
   client: null,
   tabClient: null,
   webConsoleClient: null
 };
 
@@ -500,17 +487,17 @@ NetworkEventsHandler.prototype = {
     if (aStringGrip._fullText) {
       return aStringGrip._fullText.promise;
     }
 
     let deferred = aStringGrip._fullText = Promise.defer();
     let { actor, initial, length } = aStringGrip;
     let longStringClient = this.webConsoleClient.longString(aStringGrip);
 
-    longStringClient.substring(initial.length, length, (aResponse) => {
+    longStringClient.substring(initial.length, length, aResponse => {
       if (aResponse.error) {
         Cu.reportError(aResponse.error + ": " + aResponse.message);
         deferred.reject(aResponse);
         return;
       }
       deferred.resolve(initial + aResponse.substring);
     });
 
--- a/browser/devtools/netmonitor/netmonitor-view.js
+++ b/browser/devtools/netmonitor/netmonitor-view.js
@@ -59,48 +59,34 @@ const GENERIC_VARIABLES_VIEW_SETTINGS = 
 };
 
 /**
  * Object defining the network monitor view components.
  */
 let NetMonitorView = {
   /**
    * Initializes the network monitor view.
-   *
-   * @param function aCallback
-   *        Called after the view finishes initializing.
    */
-  initialize: function(aCallback) {
-    dumpn("Initializing the NetMonitorView");
-
+  initialize: function() {
     this._initializePanes();
 
     this.Toolbar.initialize();
     this.RequestsMenu.initialize();
     this.NetworkDetails.initialize();
-
-    aCallback();
   },
 
   /**
    * Destroys the network monitor view.
-   *
-   * @param function aCallback
-   *        Called after the view finishes destroying.
    */
-  destroy: function(aCallback) {
-    dumpn("Destroying the NetMonitorView");
-
+  destroy: function() {
     this.Toolbar.destroy();
     this.RequestsMenu.destroy();
     this.NetworkDetails.destroy();
 
     this._destroyPanes();
-
-    aCallback();
   },
 
   /**
    * Initializes the UI for all the displayed panes.
    */
   _initializePanes: function() {
     dumpn("Initializing the NetMonitorView panes");
 
@@ -194,19 +180,17 @@ let NetMonitorView = {
     return deferred.promise;
   },
 
   _body: null,
   _detailsPane: null,
   _detailsPaneToggleButton: null,
   _collapsePaneString: "",
   _expandPaneString: "",
-  _editorPromises: new Map(),
-  _isInitialized: false,
-  _isDestroyed: false
+  _editorPromises: new Map()
 };
 
 /**
  * Functions handling the toolbar view: expand/collapse button etc.
  */
 function ToolbarView() {
   dumpn("ToolbarView was instantiated");
 
@@ -387,18 +371,18 @@ RequestsMenuView.prototype = Heritage.ex
     let data = Object.create(selected, {
       headers: { value: selected.requestHeaders.headers }
     });
 
     if (selected.requestPostData) {
       data.body = selected.requestPostData.postData.text;
     }
 
-    NetMonitorController.webConsoleClient.sendHTTPRequest(data, (response) => {
-      let id = response.eventActor.actor;
+    NetMonitorController.webConsoleClient.sendHTTPRequest(data, aResponse => {
+      let id = aResponse.eventActor.actor;
       this._preferredItemId = id;
     });
 
     this.closeCustomRequest();
   },
 
   /**
    * Remove the currently selected custom request.
@@ -1378,17 +1362,17 @@ CustomRequestView.prototype = {
     $("#custom-url-value").value = aData.url;
     $("#custom-method-value").value = aData.method;
     $("#custom-headers-value").value =
        writeHeaderText(aData.requestHeaders.headers);
 
     if (aData.requestPostData) {
       let body = aData.requestPostData.postData.text;
 
-      gNetwork.getString(body).then((aString) => {
+      gNetwork.getString(body).then(aString => {
         $("#custom-postdata-value").value =  aString;
       });
     }
 
     this.updateCustomQuery(aData.url);
   },
 
   /**
@@ -1673,17 +1657,17 @@ NetworkDetailsView.prototype = {
     let kb = aResponse.headersSize / 1024;
     let size = L10N.numberWithDecimals(kb, HEADERS_SIZE_DECIMALS);
     let text = L10N.getFormatStr("networkMenu.sizeKB", size);
     let headersScope = this._headers.addScope(aName + " (" + text + ")");
     headersScope.expanded = true;
 
     for (let header of aResponse.headers) {
       let headerVar = headersScope.addItem(header.name, {}, true);
-      gNetwork.getString(header.value).then((aString) => headerVar.setGrip(aString));
+      gNetwork.getString(header.value).then(aString => headerVar.setGrip(aString));
     }
   },
 
   /**
    * Sets the network request cookies shown in this view.
    *
    * @param object aResponse
    *        The message received from the server.
@@ -1716,29 +1700,29 @@ NetworkDetailsView.prototype = {
    *        The message received from the server.
    */
   _addCookies: function(aName, aResponse) {
     let cookiesScope = this._cookies.addScope(aName);
     cookiesScope.expanded = true;
 
     for (let cookie of aResponse.cookies) {
       let cookieVar = cookiesScope.addItem(cookie.name, {}, true);
-      gNetwork.getString(cookie.value).then((aString) => cookieVar.setGrip(aString));
+      gNetwork.getString(cookie.value).then(aString => cookieVar.setGrip(aString));
 
       // By default the cookie name and value are shown. If this is the only
       // information available, then nothing else is to be displayed.
       let cookieProps = Object.keys(cookie);
       if (cookieProps.length == 2) {
         continue;
       }
 
       // Display any other information other than the cookie name and value
       // which may be available.
       let rawObject = Object.create(null);
-      let otherProps = cookieProps.filter((e) => e != "name" && e != "value");
+      let otherProps = cookieProps.filter(e => e != "name" && e != "value");
       for (let prop of otherProps) {
         rawObject[prop] = cookie[prop];
       }
       cookieVar.populate(rawObject);
       cookieVar.twisty = true;
       cookieVar.expanded = true;
     }
   },
@@ -1763,17 +1747,17 @@ NetworkDetailsView.prototype = {
    *        The "requestHeaders" message received from the server.
    * @param object aPostDataResponse
    *        The "requestPostData" message received from the server.
    */
   _setRequestPostParams: function(aHeadersResponse, aPostDataResponse) {
     if (!aHeadersResponse || !aPostDataResponse) {
       return;
     }
-    gNetwork.getString(aPostDataResponse.postData.text).then((aString) => {
+    gNetwork.getString(aPostDataResponse.postData.text).then(aString => {
       // Handle query strings (poor man's forms, e.g. "?foo=bar&baz=42").
       let cType = aHeadersResponse.headers.filter(({ name }) => name == "Content-Type")[0];
       let cString = cType ? cType.value : "";
       if (cString.contains("x-www-form-urlencoded") ||
           aString.contains("x-www-form-urlencoded")) {
         let formDataGroups = aString.split(/\r\n|\n|\r/);
         for (let group of formDataGroups) {
           this._addParams(this._paramsFormData, group);
@@ -1785,17 +1769,17 @@ NetworkDetailsView.prototype = {
         // scope in the params view and place the source editor containing
         // the raw post data directly underneath.
         $("#request-params-box").removeAttribute("flex");
         let paramsScope = this._params.addScope(this._paramsPostPayload);
         paramsScope.expanded = true;
         paramsScope.locked = true;
 
         $("#request-post-data-textarea-box").hidden = false;
-        NetMonitorView.editor("#request-post-data-textarea").then((aEditor) => {
+        NetMonitorView.editor("#request-post-data-textarea").then(aEditor => {
           aEditor.setText(aString);
         });
       }
       window.emit("NetMonitor:ResponsePostParamsAvailable");
     });
   },
 
   /**
@@ -1829,17 +1813,17 @@ NetworkDetailsView.prototype = {
    *        The message received from the server.
    */
   _setResponseBody: function(aUrl, aResponse) {
     if (!aResponse) {
       return;
     }
     let { mimeType, text, encoding } = aResponse.content;
 
-    gNetwork.getString(text).then((aString) => {
+    gNetwork.getString(text).then(aString => {
       // Handle json.
       if (mimeType.contains("/json")) {
         let jsonpRegex = /^[a-zA-Z0-9_$]+\(|\)$/g; // JSONP with callback.
         let sanitizedJSON = aString.replace(jsonpRegex, "");
         let callbackPadding = aString.match(jsonpRegex);
 
         // Make sure this is an valid JSON object first. If so, nicely display
         // the parsing results in a variables view. Otherwise, simply show
@@ -1859,17 +1843,17 @@ NetworkDetailsView.prototype = {
 
           let jsonScope = this._json.addScope(jsonScopeName);
           jsonScope.addItem().populate(jsonObject, { expanded: true });
           jsonScope.expanded = true;
         }
         // Malformed JSON.
         else {
           $("#response-content-textarea-box").hidden = false;
-          NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
+          NetMonitorView.editor("#response-content-textarea").then(aEditor => {
             aEditor.setMode(SourceEditor.MODES.JAVASCRIPT);
             aEditor.setText(aString);
           });
           let infoHeader = $("#response-content-info-header");
           infoHeader.setAttribute("value", parsingError);
           infoHeader.setAttribute("tooltiptext", parsingError);
           infoHeader.hidden = false;
         }
@@ -1884,29 +1868,29 @@ NetworkDetailsView.prototype = {
 
         // Immediately display additional information about the image:
         // file name, mime type and encoding.
         $("#response-content-image-name-value").setAttribute("value", nsIURL(aUrl).fileName);
         $("#response-content-image-mime-value").setAttribute("value", mimeType);
         $("#response-content-image-encoding-value").setAttribute("value", encoding);
 
         // Wait for the image to load in order to display the width and height.
-        $("#response-content-image").onload = (e) => {
+        $("#response-content-image").onload = e => {
           // XUL images are majestic so they don't bother storing their dimensions
           // in width and height attributes like the rest of the folk. Hack around
           // this by getting the bounding client rect and subtracting the margins.
           let { width, height } = e.target.getBoundingClientRect();
           let dimensions = (width - 2) + " x " + (height - 2);
           $("#response-content-image-dimensions-value").setAttribute("value", dimensions);
         };
       }
       // Handle anything else.
       else {
         $("#response-content-textarea-box").hidden = false;
-        NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
+        NetMonitorView.editor("#response-content-textarea").then(aEditor => {
           aEditor.setMode(SourceEditor.MODES.TEXT);
           aEditor.setText(aString);
 
           // Maybe set a more appropriate mode in the Source Editor if possible,
           // but avoid doing this for very large files.
           if (aString.length < SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
             for (let key in CONTENT_MIME_TYPE_MAPPINGS) {
               if (mimeType.contains(key)) {
@@ -2031,17 +2015,17 @@ nsIURL.store = new Map();
  *         Array of query params {name, value}
  */
 function parseQueryString(aQueryString) {
   // Make sure there's at least one param available.
   if (!aQueryString || !aQueryString.contains("=")) {
     return;
   }
   // Turn the params string into an array containing { name: value } tuples.
-  let paramsArray = aQueryString.replace(/^[?&]/, "").split("&").map((e) =>
+  let paramsArray = aQueryString.replace(/^[?&]/, "").split("&").map(e =>
     let (param = e.split("=")) {
       name: NetworkHelper.convertToUnicode(unescape(param[0])),
       value: NetworkHelper.convertToUnicode(unescape(param[1]))
     });
   return paramsArray;
 }
 
 /**
--- a/browser/devtools/netmonitor/test/browser_net_simple-init.js
+++ b/browser/devtools/netmonitor/test/browser_net_simple-init.js
@@ -14,38 +14,42 @@ function test() {
     is(aDebuggee.location, SIMPLE_URL,
       "The current debuggee's location is the correct one.");
 
     function checkIfInitialized(aTag) {
       info("Checking if initialization is ok (" + aTag + ").");
 
       ok(aMonitor._view,
         "The network monitor view object exists (" + aTag + ").");
-      ok(aMonitor._view._isInitialized,
-        "The network monitor view object exists and is initialized (" + aTag + ").");
-
       ok(aMonitor._controller,
         "The network monitor controller object exists (" + aTag + ").");
-      ok(aMonitor._controller._isInitialized,
+      ok(aMonitor._controller._startup,
         "The network monitor controller object exists and is initialized (" + aTag + ").");
 
       ok(aMonitor.isReady,
         "The network monitor panel appears to be ready (" + aTag + ").");
 
       ok(aMonitor._controller.client,
         "There should be a client available at this point (" + aTag + ").");
       ok(aMonitor._controller.tabClient,
         "There should be a tabClient available at this point (" + aTag + ").");
       ok(aMonitor._controller.webConsoleClient,
         "There should be a webConsoleClient available at this point (" + aTag + ").");
     }
 
     function checkIfDestroyed(aTag) {
       info("Checking if destruction is ok.");
 
+      ok(aMonitor._view,
+        "The network monitor view object still exists (" + aTag + ").");
+      ok(aMonitor._controller,
+        "The network monitor controller object still exists (" + aTag + ").");
+      ok(aMonitor._controller._shutdown,
+        "The network monitor controller object still exists and is destroyed (" + aTag + ").");
+
       ok(!aMonitor._controller.client,
         "There shouldn't be a client available after destruction (" + aTag + ").");
       ok(!aMonitor._controller.tabClient,
         "There shouldn't be a tabClient available after destruction (" + aTag + ").");
       ok(!aMonitor._controller.webConsoleClient,
         "There shouldn't be a webConsoleClient available after destruction (" + aTag + ").");
     }
 
--- a/browser/devtools/profiler/cleopatra.js
+++ b/browser/devtools/profiler/cleopatra.js
@@ -18,34 +18,35 @@ const { PROFILE_IDLE, PROFILE_COMPLETED,
  *  - ready, when Cleopatra is done loading (you can also check the isReady
  *    property to see if a particular instance has been loaded yet.
  *
  * @param number uid
  *   Unique ID for this profile.
  * @param ProfilerPanel panel
  *   A reference to the container panel.
  */
-function Cleopatra(uid, name, panel) {
+function Cleopatra(panel, opts) {
   let doc = panel.document;
   let win = panel.window;
+  let { uid, name, showPlatformData } = opts;
 
   EventEmitter.decorate(this);
 
   this.isReady = false;
   this.isStarted = false;
   this.isFinished = false;
 
   this.panel = panel;
   this.uid = uid;
   this.name = name;
 
   this.iframe = doc.createElement("iframe");
   this.iframe.setAttribute("flex", "1");
   this.iframe.setAttribute("id", "profiler-cleo-" + uid);
-  this.iframe.setAttribute("src", "cleopatra.html?" + uid);
+  this.iframe.setAttribute("src", "cleopatra.html?uid=" + uid + "&showPlatformData=" + showPlatformData);
   this.iframe.setAttribute("hidden", "true");
 
   // Append our iframe and subscribe to postMessage events.
   // They'll tell us when the underlying page is done loading
   // or when user clicks on start/stop buttons.
 
   doc.getElementById("profiler-report").appendChild(this.iframe);
   win.addEventListener("message", function (event) {
--- a/browser/devtools/profiler/cleopatra/js/devtools.js
+++ b/browser/devtools/profiler/cleopatra/js/devtools.js
@@ -1,28 +1,44 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var gInstanceUID;
+var gParsedQS;
+
+function getParam(key) {
+  if (gParsedQS)
+    return gParsedQS[key];
+
+  var query = window.location.search.substring(1);
+  gParsedQS = {};
+
+  query.split("&").forEach(function (pair) {
+    pair = pair.split("=");
+    gParsedQS[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
+  });
+
+  return gParsedQS[key];
+}
 
 /**
  * Sends a message to the parent window with a status
  * update.
  *
  * @param string status
  *   Status to send to the parent page:
  *    - loaded, when page is loaded.
  *    - displaysource, when user wants to display source
  * @param object data (optional)
  *    Additional data to send to the parent page.
  */
 function notifyParent(status, data={}) {
   if (!gInstanceUID) {
-    gInstanceUID = window.location.search.substr(1);
+    gInstanceUID = getParam("uid");
   }
 
   window.parent.postMessage({
     uid: gInstanceUID,
     status: status,
     data: data
   }, "*");
 }
@@ -203,17 +219,18 @@ function enterFinishedProfileUI() {
         focusOnCallstack(filter.focusedCallstack, filter.name, true);
         gBreadcrumbTrail.enterLastItem(forceSelection);
       case "RangeSampleFilter":
         gHistogramView.selectRange(filter.start, filter.end);
         gBreadcrumbTrail.enterLastItem(forceSelection);
     }
   }
 
-  toggleJavascriptOnly();
+  if (getParam("showPlatformData") !== "true")
+    toggleJavascriptOnly();
 }
 
 function enterProgressUI() {
   var pane = document.createElement("div");
   var label = document.createElement("a");
   var bar = document.createElement("progress");
   var string = gStrings.getStr("profiler.loading");
 
--- a/browser/devtools/profiler/consts.js
+++ b/browser/devtools/profiler/consts.js
@@ -1,13 +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/. */
 
 "use strict";
 
 module.exports = {
-	L10N_BUNDLE:       "chrome://browser/locale/devtools/profiler.properties",
-	PROFILER_ENABLED:  "devtools.profiler.enabled",
-	PROFILE_IDLE:      0,
-	PROFILE_RUNNING:   1,
-	PROFILE_COMPLETED: 2
+	L10N_BUNDLE:        "chrome://browser/locale/devtools/profiler.properties",
+
+	PROFILER_ENABLED:   "devtools.profiler.enabled",
+	SHOW_PLATFORM_DATA: "devtools.profiler.ui.show-platform-data",
+
+	PROFILE_IDLE:       0,
+	PROFILE_RUNNING:    1,
+	PROFILE_COMPLETED:  2
 };
\ No newline at end of file
--- a/browser/devtools/profiler/panel.js
+++ b/browser/devtools/profiler/panel.js
@@ -1,26 +1,31 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Cu } = require("chrome");
-const { PROFILE_IDLE, PROFILE_RUNNING, PROFILE_COMPLETED } = require("devtools/profiler/consts");
+const {
+  PROFILE_IDLE,
+  PROFILE_RUNNING,
+  PROFILE_COMPLETED,
+  SHOW_PLATFORM_DATA
+} = require("devtools/profiler/consts");
 
 var EventEmitter = require("devtools/shared/event-emitter");
 var Promise      = require("sdk/core/promise");
 var Cleopatra    = require("devtools/profiler/cleopatra");
 var Sidebar      = require("devtools/profiler/sidebar");
 var ProfilerController = require("devtools/profiler/controller");
 
 Cu.import("resource:///modules/devtools/gDevTools.jsm");
 Cu.import("resource://gre/modules/devtools/Console.jsm");
-Cu.import("resource://gre/modules/Services.jsm")
+Cu.import("resource://gre/modules/Services.jsm");
 
 /**
  * Profiler panel. It is responsible for creating and managing
  * different profile instances (see cleopatra.js).
  *
  * ProfilerPanel is an event emitter. It can emit the following
  * events:
  *
@@ -118,34 +123,42 @@ ProfilerPanel.prototype = {
 
     if (type !== "navigator:browser") {
       win = Services.wm.getMostRecentWindow("navigator:browser");
     }
 
     return this._browserWin = win;
   },
 
+  get showPlatformData() {
+    return Services.prefs.getBoolPref(SHOW_PLATFORM_DATA);
+  },
+
+  set showPlatformData(enabled) {
+    Services.prefs.setBoolPref(SHOW_PLATFORM_DATA, enabled);
+  },
+
   /**
    * Open a debug connection and, on success, switch to the newly created
    * profile.
    *
    * @return Promise
    */
   open: function PP_open() {
     // Local profiling needs to make the target remote.
     let target = this.target;
     let promise = !target.isRemote ? target.makeRemote() : Promise.resolve(target);
 
     return promise
       .then((target) => {
         let deferred = Promise.defer();
 
         this.controller = new ProfilerController(this.target);
+
         this.sidebar = new Sidebar(this.document.querySelector("#profiles-list"));
-
         this.sidebar.widget.addEventListener("select", (ev) => {
           if (!ev.detail)
             return;
 
           let profile = this.profiles.get(ev.detail.attachment.uid);
           this.activeProfile = profile;
 
           if (profile.isReady) {
@@ -218,17 +231,21 @@ ProfilerPanel.prototype = {
    */
   createProfile: function (name) {
     if (name && this.getProfileByName(name)) {
       return this.getProfileByName(name);
     }
 
     let uid = ++this._uid;
     let name = name || this.controller.getProfileName();
-    let profile = new Cleopatra(uid, name, this);
+    let profile = new Cleopatra(this, {
+      uid: uid,
+      name: name,
+      showPlatformData: this.showPlatformData
+    });
 
     this.profiles.set(uid, profile);
     this.sidebar.addProfile(profile);
     this.emit("profileCreated", uid);
 
     return profile;
   },
 
--- a/browser/devtools/profiler/test/Makefile.in
+++ b/browser/devtools/profiler/test/Makefile.in
@@ -17,16 +17,17 @@ MOCHITEST_BROWSER_TESTS = \
 		browser_profiler_run.js \
 		browser_profiler_controller.js \
 		browser_profiler_bug_855244_multiple_tabs.js \
 		browser_profiler_console_api.js \
 		browser_profiler_console_api_named.js \
 		browser_profiler_console_api_mixed.js \
 		browser_profiler_console_api_content.js \
 		browser_profiler_escape.js \
+		browser_profiler_gecko_data.js \
 		head.js \
 		$(NULL)
 
 MOCHITEST_BROWSER_PAGES = \
 		mock_profiler_bug_834878_page.html \
 		mock_profiler_bug_834878_script.js \
 		mock_console_api.html \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_gecko_data.js
@@ -0,0 +1,52 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel;
+
+function test() {
+  waitForExplicitFinish();
+
+  setUp(URL, function onSetUp(tab, browser, panel) {
+    gTab = tab;
+    gPanel = panel;
+
+    function done() {
+      tearDown(gTab, () => { gPanel = null; gTab = null; });
+    }
+
+    Services.prefs.setBoolPref(SHOW_PLATFORM_DATA, false);
+    recordProfile()
+      .then(toggleGeckoDataOption)
+      .then(recordProfile)
+      .then(done);
+  });
+}
+
+function recordProfile() {
+  let deferred = Promise.defer();
+  let record = gPanel.controls.record;
+
+  gPanel.once("started", () => {
+    gPanel.once("parsed", () => {
+      // We cannot be sure which data is returned by
+      // the profiler within a test. Until we get rid
+      // of Cleopatra, at least.
+      deferred.resolve();
+    });
+
+    record.click();
+  });
+
+  record.click();
+  return deferred.promise;
+}
+
+function toggleGeckoDataOption() {
+  ok(!gPanel.showPlatformData, "showPlatformData is not set");
+
+  Services.prefs.setBoolPref(SHOW_PLATFORM_DATA, true);
+
+  ok(gPanel.showPlatformData, "showPlatformData is set");
+}
\ No newline at end of file
--- a/browser/devtools/profiler/test/head.js
+++ b/browser/devtools/profiler/test/head.js
@@ -1,15 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 let temp = {};
 
 const PROFILER_ENABLED = "devtools.profiler.enabled";
 const REMOTE_ENABLED = "devtools.debugger.remote-enabled";
+const SHOW_PLATFORM_DATA = "devtools.profiler.ui.show-platform-data";
 const PROFILE_IDLE = 0;
 const PROFILE_RUNNING = 1;
 const PROFILE_COMPLETED = 2;
 
 Cu.import("resource:///modules/devtools/gDevTools.jsm", temp);
 let gDevTools = temp.gDevTools;
 
 Cu.import("resource://gre/modules/devtools/Loader.jsm", temp);
@@ -24,16 +25,17 @@ let HUDService = temp.HUDService;
 // Import the GCLI test helper
 let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
 
 registerCleanupFunction(function () {
   helpers = null;
   Services.prefs.clearUserPref(PROFILER_ENABLED);
   Services.prefs.clearUserPref(REMOTE_ENABLED);
+  Services.prefs.clearUserPref(SHOW_PLATFORM_DATA);
   DebuggerServer.destroy();
 });
 
 function getProfileInternals(uid) {
   let profile = (uid != null) ? gPanel.profiles.get(uid) : gPanel.activeProfile;
   let win = profile.iframe.contentWindow;
   let doc = win.document;
 
--- a/browser/devtools/responsivedesign/test/browser_responsiveui.js
+++ b/browser/devtools/responsivedesign/test/browser_responsiveui.js
@@ -127,21 +127,27 @@ function test() {
       info("XXX BUG 851296: 'off' received.");
       executeSoon(restart);
     });
     EventUtils.synthesizeKey("VK_ESCAPE", {});
   }
 
   function restart() {
     info("XXX BUG 851296: restarting.");
-    mgr.once("on", function() {executeSoon(onUIOpen2)});
+    info("XXX BUG 851296: __responsiveUI: " + gBrowser.selectedTab.__responsiveUI);
+    mgr.once("on", function() {
+      info("XXX BUG 851296: 'on' received.");
+      executeSoon(onUIOpen2);
+    });
     synthesizeKeyFromKeyTag("key_responsiveUI");
+    info("XXX BUG 851296: restart() finished.");
   }
 
   function onUIOpen2() {
+    info("XXX BUG 851296: onUIOpen2.");
     let container = gBrowser.getBrowserContainer();
     is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
 
     // Menus are correctly updated?
     is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
 
     is(content.innerWidth, widthBeforeClose, "width restored.");
     is(content.innerHeight, heightBeforeClose, "height restored.");
@@ -178,11 +184,13 @@ function test() {
     let modifiers = {
       shiftKey: modifiersAttr.match("shift"),
       ctrlKey: modifiersAttr.match("ctrl"),
       altKey: modifiersAttr.match("alt"),
       metaKey: modifiersAttr.match("meta"),
       accelKey: modifiersAttr.match("accel")
     }
 
+    info("XXX BUG 851296: key name: " + name);
+    info("XXX BUG 851296: key modifiers: " + JSON.stringify(modifiers));
     EventUtils.synthesizeKey(name, modifiers);
   }
 }
--- a/browser/devtools/shared/test/Makefile.in
+++ b/browser/devtools/shared/test/Makefile.in
@@ -7,30 +7,36 @@ DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_BROWSER_FILES = \
-  browser_telemetry_toolboxtabs.js \
-  browser_telemetry_buttonsandsidebar.js \
-  browser_require_basic.js \
-  browser_templater_basic.js \
-  browser_toolbar_basic.js \
-  browser_toolbar_tooltip.js \
-  browser_toolbar_webconsole_errors_count.js \
-  browser_layoutHelpers.js \
-  browser_eventemitter_basic.js \
-  head.js \
-  leakhunt.js \
-  $(NULL)
+		browser_eventemitter_basic.js \
+		browser_layoutHelpers.js \
+		browser_require_basic.js \
+		browser_telemetry_buttonsandsidebar.js \
+		browser_telemetry_toolboxtabs_inspector.js \
+		browser_telemetry_toolboxtabs_jsdebugger.js \
+		browser_telemetry_toolboxtabs_jsprofiler.js \
+		browser_telemetry_toolboxtabs_netmonitor.js \
+		browser_telemetry_toolboxtabs_options.js \
+		browser_telemetry_toolboxtabs_styleeditor.js \
+		browser_telemetry_toolboxtabs_webconsole.js \
+		browser_templater_basic.js \
+		browser_toolbar_basic.js \
+		browser_toolbar_tooltip.js \
+		browser_toolbar_webconsole_errors_count.js \
+		head.js \
+		leakhunt.js \
+	$(NULL)
 
 MOCHITEST_BROWSER_FILES += \
-  browser_templater_basic.html \
-  browser_toolbar_basic.html \
-  browser_toolbar_webconsole_errors_count.html \
-  browser_layoutHelpers.html \
-  browser_layoutHelpers_iframe.html \
-  $(NULL)
+		browser_templater_basic.html \
+		browser_toolbar_basic.html \
+		browser_toolbar_webconsole_errors_count.html \
+		browser_layoutHelpers.html \
+		browser_layoutHelpers_iframe.html \
+	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
rename from browser/devtools/shared/test/browser_telemetry_toolboxtabs.js
rename to browser/devtools/shared/test/browser_telemetry_toolboxtabs_inspector.js
--- a/browser/devtools/shared/test/browser_telemetry_toolboxtabs.js
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_inspector.js
@@ -1,63 +1,48 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs.js</p>";
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_inspector.js</p>";
 
 // Because we need to gather stats for the period of time that a tool has been
 // opened we make use of setTimeout() to create tool active times.
 const TOOL_DELAY = 200;
 
 let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
 
 let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
 let Telemetry = require("devtools/shared/telemetry");
 
-let tabsToTest = ["inspector", "options", "webconsole", "jsdebugger",
-                   "styleeditor", "jsprofiler", "netmonitor"];
-
 function init() {
   Telemetry.prototype.telemetryInfo = {};
   Telemetry.prototype._oldlog = Telemetry.prototype.log;
   Telemetry.prototype.log = function(histogramId, value) {
     if (histogramId) {
       if (!this.telemetryInfo[histogramId]) {
         this.telemetryInfo[histogramId] = [];
       }
 
       this.telemetryInfo[histogramId].push(value);
     }
   }
 
-  testNextTool();
-}
-
-function testNextTool() {
-  let nextTool = tabsToTest.pop();
-
-  if (nextTool) {
-    openToolboxTabTwice(nextTool);
-  }
+  openToolboxTabTwice("inspector", false);
 }
 
 function openToolboxTabTwice(id, secondPass) {
   let target = TargetFactory.forTab(gBrowser.selectedTab);
 
   gDevTools.showToolbox(target, id).then(function(toolbox) {
     info("Toolbox tab " + id + " opened");
 
     toolbox.once("destroyed", function() {
       if (secondPass) {
-        if (tabsToTest.length > 0) {
-          testNextTool();
-        } else {
-          checkResults();
-        }
+        checkResults();
       } else {
         openToolboxTabTwice(id, true);
       }
     });
     // We use a timeout to check the tools active time
     setTimeout(function() {
       gDevTools.closeToolbox(target);
     }, TOOL_DELAY);
@@ -103,17 +88,17 @@ function reportError(error) {
 
 function finishUp() {
   gBrowser.removeCurrentTab();
 
   Telemetry.prototype.log = Telemetry.prototype._oldlog;
   delete Telemetry.prototype._oldlog;
   delete Telemetry.prototype.telemetryInfo;
 
-  TargetFactory = tabsToTest = Services = Promise = require = null;
+  TargetFactory = Services = Promise = require = null;
 
   finish();
 }
 
 function test() {
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function() {
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_jsdebugger.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_jsdebugger.js</p>";
+
+// Because we need to gather stats for the period of time that a tool has been
+// opened we make use of setTimeout() to create tool active times.
+const TOOL_DELAY = 200;
+
+let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
+let Telemetry = require("devtools/shared/telemetry");
+
+function init() {
+  Telemetry.prototype.telemetryInfo = {};
+  Telemetry.prototype._oldlog = Telemetry.prototype.log;
+  Telemetry.prototype.log = function(histogramId, value) {
+    if (histogramId) {
+      if (!this.telemetryInfo[histogramId]) {
+        this.telemetryInfo[histogramId] = [];
+      }
+
+      this.telemetryInfo[histogramId].push(value);
+    }
+  }
+
+  openToolboxTabTwice("jsdebugger", false);
+}
+
+function openToolboxTabTwice(id, secondPass) {
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+
+  gDevTools.showToolbox(target, id).then(function(toolbox) {
+    info("Toolbox tab " + id + " opened");
+
+    toolbox.once("destroyed", function() {
+      if (secondPass) {
+        checkResults();
+      } else {
+        openToolboxTabTwice(id, true);
+      }
+    });
+    // We use a timeout to check the tools active time
+    setTimeout(function() {
+      gDevTools.closeToolbox(target);
+    }, TOOL_DELAY);
+  }).then(null, reportError);
+}
+
+function checkResults() {
+  let result = Telemetry.prototype.telemetryInfo;
+
+  for (let [histId, value] of Iterator(result)) {
+    if (histId.endsWith("OPENED_PER_USER_FLAG")) {
+      ok(value.length === 1 && value[0] === true,
+         "Per user value " + histId + " has a single value of true");
+    } else if (histId.endsWith("OPENED_BOOLEAN")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element === true;
+      });
+
+      ok(okay, "All " + histId + " entries are === true");
+    } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element > 0;
+      });
+
+      ok(okay, "All " + histId + " entries have time > 0");
+    }
+  }
+
+  finishUp();
+}
+
+function reportError(error) {
+  let stack = "    " + error.stack.replace(/\n?.*?@/g, "\n    JS frame :: ");
+
+  ok(false, "ERROR: " + error + " at " + error.fileName + ":" +
+            error.lineNumber + "\n\nStack trace:" + stack);
+  finishUp();
+}
+
+function finishUp() {
+  gBrowser.removeCurrentTab();
+
+  Telemetry.prototype.log = Telemetry.prototype._oldlog;
+  delete Telemetry.prototype._oldlog;
+  delete Telemetry.prototype.telemetryInfo;
+
+  TargetFactory = Services = Promise = require = null;
+
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(init, content);
+  }, true);
+
+  content.location = TEST_URI;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_jsprofiler.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_jsprofiler.js</p>";
+
+// Because we need to gather stats for the period of time that a tool has been
+// opened we make use of setTimeout() to create tool active times.
+const TOOL_DELAY = 200;
+
+let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
+let Telemetry = require("devtools/shared/telemetry");
+
+function init() {
+  Telemetry.prototype.telemetryInfo = {};
+  Telemetry.prototype._oldlog = Telemetry.prototype.log;
+  Telemetry.prototype.log = function(histogramId, value) {
+    if (histogramId) {
+      if (!this.telemetryInfo[histogramId]) {
+        this.telemetryInfo[histogramId] = [];
+      }
+
+      this.telemetryInfo[histogramId].push(value);
+    }
+  }
+
+  openToolboxTabTwice("jsprofiler", false);
+}
+
+function openToolboxTabTwice(id, secondPass) {
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+
+  gDevTools.showToolbox(target, id).then(function(toolbox) {
+    info("Toolbox tab " + id + " opened");
+
+    toolbox.once("destroyed", function() {
+      if (secondPass) {
+        checkResults();
+      } else {
+        openToolboxTabTwice(id, true);
+      }
+    });
+    // We use a timeout to check the tools active time
+    setTimeout(function() {
+      gDevTools.closeToolbox(target);
+    }, TOOL_DELAY);
+  }).then(null, reportError);
+}
+
+function checkResults() {
+  let result = Telemetry.prototype.telemetryInfo;
+
+  for (let [histId, value] of Iterator(result)) {
+    if (histId.endsWith("OPENED_PER_USER_FLAG")) {
+      ok(value.length === 1 && value[0] === true,
+         "Per user value " + histId + " has a single value of true");
+    } else if (histId.endsWith("OPENED_BOOLEAN")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element === true;
+      });
+
+      ok(okay, "All " + histId + " entries are === true");
+    } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element > 0;
+      });
+
+      ok(okay, "All " + histId + " entries have time > 0");
+    }
+  }
+
+  finishUp();
+}
+
+function reportError(error) {
+  let stack = "    " + error.stack.replace(/\n?.*?@/g, "\n    JS frame :: ");
+
+  ok(false, "ERROR: " + error + " at " + error.fileName + ":" +
+            error.lineNumber + "\n\nStack trace:" + stack);
+  finishUp();
+}
+
+function finishUp() {
+  gBrowser.removeCurrentTab();
+
+  Telemetry.prototype.log = Telemetry.prototype._oldlog;
+  delete Telemetry.prototype._oldlog;
+  delete Telemetry.prototype.telemetryInfo;
+
+  TargetFactory = Services = Promise = require = null;
+
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(init, content);
+  }, true);
+
+  content.location = TEST_URI;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_netmonitor.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_netmonitor.js</p>";
+
+// Because we need to gather stats for the period of time that a tool has been
+// opened we make use of setTimeout() to create tool active times.
+const TOOL_DELAY = 200;
+
+let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
+let Telemetry = require("devtools/shared/telemetry");
+
+function init() {
+  Telemetry.prototype.telemetryInfo = {};
+  Telemetry.prototype._oldlog = Telemetry.prototype.log;
+  Telemetry.prototype.log = function(histogramId, value) {
+    if (histogramId) {
+      if (!this.telemetryInfo[histogramId]) {
+        this.telemetryInfo[histogramId] = [];
+      }
+
+      this.telemetryInfo[histogramId].push(value);
+    }
+  }
+
+  openToolboxTabTwice("netmonitor", false);
+}
+
+function openToolboxTabTwice(id, secondPass) {
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+
+  gDevTools.showToolbox(target, id).then(function(toolbox) {
+    info("Toolbox tab " + id + " opened");
+
+    toolbox.once("destroyed", function() {
+      if (secondPass) {
+        checkResults();
+      } else {
+        openToolboxTabTwice(id, true);
+      }
+    });
+    // We use a timeout to check the tools active time
+    setTimeout(function() {
+      gDevTools.closeToolbox(target);
+    }, TOOL_DELAY);
+  }).then(null, reportError);
+}
+
+function checkResults() {
+  let result = Telemetry.prototype.telemetryInfo;
+
+  for (let [histId, value] of Iterator(result)) {
+    if (histId.endsWith("OPENED_PER_USER_FLAG")) {
+      ok(value.length === 1 && value[0] === true,
+         "Per user value " + histId + " has a single value of true");
+    } else if (histId.endsWith("OPENED_BOOLEAN")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element === true;
+      });
+
+      ok(okay, "All " + histId + " entries are === true");
+    } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element > 0;
+      });
+
+      ok(okay, "All " + histId + " entries have time > 0");
+    }
+  }
+
+  finishUp();
+}
+
+function reportError(error) {
+  let stack = "    " + error.stack.replace(/\n?.*?@/g, "\n    JS frame :: ");
+
+  ok(false, "ERROR: " + error + " at " + error.fileName + ":" +
+            error.lineNumber + "\n\nStack trace:" + stack);
+  finishUp();
+}
+
+function finishUp() {
+  gBrowser.removeCurrentTab();
+
+  Telemetry.prototype.log = Telemetry.prototype._oldlog;
+  delete Telemetry.prototype._oldlog;
+  delete Telemetry.prototype.telemetryInfo;
+
+  TargetFactory = Services = Promise = require = null;
+
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(init, content);
+  }, true);
+
+  content.location = TEST_URI;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_options.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_options.js</p>";
+
+// Because we need to gather stats for the period of time that a tool has been
+// opened we make use of setTimeout() to create tool active times.
+const TOOL_DELAY = 200;
+
+let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
+let Telemetry = require("devtools/shared/telemetry");
+
+function init() {
+  Telemetry.prototype.telemetryInfo = {};
+  Telemetry.prototype._oldlog = Telemetry.prototype.log;
+  Telemetry.prototype.log = function(histogramId, value) {
+    if (histogramId) {
+      if (!this.telemetryInfo[histogramId]) {
+        this.telemetryInfo[histogramId] = [];
+      }
+
+      this.telemetryInfo[histogramId].push(value);
+    }
+  }
+
+  openToolboxTabTwice("options", false);
+}
+
+function openToolboxTabTwice(id, secondPass) {
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+
+  gDevTools.showToolbox(target, id).then(function(toolbox) {
+    info("Toolbox tab " + id + " opened");
+
+    toolbox.once("destroyed", function() {
+      if (secondPass) {
+        checkResults();
+      } else {
+        openToolboxTabTwice(id, true);
+      }
+    });
+    // We use a timeout to check the tools active time
+    setTimeout(function() {
+      gDevTools.closeToolbox(target);
+    }, TOOL_DELAY);
+  }).then(null, reportError);
+}
+
+function checkResults() {
+  let result = Telemetry.prototype.telemetryInfo;
+
+  for (let [histId, value] of Iterator(result)) {
+    if (histId.endsWith("OPENED_PER_USER_FLAG")) {
+      ok(value.length === 1 && value[0] === true,
+         "Per user value " + histId + " has a single value of true");
+    } else if (histId.endsWith("OPENED_BOOLEAN")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element === true;
+      });
+
+      ok(okay, "All " + histId + " entries are === true");
+    } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element > 0;
+      });
+
+      ok(okay, "All " + histId + " entries have time > 0");
+    }
+  }
+
+  finishUp();
+}
+
+function reportError(error) {
+  let stack = "    " + error.stack.replace(/\n?.*?@/g, "\n    JS frame :: ");
+
+  ok(false, "ERROR: " + error + " at " + error.fileName + ":" +
+            error.lineNumber + "\n\nStack trace:" + stack);
+  finishUp();
+}
+
+function finishUp() {
+  gBrowser.removeCurrentTab();
+
+  Telemetry.prototype.log = Telemetry.prototype._oldlog;
+  delete Telemetry.prototype._oldlog;
+  delete Telemetry.prototype.telemetryInfo;
+
+  TargetFactory = Services = Promise = require = null;
+
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(init, content);
+  }, true);
+
+  content.location = TEST_URI;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_styleeditor.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_styleeditor.js</p>";
+
+// Because we need to gather stats for the period of time that a tool has been
+// opened we make use of setTimeout() to create tool active times.
+const TOOL_DELAY = 200;
+
+let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
+let Telemetry = require("devtools/shared/telemetry");
+
+function init() {
+  Telemetry.prototype.telemetryInfo = {};
+  Telemetry.prototype._oldlog = Telemetry.prototype.log;
+  Telemetry.prototype.log = function(histogramId, value) {
+    if (histogramId) {
+      if (!this.telemetryInfo[histogramId]) {
+        this.telemetryInfo[histogramId] = [];
+      }
+
+      this.telemetryInfo[histogramId].push(value);
+    }
+  }
+
+  openToolboxTabTwice("styleeditor", false);
+}
+
+function openToolboxTabTwice(id, secondPass) {
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+
+  gDevTools.showToolbox(target, id).then(function(toolbox) {
+    info("Toolbox tab " + id + " opened");
+
+    toolbox.once("destroyed", function() {
+      if (secondPass) {
+        checkResults();
+      } else {
+        openToolboxTabTwice(id, true);
+      }
+    });
+    // We use a timeout to check the tools active time
+    setTimeout(function() {
+      gDevTools.closeToolbox(target);
+    }, TOOL_DELAY);
+  }).then(null, reportError);
+}
+
+function checkResults() {
+  let result = Telemetry.prototype.telemetryInfo;
+
+  for (let [histId, value] of Iterator(result)) {
+    if (histId.endsWith("OPENED_PER_USER_FLAG")) {
+      ok(value.length === 1 && value[0] === true,
+         "Per user value " + histId + " has a single value of true");
+    } else if (histId.endsWith("OPENED_BOOLEAN")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element === true;
+      });
+
+      ok(okay, "All " + histId + " entries are === true");
+    } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element > 0;
+      });
+
+      ok(okay, "All " + histId + " entries have time > 0");
+    }
+  }
+
+  finishUp();
+}
+
+function reportError(error) {
+  let stack = "    " + error.stack.replace(/\n?.*?@/g, "\n    JS frame :: ");
+
+  ok(false, "ERROR: " + error + " at " + error.fileName + ":" +
+            error.lineNumber + "\n\nStack trace:" + stack);
+  finishUp();
+}
+
+function finishUp() {
+  gBrowser.removeCurrentTab();
+
+  Telemetry.prototype.log = Telemetry.prototype._oldlog;
+  delete Telemetry.prototype._oldlog;
+  delete Telemetry.prototype.telemetryInfo;
+
+  TargetFactory = Services = Promise = require = null;
+
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(init, content);
+  }, true);
+
+  content.location = TEST_URI;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_telemetry_toolboxtabs_webconsole.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_styleeditor_webconsole.js</p>";
+
+// Because we need to gather stats for the period of time that a tool has been
+// opened we make use of setTimeout() to create tool active times.
+const TOOL_DELAY = 200;
+
+let {Promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
+let Telemetry = require("devtools/shared/telemetry");
+
+function init() {
+  Telemetry.prototype.telemetryInfo = {};
+  Telemetry.prototype._oldlog = Telemetry.prototype.log;
+  Telemetry.prototype.log = function(histogramId, value) {
+    if (histogramId) {
+      if (!this.telemetryInfo[histogramId]) {
+        this.telemetryInfo[histogramId] = [];
+      }
+
+      this.telemetryInfo[histogramId].push(value);
+    }
+  }
+
+  openToolboxTabTwice("webconsole", false);
+}
+
+function openToolboxTabTwice(id, secondPass) {
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+
+  gDevTools.showToolbox(target, id).then(function(toolbox) {
+    info("Toolbox tab " + id + " opened");
+
+    toolbox.once("destroyed", function() {
+      if (secondPass) {
+        checkResults();
+      } else {
+        openToolboxTabTwice(id, true);
+      }
+    });
+    // We use a timeout to check the tools active time
+    setTimeout(function() {
+      gDevTools.closeToolbox(target);
+    }, TOOL_DELAY);
+  }).then(null, reportError);
+}
+
+function checkResults() {
+  let result = Telemetry.prototype.telemetryInfo;
+
+  for (let [histId, value] of Iterator(result)) {
+    if (histId.endsWith("OPENED_PER_USER_FLAG")) {
+      ok(value.length === 1 && value[0] === true,
+         "Per user value " + histId + " has a single value of true");
+    } else if (histId.endsWith("OPENED_BOOLEAN")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element === true;
+      });
+
+      ok(okay, "All " + histId + " entries are === true");
+    } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) {
+      ok(value.length > 1, histId + " has more than one entry");
+
+      let okay = value.every(function(element) {
+        return element > 0;
+      });
+
+      ok(okay, "All " + histId + " entries have time > 0");
+    }
+  }
+
+  finishUp();
+}
+
+function reportError(error) {
+  let stack = "    " + error.stack.replace(/\n?.*?@/g, "\n    JS frame :: ");
+
+  ok(false, "ERROR: " + error + " at " + error.fileName + ":" +
+            error.lineNumber + "\n\nStack trace:" + stack);
+  finishUp();
+}
+
+function finishUp() {
+  gBrowser.removeCurrentTab();
+
+  Telemetry.prototype.log = Telemetry.prototype._oldlog;
+  delete Telemetry.prototype._oldlog;
+  delete Telemetry.prototype.telemetryInfo;
+
+  TargetFactory = Services = Promise = require = null;
+
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(init, content);
+  }, true);
+
+  content.location = TEST_URI;
+}
--- a/browser/devtools/styleeditor/StyleEditorDebuggee.jsm
+++ b/browser/devtools/styleeditor/StyleEditorDebuggee.jsm
@@ -217,23 +217,21 @@ let StyleSheet = function(form, debuggee
   EventEmitter.decorate(this);
 
   this.debuggee = debuggee;
   this._client = debuggee.client;
   this._actor = form.actor;
 
   this._onSourceLoad = this._onSourceLoad.bind(this);
   this._onPropertyChange = this._onPropertyChange.bind(this);
-  this._onError = this._onError.bind(this);
   this._onStyleApplied = this._onStyleApplied.bind(this);
 
-  this._client.addListener("sourceLoad-" + this._actor, this._onSourceLoad);
-  this._client.addListener("propertyChange-" + this._actor, this._onPropertyChange);
-  this._client.addListener("error-" + this._actor, this._onError);
-  this._client.addListener("styleApplied-" + this._actor, this._onStyleApplied);
+  this._client.addListener("sourceLoad", this._onSourceLoad);
+  this._client.addListener("propertyChange", this._onPropertyChange);
+  this._client.addListener("styleApplied", this._onStyleApplied);
 
   // set initial property values
   for (let attr in form) {
     this[attr] = form[attr];
   }
 }
 
 StyleSheet.prototype = {
@@ -269,49 +267,46 @@ StyleSheet.prototype = {
    * Handle source load event from the client.
    *
    * @param {string} type
    *        Event type
    * @param {object} request
    *        Event details
    */
   _onSourceLoad: function(type, request) {
-    this.emit("source-load", request.source);
+    if (request.from == this._actor) {
+      if (request.error) {
+        return this.emit("error", request.error);
+      }
+      this.emit("source-load", request.source);
+    }
   },
 
   /**
    * Handle a property change on the stylesheet
    *
    * @param {string} type
    *        Event type
    * @param {object} request
    *        Event details
    */
   _onPropertyChange: function(type, request) {
-    this[request.property] = request.value;
-    this.emit("property-change", request.property);
-  },
-
-  /**
-   * Propogate errors from the server that relate to this stylesheet.
-   *
-   * @param {string} type
-   *        Event type
-   * @param {object} request
-   *        Event details
-   */
-  _onError: function(type, request) {
-    this.emit("error", request.errorMessage);
+    if (request.from == this._actor) {
+      this[request.property] = request.value;
+      this.emit("property-change", request.property);
+    }
   },
 
   /**
    * Handle event when update has been successfully applied and propogate it.
    */
-  _onStyleApplied: function() {
-    this.emit("style-applied");
+  _onStyleApplied: function(type, request) {
+    if (request.from == this._actor) {
+      this.emit("style-applied");
+    }
   },
 
   /**
    * Send a request to our actor on the server
    *
    * @param {object} message
    *        Message to send to the actor
    * @param {function} callback
@@ -321,14 +316,13 @@ StyleSheet.prototype = {
     message.to = this._actor;
     this._client.request(message, callback);
   },
 
   /**
    * Clean up and remove event listeners
    */
   destroy: function() {
-    this._client.removeListener("sourceLoad-" + this._actor, this._onSourceLoad);
-    this._client.removeListener("propertyChange-" + this._actor, this._onPropertyChange);
-    this._client.removeListener("error-" + this._actor, this._onError);
-    this._client.removeListener("styleApplied-" + this._actor, this._onStyleApplied);
+    this._client.removeListener("sourceLoad", this._onSourceLoad);
+    this._client.removeListener("propertyChange", this._onPropertyChange);
+    this._client.removeListener("styleApplied", this._onStyleApplied);
   }
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -274,10 +274,55 @@ function popupHideAfterReturnWithNoSelec
 
   ok(!popup.isOpen, "popup is not open after VK_RETURN");
 
   is(inputNode.value, "", "inputNode is empty after VK_RETURN");
   is(completeNode.value, "", "completeNode is empty");
   is(jsterm.history[jsterm.history.length-1], "window.testBug",
      "jsterm history is correct");
 
-  executeSoon(finishTest);
+  executeSoon(testCompletionInText);
 }
+
+function testCompletionInText()
+{
+  info("test that completion works inside text, see bug 812618");
+
+  popup._panel.addEventListener("popupshown", function onShown() {
+    popup._panel.removeEventListener("popupshown", onShown);
+
+    ok(popup.isOpen, "popup is open");
+    is(popup.itemCount, 2, "popup.itemCount is correct");
+
+    EventUtils.synthesizeKey("VK_DOWN", {});
+    EventUtils.synthesizeKey("VK_DOWN", {});
+    is(popup.selectedIndex, 0, "popup.selectedIndex is correct");
+    ok(!completeNode.value, "completeNode.value is empty");
+
+    let items = popup.getItems().reverse().map(e => e.label);
+    let sameItems = items.every((prop, index) =>
+      ["testBug873250a", "testBug873250b"][index] === prop);
+    ok(sameItems, "getItems returns the items we expect");
+
+    info("press Tab and wait for popup to hide");
+    popup._panel.addEventListener("popuphidden", popupHideAfterCompletionInText);
+    EventUtils.synthesizeKey("VK_TAB", {});
+  });
+
+  jsterm.setInputValue("dump(window.testBu)");
+  inputNode.selectionStart = inputNode.selectionEnd = 18;
+  EventUtils.synthesizeKey("g", {});
+}
+
+function popupHideAfterCompletionInText()
+{
+  // At this point the completion suggestion should be accepted.
+  popup._panel.removeEventListener("popuphidden", popupHideAfterCompletionInText);
+
+  ok(!popup.isOpen, "popup is not open");
+  is(inputNode.value, "dump(window.testBug873250b)",
+     "completion was successful after VK_TAB");
+  is(inputNode.selectionStart, 26, "cursor location is correct");
+  is(inputNode.selectionStart, inputNode.selectionEnd, "cursor location (confirmed)");
+  ok(!completeNode.value, "completeNode is empty");
+
+  finishTest();
+}
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_622303_persistent_filters.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_622303_persistent_filters.js
@@ -1,15 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 let prefs = {
   "net": [
     "network",
-    "networkinfo"
+    "netwarn",
+    "networkinfo",
   ],
   "css": [
     "csserror",
     "cssparser"
   ],
   "js": [
     "exception",
     "jswarn",
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_737873_mixedcontent.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_737873_mixedcontent.js
@@ -7,90 +7,69 @@
  *  Tanvi Vyas <tanvi@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the Web Console Mixed Content messages are displayed
 
 const TEST_HTTPS_URI = "https://example.com/browser/browser/devtools/webconsole/test/test-bug-737873-mixedcontent.html";
 
-var origBlockDisplay;
-var origBlockActive;
-
 function test() {
   addTab("data:text/html;charset=utf8,Web Console mixed content test");
   browser.addEventListener("load", onLoad, true);
 }
 
 function onLoad(aEvent) {
   browser.removeEventListener("load", onLoad, true);
-  origBlockDisplay = Services.prefs.getBoolPref("security.mixed_content.block_display_content");
-  origBlockActive = Services.prefs.getBoolPref("security.mixed_content.block_active_content")
   Services.prefs.setBoolPref("security.mixed_content.block_display_content", false);
   Services.prefs.setBoolPref("security.mixed_content.block_active_content", false);
   openConsole(null, testMixedContent);
 }
 
 function testMixedContent(hud) {
   content.location = TEST_HTTPS_URI;
-  var aOutputNode = hud.outputNode;
-
-  waitForSuccess(
-    {
-      name: "mixed content warning displayed successfully",
-      timeout: 20000,
-      validatorFn: function() {
-        return ( aOutputNode.querySelector(".webconsole-mixed-content") );
-      },
-
-      successFn: function() {
 
-        //tests on the urlnode
-        let node = aOutputNode.querySelector(".webconsole-mixed-content");
-        ok(testSeverity(node), "Severity type is SEVERITY_WARNING.");
-
-        //tests on the warningNode
-        let warningNode = aOutputNode.querySelector(".webconsole-mixed-content-link");
-        is(warningNode.value, "[Mixed Content]", "Message text is accurate." );
-        testClickOpenNewTab(warningNode);
+  waitForMessages({
+    webconsole: hud,
+    messages: [{
+      text: "example.com",
+      category: CATEGORY_NETWORK,
+      severity: SEVERITY_WARNING,
+    }],
+  }).then((results) => {
+    let msg = [...results[0].matched][0];
+    ok(msg, "page load logged");
 
-        endTest();
-      },
+    let mixedContent = msg.querySelector(".webconsole-mixed-content");
+    ok(mixedContent, ".webconsole-mixed-content element");
 
-      failureFn: endTest,
-    }
-  );
-
-}
+    let link = msg.querySelector(".webconsole-mixed-content-link");
+    ok(link, "mixed content link element");
+    is(link.value, "[Mixed Content]", "link text is accurate");
 
-function testSeverity(node) {
-  let linkNode = node.parentNode;
-  let msgNode = linkNode.parentNode;
-  let bodyNode = msgNode.parentNode;
-  let finalNode = bodyNode.parentNode;
-
-  return finalNode.classList.contains("webconsole-msg-warn");
-}
-
-function testClickOpenNewTab(warningNode) {
-  /* Invoke the click event and check if a new tab would open to the correct page */
-  let linkOpened = false;
-  let oldOpenUILinkIn = window.openUILinkIn;
-
-  window.openUILinkIn = function(aLink) {
-    if (aLink == "https://developer.mozilla.org/en/Security/MixedContent") {
+    let oldOpenLink = hud.openLink;
+    let linkOpened = false;
+    hud.openLink = (url) => {
+      is(url, "https://developer.mozilla.org/en/Security/MixedContent",
+         "url opened");
       linkOpened = true;
-    }
-  }
+    };
+
+    EventUtils.synthesizeMouse(link, 2, 2, {}, link.ownerDocument.defaultView);
 
-  EventUtils.synthesizeMouse(warningNode, 2, 2, {},
-                             warningNode.ownerDocument.defaultView);
+    ok(linkOpened, "clicking the Mixed Content link opened a page");
 
-  ok(linkOpened, "Clicking the Mixed Content Warning node opens the desired page");
+    hud.openLink = oldOpenLink;
+
+    ok(!msg.classList.contains("hud-filtered-by-type"), "message is not filtered");
 
-  window.openUILinkIn = oldOpenUILinkIn;
-}
+    hud.setFilterState("netwarn", false);
+
+    ok(msg.classList.contains("hud-filtered-by-type"), "message is filtered");
+
+    hud.setFilterState("netwarn", true);
 
-function endTest() {
-  Services.prefs.setBoolPref("security.mixed_content.block_display_content", origBlockDisplay);
-  Services.prefs.setBoolPref("security.mixed_content.block_active_content", origBlockActive);
-  finishTest();
+    Services.prefs.clearUserPref("security.mixed_content.block_display_content");
+    Services.prefs.clearUserPref("security.mixed_content.block_active_content");
+
+    finishTest();
+  });
 }
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -114,17 +114,17 @@ const SEVERITY_CLASS_FRAGMENTS = [
 
 // The preference keys to use for each category/severity combination, indexed
 // first by category (rows) and then by severity (columns).
 //
 // Most of these rather idiosyncratic names are historical and predate the
 // division of message type into "category" and "severity".
 const MESSAGE_PREFERENCE_KEYS = [
 //  Error         Warning   Info    Log
-  [ "network",    null,         null,   "networkinfo", ],  // Network
+  [ "network",    "netwarn",    null,   "networkinfo", ],  // Network
   [ "csserror",   "cssparser",  null,   null,          ],  // CSS
   [ "exception",  "jswarn",     null,   "jslog",       ],  // JS
   [ "error",      "warn",       "info", "log",         ],  // Web Developer
   [ null,         null,         null,   null,          ],  // Input
   [ null,         null,         null,   null,          ],  // Output
   [ "secerror",   "secwarn",    null,   null,          ],  // Security
 ];
 
@@ -554,17 +554,17 @@ WebConsoleFrame.prototype = {
   /**
    * Initialize the default filter preferences.
    * @private
    */
   _initDefaultFilterPrefs: function WCF__initDefaultFilterPrefs()
   {
     let prefs = ["network", "networkinfo", "csserror", "cssparser", "exception",
                  "jswarn", "jslog", "error", "info", "warn", "log", "secerror",
-                 "secwarn"];
+                 "secwarn", "netwarn"];
     for (let pref of prefs) {
       this.filterPrefs[pref] = Services.prefs
                                .getBoolPref(this._filterPrefsPrefix + pref);
     }
   },
 
   /**
    * Sets the events for the filter input field.
@@ -4072,19 +4072,18 @@ JSTerm.prototype = {
     let inputNode = this.inputNode;
     let inputValue = inputNode.value;
     // If the inputNode has no value, then don't try to complete on it.
     if (!inputValue) {
       this.clearCompletion();
       return false;
     }
 
-    // Only complete if the selection is empty and at the end of the input.
-    if (inputNode.selectionStart == inputNode.selectionEnd &&
-        inputNode.selectionEnd != inputValue.length) {
+    // Only complete if the selection is empty.
+    if (inputNode.selectionStart != inputNode.selectionEnd) {
       this.clearCompletion();
       return false;
     }
 
     // Update the completion results.
     if (this.lastCompletion.value != inputValue) {
       this._updateCompletionResult(aType, aCallback);
       return false;
@@ -4210,16 +4209,21 @@ JSTerm.prototype = {
       popup.selectNextItem();
     }
 
     aCallback && aCallback(this);
   },
 
   onAutocompleteSelect: function JSTF_onAutocompleteSelect()
   {
+    // Render the suggestion only if the cursor is at the end of the input.
+    if (this.inputNode.selectionStart != this.inputNode.value.length) {
+      return;
+    }
+
     let currentItem = this.autocompletePopup.selectedItem;
     if (currentItem && this.lastCompletion.value) {
       let suffix = currentItem.label.substring(this.lastCompletion.
                                                matchProp.length);
       this.updateCompleteNode(suffix);
     }
     else {
       this.updateCompleteNode("");
@@ -4251,17 +4255,21 @@ JSTerm.prototype = {
   acceptProposedCompletion: function JSTF_acceptProposedCompletion()
   {
     let updated = false;
 
     let currentItem = this.autocompletePopup.selectedItem;
     if (currentItem && this.lastCompletion.value) {
       let suffix = currentItem.label.substring(this.lastCompletion.
                                                matchProp.length);
-      this.setInputValue(this.inputNode.value + suffix);
+      let cursor = this.inputNode.selectionStart;
+      let value = this.inputNode.value;
+      this.setInputValue(value.substr(0, cursor) + suffix + value.substr(cursor));
+      let newCursor = cursor + suffix.length;
+      this.inputNode.selectionStart = this.inputNode.selectionEnd = newCursor;
       updated = true;
     }
 
     this.clearCompletion();
 
     return updated;
   },
 
--- a/browser/devtools/webconsole/webconsole.xul
+++ b/browser/devtools/webconsole/webconsole.xul
@@ -82,16 +82,18 @@
                        accesskey="&btnPageNet.accesskeyMacOSX;"
 #else
                        accesskey="&btnPageNet.accesskey;"
 #endif
                        tabindex="3">
           <menupopup>
             <menuitem label="&btnConsoleErrors;" type="checkbox" autocheck="false"
                       prefKey="network"/>
+            <menuitem label="&btnConsoleWarnings;" type="checkbox" autocheck="false"
+                      prefKey="netwarn"/>
             <menuitem label="&btnConsoleLog;" type="checkbox" autocheck="false"
                       prefKey="networkinfo"/>
             <menuseparator id="saveBodiesSeparator" />
             <menuitem id="saveBodies" type="checkbox" label="&saveBodies.label;"
                       accesskey="&saveBodies.accesskey;"/>
           </menupopup>
         </toolbarbutton>
         <toolbarbutton label="&btnPageCSS.label;" type="menu-button"
--- a/browser/locales/en-US/chrome/browser/devtools/toolbox.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/toolbox.dtd
@@ -74,8 +74,21 @@
 <!ENTITY options.webconsole.label            "Web Console">
 
 <!-- LOCALIZATION NOTE (options.enablePersistentLogging.label): This is the
   -  label for the checkbox that toggles persistent logs in the Web Console,
   -  i.e. devtools.webconsole.persistlog a boolean preference in about:config,
   -  in the options panel. -->
 <!ENTITY options.enablePersistentLogging.label    "Enable persistent logs">
 <!ENTITY options.enablePersistentLogging.tooltip  "If you enable this option the Web Console will not clear the output each time you navigate to a new page">
+
+<!-- LOCALIZATION NOTE (options.profiler.label): This is the label for the
+  -  heading of the group of JavaScript Profiler preferences in the options
+  -  panel. -->
+<!ENTITY options.profiler.label            "JavaScript Profiler">
+
+<!-- LOCALIZATION NOTE (options.showPlatformData.label): This is the
+  -  label for the checkbox that toggles the display of the platform data in the,
+  -  Profiler i.e. devtools.profiler.ui.show-platform-data a boolean preference
+  -  in about:config, in the options panel. -->
+<!ENTITY options.showPlatformData.label    "Show Gecko platform data">
+<!ENTITY options.showPlatformData.tooltip  "If you enable this option the JavaScript Profiler reports will include
+Gecko platform symbols">
deleted file mode 100644
index e937b600b7bca4a2dc614180af6dfc6a35a575d8..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 00d6d450c13ce88f9013d62efcabb6d04c597800..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/linux/devtools/computedview.css
+++ b/browser/themes/linux/devtools/computedview.css
@@ -82,20 +82,16 @@ body {
 }
 
 /* From skin */
 .expander {
   visibility: hidden;
   margin-left: -12px!important;
 }
 
-.expander[open] {
-  margin-left: -17px!important;
-}
-
 .expandable {
   visibility: visible;
 }
 
 .match {
   visibility: hidden;
 }
 
deleted file mode 100644
--- a/browser/themes/linux/devtools/dark-theme.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 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/. */
-
-/* According to:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
- */
-.theme-body {
-  background: #131c26;
-  color: #8fa1b2
-}
-
-.theme-twisty {
-  cursor: pointer;
-  margin-right: 5px;
-}
-
-.theme-twisty:-moz-focusring {
-  outline-style: none;
-}
-
-.theme-twisty:not([open]) {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 5px solid rgba(255,255,255,0.5);
-  margin-left: 5px;
-}
-
-.theme-twisty[open] {
-  width: 10px;
-  height: 10px;
-  background-image: linear-gradient(to bottom right, transparent 68%,  rgba(255,255,255,0.5) 68%);
-}
-
-.theme-checkbox {
-  display: inline-block;
-  border: 0;
-  width: 14px;
-  height: 14px;
-  padding: 0;
-  outline: none;
-  background: url("chrome://browser/skin/devtools/checkbox-dark.png") no-repeat;
-}
-
-.theme-checkbox[checked] {
-  background: url("chrome://browser/skin/devtools/checkbox-dark.png") 14px 0;
-}
-
-.theme-selected {
-  background: #26384E;
-}
-
-.theme-bg-darker {
-  background-color: rgba(0,0,0,0.1);
-}
-
-.theme-link { /* blue */
-  color: #3689b2;
-}
-
-.theme-comment { /* grey */
-  color: #5c6773;
-}
-
-.theme-gutter {
-  background-color: #0f171f;
-  color: #667380;
-  border-color: #303b47;
-}
-
-.theme-separator { /* grey */
-  border-color: #303b47;
-}
-
-.theme-fg-color1 { /* green */
-  color: #5c9966;
-}
-
-.theme-fg-color2 { /* blue */
-  color: #3689b2;
-}
-
-.theme-fg-color3 { /* pink/lavender */
-  color: #a673bf;
-}
-
-.theme-fg-color4 { /* purple/violet */
-  color: #6270b2;
-}
-
-.theme-fg-color5 { /* Yellow */
-  color: #a18650;
-}
-
-.theme-fg-color6 { /* Orange */
-  color: #b26b47;
-}
-
-.theme-fg-color7 { /* Red */
-  color: #bf5656;
-}
deleted file mode 100644
--- a/browser/themes/linux/devtools/light-theme.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 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/. */
-
-/* According to:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
- */
-.theme-body {
-  background: white;
-  color: black;
-}
-
-.theme-twisty {
-  cursor: pointer;
-  margin-right: 5px;
-}
-
-.theme-twisty:-moz-focusring {
-  outline-style: none;
-}
-
-.theme-twisty:not([open]) {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 5px solid rgba(0,0,0,0.5);
-  margin-left: 5px;
-}
-
-.theme-twisty[open] {
-  width: 10px;
-  height: 10px;
-  background-image: linear-gradient(to bottom right, transparent 68%,  rgba(0,0,0,0.5) 68%);
-}
-
-.theme-checkbox {
-  display: inline-block;
-  border: 0;
-  width: 14px;
-  height: 14px;
-  padding: 0;
-  outline: none;
-  background: url("chrome://browser/skin/devtools/checkbox-light.png") no-repeat;
-}
-
-.theme-checkbox[checked] {
-  background: url("chrome://browser/skin/devtools/checkbox-light.png") 14px 0;
-}
-
-.theme-selected {
-  background-color: hsl(0,0%,90%);
-}
-
-.theme-bg-darker {
-  background: #F9F9F9;
-}
-
-.theme-link { /* blue */
-  color: hsl(208,56%,40%);
-}
-
-.theme-comment { /* grey */
-  color: hsl(90,2%,46%);
-}
-
-.theme-gutter {
-  background-color: hsl(0,0%,90%);
-  color: #667380;
-  border-color: hsl(0,0%,65%);
-}
-
-.theme-separator { /* grey */
-  border-color: #cddae5;
-}
-
-.theme-fg-color1 { /* green */
-  color: hsl(72,100%,27%);
-}
-
-.theme-fg-color2 { /* blue */
-  color: hsl(208,56%,40%);
-}
-
-.theme-fg-color3 { /* dark blue */
-  color: hsl(208,81%,21%)
-}
-
-.theme-fg-color4 { /* Orange */
-  color: hsl(24,85%,39%);
-}
-
-.theme-fg-color5 { /* Yellow */
-  color: #a18650;
-}
-
-.theme-fg-color6 { /* Orange */
-  color: hsl(24,85%,39%);
-}
-
-.theme-fg-color7 { /* Red */
-  color: #bf5656;
-}
deleted file mode 100644
--- a/browser/themes/linux/devtools/markup-view.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/* 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/. */
-
-* {
-  padding: 0;
-  margin: 0;
-}
-
-.newattr {
-  cursor: pointer;
-}
-
-.selected {
-  background-color: hsl(0,0%,90%);
-}
-
-/* Give some padding to focusable elements to match the editor input
- * that will replace them. */
-span[tabindex] {
-  display: inline-block;
-  padding: 1px 0;
-}
-
-li.container {
-  position: relative;
-  padding: 2px 0 0 2px;
-}
-
-.codebox {
-  padding-left: 14px;
-}
-
-.expander {
-  position: absolute;
-}
-
-.more-nodes {
-  padding-left: 16px;
-}
-
-.styleinspector-propertyeditor {
-  border: 1px solid #CCC;
-}
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -118,33 +118,32 @@ browser.jar:
   skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/tabview/edit-light.png         (tabview/edit-light.png)
   skin/classic/browser/tabview/search.png             (tabview/search.png)
   skin/classic/browser/tabview/stack-expander.png     (tabview/stack-expander.png)
   skin/classic/browser/tabview/tabview.png            (tabview/tabview.png)
   skin/classic/browser/tabview/tabview.css            (tabview/tabview.css)
 * skin/classic/browser/devtools/common.css            (devtools/common.css)
-  skin/classic/browser/devtools/dark-theme.css        (devtools/dark-theme.css)
-  skin/classic/browser/devtools/light-theme.css       (devtools/light-theme.css)
+  skin/classic/browser/devtools/dark-theme.css        (../shared/devtools/dark-theme.css)
+  skin/classic/browser/devtools/light-theme.css       (../shared/devtools/light-theme.css)
+  skin/classic/browser/devtools/controls.png          (../shared/devtools/controls.png)
   skin/classic/browser/devtools/widgets.css           (devtools/widgets.css)
   skin/classic/browser/devtools/commandline-icon.png  (devtools/commandline-icon.png)
   skin/classic/browser/devtools/command-paintflashing.png  (devtools/command-paintflashing.png)
   skin/classic/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
   skin/classic/browser/devtools/command-scratchpad.png (devtools/command-scratchpad.png)
   skin/classic/browser/devtools/command-tilt.png      (devtools/command-tilt.png)
   skin/classic/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
   skin/classic/browser/devtools/ruleview.css          (devtools/ruleview.css)
 * skin/classic/browser/devtools/webconsole.css                  (devtools/webconsole.css)
   skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
   skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
-  skin/classic/browser/devtools/checkbox-dark.png     (devtools/checkbox-dark.png)
-  skin/classic/browser/devtools/checkbox-light.png    (devtools/checkbox-light.png)
   skin/classic/browser/devtools/commandline.css              (devtools/commandline.css)
-  skin/classic/browser/devtools/markup-view.css      (devtools/markup-view.css)
+  skin/classic/browser/devtools/markup-view.css       (../shared/devtools/markup-view.css)
   skin/classic/browser/devtools/orion.css             (devtools/orion.css)
   skin/classic/browser/devtools/orion-container.css   (devtools/orion-container.css)
   skin/classic/browser/devtools/orion-task.png        (devtools/orion-task.png)
   skin/classic/browser/devtools/orion-breakpoint.png  (devtools/orion-breakpoint.png)
   skin/classic/browser/devtools/orion-debug-location.png (devtools/orion-debug-location.png)
   skin/classic/browser/devtools/breadcrumbs-scrollbutton.png                 (devtools/breadcrumbs-scrollbutton.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-pressed.png              (devtools/breadcrumbs/ltr-end-pressed.png)
   skin/classic/browser/devtools/breadcrumbs/ltr-end-selected-pressed.png     (devtools/breadcrumbs/ltr-end-selected-pressed.png)
deleted file mode 100644
index e937b600b7bca4a2dc614180af6dfc6a35a575d8..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 00d6d450c13ce88f9013d62efcabb6d04c597800..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/osx/devtools/computedview.css
+++ b/browser/themes/osx/devtools/computedview.css
@@ -100,20 +100,16 @@ body {
 }
 
 /* From skin */
 .expander {
   visibility: hidden;
   margin-left: -12px!important;
 }
 
-.expander[open] {
-  margin-left: -17px!important;
-}
-
 .expandable {
   visibility: visible;
 }
 
 .match {
   visibility: hidden;
 }
 
deleted file mode 100644
--- a/browser/themes/osx/devtools/dark-theme.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 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/. */
-
-/* According to:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
- */
-.theme-body {
-  background: #131c26;
-  color: #8fa1b2
-}
-
-.theme-twisty {
-  cursor: pointer;
-  margin-right: 5px;
-}
-
-.theme-twisty:-moz-focusring {
-  outline-style: none;
-}
-
-.theme-twisty:not([open]) {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 5px solid rgba(255,255,255,0.5);
-  margin-left: 5px;
-}
-
-.theme-twisty[open] {
-  width: 10px;
-  height: 10px;
-  background-image: linear-gradient(to bottom right, transparent 68%,  rgba(255,255,255,0.5) 68%);
-}
-
-.theme-checkbox {
-  display: inline-block;
-  border: 0;
-  width: 14px;
-  height: 14px;
-  padding: 0;
-  outline: none;
-  background: url("chrome://browser/skin/devtools/checkbox-dark.png") no-repeat;
-}
-
-.theme-checkbox[checked] {
-  background: url("chrome://browser/skin/devtools/checkbox-dark.png") 14px 0;
-}
-
-.theme-selected {
-  background: #26384E;
-}
-
-.theme-bg-darker {
-  background-color: rgba(0,0,0,0.1);
-}
-
-.theme-link { /* blue */
-  color: #3689b2;
-}
-
-.theme-comment { /* grey */
-  color: #5c6773;
-}
-
-.theme-gutter {
-  background-color: #0f171f;
-  color: #667380;
-  border-color: #303b47;
-}
-
-.theme-separator { /* grey */
-  border-color: #303b47;
-}
-
-.theme-fg-color1 { /* green */
-  color: #5c9966;
-}
-
-.theme-fg-color2 { /* blue */
-  color: #3689b2;
-}
-
-.theme-fg-color3 { /* pink/lavender */
-  color: #a673bf;
-}
-
-.theme-fg-color4 { /* purple/violet */
-  color: #6270b2;
-}
-
-.theme-fg-color5 { /* Yellow */
-  color: #a18650;
-}
-
-.theme-fg-color6 { /* Orange */
-  color: #b26b47;
-}
-
-.theme-fg-color7 { /* Red */
-  color: #bf5656;
-}
deleted file mode 100644
--- a/browser/themes/osx/devtools/light-theme.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 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/. */
-
-/* According to:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
- */
-.theme-body {
-  background: white;
-  color: black;
-}
-
-.theme-twisty {
-  cursor: pointer;
-  margin-right: 5px;
-}
-
-.theme-twisty:-moz-focusring {
-  outline-style: none;
-}
-
-.theme-twisty:not([open]) {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 5px solid rgba(0,0,0,0.5);
-  margin-left: 5px;
-}
-
-.theme-twisty[open] {
-  width: 10px;
-  height: 10px;
-  background-image: linear-gradient(to bottom right, transparent 68%,  rgba(0,0,0,0.5) 68%);
-}
-
-.theme-checkbox {
-  display: inline-block;
-  border: 0;
-  width: 14px;
-  height: 14px;
-  padding: 0;
-  outline: none;
-  background: url("chrome://browser/skin/devtools/checkbox-light.png") no-repeat;
-}
-
-.theme-checkbox[checked] {
-  background: url("chrome://browser/skin/devtools/checkbox-light.png") 14px 0;
-}
-
-.theme-selected {
-  background-color: hsl(0,0%,90%);
-}
-
-.theme-bg-darker {
-  background: #F9F9F9;
-}
-
-.theme-link { /* blue */
-  color: hsl(208,56%,40%);
-}
-
-.theme-comment { /* grey */
-  color: hsl(90,2%,46%);
-}
-
-.theme-gutter {
-  background-color: hsl(0,0%,90%);
-  color: #667380;
-  border-color: hsl(0,0%,65%);
-}
-
-.theme-separator { /* grey */
-  border-color: #cddae5;
-}
-
-.theme-fg-color1 { /* green */
-  color: hsl(72,100%,27%);
-}
-
-.theme-fg-color2 { /* blue */
-  color: hsl(208,56%,40%);
-}
-
-.theme-fg-color3 { /* dark blue */
-  color: hsl(208,81%,21%)
-}
-
-.theme-fg-color4 { /* Orange */
-  color: hsl(24,85%,39%);
-}
-
-.theme-fg-color5 { /* Yellow */
-  color: #a18650;
-}
-
-.theme-fg-color6 { /* Orange */
-  color: hsl(24,85%,39%);
-}
-
-.theme-fg-color7 { /* Red */
-  color: #bf5656;
-}
deleted file mode 100644
--- a/browser/themes/osx/devtools/markup-view.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/* 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/. */
-
-* {
-  padding: 0;
-  margin: 0;
-}
-
-.newattr {
-  cursor: pointer;
-}
-
-.selected {
-  background-color: hsl(0,0%,90%);
-}
-
-/* Give some padding to focusable elements to match the editor input
- * that will replace them. */
-span[tabindex] {
-  display: inline-block;
-  padding: 1px 0;
-}
-
-li.container {
-  position: relative;
-  padding: 2px 0 0 2px;
-}
-
-.codebox {
-  padding-left: 14px;
-}
-
-.expander {
-  position: absolute;
-}
-
-.more-nodes {
-  padding-left: 16px;
-}
-
-.styleinspector-propertyeditor {
-  border: 1px solid #CCC;
-}
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -206,30 +206,29 @@ browser.jar:
   skin/classic/browser/tabbrowser/tabDragIndicator@2x.png                (tabbrowser/tabDragIndicator@2x.png)
   skin/classic/browser/tabview/close.png                    (tabview/close.png)
   skin/classic/browser/tabview/edit-light.png               (tabview/edit-light.png)
   skin/classic/browser/tabview/search.png                   (tabview/search.png)
   skin/classic/browser/tabview/stack-expander.png           (tabview/stack-expander.png)
   skin/classic/browser/tabview/tabview.png                  (tabview/tabview.png)
   skin/classic/browser/tabview/tabview.css                  (tabview/tabview.css)
 * skin/classic/browser/devtools/common.css                  (devtools/common.css)
-  skin/classic/browser/devtools/dark-theme.css              (devtools/dark-theme.css)
-  skin/classic/browser/devtools/light-theme.css             (devtools/light-theme.css)
+  skin/classic/browser/devtools/dark-theme.css              (../shared/devtools/dark-theme.css)
+  skin/classic/browser/devtools/light-theme.css             (../shared/devtools/light-theme.css)
+  skin/classic/browser/devtools/controls.png                (../shared/devtools/controls.png)
   skin/classic/browser/devtools/widgets.css                 (devtools/widgets.css)
   skin/classic/browser/devtools/commandline-icon.png        (devtools/commandline-icon.png)
   skin/classic/browser/devtools/command-paintflashing.png   (devtools/command-paintflashing.png)
   skin/classic/browser/devtools/command-responsivemode.png  (devtools/command-responsivemode.png)
   skin/classic/browser/devtools/command-scratchpad.png      (devtools/command-scratchpad.png)
   skin/classic/browser/devtools/command-tilt.png            (devtools/command-tilt.png)
   skin/classic/browser/devtools/alerticon-warning.png       (devtools/alerticon-warning.png)
   skin/classic/browser/devtools/ruleview.css                (devtools/ruleview.css)
   skin/classic/browser/devtools/commandline.css             (devtools/commandline.css)
-  skin/classic/browser/devtools/checkbox-dark.png           (devtools/checkbox-dark.png)
-  skin/classic/browser/devtools/checkbox-light.png          (devtools/checkbox-light.png)
-  skin/classic/browser/devtools/markup-view.css             (devtools/markup-view.css)
+  skin/classic/browser/devtools/markup-view.css             (../shared/devtools/markup-view.css)
   skin/classic/browser/devtools/orion.css                   (devtools/orion.css)
   skin/classic/browser/devtools/orion-container.css         (devtools/orion-container.css)
   skin/classic/browser/devtools/orion-task.png              (devtools/orion-task.png)
   skin/classic/browser/devtools/orion-breakpoint.png        (devtools/orion-breakpoint.png)
   skin/classic/browser/devtools/orion-debug-location.png    (devtools/orion-debug-location.png)
 * skin/classic/browser/devtools/webconsole.css                  (devtools/webconsole.css)
   skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
   skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ebba41cd794c88fb0b4c1795bed6525d85061bd5
GIT binary patch
literal 668
zc$@*80%QG&P)<h;3K|Lk000e1NJLTq001}u000~a1^@s6G`oC000004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10vSm}K~z|U-Iy^?6hRn<pO>65K_W`j&iDsZ8YP&}!B5a!DRx%=
z0WCmVT6z*HNPvchn!g~4k;IOK(!|7yyU$`7GPgIox3fD#%)RB@e*5fm^WE&s$;_DM
z^Z+Dn#1xs?MwdDus?NJUx~><1*QPAhwvOfx+o^7*;l-^YX;IRqqz5@UUKW8(;D(n?
zP|{uC3$O}2$;I*F^B%jwB!ZHbByCB$;|+fVo&q~&_A>>?%M!2!1bM)@8%#BWZ-5ox
z6M&=_K>r%FlZa8t11fnv(qtQW3A~eZ27Ca9z&A6yO2i2A0H6027~v(E!E1@nz#od$
z>lt}k(<R8mYfYDAi;S6FQhbAuuQmNN;-zX)0L<)E(k^h4sWr<v1$KcGO0DUVR1m<-
zwo~78LTY(8g0b7Ku64w3yIR$0+Be%-w`%`G#snqZyX9xd$_ve4U(!NOXen=jN4ahu
z61)$*m-H|fw3InuolKHdzrlH6eHtX|7MUcHl9n4@no4qnH)$1}r)bw!2UbaI6ubVq
z`0uH%k}JTPKhWegF$Y91It}GQnWdfJm>f(NyaM*j>{kq_gWM1}0DeT)1?8Y#(8-M*
zLF&>%&b8<eIHWk=#iUXWss#tY{w>J4IJxhUb+vL3793E_T-0H;qudc0<RE-pIyAG3
z7?Pydz;obt;N!m&%8!949>w1kuPS(hk!PFs)5JfP(4GmkFEBy?0000<MNUMnLSTXb
CWhYSp
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/devtools/dark-theme.css
@@ -0,0 +1,98 @@
+/* vim:set ts=2 sw=2 sts=2 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/. */
+
+/* According to:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
+ */
+.theme-body {
+  background: #131c26;
+  color: #8fa1b2
+}
+
+.theme-twisty {
+  cursor: pointer;
+  width: 14px;
+  height: 14px;
+  background-repeat: no-repeat;
+  background-image: url("chrome://browser/skin/devtools/controls.png");
+  background-position: -28px -14px;
+}
+
+.theme-twisty:-moz-focusring {
+  outline-style: none;
+}
+
+.theme-twisty[open] {
+  background-position: -42px -14px;
+}
+
+.theme-checkbox {
+  display: inline-block;
+  border: 0;
+  width: 14px;
+  height: 14px;
+  padding: 0;
+  outline: none;
+  background-image: url("chrome://browser/skin/devtools/controls.png");
+  background-position: -28px 0;
+}
+
+.theme-checkbox[checked] {
+  background-position: -42px 0;
+}
+
+.theme-selected {
+  background: #26384E;
+}
+
+.theme-bg-darker {
+  background-color: rgba(0,0,0,0.1);
+}
+
+.theme-link { /* blue */
+  color: #3689b2;
+}
+
+.theme-comment { /* grey */
+  color: #5c6773;
+}
+
+.theme-gutter {
+  background-color: #0f171f;
+  color: #667380;
+  border-color: #303b47;
+}
+
+.theme-separator { /* grey */
+  border-color: #303b47;
+}
+
+.theme-fg-color1 { /* green */
+  color: #5c9966;
+}
+
+.theme-fg-color2 { /* blue */
+  color: #3689b2;
+}
+
+.theme-fg-color3 { /* pink/lavender */
+  color: #a673bf;
+}
+
+.theme-fg-color4 { /* purple/violet */
+  color: #6270b2;
+}
+
+.theme-fg-color5 { /* Yellow */
+  color: #a18650;
+}
+
+.theme-fg-color6 { /* Orange */
+  color: #b26b47;
+}
+
+.theme-fg-color7 { /* Red */
+  color: #bf5656;
+}
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/devtools/light-theme.css
@@ -0,0 +1,98 @@
+/* vim:set ts=2 sw=2 sts=2 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/. */
+
+/* According to:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
+ */
+.theme-body {
+  background: white;
+  color: black;
+}
+
+.theme-twisty {
+  cursor: pointer;
+  width: 14px;
+  height: 14px;
+  background-repeat: no-repeat;
+  background-image: url("chrome://browser/skin/devtools/controls.png");
+  background-position: 0 -14px;
+}
+
+.theme-twisty:-moz-focusring {
+  outline-style: none;
+}
+
+.theme-twisty[open] {
+  background-position: -14px -14px;
+}
+
+.theme-checkbox {
+  display: inline-block;
+  border: 0;
+  width: 14px;
+  height: 14px;
+  padding: 0;
+  outline: none;
+  background-image: url("chrome://browser/skin/devtools/controls.png");
+  background-position: 0 0;
+}
+
+.theme-checkbox[checked] {
+  background-position: -14px 0;
+}
+
+.theme-selected {
+  background-color: hsl(0,0%,90%);
+}
+
+.theme-bg-darker {
+  background: #F9F9F9;
+}
+
+.theme-link { /* blue */
+  color: hsl(208,56%,40%);
+}
+
+.theme-comment { /* grey */
+  color: hsl(90,2%,46%);
+}
+
+.theme-gutter {
+  background-color: hsl(0,0%,90%);
+  color: #667380;
+  border-color: hsl(0,0%,65%);
+}
+
+.theme-separator { /* grey */
+  border-color: #cddae5;
+}
+
+.theme-fg-color1 { /* green */
+  color: hsl(72,100%,27%);
+}
+
+.theme-fg-color2 { /* blue */
+  color: hsl(208,56%,40%);
+}
+
+.theme-fg-color3 { /* dark blue */
+  color: hsl(208,81%,21%)
+}
+
+.theme-fg-color4 { /* Orange */
+  color: hsl(24,85%,39%);
+}
+
+.theme-fg-color5 { /* Yellow */
+  color: #a18650;
+}
+
+.theme-fg-color6 { /* Orange */
+  color: hsl(24,85%,39%);
+}
+
+.theme-fg-color7 { /* Red */
+  color: #bf5656;
+}
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/devtools/markup-view.css
@@ -0,0 +1,48 @@
+/* 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/. */
+
+* {
+  padding: 0;
+  margin: 0;
+}
+
+.newattr {
+  cursor: pointer;
+}
+
+.selected {
+  background-color: hsl(0,0%,90%);
+}
+
+/* Give some padding to focusable elements to match the editor input
+ * that will replace them. */
+span[tabindex] {
+  display: inline-block;
+  padding: 1px 0;
+}
+
+li.container {
+  padding: 2px 0 0 2px;
+}
+
+.codebox {
+  padding-left: 14px;
+}
+
+.codebox > * {
+  vertical-align: middle;
+}
+
+.expander {
+  display: inline-block;
+  margin-left: -14px;
+}
+
+.more-nodes {
+  padding-left: 16px;
+}
+
+.styleinspector-propertyeditor {
+  border: 1px solid #CCC;
+}
deleted file mode 100644
index e937b600b7bca4a2dc614180af6dfc6a35a575d8..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 00d6d450c13ce88f9013d62efcabb6d04c597800..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/windows/devtools/computedview.css
+++ b/browser/themes/windows/devtools/computedview.css
@@ -100,20 +100,16 @@ body {
 }
 
 /* From skin */
 .expander {
   visibility: hidden;
   margin-left: -12px!important;
 }
 
-.expander[open] {
-  margin-left: -17px!important;
-}
-
 .expandable {
   visibility: visible;
 }
 
 .match {
   visibility: hidden;
 }
 
deleted file mode 100644
--- a/browser/themes/windows/devtools/dark-theme.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 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/. */
-
-/* According to:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
- */
-.theme-body {
-  background: #131c26;
-  color: #8fa1b2
-}
-
-.theme-twisty {
-  cursor: pointer;
-  margin-right: 5px;
-}
-
-.theme-twisty:-moz-focusring {
-  outline-style: none;
-}
-
-.theme-twisty:not([open]) {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 5px solid rgba(255,255,255,0.5);
-  margin-left: 5px;
-}
-
-.theme-twisty[open] {
-  width: 10px;
-  height: 10px;
-  background-image: linear-gradient(to bottom right, transparent 68%,  rgba(255,255,255,0.5) 68%);
-}
-
-.theme-checkbox {
-  display: inline-block;
-  border: 0;
-  width: 14px;
-  height: 14px;
-  padding: 0;
-  outline: none;
-  background: url("chrome://browser/skin/devtools/checkbox-dark.png") no-repeat;
-}
-
-.theme-checkbox[checked] {
-  background: url("chrome://browser/skin/devtools/checkbox-dark.png") 14px 0;
-}
-
-.theme-selected {
-  background: #26384E;
-}
-
-.theme-bg-darker {
-  background-color: rgba(0,0,0,0.1);
-}
-
-.theme-link { /* blue */
-  color: #3689b2;
-}
-
-.theme-comment { /* grey */
-  color: #5c6773;
-}
-
-.theme-gutter {
-  background-color: #0f171f;
-  color: #667380;
-  border-color: #303b47;
-}
-
-.theme-separator { /* grey */
-  border-color: #303b47;
-}
-
-.theme-fg-color1 { /* green */
-  color: #5c9966;
-}
-
-.theme-fg-color2 { /* blue */
-  color: #3689b2;
-}
-
-.theme-fg-color3 { /* pink/lavender */
-  color: #a673bf;
-}
-
-.theme-fg-color4 { /* purple/violet */
-  color: #6270b2;
-}
-
-.theme-fg-color5 { /* Yellow */
-  color: #a18650;
-}
-
-.theme-fg-color6 { /* Orange */
-  color: #b26b47;
-}
-
-.theme-fg-color7 { /* Red */
-  color: #bf5656;
-}
deleted file mode 100644
--- a/browser/themes/windows/devtools/light-theme.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 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/. */
-
-/* According to:
- * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
- */
-.theme-body {
-  background: white;
-  color: black;
-}
-
-.theme-twisty {
-  cursor: pointer;
-  margin-right: 5px;
-}
-
-.theme-twisty:-moz-focusring {
-  outline-style: none;
-}
-
-.theme-twisty:not([open]) {
-  width: 0;
-  height: 0;
-  border-top: 5px solid transparent;
-  border-bottom: 5px solid transparent;
-  border-left: 5px solid rgba(0,0,0,0.5);
-  margin-left: 5px;
-}
-
-.theme-twisty[open] {
-  width: 10px;
-  height: 10px;
-  background-image: linear-gradient(to bottom right, transparent 68%,  rgba(0,0,0,0.5) 68%);
-}
-
-.theme-checkbox {
-  display: inline-block;
-  border: 0;
-  width: 14px;
-  height: 14px;
-  padding: 0;
-  outline: none;
-  background: url("chrome://browser/skin/devtools/checkbox-light.png") no-repeat;
-}
-
-.theme-checkbox[checked] {
-  background: url("chrome://browser/skin/devtools/checkbox-light.png") 14px 0;
-}
-
-.theme-selected {
-  background-color: hsl(0,0%,90%);
-}
-
-.theme-bg-darker {
-  background: #F9F9F9;
-}
-
-.theme-link { /* blue */
-  color: hsl(208,56%,40%);
-}
-
-.theme-comment { /* grey */
-  color: hsl(90,2%,46%);
-}
-
-.theme-gutter {
-  background-color: hsl(0,0%,90%);
-  color: #667380;
-  border-color: hsl(0,0%,65%);
-}
-
-.theme-separator { /* grey */
-  border-color: #cddae5;
-}
-
-.theme-fg-color1 { /* green */
-  color: hsl(72,100%,27%);
-}
-
-.theme-fg-color2 { /* blue */
-  color: hsl(208,56%,40%);
-}
-
-.theme-fg-color3 { /* dark blue */
-  color: hsl(208,81%,21%)
-}
-
-.theme-fg-color4 { /* Orange */
-  color: hsl(24,85%,39%);
-}
-
-.theme-fg-color5 { /* Yellow */
-  color: #a18650;
-}
-
-.theme-fg-color6 { /* Orange */
-  color: hsl(24,85%,39%);
-}
-
-.theme-fg-color7 { /* Red */
-  color: #bf5656;
-}
deleted file mode 100644
--- a/browser/themes/windows/devtools/markup-view.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/* 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/. */
-
-* {
-  padding: 0;
-  margin: 0;
-}
-
-.newattr {
-  cursor: pointer;
-}
-
-.selected {
-  background-color: hsl(0,0%,90%);
-}
-
-/* Give some padding to focusable elements to match the editor input
- * that will replace them. */
-span[tabindex] {
-  display: inline-block;
-  padding: 1px 0;
-}
-
-li.container {
-  position: relative;
-  padding: 2px 0 0 2px;
-}
-
-.codebox {
-  padding-left: 14px;
-}
-
-.expander {
-  position: absolute;
-}
-
-.more-nodes {
-  padding-left: 16px;
-}
-
-.styleinspector-propertyeditor {
-  border: 1px solid #CCC;
-}
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -144,30 +144,29 @@ browser.jar:
         skin/classic/browser/tabview/edit-light.png                 (tabview/edit-light.png)
         skin/classic/browser/tabview/grain.png                      (tabview/grain.png)
         skin/classic/browser/tabview/search.png                     (tabview/search.png)
         skin/classic/browser/tabview/stack-expander.png             (tabview/stack-expander.png)
         skin/classic/browser/tabview/tabview.png                    (tabview/tabview.png)
         skin/classic/browser/tabview/tabview-inverted.png           (tabview/tabview-inverted.png)
         skin/classic/browser/tabview/tabview.css                    (tabview/tabview.css)
 *       skin/classic/browser/devtools/common.css                    (devtools/common.css)
-        skin/classic/browser/devtools/dark-theme.css                (devtools/dark-theme.css)
-        skin/classic/browser/devtools/light-theme.css               (devtools/light-theme.css)
+        skin/classic/browser/devtools/dark-theme.css                (../shared/devtools/dark-theme.css)
+        skin/classic/browser/devtools/light-theme.css               (../shared/devtools/light-theme.css)
+        skin/classic/browser/devtools/controls.png                  (../shared/devtools/controls.png)
         skin/classic/browser/devtools/widgets.css                   (devtools/widgets.css)
         skin/classic/browser/devtools/commandline-icon.png          (devtools/commandline-icon.png)
         skin/classic/browser/devtools/alerticon-warning.png         (devtools/alerticon-warning.png)
         skin/classic/browser/devtools/ruleview.css                  (devtools/ruleview.css)
         skin/classic/browser/devtools/commandline.css               (devtools/commandline.css)
         skin/classic/browser/devtools/command-paintflashing.png     (devtools/command-paintflashing.png)
         skin/classic/browser/devtools/command-responsivemode.png    (devtools/command-responsivemode.png)
         skin/classic/browser/devtools/command-scratchpad.png        (devtools/command-scratchpad.png)
         skin/classic/browser/devtools/command-tilt.png              (devtools/command-tilt.png)
-        skin/classic/browser/devtools/checkbox-dark.png             (devtools/checkbox-dark.png)
-        skin/classic/browser/devtools/checkbox-light.png            (devtools/checkbox-light.png)
-        skin/classic/browser/devtools/markup-view.css               (devtools/markup-view.css)
+        skin/classic/browser/devtools/markup-view.css               (../shared/devtools/markup-view.css)
         skin/classic/browser/devtools/orion.css                     (devtools/orion.css)
         skin/classic/browser/devtools/orion-container.css           (devtools/orion-container.css)
         skin/classic/browser/devtools/orion-task.png                (devtools/orion-task.png)
         skin/classic/browser/devtools/orion-breakpoint.png          (devtools/orion-breakpoint.png)
         skin/classic/browser/devtools/orion-debug-location.png      (devtools/orion-debug-location.png)
 *       skin/classic/browser/devtools/webconsole.css                  (devtools/webconsole.css)
         skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
         skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
@@ -399,30 +398,29 @@ browser.jar:
         skin/classic/aero/browser/tabview/edit-light.png             (tabview/edit-light.png)
         skin/classic/aero/browser/tabview/grain.png                  (tabview/grain.png)
         skin/classic/aero/browser/tabview/search.png                 (tabview/search.png)
         skin/classic/aero/browser/tabview/stack-expander.png         (tabview/stack-expander.png)
         skin/classic/aero/browser/tabview/tabview.png                (tabview/tabview.png)
         skin/classic/aero/browser/tabview/tabview-inverted.png       (tabview/tabview-inverted.png)
         skin/classic/aero/browser/tabview/tabview.css                (tabview/tabview.css)
 *       skin/classic/aero/browser/devtools/common.css                (devtools/common.css)
-        skin/classic/aero/browser/devtools/dark-theme.css            (devtools/dark-theme.css)
-        skin/classic/aero/browser/devtools/light-theme.css           (devtools/light-theme.css)
+        skin/classic/aero/browser/devtools/dark-theme.css            (../shared/devtools/dark-theme.css)
+        skin/classic/aero/browser/devtools/light-theme.css           (../shared/devtools/light-theme.css)
+        skin/classic/aero/browser/devtools/controls.png              (../shared/devtools/controls.png)
         skin/classic/aero/browser/devtools/widgets.css               (devtools/widgets.css)
         skin/classic/aero/browser/devtools/commandline-icon.png      (devtools/commandline-icon.png)
         skin/classic/aero/browser/devtools/command-paintflashing.png  (devtools/command-paintflashing.png)
         skin/classic/aero/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
         skin/classic/aero/browser/devtools/command-scratchpad.png    (devtools/command-scratchpad.png)
         skin/classic/aero/browser/devtools/command-tilt.png          (devtools/command-tilt.png)
-        skin/classic/aero/browser/devtools/checkbox-dark.png         (devtools/checkbox-dark.png)
-        skin/classic/aero/browser/devtools/checkbox-light.png        (devtools/checkbox-light.png)
         skin/classic/aero/browser/devtools/alerticon-warning.png     (devtools/alerticon-warning.png)
         skin/classic/aero/browser/devtools/ruleview.css              (devtools/ruleview.css)
         skin/classic/aero/browser/devtools/commandline.css           (devtools/commandline.css)
-        skin/classic/aero/browser/devtools/markup-view.css           (devtools/markup-view.css)
+        skin/classic/aero/browser/devtools/markup-view.css           (../shared/devtools/markup-view.css)
         skin/classic/aero/browser/devtools/orion.css                 (devtools/orion.css)
         skin/classic/aero/browser/devtools/orion-container.css       (devtools/orion-container.css)
         skin/classic/aero/browser/devtools/orion-task.png            (devtools/orion-task.png)
         skin/classic/aero/browser/devtools/orion-breakpoint.png      (devtools/orion-breakpoint.png)
         skin/classic/aero/browser/devtools/orion-debug-location.png  (devtools/orion-debug-location.png)
 *       skin/classic/aero/browser/devtools/webconsole.css                  (devtools/webconsole.css)
         skin/classic/aero/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
         skin/classic/aero/browser/devtools/webconsole.png                  (devtools/webconsole.png)
--- a/config/config.mk
+++ b/config/config.mk
@@ -352,22 +352,20 @@ MAKE_JARS_FLAGS = \
 ifdef USE_EXTENSION_MANIFEST
 MAKE_JARS_FLAGS += -e
 endif
 
 ifdef BOTH_MANIFESTS
 MAKE_JARS_FLAGS += --both-manifests
 endif
 
-TAR_CREATE_FLAGS = -cvhf
-TAR_CREATE_FLAGS_QUIET = -chf
+TAR_CREATE_FLAGS = -chf
 
 ifeq ($(OS_ARCH),OS2)
-TAR_CREATE_FLAGS = -cvf
-TAR_CREATE_FLAGS_QUIET = -cf
+TAR_CREATE_FLAGS = -cf
 endif
 
 #
 # Personal makefile customizations go in these optional make include files.
 #
 MY_CONFIG	:= $(DEPTH)/config/myconfig.mk
 MY_RULES	:= $(DEPTH)/config/myrules.mk
 
--- a/config/makefiles/makeutils.mk
+++ b/config/makefiles/makeutils.mk
@@ -113,9 +113,9 @@ ifdef USE_AUTOTARGETS_MK # mkdir_deps
   include $(topORerr)/config/makefiles/autotargets.mk
 endif
 
 ifdef USE_RCS_MK
   include $(topORerr)/config/makefiles/rcs.mk
 endif
 
 ## copy(src, dst): recursive copy
-copy_dir = (cd $(1)/. && $(TAR) $(TAR_CREATE_FLAGS_QUIET) - .) | (cd $(2)/. && tar -xf -)
+copy_dir = (cd $(1)/. && $(TAR) $(TAR_CREATE_FLAGS) - .) | (cd $(2)/. && tar -xf -)
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -27,16 +27,17 @@
 #include "nsTHashtable.h"                // for member
 #include "mozilla/dom/DocumentBinding.h"
 
 class imgIRequest;
 class nsAString;
 class nsBindingManager;
 class nsCSSStyleSheet;
 class nsDOMNavigationTiming;
+class nsDOMTouchList;
 class nsEventStates;
 class nsFrameLoader;
 class nsHTMLCSSStyleSheet;
 class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsIAtom;
 class nsIBFCacheEntry;
 class nsIBoxObject;
@@ -45,17 +46,16 @@ class nsIContent;
 class nsIContentSink;
 class nsIDocShell;
 class nsIDocumentObserver;
 class nsIDOMDocument;
 class nsIDOMDocumentFragment;
 class nsIDOMDocumentType;
 class nsIDOMElement;
 class nsIDOMNodeList;
-class nsIDOMTouchList;
 class nsIDOMXPathExpression;
 class nsIDOMXPathNSResolver;
 class nsILayoutHistoryState;
 class nsIObjectLoadingContent;
 class nsIObserver;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIRequest;
@@ -2094,21 +2094,21 @@ public:
              nsISupports* aResult, mozilla::ErrorResult& rv);
   // Touch event handlers already on nsINode
   already_AddRefed<mozilla::dom::Touch>
     CreateTouch(nsIDOMWindow* aView, mozilla::dom::EventTarget* aTarget,
                 int32_t aIdentifier, int32_t aPageX, int32_t aPageY,
                 int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
                 int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY,
                 float aRotationAngle, float aForce);
-  already_AddRefed<nsIDOMTouchList> CreateTouchList();
-  already_AddRefed<nsIDOMTouchList>
+  already_AddRefed<nsDOMTouchList> CreateTouchList();
+  already_AddRefed<nsDOMTouchList>
     CreateTouchList(mozilla::dom::Touch& aTouch,
                     const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<mozilla::dom::Touch> >& aTouches);
-  already_AddRefed<nsIDOMTouchList>
+  already_AddRefed<nsDOMTouchList>
     CreateTouchList(const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<mozilla::dom::Touch> >& aTouches);
 
   void SetStyleSheetChangeEventsEnabled(bool aValue)
   {
     mStyleSheetChangeEventsEnabled = aValue;
   }
 
   bool StyleSheetChangeEventsEnabled() const
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -146,17 +146,17 @@ public:
     if (htmlScript) {
       htmlScript->GetAsync(&async);
     }
     mForceAsync = !async;
   }
 
   void SetCreatorParser(nsIParser* aParser)
   {
-    mCreatorParser = getter_AddRefs(NS_GetWeakReference(aParser));
+    mCreatorParser = do_GetWeakReference(aParser);
   }
 
   /**
    * Unblocks the creator parser
    */
   void UnblockParser()
   {
     nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -9296,17 +9296,17 @@ nsIDocument::CreateTouch(nsIDOMWindow* a
                                     aForce);
   return touch.forget();
 }
 
 NS_IMETHODIMP
 nsDocument::CreateTouchList(nsIVariant* aPoints,
                             nsIDOMTouchList** aRetVal)
 {
-  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
+  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList(ToSupports(this));
   if (aPoints) {
     uint16_t type;
     aPoints->GetDataType(&type);
     if (type == nsIDataType::VTYPE_INTERFACE ||
         type == nsIDataType::VTYPE_INTERFACE_IS) {
       nsCOMPtr<nsISupports> data;
       aPoints->GetAsISupports(getter_AddRefs(data));
       nsCOMPtr<nsIDOMTouch> point = do_QueryInterface(data);
@@ -9333,39 +9333,39 @@ nsDocument::CreateTouchList(nsIVariant* 
       nsMemory::Free(rawArray);
     }
   }
 
   *aRetVal = retval.forget().get();
   return NS_OK;
 }
 
-already_AddRefed<nsIDOMTouchList>
+already_AddRefed<nsDOMTouchList>
 nsIDocument::CreateTouchList()
 {
-  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
+  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList(ToSupports(this));
   return retval.forget();
 }
 
-already_AddRefed<nsIDOMTouchList>
+already_AddRefed<nsDOMTouchList>
 nsIDocument::CreateTouchList(Touch& aTouch,
                              const Sequence<OwningNonNull<Touch> >& aTouches)
 {
-  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
+  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList(ToSupports(this));
   retval->Append(&aTouch);
   for (uint32_t i = 0; i < aTouches.Length(); ++i) {
     retval->Append(aTouches[i].get());
   }
   return retval.forget();
 }
 
-already_AddRefed<nsIDOMTouchList>
+already_AddRefed<nsDOMTouchList>
 nsIDocument::CreateTouchList(const Sequence<OwningNonNull<Touch> >& aTouches)
 {
-  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
+  nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList(ToSupports(this));
   for (uint32_t i = 0; i < aTouches.Length(); ++i) {
     retval->Append(aTouches[i].get());
   }
   return retval.forget();
 }
 
 already_AddRefed<nsDOMCaretPosition>
 nsIDocument::CaretPositionFromPoint(float aX, float aY)
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -3943,11 +3943,8 @@ CanvasRenderingContext2D::MarkContextCle
 bool
 CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager *aManager)
 {
   return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight));
 }
 
 }
 }
-
-DOMCI_DATA(CanvasRenderingContext2D, mozilla::dom::CanvasRenderingContext2D)
-
--- a/content/events/src/Touch.h
+++ b/content/events/src/Touch.h
@@ -8,16 +8,17 @@
 
 #include "nsIDOMTouchEvent.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/Attributes.h"
 #include "nsJSEnvironment.h"
 #include "nsWrapperCache.h"
 #include "mozilla/dom/EventTarget.h"
+#include "Units.h"
 
 namespace mozilla {
 namespace dom {
 
 class Touch MOZ_FINAL : public nsIDOMTouch
                       , public nsWrapperCache
 {
 public:
@@ -34,19 +35,19 @@ public:
         int32_t aRadiusX,
         int32_t aRadiusY,
         float aRotationAngle,
         float aForce)
     {
       SetIsDOMBinding();
       mTarget = aTarget;
       mIdentifier = aIdentifier;
-      mPagePoint = nsIntPoint(aPageX, aPageY);
+      mPagePoint = CSSIntPoint(aPageX, aPageY);
       mScreenPoint = nsIntPoint(aScreenX, aScreenY);
-      mClientPoint = nsIntPoint(aClientX, aClientY);
+      mClientPoint = CSSIntPoint(aClientX, aClientY);
       mRefPoint = nsIntPoint(0, 0);
       mPointsInitialized = true;
       mRadius.x = aRadiusX;
       mRadius.y = aRadiusY;
       mRotationAngle = aRotationAngle;
       mForce = aForce;
 
       mChanged = false;
@@ -56,19 +57,19 @@ public:
   Touch(int32_t aIdentifier,
         nsIntPoint aPoint,
         nsIntPoint aRadius,
         float aRotationAngle,
         float aForce)
     {
       SetIsDOMBinding();
       mIdentifier = aIdentifier;
-      mPagePoint = nsIntPoint(0, 0);
+      mPagePoint = CSSIntPoint(0, 0);
       mScreenPoint = nsIntPoint(0, 0);
-      mClientPoint = nsIntPoint(0, 0);
+      mClientPoint = CSSIntPoint(0, 0);
       mRefPoint = aPoint;
       mPointsInitialized = false;
       mRadius = aRadius;
       mRotationAngle = aRotationAngle;
       mForce = aForce;
 
       mChanged = false;
       mMessage = 0;
@@ -100,18 +101,18 @@ public:
   int32_t PageX() const { return mPagePoint.x; }
   int32_t PageY() const { return mPagePoint.y; }
   int32_t RadiusX() const { return mRadius.x; }
   int32_t RadiusY() const { return mRadius.y; }
   float RotationAngle() const { return mRotationAngle; }
   float Force() const { return mForce; }
 
   int32_t mIdentifier;
-  nsIntPoint mPagePoint;
-  nsIntPoint mClientPoint;
+  CSSIntPoint mPagePoint;
+  CSSIntPoint mClientPoint;
   nsIntPoint mScreenPoint;
   nsIntPoint mRadius;
   float mRotationAngle;
   float mForce;
 protected:
   bool mPointsInitialized;
 };
 
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -1086,75 +1086,75 @@ nsDOMEvent::GetScreenCoords(nsPresContex
 
   nsIntPoint offset = aPoint + guiEvent->widget->WidgetToScreenOffset();
   nscoord factor = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
   return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
                     nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
 }
 
 //static
-nsIntPoint
+CSSIntPoint
 nsDOMEvent::GetPageCoords(nsPresContext* aPresContext,
                           nsEvent* aEvent,
                           nsIntPoint aPoint,
-                          nsIntPoint aDefaultPoint)
+                          CSSIntPoint aDefaultPoint)
 {
-  nsIntPoint pagePoint = nsDOMEvent::GetClientCoords(aPresContext,
-                                                     aEvent,
-                                                     aPoint,
-                                                     aDefaultPoint);
+  CSSIntPoint pagePoint = nsDOMEvent::GetClientCoords(aPresContext,
+                                                      aEvent,
+                                                      aPoint,
+                                                      aDefaultPoint);
 
   // If there is some scrolling, add scroll info to client point.
   if (aPresContext && aPresContext->GetPresShell()) {
     nsIPresShell* shell = aPresContext->GetPresShell();
     nsIScrollableFrame* scrollframe = shell->GetRootScrollFrameAsScrollable();
     if (scrollframe) {
-      nsPoint pt = scrollframe->GetScrollPosition();
-      pagePoint += nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
-                              nsPresContext::AppUnitsToIntCSSPixels(pt.y));
+      pagePoint += CSSIntPoint::FromAppUnitsRounded(scrollframe->GetScrollPosition());
     }
   }
 
   return pagePoint;
 }
 
 // static
-nsIntPoint
+CSSIntPoint
 nsDOMEvent::GetClientCoords(nsPresContext* aPresContext,
                             nsEvent* aEvent,
                             nsIntPoint aPoint,
-                            nsIntPoint aDefaultPoint)
+                            CSSIntPoint aDefaultPoint)
 {
   if (nsEventStateManager::sIsPointerLocked) {
     return nsEventStateManager::sLastClientPoint;
   }
 
   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 ||
-      !((nsGUIEvent*)aEvent)->widget) {
+      !static_cast<nsGUIEvent*>(aEvent)->widget) {
     return aDefaultPoint;
   }
 
-  nsPoint pt(0, 0);
   nsIPresShell* shell = aPresContext->GetPresShell();
   if (!shell) {
-    return nsIntPoint(0, 0);
+    return CSSIntPoint(0, 0);
   }
+
   nsIFrame* rootFrame = shell->GetRootFrame();
-  if (rootFrame)
-    pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aPoint, rootFrame);
+  if (!rootFrame) {
+    return CSSIntPoint(0, 0);
+  }
+  nsPoint pt =
+    nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aPoint, rootFrame);
 
-  return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
-                    nsPresContext::AppUnitsToIntCSSPixels(pt.y));
+  return CSSIntPoint::FromAppUnitsRounded(pt);
 }
 
 // To be called ONLY by nsDOMEvent::GetType (which has the additional
 // logic for handling user-defined events).
 // static
 const char* nsDOMEvent::GetEventName(uint32_t aEventType)
 {
   switch(aEventType) {
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -14,16 +14,17 @@
 #include "nsPIDOMWindow.h"
 #include "nsPoint.h"
 #include "nsGUIEvent.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/EventBinding.h"
 #include "nsIScriptGlobalObject.h"
+#include "Units.h"
 
 class nsIContent;
 class nsPresContext;
 struct JSContext;
 class JSObject;
 
 // Dummy class so we can cast through it to get from nsISupports to
 // nsDOMEvent subclasses with only two non-ambiguous static casts.
@@ -94,24 +95,22 @@ public:
 
   static PopupControlState GetEventPopupControlState(nsEvent *aEvent);
 
   static void PopupAllowedEventsChanged();
 
   static void Shutdown();
 
   static const char* GetEventName(uint32_t aEventType);
-  static nsIntPoint GetClientCoords(nsPresContext* aPresContext,
-                                    nsEvent* aEvent,
-                                    nsIntPoint aPoint,
-                                    nsIntPoint aDefaultPoint);
-  static nsIntPoint GetPageCoords(nsPresContext* aPresContext,
-                                  nsEvent* aEvent,
-                                  nsIntPoint aPoint,
-                                  nsIntPoint aDefaultPoint);
+  static mozilla::CSSIntPoint
+  GetClientCoords(nsPresContext* aPresContext, nsEvent* aEvent,
+                  nsIntPoint aPoint, mozilla::CSSIntPoint aDefaultPoint);
+  static mozilla::CSSIntPoint
+  GetPageCoords(nsPresContext* aPresContext, nsEvent* aEvent, nsIntPoint aPoint,
+                mozilla::CSSIntPoint aDefaultPoint);
   static nsIntPoint GetScreenCoords(nsPresContext* aPresContext,
                                     nsEvent* aEvent,
                                     nsIntPoint aPoint);
 
   static already_AddRefed<nsDOMEvent> Constructor(const mozilla::dom::GlobalObject& aGlobal,
                                                   const nsAString& aType,
                                                   const mozilla::dom::EventInit& aParam,
                                                   mozilla::ErrorResult& aRv);
--- a/content/events/src/nsDOMNotifyPaintEvent.cpp
+++ b/content/events/src/nsDOMNotifyPaintEvent.cpp
@@ -87,17 +87,17 @@ nsDOMNotifyPaintEvent::ClientRects()
     rect->SetLayoutRect(*rgnRect);
     rectList->Append(rect);
   }
 
   return rectList.forget();
 }
 
 NS_IMETHODIMP
-nsDOMNotifyPaintEvent::GetPaintRequests(nsIDOMPaintRequestList** aResult)
+nsDOMNotifyPaintEvent::GetPaintRequests(nsISupports** aResult)
 {
   nsRefPtr<nsPaintRequestList> requests = PaintRequests();
   requests.forget(aResult);
   return NS_OK;
 }
 
 already_AddRefed<nsPaintRequestList>
 nsDOMNotifyPaintEvent::PaintRequests()
--- a/content/events/src/nsDOMTouchEvent.cpp
+++ b/content/events/src/nsDOMTouchEvent.cpp
@@ -5,68 +5,77 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMTouchEvent.h"
 #include "nsGUIEvent.h"
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsPresContext.h"
 #include "mozilla/dom/Touch.h"
+#include "mozilla/dom/TouchListBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // TouchList
-nsDOMTouchList::nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches)
-{
-  mPoints.AppendElements(aTouches);
-  nsJSContext::LikelyShortLivingObjectCreated();
-}
-
-DOMCI_DATA(TouchList, nsDOMTouchList)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouchList)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIDOMTouchList)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TouchList)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTION_1(nsDOMTouchList, mPoints)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsDOMTouchList, mParent, mPoints)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTouchList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTouchList)
 
+/* virtual */ JSObject*
+nsDOMTouchList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+{
+  return TouchListBinding::Wrap(aCx, aScope, this);
+}
+
+/* static */ bool
+nsDOMTouchList::PrefEnabled()
+{
+  return nsDOMTouchEvent::PrefEnabled();
+}
+
 NS_IMETHODIMP
 nsDOMTouchList::GetLength(uint32_t* aLength)
 {
-  *aLength = mPoints.Length();
+  *aLength = Length();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMTouchList::Item(uint32_t aIndex, nsIDOMTouch** aRetVal)
 {
-  NS_IF_ADDREF(*aRetVal = mPoints.SafeElementAt(aIndex, nullptr));
+  NS_IF_ADDREF(*aRetVal = Item(aIndex));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMTouchList::IdentifiedTouch(int32_t aIdentifier, nsIDOMTouch** aRetVal)
 {
-  *aRetVal = nullptr;
+  NS_IF_ADDREF(*aRetVal = IdentifiedTouch(aIdentifier));
+  return NS_OK;
+}
+
+Touch*
+nsDOMTouchList::IdentifiedTouch(int32_t aIdentifier) const
+{
   for (uint32_t i = 0; i < mPoints.Length(); ++i) {
-    nsCOMPtr<nsIDOMTouch> point = mPoints[i];
-    int32_t identifier;
-    if (point && NS_SUCCEEDED(point->GetIdentifier(&identifier)) &&
-        aIdentifier == identifier) {
-      point.swap(*aRetVal);
-      break;
+    Touch* point = mPoints[i];
+    if (point && point->Identifier() == aIdentifier) {
+      return point;
     }
   }
-  return NS_OK;
+  return nullptr;
 }
 
 // TouchEvent
 
 nsDOMTouchEvent::nsDOMTouchEvent(mozilla::dom::EventTarget* aOwner,
                                  nsPresContext* aPresContext,
                                  nsTouchEvent* aEvent)
   : nsDOMUIEvent(aOwner, aPresContext,
@@ -146,26 +155,26 @@ nsDOMTouchEvent::GetTouches(nsIDOMTouchL
 
 nsDOMTouchList*
 nsDOMTouchEvent::Touches()
 {
   if (!mTouches) {
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(mEvent);
     if (mEvent->message == NS_TOUCH_END || mEvent->message == NS_TOUCH_CANCEL) {
       // for touchend events, remove any changed touches from the touches array
-      nsTArray<nsCOMPtr<nsIDOMTouch> > unchangedTouches;
-      const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+      nsTArray< nsRefPtr<Touch> > unchangedTouches;
+      const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
       for (uint32_t i = 0; i < touches.Length(); ++i) {
         if (!touches[i]->mChanged) {
           unchangedTouches.AppendElement(touches[i]);
         }
       }
-      mTouches = new nsDOMTouchList(unchangedTouches);
+      mTouches = new nsDOMTouchList(ToSupports(this), unchangedTouches);
     } else {
-      mTouches = new nsDOMTouchList(touchEvent->touches);
+      mTouches = new nsDOMTouchList(ToSupports(this), touchEvent->touches);
     }
   }
   return mTouches;
 }
 
 NS_IMETHODIMP
 nsDOMTouchEvent::GetTargetTouches(nsIDOMTouchList** aTargetTouches)
 {
@@ -173,56 +182,55 @@ nsDOMTouchEvent::GetTargetTouches(nsIDOM
   NS_ADDREF(*aTargetTouches = TargetTouches());
   return NS_OK;
 }
 
 nsDOMTouchList*
 nsDOMTouchEvent::TargetTouches()
 {
   if (!mTargetTouches) {
-    nsTArray<nsCOMPtr<nsIDOMTouch> > targetTouches;
+    nsTArray< nsRefPtr<Touch> > targetTouches;
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(mEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       // for touchend/cancel events, don't append to the target list if this is a
       // touch that is ending
       if ((mEvent->message != NS_TOUCH_END &&
            mEvent->message != NS_TOUCH_CANCEL) || !touches[i]->mChanged) {
-        EventTarget* targetPtr = touches[i]->GetTarget();
-        if (targetPtr == mEvent->originalTarget) {
+        if (touches[i]->mTarget == mEvent->originalTarget) {
           targetTouches.AppendElement(touches[i]);
         }
       }
     }
-    mTargetTouches = new nsDOMTouchList(targetTouches);
+    mTargetTouches = new nsDOMTouchList(ToSupports(this), targetTouches);
   }
   return mTargetTouches;
 }
 
 NS_IMETHODIMP
 nsDOMTouchEvent::GetChangedTouches(nsIDOMTouchList** aChangedTouches)
 {
   NS_ENSURE_ARG_POINTER(aChangedTouches);
   NS_ADDREF(*aChangedTouches = ChangedTouches());
   return NS_OK;
 }
 
 nsDOMTouchList*
 nsDOMTouchEvent::ChangedTouches()
 {
   if (!mChangedTouches) {
-    nsTArray<nsCOMPtr<nsIDOMTouch> > changedTouches;
+    nsTArray< nsRefPtr<Touch> > changedTouches;
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(mEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       if (touches[i]->mChanged) {
         changedTouches.AppendElement(touches[i]);
       }
     }
-    mChangedTouches = new nsDOMTouchList(changedTouches);
+    mChangedTouches = new nsDOMTouchList(ToSupports(this), changedTouches);
   }
   return mChangedTouches;
 }
 
 NS_IMETHODIMP
 nsDOMTouchEvent::GetAltKey(bool* aAltKey)
 {
   *aAltKey = AltKey();
--- a/content/events/src/nsDOMTouchEvent.h
+++ b/content/events/src/nsDOMTouchEvent.h
@@ -7,42 +7,79 @@
 
 #include "nsDOMUIEvent.h"
 #include "nsIDOMTouchEvent.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/Attributes.h"
 #include "nsJSEnvironment.h"
 #include "mozilla/dom/TouchEventBinding.h"
+#include "nsWrapperCache.h"
 
 class nsDOMTouchList MOZ_FINAL : public nsIDOMTouchList
+                               , public nsWrapperCache
 {
+  typedef mozilla::dom::Touch Touch;
+
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouchList)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTouchList)
   NS_DECL_NSIDOMTOUCHLIST
 
-  nsDOMTouchList()
+  nsDOMTouchList(nsISupports* aParent)
+    : mParent(aParent)
   {
+    SetIsDOMBinding();
     nsJSContext::LikelyShortLivingObjectCreated();
   }
-  nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches);
+  nsDOMTouchList(nsISupports* aParent,
+                 const nsTArray< nsRefPtr<Touch> >& aTouches)
+    : mParent(aParent)
+    , mPoints(aTouches)
+  {
+    SetIsDOMBinding();
+    nsJSContext::LikelyShortLivingObjectCreated();
+  }
 
-  void Append(nsIDOMTouch* aPoint)
+  void Append(Touch* aPoint)
   {
     mPoints.AppendElement(aPoint);
   }
 
-  nsIDOMTouch* GetItemAt(uint32_t aIndex)
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  nsISupports* GetParentObject() const
   {
-    return mPoints.SafeElementAt(aIndex, nullptr);
+    return mParent;
   }
 
+  static bool PrefEnabled();
+
+  uint32_t Length() const
+  {
+    return mPoints.Length();
+  }
+  Touch* Item(uint32_t aIndex) const
+  {
+    return mPoints.SafeElementAt(aIndex);
+  }
+  Touch* IndexedGetter(uint32_t aIndex, bool& aFound) const
+  {
+    aFound = aIndex < mPoints.Length();
+    if (!aFound) {
+      return nullptr;
+    }
+    return mPoints[aIndex];
+  }
+  Touch* IdentifiedTouch(int32_t aIdentifier) const;
+
 protected:
-  nsTArray<nsCOMPtr<nsIDOMTouch> > mPoints;
+  nsCOMPtr<nsISupports> mParent;
+  nsTArray< nsRefPtr<Touch> > mPoints;
 };
 
 class nsDOMTouchEvent : public nsDOMUIEvent,
                         public nsIDOMTouchEvent
 {
 public:
   nsDOMTouchEvent(mozilla::dom::EventTarget* aOwner,
                   nsPresContext* aPresContext, nsTouchEvent* aEvent);
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -126,26 +126,16 @@ nsDOMUIEvent::GetMovementPoint()
   }
 
   // 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;
 }
 
-nsIntPoint
-nsDOMUIEvent::GetClientPoint()
-{
-  if (mIsPointerLocked) {
-    return mLastClientPoint;
-  }
-
-  return CalculateClientPoint(mPresContext, mEvent, &mClientPoint);
-}
-
 NS_IMETHODIMP
 nsDOMUIEvent::GetView(nsIDOMWindow** aView)
 {
   *aView = mView;
   NS_IF_ADDREF(*aView);
   return NS_OK;
 }
 
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -7,20 +7,22 @@
 #define nsDOMUIEvent_h
 
 #include "mozilla/Attributes.h"
 #include "nsIDOMUIEvent.h"
 #include "nsDOMEvent.h"
 #include "nsLayoutUtils.h"
 #include "nsEvent.h"
 #include "mozilla/dom/UIEventBinding.h"
+#include "Units.h"
 
 class nsDOMUIEvent : public nsDOMEvent,
                      public nsIDOMUIEvent
 {
+  typedef mozilla::CSSIntPoint CSSIntPoint;
 public:
   nsDOMUIEvent(mozilla::dom::EventTarget* aOwner,
                nsPresContext* aPresContext, nsGUIEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMUIEvent, nsDOMEvent)
 
   // nsIDOMUIEvent Interface
@@ -50,44 +52,45 @@ public:
 
     nsIntPoint offset = aEvent->refPoint +
                         ((nsGUIEvent*)aEvent)->widget->WidgetToScreenOffset();
     nscoord factor = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
     return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
                       nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
   }
 
-  static nsIntPoint CalculateClientPoint(nsPresContext* aPresContext,
-                                         nsEvent* aEvent,
-                                         nsIntPoint* aDefaultClientPoint)
+  static CSSIntPoint CalculateClientPoint(nsPresContext* aPresContext,
+                                          nsEvent* aEvent,
+                                          CSSIntPoint* aDefaultClientPoint)
   {
     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 ||
-        !((nsGUIEvent*)aEvent)->widget) {
-      return (nullptr == aDefaultClientPoint ? nsIntPoint(0, 0) :
-        nsIntPoint(aDefaultClientPoint->x, aDefaultClientPoint->y));
+        !static_cast<nsGUIEvent*>(aEvent)->widget) {
+      return aDefaultClientPoint
+             ? *aDefaultClientPoint
+             : CSSIntPoint(0, 0);
     }
 
-    nsPoint pt(0, 0);
     nsIPresShell* shell = aPresContext->GetPresShell();
     if (!shell) {
-      return nsIntPoint(0, 0);
+      return CSSIntPoint(0, 0);
     }
     nsIFrame* rootFrame = shell->GetRootFrame();
-    if (rootFrame) {
-      pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
+    if (!rootFrame) {
+      return CSSIntPoint(0, 0);
     }
+    nsPoint pt =
+      nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
 
-    return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
-                      nsPresContext::AppUnitsToIntCSSPixels(pt.y));
+    return CSSIntPoint::FromAppUnitsRounded(pt);
   }
 
   static already_AddRefed<nsDOMUIEvent> Constructor(const mozilla::dom::GlobalObject& aGlobal,
                                                     const nsAString& aType,
                                                     const mozilla::dom::UIEventInit& aParam,
                                                     mozilla::ErrorResult& aRv);
 
   virtual JSObject* WrapObject(JSContext* aCx,
@@ -136,29 +139,28 @@ public:
   {
     return mEvent->mFlags.mPropagationStopped;
   }
 
   bool IsChar() const;
 
 protected:
   // Internal helper functions
-  nsIntPoint GetClientPoint();
   nsIntPoint GetMovementPoint();
   nsIntPoint GetLayerPoint() const;
 
   nsCOMPtr<nsIDOMWindow> mView;
   int32_t mDetail;
-  nsIntPoint mClientPoint;
+  CSSIntPoint mClientPoint;
   // Screenpoint is mEvent->refPoint.
   nsIntPoint mLayerPoint;
-  nsIntPoint mPagePoint;
+  CSSIntPoint mPagePoint;
   nsIntPoint mMovementPoint;
   bool mIsPointerLocked;
-  nsIntPoint mLastClientPoint;
+  CSSIntPoint mLastClientPoint;
 
   typedef mozilla::widget::Modifiers Modifiers;
   static Modifiers ComputeModifierState(const nsAString& aModifiersList);
   bool GetModifierStateInternal(const nsAString& aKey);
 };
 
 #define NS_FORWARD_TO_NSDOMUIEVENT                          \
   NS_FORWARD_NSIDOMUIEVENT(nsDOMUIEvent::)                  \
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -117,17 +117,17 @@ static int32_t sChromeAccessModifier = 0
 int32_t nsEventStateManager::sUserInputEventDepth = 0;
 bool nsEventStateManager::sNormalLMouseEventInProcess = false;
 nsEventStateManager* nsEventStateManager::sActiveESM = nullptr;
 nsIDocument* nsEventStateManager::sMouseOverDocument = nullptr;
 nsWeakFrame nsEventStateManager::sLastDragOverFrame = nullptr;
 nsIntPoint nsEventStateManager::sLastRefPoint = kInvalidRefPoint;
 nsIntPoint nsEventStateManager::sLastScreenPoint = nsIntPoint(0,0);
 nsIntPoint nsEventStateManager::sSynthCenteringPoint = kInvalidRefPoint;
-nsIntPoint nsEventStateManager::sLastClientPoint = nsIntPoint(0,0);
+CSSIntPoint nsEventStateManager::sLastClientPoint = CSSIntPoint(0, 0);
 bool nsEventStateManager::sIsPointerLocked = false;
 // Reference to the pointer locked element.
 nsWeakPtr nsEventStateManager::sPointerLockedElement;
 // Reference to the document which requested pointer lock.
 nsWeakPtr nsEventStateManager::sPointerLockedDoc;
 nsCOMPtr<nsIContent> nsEventStateManager::sDragOverContent = nullptr;
 
 static uint32_t gMouseOrKeyboardEventCounter = 0;
@@ -1548,17 +1548,17 @@ nsEventStateManager::MapEventCoordinates
 {
   if (aEvent->eventStructType != NS_TOUCH_EVENT) {
     aEvent->refPoint = aOffset;
   } else {
     aEvent->refPoint = nsIntPoint();
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
     // Then offset all the touch points by that distance, to put them
     // in the space where top-left is 0,0.
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       nsIDOMTouch* touch = touches[i];
       if (touch) {
         touch->mRefPoint += aOffset;
       }
     }
   }
 }
@@ -1632,17 +1632,17 @@ nsEventStateManager::HandleCrossProcessE
     // This is a touch event with possibly multiple touch points.
     // Each touch point may have its own target.  So iterate through
     // all of them and collect the unique set of targets for event
     // forwarding.
     //
     // This loop is similar to the one used in
     // PresShell::DispatchTouchEvent().
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       nsIDOMTouch* touch = touches[i];
       // NB: the |mChanged| check is an optimization, subprocesses can
       // compute this for themselves.  If the touch hasn't changed, we
       // may be able to avoid forwarding the event entirely (which is
       // not free).
       if (!touch || !touch->mChanged) {
         continue;
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -18,16 +18,17 @@
 #include "nsIFrameLoader.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIScrollableFrame.h"
 #include "nsFocusManager.h"
 #include "nsEventStates.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIFrame.h"
+#include "Units.h"
 
 class nsIPresShell;
 class nsIContent;
 class nsIDocument;
 class nsIDocShell;
 class nsIDocShellTreeNode;
 class nsIDocShellTreeItem;
 class imgIContainer;
@@ -207,17 +208,17 @@ public:
   // locked. This is used by nsDOMEvent::GetScreenCoords() to make mouse
   // events' screen coord appear frozen at the last mouse position while
   // the pointer is locked.
   static nsIntPoint sLastScreenPoint;
 
   // Holds the point in client coords of the last mouse event. Used by
   // nsDOMEvent::GetClientCoords() to make mouse events' client coords appear
   // frozen at the last mouse position while the pointer is locked.
-  static nsIntPoint sLastClientPoint;
+  static mozilla::CSSIntPoint sLastClientPoint;
 
   static bool sIsPointerLocked;
   static nsWeakPtr sPointerLockedElement;
   static nsWeakPtr sPointerLockedDoc;
 
 protected:
   friend class MouseEnterLeaveDispatcher;
 
--- a/content/events/src/nsPaintRequest.cpp
+++ b/content/events/src/nsPaintRequest.cpp
@@ -50,36 +50,21 @@ NS_IMETHODIMP
 nsPaintRequest::GetXPCOMReason(nsAString& aResult)
 {
   GetReason(aResult);
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsPaintRequestList, mParent)
 
-NS_INTERFACE_TABLE_HEAD(nsPaintRequestList)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPaintRequestList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_TABLE1(nsPaintRequestList, nsIDOMPaintRequestList)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsPaintRequestList)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPaintRequestList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPaintRequestList)
 
 JSObject*
-nsPaintRequestList::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope)
-{
-  return mozilla::dom::PaintRequestListBinding::Wrap(cx, scope, this);
-}
-
-NS_IMETHODIMP    
-nsPaintRequestList::GetLength(uint32_t* aLength)
+nsPaintRequestList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
-  *aLength = Length();
-  return NS_OK;
+  return PaintRequestListBinding::Wrap(aCx, aScope, this);
 }
-
-NS_IMETHODIMP    
-nsPaintRequestList::Item(uint32_t aIndex, nsIDOMPaintRequest** aReturn)
-{
-  NS_IF_ADDREF(*aReturn = Item(aIndex));
-  return NS_OK;
-}
--- a/content/events/src/nsPaintRequest.h
+++ b/content/events/src/nsPaintRequest.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NSPAINTREQUEST_H_
 #define NSPAINTREQUEST_H_
 
 #include "nsIDOMPaintRequest.h"
-#include "nsIDOMPaintRequestList.h"
 #include "nsPresContext.h"
 #include "nsIDOMEvent.h"
 #include "mozilla/Attributes.h"
 #include "nsClientRect.h"
 #include "nsWrapperCache.h"
 
 class nsPaintRequest MOZ_FINAL : public nsIDOMPaintRequest
                                , public nsWrapperCache
@@ -48,58 +47,40 @@ public:
 
 private:
   ~nsPaintRequest() {}
 
   nsCOMPtr<nsIDOMEvent> mParent;
   nsInvalidateRequestList::Request mRequest;
 };
 
-class nsPaintRequestList MOZ_FINAL : public nsIDOMPaintRequestList,
+class nsPaintRequestList MOZ_FINAL : public nsISupports,
                                      public nsWrapperCache
 {
 public:
   nsPaintRequestList(nsIDOMEvent *aParent) : mParent(aParent)
   {
     SetIsDOMBinding();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPaintRequestList)
-  NS_DECL_NSIDOMPAINTREQUESTLIST
   
-  virtual JSObject* WrapObject(JSContext *cx,
-                               JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(nsPaintRequest* aElement)
   {
     mArray.AppendElement(aElement);
   }
 
-  static nsPaintRequestList* FromSupports(nsISupports* aSupports)
-  {
-#ifdef DEBUG
-    {
-      nsCOMPtr<nsIDOMPaintRequestList> list_qi = do_QueryInterface(aSupports);
-
-      // If this assertion fires the QI implementation for the object in
-      // question doesn't use the nsIDOMClientRectList pointer as the nsISupports
-      // pointer. That must be fixed, or we'll crash...
-      NS_ASSERTION(list_qi == static_cast<nsIDOMPaintRequestList*>(aSupports),
-                   "Uh, fix QI!");
-    }
-#endif
-
-    return static_cast<nsPaintRequestList*>(aSupports);
-  }
-
   uint32_t Length()
   {
     return mArray.Length();
   }
 
   nsPaintRequest* Item(uint32_t aIndex)
   {
     return mArray.SafeElementAt(aIndex);
--- a/content/html/content/src/HTMLAnchorElement.cpp
+++ b/content/html/content/src/HTMLAnchorElement.cpp
@@ -1,26 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLAnchorElement.h"
 
+#include "mozilla/dom/HTMLAnchorElementBinding.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/dom/HTMLAnchorElementBinding.h"
-
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
-#include "nsIPresShell.h"
+#include "nsHTMLDNSPrefetch.h"
 #include "nsIDocument.h"
+#include "nsIPresShell.h"
 #include "nsPresContext.h"
-#include "nsHTMLDNSPrefetch.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
 
 namespace mozilla {
 namespace dom {
 
 #define ANCHOR_ELEMENT_FLAG_BIT(n_) NODE_FLAG_BIT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
 
--- a/content/html/content/src/HTMLAnchorElement.h
+++ b/content/html/content/src/HTMLAnchorElement.h
@@ -3,37 +3,36 @@
 /* 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_HTMLAnchorElement_h
 #define mozilla_dom_HTMLAnchorElement_h
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/Link.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsILink.h"
-#include "Link.h"
-#include "base/compiler_specific.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLAnchorElement : public nsGenericHTMLElement,
                           public nsIDOMHTMLAnchorElement,
                           public nsILink,
                           public Link
 {
 public:
   using Element::GetText;
   using Element::SetText;
 
   HTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
-    , ALLOW_THIS_IN_INITIALIZER_LIST(Link(this))
+    , Link(MOZ_THIS_IN_INITIALIZER_LIST())
   {
     SetIsDOMBinding();
   }
   virtual ~HTMLAnchorElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
--- a/content/html/content/src/HTMLAreaElement.cpp
+++ b/content/html/content/src/HTMLAreaElement.cpp
@@ -1,28 +1,28 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLAreaElement.h"
 
-#include "mozilla/MemoryReporting.h"
+#include "mozilla/Attributes.h"
 #include "mozilla/dom/HTMLAreaElementBinding.h"
-#include "base/compiler_specific.h"
+#include "mozilla/MemoryReporting.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Area)
 
 namespace mozilla {
 namespace dom {
 
 HTMLAreaElement::HTMLAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
-    ALLOW_THIS_IN_INITIALIZER_LIST(Link(this))
+  : nsGenericHTMLElement(aNodeInfo)
+  , Link(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   SetIsDOMBinding();
 }
 
 HTMLAreaElement::~HTMLAreaElement()
 {
 }
 
--- a/content/html/content/src/HTMLAreaElement.h
+++ b/content/html/content/src/HTMLAreaElement.h
@@ -3,22 +3,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_HTMLAreaElement_h
 #define mozilla_dom_HTMLAreaElement_h
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/Link.h"
+#include "nsGenericHTMLElement.h"
+#include "nsGkAtoms.h"
 #include "nsIDOMHTMLAreaElement.h"
-#include "nsGenericHTMLElement.h"
 #include "nsILink.h"
-#include "nsGkAtoms.h"
 #include "nsIURL.h"
-#include "Link.h"
 
 class nsIDocument;
 
 namespace mozilla {
 namespace dom {
 
 class HTMLAreaElement : public nsGenericHTMLElement,
                         public nsIDOMHTMLAreaElement,
--- a/content/html/content/src/HTMLLinkElement.cpp
+++ b/content/html/content/src/HTMLLinkElement.cpp
@@ -1,43 +1,43 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLLinkElement.h"
 
-#include "mozilla/MemoryReporting.h"
+#include "mozilla/Attributes.h"
 #include "mozilla/dom/HTMLLinkElementBinding.h"
-#include "base/compiler_specific.h"
+#include "mozilla/MemoryReporting.h"
+#include "nsAsyncDOMEvent.h"
+#include "nsContentUtils.h"
 #include "nsGenericHTMLElement.h"
+#include "nsGkAtoms.h"
+#include "nsIDocument.h"
+#include "nsIDOMEvent.h"
+#include "nsIDOMStyleSheet.h"
 #include "nsILink.h"
-#include "nsGkAtoms.h"
-#include "nsStyleConsts.h"
-#include "nsIDOMStyleSheet.h"
 #include "nsIStyleSheet.h"
 #include "nsIStyleSheetLinkingElement.h"
-#include "nsReadableUtils.h"
-#include "nsUnicharUtils.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
-#include "nsIDocument.h"
-#include "nsIDOMEvent.h"
-#include "nsContentUtils.h"
 #include "nsPIDOMWindow.h"
-#include "nsAsyncDOMEvent.h"
+#include "nsReadableUtils.h"
+#include "nsStyleConsts.h"
+#include "nsUnicharUtils.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
 
 namespace mozilla {
 namespace dom {
 
 HTMLLinkElement::HTMLLinkElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsGenericHTMLElement(aNodeInfo),
-    ALLOW_THIS_IN_INITIALIZER_LIST(Link(this))
+  : nsGenericHTMLElement(aNodeInfo)
+  , Link(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   SetIsDOMBinding();
 }
 
 HTMLLinkElement::~HTMLLinkElement()
 {
 }
 
--- a/content/html/content/src/HTMLLinkElement.h
+++ b/content/html/content/src/HTMLLinkElement.h
@@ -2,21 +2,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_HTMLLinkElement_h
 #define mozilla_dom_HTMLLinkElement_h
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/Link.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsILink.h"
 #include "nsStyleLinkElement.h"
-#include "mozilla/dom/Link.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLLinkElement : public nsGenericHTMLElement,
                         public nsIDOMHTMLLinkElement,
                         public nsILink,
                         public nsStyleLinkElement,
--- a/content/html/content/src/HTMLOptionsCollection.cpp
+++ b/content/html/content/src/HTMLOptionsCollection.cpp
@@ -28,18 +28,16 @@
 #include "nsIFrame.h"
 #include "nsIListControlFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsMappedAttributes.h"
 #include "nsRuleData.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleConsts.h"
 
-DOMCI_DATA(HTMLOptionsCollection, mozilla::dom::HTMLOptionsCollection)
-
 namespace mozilla {
 namespace dom {
 
 HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement* aSelect)
 {
   SetIsDOMBinding();
 
   // Do not maintain a reference counted reference. When
--- a/content/html/content/src/HTMLSelectElement.cpp
+++ b/content/html/content/src/HTMLSelectElement.cpp
@@ -1,22 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLSelectElement.h"
 
 #include "mozAutoDocUpdate.h"
+#include "mozilla/Attributes.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLOptGroupElement.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLSelectElementBinding.h"
 #include "mozilla/Util.h"
-#include "base/compiler_specific.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsError.h"
 #include "nsEventDispatcher.h"
 #include "nsEventStates.h"
 #include "nsFormSubmission.h"
 #include "nsGkAtoms.h"
 #include "nsGUIEvent.h"
 #include "nsIComboboxControlFrame.h"
@@ -99,17 +99,17 @@ SafeOptionListMutation::~SafeOptionListM
 //
 
 // construction, destruction
 
 
 HTMLSelectElement::HTMLSelectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                                      FromParser aFromParser)
   : nsGenericHTMLFormElement(aNodeInfo),
-    ALLOW_THIS_IN_INITIALIZER_LIST(mOptions(new HTMLOptionsCollection(this))),
+    mOptions(new HTMLOptionsCollection(MOZ_THIS_IN_INITIALIZER_LIST())),
     mIsDoneAddingChildren(!aFromParser),
     mDisabledChanged(false),
     mMutating(false),
     mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
     mSelectionHasChanged(false),
     mDefaultSelectionSet(false),
     mCanShowInvalidUI(true),
     mCanShowValidUI(true),
--- a/content/html/content/src/HTMLTableElement.cpp
+++ b/content/html/content/src/HTMLTableElement.cpp
@@ -707,16 +707,45 @@ HTMLTableElement::DeleteCaption()
     nsINode::RemoveChild(*caption, rv);
     MOZ_ASSERT(!rv.Failed());
   }
 
   return NS_OK;
 }
 
 already_AddRefed<nsGenericHTMLElement>
+HTMLTableElement::CreateTBody()
+{
+  nsCOMPtr<nsINodeInfo> nodeInfo =
+    OwnerDoc()->NodeInfoManager()->GetNodeInfo(nsGkAtoms::tbody, nullptr,
+                                               kNameSpaceID_XHTML,
+                                               nsIDOMNode::ELEMENT_NODE);
+  MOZ_ASSERT(nodeInfo);
+
+  nsCOMPtr<nsGenericHTMLElement> newBody =
+    NS_NewHTMLTableSectionElement(nodeInfo.forget());
+  MOZ_ASSERT(newBody);
+
+  nsIContent* referenceNode = nullptr;
+  for (nsIContent* child = nsINode::GetLastChild();
+       child;
+       child = child->GetPreviousSibling()) {
+    if (child->IsHTML(nsGkAtoms::tbody)) {
+      referenceNode = child->GetNextSibling();
+      break;
+    }
+  }
+
+  ErrorResult rv;
+  nsINode::InsertBefore(*newBody, referenceNode, rv);
+
+  return newBody.forget();
+}
+
+already_AddRefed<nsGenericHTMLElement>
 HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 {
   /* get the ref row at aIndex
      if there is one, 
        get its parent
        insert the new row just before the ref row
      else
        get the first row group
--- a/content/html/content/src/HTMLTableElement.h
+++ b/content/html/content/src/HTMLTableElement.h
@@ -88,16 +88,19 @@ public:
     DeleteTFoot();
     if (aTFoot) {
       nsINode::AppendChild(*aTFoot, aError);
     }
   }
   already_AddRefed<nsGenericHTMLElement> CreateTFoot();
 
   nsIHTMLCollection* TBodies();
+
+  already_AddRefed<nsGenericHTMLElement> CreateTBody();
+
   nsIHTMLCollection* Rows();
 
   already_AddRefed<nsGenericHTMLElement> InsertRow(int32_t aIndex,
                                                    ErrorResult& aError);
   void DeleteRow(int32_t aIndex, ErrorResult& aError);
 
   void GetAlign(nsString& aAlign)
   {
--- a/content/html/content/src/HTMLTextAreaElement.cpp
+++ b/content/html/content/src/HTMLTextAreaElement.cpp
@@ -1,48 +1,47 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLTextAreaElement.h"
+
+#include "mozAutoDocUpdate.h"
+#include "mozilla/Attributes.h"
 #include "mozilla/dom/HTMLTextAreaElementBinding.h"
 #include "mozilla/Util.h"
-#include "base/compiler_specific.h"
-
-#include "nsIControllers.h"
+#include "nsAttrValueInlines.h"
+#include "nsContentCID.h"
+#include "nsContentCreatorFunctions.h"
+#include "nsError.h"
+#include "nsEventDispatcher.h"
 #include "nsFocusManager.h"
-#include "nsPIDOMWindow.h"
-#include "nsContentCID.h"
+#include "nsFormSubmission.h"
+#include "nsGUIEvent.h"
 #include "nsIComponentManager.h"
+#include "nsIConstraintValidation.h"
+#include "nsIControllers.h"
+#include "nsIDocument.h"
 #include "nsIDOMHTMLFormElement.h"
+#include "nsIFormControlFrame.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
-#include "nsFormSubmission.h"
-#include "nsAttrValueInlines.h"
-#include "nsStyleConsts.h"
-#include "nsPresContext.h"
+#include "nsIFrame.h"
+#include "nsISupportsPrimitives.h"
+#include "nsITextControlFrame.h"
+#include "nsLayoutUtils.h"
+#include "nsLinebreakConverter.h"
 #include "nsMappedAttributes.h"
-#include "nsIFormControlFrame.h"
-#include "nsITextControlFrame.h"
-#include "nsLinebreakConverter.h"
-#include "nsIDocument.h"
-#include "nsIFrame.h"
-#include "nsGUIEvent.h"
+#include "nsPIDOMWindow.h"
+#include "nsPresContext.h"
 #include "nsPresState.h"
 #include "nsReadableUtils.h"
-#include "nsEventDispatcher.h"
-#include "nsLayoutUtils.h"
-#include "nsError.h"
-#include "mozAutoDocUpdate.h"
-#include "nsISupportsPrimitives.h"
-#include "nsContentCreatorFunctions.h"
-#include "nsIConstraintValidation.h"
-
+#include "nsStyleConsts.h"
 #include "nsTextEditorState.h"
 
 static NS_DEFINE_CID(kXULControllersCID,  NS_XULCONTROLLERS_CID);
 
 #define NS_NO_CONTENT_DISPATCH (1 << 0)
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea)
 
@@ -54,17 +53,17 @@ HTMLTextAreaElement::HTMLTextAreaElement
   : nsGenericHTMLFormElement(aNodeInfo),
     mValueChanged(false),
     mHandlingSelect(false),
     mDoneAddingChildren(!aFromParser),
     mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
     mDisabledChanged(false),
     mCanShowInvalidUI(true),
     mCanShowValidUI(true),
-    ALLOW_THIS_IN_INITIALIZER_LIST(mState(this))
+    mState(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   AddMutationObserver(this);
 
   // Set up our default state.  By default we're enabled (since we're
   // a control type that can be disabled but not actually disabled
   // right now), optional, and valid.  We are NOT readwrite by default
   // until someone calls UpdateEditableState on us, apparently!  Also
   // by default we don't have to show validity UI and so forth.
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1067,30 +1067,30 @@ nsHTMLDocument::SetDomain(const nsAStrin
   }
 
   rv = NodePrincipal()->SetDomain(newURI);
 }
 
 nsGenericHTMLElement*
 nsHTMLDocument::GetBody()
 {
-  Element* body = GetBodyElement();
-
-  if (body) {
-    // There is a body element, return that as the body.
-    return static_cast<nsGenericHTMLElement*>(body);
+  Element* html = GetHtmlElement();
+  if (!html) {
+    return nullptr;
   }
 
-  // The document is most likely a frameset document so look for the
-  // outer most frameset element
-  nsRefPtr<nsContentList> nodeList =
-    NS_GetContentList(this, kNameSpaceID_XHTML, NS_LITERAL_STRING("frameset"));
-  Element* frameset = nodeList->GetElementAt(0);
-  MOZ_ASSERT(!frameset || frameset->IsHTML());
-  return static_cast<nsGenericHTMLElement*>(frameset);
+  for (nsIContent* child = html->GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    if (child->IsHTML(nsGkAtoms::body) || child->IsHTML(nsGkAtoms::frameset)) {
+      return static_cast<nsGenericHTMLElement*>(child);
+    }
+  }
+
+  return nullptr;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
 {
   *aBody = nullptr;
 
   nsIContent *body = GetBody();
--- a/content/html/document/test/Makefile.in
+++ b/content/html/document/test/Makefile.in
@@ -63,17 +63,16 @@ MOCHITEST_FILES = 	test_bug1682.html \
 		test_bug482659.html \
 		test_bug486741.html \
 		test_bug489532.html \
 		test_bug497242.xhtml \
 		test_bug499092.html \
 		bug499092.xml \
 		bug499092.html \
 		test_bug512367.html \
-		test_bug571981.html \
 		test_bug677495.html \
 		test_bug677495-1.html \
 		test_bug741266.html \
 		test_non-ascii-cookie.html \
 		test_non-ascii-cookie.html^headers^ \
 		test_bug765780.html \
 		$(NULL)
 
deleted file mode 100644
--- a/content/html/document/test/test_bug571981.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=571981
--->
-<head>
-  <title>Test for Bug 571981</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=571981">Mozilla Bug 571981</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-  <iframe id="testframe"></iframe>
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 571981 **/
-
-SimpleTest.waitForExplicitFinish();
-addLoadEvent(function() {
-  var doc = document.getElementById("testframe").contentDocument;
-  var elem = doc.documentElement;
-  ok(elem.nodeName == "HTML" &&
-     elem.namespaceURI == "http://www.w3.org/1999/xhtml",
-     "documentElement should be an html element with nodename 'HTML'");
-  var childNodes = elem.childNodes;
-  elem = null;
-  for (var i = 0; i < childNodes.length; ++i) {
-    if (childNodes[i].nodeName == "BODY" &&
-        childNodes[i].namespaceURI == "http://www.w3.org/1999/xhtml") {
-      elem = childNodes[i];
-    }
-  }
-  ok(elem && doc.body == elem,
-     "HTMLDocument.body should be an html element with nodeName 'BODY' " +
-     "and a child of the documentElement");
-  doc.removeChild(doc.documentElement);
-  elem = doc.appendChild(doc.createElementNS("http://www.w3.org/1999/xhtml",
-                                             "frameset"));
-  var framesets = doc.getElementsByTagNameNS("http://www.w3.org/1999/xhtml",
-                                             "frameset");
-  ok(doc.body && doc.body == framesets[0],
-     "HTMLDocument.body should be the first html element in the document " +
-     "with nodename 'frameset'");
-  doc.removeChild(doc.documentElement);
-  doc.appendChild(doc.createElementNS('wrongnamespace', 'frameset'));
-  is(doc.body, null,
-     "HTMLDocument.body should not return non-html elements");
-  SimpleTest.finish();
-});
-
-</script>
-</pre>
-</body>
-</html>
--- a/content/svg/content/src/SVGAElement.cpp
+++ b/content/svg/content/src/SVGAElement.cpp
@@ -1,21 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SVGAElement.h"
-#include "base/compiler_specific.h"
+
+#include "mozilla/Attributes.h"
 #include "mozilla/dom/SVGAElementBinding.h"
+#include "nsCOMPtr.h"
+#include "nsContentUtils.h"
+#include "nsGkAtoms.h"
 #include "nsILink.h"
 #include "nsSVGString.h"
-#include "nsCOMPtr.h"
-#include "nsGkAtoms.h"
-#include "nsContentUtils.h"
 
 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(A)
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
 SVGAElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
@@ -40,18 +41,18 @@ NS_IMPL_ISUPPORTS_INHERITED5(SVGAElement
                              nsILink,
                              Link)
 
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGAElement::SVGAElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : SVGAElementBase(aNodeInfo),
-    ALLOW_THIS_IN_INITIALIZER_LIST(Link(this))
+  : SVGAElementBase(aNodeInfo)
+  , Link(MOZ_THIS_IN_INITIALIZER_LIST())
 {
 }
 
 already_AddRefed<SVGAnimatedString>
 SVGAElement::Href()
 {
   return mStringAttributes[HREF].ToDOMAnimatedString(this);
 }
--- a/content/svg/content/src/SVGRect.cpp
+++ b/content/svg/content/src/SVGRect.cpp
@@ -1,20 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SVGRect.h"
 #include "nsContentUtils.h"
-#include "nsDOMClassInfoID.h"
 #include "nsSVGElement.h"
 
-DOMCI_DATA(SVGRect, mozilla::dom::SVGRect)
-
 namespace mozilla {
 namespace dom {
 
 //----------------------------------------------------------------------
 // implementation:
 
 SVGRect::SVGRect(nsIContent* aParent, float x, float y, float w, float h)
   : SVGIRect(), mParent(aParent), mX(x), mY(y), mWidth(w), mHeight(h)
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -471,17 +471,17 @@ nsXBLPrototypeBinding::GetBaseTag(int32_
 }
 
 bool
 nsXBLPrototypeBinding::ImplementsInterface(REFNSIID aIID) const
 {
   // Check our IID table.
   if (mInterfaceTable) {
     nsIIDKey key(aIID);
-    nsCOMPtr<nsISupports> supports = getter_AddRefs(static_cast<nsISupports*>(mInterfaceTable->Get(&key)));
+    nsCOMPtr<nsISupports> supports = dont_AddRef(mInterfaceTable->Get(&key));
     return supports != nullptr;
   }
 
   return false;
 }
 
 // Internal helpers ///////////////////////////////////////////////////////////////////////
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -515,19 +515,16 @@ static nsDOMClassInfoData sClassInfoData
   // Crypto classes
 #ifndef MOZ_DISABLE_CRYPTOLEGACY
   NS_DEFINE_CLASSINFO_DATA(CRMFObject, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
   NS_DEFINE_CLASSINFO_DATA(Crypto, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(CSSRect, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
   // DOM Chrome Window class.
   NS_DEFINE_CLASSINFO_DATA(ChromeWindow, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
 #ifdef MOZ_XUL
   NS_DEFINE_CLASSINFO_DATA(XULTemplateBuilder, nsDOMGenericSH,
                            DEFAULT_SCRIPTABLE_FLAGS)
@@ -665,18 +662,16 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBKeyRange, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBIndex, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, IDBEventTargetSH,
                            IDBEVENTTARGET_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(TouchList, nsDOMTouchListSH,
-                           ARRAY_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframeRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -784,19 +779,16 @@ jsid nsDOMClassInfo::sItem_id           
 jsid nsDOMClassInfo::sNamedItem_id       = JSID_VOID;
 jsid nsDOMClassInfo::sEnumerate_id       = JSID_VOID;
 jsid nsDOMClassInfo::sNavigator_id       = JSID_VOID;
 jsid nsDOMClassInfo::sTop_id             = JSID_VOID;
 jsid nsDOMClassInfo::sDocument_id        = JSID_VOID;
 jsid nsDOMClassInfo::sFrames_id          = JSID_VOID;
 jsid nsDOMClassInfo::sSelf_id            = JSID_VOID;
 jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
-jsid nsDOMClassInfo::sURL_id             = JSID_VOID;
-jsid nsDOMClassInfo::sOnload_id          = JSID_VOID;
-jsid nsDOMClassInfo::sOnerror_id         = JSID_VOID;
 
 static const JSClass *sObjectClass = nullptr;
 
 /**
  * Set our JSClass pointer for the Object class
  */
 static void
 FindObjectClass(JSContext* cx, JSObject* aGlobalObject)
@@ -979,19 +971,16 @@ nsDOMClassInfo::DefineStaticJSVals(JSCon
   SET_JSID_TO_STRING(sNamedItem_id,       cx, "namedItem");
   SET_JSID_TO_STRING(sEnumerate_id,       cx, "enumerateProperties");
   SET_JSID_TO_STRING(sNavigator_id,       cx, "navigator");
   SET_JSID_TO_STRING(sTop_id,             cx, "top");
   SET_JSID_TO_STRING(sDocument_id,        cx, "document");
   SET_JSID_TO_STRING(sFrames_id,          cx, "frames");
   SET_JSID_TO_STRING(sSelf_id,            cx, "self");
   SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject");
-  SET_JSID_TO_STRING(sURL_id,             cx, "URL");
-  SET_JSID_TO_STRING(sOnload_id,          cx, "onload");
-  SET_JSID_TO_STRING(sOnerror_id,         cx, "onerror");
 
   return NS_OK;
 }
 
 // static
 bool
 nsDOMClassInfo::ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
 {
@@ -1377,20 +1366,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(StyleSheetList, nsIDOMStyleSheetList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMStyleSheetList)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(CSSStyleSheet, nsIDOMCSSStyleSheet)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleSheet)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSRect, nsIDOMRect)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMRect)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(Selection, nsISelection)
     DOM_CLASSINFO_MAP_ENTRY(nsISelection)
   DOM_CLASSINFO_MAP_END
 
 #ifdef MOZ_XUL
   DOM_CLASSINFO_MAP_BEGIN(XULCommandDispatcher, nsIDOMXULCommandDispatcher)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULCommandDispatcher)
   DOM_CLASSINFO_MAP_END
@@ -1640,21 +1625,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(IDBOpenDBRequest, nsIIDBOpenDBRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBOpenDBRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIIDBRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN_MAYBE_DISABLE(TouchList, nsIDOMTouchList,
-                                        !nsDOMTouchEvent::PrefEnabled())
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMTouchList)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(MozCSSKeyframeRule, nsIDOMMozCSSKeyframeRule)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframeRule)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozCSSKeyframesRule, nsIDOMMozCSSKeyframesRule)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozCSSKeyframesRule)
   DOM_CLASSINFO_MAP_END
 
@@ -2060,24 +2040,16 @@ nsDOMClassInfo::NewResolve(nsIXPConnectW
 {
   if (id == sConstructor_id) {
     return ResolveConstructor(cx, obj, objp);
   }
 
   return NS_OK;
 }
 
-nsISupports*
-nsDOMTouchListSH::GetItemAt(nsISupports *aNative, uint32_t aIndex,
-                            nsWrapperCache **aCache, nsresult *aResult)
-{
-  nsDOMTouchList* list = static_cast<nsDOMTouchList*>(aNative);
-  return list->GetItemAt(aIndex);
-}
-
 NS_IMETHODIMP
 nsDOMClassInfo::Convert(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                         JSObject *obj, uint32_t type, jsval *vp,
                         bool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::Convert Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
@@ -2404,18 +2376,16 @@ nsDOMClassInfo::ShutDown()
   sItem_id            = JSID_VOID;
   sEnumerate_id       = JSID_VOID;
   sNavigator_id       = JSID_VOID;
   sTop_id             = JSID_VOID;
   sDocument_id        = JSID_VOID;
   sFrames_id          = JSID_VOID;
   sSelf_id            = JSID_VOID;
   sWrappedJSObject_id = JSID_VOID;
-  sOnload_id          = JSID_VOID;
-  sOnerror_id         = JSID_VOID;
 
   NS_IF_RELEASE(sXPConnect);
   NS_IF_RELEASE(sSecMan);
   sIsInitialized = false;
 }
 
 // Window helper
 
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -174,18 +174,17 @@ protected:
             id == sStatusbar_id    ||
             id == sControllers_id  ||
             id == sScrollX_id      ||
             id == sScrollY_id      ||
             id == sScrollMaxX_id   ||
             id == sScrollMaxY_id   ||
             id == sLength_id       ||
             id == sFrames_id       ||
-            id == sSelf_id         ||
-            id == sURL_id);
+            id == sSelf_id);
   }
 
   static nsIXPConnect *sXPConnect;
   static nsIScriptSecurityManager *sSecMan;
 
   // nsIXPCScriptable code
   static nsresult DefineStaticJSVals(JSContext *cx);
 
@@ -198,41 +197,32 @@ public:
   static jsid sConstructor_id;
   static jsid s_content_id;
   static jsid sContent_id;
   static jsid sMenubar_id;
   static jsid sToolbar_id;
   static jsid sLocationbar_id;
   static jsid sPersonalbar_id;
   static jsid sStatusbar_id;
-  static jsid sDialogArguments_id;
   static jsid sControllers_id;
   static jsid sLength_id;
   static jsid sScrollX_id;
   static jsid sScrollY_id;
   static jsid sScrollMaxX_id;
   static jsid sScrollMaxY_id;
   static jsid sItem_id;
   static jsid sNamedItem_id;
   static jsid sEnumerate_id;
   static jsid sNavigator_id;
   static jsid sTop_id;
   static jsid sDocument_id;
   static jsid sFrames_id;
   static jsid sSelf_id;
   static jsid sJava_id;
-  static jsid sPackages_id;
   static jsid sWrappedJSObject_id;
-  static jsid sURL_id;
-  static jsid sOnload_id;
-  static jsid sOnerror_id;
-
-protected:
-  static JSPropertyOp sXPCNativeWrapperGetPropertyOp;
-  static JSPropertyOp sXrayWrapperPropertyHolderGetPropertyOp;
 };
 
 // THIS ONE ISN'T SAFE!! It assumes that the private of the JSObject is
 // an nsISupports.
 inline
 const nsQueryInterface
 do_QueryWrappedNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj)
 {
@@ -667,37 +657,16 @@ protected:
 
 public:
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsCSSRuleListSH(aData);
   }
 };
 
-class nsDOMTouchListSH : public nsArraySH
-{
-  protected:
-  nsDOMTouchListSH(nsDOMClassInfoData* aData) : nsArraySH(aData)
-  {
-  }
-
-  virtual ~nsDOMTouchListSH()
-  {
-  }
-
-  virtual nsISupports* GetItemAt(nsISupports *aNative, uint32_t aIndex,
-                                 nsWrapperCache **aCache, nsresult *aResult) MOZ_OVERRIDE;
-
-  public:
-  static nsIClassInfo* doCreate(nsDOMClassInfoData* aData)
-  {
-    return new nsDOMTouchListSH(aData);
-  }
-};
-
 // WebApps Storage helpers
 
 class nsStorage2SH : public nsDOMGenericSH
 {
 protected:
   nsStorage2SH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
   {
   }
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -43,19 +43,16 @@ DOMCI_CLASS(TreeContentView)
 #endif
 
 // Crypto classes
 #ifndef MOZ_DISABLE_CRYPTOLEGACY
 DOMCI_CLASS(CRMFObject)
 #endif
 DOMCI_CLASS(Crypto)
 
-// Rect object used by getComputedStyle
-DOMCI_CLASS(CSSRect)
-
 // DOM Chrome Window class, almost identical to Window
 DOMCI_CLASS(ChromeWindow)
 
 #ifdef MOZ_XUL
 DOMCI_CLASS(XULTemplateBuilder)
 DOMCI_CLASS(XULTreeBuilder)
 #endif
 
@@ -129,17 +126,16 @@ DOMCI_CLASS(IDBDatabase)
 DOMCI_CLASS(IDBObjectStore)
 DOMCI_CLASS(IDBTransaction)
 DOMCI_CLASS(IDBCursor)
 DOMCI_CLASS(IDBCursorWithValue)
 DOMCI_CLASS(IDBKeyRange)
 DOMCI_CLASS(IDBIndex)
 DOMCI_CLASS(IDBOpenDBRequest)
 
-DOMCI_CLASS(TouchList)
 
 DOMCI_CLASS(MozCSSKeyframeRule)
 DOMCI_CLASS(MozCSSKeyframesRule)
 
 DOMCI_CLASS(CSSPageRule)
 
 DOMCI_CLASS(MediaQueryList)
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -4849,17 +4849,17 @@ nsGlobalWindow::GetScrollXY(int32_t* aSc
   nsPoint scrollPos = sf->GetScrollPosition();
   if (scrollPos != nsPoint(0,0) && !aDoFlush) {
     // Oh, well.  This is the expensive case -- the window is scrolled and we
     // didn't actually flush yet.  Repeat, but with a flush, since the content
     // may get shorter and hence our scroll position may decrease.
     return GetScrollXY(aScrollX, aScrollY, true);
   }
 
-  nsIntPoint scrollPosCSSPixels = sf->GetScrollPositionCSSPixels();
+  CSSIntPoint scrollPosCSSPixels = sf->GetScrollPositionCSSPixels();
   if (aScrollX) {
     *aScrollX = scrollPosCSSPixels.x;
   }
   if (aScrollY) {
     *aScrollY = scrollPosCSSPixels.y;
   }
   return NS_OK;
 }
@@ -6102,18 +6102,17 @@ nsGlobalWindow::ScrollTo(const CSSIntPoi
 NS_IMETHODIMP
 nsGlobalWindow::ScrollBy(int32_t aXScrollDif, int32_t aYScrollDif)
 {
   FlushPendingNotifications(Flush_Layout);
   nsIScrollableFrame *sf = GetScrollFrame();
 
   if (sf) {
     CSSIntPoint scrollPos =
-      CSSIntPoint::FromAppUnitsRounded(sf->GetScrollPosition()) +
-      CSSIntPoint(aXScrollDif, aYScrollDif);
+      sf->GetScrollPositionCSSPixels() + CSSIntPoint(aXScrollDif, aYScrollDif);
     // It seems like it would make more sense for ScrollBy to use
     // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
     // Perhaps Web content does too.
     ScrollTo(scrollPos);
   }
 
   return NS_OK;
 }
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1154,16 +1154,21 @@ DOMInterfaces = {
 'TimeRanges': {
     'wrapperCache': False
 },
 
 'TouchEvent': {
     'nativeType': 'nsDOMTouchEvent',
 },
 
+'TouchList': {
+    'nativeType': 'nsDOMTouchList',
+    'headerFile': 'nsDOMTouchEvent.h',
+},
+
 'TransitionEvent': {
     'nativeType': 'nsDOMTransitionEvent',
 },
 
 'TreeColumns': {
     'nativeType': 'nsTreeColumns',
 },
 
@@ -1726,17 +1731,16 @@ addExternalIface('OutputStream', nativeT
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
 addExternalIface('PrintCallback', nativeType='nsIPrintCallback',
                  headerFile='nsIDOMHTMLCanvasElement.h')
 addExternalIface('Selection', nativeType='nsISelection')
 addExternalIface('StyleSheetList')
 addExternalIface('SVGLength')
 addExternalIface('SVGNumber')
-addExternalIface('TouchList', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
 addExternalIface('UserDataHandler')
 addExternalIface('Window')
 addExternalIface('XPathResult', nativeType='nsISupports')
 addExternalIface('XPathExpression')
 addExternalIface('XPathNSResolver')
 addExternalIface('XULCommandDispatcher')
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -2089,46 +2089,16 @@ bool
 BluetoothDBusService::GetDevicePath(const nsAString& aAdapterPath,
                                     const nsAString& aDeviceAddress,
                                     nsAString& aDevicePath)
 {
   aDevicePath = GetObjectPathFromAddress(aAdapterPath, aDeviceAddress);
   return true;
 }
 
-static int
-GetDeviceServiceChannel(const nsAString& aObjectPath,
-                        const nsAString& aPattern,
-                        int aAttributeId)
-{
-  // This is a blocking call, should not be run on main thread.
-  MOZ_ASSERT(!NS_IsMainThread());
-
-#ifdef MOZ_WIDGET_GONK
-  // GetServiceAttributeValue only exists in android's bluez dbus binding
-  // implementation
-  nsCString tempPattern = NS_ConvertUTF16toUTF8(aPattern);
-  const char* pattern = tempPattern.get();
-
-  DBusMessage *reply =
-    dbus_func_args(gThreadConnection->GetConnection(),
-                   NS_ConvertUTF16toUTF8(aObjectPath).get(),
-                   DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
-                   DBUS_TYPE_STRING, &pattern,
-                   DBUS_TYPE_UINT16, &aAttributeId,
-                   DBUS_TYPE_INVALID);
-
-  return reply ? dbus_returns_int32(reply) : -1;
-#else
-  // FIXME/Bug 793977 qdot: Just return something for desktop, until we have a
-  // parser for the GetServiceAttributes xml block
-  return 1;
-#endif
-}
-
 // static
 bool
 BluetoothDBusService::RemoveReservedServicesInternal(
                                       const nsTArray<uint32_t>& aServiceHandles)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   int length = aServiceHandles.Length();
@@ -2584,82 +2554,118 @@ public:
   {
     MOZ_ASSERT(!aObjectPath.IsEmpty());
     MOZ_ASSERT(!aServiceUuid.IsEmpty());
     MOZ_ASSERT(aManager);
 
     mDeviceAddress = GetAddressFromObjectPath(aObjectPath);
   }
 
-  nsresult
-  Run()
+  NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     mManager->OnGetServiceChannel(mDeviceAddress, mServiceUuid, mChannel);
 
     return NS_OK;
   }
 
 private:
   nsString mDeviceAddress;
   nsString mServiceUuid;
   int mChannel;
   BluetoothProfileManagerBase* mManager;
 };
 
-class GetServiceChannelRunnable : public nsRunnable
+class OnGetServiceChannelReplyHandler : public DBusReplyHandler
 {
 public:
-  GetServiceChannelRunnable(const nsAString& aObjectPath,
-                            const nsAString& aServiceUuid,
-                            BluetoothProfileManagerBase* aManager)
-    : mObjectPath(aObjectPath),
-      mServiceUuid(aServiceUuid),
-      mManager(aManager)
+  OnGetServiceChannelReplyHandler(const nsAString& aObjectPath,
+                                  const nsAString& aServiceUUID,
+                                  BluetoothProfileManagerBase* aBluetoothProfileManager)
+  : mObjectPath(aObjectPath),
+    mServiceUUID(aServiceUUID),
+    mBluetoothProfileManager(aBluetoothProfileManager)
   {
-    MOZ_ASSERT(!aObjectPath.IsEmpty());
-    MOZ_ASSERT(!aServiceUuid.IsEmpty());
-    MOZ_ASSERT(aManager);
+    MOZ_ASSERT(mBluetoothProfileManager);
   }
 
-  nsresult
-  Run()
+  void Handle(DBusMessage* aReply)
   {
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    int channel = GetDeviceServiceChannel(mObjectPath, mServiceUuid, 0x0004);
-    nsRefPtr<nsRunnable> r(new OnGetServiceChannelRunnable(mObjectPath,
-                                                           mServiceUuid,
-                                                           channel,
-                                                           mManager));
-    NS_DispatchToMainThread(r);
-    return NS_OK;
+    MOZ_ASSERT(!NS_IsMainThread()); // DBus thread
+
+    // The default channel is an invalid value of -1. We
+    // update it if we have received a correct reply. Both
+    // cases, valid and invalid channel numbers, are handled
+    // in BluetoothProfileManagerBase::OnGetServiceChannel.
+
+    int channel = -1;
+
+    if (aReply && (dbus_message_get_type(aReply) != DBUS_MESSAGE_TYPE_ERROR)) {
+      channel = dbus_returns_int32(aReply);
+    }
+
+    nsRefPtr<nsRunnable> r = new OnGetServiceChannelRunnable(mObjectPath,
+                                                             mServiceUUID,
+                                                             channel,
+                                                             mBluetoothProfileManager);
+    nsresult rv = NS_DispatchToMainThread(r);
+    NS_ENSURE_SUCCESS_VOID(rv);
   }
 
 private:
   nsString mObjectPath;
-  nsString mServiceUuid;
-  BluetoothProfileManagerBase* mManager;
+  nsString mServiceUUID;
+  BluetoothProfileManagerBase* mBluetoothProfileManager;
 };
 
 nsresult
 BluetoothDBusService::GetServiceChannel(const nsAString& aDeviceAddress,
-                                        const nsAString& aServiceUuid,
+                                        const nsAString& aServiceUUID,
                                         BluetoothProfileManagerBase* aManager)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mBluetoothCommandThread);
 
   nsString objectPath(GetObjectPathFromAddress(sAdapterPath, aDeviceAddress));
 
-  nsRefPtr<nsRunnable> r(new GetServiceChannelRunnable(objectPath,
-                                                       aServiceUuid,
-                                                       aManager));
-  mBluetoothCommandThread->Dispatch(r, NS_DISPATCH_NORMAL);
+#ifdef MOZ_WIDGET_GONK
+  static const int sProtocolDescriptorList = 0x0004;
+
+  // GetServiceAttributeValue only exists in android's bluez dbus binding
+  // implementation
+  nsCString serviceUUID = NS_ConvertUTF16toUTF8(aServiceUUID);
+  const char* cstrServiceUUID = serviceUUID.get();
+
+  nsRefPtr<OnGetServiceChannelReplyHandler> handler =
+    new OnGetServiceChannelReplyHandler(objectPath, aServiceUUID, aManager);
+
+  bool success = dbus_func_args_async(mConnection, -1,
+                                      OnGetServiceChannelReplyHandler::Callback, handler,
+                                      NS_ConvertUTF16toUTF8(objectPath).get(),
+                                      DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
+                                      DBUS_TYPE_STRING, &cstrServiceUUID,
+                                      DBUS_TYPE_UINT16, &sProtocolDescriptorList,
+                                      DBUS_TYPE_INVALID);
+  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
+
+  handler.forget();
+#else
+  // FIXME/Bug 793977 qdot: Just set something for desktop, until we have a
+  // parser for the GetServiceAttributes xml block
+  //
+  // Even though we are on the main thread already, we need to dispatch a
+  // runnable here. OnGetServiceChannel needs mRunnable to be set, which
+  // happens after GetServiceChannel returns.
+  nsRefPtr<nsRunnable> r = new OnGetServiceChannelRunnable(objectPath,
+                                                           aServiceUUID,
+                                                           1,
+                                                           aManager);
+  nsresult rv = NS_DispatchToMainThread(r);
+  NS_ENSURE_SUCCESS_VOID(rv);
+#endif
 
   return NS_OK;
 }
 
 static void
 DiscoverServicesCallback(DBusMessage* aMsg, void* aData)
 {
   MOZ_ASSERT(!NS_IsMainThread());
--- a/dom/file/ArchiveRequest.cpp
+++ b/dom/file/ArchiveRequest.cpp
@@ -6,17 +6,16 @@
 
 #include "ArchiveRequest.h"
 
 #include "mozilla/dom/ArchiveRequestBinding.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsLayoutStatics.h"
 #include "nsEventDispatcher.h"
-#include "nsDOMClassInfoID.h"
 
 USING_FILE_NAMESPACE
 
 /**
  * Class used to make asynchronous the ArchiveRequest.
  */
 class ArchiveRequestEvent : public nsRunnable
 {
@@ -274,10 +273,8 @@ ArchiveRequest::Create(nsIDOMWindow* aOw
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ArchiveRequest, DOMRequest,
                                      mArchiveReader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ArchiveRequest)
 NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
 
 NS_IMPL_ADDREF_INHERITED(ArchiveRequest, DOMRequest)
 NS_IMPL_RELEASE_INHERITED(ArchiveRequest, DOMRequest)
-
-DOMCI_DATA(ArchiveRequest, ArchiveRequest)
--- a/dom/icc/interfaces/nsIDOMIccManager.idl
+++ b/dom/icc/interfaces/nsIDOMIccManager.idl
@@ -4,17 +4,17 @@
 
 #include "nsIDOMEventTarget.idl"
 #include "SimToolKit.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMDOMRequest;
 interface nsIDOMContact;
 
-[scriptable, builtinclass, uuid(d21b7070-c2bc-11e2-8b8b-0800200c9a66)]
+[scriptable, builtinclass, uuid(5f405112-4da9-4d4d-942c-4da3cb7928e1)]
 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;
@@ -427,16 +427,30 @@ interface nsIDOMMozIccManager : nsIDOMEv
    * 'setCardLock' fails.
    *
    * The result will be an object containing information
    * about the specified lock's status,
    * e.g. {lockType: "pin", retryCount: 2}.
    */
   [implicit_jscontext] attribute jsval onicccardlockerror;
 
+  /**
+   * Retrieve the number of remaining tries for unlocking the card.
+   *
+   * @param lockType
+   *        Identifies the lock type, e.g. "pin" for the PIN lock, "puk" for
+   *        the PUK lock.
+   *
+   * @return a DOM Request.
+   *         If the lock type is "pin", or "puk", the request's result will be
+   *         an object containing the number of retries for the specified
+   *         lock. For any other lock type, the result is undefined.
+   */
+  nsIDOMDOMRequest getCardLockRetryCount(in DOMString lockType);
+
   // UICC Phonebook Interfaces.
 
   /**
    * Read ICC contacts.
    *
    * @param contactType
    *        One of type as below,
    *        - 'adn': Abbreviated Dialling Number
--- a/dom/icc/interfaces/nsIIccProvider.idl
+++ b/dom/icc/interfaces/nsIIccProvider.idl
@@ -16,17 +16,17 @@ interface nsIIccListener : nsISupports
   void notifyIccCardLockError(in DOMString lockType,
                               in unsigned long retryCount);
   void notifyCardStateChanged();
 };
 
 /**
  * XPCOM component (in the content process) that provides the ICC information.
  */
-[scriptable, uuid(77487bf0-c2be-11e2-8b8b-0800200c9a66)]
+[scriptable, uuid(7131dfbe-9a2c-434d-b6b8-3eebf491ce1a)]
 interface nsIIccProvider : nsISupports
 {
   /**
    * Called when a content process registers receiving unsolicited messages from
    * RadioInterfaceLayer in the chrome process. Only a content process that has
    * the 'mobileconnection' permission is allowed to register.
    */
   void registerIccMsg(in nsIIccListener listener);
@@ -52,16 +52,17 @@ interface nsIIccProvider : nsISupports
                             in jsval        event);
 
   /**
    * Card lock interfaces.
    */
   nsIDOMDOMRequest getCardLockState(in nsIDOMWindow window, in DOMString lockType);
   nsIDOMDOMRequest unlockCardLock(in nsIDOMWindow window, in jsval info);
   nsIDOMDOMRequest setCardLock(in nsIDOMWindow window, in jsval info);
+  nsIDOMDOMRequest getCardLockRetryCount(in nsIDOMWindow window, in DOMString lockType);
 
   /**
    * Phonebook interfaces.
    */
   nsIDOMDOMRequest readContacts(in nsIDOMWindow window,
                                 in DOMString contactType);
 
   nsIDOMDOMRequest updateContact(in nsIDOMWindow window,
--- a/dom/icc/src/IccManager.cpp
+++ b/dom/icc/src/IccManager.cpp
@@ -166,16 +166,26 @@ IccManager::UnlockCardLock(const JS::Val
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->UnlockCardLock(GetOwner(), aInfo, aDomRequest);
 }
 
 NS_IMETHODIMP
+IccManager::GetCardLockRetryCount(const nsAString& aLockType, nsIDOMDOMRequest** aDomRequest)
+{
+  if (!mProvider) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return mProvider->GetCardLockRetryCount(GetOwner(), aLockType, aDomRequest);
+}
+
+NS_IMETHODIMP
 IccManager::IccOpenChannel(const nsAString& aAid, nsIDOMDOMRequest** aRequest)
 {
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->IccOpenChannel(GetOwner(), aAid, aRequest);
 }
--- a/dom/icc/tests/marionette/test_icc_card_lock.js
+++ b/dom/icc/tests/marionette/test_icc_card_lock.js
@@ -85,20 +85,90 @@ function testPinChangeSuccess() {
   request.onsuccess = function onsuccess() {
     is(request.result.lockType, "pin");
     is(request.result.success, true);
 
     runNextTest();
   };
 }
 
+/* Read PIN-lock retry count */
+function testPinCardLockRetryCount() {
+  let request = icc.getCardLockRetryCount('pin');
+
+  ok(request instanceof DOMRequest,
+     'request instanceof ' + request.constructor);
+
+  request.onsuccess = function onsuccess() {
+    is(request.result.lockType, 'pin',
+        'lockType is ' + request.result.lockType);
+    ok(request.result.retryCount >= 0,
+        'retryCount is ' + request.result.retryCount);
+    runNextTest();
+  };
+  request.onerror = function onerror() {
+    // The operation is optional any might not be supported for all
+    // all locks. In this case, we generate 'NotSupportedError' for
+    // the valid lock types.
+    is(request.error.name, 'RequestNotSupported',
+        'error name is ' + request.error.name);
+    runNextTest();
+  };
+}
+
+/* Read PUK-lock retry count */
+function testPukCardLockRetryCount() {
+  let request = icc.getCardLockRetryCount('puk');
+
+  ok(request instanceof DOMRequest,
+     'request instanceof ' + request.constructor);
+
+  request.onsuccess = function onsuccess() {
+    is(request.result.lockType, 'puk',
+        'lockType is ' + request.result.lockType);
+    ok(request.result.retryCount >= 0,
+        'retryCount is ' + request.result.retryCount);
+    runNextTest();
+  };
+  request.onerror = function onerror() {
+    // The operation is optional any might not be supported for all
+    // all locks. In this case, we generate 'NotSupportedError' for
+    // the valid lock types.
+    is(request.error.name, 'RequestNotSupported',
+        'error name is ' + request.error.name);
+    runNextTest();
+  };
+}
+
+/* Read lock retry count for an invalid entries  */
+function testInvalidCardLockRetryCount() {
+  let request = icc.getCardLockRetryCount('invalid-lock-type');
+
+  ok(request instanceof DOMRequest,
+     'request instanceof ' + request.constructor);
+
+  request.onsuccess = function onsuccess() {
+    ok(false,
+        'request should never return success for an invalid lock type');
+    runNextTest();
+  };
+  request.onerror = function onerror() {
+    is(request.error.name, 'GenericFailure',
+        'error name is ' + request.error.name);
+    runNextTest();
+  };
+}
+
 let tests = [
   testPinChangeFailed,
   testPinChangeFailedNotification,
   testPinChangeSuccess,
+  testPinCardLockRetryCount,
+  testPukCardLockRetryCount,
+  testInvalidCardLockRetryCount
 ];
 
 function runNextTest() {
   let test = tests.shift();
   if (!test) {
     cleanUp();
     return;
   }
--- a/dom/imptests/failures/html/html/dom/documents/dta/Makefile.in
+++ b/dom/imptests/failures/html/html/dom/documents/dta/Makefile.in
@@ -5,17 +5,16 @@ DEPTH := @DEPTH@
 topsrcdir := @top_srcdir@
 srcdir := @srcdir@
 VPATH := @srcdir@
 relativesrcdir := @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES := \
-  test_document.body-getter.html.json \
   test_document.title-03.html.json \
   test_document.title-04.xhtml.json \
   test_document.title-06.html.json \
   test_document.title-07.html.json \
   test_nameditem-02.html.json \
   test_nameditem-03.html.json \
   test_nameditem-04.html.json \
   test_nameditem-05.html.json \
deleted file mode 100644
--- a/dom/imptests/failures/html/html/dom/documents/dta/test_document.body-getter.html.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "Frameset followed by body inside the html element": true,
-  "Body followed by frameset inside a non-HTML html element": true,
-  "Frameset followed by body inside a non-HTML html element": true,
-  "Frameset inside an x element followed by a frameset": true,
-  "Frameset as the root node": true,
-  "Body as the root node with a frameset child": true,
-  "Frameset as the root node with a body child": true
-}
--- a/dom/imptests/failures/html/html/semantics/tabular-data/the-table-element/Makefile.in
+++ b/dom/imptests/failures/html/html/semantics/tabular-data/the-table-element/Makefile.in
@@ -5,14 +5,13 @@ DEPTH := @DEPTH@
 topsrcdir := @top_srcdir@
 srcdir := @srcdir@
 VPATH := @srcdir@
 relativesrcdir := @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES := \
-  test_createTBody.html.json \
   test_table-insertRow.html.json \
   test_table-rows.html.json \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/dom/imptests/failures/html/html/semantics/tabular-data/the-table-element/test_createTBody.html.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "No child nodes": true,
-  "One tbody child node": true,
-  "Two tbody child nodes": true,
-  "A thead and a tbody child node": true,
-  "A tfoot and a tbody child node": true,
-  "A tbody and a thead child node": true,
-  "A tbody and a tfoot child node": true,
-  "Two tbody child nodes and a div": true,
-  "One HTML and one namespaced tbody child node": true,
-  "Two nested tbody child nodes": true,
-  "A tbody node inside a thead child node": true,
-  "A tbody node inside a tfoot child node": true,
-  "A tbody node inside a thead child node after a tbody child node": true,
-  "A tbody node inside a tfoot child node after a tbody child node": true
-}
--- a/dom/interfaces/events/moz.build
+++ b/dom/interfaces/events/moz.build
@@ -35,17 +35,16 @@ XPIDL_SOURCES += [
     'nsIDOMMouseEvent.idl',
     'nsIDOMMouseScrollEvent.idl',
     'nsIDOMMutationEvent.idl',
     'nsIDOMNSEvent.idl',
     'nsIDOMNotifyAudioAvailableEvent.idl',
     'nsIDOMNotifyPaintEvent.idl',
     'nsIDOMPageTransitionEvent.idl',
     'nsIDOMPaintRequest.idl',
-    'nsIDOMPaintRequestList.idl',
     'nsIDOMPopStateEvent.idl',
     'nsIDOMPopupBlockedEvent.idl',
     'nsIDOMProgressEvent.idl',
     'nsIDOMRecordErrorEvent.idl',
     'nsIDOMScrollAreaEvent.idl',
     'nsIDOMSimpleGestureEvent.idl',
     'nsIDOMSmartCardEvent.idl',
     'nsIDOMStyleRuleChangeEvent.idl',
--- a/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
+++ b/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
@@ -7,17 +7,17 @@
 
 interface nsIDOMPaintRequestList;
 
 /**
  * The nsIDOMNotifyPaintEvent interface is used for the MozDOMAfterPaint
  * event, which fires at a window when painting has happened in
  * that window.
  */
-[scriptable, builtinclass, uuid(e3560df8-0926-48da-b13a-36d3938c95af)]
+[scriptable, builtinclass, uuid(ef68f0d5-5b55-4198-9e59-a5e2c57d3adc)]
 interface nsIDOMNotifyPaintEvent : nsIDOMEvent
 {
   /**
    * Get a list of rectangles which are affected. The rectangles are in CSS pixels
    * relative to the viewport origin.
    * If the caller is not trusted (e.g., regular Web content) then only painting
    * caused by the current document is reported; in particular, painting in subdocuments
    * is not reported.
@@ -27,11 +27,11 @@ interface nsIDOMNotifyPaintEvent : nsIDO
    * Get the bounding box of the rectangles which are affected. The rectangle
    * is in CSS pixels relative to the viewport origin.
    * If the caller is not trusted (e.g., regular Web content) then only painting
    * caused by the current document is reported; in particular, painting in subdocuments
    * is not reported.
    */
   readonly attribute nsIDOMClientRect boundingClientRect;
 
-  readonly attribute nsIDOMPaintRequestList paintRequests;
+  readonly attribute nsISupports /* PaintRequestList */ paintRequests;
 };
 
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMPaintRequestList.idl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "domstubs.idl"
-
-interface nsIDOMPaintRequest;
-
-[scriptable, uuid(1d6a6e10-e9f0-468b-b8e5-da39c945690e)]
-interface nsIDOMPaintRequestList : nsISupports
-{
-  readonly attribute unsigned long length;
-  nsIDOMPaintRequest        item(in unsigned long index);
-};
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2567,10 +2567,42 @@ ContentParent::CheckAppHasStatus(unsigne
 
 bool
 ContentParent::RecvSystemMessageHandled()
 {
     SystemMessageHandledListener::OnSystemMessageHandled();
     return true;
 }
 
+bool
+ContentParent::RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint)
+{
+#ifdef MOZ_WIDGET_GONK
+  nsresult rv;
+  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
+  if (vs) {
+    vs->CreateFakeVolume(fsName, mountPoint);
+  }
+  return true;
+#else
+  NS_WARNING("ContentParent::RecvCreateFakeVolume shouldn't be called when MOZ_WIDGET_GONK is not defined");
+  return false;
+#endif
+}
+
+bool
+ContentParent::RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState)
+{
+#ifdef MOZ_WIDGET_GONK
+  nsresult rv;
+  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
+  if (vs) {
+    vs->SetFakeVolumeState(fsName, fsState);
+  }
+  return true;
+#else
+  NS_WARNING("ContentParent::RecvSetFakeVolumeState shouldn't be called when MOZ_WIDGET_GONK is not defined");
+  return false;
+#endif
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -411,16 +411,20 @@ private:
     virtual bool RecvAudioChannelChangedNotification();
 
     virtual bool RecvBroadcastVolume(const nsString& aVolumeName);
 
     virtual bool RecvRecordingDeviceEvents(const nsString& aRecordingStatus);
 
     virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
 
+    virtual bool RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint) MOZ_OVERRIDE;
+
+    virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) MOZ_OVERRIDE;
+
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
     GeckoChildProcessHost* mSubprocess;
     base::ChildPrivileges mOSPrivileges;
 
     uint64_t mChildID;
     int32_t mGeolocationWatchID;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -510,14 +510,18 @@ parent:
     // get nsIVolumeService to broadcast volume information
     async BroadcastVolume(nsString volumeName);
 
     async RecordingDeviceEvents(nsString recordingStatus);
 
     // Notify the parent that the child has finished handling a system message.
     async SystemMessageHandled();
 
+    // called by the child (test code only) to propagate volume changes to the parent
+    async CreateFakeVolume(nsString fsName, nsString mountPoint);
+    async SetFakeVolumeState(nsString fsName, int32_t fsState);
+
 both:
      AsyncMessage(nsString aMessage, ClonedMessageData aData);
 };
 
 }
 }
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -42,16 +42,21 @@ const kMessages =["SystemMessageManager:
                   "SystemMessageManager:AskReadyToRegister",
                   "SystemMessageManager:HandleMessagesDone",
                   "child-process-shutdown"]
 
 function debug(aMsg) {
   // dump("-- SystemMessageInternal " + Date.now() + " : " + aMsg + "\n");
 }
 
+
+const MSG_SENT_SUCCESS = 0;
+const MSG_SENT_FAILURE_PERM_DENIED = 1;
+const MSG_SENT_FAILURE_APP_NOT_RUNNING = 2;
+
 // Implementation of the component used by internal users.
 
 function SystemMessageInternal() {
   // The set of pages registered by installed apps. We keep the
   // list of pending messages for each page here also.
   this._pages = [];
 
   // The set of listeners. This is a multi-dimensional object. The _listeners
@@ -153,33 +158,38 @@ SystemMessageInternal.prototype = {
 
     // Give this message an ID so that we can identify the message and
     // clean it up from the pending message queue when apps receive it.
     let messageID = gUUIDGenerator.generateUUID().toString();
 
     debug("Sending " + aType + " " + JSON.stringify(aMessage) +
       " for " + aPageURI.spec + " @ " + aManifestURI.spec);
 
+    let result = this._sendMessageCommon(aType,
+                                         aMessage,
+                                         messageID,
+                                         aPageURI.spec,
+                                         aManifestURI.spec);
+    debug("Returned status of sending message: " + result);
+
     // Don't need to open the pages and queue the system message
     // which was not allowed to be sent.
-    if (!this._sendMessageCommon(aType,
-                                 aMessage,
-                                 messageID,
-                                 aPageURI.spec,
-                                 aManifestURI.spec)) {
+    if (result === MSG_SENT_FAILURE_PERM_DENIED) {
       return;
     }
 
     let page = this._findPage(aType, aPageURI.spec, aManifestURI.spec);
     if (page) {
       // Queue this message in the corresponding pages.
       this._queueMessage(page, aMessage, messageID);
 
-      // Open app pages to handle their pending messages.
-      this._openAppPage(page, aMessage);
+        if (result === MSG_SENT_FAILURE_APP_NOT_RUNNING) {
+          // Don't open the page again if we already sent the message to it.
+          this._openAppPage(page, aMessage);
+        }
     }
   },
 
   broadcastMessage: function broadcastMessage(aType, aMessage) {
     // Buffer system messages until the webapps' registration is ready,
     // so that we can know the correct pages registered to be broadcasted.
     if (!this._webappsRegistryReady) {
       this._bufferedSysMsgs.push({ how: "broadcast",
@@ -191,31 +201,37 @@ SystemMessageInternal.prototype = {
     // Give this message an ID so that we can identify the message and
     // clean it up from the pending message queue when apps receive it.
     let messageID = gUUIDGenerator.generateUUID().toString();
 
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     // Find pages that registered an handler for this type.
     this._pages.forEach(function(aPage) {
       if (aPage.type == aType) {
+        let result = this._sendMessageCommon(aType,
+                                             aMessage,
+                                             messageID,
+                                             aPage.uri,
+                                             aPage.manifest);
+        debug("Returned status of sending message: " + result);
+
+
         // Don't need to open the pages and queue the system message
         // which was not allowed to be sent.
-        if (!this._sendMessageCommon(aType,
-                                     aMessage,
-                                     messageID,
-                                     aPage.uri,
-                                     aPage.manifest)) {
+        if (result === MSG_SENT_FAILURE_PERM_DENIED) {
           return;
         }
 
         // Queue this message in the corresponding pages.
         this._queueMessage(aPage, aMessage, messageID);
 
-        // Open app pages to handle their pending messages.
-        this._openAppPage(aPage, aMessage);
+        if (result === MSG_SENT_FAILURE_APP_NOT_RUNNING) {
+          // Open app pages to handle their pending messages.
+          this._openAppPage(aPage, aMessage);
+        }
       }
     }, this);
   },
 
   registerPage: function registerPage(aType, aPageURI, aManifestURI) {
     if (!aPageURI || !aManifestURI) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
@@ -520,17 +536,17 @@ SystemMessageInternal.prototype = {
 
   _sendMessageCommon:
     function _sendMessageCommon(aType, aMessage, aMessageID, aPageURI, aManifestURI) {
     // Don't send the system message not granted by the app's permissions.
     if (!SystemMessagePermissionsChecker
           .isSystemMessagePermittedToSend(aType,
                                           aPageURI,
                                           aManifestURI)) {
-      return false;
+      return MSG_SENT_FAILURE_PERM_DENIED;
     }
 
     let appPageIsRunning = false;
     let pageKey = this._createKeyForPage({ type: aType,
                                            manifest: aManifestURI,
                                            uri: aPageURI })
 
     let targets = this._listeners[aManifestURI];
@@ -566,19 +582,21 @@ SystemMessageInternal.prototype = {
 
     if (!appPageIsRunning) {
       // The app page isn't running and relies on the 'open-app' chrome event to
       // wake it up. We still need to acquire a CPU wake lock for that page and
       // expect that we will receive a "SystemMessageManager:HandleMessagesDone"
       // message when the page finishes handling the system message with other
       // pending messages. At that point, we'll release the lock we acquired.
       this._acquireCpuWakeLock(pageKey);
+      return MSG_SENT_FAILURE_APP_NOT_RUNNING;
+    } else {
+      return MSG_SENT_SUCCESS;
     }
 
-    return true;
   },
 
   classID: Components.ID("{70589ca5-91ac-4b9e-b839-d6a88167d714}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesInternal, Ci.nsIObserver])
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemMessageInternal]);
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -468,23 +468,17 @@ MmsMessage::GetSmil(nsAString& aSmil)
 {
   aSmil = mSmil;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetAttachments(JSContext* aCx, JS::Value* aAttachments)
 {
-  // TODO Bug 850529 We should return an empty array (or null)
-  // when it has no attachments? Need to further check this.
   uint32_t length = mAttachments.Length();
-  if (length == 0) {
-    *aAttachments = JSVAL_NULL;
-    return NS_OK;
-  }
 
   JS::Rooted<JSObject*> attachments(aCx, JS_NewArrayObject(aCx, length, nullptr));
   NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY);
 
   for (uint32_t i = 0; i < length; ++i) {
     const MmsAttachment &attachment = mAttachments[i];
 
     JS::Rooted<JSObject*> attachmentObj(aCx, JS_NewObject(aCx, nullptr, nullptr, nullptr));
--- a/dom/mobilemessage/tests/marionette/manifest.ini
+++ b/dom/mobilemessage/tests/marionette/manifest.ini
@@ -29,8 +29,9 @@ qemu = true
 [test_bug814761.js]
 [test_strict_7bit_encoding.js]
 [test_incoming_max_segments.js]
 [test_outgoing_max_segments.js]
 [test_update_thread_record_in_delete.js]
 [test_massive_incoming_delete.js]
 [test_getsegmentinfofortext.js]
 [test_phone_number_normalization.js]
+[test_mmsmessage_attachments.js]
new file mode 100644
--- /dev/null
+++ b/dom/mobilemessage/tests/marionette/test_mmsmessage_attachments.js
@@ -0,0 +1,121 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+
+const MMS_MAX_LENGTH_SUBJECT = 40;
+
+SpecialPowers.addPermission("sms", true, document);
+SpecialPowers.setBoolPref("dom.sms.enabled", true);
+
+let tasks = {
+  // List of test fuctions. Each of them should call |tasks.next()| when
+  // completed or |tasks.finish()| to jump to the last one.
+  _tasks: [],
+  _nextTaskIndex: 0,
+
+  push: function push(func) {
+    this._tasks.push(func);
+  },
+
+  next: function next() {
+    let index = this._nextTaskIndex++;
+    let task = this._tasks[index];
+    try {
+      task();
+    } catch (ex) {
+      ok(false, "test task[" + index + "] throws: " + ex);
+      // Run last task as clean up if possible.
+      if (index != this._tasks.length - 1) {
+        this.finish();
+      }
+    }
+  },
+
+  finish: function finish() {
+    this._tasks[this._tasks.length - 1]();
+  },
+
+  run: function run() {
+    this.next();
+  }
+};
+
+let mozMobileMessage;
+
+function getAllMessages(callback, filter, reverse) {
+  if (!filter) {
+    filter = new MozSmsFilter;
+  }
+  let messages = [];
+  let request = mozMobileMessage.getMessages(filter, reverse || false);
+  request.onsuccess = function(event) {
+    if (request.result) {
+      messages.push(request.result);
+      request.continue();
+      return;
+    }
+
+    window.setTimeout(callback.bind(null, messages), 0);
+  }
+}
+
+function deleteAllMessages() {
+  getAllMessages(function deleteAll(messages) {
+    let message = messages.shift();
+    if (!message) {
+      ok(true, "all messages deleted");
+      tasks.next();
+      return;
+    }
+
+    let request = mozMobileMessage.delete(message.id);
+    request.onsuccess = deleteAll.bind(null, messages);
+    request.onerror = function (event) {
+      ok(false, "failed to delete all messages");
+      tasks.finish();
+    }
+  });
+}
+
+tasks.push(function () {
+  log("Verifying initial state.");
+
+  mozMobileMessage = window.navigator.mozMobileMessage;
+  ok(mozMobileMessage instanceof MozMobileMessageManager);
+
+  tasks.next();
+});
+
+tasks.push(function () {
+  log("MmsMessage.attachments should be an empty array.");
+
+  mozMobileMessage.onfailed = function (event) {
+    mozMobileMessage.onfailed = null;
+
+    let message = event.message;
+    ok(Array.isArray(message.attachments) && message.attachments.length === 0,
+       "message.attachments should be an empty array.");
+
+    tasks.next();
+  };
+
+  // Have a long long subject causes the send fails, so we don't need
+  // networking here.
+  mozMobileMessage.sendMMS({
+    subject: new Array(MMS_MAX_LENGTH_SUBJECT + 2).join("a"),
+    receivers: ["1", "2"],
+    attachments: [],
+  });
+});
+
+tasks.push(deleteAllMessages);
+
+// WARNING: All tasks should be pushed before this!!!
+tasks.push(function cleanUp() {
+  SpecialPowers.removePermission("sms", document);
+  SpecialPowers.clearUserPref("dom.sms.enabled");
+  finish();
+});
+
+tasks.run();
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -74,16 +74,17 @@ const RIL_IPC_MSG_NAMES = [
   "RIL:NetworkSelectionModeChanged",
   "RIL:SelectNetwork",
   "RIL:SelectNetworkAuto",
   "RIL:CallStateChanged",
   "RIL:VoicemailNotification",
   "RIL:VoicemailInfoChanged",
   "RIL:CallError",
   "RIL:CardLockResult",
+  "RIL:CardLockRetryCount",
   "RIL:USSDReceived",
   "RIL:SendMMI:Return:OK",
   "RIL:SendMMI:Return:KO",
   "RIL:CancelMMI:Return:OK",
   "RIL:CancelMMI:Return:KO",
   "RIL:StkCommand",
   "RIL:StkSessionEnd",
   "RIL:DataError",
@@ -118,16 +119,27 @@ function MobileIccCardLockResult(options
 }
 MobileIccCardLockResult.prototype = {
   __exposedProps__ : {lockType: 'r',
                       enabled: 'r',
                       retryCount: 'r',
                       success: 'r'}
 };
 
+function MobileIccCardLockRetryCount(options) {
+  this.lockType = options.lockType;
+  this.retryCount = options.retryCount;
+  this.success = options.success;
+}
+MobileIccCardLockRetryCount.prototype = {
+  __exposedProps__ : {lockType: 'r',
+                      retryCount: 'r',
+                      success: 'r'}
+};
+
 function MobileICCInfo() {}
 MobileICCInfo.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozMobileICCInfo]),
   classID:        MOBILEICCINFO_CID,
   classInfo:      XPCOMUtils.generateCI({
     classID:          MOBILEICCINFO_CID,
     classDescription: "MobileICCInfo",
     flags:            Ci.nsIClassInfo.DOM_OBJECT,
@@ -645,16 +657,33 @@ RILContentHelper.prototype = {
     info.requestId = this.getRequestId(request);
     cpmm.sendAsyncMessage("RIL:SetCardLock", {
       clientId: 0,
       data: info
     });
     return request;
   },
 
+  getCardLockRetryCount: function getCardLockRetryCount(window, lockType) {
+    if (window == null) {
+      throw Components.Exception("Can't get window object",
+                                  Cr.NS_ERROR_UNEXPECTED);
+    }
+    let request = Services.DOMRequest.createRequest(window);
+    let requestId = this.getRequestId(request);
+    cpmm.sendAsyncMessage("RIL:GetCardLockRetryCount", {
+      clientId: 0,
+      data: {
+        lockType: lockType,
+        requestId: requestId
+      }
+    });
+    return request;
+  },
+
   sendMMI: function sendMMI(window, mmi) {
     // We need to save the global window to get the proper MMIError
     // constructor once we get the reply from the parent process.
     this._window = window;
 
     debug("Sending MMI " + mmi);
     if (!window) {
       throw Components.Exception("Can't get window object",
@@ -1373,16 +1402,24 @@ RILContentHelper.prototype = {
               msg.json.rilMessageType == "iccUnlockCardLock") {
             this._deliverEvent("_iccListeners",
                                "notifyIccCardLockError",
                                [msg.json.lockType, msg.json.retryCount]);
           }
           this.fireRequestError(msg.json.requestId, msg.json.errorMsg);
         }
         break;
+      case "RIL:CardLockRetryCount":
+        if (msg.json.success) {
+          let result = new MobileIccCardLockRetryCount(msg.json);
+          this.fireRequestSuccess(msg.json.requestId, result);
+        } else {
+          this.fireRequestError(msg.json.requestId, msg.json.errorMsg);
+        }
+        break;
       case "RIL:USSDReceived": {
         let data = msg.json.data;
         this._deliverEvent("_mobileConnectionListeners",
                            "notifyUssdReceived",
                            [data.message, data.sessionEnded]);
         break;
       }
       case "RIL:SendMMI:Return:OK":
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -110,16 +110,17 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES
 const RIL_IPC_ICCMANAGER_MSG_NAMES = [
   "RIL:SendStkResponse",
   "RIL:SendStkMenuSelection",
   "RIL:SendStkTimerExpiration",
   "RIL:SendStkEventDownload",
   "RIL:GetCardLockState",
   "RIL:UnlockCardLock",
   "RIL:SetCardLock",
+  "RIL:GetCardLockRetryCount",
   "RIL:IccOpenChannel",
   "RIL:IccExchangeAPDU",
   "RIL:IccCloseChannel",
   "RIL:ReadIccContacts",
   "RIL:UpdateIccContact",
   "RIL:RegisterIccMsg"
 ];
 
@@ -821,16 +822,20 @@ RadioInterface.prototype = {
       case "RIL:UnlockCardLock":
         gMessageManager.saveRequestTarget(msg);
         this.unlockCardLock(msg.json.data);
         break;
       case "RIL:SetCardLock":
         gMessageManager.saveRequestTarget(msg);
         this.setCardLock(msg.json.data);
         break;
+      case "RIL:GetCardLockRetryCount":
+        gMessageManager.saveRequestTarget(msg);
+        this.getCardLockRetryCount(msg.json.data);
+        break;
       case "RIL:SendMMI":
         gMessageManager.saveRequestTarget(msg);
         this.sendMMI(msg.json.data);
         break;
       case "RIL:CancelMMI":
         gMessageManager.saveRequestTarget(msg);
         this.cancelMMI(msg.json.data);
         break;
@@ -1020,16 +1025,19 @@ RadioInterface.prototype = {
       case "iccimsi":
         this.rilContext.imsi = message.imsi;
         break;
       case "iccGetCardLockState":
       case "iccSetCardLock":
       case "iccUnlockCardLock":
         this.handleIccCardLockResult(message);
         break;
+      case "iccGetCardLockRetryCount":
+        this.handleIccCardLockRetryCount(message);
+        break;
       case "icccontacts":
         this.handleReadIccContacts(message);
         break;
       case "icccontactupdate":
         this.handleUpdateIccContact(message);
         break;
       case "iccmbdn":
         this.handleIccMbdn(message);
@@ -2102,16 +2110,20 @@ RadioInterface.prototype = {
       }
     }
   },
 
   handleIccCardLockResult: function handleIccCardLockResult(message) {
     gMessageManager.sendRequestResults("RIL:CardLockResult", message);
   },
 
+  handleIccCardLockRetryCount: function handleIccCardLockRetryCount(message) {
+    gMessageManager.sendRequestResults("RIL:CardLockRetryCount", message);
+  },
+
   handleUSSDReceived: function handleUSSDReceived(ussd) {
     if (DEBUG) this.debug("handleUSSDReceived " + JSON.stringify(ussd));
     gSystemMessenger.broadcastMessage("ussd-received", ussd);
     gMessageManager.sendMobileConnectionMessage("RIL:USSDReceived",
                                                 this.clientId, ussd);
   },
 
   handleSendMMI: function handleSendMMI(message) {
@@ -3328,16 +3340,21 @@ RadioInterface.prototype = {
     this.worker.postMessage(message);
   },
 
   setCardLock: function setCardLock(message) {
     message.rilMessageType = "iccSetCardLock";
     this.worker.postMessage(message);
   },
 
+  getCardLockRetryCount: function getCardLockRetryCount(message) {
+    message.rilMessageType = "iccGetCardLockRetryCount";
+    this.worker.postMessage(message);
+  },
+
   readIccContacts: function readIccContacts(message) {
     message.rilMessageType = "readICCContacts";
     this.worker.postMessage(message);
   },
 
   updateIccContact: function updateIccContact(message) {
     message.rilMessageType = "updateICCContact";
     this.worker.postMessage(message);
--- a/dom/system/gonk/nsIVolume.idl
+++ b/dom/system/gonk/nsIVolume.idl
@@ -1,16 +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/. */
 
 #include "nsISupports.idl"
 #include "nsIVolumeStat.idl"
 
-[scriptable, uuid(1134f267-7b81-42f2-b64a-6edb91286576)]
+[scriptable, uuid(4b5bd562-bd05-4658-ab0f-f668a9e25fb5)]
 interface nsIVolume : nsISupports
 {
   // These MUST match the states from android's system/vold/Volume.h header
   const long STATE_INIT        = -1;
   const long STATE_NOMEDIA     = 0;
   const long STATE_IDLE        = 1;
   const long STATE_PENDING     = 2;
   const long STATE_CHECKING    = 3;
@@ -44,16 +44,19 @@ interface nsIVolume : nsISupports
   // every time the mountGeneration changes, so you'll need to reacquire
   // the wakelock every time the volume becomes mounted.
   readonly attribute DOMString mountLockName;
 
   // Determines if a mountlock is currently being held against this volume.
   readonly attribute boolean isMountLocked;
 
   nsIVolumeStat getStats();
+
+  // Whether this is a fake volume.
+  readonly attribute boolean isFake;
 };
 
 %{C++
 // For use with the ObserverService
 #define NS_VOLUME_STATE_CHANGED  "volume-state-changed"
 
 namespace mozilla {
 namespace system {
--- a/dom/system/gonk/nsIVolumeService.idl
+++ b/dom/system/gonk/nsIVolumeService.idl
@@ -7,27 +7,31 @@
 #include "nsIVolumeMountLock.idl"
 
 %{C++
 #include "nsTArray.h"
 #include "nsString.h"
 %}
 [ref] native nsStringTArrayRef(nsTArray<nsString>);
 
-[scriptable, uuid(7c179fb7-67a0-43a3-9337-294e0360b858)]
+[scriptable, uuid(a3b110cd-74f2-43cb-84c6-2a87713f2774)]
 interface nsIVolumeService : nsISupports
 {
     nsIVolume getVolumeByName(in DOMString volName);
     nsIVolume getVolumeByPath(in DOMString path);
     nsIVolume createOrGetVolumeByPath(in DOMString path);
 
     void BroadcastVolume(in DOMString volName);
 
     nsIVolumeMountLock createMountLock(in DOMString volName);
 
     [noscript] void getVolumeNames(in nsStringTArrayRef aVolNames);
+
+    /* for test case only to simulate sdcard insertion/removal */
+    void createFakeVolume(in DOMString name, in DOMString path);
+    void SetFakeVolumeState(in DOMString name, in long state);
 };
 
 %{C++
 #define NS_VOLUMESERVICE_CID \
   {0x7c179fb7, 0x67a0, 0x43a3, {0x93, 0x37, 0x29, 0x4e, 0x03, 0x60, 0xb8, 0x58}}
 #define NS_VOLUMESERVICE_CONTRACTID "@mozilla.org/telephony/volume-service;1"
 %}
--- a/dom/system/gonk/nsVolume.cpp
+++ b/dom/system/gonk/nsVolume.cpp
@@ -45,17 +45,18 @@ NS_VolumeStateStr(int32_t aState)
 // we use a thread safe AddRef implementation.
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsVolume, nsIVolume)
 
 nsVolume::nsVolume(const Volume* aVolume)
   : mName(NS_ConvertUTF8toUTF16(aVolume->Name())),
     mMountPoint(NS_ConvertUTF8toUTF16(aVolume->MountPoint())),
     mState(aVolume->State()),
     mMountGeneration(aVolume->MountGeneration()),
-    mMountLocked(aVolume->IsMountLocked())
+    mMountLocked(aVolume->IsMountLocked()),
+    mIsFake(false)
 {
 }
 
 bool nsVolume::Equals(nsIVolume* aVolume)
 {
   nsString volName;
   aVolume->GetName(volName);
   if (!mName.Equals(volName)) {
@@ -80,16 +81,23 @@ bool nsVolume::Equals(nsIVolume* aVolume
     return false;
   }
 
   bool volIsMountLocked;
   aVolume->GetIsMountLocked(&volIsMountLocked);
   if (mMountLocked != volIsMountLocked) {
     return false;
   }
+
+  bool isFake;
+  aVolume->GetIsFake(&isFake);
+  if (mIsFake != isFake) {
+    return false;
+  }
+
   return true;
 }
 
 NS_IMETHODIMP nsVolume::GetIsMountLocked(bool *aIsMountLocked)
 {
   *aIsMountLocked = mMountLocked;
   return NS_OK;
 }
@@ -131,16 +139,22 @@ NS_IMETHODIMP nsVolume::GetStats(nsIVolu
   if (mState != STATE_MOUNTED) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   NS_IF_ADDREF(*aResult = new nsVolumeStat(mMountPoint));
   return NS_OK;
 }
 
+NS_IMETHODIMP nsVolume::GetIsFake(bool *aIsFake)
+{
+  *aIsFake = mIsFake;
+  return NS_OK;
+}
+
 void
 nsVolume::LogState() const
 {
   if (mState == nsIVolume::STATE_MOUNTED) {
     LOG("nsVolume: %s state %s @ '%s' gen %d locked %d",
         NameStr().get(), StateStr(), MountPointStr().get(),
         MountGeneration(), (int)IsMountLocked());
     return;
@@ -151,16 +165,17 @@ nsVolume::LogState() const
 
 void nsVolume::Set(nsIVolume* aVolume)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   aVolume->GetName(mName);
   aVolume->GetMountPoint(mMountPoint);
   aVolume->GetState(&mState);
+  aVolume->GetIsFake(&mIsFake);
 
   int32_t volMountGeneration;
   aVolume->GetMountGeneration(&volMountGeneration);
 
   if (mState != nsIVolume::STATE_MOUNTED) {
     // Since we're not in the mounted state, we need to
     // forgot whatever mount generation we may have had.
     mMountGeneration = -1;
@@ -217,10 +232,30 @@ nsVolume::UpdateMountLock(bool aMountLoc
   LogState();
   XRE_GetIOMessageLoop()->PostTask(
      FROM_HERE,
      NewRunnableFunction(Volume::UpdateMountLock,
                          NS_LossyConvertUTF16toASCII(Name()),
                          MountGeneration(), aMountLocked));
 }
 
+void
+nsVolume::SetState(int32_t aState)
+{
+  static int32_t sMountGeneration = 0;
+
+  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(IsFake());
+
+  if (aState == mState) {
+    return;
+  }
+
+  if (aState == nsIVolume::STATE_MOUNTED) {
+    mMountGeneration = ++sMountGeneration;
+  }
+
+  mState = aState;
+}
+
 } // system
 } // mozilla
--- a/dom/system/gonk/nsVolume.h
+++ b/dom/system/gonk/nsVolume.h
@@ -27,27 +27,29 @@ public:
 
   // This constructor is used by ContentChild::RecvFileSystemUpdate
   nsVolume(const nsAString& aName, const nsAString& aMountPoint,
            const int32_t& aState, const int32_t& aMountGeneration)
     : mName(aName),
       mMountPoint(aMountPoint),
       mState(aState),
       mMountGeneration(aMountGeneration),
-      mMountLocked(false)
+      mMountLocked(false),
+      mIsFake(false)
   {
   }
 
   // This constructor is used by nsVolumeService::FindAddVolumeByName, and
   // will be followed shortly by a Set call.
   nsVolume(const nsAString& aName)
     : mName(aName),
       mState(STATE_INIT),
       mMountGeneration(-1),
-      mMountLocked(true)  // Needs to agree with Volume::Volume
+      mMountLocked(true),  // Needs to agree with Volume::Volume
+      mIsFake(false)
   {
   }
 
   bool Equals(nsIVolume* aVolume);
   void Set(nsIVolume* aVolume);
 
   void LogState() const;
 
@@ -67,19 +69,24 @@ public:
 
 private:
   ~nsVolume() {}
 
   friend class nsVolumeService; // Calls the following XxxMountLock functions
   void UpdateMountLock(const nsAString& aMountLockState);
   void UpdateMountLock(bool aMountLocked);
 
+  bool IsFake() const                 { return mIsFake; }
+  void SetIsFake(bool aIsFake)        { mIsFake = aIsFake; }
+  void SetState(int32_t aState);
+
   nsString mName;
   nsString mMountPoint;
   int32_t  mState;
   int32_t  mMountGeneration;
   bool     mMountLocked;
+  bool     mIsFake;
 };
 
 } // system
 } // mozilla
 
 #endif  // mozilla_system_nsvolume_h__
--- a/dom/system/gonk/nsVolumeService.cpp
+++ b/dom/system/gonk/nsVolumeService.cpp
@@ -321,52 +321,96 @@ nsVolumeService::FindVolumeByName(const 
       return vol.forget();
     }
   }
   return nullptr;
 }
 
 //static
 already_AddRefed<nsVolume>
-nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName)
+nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake /*= false*/)
 {
   MonitorAutoLock autoLock(mArrayMonitor);
 
   nsRefPtr<nsVolume> vol;
   vol = FindVolumeByName(aName);
   if (vol) {
     return vol.forget();
   }
   // Volume not found - add a new one
   vol = new nsVolume(aName);
+  vol->SetIsFake(aIsFake);
   mVolumeArray.AppendElement(vol);
   return vol.forget();
 }
 
 void
 nsVolumeService::UpdateVolume(nsIVolume* aVolume)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsString volName;
   aVolume->GetName(volName);
-  nsRefPtr<nsVolume> vol = CreateOrFindVolumeByName(volName);
+  bool aIsFake;
+  aVolume->GetIsFake(&aIsFake);
+  nsRefPtr<nsVolume> vol = CreateOrFindVolumeByName(volName, aIsFake);
   if (vol->Equals(aVolume)) {
     // Nothing has really changed. Don't bother telling anybody.
     return;
   }
+
+  if (!vol->IsFake() && aIsFake) {
+    // Prevent an incoming fake volume from overriding an existing real volume.
+    return;
+  }
+
   vol->Set(aVolume);
   nsCOMPtr<nsIObserverService> obs = GetObserverService();
   if (!obs) {
     return;
   }
   NS_ConvertUTF8toUTF16 stateStr(vol->StateStr());
   obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
 }
 
+NS_IMETHODIMP
+nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
+{
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    nsRefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_INIT, -1);
+    vol->SetIsFake(true);
+    UpdateVolume(vol.get());
+    return NS_OK;
+  }
+
+  ContentChild::GetSingleton()->SendCreateFakeVolume(nsString(name), nsString(path));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
+{
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    nsRefPtr<nsVolume> vol;
+    {
+      MonitorAutoLock autoLock(mArrayMonitor);
+      vol = FindVolumeByName(name);
+    }
+    if (!vol || !vol->IsFake()) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+    vol->SetState(state);
+    UpdateVolume(vol.get());
+    return NS_OK;
+  }
+
+  ContentChild::GetSingleton()->SendSetFakeVolumeState(nsString(name), state);
+  return NS_OK;
+}
+
 /***************************************************************************
 * The UpdateVolumeRunnable creates an nsVolume and updates the main thread
 * data structure while running on the main thread.
 */
 class UpdateVolumeRunnable : public nsRunnable
 {
 public:
   UpdateVolumeRunnable(nsVolumeService* aVolumeService, const Volume* aVolume)
--- a/dom/system/gonk/nsVolumeService.h
+++ b/dom/system/gonk/nsVolumeService.h
@@ -45,17 +45,17 @@ public:
 
 private:
   ~nsVolumeService();
 
   void CheckMountLock(const nsAString& aMountLockName,
                       const nsAString& aMountLockState);
   already_AddRefed<nsVolume> FindVolumeByMountLockName(const nsAString& aMountLockName);
   already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName);
-  already_AddRefed<nsVolume> CreateOrFindVolumeByName(const nsAString& aName);
+  already_AddRefed<nsVolume> CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake = false);
 
   Monitor mArrayMonitor;
   nsVolume::Array mVolumeArray;
 
   static StaticRefPtr<nsVolumeService> sSingleton;
 };
 
 } // system
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1192,16 +1192,46 @@ let RIL = {
     options.password = ""; // For query no need to provide pin.
     options.serviceClass = ICC_SERVICE_CLASS_VOICE |
                            ICC_SERVICE_CLASS_DATA  |
                            ICC_SERVICE_CLASS_FAX;
     this.queryICCFacilityLock(options);
   },
 
   /**
+   * Helper function for fetching the number of unlock retries of ICC locks.
+   */
+  iccGetCardLockRetryCount: function iccGetCardLockRetryCount(options) {
+    switch (options.lockType) {
+      case "pin":
+      case "puk":
+      case "pin2":
+      case "puk2":
+      case "nck":
+      case "cck":
+      case "spck":
+        options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
+        options.success = false;
+        this.sendDOMMessage(options);
+        return;
+      default:
+        options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
+        options.success = false;
+        this.sendDOMMessage(options);
+        return;
+    }
+
+    // TODO: We currently don't have a way for
+    // reading the retry count. See bug 868896.
+    options.retryCount = 0;
+    options.success = true;
+    this.sendDOMMessage(options);
+  },
+
+  /**
    * Query ICC facility lock.
    *
    * @param facility
    *        One of ICC_CB_FACILITY_*.
    * @param password
    *        Password for the facility, or "" if not required.
    * @param serviceClass
    *        One of ICC_SERVICE_CLASS_*.
--- a/dom/system/gonk/tests/marionette/manifest.ini
+++ b/dom/system/gonk/tests/marionette/manifest.ini
@@ -1,8 +1,9 @@
 [DEFAULT]
 b2g = true
 browser = false
 qemu = true
 
 [test_geolocation.js]
 disabled = Bug 808783
 [test_get_voicemailInfo.js]
+[test_fakevolume.js]
new file mode 100644
--- /dev/null
+++ b/dom/system/gonk/tests/marionette/test_fakevolume.js
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 10000;
+
+let Cc = SpecialPowers.Cc;
+let Ci = SpecialPowers.Ci;
+
+let volumeService = Cc["@mozilla.org/telephony/volume-service;1"].getService(Ci.nsIVolumeService);
+ok(volumeService, "Should have volume service");
+
+let volName = "fake";
+let mountPoint = "/data/fake/storage";
+volumeService.createFakeVolume(volName, mountPoint);
+
+let vol = volumeService.getVolumeByName(volName);
+ok(vol, "volume shouldn't be null");
+
+is(volName, vol.name, "name");
+is(mountPoint, vol.mountPoint, "moutnPoint");
+is(Ci.nsIVolume.STATE_INIT, vol.state, "state");
+
+
+let oldMountGen = vol.mountGeneration;
+volumeService.SetFakeVolumeState(volName, Ci.nsIVolume.STATE_MOUNTED);
+is(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state");
+ok(vol.mountGeneration > oldMountGen, "mount generation should be incremented");
+
+finish();
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -11,17 +11,16 @@
  * http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#sec-document-interface
  * http://dev.w3.org/csswg/cssom/#extensions-to-the-document-interface
  * http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
  *
  * http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMDocument.idl
  */
 
 interface StyleSheetList;
-interface TouchList;
 interface WindowProxy;
 interface nsISupports;
 
 enum VisibilityState { "hidden", "visible" };
 
 /* http://dom.spec.whatwg.org/#interface-document */
 [Constructor]
 interface Document : Node {
--- a/dom/webidl/HTMLTableElement.webidl
+++ b/dom/webidl/HTMLTableElement.webidl
@@ -19,17 +19,17 @@ interface HTMLTableElement : HTMLElement
            attribute HTMLTableSectionElement? tHead;
   HTMLElement createTHead();
   void deleteTHead();
            [SetterThrows]
            attribute HTMLTableSectionElement? tFoot;
   HTMLElement createTFoot();
   void deleteTFoot();
   readonly attribute HTMLCollection tBodies;
-  //HTMLElement createTBody();
+  HTMLElement createTBody();
   readonly attribute HTMLCollection rows;
   [Throws]
   HTMLElement insertRow(optional long index = -1);
   [Throws]
   void deleteRow(long index);
   //         attribute boolean sortable;
   //void stopSorting();
 };
--- a/dom/webidl/TouchEvent.webidl
+++ b/dom/webidl/TouchEvent.webidl
@@ -1,15 +1,14 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-interface TouchList;
 interface WindowProxy;
 
 [PrefControlled]
 interface TouchEvent : UIEvent {
   readonly attribute TouchList touches;
   readonly attribute TouchList targetTouches;
   readonly attribute TouchList changedTouches;
 
--- a/dom/webidl/TouchList.webidl
+++ b/dom/webidl/TouchList.webidl
@@ -1,17 +1,23 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
- * http://dvcs.w3.org/hg/webevents/raw-file/default/touchevents.html
+ * https://dvcs.w3.org/hg/webevents/raw-file/v1/touchevents.html
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
+[PrefControlled]
 interface TouchList {
+  [Pure]
   readonly attribute unsigned long length;
   getter Touch? item(unsigned long index);
-  Touch identifiedTouch(long identifier);
 };
+
+/* Mozilla extension. */
+partial interface TouchList {
+  Touch? identifiedTouch(long identifier);
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -342,16 +342,17 @@ webidl_files = \
   TextTrack.webidl \
   TextTrackCue.webidl \
   TextTrackCueList.webidl \
   TextTrackList.webidl \
   TimeEvent.webidl \
   TimeRanges.webidl \
   Touch.webidl \
   TouchEvent.webidl \
+  TouchList.webidl \
   TransitionEvent.webidl \
   TreeColumns.webidl \
   TreeWalker.webidl \
   UIEvent.webidl \
   UndoManager.webidl \
   URL.webidl \
   URLUtils.webidl \
   ValidityState.webidl \
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -502,20 +502,24 @@ var WifiManager = (function() {
   function getMacAddressCommand(callback) {
     doStringCommand("DRIVER MACADDR", function(reply) {
       if (reply)
         reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX
       callback(reply);
     });
   }
 
-  function setPowerModeCommand(mode, callback) {
+  function setPowerModeCommandICS(mode, callback) {
     doBooleanCommand("DRIVER POWERMODE " + (mode === "AUTO" ? 0 : 1), "OK", callback);
   }
 
+  function setPowerModeCommandJB(mode, callback) {
+    doBooleanCommand("SET ps " + (mode === "AUTO" ? 1 : 0), "OK", callback);
+  }
+
   function getPowerModeCommand(callback) {
     doStringCommand("DRIVER GETPOWER", function(reply) {
       if (reply)
         reply = (reply.split()[2]|0); // Format: powermode = XX
       callback(reply);
     });
   }
 
@@ -1503,17 +1507,19 @@ var WifiManager = (function() {
   manager.setScanMode = function(mode, callback) {
     setScanModeCommand(mode === "active", callback);
   }
   manager.setBackgroundScan = setBackgroundScan;
   manager.scan = scanCommand;
   manager.wpsPbc = wpsPbcCommand;
   manager.wpsPin = wpsPinCommand;
   manager.wpsCancel = wpsCancelCommand;
-  manager.setPowerMode = setPowerModeCommand;
+  manager.setPowerMode = (sdkVersion >= 16)
+                         ? setPowerModeCommandJB
+                         : setPowerModeCommandICS;
   manager.setSuspendOptimizations = setSuspendOptimizationsCommand;
   manager.setStaticIpMode = setStaticIpMode;
   manager.getRssiApprox = getRssiApproxCommand;
   manager.getLinkSpeed = getLinkSpeedCommand;
   manager.getDhcpInfo = function() { return dhcpInfo; }
   manager.getConnectionInfo = (sdkVersion >= 15)
                               ? getConnectionInfoICS
                               : getConnectionInfoGB;
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -1729,62 +1729,67 @@ nsEditor::InsertContainerAbove(nsIConten
   res = InsertNode(newContent->AsDOMNode(), parent->AsDOMNode(), offset);
   newContent.forget(aOutNode);
   return res;  
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // MoveNode:  move aNode to {aParent,aOffset}
 nsresult
-nsEditor::MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset)
-{
-  MOZ_ASSERT(aNode && aParent);
-  MOZ_ASSERT(aOffset == -1 || (0 <= aOffset &&
-                               aOffset <= (int32_t)aParent->Length()));
-  nsresult res = MoveNode(aNode->AsDOMNode(), aParent->AsDOMNode(), aOffset);
-  NS_ASSERTION(NS_SUCCEEDED(res), "MoveNode failed");
-  NS_ENSURE_SUCCESS(res, res);
-  return NS_OK;
+nsEditor::MoveNode(nsIDOMNode* aNode, nsIDOMNode* aParent, int32_t aOffset)
+{
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  NS_ENSURE_STATE(node);
+
+  nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
+  NS_ENSURE_STATE(parent);
+
+  return MoveNode(node, parent, aOffset);
 }
 
 nsresult
-nsEditor::MoveNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset)
-{
-  NS_ENSURE_TRUE(aNode && aParent, NS_ERROR_NULL_POINTER);
-  nsresult res;
+nsEditor::MoveNode(nsINode* aNode, nsINode* aParent, int32_t aOffset)
+{
+  MOZ_ASSERT(aNode);
+  MOZ_ASSERT(aParent);
+  MOZ_ASSERT(aOffset == -1 ||
+             (0 <= aOffset && SafeCast<uint32_t>(aOffset) <= aParent->Length()));
 
   int32_t oldOffset;
-  nsCOMPtr<nsIDOMNode> oldParent = GetNodeLocation(aNode, &oldOffset);
+  nsCOMPtr<nsINode> oldParent = GetNodeLocation(aNode, &oldOffset);
   
-  if (aOffset == -1)
-  {
-    uint32_t unsignedOffset;
-    // magic value meaning "move to end of aParent"
-    res = GetLengthOfDOMNode(aParent, unsignedOffset);
-    NS_ENSURE_SUCCESS(res, res);
-    aOffset = (int32_t)unsignedOffset;
+  if (aOffset == -1) {
+    // Magic value meaning "move to end of aParent".
+    aOffset = SafeCast<int32_t>(aParent->Length());
+  }
+  
+  // Don't do anything if it's already in right place.
+  if (aParent == oldParent && aOffset == oldOffset) {
+    return NS_OK;
   }
   
-  // don't do anything if it's already in right place
-  if ((aParent == oldParent.get()) && (oldOffset == aOffset)) return NS_OK;
-  
-  // notify our internal selection state listener
-  nsAutoMoveNodeSelNotify selNotify(mRangeUpdater, oldParent, oldOffset, aParent, aOffset);
+  // Notify our internal selection state listener.
+  nsAutoMoveNodeSelNotify selNotify(mRangeUpdater, oldParent, oldOffset,
+                                    aParent, aOffset);
   
-  // need to adjust aOffset if we are moving aNode further along in its current parent
-  if ((aParent == oldParent.get()) && (oldOffset < aOffset)) 
-  {
-    aOffset--;  // this is because when we delete aNode, it will make the offsets after it off by one
+  // Need to adjust aOffset if we are moving aNode further along in its current
+  // parent.
+  if (aParent == oldParent && oldOffset < aOffset) {
+    // This is because when we delete aNode, it will make the offsets after it
+    // off by one.
+    aOffset--;
   }
 
-  // Hold a reference so aNode doesn't go away when we remove it (bug 772282)
-  nsCOMPtr<nsIDOMNode> node = aNode;
-  res = DeleteNode(node);
-  NS_ENSURE_SUCCESS(res, res);
-  return InsertNode(node, aParent, aOffset);
+  // Hold a reference so aNode doesn't go away when we remove it (bug 772282).
+  nsCOMPtr<nsINode> kungFuDeathGrip = aNode;
+
+  nsresult rv = DeleteNode(aNode);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return InsertNode(aNode->AsDOMNode(), aParent->AsDOMNode(), aOffset);
 }
 
 
 NS_IMETHODIMP
 nsEditor::AddEditorObserver(nsIEditorObserver *aObserver)
 {
   // we don't keep ownership of the observers.  They must
   // remove themselves as observers before they are destroyed.
@@ -3068,16 +3073,32 @@ nsEditor::GetNodeLocation(nsIDOMNode* aC
     aChild->GetParentNode(getter_AddRefs(parent))));
   if (parent) {
     *outOffset = GetChildOffset(aChild, parent);
   }
 
   return parent.forget();
 }
 
+nsINode*
+nsEditor::GetNodeLocation(nsINode* aChild, int32_t* aOffset)
+{
+  MOZ_ASSERT(aChild);
+  MOZ_ASSERT(aOffset);
+
+  nsINode* parent = aChild->GetParentNode();
+  if (parent) {
+    *aOffset = parent->IndexOf(aChild);
+    MOZ_ASSERT(*aOffset != -1);
+  } else {
+    *aOffset = -1;
+  }
+  return parent;
+}
+
 // returns the number of things inside aNode.  
 // If aNode is text, returns number of characters. If not, returns number of children nodes.
 nsresult
 nsEditor::GetLengthOfDOMNode(nsIDOMNode *aNode, uint32_t &aCount) 
 {
   aCount = 0;
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -225,17 +225,17 @@ public:
                                 const nsAString* aAttribute = nullptr,
                                 const nsAString* aValue = nullptr);
   nsresult InsertContainerAbove(nsIDOMNode *inNode, 
                                 nsCOMPtr<nsIDOMNode> *outNode, 
                                 const nsAString &aNodeType,
                                 const nsAString *aAttribute = nullptr,
                                 const nsAString *aValue = nullptr);
   nsresult JoinNodes(nsINode* aNodeToKeep, nsIContent* aNodeToMove);
-  nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset);
+  nsresult MoveNode(nsINode* aNode, nsINode* aParent, int32_t aOffset);
   nsresult MoveNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset);
 
   /* Method to replace certain CreateElementNS() calls. 
      Arguments:
       nsString& aTag          - tag you want
       nsIContent** aContent   - returned Content that was created with above namespace.
   */
   nsresult CreateHTMLContent(const nsAString& aTag,
@@ -466,16 +466,17 @@ public:
                                 nsIDOMNode *aParent);
 
   /**
    *  Set outOffset to the offset of aChild in the parent.
    *  Returns the parent of aChild.
    */
   static already_AddRefed<nsIDOMNode> GetNodeLocation(nsIDOMNode* aChild,
                                                       int32_t* outOffset);
+  static nsINode* GetNodeLocation(nsINode* aChild, int32_t* aOffset);
 
   /** returns the number of things inside aNode in the out-param aCount.  
     * @param  aNode is the node to get the length of.  
     *         If aNode is text, returns number of characters. 
     *         If not, returns number of children nodes.
     * @param  aCount [OUT] the result of the above calculation.
     */
   static nsresult GetLengthOfDOMNode(nsIDOMNode *aNode, uint32_t &aCount);
--- a/editor/libeditor/base/nsSelectionState.cpp
+++ b/editor/libeditor/base/nsSelectionState.cpp
@@ -587,57 +587,55 @@ nsresult
 nsRangeUpdater::DidInsertContainer()
 {
   NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);  
   mLock = false;
   return NS_OK;
 }
 
 
-nsresult
+void
 nsRangeUpdater::WillMoveNode()
 {
-  if (mLock) return NS_ERROR_UNEXPECTED;  
   mLock = true;
-  return NS_OK;
 }
 
 
-nsresult
-nsRangeUpdater::DidMoveNode(nsIDOMNode *aOldParent, int32_t aOldOffset, nsIDOMNode *aNewParent, int32_t aNewOffset)
+void
+nsRangeUpdater::DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
+                            nsINode* aNewParent, int32_t aNewOffset)
 {
-  NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);  
+  MOZ_ASSERT(aOldParent);
+  MOZ_ASSERT(aNewParent);
+  NS_ENSURE_TRUE_VOID(mLock);
   mLock = false;
 
-  NS_ENSURE_TRUE(aOldParent && aNewParent, NS_ERROR_NULL_POINTER);
-  uint32_t i, count = mArray.Length();
-  if (!count) {
-    return NS_OK;
-  }
+  nsIDOMNode* oldParent = aOldParent->AsDOMNode();
+  nsIDOMNode* newParent = aNewParent->AsDOMNode();
 
-  nsRangeStore *item;
-  
-  for (i=0; i<count; i++)
-  {
-    item = mArray[i];
-    NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
+  for (uint32_t i = 0, count = mArray.Length(); i < count; ++i) {
+    nsRangeStore* item = mArray[i];
+    NS_ENSURE_TRUE_VOID(item);
     
     // like a delete in aOldParent
-    if ((item->startNode.get() == aOldParent) && (item->startOffset > aOldOffset))
+    if (item->startNode == oldParent && item->startOffset > aOldOffset) {
       item->startOffset--;
-    if ((item->endNode.get() == aOldParent) && (item->endOffset > aOldOffset))
+    }
+    if (item->endNode == oldParent && item->endOffset > aOldOffset) {
       item->endOffset--;
+    }
       
     // and like an insert in aNewParent
-    if ((item->startNode.get() == aNewParent) && (item->startOffset > aNewOffset))
+    if (item->startNode == newParent && item->startOffset > aNewOffset) {
       item->startOffset++;
-    if ((item->endNode.get() == aNewParent) && (item->endOffset > aNewOffset))
+    }
+    if (item->endNode == newParent && item->endOffset > aNewOffset) {
       item->endOffset++;
+    }
   }
-  return NS_OK;
 }
 
 
 
 /***************************************************************************
  * helper class for nsSelectionState.  nsRangeStore stores range endpoints.
  */
 
--- a/editor/libeditor/base/nsSelectionState.h
+++ b/editor/libeditor/base/nsSelectionState.h
@@ -97,18 +97,19 @@ class nsRangeUpdater
     // the following gravity routines need will/did sandwiches, because the other gravity
     // routines will be called inside of these sandwiches, but should be ignored.
     nsresult WillReplaceContainer();
     nsresult DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode);
     nsresult WillRemoveContainer();
     nsresult DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset, uint32_t aNodeOrigLen);
     nsresult WillInsertContainer();
     nsresult DidInsertContainer();
-    nsresult WillMoveNode();
-    nsresult DidMoveNode(nsIDOMNode *aOldParent, int32_t aOldOffset, nsIDOMNode *aNewParent, int32_t aNewOffset);
+    void WillMoveNode();
+    void DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
+                     nsINode* aNewParent, int32_t aNewOffset);
   protected:    
     nsTArray<nsRefPtr<nsRangeStore> > mArray;
     bool mLock;
 };
 
 
 /***************************************************************************
  * helper class for using nsSelectionState.  stack based class for doing
@@ -237,33 +238,35 @@ class MOZ_STACK_CLASS nsAutoInsertContai
  * another helper class for nsSelectionState.  stack based class for doing
  * Will/DidMoveNode()
  */
 
 class MOZ_STACK_CLASS nsAutoMoveNodeSelNotify
 {
   private:
     nsRangeUpdater &mRU;
-    nsIDOMNode *mOldParent;
-    nsIDOMNode *mNewParent;
+    nsINode* mOldParent;
+    nsINode* mNewParent;
     int32_t    mOldOffset;
     int32_t    mNewOffset;
 
   public:
     nsAutoMoveNodeSelNotify(nsRangeUpdater &aRangeUpdater, 
-                            nsIDOMNode *aOldParent, 
+                            nsINode* aOldParent,
                             int32_t aOldOffset, 
-                            nsIDOMNode *aNewParent, 
-                            int32_t aNewOffset) :
-    mRU(aRangeUpdater)
-    ,mOldParent(aOldParent)
-    ,mNewParent(aNewParent)
-    ,mOldOffset(aOldOffset)
-    ,mNewOffset(aNewOffset)
+                            nsINode* aNewParent,
+                            int32_t aNewOffset)
+      : mRU(aRangeUpdater)
+      , mOldParent(aOldParent)
+      , mNewParent(aNewParent)
+      , mOldOffset(aOldOffset)
+      , mNewOffset(aNewOffset)
     {
+      MOZ_ASSERT(aOldParent);
+      MOZ_ASSERT(aNewParent);
       mRU.WillMoveNode();
     }
     
     ~nsAutoMoveNodeSelNotify()
     {
       mRU.DidMoveNode(mOldParent, mOldOffset, mNewParent, mNewOffset);
     }
 };
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -263,17 +263,17 @@ AsyncPanZoomController::ReceiveInputEven
   default:
     status = nsEventStatus_eIgnore;
     break;
   }
 
   switch (aEvent.eventStructType) {
   case NS_TOUCH_EVENT: {
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aOutEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       nsIDOMTouch* touch = touches[i];
       if (touch) {
         CSSPoint refPoint = WidgetSpaceToCompensatedViewportSpace(
           ScreenPoint::FromUnknownPoint(gfx::Point(
             touch->mRefPoint.x, touch->mRefPoint.y)),
           currentResolution);
         touch->mRefPoint = nsIntPoint(refPoint.x, refPoint.y);
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -955,17 +955,17 @@ NS_IMETHODIMP imgLoader::FindEntryProper
 
   uri->GetSpec(spec);
   *_retval = nullptr;
 
   if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
     if (mCacheTracker && entry->HasNoProxies())
       mCacheTracker->MarkUsed(entry);
 
-    nsRefPtr<imgRequest> request = getter_AddRefs(entry->GetRequest());
+    nsRefPtr<imgRequest> request = entry->GetRequest();
     if (request) {
       *_retval = request->Properties();
       NS_ADDREF(*_retval);
     }
   }
 
   return NS_OK;
 }
@@ -1002,17 +1002,17 @@ bool imgLoader::PutIntoCache(nsIURI *key
 
   // Check to see if this request already exists in the cache and is being
   // loaded on a different thread. If so, don't allow this entry to be added to
   // the cache.
   nsRefPtr<imgCacheEntry> tmpCacheEntry;
   if (cache.Get(spec, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
     PR_LOG(GetImgLog(), PR_LOG_DEBUG,
            ("[this=%p] imgLoader::PutIntoCache -- Element already in the cache", nullptr));
-    nsRefPtr<imgRequest> tmpRequest = getter_AddRefs(tmpCacheEntry->GetRequest());
+    nsRefPtr<imgRequest> tmpRequest = tmpCacheEntry->GetRequest();
 
     // If it already exists, and we're putting the same key into the cache, we
     // should remove the old version.
     PR_LOG(GetImgLog(), PR_LOG_DEBUG,
            ("[this=%p] imgLoader::PutIntoCache -- Replacing cached element", nullptr));
 
     RemoveFromCache(key);
   } else {
@@ -1035,17 +1035,17 @@ bool imgLoader::PutIntoCache(nsIURI *key
       addrv = mCacheTracker->AddObject(entry);
 
     if (NS_SUCCEEDED(addrv)) {
       imgCacheQueue &queue = GetCacheQueue(key);
       queue.Push(entry);
     }
   }
 
-  nsRefPtr<imgRequest> request(getter_AddRefs(entry->GetRequest()));
+  nsRefPtr<imgRequest> request = entry->GetRequest();
   request->SetIsInCache(true);
 
   return true;
 }
 
 bool imgLoader::SetHasNoProxies(nsIURI *key, imgCacheEntry *entry)
 {
 #if defined(PR_LOGGING)
@@ -1404,30 +1404,30 @@ bool imgLoader::RemoveFromCache(nsIURI *
     if (entry->HasNoProxies()) {
       if (mCacheTracker)
         mCacheTracker->RemoveObject(entry);
       queue.Remove(entry);
     }
 
     entry->SetEvicted(true);
 
-    nsRefPtr<imgRequest> request(getter_AddRefs(entry->GetRequest()));
+    nsRefPtr<imgRequest> request = entry->GetRequest();
     request->SetIsInCache(false);
 
     return true;
   }
   else
     return false;
 }
 
 bool imgLoader::RemoveFromCache(imgCacheEntry *entry)
 {
   LOG_STATIC_FUNC(GetImgLog(), "imgLoader::RemoveFromCache entry");
 
-  nsRefPtr<imgRequest> request(getter_AddRefs(entry->GetRequest()));
+  nsRefPtr<imgRequest> request = entry->GetRequest();
   if (request) {
     nsCOMPtr<nsIURI> key;
     if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(key))) && key) {
       imgCacheTable &cache = GetCache(key);
       imgCacheQueue &queue = GetCacheQueue(key);
       nsAutoCString spec;
       key->GetSpec(spec);
 
@@ -1620,17 +1620,17 @@ nsresult imgLoader::LoadImage(nsIURI *aU
   // for correctly dealing with image load requests that are a result
   // of post data.
   imgCacheTable &cache = GetCache(aURI);
 
   if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
     if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
                       aLoadGroup, aObserver, aCX, requestFlags, true,
                       _retval, aPolicy, aLoadingPrincipal, corsmode)) {
-      request = getter_AddRefs(entry->GetRequest());
+      request = entry->GetRequest();
 
       // If this entry has no proxies, its request has no reference to the entry.
       if (entry->HasNoProxies()) {
         LOG_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::LoadImage() adding proxyless entry", "uri", spec.get());
         NS_ABORT_IF_FALSE(!request->HasCacheEntry(), "Proxyless entry's request has cache entry!");
         request->SetCacheEntry(entry);
 
         if (mCacheTracker)
@@ -1846,30 +1846,30 @@ nsresult imgLoader::LoadImageWithChannel
       // it says that the entry isn't valid any more, we'll only use the entry
       // we're getting if the channel is loading from the cache anyways.
       //
       // XXX -- should this be changed? it's pretty much verbatim from the old
       // code, but seems nonsensical.
       if (ValidateEntry(entry, uri, nullptr, nullptr, nullptr, aObserver, aCX,
                         requestFlags, false, nullptr, nullptr, nullptr,
                         imgIRequest::CORS_NONE)) {
-        request = getter_AddRefs(entry->GetRequest());
+        request = entry->GetRequest();
       } else {
         nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(channel));
         bool bUseCacheCopy;
 
         if (cacheChan)
           cacheChan->IsFromCache(&bUseCacheCopy);
         else
           bUseCacheCopy = false;
 
-        if (!bUseCacheCopy)
+        if (!bUseCacheCopy) {
           entry = nullptr;
-        else {
-          request = getter_AddRefs(entry->GetRequest());
+        } else {
+          request = entry->GetRequest();
         }
       }
 
       if (request && entry) {
         // If this entry has no proxies, its request has no reference to the entry.
         if (entry->HasNoProxies()) {
           LOG_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::LoadImageWithChannel() adding proxyless entry", "uri", spec.get());
           NS_ABORT_IF_FALSE(!request->HasCacheEntry(), "Proxyless entry's request has cache entry!");
--- a/ipc/chromium/src/base/basictypes.h
+++ b/ipc/chromium/src/base/basictypes.h
@@ -231,82 +231,16 @@ typedef uint32_t MetatagId;
 // Argument type used in interfaces that can optionally take ownership
 // of a passed in argument.  If TAKE_OWNERSHIP is passed, the called
 // object takes ownership of the argument.  Otherwise it does not.
 enum Ownership {
   DO_NOT_TAKE_OWNERSHIP,
   TAKE_OWNERSHIP
 };
 
-// bit_cast<Dest,Source> is a template function that implements the
-// equivalent of "*reinterpret_cast<Dest*>(&source)".  We need this in
-// very low-level functions like the protobuf library and fast math
-// support.
-//
-//   float f = 3.14159265358979;
-//   int i = bit_cast<int32_t>(f);
-//   // i = 0x40490fdb
-//
-// The classical address-casting method is:
-//
-//   // WRONG
-//   float f = 3.14159265358979;            // WRONG
-//   int i = * reinterpret_cast<int*>(&f);  // WRONG
-//
-// The address-casting method actually produces undefined behavior
-// according to ISO C++ specification section 3.10 -15 -.  Roughly, this
-// section says: if an object in memory has one type, and a program
-// accesses it with a different type, then the result is undefined
-// behavior for most values of "different type".
-//
-// This is true for any cast syntax, either *(int*)&f or
-// *reinterpret_cast<int*>(&f).  And it is particularly true for
-// conversions betweeen integral lvalues and floating-point lvalues.
-//
-// The purpose of 3.10 -15- is to allow optimizing compilers to assume
-// that expressions with different types refer to different memory.  gcc
-// 4.0.1 has an optimizer that takes advantage of this.  So a
-// non-conforming program quietly produces wildly incorrect output.
-//
-// The problem is not the use of reinterpret_cast.  The problem is type
-// punning: holding an object in memory of one type and reading its bits
-// back using a different type.
-//
-// The C++ standard is more subtle and complex than this, but that
-// is the basic idea.
-//
-// Anyways ...
-//
-// bit_cast<> calls memcpy() which is blessed by the standard,
-// especially by the example in section 3.9 .  Also, of course,
-// bit_cast<> wraps up the nasty logic in one place.
-//
-// Fortunately memcpy() is very fast.  In optimized mode, with a
-// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
-// code with the minimal amount of data movement.  On a 32-bit system,
-// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
-// compiles to two loads and two stores.
-//
-// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
-//
-// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
-// is likely to surprise you.
-
-template <class Dest, class Source>
-inline Dest bit_cast(const Source& source) {
-  // Compile time assertion: sizeof(Dest) == sizeof(Source)
-  // A compile error here means your Dest and Source have different sizes.
-  MOZ_STATIC_ASSERT(sizeof(Dest) == sizeof(Source),
-                    "Only bit-cast between identically-sized types!");
-
-  Dest dest;
-  memcpy(&dest, &source, sizeof(dest));
-  return dest;
-}
-
 // The following enum should be used only as a constructor argument to indicate
 // that the variable has static storage class, and that the constructor should
 // do nothing to its state.  It indicates to the reader that it is legal to
 // declare a static instance of the class, provided the constructor is given
 // the base::LINKER_INITIALIZED argument.  Normally, it is unsafe to declare a
 // static variable that has a constructor or a destructor because invocation
 // order is undefined.  However, IF the type can be initialized by filling with
 // zeroes (which the loader does for static variables), AND the destructor also
--- a/ipc/chromium/src/base/time_win.cc
+++ b/ipc/chromium/src/base/time_win.cc
@@ -41,39 +41,41 @@
 #include <mmsystem.h>
 
 #include "base/basictypes.h"
 #include "base/lock.h"
 #include "base/logging.h"
 #include "base/cpu.h"
 #include "base/singleton.h"
 #include "base/system_monitor.h"
+#include "mozilla/Casting.h"
 
 using base::Time;
 using base::TimeDelta;
 using base::TimeTicks;
+using mozilla::BitwiseCast;
 
 namespace {
 
 // From MSDN, FILETIME "Contains a 64-bit value representing the number of
 // 100-nanosecond intervals since January 1, 1601 (UTC)."
 int64_t FileTimeToMicroseconds(const FILETIME& ft) {
-  // Need to bit_cast to fix alignment, then divide by 10 to convert
+  // Need to BitwiseCast to fix alignment, then divide by 10 to convert
   // 100-nanoseconds to milliseconds. This only works on little-endian
   // machines.
-  return bit_cast<int64_t, FILETIME>(ft) / 10;
+  return BitwiseCast<int64_t>(ft) / 10;
 }
 
 void MicrosecondsToFileTime(int64_t us, FILETIME* ft) {
   DCHECK(us >= 0) << "Time is less than 0, negative values are not "
       "representable in FILETIME";
 
-  // Multiply by 10 to convert milliseconds to 100-nanoseconds. Bit_cast will
+  // Multiply by 10 to convert milliseconds to 100-nanoseconds. BitwiseCast will
   // handle alignment problems. This only works on little-endian machines.
-  *ft = bit_cast<FILETIME, int64_t>(us * 10);
+  *ft = BitwiseCast<FILETIME>(us * 10);
 }
 
 int64_t CurrentWallclockMicroseconds() {
   FILETIME ft;
   ::GetSystemTimeAsFileTime(&ft);
   return FileTimeToMicroseconds(ft);
 }
 
--- a/ipc/chromium/src/chrome/common/ipc_channel.h
+++ b/ipc/chromium/src/chrome/common/ipc_channel.h
@@ -108,16 +108,20 @@ class Channel : public Message::Sender {
   //
   // If the kTestingChannelID flag is specified on the command line then
   // a named FIFO is used as the channel transport mechanism rather than a
   // socketpair() in which case this method returns -1 for both parameters.
   void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const;
 
   // Return the server side of the socketpair.
   int GetServerFileDescriptor() const;
+
+  // Close the client side of the socketpair.
+  void CloseClientFileDescriptor();
+
 #elif defined(OS_WIN)
   // Return the server pipe handle.
   void* GetServerPipeHandle() const;
 #endif  // defined(OS_POSIX)
 
  private:
   // PIMPL to which all channel calls are delegated.
   class ChannelImpl;
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -774,16 +774,24 @@ bool Channel::ChannelImpl::Send(Message*
 
 void Channel::ChannelImpl::GetClientFileDescriptorMapping(int *src_fd,
                                                           int *dest_fd) const {
   DCHECK(mode_ == MODE_SERVER);
   *src_fd = client_pipe_;
   *dest_fd = kClientChannelFd;
 }
 
+void Channel::ChannelImpl::CloseClientFileDescriptor() {
+  if (client_pipe_ != -1) {
+    Singleton<PipeMap>()->Remove(pipe_name_);
+    HANDLE_EINTR(close(client_pipe_));
+    client_pipe_ = -1;
+  }
+}
+
 // Called by libevent when we can read from th pipe without blocking.
 void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) {
   bool send_server_hello_msg = false;
   if (waiting_connect_ && mode_ == MODE_SERVER) {
     // In the case of a socketpair() the server starts listening on its end
     // of the pipe in Connect().
     DCHECK(uses_fifo_);
 
@@ -939,9 +947,13 @@ bool Channel::Send(Message* message) {
 void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const {
   return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd);
 }
 
 int Channel::GetServerFileDescriptor() const {
   return channel_impl_->GetServerFileDescriptor();
 }
 
+void Channel::CloseClientFileDescriptor() {
+  channel_impl_->CloseClientFileDescriptor();
+}
+
 }  // namespace IPC
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.h
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.h
@@ -35,16 +35,17 @@ class Channel::ChannelImpl : public Mess
     return old;
   }
   bool Send(Message* message);
   void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const;
   int GetServerFileDescriptor() const {
     DCHECK(mode_ == MODE_SERVER);
     return pipe_;
   }
+  void CloseClientFileDescriptor();
 
  private:
   void Init(Mode mode, Listener* listener);
   bool CreatePipe(const std::wstring& channel_id, Mode mode);
   bool EnqueueHelloMessage();
 
   bool ProcessIncomingMessages();
   bool ProcessOutgoingMessages();
--- a/ipc/dbus/DBusUtils.cpp
+++ b/ipc/dbus/DBusUtils.cpp
@@ -622,17 +622,16 @@ int dbus_returns_int32(DBusMessage *repl
 
   dbus_error_init(&err);
   if (!dbus_message_get_args(reply, &err,
                              DBUS_TYPE_INT32, &ret,
                              DBUS_TYPE_INVALID)) {
     LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
   }
 
-  dbus_message_unref(reply);
   return ret;
 }
 
 int dbus_returns_uint32(DBusMessage *reply)
 {
   DBusError err;
   uint32_t ret = -1;
 
@@ -642,10 +641,20 @@ int dbus_returns_uint32(DBusMessage *rep
                              DBUS_TYPE_INVALID)) {
     LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
   }
 
   dbus_message_unref(reply);
   return ret;
 }
 
+void DBusReplyHandler::Callback(DBusMessage* aReply, void* aData)
+{
+  MOZ_ASSERT(aData);
+
+  nsRefPtr<DBusReplyHandler> handler =
+    already_AddRefed<DBusReplyHandler>(static_cast<DBusReplyHandler*>(aData));
+
+  handler->Handle(aReply);
+}
+
 }
 }
--- a/ipc/dbus/DBusUtils.h
+++ b/ipc/dbus/DBusUtils.h
@@ -15,16 +15,17 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
 #ifndef mozilla_ipc_dbus_dbusutils_h__
 #define mozilla_ipc_dbus_dbusutils_h__
 
 #include <dbus/dbus.h>
+#include "mozilla/RefPtr.h"
 #include "mozilla/Scoped.h"
 
 // LOGE and free a D-Bus error
 // Using #define so that __FUNCTION__ resolves usefully
 #define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) log_and_free_dbus_error(err, __FUNCTION__, msg);
 #define LOG_AND_FREE_DBUS_ERROR(err) log_and_free_dbus_error(err, __FUNCTION__);
 
 struct DBusMessage;
@@ -45,19 +46,56 @@ public:
     if (mMsg) dbus_message_unref(mMsg);
   }
   operator DBusMessage*() { return mMsg; }
   DBusMessage* get() { return mMsg; }
 private:
   DBusMessage* mMsg;
 };
 
+/**
+ * DBusReplyHandler represents a handler for DBus reply messages. Inherit
+ * from this class and implement the Handle method. The method Callback
+ * should be passed to the DBus send function, with the class instance as
+ * user-data argument.
+ */
+class DBusReplyHandler : public mozilla::RefCounted<DBusReplyHandler>
+{
+public:
+  virtual ~DBusReplyHandler() {
+  }
+
+  /**
+   * Implements a call-back function for DBus. The supplied value for
+   * aData must be a pointer to an instance of DBusReplyHandler.
+   */
+  static void Callback(DBusMessage* aReply, void* aData);
+
+  /**
+   * Call-back method for handling the reply message from DBus.
+   */
+  virtual void Handle(DBusMessage* aReply) = 0;
+
+protected:
+  DBusReplyHandler()
+  {
+  }
+
+  DBusReplyHandler(const DBusReplyHandler& aHandler)
+  {
+  }
+
+  DBusReplyHandler& operator = (const DBusReplyHandler& aRhs)
+  {
+    return *this;
+  }
+};
+
 typedef void (*DBusCallback)(DBusMessage *, void *);
 
-
 void log_and_free_dbus_error(DBusError* err,
                              const char* function,
                              DBusMessage* msg = NULL);
 
 dbus_bool_t dbus_func_send(DBusConnection *aConnection,
                            dbus_uint32_t *aSerial,
                            DBusMessage *aMessage);
 
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -651,16 +651,21 @@ GeckoChildProcessHost::PerformAsyncLaunc
   childArgv.push_back(childProcessType);
 
   base::LaunchApp(childArgv, mFileMap,
 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD)
                   newEnvVars, privs,
 #endif
                   false, &process, arch);
 
+  // We're in the parent and the child was launched. Close the child FD in the
+  // parent as soon as possible, which will allow the parent to detect when the
+  // child closes its FD (either due to normal exit or due to crash).
+  GetChannel()->CloseClientFileDescriptor();
+
 #ifdef MOZ_WIDGET_COCOA
   // Wait for the child process to send us its 'task_t' data.
   const int kTimeoutMs = 10000;
 
   MachReceiveMessage child_message;
   ReceivePort parent_recv_port(mach_connection_name.c_str());
   kern_return_t err = parent_recv_port.WaitForMessage(&child_message, kTimeoutMs);
   if (err != KERN_SUCCESS) {
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -497,17 +497,17 @@ jsds_ErrorHookProc (JSDContext *jsdc, JS
     
     running = true;
     
     nsCOMPtr<jsdIValue> val;
     if (JS_IsExceptionPending(cx)) {
         jsval jv;
         JS_GetPendingException(cx, &jv);
         JSDValue *jsdv = JSD_NewValue (jsdc, jv);
-        val = getter_AddRefs(jsdValue::FromPtr(jsdc, jsdv));
+        val = dont_AddRef(jsdValue::FromPtr(jsdc, jsdv));
     }
     
     nsAutoCString fileName;
     uint32_t    line;
     uint32_t    pos;
     uint32_t    flags;
     uint32_t    errnum;
     bool        rval;
@@ -562,18 +562,17 @@ jsds_CallHookProc (JSDContext* jsdc, JSD
     if (!hook)
         return JS_TRUE;
 
     if (!jsds_FilterHook (jsdc, jsdthreadstate))
         return JS_FALSE;
 
     JSDStackFrameInfo *native_frame = JSD_GetStackFrame (jsdc, jsdthreadstate);
     nsCOMPtr<jsdIStackFrame> frame =
-        getter_AddRefs(jsdStackFrame::FromPtr(jsdc, jsdthreadstate,
-                                              native_frame));
+        dont_AddRef(jsdStackFrame::FromPtr(jsdc, jsdthreadstate, native_frame));
     gJsds->DoPause(nullptr, true);
     hook->OnCall(frame, type);    
     gJsds->DoUnPause(nullptr, true);
     jsdStackFrame::InvalidateAll();
 
     return JS_TRUE;
 }
 
@@ -608,34 +607,33 @@ jsds_ExecutionHookProc (JSDContext* jsdc
             }
             break;
         case JSD_HOOK_THROW:
         {
             hook_rv = JSD_HOOK_RETURN_CONTINUE_THROW;
             gJsds->GetThrowHook(getter_AddRefs(hook));
             if (hook) {
                 JSDValue *jsdv = JSD_GetException (jsdc, jsdthreadstate);
-                js_rv = getter_AddRefs(jsdValue::FromPtr (jsdc, jsdv));
+                js_rv = dont_AddRef(jsdValue::FromPtr (jsdc, jsdv));
             }
             break;
         }
         default:
             NS_ASSERTION (0, "Unknown hook type.");
     }
 
     if (!hook)
         return hook_rv;
     
     if (!jsds_FilterHook (jsdc, jsdthreadstate))
         return JSD_HOOK_RETURN_CONTINUE;
     
     JSDStackFrameInfo *native_frame = JSD_GetStackFrame (jsdc, jsdthreadstate);
     nsCOMPtr<jsdIStackFrame> frame =
-        getter_AddRefs(jsdStackFrame::FromPtr(jsdc, jsdthreadstate,
-                                              native_frame));
+        dont_AddRef(jsdStackFrame::FromPtr(jsdc, jsdthreadstate, native_frame));
     gJsds->DoPause(nullptr, true);
     jsdIValue *inout_rv = js_rv;
     NS_IF_ADDREF(inout_rv);
     hook->OnExecute (frame, type, &inout_rv, &hook_rv);
     js_rv = inout_rv;
     NS_IF_RELEASE(inout_rv);
     gJsds->DoUnPause(nullptr, true);
     jsdStackFrame::InvalidateAll();
@@ -667,17 +665,17 @@ jsds_ScriptHookProc (JSDContext* jsdc, J
 
         /* a script is being created */
         if (!hook) {
             /* nobody cares, just exit */
             return;
         }
             
         nsCOMPtr<jsdIScript> script = 
-            getter_AddRefs(jsdScript::FromPtr(jsdc, jsdscript));
+            dont_AddRef(jsdScript::FromPtr(jsdc, jsdscript));
 #ifdef CAUTIOUS_SCRIPTHOOK
         JS_UNKEEP_ATOMS(rt);
 #endif
         gJsds->DoPause(nullptr, true);
         hook->OnScriptCreated (script);
         gJsds->DoUnPause(nullptr, true);
 #ifdef CAUTIOUS_SCRIPTHOOK
         JS_KEEP_ATOMS(rt);
@@ -2676,17 +2674,17 @@ jsdService::EnumerateContexts (jsdIConte
         return NS_OK;
     
     JSContext *iter = NULL;
     JSContext *cx;
 
     while ((cx = JS_ContextIterator (mRuntime, &iter)))
     {
         nsCOMPtr<jsdIContext> jsdicx = 
-            getter_AddRefs(jsdContext::FromPtr(mCx, cx));
+            dont_AddRef(jsdContext::FromPtr(mCx, cx));
         if (jsdicx)
         {
             if (NS_FAILED(enumerator->EnumerateContext(jsdicx)))
                 break;
         }
     }
 
     return NS_OK;
@@ -2699,17 +2697,17 @@ jsdService::EnumerateScripts (jsdIScript
     
     JSDScript *script;
     JSDScript *iter = NULL;
     nsresult rv = NS_OK;
     
     JSD_LockScriptSubsystem(mCx);
     while((script = JSD_IterateScripts(mCx, &iter))) {
         nsCOMPtr<jsdIScript> jsdis =
-            getter_AddRefs(jsdScript::FromPtr(mCx, script));
+            dont_AddRef(jsdScript::FromPtr(mCx, script));
         rv = enumerator->EnumerateScript (jsdis);
         if (NS_FAILED(rv))
             break;
     }
     JSD_UnlockScriptSubsystem(mCx);
 
     return rv;
 }
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -352,22 +352,20 @@ MAKE_JARS_FLAGS = \
 ifdef USE_EXTENSION_MANIFEST
 MAKE_JARS_FLAGS += -e
 endif
 
 ifdef BOTH_MANIFESTS
 MAKE_JARS_FLAGS += --both-manifests
 endif
 
-TAR_CREATE_FLAGS = -cvhf
-TAR_CREATE_FLAGS_QUIET = -chf
+TAR_CREATE_FLAGS = -chf
 
 ifeq ($(OS_ARCH),OS2)
-TAR_CREATE_FLAGS = -cvf
-TAR_CREATE_FLAGS_QUIET = -cf
+TAR_CREATE_FLAGS = -cf
 endif
 
 #
 # Personal makefile customizations go in these optional make include files.
 #
 MY_CONFIG	:= $(DEPTH)/config/myconfig.mk
 MY_RULES	:= $(DEPTH)/config/myrules.mk
 
--- a/js/src/config/makefiles/makeutils.mk
+++ b/js/src/config/makefiles/makeutils.mk
@@ -113,9 +113,9 @@ ifdef USE_AUTOTARGETS_MK # mkdir_deps
   include $(topORerr)/config/makefiles/autotargets.mk
 endif
 
 ifdef USE_RCS_MK
   include $(topORerr)/config/makefiles/rcs.mk
 endif
 
 ## copy(src, dst): recursive copy
-copy_dir = (cd $(1)/. && $(TAR) $(TAR_CREATE_FLAGS_QUIET) - .) | (cd $(2)/. && tar -xf -)
+copy_dir = (cd $(1)/. && $(TAR) $(TAR_CREATE_FLAGS) - .) | (cd $(2)/. && tar -xf -)
--- a/js/src/tests/Makefile.in
+++ b/js/src/tests/Makefile.in
@@ -39,11 +39,11 @@ TEST_FILES = \
   test262/ \
   $(NULL)
 
 PKG_STAGE = $(DIST)/test-package-stage
 
 # stage tests for packaging
 stage-package:
 	$(NSINSTALL) -D $(PKG_STAGE)/jsreftest/tests
-	(cd $(srcdir) && tar $(TAR_CREATE_FLAGS_QUIET) - $(TEST_FILES)) | (cd $(PKG_STAGE)/jsreftest/tests && tar -xf -)
+	(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - $(TEST_FILES)) | (cd $(PKG_STAGE)/jsreftest/tests && tar -xf -)
 	$(PYTHON) $(srcdir)/jstests.py --make-manifests $(PKG_STAGE)/jsreftest/tests/
 
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -48,18 +48,16 @@ members = [
     'nsIDOMJSWindow.dump',
     # nsLocationSH has ~ALLOW_PROP_MODS_TO_PROTOTYPE, so don't try.
     #'nsIDOMLocation.hostname',
     #'nsIDOMLocation.href',
 
     # dom/interfaces/core
     'nsIDOMDOMStringList.*',
 
-    'nsIDOMTouchList.*',
-
     # dom/interfaces/storage
     'nsIDOMToString.toString',
     'nsIDOMStorage.setItem',
     'nsIDOMStorage.length',
     'nsIDOMStorage.getItem',
     'nsIDOMStorage.key',
     'nsIDOMStorage.removeItem',
     'nsIDOMStorage.clear',
@@ -110,24 +108,18 @@ members = [
 # nsIDOMEvent, for example, just look for nsIDOMEvent.idl.  But IDL filenames
 # for very long interface names are slightly abbreviated, and many interfaces
 # don't have their own files, just for extra wackiness.  So qsgen.py needs
 # a little help.
 #
 irregularFilenames = {
     # stowaways
     'nsIDOMBlob': 'nsIDOMFile',
-
     'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
-
-    'nsIDOMTouch': 'nsIDOMTouchEvent',
-    'nsIDOMTouchList': 'nsIDOMTouchEvent',
-
     'nsITelephoneCallback': 'nsITelephone',
-
     'nsIDOMWindowPerformance': 'nsIDOMWindow',
     }
 
 customIncludes = [
     'nsDOMQS.h',
     'nsPerformance.h',
     'mozilla/dom/EventTargetBinding.h',
     ]
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -31,17 +31,17 @@
 #include "nsCompatibility.h"
 #include "nsFrameManagerBase.h"
 #include "nsRect.h"
 #include "mozFlushType.h"
 #include "nsWeakReference.h"
 #include <stdio.h> // for FILE definition
 #include "nsChangeHint.h"
 #include "nsGUIEvent.h"
-#include "nsInterfaceHashtable.h"
+#include "nsRefPtrHashtable.h"
 #include "nsEventStates.h"
 #include "nsPresArena.h"
 #include "nsIImageLoadingContent.h"
 
 class nsIContent;
 class nsIDocument;
 class nsIFrame;
 class nsPresContext;
@@ -1124,17 +1124,17 @@ public:
   {
     return mIsActive;
   }
 
   // mouse capturing
 
   static CapturingContentInfo gCaptureInfo;
 
-  static nsInterfaceHashtable<nsUint32HashKey, nsIDOMTouch> gCaptureTouchList;
+  static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch> gCaptureTouchList;
   static bool gPreventMouseEvents;
 
   /**
    * When capturing content is set, it traps all mouse events and retargets
    * them at this content node. If capturing is not allowed
    * (gCaptureInfo.mAllowed is false), then capturing is not set. However, if
    * the CAPTURE_IGNOREALLOWED flag is set, the allowed state is ignored and
    * capturing is set regardless. To disable capture, pass null for the value
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -193,17 +193,17 @@ using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */, nullptr /* mContent */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
-nsInterfaceHashtable<nsUint32HashKey, nsIDOMTouch> nsIPresShell::gCaptureTouchList;
+nsRefPtrHashtable<nsUint32HashKey, dom::Touch> nsIPresShell::gCaptureTouchList;
 bool nsIPresShell::gPreventMouseEvents = false;
 
 // convert a color value to a string, in the CSS format #RRGGBB
 // *  - initially created for bugs 31816, 20760, 22963
 static void ColorToString(nscolor aColor, nsAutoString &aString);
 
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
@@ -5857,21 +5857,21 @@ PresShell::RecordMouseLocation(nsGUIEven
            this, aEvent->widget);
     printf("[ps=%p]clearing mouse location\n",
            this);
 #endif
   }
 }
 
 static void
-EvictTouchPoint(nsCOMPtr<nsIDOMTouch>& aTouch)
+EvictTouchPoint(nsRefPtr<dom::Touch>& aTouch)
 {
   nsIWidget *widget = nullptr;
   // is there an easier/better way to dig out the widget?
-  nsCOMPtr<nsINode> node(do_QueryInterface(aTouch->GetTarget()));
+  nsCOMPtr<nsINode> node(do_QueryInterface(aTouch->mTarget));
   if (!node) {
     return;
   }
   nsIDocument* doc = node->GetCurrentDoc();
   if (!doc) {
     return;
   }
   nsIPresShell *presShell = doc->GetShell();
@@ -5894,31 +5894,31 @@ EvictTouchPoint(nsCOMPtr<nsIDOMTouch>& a
   event.time = PR_IntervalNow();
   event.touches.AppendElement(aTouch);
 
   nsEventStatus status;
   widget->DispatchEvent(&event, status);
 }
 
 static PLDHashOperator
-AppendToTouchList(const uint32_t& aKey, nsCOMPtr<nsIDOMTouch>& aData, void *aTouchList)
-{
-  nsTArray<nsCOMPtr<nsIDOMTouch> > *touches = static_cast<nsTArray<nsCOMPtr<nsIDOMTouch> > *>(aTouchList);
+AppendToTouchList(const uint32_t& aKey, nsRefPtr<dom::Touch>& aData, void *aTouchList)
+{
+  nsTArray< nsRefPtr<dom::Touch> >* touches =
+    static_cast<nsTArray< nsRefPtr<dom::Touch> >*>(aTouchList);
   aData->mChanged = false;
   touches->AppendElement(aData);
   return PL_DHASH_NEXT;
 }
 
 static PLDHashOperator
-FindAnyTarget(const uint32_t& aKey, nsCOMPtr<nsIDOMTouch>& aData,
+FindAnyTarget(const uint32_t& aKey, nsRefPtr<dom::Touch>& aData,
               void* aAnyTarget)
 {
   if (aData) {
-    nsCOMPtr<nsIDOMEventTarget> target;
-    aData->GetTarget(getter_AddRefs(target));
+    dom::EventTarget* target = aData->Target();
     if (target) {
       nsCOMPtr<nsIContent>* content =
         static_cast<nsCOMPtr<nsIContent>*>(aAnyTarget);
       *content = do_QueryInterface(target);
       return PL_DHASH_STOP;
     }
   }
   return PL_DHASH_NEXT;
@@ -6128,17 +6128,17 @@ PresShell::HandleEvent(nsIFrame        *
     if (!captureRetarget && !isWindowLevelMouseExit) {
       nsPoint eventPoint;
       if (aEvent->message == NS_TOUCH_START) {
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
         // if there is only one touch in this touchstart event, assume that it is
         // the start of a new touch session and evict any old touches in the
         // queue
         if (touchEvent->touches.Length() == 1) {
-          nsTArray<nsCOMPtr<nsIDOMTouch> > touches;
+          nsTArray< nsRefPtr<dom::Touch> > touches;
           gCaptureTouchList.Enumerate(&AppendToTouchList, (void *)&touches);
           for (uint32_t i = 0; i < touches.Length(); ++i) {
             EvictTouchPoint(touches[i]);
           }
         }
         // if this is a continuing session, ensure that all these events are
         // in the same document by taking the target of the events already in
         // the capture list
@@ -6147,22 +6147,20 @@ PresShell::HandleEvent(nsIFrame        *
           gCaptureTouchList.Enumerate(&FindAnyTarget, &anyTarget);
         } else {
           gPreventMouseEvents = false;
         }
 
         // Add any new touches to the queue
         for (int32_t i = touchEvent->touches.Length(); i; ) {
           --i;
-          nsIDOMTouch *touch = touchEvent->touches[i];
-          Touch *domtouch = static_cast<Touch*>(touch);
+          dom::Touch* touch = touchEvent->touches[i];
           touch->mMessage = aEvent->message;
 
-          int32_t id = 0;
-          touch->GetIdentifier(&id);
+          int32_t id = touch->Identifier();
           if (!gCaptureTouchList.Get(id, nullptr)) {
             // This event is a new touch. Mark it as a changedTouch and
             // add it to the queue.
             touch->mChanged = true;
 
             // find the target for this touch
             uint32_t flags = 0;
             eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
@@ -6172,17 +6170,17 @@ PresShell::HandleEvent(nsIFrame        *
                                                              frame,
                                                              eventPoint,
                                                              flags);
             if (target && !anyTarget) {
               target->GetContentForEvent(aEvent, getter_AddRefs(anyTarget));
               while (anyTarget && !anyTarget->IsElement()) {
                 anyTarget = anyTarget->GetParent();
               }
-              domtouch->SetTarget(anyTarget);
+              touch->SetTarget(anyTarget);
               gCaptureTouchList.Put(id, touch);
             } else {
               nsIFrame* newTargetFrame = nullptr;
               for (nsIFrame* f = target; f;
                    f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
                 if (f->PresContext()->Document() == anyTarget->OwnerDoc()) {
                   newTargetFrame = f;
                   break;
@@ -6212,23 +6210,21 @@ PresShell::HandleEvent(nsIFrame        *
             }
             if (target) {
               frame = target;
             }
           } else {
             // This touch is an old touch, we need to ensure that is not
             // marked as changed and set its target correctly
             touch->mChanged = false;
-            int32_t id;
-            touch->GetIdentifier(&id);
-
-            nsCOMPtr<nsIDOMTouch> oldTouch;
-            gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+            int32_t id = touch->Identifier();
+
+            nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList.GetWeak(id);
             if (oldTouch) {
-              domtouch->SetTarget(oldTouch->GetTarget());
+              touch->SetTarget(oldTouch->mTarget);
               gCaptureTouchList.Put(id, touch);
             }
           }
         }
       } else {
         eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
       }
       uint32_t flags = 0;
@@ -6281,34 +6277,31 @@ PresShell::HandleEvent(nsIFrame        *
     PresShell* shell =
         static_cast<PresShell*>(frame->PresContext()->PresShell());
     switch (aEvent->message) {
       case NS_TOUCH_MOVE:
       case NS_TOUCH_CANCEL:
       case NS_TOUCH_END: {
         // get the correct shell to dispatch to
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-        nsTArray<nsCOMPtr<nsIDOMTouch> >  &touches = touchEvent->touches;
+        nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
         for (uint32_t i = 0; i < touches.Length(); ++i) {
-          nsIDOMTouch *touch = touches[i];
+          dom::Touch* touch = touches[i];
           if (!touch) {
             break;
           }
   
-          int32_t id;
-          touch->GetIdentifier(&id);
-          nsCOMPtr<nsIDOMTouch> oldTouch;
-          gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+          nsRefPtr<dom::Touch> oldTouch =
+            gCaptureTouchList.GetWeak(touch->Identifier());
           if (!oldTouch) {
             break;
           }
   
-          nsCOMPtr<nsIDOMEventTarget> targetPtr;
-          oldTouch->GetTarget(getter_AddRefs(targetPtr));
-          nsCOMPtr<nsIContent> content = do_QueryInterface(targetPtr);
+          nsCOMPtr<nsIContent> content =
+            do_QueryInterface(oldTouch->Target());
           if (!content) {
             break;
           }
 
           nsIFrame* contentFrame = content->GetPrimaryFrame();
           if (!contentFrame) {
             break;
           }
@@ -6676,77 +6669,70 @@ PresShell::HandleEventInternal(nsEvent* 
       case NS_MOUSE_BUTTON_UP:
         isHandlingUserInput = true;
         break;
       case NS_TOUCH_CANCEL:
       case NS_TOUCH_END: {
         // Remove the changed touches
         // need to make sure we only remove touches that are ending here
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-        nsTArray<nsCOMPtr<nsIDOMTouch> >  &touches = touchEvent->touches;
+        nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
         for (uint32_t i = 0; i < touches.Length(); ++i) {
-          nsIDOMTouch *touch = touches[i];
-          Touch *domtouch = static_cast<Touch*>(touch);
+          dom::Touch* touch = touches[i];
           if (!touch) {
             continue;
           }
           touch->mMessage = aEvent->message;
           touch->mChanged = true;
-          nsCOMPtr<nsIDOMTouch> oldTouch;
-
-          int32_t id;
-          touch->GetIdentifier(&id);
-
-          gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+
+          int32_t id = touch->Identifier();
+          nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList.GetWeak(id);
           if (!oldTouch) {
             continue;
           }
-          nsCOMPtr<EventTarget> targetPtr = oldTouch->GetTarget();
+          nsCOMPtr<EventTarget> targetPtr = oldTouch->mTarget;
 
           mCurrentEventContent = do_QueryInterface(targetPtr);
-          domtouch->SetTarget(targetPtr);
+          touch->SetTarget(targetPtr);
           gCaptureTouchList.Remove(id);
         }
         // add any touches left in the touch list, but ensure changed=false
         gCaptureTouchList.Enumerate(&AppendToTouchList, (void *)&touches);
         break;
       }
       case NS_TOUCH_MOVE: {
         // Check for touches that changed. Mark them add to queue
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-        nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+        nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
         bool haveChanged = false;
         for (int32_t i = touches.Length(); i; ) {
           --i;
-          nsIDOMTouch *touch = touches[i];
-          Touch *domtouch = static_cast<Touch*>(touch);
+          dom::Touch* touch = touches[i];
           if (!touch) {
             continue;
           }
-          int32_t id;
-          touch->GetIdentifier(&id);
+          int32_t id = touch->Identifier();
           touch->mMessage = aEvent->message;
 
-          nsCOMPtr<nsIDOMTouch> oldTouch;
-          gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+          nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList.GetWeak(id);
           if (!oldTouch) {
             touches.RemoveElementAt(i);
             continue;
           }
-          if(domtouch->Equals(oldTouch)) {
+          if (touch->Equals(oldTouch)) {
             touch->mChanged = true;
             haveChanged = true;
           }
 
-          nsCOMPtr<EventTarget> targetPtr = oldTouch->GetTarget();
+          nsCOMPtr<dom::EventTarget> targetPtr = oldTouch->mTarget;
           if (!targetPtr) {
             touches.RemoveElementAt(i);
             continue;
           }
-          domtouch->SetTarget(targetPtr);
+          touch->SetTarget(targetPtr);
 
           gCaptureTouchList.Put(id, touch);
           // if we're moving from touchstart to touchmove for this touch
           // we allow preventDefault to prevent mouse events
           if (oldTouch->mMessage != touch->mMessage) {
             touchIsNew = true;
           }
         }
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1575,17 +1575,17 @@ nsGfxScrollFrameInner::AsyncScrollCallba
   // up scrolling to.
   self->mDestination = self->GetScrollPosition();
 }
 
 void
 nsGfxScrollFrameInner::ScrollToCSSPixels(const CSSIntPoint& aScrollPosition)
 {
   nsPoint current = GetScrollPosition();