Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 03 Nov 2015 12:12:18 +0100
changeset 270927 574472951d246118ba1fc4da4b2380b99ef7ed8e
parent 270900 4bccd2788f121ff7f5f7a963583b94e14b34f01e (current diff)
parent 270926 bb4d614a0b09bcb9738c151dccfcd9b3857a6a7c (diff)
child 270928 d2aaa8d2568dd429240f5f0251ebc956cd06f9f2
push id67502
push usercbook@mozilla.com
push dateTue, 03 Nov 2015 11:12:27 +0000
treeherdermozilla-inbound@574472951d24 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound
devtools/client/app-manager/app-projects.js
devtools/client/app-manager/app-validator.js
devtools/client/app-manager/moz.build
devtools/client/app-manager/test/.eslintrc
devtools/client/app-manager/test/chrome.ini
devtools/client/app-manager/test/test_app_validator.html
devtools/client/app-manager/test/validator/no-name-or-icon/home.html
devtools/client/app-manager/test/validator/no-name-or-icon/manifest.webapp
devtools/client/app-manager/test/validator/non-absolute-path/manifest.webapp
devtools/client/app-manager/test/validator/valid/alsoValid/manifest.webapp
devtools/client/app-manager/test/validator/valid/home.html
devtools/client/app-manager/test/validator/valid/icon.png
devtools/client/app-manager/test/validator/valid/manifest.webapp
devtools/client/app-manager/test/validator/wrong-launch-path/icon.png
devtools/client/app-manager/test/validator/wrong-launch-path/manifest.webapp
devtools/client/themes/app-manager/images/default-app-icon.png
devtools/client/themes/app-manager/images/noise.png
devtools/client/themes/app-manager/images/rocket.svg
devtools/shared/gcli/gcli.jsm
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c72c9278ddc2f442d193474993d36e7f2cfb08c4"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- Stock Android things -->
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="38934e434c6c49ffdf7492f20f7258e7c3934b49"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="38934e434c6c49ffdf7492f20f7258e7c3934b49"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="38934e434c6c49ffdf7492f20f7258e7c3934b49"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c72c9278ddc2f442d193474993d36e7f2cfb08c4"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- Stock Android things -->
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "7954ff0cbd794a35499a1082bed273598f82ee6f", 
+        "git_revision": "06de78d2c61c084956640c480280ba518b2fe29f", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "a5acce8518931374a2a78442726dfe6a724a3962", 
+    "revision": "53578330b30736e8fef30dee4eccf296e2d53ca3", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -13,17 +13,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="38934e434c6c49ffdf7492f20f7258e7c3934b49"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7954ff0cbd794a35499a1082bed273598f82ee6f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="06de78d2c61c084956640c480280ba518b2fe29f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="956700d9754349b630a34551750ae6353614b6aa"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="27de93fe66c3e80e157d157bd52ca99565351669"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/browser/components/loop/content/js/roomStore.js
+++ b/browser/components/loop/content/js/roomStore.js
@@ -351,21 +351,21 @@ loop.store = loop.store || {};
      */
     shareRoomUrl: function(actionData) {
       var providerOrigin = new URL(actionData.provider.origin).hostname;
       var shareTitle = "";
       var shareBody = null;
 
       switch (providerOrigin) {
         case "mail.google.com":
-          shareTitle = mozL10n.get("share_email_subject6");
-          shareBody = mozL10n.get("share_email_body6", {
+          shareTitle = mozL10n.get("share_email_subject7");
+          shareBody = mozL10n.get("share_email_body7", {
             callUrl: actionData.roomUrl
           });
-          shareBody += mozL10n.get("share_email_footer");
+          shareBody += mozL10n.get("share_email_footer2");
           break;
         case "twitter.com":
         default:
           shareTitle = mozL10n.get("share_tweet", {
             clientShortname2: mozL10n.get("clientShortname2")
           });
           break;
       }
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -263,20 +263,28 @@ loop.roomViews = (function(mozL10n) {
       };
     },
 
     handleEmailButtonClick: function(event) {
       event.preventDefault();
 
       var roomData = this.props.roomData;
       var contextURL = roomData.roomContextUrls && roomData.roomContextUrls[0];
+      if (contextURL) {
+        if (contextURL.location === null) {
+          contextURL = undefined;
+        } else {
+          contextURL = sharedUtils.formatURL(contextURL.location).hostname;
+        }
+      }
+
       this.props.dispatcher.dispatch(
         new sharedActions.EmailRoomUrl({
           roomUrl: roomData.roomUrl,
-          roomDescription: contextURL && contextURL.description,
+          roomDescription: contextURL,
           from: "conversation"
         }));
     },
 
     handleCopyButtonClick: function(event) {
       event.preventDefault();
 
       this.props.dispatcher.dispatch(new sharedActions.CopyRoomUrl({
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -263,20 +263,28 @@ loop.roomViews = (function(mozL10n) {
       };
     },
 
     handleEmailButtonClick: function(event) {
       event.preventDefault();
 
       var roomData = this.props.roomData;
       var contextURL = roomData.roomContextUrls && roomData.roomContextUrls[0];
+      if (contextURL) {
+        if (contextURL.location === null) {
+          contextURL = undefined;
+        } else {
+          contextURL = sharedUtils.formatURL(contextURL.location).hostname;
+        }
+      }
+
       this.props.dispatcher.dispatch(
         new sharedActions.EmailRoomUrl({
           roomUrl: roomData.roomUrl,
-          roomDescription: contextURL && contextURL.description,
+          roomDescription: contextURL,
           from: "conversation"
         }));
     },
 
     handleCopyButtonClick: function(event) {
       event.preventDefault();
 
       this.props.dispatcher.dispatch(new sharedActions.CopyRoomUrl({
--- a/browser/components/loop/content/shared/js/utils.js
+++ b/browser/components/loop/content/shared/js/utils.js
@@ -386,27 +386,26 @@ var inChrome = typeof Components != "und
   function composeCallUrlEmail(callUrl, recipient, contextDescription, from) {
     var mozLoop = navigator.mozLoop;
     if (typeof mozLoop === "undefined") {
       console.warn("composeCallUrlEmail isn't available for Loop standalone.");
       return;
     }
 
     var subject, body;
-    var footer = mozL10n.get("share_email_footer");
-
+    var footer = mozL10n.get("share_email_footer2");
     if (contextDescription) {
-      subject = mozL10n.get("share_email_subject6");
-      body = mozL10n.get("share_email_body_context2", {
+      subject = mozL10n.get("share_email_subject7");
+      body = mozL10n.get("share_email_body_context3", {
         callUrl: callUrl,
         title: contextDescription
       });
     } else {
-      subject = mozL10n.get("share_email_subject6");
-      body = mozL10n.get("share_email_body6", {
+      subject = mozL10n.get("share_email_subject7");
+      body = mozL10n.get("share_email_body7", {
         callUrl: callUrl
       });
     }
     var bodyFooter = body + footer;
     bodyFooter = bodyFooter.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n");
     mozLoop.composeEmail(
       subject,
       bodyFooter,
--- a/browser/components/loop/test/desktop-local/roomStore_test.js
+++ b/browser/components/loop/test/desktop-local/roomStore_test.js
@@ -548,17 +548,17 @@ describe("loop.store.RoomStore", functio
           roomUrl: roomUrl,
           provider: {
             origin: origin
           }
         }));
 
         sinon.assert.calledOnce(fakeMozLoop.socialShareRoom);
         sinon.assert.calledWithExactly(fakeMozLoop.socialShareRoom, origin,
-          roomUrl, "share_email_subject6", "share_email_body6" + "share_email_footer");
+          roomUrl, "share_email_subject7", "share_email_body7" + "share_email_footer2");
       });
 
       it("should pass the correct data for all other Social Providers", function() {
         var roomUrl = "http://invalid2";
         var origin = "https://twitter.com/share";
         store.shareRoomUrl(new sharedActions.ShareRoomUrl({
           roomUrl: roomUrl,
           provider: {
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -207,17 +207,18 @@ describe("loop.roomViews", function() {
         savingContext: false,
         show: true,
         showEditContext: false
       }, props);
       return TestUtils.renderIntoDocument(
         React.createElement(loop.roomViews.DesktopRoomInvitationView, props));
     }
 
-    it("should dispatch an EmailRoomUrl action when the email button is pressed",
+    it("should dispatch an EmailRoomUrl with no description" +
+       " for rooms without context when the email button is pressed",
       function() {
         view = mountTestComponent({
           roomData: { roomUrl: "http://invalid" }
         });
 
         var emailBtn = view.getDOMNode().querySelector(".btn-email");
 
         React.addons.TestUtils.Simulate.click(emailBtn);
@@ -226,36 +227,35 @@ describe("loop.roomViews", function() {
         sinon.assert.calledWith(dispatcher.dispatch,
           new sharedActions.EmailRoomUrl({
             roomUrl: "http://invalid",
             roomDescription: undefined,
             from: "conversation"
           }));
       });
 
-    it("should dispatch a different EmailRoomUrl action for rooms with context",
+    it("should dispatch an EmailRoomUrl with a domain name description for rooms with context",
       function() {
         var url = "http://invalid";
-        var description = "Hello, is it me you're looking for?";
         view = mountTestComponent({
           roomData: {
             roomUrl: url,
-            roomContextUrls: [{ description: description }]
+            roomContextUrls: [{ location: "http://www.mozilla.com/" }]
           }
         });
 
         var emailBtn = view.getDOMNode().querySelector(".btn-email");
 
         React.addons.TestUtils.Simulate.click(emailBtn);
 
         sinon.assert.calledOnce(dispatcher.dispatch);
         sinon.assert.calledWith(dispatcher.dispatch,
           new sharedActions.EmailRoomUrl({
             roomUrl: url,
-            roomDescription: description,
+            roomDescription: "www.mozilla.com",
             from: "conversation"
           }));
       });
 
     describe("Copy Button", function() {
       beforeEach(function() {
         view = mountTestComponent({
           roomData: { roomUrl: "http://invalid" }
--- a/browser/components/loop/test/shared/utils_test.js
+++ b/browser/components/loop/test/shared/utils_test.js
@@ -317,23 +317,23 @@ describe("loop.shared.utils", function()
 
   describe("#composeCallUrlEmail", function() {
     var composeEmail, telemetryAddValue;
 
     beforeEach(function() {
       // fake mozL10n
       sandbox.stub(navigator.mozL10n, "get", function(id) {
         switch (id) {
-          case "share_email_subject6":
+          case "share_email_subject7":
             return "subject";
-          case "share_email_body6":
+          case "share_email_body7":
             return "body";
-          case "share_email_body_context2":
+          case "share_email_body_context3":
             return "body_context";
-          case "share_email_footer":
+          case "share_email_footer2":
             return "footer";
         }
       });
       composeEmail = sandbox.spy();
       telemetryAddValue = sandbox.spy();
       navigator.mozLoop = {
         SHARING_ROOM_URL: {
           EMAIL_FROM_CALLFAILED: 2,
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -639,16 +639,17 @@ BrowserGlue.prototype = {
     ExtensionManagement.registerScript("chrome://browser/content/ext-browserAction.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-pageAction.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-contextMenus.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-tabs.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-windows.js");
     ExtensionManagement.registerScript("chrome://browser/content/ext-bookmarks.js");
 
     this._flashHangCount = 0;
+    this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve);
   },
 
   // cleanup (called on application shutdown)
   _dispose: function BG__dispose() {
     let os = Services.obs;
     os.removeObserver(this, "notifications-open-settings");
     os.removeObserver(this, "prefservice:after-app-defaults");
     os.removeObserver(this, "final-ui-startup");
@@ -1136,16 +1137,17 @@ BrowserGlue.prototype = {
     if (!disableResetPrompt && lastUse &&
         Date.now() - lastUse >= OFFER_PROFILE_RESET_INTERVAL_MS) {
       this._resetUnusedProfileNotification();
     }
 
     this._checkForOldBuildUpdates();
 
     this._firstWindowTelemetry(aWindow);
+    this._firstWindowLoaded();
   },
 
   /**
    * Application shutdown handler.
    */
   _onQuitApplicationGranted: function () {
     // This pref must be set here because SessionStore will use its value
     // on quit-application.
@@ -2204,17 +2206,17 @@ BrowserGlue.prototype = {
     }
 
     if (currentUIVersion < 31) {
       xulStore.removeValue(BROWSER_DOCURL, "bookmarks-menu-button", "class");
       xulStore.removeValue(BROWSER_DOCURL, "home-button", "class");
     }
 
     if (currentUIVersion < 32) {
-      this._notifyNotificationsUpgrade();
+      this._notifyNotificationsUpgrade().catch(Cu.reportError);
     }
 
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _hasExistingNotificationPermission: function BG__hasExistingNotificationPermission() {
     let enumerator = Services.perms.enumerator;
@@ -2222,39 +2224,35 @@ BrowserGlue.prototype = {
       let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
       if (permission.type == "desktop-notification") {
         return true;
       }
     }
     return false;
   },
 
-  _notifyNotificationsUpgrade: function BG__notifyNotificationsUpgrade() {
+  _notifyNotificationsUpgrade: Task.async(function* () {
     if (!this._hasExistingNotificationPermission()) {
       return;
     }
+    yield this._firstWindowReady;
     function clickCallback(subject, topic, data) {
       if (topic != "alertclickcallback")
         return;
       let win = RecentWindow.getMostRecentBrowserWindow();
       win.openUILinkIn(data, "tab");
     }
     let imageURL = "chrome://browser/skin/web-notifications-icon.svg";
     let title = gBrowserBundle.GetStringFromName("webNotifications.upgradeTitle");
-    let text = gBrowserBundle.GetStringFromName("webNotifications.upgradeInfo");
+    let text = gBrowserBundle.GetStringFromName("webNotifications.upgradeBody");
     let url = Services.urlFormatter.formatURLPref("browser.push.warning.migrationURL");
 
-    try {
-      AlertsService.showAlertNotification(imageURL, title, text,
-                                          true, url, clickCallback);
-    }
-    catch (e) {
-      Cu.reportError(e);
-    }
-  },
+    AlertsService.showAlertNotification(imageURL, title, text,
+                                        true, url, clickCallback);
+  }),
 
   // ------------------------------
   // public nsIBrowserGlue members
   // ------------------------------
 
   sanitize: function BG_sanitize(aParentWindow) {
     this._sanitizer.sanitize(aParentWindow);
   },
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -379,18 +379,18 @@ webNotifications.receiveForSession=Recei
 webNotifications.receiveForSession.accesskey=s
 webNotifications.alwaysReceive=Always Receive Notifications
 webNotifications.alwaysReceive.accesskey=A
 webNotifications.neverShow=Always Block Notifications
 webNotifications.neverShow.accesskey=N
 webNotifications.receiveFromSite=Would you like to receive notifications from this site?
 # LOCALIZATION NOTE (webNotifications.upgradeTitle): When using native notifications on OS X, the title may be truncated around 32 characters.
 webNotifications.upgradeTitle=Upgraded notifications
-# LOCALIZATION NOTE (webNotifications.upgradeInfo): When using native notifications on OS X, the body may be truncated around 100 characters in some views.
-webNotifications.upgradeInfo=You will receive notifications from sites, even those not open in a tab. Click to learn more.
+# LOCALIZATION NOTE (webNotifications.upgradeBody): When using native notifications on OS X, the body may be truncated around 100 characters in some views.
+webNotifications.upgradeBody=You can now receive notifications from sites that are not currently loaded. Click to learn more.
 
 # Pointer lock UI
 
 pointerLock.allow2=Hide pointer
 pointerLock.allow2.accesskey=H
 pointerLock.alwaysAllow=Always allow hiding
 pointerLock.alwaysAllow.accesskey=A
 pointerLock.neverAllow=Never allow hiding
--- a/browser/locales/en-US/chrome/browser/devtools/app-manager.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/app-manager.properties
@@ -22,9 +22,8 @@ validator.missIconMarketplace2=app submi
 validator.invalidAppType=Unknown app type: '%S'.
 validator.invalidHostedPriviledges=Hosted App can't be type '%S'.
 validator.noCertifiedSupport='certified' apps are not fully supported on the App manager.
 validator.nonAbsoluteLaunchPath=Launch path has to be an absolute path starting with '/': '%S'
 validator.accessFailedLaunchPath=Unable to access the app starting document '%S'
 # LOCALIZATION NOTE (validator.accessFailedLaunchPathBadHttpCode): %1$S is the URI of
 # the launch document, %2$S is the http error code.
 validator.accessFailedLaunchPathBadHttpCode=Unable to access the app starting document '%1$S', got HTTP code %2$S
-
--- a/browser/locales/en-US/chrome/browser/devtools/webide.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/webide.dtd
@@ -70,16 +70,19 @@
 <!ENTITY key_toggleToolbox "VK_F12">
 <!-- toggle sidebar -->
 <!ENTITY key_toggleEditor "B">
 <!-- zoom -->
 <!ENTITY key_zoomin "+">
 <!ENTITY key_zoomin2 "=">
 <!ENTITY key_zoomout "-">
 <!ENTITY key_resetzoom "0">
+<!-- reload WebIDE and devtools from local checkout -->
+<!-- this binding is with accel+alt, whereas all others are just accel -->
+<!ENTITY key_reload_devtools "R">
 
 <!ENTITY projectPanel_myProjects "My Projects">
 <!ENTITY projectPanel_runtimeApps "Runtime Apps">
 <!ENTITY projectPanel_tabs "Tabs">
 <!ENTITY runtimePanel_usb "USB Devices">
 <!ENTITY runtimePanel_wifi "Wi-Fi Devices">
 <!ENTITY runtimePanel_simulator "Simulators">
 <!ENTITY runtimePanel_other "Other">
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties
+++ b/browser/locales/en-US/chrome/browser/loop/loop.properties
@@ -54,25 +54,25 @@ check_internet_connection=Please check y
 login_expired=Your Login Has Expired
 service_not_available=Service Unavailable At This Time
 problem_accessing_account=There Was A Problem Accessing Your Account
 
 ## LOCALIZATION NOTE(retry_button): Displayed when there is an error to retry
 ## the appropriate action.
 retry_button=Retry
 
-share_email_subject6=Join me for a video conversation
-## LOCALIZATION NOTE (share_email_body6): In this item, don't translate the
+share_email_subject7=Your invitation to browse the Web together
+## LOCALIZATION NOTE (share_email_body7): In this item, don't translate the
 ## part between {{..}} and leave the \n\n part alone
-share_email_body6=Click the Firefox Hello link to connect to the conversation now: {{callUrl}}
-## LOCALIZATION NOTE (share_email_body_context2): In this item, don't translate
+share_email_body7=A friend is waiting for you on Firefox Hello. Click the link to connect and browse the Web together: {{callUrl}}
+## LOCALIZATION NOTE (share_email_body_context3): In this item, don't translate
 ## the part between {{..}} and leave the \n\n part alone.
-share_email_body_context2=Join me for a video conversation. Click the Firefox Hello link to connect now: {{callUrl}}\n\nLet’s talk about this during our conversation: {{title}}
-## LOCALIZATION NOTE (share_email_footer): Common footer content for both email types
-share_email_footer=\n\n________\nJoin and create video conversations free with Firefox Hello. Connect easily over video with anyone, anywhere. No downloads or registration. Learn more at http://www.firefox.com/hello
+share_email_body_context3=A friend is waiting for you on Firefox Hello. Click the link to connect and browse {{title}} together: {{callUrl}}
+## LOCALIZATION NOTE (share_email_footer2): Common footer content for both email types
+share_email_footer2=\n\n____________\nFirefox Hello lets you browse the Web with your friends. Use it when you want to get things done: plan together, work together, laugh together. Learn more at http://www.firefox.com/hello
 ## LOCALIZATION NOTE (share_tweeet): In this item, don't translate the part
 ## between {{..}}. Please keep the text below 117 characters to make sure it fits
 ## in a tweet.
 share_tweet=Join me for a video conversation on {{clientShortname2}}!
 
 share_add_service_button=Add a Service
 
 ## LOCALIZATION NOTE (copy_link_menuitem, email_link_menuitem, delete_conversation_menuitem):
@@ -211,16 +211,21 @@ no_conversations_message_heading2=No con
 ## LOCALIZATION NOTE(no_conversations_start_message2): Subheading inviting the
 ## user to start a new conversation.
 no_conversations_start_message2=Start a new one!
 
 # LOCALIZATION NOTE (context_inroom_header): this string is displayed in the
 # conversation window when the user edits context. It is a header to the edit
 # section.
 context_inroom_header=Let's Talk About…
+# LOCALIZATION NOTE (context_inroom_label2): this string is followed by the
+# title and domain of the website you are having a conversation about, displayed on a
+# separate line. If this structure doesn't work for your locale, you might want
+# to consider this as a stand-alone title. See example screenshot:
+# https://bug1115342.bugzilla.mozilla.org/attachment.cgi?id=8563677
 context_edit_name_placeholder=Conversation Name
 context_edit_comments_placeholder=Comments
 context_cancel_label=Cancel
 context_done_label=Done
 conversation_settings_menu_edit_context=Edit Context
 conversation_settings_menu_hide_context=Hide Context
 
 
deleted file mode 100644
--- a/devtools/client/app-manager/moz.build
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
-
-DevToolsModules(
-    'app-projects.js',
-    'app-validator.js',
-)
deleted file mode 100644
--- a/devtools/client/app-manager/test/.eslintrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  // Extend from the shared list of defined globals for mochitests.
-  "extends": "../../../.eslintrc.mochitests"
-}
deleted file mode 100644
--- a/devtools/client/app-manager/test/chrome.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-tags = devtools
-skip-if = buildapp == 'b2g'
-support-files =
-  validator/*
-
-[test_app_validator.html]
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -317,19 +317,16 @@ devtools.jar:
     skin/themes/images/cubic-bezier-swatch.png (themes/images/cubic-bezier-swatch.png)
     skin/themes/images/cubic-bezier-swatch@2x.png (themes/images/cubic-bezier-swatch@2x.png)
     skin/themes/images/undock@2x.png (themes/images/undock@2x.png)
     skin/themes/font-inspector.css (themes/font-inspector.css)
     skin/themes/computedview.css (themes/computedview.css)
     skin/themes/images/arrow-e.png (themes/images/arrow-e.png)
     skin/themes/images/arrow-e@2x.png (themes/images/arrow-e@2x.png)
     skin/themes/projecteditor/projecteditor.css (themes/projecteditor/projecteditor.css)
-    skin/themes/app-manager/images/rocket.svg (themes/app-manager/images/rocket.svg)
-    skin/themes/app-manager/images/noise.png (themes/app-manager/images/noise.png)
-    skin/themes/app-manager/images/default-app-icon.png (themes/app-manager/images/default-app-icon.png)
     skin/themes/images/search-clear-failed.svg (themes/images/search-clear-failed.svg)
     skin/themes/images/search-clear-light.svg (themes/images/search-clear-light.svg)
     skin/themes/images/search-clear-dark.svg (themes/images/search-clear-dark.svg)
     skin/themes/tooltip/arrow-horizontal-dark.png (themes/tooltip/arrow-horizontal-dark.png)
     skin/themes/tooltip/arrow-horizontal-dark@2x.png (themes/tooltip/arrow-horizontal-dark@2x.png)
     skin/themes/tooltip/arrow-vertical-dark.png (themes/tooltip/arrow-vertical-dark.png)
     skin/themes/tooltip/arrow-vertical-dark@2x.png (themes/tooltip/arrow-vertical-dark@2x.png)
     skin/themes/tooltip/arrow-horizontal-light.png (themes/tooltip/arrow-horizontal-light.png)
--- a/devtools/client/moz.build
+++ b/devtools/client/moz.build
@@ -4,17 +4,16 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include('../templates.mozbuild')
 
 DIRS += [
     'aboutdebugging/components',
     'animationinspector',
-    'app-manager',
     'canvasdebugger',
     'commandline',
     'debugger',
     'eyedropper',
     'fontinspector',
     'framework',
     'inspector',
     'jsonview',
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -16,21 +16,16 @@ pref("devtools.devedition.promo.url", "h
 
 // Disable the error console
 pref("devtools.errorconsole.enabled", false);
 
 // Developer toolbar preferences
 pref("devtools.toolbar.enabled", true);
 pref("devtools.toolbar.visible", false);
 
-// Enable the app manager
-pref("devtools.appmanager.enabled", true);
-pref("devtools.appmanager.lastTab", "help");
-pref("devtools.appmanager.manifestEditor.enabled", true);
-
 // Enable DevTools WebIDE by default
 pref("devtools.webide.enabled", true);
 
 // Toolbox preferences
 pref("devtools.toolbox.footer.height", 250);
 pref("devtools.toolbox.sidebar.width", 500);
 pref("devtools.toolbox.host", "bottom");
 pref("devtools.toolbox.previousHost", "side");
--- a/devtools/client/themes/memory.css
+++ b/devtools/client/themes/memory.css
@@ -19,297 +19,359 @@
   --row-hover-background-color: rgba(76,158,217,0.2);
 }
 
 html, body, #app, #memory-tool {
   height: 100%;
 }
 
 #memory-tool {
+  /**
+   * Flex: contains two children: .devtools-toolbar and #memory-tool-container,
+   * which need to be laid out vertically. The toolbar has a fixed height and
+   * the container needs to flex to fill out all remaining vertical space.
+   */
   display: flex;
   flex-direction: column;
   --sidebar-width: 185px;
   /**
    * If --heap-tree-row-height changes, be sure to change HEAP_TREE_ROW_HEIGHT
    * in `devtools/client/memory/components/heap.js`.
    */
   --heap-tree-row-height: 14px;
   --heap-tree-header-height: 17px;
 }
 
-#memory-tool .devtools-toolbar {
+/**
+ * Toolbar
+ */
+
+.devtools-toolbar {
+  /**
+   * Flex: contains several children, which need to be laid out horizontally,
+   * and aligned vertically in the middle of the container.
+   */
   display: flex;
   align-items: center;
 }
 
-.devtools-toolbar .toolbar-group {
-  position: absolute;
-  left: var(--sidebar-width);
-  top: -2px;
-  white-space: nowrap;
-}
-
-.toolbar-group > label {
-  margin-right: 5px;
-}
-
-.toolbar-group .breakdown-by span {
-  margin-right: 5px;
+.devtools-toolbar > .toolbar-group {
+  /**
+   * We want this to be exactly at a --sidebar-width distance from the
+   * toolbar's start boundary. A .devtools-toolbar has a 3px start padding
+   * and the preceeding .take-snapshot button is exactly 32px.
+   */
+  margin-inline-start: calc(var(--sidebar-width) - 3px - 32px);
+  border-inline-start: 1px solid var(--theme-splitter-color);
+  padding-inline-start: 5px;
 }
 
-#memory-tool-container {
-  overflow: hidden;
-  display: flex;
-  flex: 1;
+.devtools-toolbar > .toolbar-group > label {
+  margin-inline-end: 5px;
 }
 
-/**
- * Toolbar
- */
-
-.devtools-toolbar .devtools-button.take-snapshot {
-  -moz-appearance: none;
-  margin-inline-start: 1px;
-  margin-inline-end: 1px;
+.devtools-toolbar > .toolbar-group > label.breakdown-by > span {
+  margin-inline-end: 5px;
 }
 
-.devtools-toolbar .devtools-button.take-snapshot::before {
+.devtools-toolbar > .devtools-button.take-snapshot::before {
   background-image: url(images/command-screenshot.png);
   background-size: 64px 16px;
   background-position: 0 center;
 }
 @media (min-resolution: 1.1dppx) {
-  .devtools-toolbar .devtools-button.take-snapshot::before {
+  .devtools-toolbar > .devtools-button.take-snapshot::before {
     background-image: url(images/command-screenshot@2x.png);
   }
 }
 
 /**
  * TODO bug 1213100
- * Once we figure out how to store invertable buttons (pseudo element like in this case?)
- * we should add a .invertable class to handle this generally, rather than the definitions
- * in toolbars.inc.css.
+ * Once we figure out how to store invertable buttons (pseudo element like in
+ * this case?) we should add a .invertable class to handle this generally,
+ * rather than the definitions in toolbars.inc.css.
  *
  * @see bug 1173397 for another inverted related bug
  */
-.theme-light .devtools-toolbarbutton.take-snapshot::before {
+.theme-light .devtools-toolbar > .devtools-toolbarbutton.take-snapshot::before {
   filter: url(images/filters.svg#invert);
 }
 
+/**
+ * Container (sidebar + main panel)
+ */
+
+#memory-tool-container {
+  /**
+   * Flex: contains two children: .list (sidebar) and #heap-view (main panel),
+   * which need to be laid out horizontally. The sidebar has a fixed width and
+   * the main panel needs to flex to fill out all remaining horizontal space.
+   */
+  display: flex;
+  /**
+   * Flexing to fill out remaining vertical space. The preceeding sibling is
+   * the toolbar. @see #memory-tool.
+   */
+  flex: 1;
+  overflow: hidden;
+}
+
+/**
+ * Sidebar
+ */
+
 .list {
-  min-width: var(--sidebar-width);
   width: var(--sidebar-width);
   overflow-y: auto;
   margin: 0;
   padding: 0;
   background-color: var(--theme-sidebar-background);
   border-inline-end: 1px solid var(--theme-splitter-color);
 }
 
-.list > li {
+.snapshot-list-item {
+  /**
+   * Flex: contains several children, which need to be laid out vertically.
+   */
   display: flex;
   flex-direction: column;
   color: var(--theme-body-color);
   border-bottom: 1px solid rgba(128,128,128,0.15);
   padding: 8px;
   cursor: pointer;
 }
 
-.list > li.selected {
+.snapshot-list-item.selected {
   background-color: var(--theme-selection-background);
   color: var(--theme-selection-color);
 }
 
-.snapshot-list-item .snapshot-title {
-  display: block;
+.snapshot-list-item > .snapshot-title {
   margin-bottom: 14px;
 }
 
-.snapshot-list-item .snapshot-state,
-.snapshot-list-item .snapshot-totals {
+.snapshot-list-item > .snapshot-state,
+.snapshot-list-item > .snapshot-totals {
   font-size: 90%;
   color: var(--theme-body-color-alt);
 }
 
-.snapshot-list-item.selected .snapshot-state,
-.snapshot-list-item.selected .snapshot-totals {
+.snapshot-list-item.selected > .snapshot-state,
+.snapshot-list-item.selected > .snapshot-totals {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /**
  * Main panel
  */
 
 #heap-view {
+  /**
+   * Flex: contains a .heap-view-panel which needs to fill out all the
+   * available space, horizontally and vertically.
+   */;
   display: flex;
+  /**
+   * Flexing to fill out remaining horizontal space. The preceeding sibling
+   * is the sidebar. @see #memory-tool-container.
+   */
   flex: 1;
-  justify-content: center;
   background-color: var(--theme-toolbar-background);
-  min-width: 400px;
 }
 
-#heap-view .snapshot-status,
-#heap-view .take-snapshot {
+#heap-view > .heap-view-panel {
+  /**
+   * Flex: can contain several children, including a tree with a header and
+   * multiple rows, all of which need to be laid out vertically. When the
+   * tree is visible, the header has a fixed height and tree body needs to flex
+   * to fill out all remaining vertical space.
+   */
+  display: flex;
+  flex-direction: column;
+  /**
+   * Flexing to fill out remaining horizontal space. @see #heap-view.
+   */
+  flex: 1;
+}
+
+#heap-view > .heap-view-panel > .snapshot-status,
+#heap-view > .heap-view-panel > .take-snapshot {
   margin: auto;
   margin-top: 65px;
   font-size: 120%;
 }
 
-#heap-view .snapshot-status {
-  display: block;
-  text-align: center;
-}
-
-#heap-view .take-snapshot {
+#heap-view > .heap-view-panel > .take-snapshot {
   padding: 5px;
 }
 
-#heap-view .heap-view-panel {
-  display: flex;
-  flex-direction: column;
-  flex: 1;
-}
-
-#heap-view .heap-view-panel[data-state="snapshot-state-error"] pre {
-  /* TODO */
+#heap-view > .heap-view-panel[data-state="snapshot-state-error"] pre {
   background-color: var(--theme-body-background);
-  overflow-y: auto;
   margin: 20px;
   padding: 20px;
 }
 
 /**
- * Heap Tree View
+ * Heap tree view header
  */
 
-#heap-view .theme-twisty {
-  float: left;
-}
-
 .header {
-  height: var(--heap-tree-header-height);
+  /**
+   * Flex: contains several span columns, all of which need to be laid out
+   * horizontally. All columns except the last one have percentage widths, and
+   * the last one needs to flex to fill out all remaining horizontal space.
+   */
   display: flex;
-  align-items: center;
   color: var(--theme-body-color);
   background-color: var(--theme-tab-toolbar-background);
+  border-bottom: 1px solid var(--cell-border-color);
+}
+
+.header > span {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: var(--heap-tree-header-height);
+  justify-content: center;
+  font-size: 90%;
+  white-space: nowrap;
 }
 
-.tree span {
-  line-height: var(--heap-tree-row-height);
+.header > .heap-tree-item-name {
+  justify-content: flex-start;
 }
 
+/**
+ * Heap tree view body
+ */
+
 .tree {
+  /**
+   * Flexing to fill out remaining vertical space. @see .heap-view-panel
+   */
   flex: 1;
   overflow-y: auto;
   background-color: var(--theme-body-background);
 }
 
 .tree-node {
   height: var(--heap-tree-row-height);
-  clear: left;
-}
-
-.heap-tree-percent {
-  width: 30%;
 }
 
-.heap-tree-number {
-  width: 70%;
-  color: var(--theme-content-color3);
-  padding-right: 5px;
-}
+/**
+ * Heap tree view columns
+ */
 
-.focused .heap-tree-number {
-  color: var(--theme-selection-color);
-}
-
-.heap-tree-item, .header {
-  list-style-type: none;
-  height: var(--heap-tree-row-height);
+.heap-tree-item {
+  /**
+   * Flex: contains several span columns, all of which need to be laid out
+   * horizontally. All columns except the last one have percentage widths, and
+   * the last one needs to flex to fill out all remaining horizontal space.
+   */
   display: flex;
-  flex-direction: row;
 }
 
 .tree-node:nth-child(2n) {
   background-color: var(--row-alt-background-color);
 }
 
 .tree-node:hover {
   background-color: var(--row-hover-background-color);
 }
 
-.tree-node:focus, .heap-tree-item.focused {
+.heap-tree-item.focused {
   background-color: var(--theme-selection-background);
   color: var(--theme-selection-color);
 }
 
-.header {
-  background-color: var(--theme-tab-toolbar-background);
-  border-color: var(--cell-border-color);
-  border-style: solid;
-  border-width: 0px 0px 1px 0px;
-}
-
-.header span {
-  text-align: center;
-  line-height: var(--heap-tree-header-height);
-  font-size: 90%;
-  display: inline;
-}
-
-.header span, .heap-tree-number, .heap-tree-percent, .heap-tree-item-name {
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.header .heap-tree-item-name {
-  text-align: left;
-}
-
 .heap-tree-item-bytes,
 .heap-tree-item-count,
 .heap-tree-item-total-bytes,
 .heap-tree-item-total-count {
+  /**
+   * Flex: contains several subcolumns, which need to be laid out horizontally.
+   * These subcolumns may have specific widths or need to flex.
+   */
+  display: flex;
   text-align: end;
   border-inline-end: var(--cell-border-color) 1px solid;
-  padding-inline-end: 5px;
-  display: flex;
-  flex-direction: row;
 }
 
 .heap-tree-item-count,
 .heap-tree-item-total-count {
   width: 8%;
 }
 
 .heap-tree-item-bytes,
 .heap-tree-item-total-bytes {
   width: 10%;
 }
 
 .heap-tree-item-name {
-  width: 50%;
-  padding-left: 5px;
+  /**
+   * Flex: contains an .arrow and some text, which need to be laid out
+   * horizontally, vertically aligned in the middle of the container.
+   */
+  display: flex;
+  align-items: center;
+  /**
+   * Flexing to fill out remaining vertical space.
+   * @see .header and .heap-tree-item */
+  flex: 1;
+  padding-inline-start: 5px;
+}
+
+/**
+ * Heap tree view subcolumns
+ */
+
+.heap-tree-number,
+.heap-tree-percent,
+.heap-tree-item-name {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 
+.heap-tree-number,
+.heap-tree-percent {
+  padding-inline-end: 5px;
+}
+
+.heap-tree-number {
+  flex: 1;
+  color: var(--theme-content-color3);
+}
+
+.heap-tree-percent {
+  width: 2.5em;
+}
+
+.heap-tree-item.focused .heap-tree-number,
+.heap-tree-item.focused .heap-tree-percent {
+  color: inherit;
+}
+
+/**
+ * Heap tree errors.
+ */
+
 .error::before {
   content: "";
   display: inline-block;
   width: 12px;
   height: 12px;
+  max-height: 12px;
   background-image: url(chrome://devtools/skin/themes/images/webconsole.svg);
   background-size: 72px 60px;
   background-position: -24px -24px;
   background-repeat: no-repeat;
   margin: 0px;
   margin-top: 2px;
   margin-inline-end: 5px;
-  max-height: 12px;
 }
 
 .theme-light .error::before {
   background-image: url(chrome://devtools/skin/themes/images/webconsole.svg#light-icons);
 }
 
 /**
  * Frame View components
@@ -327,33 +389,31 @@ html, body, #app, #memory-tool {
   color: var(--theme-highlight-blue);
   cursor: pointer;
 }
 
 .frame-link-filename:hover {
   text-decoration: underline;
 }
 
-.frame-link-column, .frame-link-line, .frame-link-colon {
+.frame-link-column,
+.frame-link-line,
+.frame-link-colon {
   color: var(--theme-highlight-orange);
 }
 
 .frame-link-host {
+  margin-inline-start: 5px;
   font-size: 90%;
-  margin-left: 5px;
   color: var(--theme-content-color2);
 }
 
 .frame-link-function-display-name {
-  margin-right: 5px;
+  margin-inline-end: 5px;
 }
 
 .no-allocation-stacks {
     border-color: var(--theme-splitter-color);
     border-style: solid;
     border-width: 0px 0px 1px 0px;
     text-align: center;
     padding: 5px;
 }
-
-label select {
-  margin: 5px;
-}
--- a/devtools/client/webide/content/details.js
+++ b/devtools/client/webide/content/details.js
@@ -1,18 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var Cu = Components.utils;
 Cu.import("resource://devtools/client/framework/gDevTools.jsm");
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
 const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
-const {AppValidator} = require("devtools/client/app-manager/app-validator");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {ProjectBuilding} = require("devtools/client/webide/modules/build");
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   document.addEventListener("visibilitychange", updateUI, true);
   AppManager.on("app-manager-update", onAppManagerUpdate);
   updateUI();
--- a/devtools/client/webide/content/newapp.js
+++ b/devtools/client/webide/content/newapp.js
@@ -8,18 +8,18 @@ var Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ZipUtils", "resource://gre/modules/ZipUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm");
 
 const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
+const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
+const {AppProjects} = require("devtools/client/webide/modules/app-projects");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const {getJSON} = require("devtools/client/shared/getjson");
 
 const TEMPLATES_URL = "devtools.webide.templatesURL";
 
 var gTemplateList = null;
 
 // See bug 989619
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -6,18 +6,18 @@ var Cc = Components.classes;
 var Cu = Components.utils;
 var Ci = Components.interfaces;
 
 Cu.import("resource://devtools/client/framework/gDevTools.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
 const {Toolbox} = require("devtools/client/framework/toolbox");
-const {Services} = Cu.import("resource://gre/modules/Services.jsm");
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
+const Services = require("Services");
+const {AppProjects} = require("devtools/client/webide/modules/app-projects");
 const {Connection} = require("devtools/shared/client/connection-manager");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const EventEmitter = require("devtools/shared/event-emitter");
 const promise = require("promise");
 const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor");
 const {GetAvailableAddons} = require("devtools/client/webide/modules/addons");
 const {getJSON} = require("devtools/client/shared/getjson");
 const utils = require("devtools/client/webide/modules/utils");
@@ -1150,9 +1150,16 @@ var Cmds = {
       Services.prefs.setCharPref("devtools.webide.zoom", UI.contentViewer.fullZoom);
     }
   },
 
   resetZoom: function() {
     UI.contentViewer.fullZoom = 1;
     Services.prefs.setCharPref("devtools.webide.zoom", 1);
   },
+
+  reloadDevtools: function(event) {
+    if (Services.prefs.prefHasUserValue("devtools.loader.srcdir")) {
+      let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+      devtools.reload();
+    }
+  }
 };
--- a/devtools/client/webide/content/webide.xul
+++ b/devtools/client/webide/content/webide.xul
@@ -53,16 +53,17 @@
       <command id="cmd_showPrefs" oncommand="Cmds.showPrefs()"/>
       <command id="cmd_showTroubleShooting" oncommand="Cmds.showTroubleShooting()"/>
       <command id="cmd_play" oncommand="Cmds.play()"/>
       <command id="cmd_stop" oncommand="Cmds.stop()" label="&projectMenu_stop_label;"/>
       <command id="cmd_toggleToolbox" oncommand="Cmds.toggleToolbox()"/>
       <command id="cmd_zoomin" label="&viewMenu_zoomin_label;" oncommand="Cmds.zoomIn()"/>
       <command id="cmd_zoomout" label="&viewMenu_zoomout_label;" oncommand="Cmds.zoomOut()"/>
       <command id="cmd_resetzoom" label="&viewMenu_resetzoom_label;" oncommand="Cmds.resetZoom()"/>
+      <command id="cmd_reload_devtools" oncommand="Cmds.reloadDevtools()"/>
     </commandset>
   </commandset>
 
   <menubar id="main-menubar">
     <menu id="menu-project" label="&projectMenu_label;" accesskey="&projectMenu_accesskey;">
       <menupopup id="menu-project-popup">
         <menuitem command="cmd_newApp" accesskey="&projectMenu_newApp_accesskey;"/>
         <menuitem command="cmd_importPackagedApp" accesskey="&projectMenu_importPackagedApp_accesskey;"/>
@@ -110,16 +111,17 @@
     <key key="&key_showProjectPanel;" id="key_showProjectPanel" command="cmd_showProjectPanel" modifiers="accel"/>
     <key key="&key_play;" id="key_play" command="cmd_play" modifiers="accel"/>
     <key key="&key_toggleEditor;" id="key_toggleEditor" command="cmd_toggleEditor" modifiers="accel"/>
     <key keycode="&key_toggleToolbox;" id="key_toggleToolbox" command="cmd_toggleToolbox"/>
     <key key="&key_zoomin;" id="key_zoomin" command="cmd_zoomin" modifiers="accel"/>
     <key key="&key_zoomin2;" id="key_zoomin2" command="cmd_zoomin" modifiers="accel"/>
     <key key="&key_zoomout;" id="key_zoomout" command="cmd_zoomout" modifiers="accel"/>
     <key key="&key_resetzoom;" id="key_resetzoom" command="cmd_resetzoom" modifiers="accel"/>
+    <key key="&key_reload_devtools;" id="key_reload_devtools" command="cmd_reload_devtools" modifiers="accel alt"/>
   </keyset>
 
   <tooltip id="aHTMLTooltip" page="true"/>
 
   <toolbar id="main-toolbar">
 
     <vbox flex="1">
       <hbox id="action-buttons-container" class="busy">
--- a/devtools/client/webide/modules/app-manager.js
+++ b/devtools/client/webide/modules/app-manager.js
@@ -1,41 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const {Cu} = require("chrome");
 
 const promise = require("promise");
 const {TargetFactory} = require("devtools/client/framework/target");
-const {Services} = Cu.import("resource://gre/modules/Services.jsm");
-const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
+const Services = require("Services");
+const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
 const EventEmitter = require("devtools/shared/event-emitter");
 const {TextEncoder, OS}  = Cu.import("resource://gre/modules/osfile.jsm", {});
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
+const {AppProjects} = require("devtools/client/webide/modules/app-projects");
 const TabStore = require("devtools/client/webide/modules/tab-store");
-const {AppValidator} = require("devtools/client/app-manager/app-validator");
+const {AppValidator} = require("devtools/client/webide/modules/app-validator");
 const {ConnectionManager, Connection} = require("devtools/shared/client/connection-manager");
 const {AppActorFront} = require("devtools/shared/apps/app-actor-front");
 const {getDeviceFront} = require("devtools/server/actors/device");
 const {getPreferenceFront} = require("devtools/server/actors/preference");
 const {getSettingsFront} = require("devtools/server/actors/settings");
 const {setTimeout} = require("sdk/timers");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 const {RuntimeScanners, RuntimeTypes} = require("devtools/client/webide/modules/runtimes");
 const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const Telemetry = require("devtools/client/shared/telemetry");
 const {ProjectBuilding} = require("./build");
 
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
 
 var AppManager = exports.AppManager = {
 
-  // FIXME: will break when devtools/app-manager will be removed:
-  DEFAULT_PROJECT_ICON: "chrome://devtools/skin/themes/app-manager/images/default-app-icon.png",
+  DEFAULT_PROJECT_ICON: "chrome://devtools/skin/themes/webide/default-app-icon.png",
   DEFAULT_PROJECT_NAME: "--",
 
   _initialized: false,
 
   init: function() {
     if (this._initialized) {
       return;
     }
rename from devtools/client/app-manager/app-projects.js
rename to devtools/client/webide/modules/app-projects.js
--- a/devtools/client/app-manager/app-projects.js
+++ b/devtools/client/webide/modules/app-projects.js
@@ -1,16 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 const {Cc,Ci,Cu,Cr} = require("chrome");
 const ObservableObject = require("devtools/client/shared/observable-object");
 const promise = require("devtools/shared/deprecated-sync-thenables");
 
-const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js");
+const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js", {});
 const {generateUUID} = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
-const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
-const { indexedDB } = require("sdk/indexed-db");
+const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
+const {indexedDB} = require("sdk/indexed-db");
 
 /**
  * IndexedDB wrapper that just save project objects
  *
  * The only constraint is that project objects have to have
  * a unique `location` object.
  */
 
rename from devtools/client/app-manager/app-validator.js
rename to devtools/client/webide/modules/app-validator.js
--- a/devtools/client/app-manager/app-validator.js
+++ b/devtools/client/webide/modules/app-validator.js
@@ -1,18 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 var {Ci,Cu,CC} = require("chrome");
 const promise = require("devtools/shared/deprecated-sync-thenables");
 
-const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
-const {Services} = Cu.import("resource://gre/modules/Services.jsm");
+const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
+const Services = require("Services");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 var XMLHttpRequest = CC("@mozilla.org/xmlextras/xmlhttprequest;1");
 var strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
 
 function AppValidator({ type, location }) {
   this.type = type;
   this.location = location;
   this.errors = [];
--- a/devtools/client/webide/modules/moz.build
+++ b/devtools/client/webide/modules/moz.build
@@ -2,16 +2,18 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'addons.js',
     'app-manager.js',
+    'app-projects.js',
+    'app-validator.js',
     'build.js',
     'config-view.js',
     'project-list.js',
     'runtime-list.js',
     'runtimes.js',
     'simulator-process.js',
     'simulators.js',
     'tab-store.js',
--- a/devtools/client/webide/modules/project-list.js
+++ b/devtools/client/webide/modules/project-list.js
@@ -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/. */
 
 const {Cu} = require("chrome");
 
-const {Services} = Cu.import("resource://gre/modules/Services.jsm");
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
+const Services = require("Services");
+const {AppProjects} = require("devtools/client/webide/modules/app-projects");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const promise = require("promise");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 const utils = require("devtools/client/webide/modules/utils");
 const Telemetry = require("devtools/client/shared/telemetry");
 
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
--- a/devtools/client/webide/modules/runtime-list.js
+++ b/devtools/client/webide/modules/runtime-list.js
@@ -1,16 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const {Cu} = require("chrome");
 
 const {Services} = Cu.import("resource://gre/modules/Services.jsm");
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
 const {AppManager} = require("devtools/client/webide/modules/app-manager");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {RuntimeScanners, WiFiScanner} = require("devtools/client/webide/modules/runtimes");
 const {Devices} = Cu.import("resource://devtools/shared/apps/Devices.jsm");
 const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
 const utils = require("devtools/client/webide/modules/utils");
 
 const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
--- a/devtools/client/webide/test/chrome.ini
+++ b/devtools/client/webide/test/chrome.ini
@@ -34,16 +34,17 @@ support-files =
   build_app_windows2/manifest.webapp
   build_app_windows2/package.json
   build_app_windows2/stage/empty-directory
   device_front_shared.js
   head.js
   hosted_app.manifest
   templates.json
   ../../shared/test/browser_devices.json
+  validator/*
 
 [test_basic.html]
 [test_newapp.html]
 skip-if = buildapp == 'b2g' || (os == "mac" && (os_version == "10.8" || os_version == "10.10") && debug) || (os == "win" && os_version == "10.0") # Bug 1135315, bug 1197053
 [test_import.html]
 [test_duplicate_import.html]
 [test_runtime.html]
 [test_manifestUpdate.html]
@@ -57,8 +58,9 @@ skip-if = true # Bug 1201392 - Update ad
 skip-if = true # Bug 1201392 - Update add-ons after migration
 [test_device_preferences.html]
 [test_device_settings.html]
 [test_fullscreenToolbox.html]
 [test_zoom.html]
 [test_build.html]
 [test_simulators.html]
 [test_toolbox.html]
+[test_app_validator.html]
--- a/devtools/client/webide/test/head.js
+++ b/devtools/client/webide/test/head.js
@@ -7,17 +7,17 @@ var {utils: Cu, classes: Cc, interfaces:
 
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 
 const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
 const {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {});
 const promise = require("promise");
-const {AppProjects} = require("devtools/client/app-manager/app-projects");
+const {AppProjects} = require("devtools/client/webide/modules/app-projects");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 DevToolsUtils.testing = true;
 
 var TEST_BASE;
 if (window.location === "chrome://browser/content/browser.xul") {
   TEST_BASE = "chrome://mochitests/content/browser/devtools/client/webide/test/";
 } else {
   TEST_BASE = "chrome://mochitests/content/chrome/devtools/client/webide/test/";
rename from devtools/client/app-manager/test/test_app_validator.html
rename to devtools/client/webide/test/test_app_validator.html
--- a/devtools/client/app-manager/test/test_app_validator.html
+++ b/devtools/client/webide/test/test_app_validator.html
@@ -15,17 +15,17 @@
 
     <script type="application/javascript;version=1.8">
     const Cu = Components.utils;
     const Cc = Components.classes;
     const Ci = Components.interfaces;
     Cu.import("resource://testing-common/httpd.js");
     const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
 
-    const {AppValidator} = require("devtools/client/app-manager/app-validator");
+    const {AppValidator} = require("devtools/client/webide/modules/app-validator");
     const {Services} = Cu.import("resource://gre/modules/Services.jsm");
     const nsFile = Components.Constructor("@mozilla.org/file/local;1",
                                            "nsILocalFile", "initWithPath");
     const cr = Cc["@mozilla.org/chrome/chrome-registry;1"]
                  .getService(Ci.nsIChromeRegistry);
     const strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
     let httpserver, origin;
 
rename from devtools/client/app-manager/test/validator/no-name-or-icon/home.html
rename to devtools/client/webide/test/validator/no-name-or-icon/home.html
rename from devtools/client/app-manager/test/validator/no-name-or-icon/manifest.webapp
rename to devtools/client/webide/test/validator/no-name-or-icon/manifest.webapp
rename from devtools/client/app-manager/test/validator/non-absolute-path/manifest.webapp
rename to devtools/client/webide/test/validator/non-absolute-path/manifest.webapp
rename from devtools/client/app-manager/test/validator/valid/alsoValid/manifest.webapp
rename to devtools/client/webide/test/validator/valid/alsoValid/manifest.webapp
rename from devtools/client/app-manager/test/validator/valid/home.html
rename to devtools/client/webide/test/validator/valid/home.html
rename from devtools/client/app-manager/test/validator/valid/icon.png
rename to devtools/client/webide/test/validator/valid/icon.png
rename from devtools/client/app-manager/test/validator/valid/manifest.webapp
rename to devtools/client/webide/test/validator/valid/manifest.webapp
rename from devtools/client/app-manager/test/validator/wrong-launch-path/icon.png
rename to devtools/client/webide/test/validator/wrong-launch-path/icon.png
rename from devtools/client/app-manager/test/validator/wrong-launch-path/manifest.webapp
rename to devtools/client/webide/test/validator/wrong-launch-path/manifest.webapp
--- a/devtools/client/webide/themes/deck.css
+++ b/devtools/client/webide/themes/deck.css
@@ -31,19 +31,20 @@ h1 {
   font-size: 2em;
   font-weight: lighter;
   line-height: 1.2;
   margin: 0;
   margin-bottom: .5em;
 }
 
 #controls {
-  position: absolute;
-  top: 10px;
-  right: 10px;
+  float: right;
+  position: relative;
+  top: -10px;
+  right: -10px;
 }
 
 #controls > a {
   color: #4C9ED9;
   font-size: small;
   cursor: pointer;
   border-bottom: 1px dotted;
   margin-left: 10px;
rename from devtools/client/themes/app-manager/images/default-app-icon.png
rename to devtools/client/webide/themes/default-app-icon.png
--- a/devtools/client/webide/themes/jar.mn
+++ b/devtools/client/webide/themes/jar.mn
@@ -14,8 +14,11 @@ webide.jar:
   skin/runtimedetails.css      (runtimedetails.css)
   skin/permissionstable.css    (permissionstable.css)
   skin/monitor.css             (monitor.css)
   skin/config-view.css         (config-view.css)
   skin/wifi-auth.css           (wifi-auth.css)
   skin/logs.css                (logs.css)
   skin/panel-listing.css       (panel-listing.css)
   skin/simulator.css           (simulator.css)
+  skin/rocket.svg              (rocket.svg)
+  skin/noise.png               (noise.png)
+  skin/default-app-icon.png    (default-app-icon.png)
rename from devtools/client/themes/app-manager/images/noise.png
rename to devtools/client/webide/themes/noise.png
rename from devtools/client/themes/app-manager/images/rocket.svg
rename to devtools/client/webide/themes/rocket.svg
--- a/devtools/client/webide/themes/webide.css
+++ b/devtools/client/webide/themes/webide.css
@@ -129,17 +129,17 @@ window.busy-determined #action-busy-unde
 [sidebar-displayed] {
   display: block;
 }
 
 /* Main view */
 
 #deck {
   background-color: rgb(225, 225, 225);
-  background-image: url('chrome://devtools/skin/themes/app-manager/images/rocket.svg'), url('chrome://devtools/skin/themes/app-manager/images/noise.png');
+  background-image: url('rocket.svg'), url('noise.png');
   background-repeat: no-repeat, repeat;
   background-size: 35%, auto;
   background-position: center center, top left;
 %ifndef XP_MACOSX
   border-top: 1px solid #AAA;
 %endif
 }
 
--- a/devtools/server/main.js
+++ b/devtools/server/main.js
@@ -953,16 +953,23 @@ var DebuggerServer = {
 
     let actor, childTransport;
     let prefix = aConnection.allocID("child");
     let netMonitor = null;
 
     // provides hook to actor modules that need to exchange messages
     // between e10s parent and child processes
     let onSetupInParent = function (msg) {
+      // We may have multiple connectToChild instance running for the same tab
+      // and need to filter the messages. Also the DebuggerServerConnection's
+      // prefix has an additional '/' and the end, so use `includes`.
+      if (!msg.json.prefix.includes(prefix)) {
+        return;
+      }
+
       let { module, setupParent } = msg.json;
       let m, fn;
 
       try {
         m = require(module);
 
         if (!setupParent in m) {
           dumpn("ERROR: module '" + module + "' does not export '" + setupParent + "'");
@@ -1736,21 +1743,22 @@ DebuggerServerConnection.prototype = {
    * @param module
    *        The module to be required
    * @param setupParent
    *        The name of the setup helper exported by the above module
    *        (setup helper signature: function ({mm}) { ... })
    * @return boolean
    *         true if the setup helper returned successfully
    */
-  setupInParent: function({ conn, module, setupParent }) {
+  setupInParent: function({ module, setupParent }) {
     if (!this.parentMessageManager) {
       return false;
     }
 
     let { sendSyncMessage } = this.parentMessageManager;
 
     return sendSyncMessage("debug:setup-in-parent", {
+      prefix: this.prefix,
       module: module,
       setupParent: setupParent
     });
   },
 };
--- a/devtools/server/tests/mochitest/test_preference.html
+++ b/devtools/server/tests/mochitest/test_preference.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <html>
 <!--
-Bug 943251 - Allow accessing about:config from app-manager
+Bug 943251 - Allow accessing about:config from WebIDE
 -->
 <head>
   <meta charset="utf-8">
   <title>Test Preference Actor</title>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
 <body>
--- a/devtools/shared/Loader.jsm
+++ b/devtools/shared/Loader.jsm
@@ -82,19 +82,17 @@ BuiltinProvider.prototype = {
       paths: {
         // When you add a line to this mapping, don't forget to make a
         // corresponding addition to the SrcdirProvider mapping below as well.
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
         "": "resource://gre/modules/commonjs/",
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
         "devtools": "resource://devtools",
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
-        "devtools/client": "resource://devtools/client",
-        // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
-        "gcli": "resource://devtools/gcli",
+        "gcli": "resource://devtools/shared/gcli/source/lib/gcli",
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
         "promise": "resource://gre/modules/Promise-backend.js",
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
         "acorn": "resource://devtools/acorn",
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
         "acorn/util/walk": "resource://devtools/acorn/walk.js",
         // ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
         "source-map": "resource://devtools/sourcemap/source-map.js",
@@ -423,22 +421,32 @@ DevToolsLoader.prototype = {
     events.emit("devtools-unloaded", {});
 
     this._provider.unload("reload");
     delete this._provider;
     delete this._mainid;
     this._chooseProvider();
     this.main("devtools/client/main");
 
-    // Reopen the toolbox automatically if requested
-    if (showToolbox) {
-      let { gBrowser } = Services.wm.getMostRecentWindow("navigator:browser");
-      let target = this.TargetFactory.forTab(gBrowser.selectedTab);
-      const { gDevTools } = this.require("resource://devtools/client/framework/gDevTools.jsm");
-      gDevTools.showToolbox(target);
+    let window = Services.wm.getMostRecentWindow(null);
+    let location = window.location.href;
+    if (location.includes("/browser.xul") && showToolbox) {
+      // Reopen the toolbox automatically if we are reloading from toolbox shortcut
+      // and are on a browser window.
+      // Wait for a second before opening the toolbox to avoid races
+      // between the old and the new one.
+      let {setTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
+      setTimeout(() => {
+        let { gBrowser } = window;
+        let target = this.TargetFactory.forTab(gBrowser.selectedTab);
+        const { gDevTools } = this.require("resource://devtools/client/framework/gDevTools.jsm");
+        gDevTools.showToolbox(target);
+      }, 1000);
+    } else if (location.includes("/webide.xul")) {
+      window.location.reload();
     }
   },
 
   /**
    * Sets whether the compartments loaded by this instance should be invisible
    * to the debugger.  Invisibility is needed for loaders that support debugging
    * of chrome code.  This is true of remote target environments, like Fennec or
    * B2G.  It is not the default case for desktop Firefox because we offer the
deleted file mode 100644
--- a/devtools/shared/gcli/gcli.jsm
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2012, Mozilla Foundation and contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = [ "gcli", "Requisition" ];
-
-var {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {});
-
-this.gcli = require('gcli/index');
-this.Requisition = require('gcli/cli').Requisition;
--- a/devtools/shared/gcli/moz.build
+++ b/devtools/shared/gcli/moz.build
@@ -1,110 +1,23 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += [
     'commands',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.commands += [
-    'source/lib/gcli/commands/clear.js',
-    'source/lib/gcli/commands/commands.js',
-    'source/lib/gcli/commands/connect.js',
-    'source/lib/gcli/commands/context.js',
-    'source/lib/gcli/commands/exec.js',
-    'source/lib/gcli/commands/global.js',
-    'source/lib/gcli/commands/help.js',
-    'source/lib/gcli/commands/intro.js',
-    'source/lib/gcli/commands/lang.js',
-    'source/lib/gcli/commands/mocks.js',
-    'source/lib/gcli/commands/pref.js',
-    'source/lib/gcli/commands/preflist.js',
-    'source/lib/gcli/commands/test.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.connectors += [
-    'source/lib/gcli/connectors/connectors.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.converters += [
-    'source/lib/gcli/converters/basic.js',
-    'source/lib/gcli/converters/converters.js',
-    'source/lib/gcli/converters/html.js',
-    'source/lib/gcli/converters/terminal.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.fields += [
-    'source/lib/gcli/fields/delegate.js',
-    'source/lib/gcli/fields/fields.js',
-    'source/lib/gcli/fields/selection.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.languages += [
-    'source/lib/gcli/languages/command.html',
-    'source/lib/gcli/languages/command.js',
-    'source/lib/gcli/languages/javascript.js',
-    'source/lib/gcli/languages/languages.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.mozui += [
-    'source/lib/gcli/mozui/completer.js',
-    'source/lib/gcli/mozui/inputter.js',
-    'source/lib/gcli/mozui/tooltip.js',
+    'source/lib/gcli',
+    'source/lib/gcli/connectors',
+    'source/lib/gcli/converters',
+    'source/lib/gcli/commands',
+    'source/lib/gcli/fields',
+    'source/lib/gcli/languages',
+    'source/lib/gcli/mozui',
+    'source/lib/gcli/types',
+    'source/lib/gcli/ui',
+    'source/lib/gcli/util',
 ]
 
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.types += [
-    'source/lib/gcli/types/array.js',
-    'source/lib/gcli/types/boolean.js',
-    'source/lib/gcli/types/command.js',
-    'source/lib/gcli/types/date.js',
-    'source/lib/gcli/types/delegate.js',
-    'source/lib/gcli/types/file.js',
-    'source/lib/gcli/types/fileparser.js',
-    'source/lib/gcli/types/javascript.js',
-    'source/lib/gcli/types/node.js',
-    'source/lib/gcli/types/number.js',
-    'source/lib/gcli/types/resource.js',
-    'source/lib/gcli/types/selection.js',
-    'source/lib/gcli/types/setting.js',
-    'source/lib/gcli/types/string.js',
-    'source/lib/gcli/types/types.js',
-    'source/lib/gcli/types/union.js',
-    'source/lib/gcli/types/url.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.ui += [
-    'source/lib/gcli/ui/focus.js',
-    'source/lib/gcli/ui/history.js',
-    'source/lib/gcli/ui/intro.js',
-    'source/lib/gcli/ui/menu.css',
-    'source/lib/gcli/ui/menu.html',
-    'source/lib/gcli/ui/menu.js',
-    'source/lib/gcli/ui/view.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli.util += [
-    'source/lib/gcli/util/domtemplate.js',
-    'source/lib/gcli/util/fileparser.js',
-    'source/lib/gcli/util/filesystem.js',
-    'source/lib/gcli/util/host.js',
-    'source/lib/gcli/util/l10n.js',
-    'source/lib/gcli/util/legacy.js',
-    'source/lib/gcli/util/prism.js',
-    'source/lib/gcli/util/spell.js',
-    'source/lib/gcli/util/util.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.gcli += [
-    'source/lib/gcli/cli.js',
-    'source/lib/gcli/index.js',
-    'source/lib/gcli/l10n.js',
-    'source/lib/gcli/settings.js',
-    'source/lib/gcli/system.js',
-]
-
-FINAL_TARGET_FILES.chrome.devtools.modules.devtools.shared.gcli += [
-    'gcli.jsm',
-    'Templater.jsm',
-]
+DevToolsModules(
+    'Templater.jsm'
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/commands/moz.build
@@ -0,0 +1,21 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'clear.js',
+    'commands.js',
+    'connect.js',
+    'context.js',
+    'exec.js',
+    'global.js',
+    'help.js',
+    'intro.js',
+    'lang.js',
+    'mocks.js',
+    'pref.js',
+    'preflist.js',
+    'test.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/connectors/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'connectors.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/converters/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'basic.js',
+    'converters.js',
+    'html.js',
+    'terminal.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/fields/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'delegate.js',
+    'fields.js',
+    'selection.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/languages/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'command.html',
+    'command.js',
+    'javascript.js',
+    'languages.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'cli.js',
+    'index.js',
+    'l10n.js',
+    'settings.js',
+    'system.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/mozui/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'completer.js',
+    'inputter.js',
+    'tooltip.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/types/moz.build
@@ -0,0 +1,25 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'array.js',
+    'boolean.js',
+    'command.js',
+    'date.js',
+    'delegate.js',
+    'file.js',
+    'fileparser.js',
+    'javascript.js',
+    'node.js',
+    'number.js',
+    'resource.js',
+    'selection.js',
+    'setting.js',
+    'string.js',
+    'types.js',
+    'union.js',
+    'url.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/ui/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'focus.js',
+    'history.js',
+    'intro.js',
+    'menu.css',
+    'menu.html',
+    'menu.js',
+    'view.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/shared/gcli/source/lib/gcli/util/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DevToolsModules(
+    'domtemplate.js',
+    'fileparser.js',
+    'filesystem.js',
+    'host.js',
+    'l10n.js',
+    'legacy.js',
+    'prism.js',
+    'spell.js',
+    'util.js',
+)
--- a/devtools/shared/tests/mochitest/test_loader_paths.html
+++ b/devtools/shared/tests/mochitest/test_loader_paths.html
@@ -38,15 +38,15 @@
         Cu.import("resource://devtools/shared/Loader.jsm", {});
 
       let builtin = new BuiltinProvider();
       builtin.load();
       let srcdir = new SrcdirProvider();
       srcdir.load();
 
       is(builtin.loader.mapping.length,
-         srcdir.loader.mapping.length + 2,
-         "The built-in loader has 2 additional mappings.");
+         srcdir.loader.mapping.length + 1,
+         "The built-in loader has one additional mappings.");
 
       Services.prefs.clearUserPref(SRCDIR_PREF);
     </script>
   </body>
 </html>
--- a/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/Launcher.java
+++ b/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/Launcher.java
@@ -9,16 +9,18 @@ import java.util.Date;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.KeyguardManager.KeyguardLock;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.location.Location;
+import android.location.LocationListener;
 import android.os.Bundle;
 import android.support.v4.app.FragmentActivity;
 import android.util.Log;
 import android.view.View;
 
 import org.json.JSONObject;
 import org.json.JSONException;
 
@@ -48,16 +50,44 @@ public class Launcher extends FragmentAc
     private SettingsMapper      mSettings;
 
     private static final long   kHomeRepeat = 2;
     private static final long   kHomeDelay  = 500; // delay in ms to tap kHomeRepeat times.
     private long                mFirstHome;
     private long                mLastHome;
     private long                mHomeCount;
 
+    final class GeckoInterface extends BaseGeckoInterface
+                               implements LocationListener {
+        public GeckoInterface(Context context) {
+            super(context);
+        }
+
+        public LocationListener getLocationListener() {
+            return this;
+        }
+
+        @Override
+        public void onLocationChanged(Location location) {
+            GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location));
+        }
+
+        @Override
+        public void onProviderDisabled(String provider) {
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {
+        }
+
+        @Override
+        public void onStatusChanged(String provider, int status, Bundle extras) {
+        }
+    }
+
     /** ContextGetter */
     public Context getContext() {
         return this;
     }
 
     public SharedPreferences getSharedPreferences() {
         return null;
     }
@@ -87,17 +117,17 @@ public class Launcher extends FragmentAc
         Log.w(LOGTAG, "onCreate");
         super.onCreate(savedInstanceState);
 
         IntentHelper.init(this);
         mScreenStateObserver = new ScreenStateObserver(this);
 
         initGecko();
 
-        GeckoAppShell.setGeckoInterface(new BaseGeckoInterface(this));
+        GeckoAppShell.setGeckoInterface(new GeckoInterface(this));
 
         UpdateServiceHelper.registerForUpdates(this);
 
         EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "Launcher:Ready");
 
         setContentView(R.layout.launcher);
 
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -248,17 +248,17 @@ public class GeckoEvent {
             PointF geckoPoint = new PointF(pt.x, pt.y);
             geckoPoint = GeckoAppShell.getLayerView().convertViewPointToLayerPoint(geckoPoint);
 
             if (geckoPoint == null) {
                 // This could happen if Gecko isn't ready yet.
                 return null;
             }
 
-            event.mPoints[0] = new Point(Math.round(geckoPoint.x), Math.round(geckoPoint.y));
+            event.mPoints[0] = new Point((int)Math.floor(geckoPoint.x), (int)Math.floor(geckoPoint.y));
 
             event.mX = size;
             event.mTime = System.currentTimeMillis();
             return event;
         } catch (Exception e) {
             // This can happen if Gecko isn't ready yet
             return null;
         }
@@ -329,17 +329,17 @@ public class GeckoEvent {
 
     private void addMotionPoint(int index, int eventIndex, MotionEvent event, boolean keepInViewCoordinates) {
         try {
             PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex));
             if (!keepInViewCoordinates) {
                 geckoPoint = GeckoAppShell.getLayerView().convertViewPointToLayerPoint(geckoPoint);
             }
 
-            mPoints[index] = new Point(Math.round(geckoPoint.x), Math.round(geckoPoint.y));
+            mPoints[index] = new Point((int)Math.floor(geckoPoint.x), (int)Math.floor(geckoPoint.y));
             mPointIndicies[index] = event.getPointerId(eventIndex);
 
             double radians = event.getOrientation(eventIndex);
             mOrientations[index] = (float) Math.toDegrees(radians);
             // w3c touchevents spec does not allow orientations == 90
             // this shifts it to -90, which will be shifted to zero below
             if (mOrientations[index] == 90)
                 mOrientations[index] = -90;
--- a/mobile/android/base/prompts/PromptInput.java
+++ b/mobile/android/base/prompts/PromptInput.java
@@ -12,16 +12,17 @@ import java.util.GregorianCalendar;
 import org.json.JSONObject;
 import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.widget.AllCapsTextView;
 import org.mozilla.gecko.widget.DateTimePicker;
 import org.mozilla.gecko.widget.FloatingHintEditText;
 
 import android.content.Context;
 import android.content.res.Configuration;
+import android.support.v7.widget.AppCompatCheckBox;
 import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.inputmethod.InputMethodManager;
@@ -141,17 +142,17 @@ public class PromptInput {
 
         public CheckboxInput(JSONObject obj) {
             super(obj);
             mChecked = obj.optBoolean("checked");
         }
 
         @Override
         public View getView(Context context) throws UnsupportedOperationException {
-            CheckBox checkbox = new CheckBox(context);
+            final CheckBox checkbox = new AppCompatCheckBox(context);
             checkbox.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
             checkbox.setText(mLabel);
             checkbox.setChecked(mChecked);
             mView = (View)checkbox;
             return mView;
         }
 
         @Override
--- a/mobile/android/base/resources/layout/default_doorhanger.xml
+++ b/mobile/android/base/resources/layout/default_doorhanger.xml
@@ -17,17 +17,18 @@
     <LinearLayout android:id="@+id/doorhanger_inputs"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:orientation="vertical"
               android:layout_marginTop="@dimen/doorhanger_section_padding_medium"
               android:gravity="right"
               android:visibility="gone"/>
 
-    <CheckBox android:id="@+id/doorhanger_checkbox"
+    <android.support.v7.widget.AppCompatCheckBox
+              android:id="@+id/doorhanger_checkbox"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_marginTop="@dimen/doorhanger_section_padding_medium"
               android:checked="true"
               android:textColor="@color/placeholder_active_grey"
               android:visibility="gone"/>
 
 </LinearLayout>
--- a/mobile/android/base/resources/layout/login_edit_dialog.xml
+++ b/mobile/android/base/resources/layout/login_edit_dialog.xml
@@ -16,15 +16,16 @@
               android:hint="@string/doorhanger_login_edit_username_hint"/>
 
     <EditText android:id="@+id/password_edit"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:inputType="textPassword"
               android:hint="@string/doorhanger_login_edit_password_hint"/>
 
-    <CheckBox android:id="@+id/checkbox_toggle_password"
+    <android.support.v7.widget.AppCompatCheckBox
+              android:id="@+id/checkbox_toggle_password"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@string/doorhanger_login_edit_toggle"
               android:layout_marginTop="@dimen/doorhanger_subsection_padding"/>
 
 </LinearLayout>
--- a/mobile/android/base/resources/layout/site_setting_item.xml
+++ b/mobile/android/base/resources/layout/site_setting_item.xml
@@ -36,17 +36,17 @@
             android:textAppearance="?android:attr/textAppearanceSmall"
             style="Widget.ListItem"
             android:gravity="center_vertical|left"
             android:singleLine="true"
             android:ellipsize="marquee"/>
 
     </LinearLayout>
 
-    <CheckBox
+    <android.support.v7.widget.AppCompatCheckBox
         android:id="@+id/checkbox"
         android:layout_width="35dip"
         android:layout_height="wrap_content"
         android:paddingRight="12dip"
         android:gravity="center_vertical"
         android:focusable="false"
         android:clickable="false"/>
 
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -1553,17 +1553,17 @@ function renderPayloadList(ping) {
   if (!ping.payload.childPayloads) {
     listEl.disabled = true;
     return
   }
   listEl.disabled = false;
 
   for (; payloadIndex <= ping.payload.childPayloads.length; ++payloadIndex) {
     option = document.createElement("option");
-    text = bundle.formatStringFromName("childPayload", [payloadIndex], 1);
+    text = bundle.formatStringFromName("childPayloadN", [payloadIndex], 1);
     content = document.createTextNode(text);
     option.appendChild(content);
     option.setAttribute("value", payloadIndex);
     listEl.appendChild(option);
   }
 }
 
 function displayPingData(ping, updatePayloadList = false) {
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
@@ -68,10 +68,10 @@ addonTableDetails = Details
 
 # Note to translators:
 # - The %1$S will be replaced with the name of an Add-on Provider (e.g. "XPI", "Plugin")
 addonProvider = %1$S Provider
 
 parentPayload = Parent Payload
 
 # Note to translators:
-# - The %1$s will be replaced with the number of the child payload (e.g. "1", "2")
-childPayload = Child Payload %1$s
+# - The %1$S will be replaced with the number of the child payload (e.g. "1", "2")
+childPayloadN = Child Payload %1$S