Merge m-c to inbound.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 26 Feb 2013 16:30:06 -0500
changeset 123084 920e402561568674a2b93e628de9c7fac33cc6cc
parent 123083 27c71bbc1675d83775337482b0a9998e90c52483 (diff)
parent 122990 55d8934477f6e323aed914720aed703e43f6d85a (current diff)
child 123085 6f0afe551e178f12c6fefa947bd0c6c1f13fc1c1
push id24372
push useremorley@mozilla.com
push dateWed, 27 Feb 2013 13:22:59 +0000
treeherdermozilla-central@0a91da5f5eab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to inbound.
--- a/b2g/config/otoro/releng-otoro.tt
+++ b/b2g/config/otoro/releng-otoro.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 895408640,
-"digest": "fc5be04b9b8365cd65fa8e66f4686bf0da8e34abb16ee618dd069469c9d9c9c3495562ebfcd21a2beadb27d59d6c011781188b9038ffebfd3e85cdd264f0aac3",
+"size": 896038748,
+"digest": "a153b55e13938c608d0d449073142322470aaf6c77375165df83dc845d9c357d0cf4754db3b058d4707442cd6252fe3076e81a22c32cb34bd3df6432ad5b99f1",
 "algorithm": "sha512",
 "filename": "gonk.tar.xz"
 },
 {
 "size": 4139008,
 "digest": "6f65553e882316582b944e46c659915a1b907c4a326104cb31d81356330dddacba757e3eafbd282063da0e670c3c5d6b9a0905ab88da84b47848d810c37571cb",
 "algorithm": "sha512",
 "filename": "boot.img"
--- a/b2g/config/otoro/sources.xml
+++ b/b2g/config/otoro/sources.xml
@@ -1,109 +1,110 @@
 <?xml version="1.0" ?><manifest>
   <!-- This is only a record of which revisions were pulled to generate the
        gonk.tar.xz snapshot referred to by releng-otoro.tt -->
 
   <remote fetch="https://android.googlesource.com/" name="aosp"/>
-  <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
+  <remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
+  <remote fetch="git://github.com/mozilla-b2g/" name="b2ggithub"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
   <remote fetch="git://codeaurora.org/" name="caf"/>
   <remote fetch="git://android.git.linaro.org/" name="linaro"/>
-  <remote fetch="https://git.mozilla.org" name="mozillaorg"/>
+  <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
 
   <!-- Gonk specific things and forks -->
-  <project name="platform_build" path="build" remote="b2g" revision="273ba23d5c6c9f6a34995a3cc429804d1449ca9f">
+  <project name="platform_build" path="build" remote="b2g" revision="43434d6cdbf702e6197e0791f19406860284edf6">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="654358494ba601a46ef9838debc95417ae464cc6"/>
-  <project name="rilproxy" path="rilproxy" remote="b2g" revision="32106d4ea635ebe17a1610b643b398db639b8b97"/>
-  <project name="librecovery" path="librecovery" remote="b2g" revision="e1bd90051c9e937221eb1f91c94e3cde747311a7"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
+  <!-- Information: fake-dalvik is tagged with B2G_1_0_0_20130125190500 --><project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c6fc2e70b2586fe45db4b676567be2aa94cf420e"/>
+  <project name="rilproxy" path="rilproxy" remote="b2g" revision="f634b3d50effdd42828cc757c01fdbf74e562a36"/>
+  <!-- Information: librecovery is tagged with B2G_1_0_0_20130125190500 --><project name="librecovery" path="librecovery" remote="b2g" revision="601fc18b28c9d7cf6954b281ddd3b705c74a9215"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="62f94a26d34c1f1e1846efd58d34363c051e8c66"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <!-- Information: platform/bionic is tagged with M8960AAAAANLYA100715A --><project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <!-- Information: platform/bootable/recovery is tagged with M8960AAAAANLYA100715A --><project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <!-- Information: platform/development is tagged with M8960AAAAANLYA100715A --><project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
-  <!-- Information: device/common is tagged with M8960AAAAANLYA1005304 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
+  <!-- Information: device/common is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <!-- Information: device/sample is tagged with M8960AAAAANLYA100715A --><project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
-  <!-- Information: platform/external/apache-http is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/apache-http" path="external/apache-http" revision="6c9d8c58d3ed710f87c26820d903bb8aad81754f"/>
+  <project name="platform_external_apriori" path="external/apriori" remote="b2ggithub" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
   <!-- Information: platform/external/bluetooth/bluez is tagged with M76XXUSNEKNLYA2040 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="1023c91c66e9c3bd1132480051993bf7827770f6"/>
-  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
-  <!-- Information: platform/external/bluetooth/hcidump is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
-  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
-  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
+  <!-- Information: platform/external/bluetooth/hcidump is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
+  <!-- Information: platform/external/bsdiff is tagged with A8064AAAAANLYA102313 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
+  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
   <!-- Information: platform/external/dbus is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dbus" path="external/dbus" revision="c7517b6195dc6926728352113e6cc335da3f9c9e"/>
   <!-- Information: platform/external/dhcpcd is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="1e00fb67022d0921af0fead263f81762781b9ffa"/>
-  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
-  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
-  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
-  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
-  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
-  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
-  <!-- Information: platform/external/gtest is tagged with android-4.2.1_r1 --><project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="344e5f3db17615cc853073a02968a603efd39109"/>
-  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
-  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
-  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
-  <!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
-  <!-- Information: platform/external/jpeg is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
-  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
-  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
-  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
-  <!-- Information: platform/external/libphonenumber is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libphonenumber" path="external/libphonenumber" revision="8d22c9a05eda1935c6dc27d188158e6ee38dc016"/>
+  <!-- Information: platform/external/dnsmasq is tagged with A8064AAAAANLYA102313 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2ggithub" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
+  <project name="platform_external_elfutils" path="external/elfutils" remote="b2ggithub" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
+  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
+  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
+  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
+  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
+  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with A8064AAAAANLYA102313 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
+  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
+  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
+  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/jpeg is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
+  <!-- Information: platform/external/libgsm is tagged with A8064AAAAANLYA102313 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.134 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
+  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.134 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
   <!-- Information: platform/external/libpng is tagged with M8960AAAAANLYA100715A --><project name="platform/external/libpng" path="external/libpng" revision="9c3730f0efa69f580f03463c237cd928f3196404"/>
-  <!-- Information: platform/external/libvpx is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
-  <!-- Information: platform/external/llvm is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
-  <!-- Information: platform/external/mksh is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
-  <project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
+  <!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
+  <!-- Information: platform/external/llvm is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
+  <!-- Information: platform/external/mksh is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
+  <!-- Information: platform_external_opensans is tagged with B2G_1_0_0_20130125190500 --><project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
   <!-- Information: platform/external/openssl is tagged with AU_LINUX_ANDROID_ICS.04.00.04.00.110 --><project name="platform/external/openssl" path="external/openssl" revision="27d333cce9a31c806b4bfa042925f045c727aecd"/>
-  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
-  <project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
+  <!-- Information: platform/external/protobuf is tagged with A8064AAAAANLYA102313 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with A8064AAAAANLYA102313 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: screencap-gonk is tagged with B2G_1_0_0_20130125190500 --><project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
   <!-- Information: platform/external/skia is tagged with M8960AAAAANLYA100715A --><project name="platform/external/skia" path="external/skia" revision="7d90c85f2c0e3b747f7c7eff8bc9253b0063b439"/>
-  <!-- Information: platform/external/sonivox is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
-  <!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/sonivox is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
+  <!-- Information: platform/external/speex is tagged with A8064AAAAANLYA102313 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
   <project name="platform/external/sqlite" path="external/sqlite" revision="fb30e613139b8836fdc8e81e166cf3a76e5fa17f"/>
-  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
-  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
-  <!-- Information: platform/external/tinyalsa is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
-  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
-  <project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
-  <!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
-  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
-  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
+  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.134 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/tinyalsa is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
+  <!-- Information: platform/external/tremolo is tagged with A8064AAAAANLYA102313 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: unbootimg is tagged with B2G_1_0_0_20130125190500 --><project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
+  <!-- Information: platform/external/webp is tagged with A8064AAAAANLYA102313 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
+  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
+  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
   <!-- Information: platform/external/hostap is tagged with M8960AAAAANLYA1047 --><project name="platform/external/hostap" path="external/hostap" revision="bf04b0faadbdeb4b7943f2e2c4c5aa59df872bb1"/>
-  <!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
-  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
+  <!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
+  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
   <!-- Information: platform/frameworks/base is tagged with M76XXUSNEKNLYA2040 --><project name="platform/frameworks/base" path="frameworks/base" revision="eb2bc75803ca179353c24c364a9c8a8ce23e8b78"/>
-  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
-  <!-- Information: platform/frameworks/support is tagged with M8960AAAAANLYA1005304 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
+  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
+  <!-- Information: platform/frameworks/support is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
   <!-- Information: platform/hardware/libhardware is tagged with M8960AAAAANLYA1049B --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="4a619901847621f8a7305edf42dd07347a140484"/>
   <!-- Information: platform/hardware/libhardware_legacy is tagged with M8960AAAAANLYA153611 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="87b4d7afa8f854b445e2d0d95091f6f6069f2b30"/>
   <!-- Information: platform/libcore is tagged with M8960AAAAANLYA100715A --><project name="platform/libcore" path="libcore" revision="30841f9fba9ccd5c54f4f079f495994db97f283e"/>
-  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
-  <!-- Information: platform/prebuilt is tagged with M8960AAAAANLYA1005304 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
+  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
+  <!-- Information: platform/prebuilt is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
   <!-- Information: platform/system/bluetooth is tagged with M8960AAAAANLYA100703 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="7772cad4823f1f427ce1d4df84a55982386d6d18"/>
   <!-- Information: platform/system/core is tagged with M76XXUSNEKNLYA2040 --><project name="platform/system/core" path="system/core" revision="bf1970408676ce570b8f4dc3efa038e47552137f"/>
-  <!-- Information: platform/system/extras is tagged with M8960AAAAANLYA1005304 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
-  <!-- Information: platform/system/media is tagged with M8960AAAAANLYA1005304 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
+  <!-- Information: platform/system/extras is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
+  <!-- Information: platform/system/media is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
   <!-- Information: platform/system/netd is tagged with M8960AAAAANLYA1049 --><project name="platform/system/netd" path="system/netd" revision="306e765248e3900041bf2737e9f57b1b5694a4ce"/>
   <!-- Information: platform/system/vold is tagged with M8960AAAAANLYA100715A --><project name="platform/system/vold" path="system/vold" revision="99fff257d53cc045d1460841edca5d901dacfcf5"/>
 
   <!-- Otoro/Unagi specific things -->
   <!-- Information: device/qcom/common is tagged with M8960AAAAANLYA100715A --><project name="device/qcom/common" path="device/qcom/common" revision="b9cdab8e1e1a215a8c65b8d5816f666bec7be205"/>
   <!-- Information: platform/vendor/qcom/msm7627a is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="d920a502ba17cf4d716f8b1a615f07e796b0501a"/>
-  <project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="e3e99b264dd0230108aa78f2b653db4ce0e494fb"/>
-  <project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="e74925a10e11a4f0bc56158c248bd20c521d3dd7"/>
-  <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
+  <!-- Information: android-device-otoro is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="7662275433fc0b1d8b035f03185b24b7ca965ab4"/>
+  <!-- Information: android-device-unagi is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="6c014552d1b26bee611d9a9b23bd4cd014e392ee"/>
+  <!-- Information: codeaurora_kernel_msm is tagged with B2G_1_0_0_20130125190500 --><project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
   <!-- Information: platform/hardware/qcom/camera is tagged with M76XXUSNEKNLYA2040 --><project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="1acf77a75e30f3fc8b1eed2057c97adf1cb1633f"/>
-  <project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
+  <!-- Information: hardware_qcom_display is tagged with B2G_1_0_0_20130125190500 --><project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
   <!-- Information: platform/hardware/qcom/media is tagged with M8960AAAAANLYA100715A --><project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="552c3ddb7174a01f3508782d40c4d8c845ab441a"/>
   <!-- Information: platform/hardware/qcom/gps is tagged with M8960AAAAANLYA100705 --><project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="23d5707b320d7fc69f8ba3b7d84d78a1c5681708"/>
-  <!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
+  <!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
   <!-- Information: platform/vendor/qcom-opensource/omx/mm-core is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom-opensource/omx/mm-core" path="vendor/qcom/opensource/omx/mm-core" revision="ab17ac9a074b4bb69986a8436336bdfbbaf9cd39"/>
   <!-- Information: platform/hardware/ril is tagged with M76XXUSNEKNLYA1610 --><project name="platform/hardware/ril" path="hardware/ril" remote="caf" revision="fe9a3f63922143b57e79ed570bab2328df8c83a5"/>
 </manifest>
\ No newline at end of file
--- a/b2g/config/panda/releng-pandaboard.tt
+++ b/b2g/config/panda/releng-pandaboard.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 678628568,
-"digest": "e0b98a75831313171781d91ab4c3b8ae66e3af7fcec433a33d75fbc647cb3bba311f790ccb9cd9c8be8c5549210b759d6b85afe7395ada74c2c319a29556fd8e",
+"size": 677418796,
+"digest": "34f8e675382cbd6acc8803a540c9ecd51641f24679b3803ff585176c1ba5b869989bed070ee6db79f70d4875d16ad6b4cb2e676e24caca4012874574d3899d2c",
 "algorithm": "sha512",
 "filename": "gonk.tar.xz"
 },
 {
 "size": 2116507,
 "digest": "be67a012963a5c162834f9fcb989bcebd2d047dcb4e17ee23031b694dcf7cdfd6d7a6545d7a1f5e7293b6d24415403972f4ea1ab8c6c78fefcabfaf3f6875214",
 "algorithm": "sha512",
 "filename": "download-panda.tar.bz2"
--- a/b2g/config/panda/sources.xml
+++ b/b2g/config/panda/sources.xml
@@ -1,99 +1,101 @@
 <?xml version="1.0" ?><manifest>
   <!-- This is only a record of which revisions were pulled to generate the
        gonk.tar.xz snapshot referred to by releng-pandaboard.tt -->
 
   <remote fetch="https://android.googlesource.com/" name="aosp"/>
   <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
   <remote fetch="git://android.git.linaro.org/" name="linaro"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
-  <remote fetch="http://git.mozilla.org/" name="mozillaorg"/>
+  <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="linaro" 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="0784cdcb29ae45e5bf903cc03fa1bc206162665b">
+  <project name="platform_build" path="build" remote="b2g" revision="43434d6cdbf702e6197e0791f19406860284edf6">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2f8c7d3546bda16b02a61b422786919875c19f15"/>
-  <project name="rilproxy" path="rilproxy" remote="b2g" revision="2d380d27c86263537f6b829cd0238f5dd702c735"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
+  <!-- Information: fake-dalvik is tagged with B2G_1_0_0_20130125190500 --><project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c6fc2e70b2586fe45db4b676567be2aa94cf420e"/>
+  <project name="rilproxy" path="rilproxy" remote="b2g" revision="f634b3d50effdd42828cc757c01fdbf74e562a36"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="62f94a26d34c1f1e1846efd58d34363c051e8c66"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
-  <!-- Information: platform/bionic is tagged with android-4.0.4_r2.1 --><project name="platform/bionic" path="bionic" revision="3d11bf0f3f3cf848f6f1e8449bf8736d8d1c78a3"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <project name="platform/bionic" path="bionic" revision="c7bab8cb8483e7869eabdbd4add7c9e5beeecc80"/>
   <!-- Information: platform/bootable/recovery is tagged with android-4.0.4_r2.1 --><project name="platform/bootable/recovery" path="bootable/recovery" revision="fadc5ac81d6400ebdd041f7d4ea64021596d6b7d"/>
   <!-- Information: device/common is tagged with android-sdk-adt_r20 --><project name="device/common" path="device/common" revision="7d4526582f88808a3194e1a3b304abb369d2745c"/>
   <!-- Information: device/sample is tagged with android-4.0.4_r2.1 --><project name="device/sample" path="device/sample" revision="ef228b8b377a9663e94be4b1aeb6c2bf7a07d098"/>
-  <!-- Information: platform/external/apache-http is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/apache-http" path="external/apache-http" revision="6c9d8c58d3ed710f87c26820d903bb8aad81754f"/>
+  <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
   <!-- Information: platform/external/bluetooth/bluez is tagged with android-4.0.4_r2.1 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="966afbd88f0bfc325bf80274ad2723c238883fa1"/>
   <!-- Information: platform/external/bluetooth/glib is tagged with android-4.1.1_r6.1 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="1143b9918eab068401b604eb11c3f651f4e38b25"/>
   <!-- Information: platform/external/bluetooth/hcidump is tagged with android-4.1.1_r6.1 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="7322661808c2006b7848e79e6bb72b37fbcf6710"/>
-  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
-  <project name="platform/external/busybox" path="external/busybox" remote="linaro" revision="0a41b083cdaf2ddd602fb5c955329494da25f2b9"/>
-  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
+  <project name="platform/external/busybox" path="external/busybox" remote="linaro" revision="2e461c8029a50d986dfe4ab07ae5a1834b5c40f0"/>
+  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
   <!-- Information: platform/external/dbus is tagged with android-4.1.1_r6.1 --><project name="platform/external/dbus" path="external/dbus" revision="537eaff5de9aace3348436166d4cde7adc1e488e"/>
   <!-- Information: platform/external/dhcpcd is tagged with android-sdk-adt_r20 --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="ddaa48f57b54b2862b3e6dcf18a44c9647f3baaa"/>
-  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
-  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
-  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
-  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
-  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
-  <!-- Information: platform/external/gtest is tagged with android-sdk-support_r11 --><project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="344e5f3db17615cc853073a02968a603efd39109"/>
+  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2g" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
+  <project name="platform_external_elfutils" path="external/elfutils" remote="b2g" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
+  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
+  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
+  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
+  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
   <!-- Information: platform/external/harfbuzz is tagged with android-sdk-adt_r20 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="bae491c03a00757d83ede8d855b7d85d246bde3d"/>
-  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
-  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
-  <!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
+  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
+  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/jhead is tagged with android-4.0.4_r2.1 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
   <!-- Information: platform/external/jpeg is tagged with android-4.1.1_r6.1 --><project name="platform/external/jpeg" path="external/jpeg" revision="d4fad7f50f79626455d88523207e05b868819cd8"/>
-  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with android-sdk-support_r11 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
   <!-- Information: platform/external/libnfc-nxp is tagged with android-4.0.4_r2.1 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="533c14450e6239cce8acb74f4e4dea2c89f8f219"/>
-  <!-- Information: platform/external/libnl-headers is tagged with android-sdk-support_r11 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
-  <!-- Information: platform/external/libphonenumber is tagged with android-4.0.4_r2.1 --><project name="platform/external/libphonenumber" path="external/libphonenumber" revision="d470984844c388d6766c3de6ac64e93e00480fc9"/>
+  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
   <!-- Information: platform/external/libpng is tagged with android-4.0.4_r2.1 --><project name="platform/external/libpng" path="external/libpng" revision="84d92c718ab9f48faec0f640747c4b6f7a995607"/>
-  <!-- Information: platform/external/libvpx is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
+  <!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
   <!-- Information: platform/external/mksh is tagged with M8960AAAAANLYA1099D --><project name="platform/external/mksh" path="external/mksh" revision="5155f1c7438ef540d7b25eb70aa1639579795b07"/>
-  <project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
+  <!-- Information: platform_external_opensans is tagged with B2G_1_0_0_20130125190500 --><project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
   <!-- Information: platform/external/openssl is tagged with android-4.0.4_r2.1 --><project name="platform/external/openssl" path="external/openssl" revision="ce96fb211b9a44bbd7fb5ef7ed0e6c1244045c2e"/>
-  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
-  <project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
+  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: screencap-gonk is tagged with B2G_1_0_0_20130125190500 --><project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
   <!-- Information: platform/external/skia is tagged with android-4.0.4_r2.1 --><project name="platform/external/skia" path="external/skia" revision="5c67a309e16bffe7013defda8f1217b3ce2420b4"/>
   <!-- Information: platform/external/sonivox is tagged with android-sdk-adt_r20 --><project name="platform/external/sonivox" path="external/sonivox" revision="5f9600971859fe072f31b38a51c38157f5f9b381"/>
-  <!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/speex is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
   <!-- Information: platform/external/sqlite is tagged with android-4.0.4_r2.1 --><project name="platform/external/sqlite" path="external/sqlite" revision="c999ff8c12a4cf81cb9ad628f47b2720effba5e5"/>
-  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
-  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with android-sdk-support_r11 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
+  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
   <!-- Information: platform/external/tinyalsa is tagged with android-4.0.4_r2.1 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="495239e683a728957c890c124b239f9b7b8ef5a8"/>
-  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
-  <!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.041 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
+  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: platform/external/webp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
   <!-- Information: platform/external/webrtc is tagged with android-sdk-adt_r20 --><project name="platform/external/webrtc" path="external/webrtc" revision="4b6dc1ec58105d17dc8c2f550124cc0621dc93b7"/>
-  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="6dd24fc3792d71edccef9b09140f9a44b063a553"/>
   <!-- Information: platform/external/zlib is tagged with android-4.0.4_r2.1 --><project name="platform/external/zlib" path="external/zlib" revision="69e5801bd16a495e1c1666669fe827b1ddb8d56b"/>
   <!-- Information: platform/external/yaffs2 is tagged with android-4.0.4-aah_r1 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="6232e2d5ab34a40d710e4b05ab0ec6e3727804e7"/>
   <!-- Information: platform/frameworks/base is tagged with android-4.0.4_r2.1 --><project name="platform/frameworks/base" path="frameworks/base" revision="df331873c8576e0ae34ae1ee3cc258beed373535"/>
-  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.138 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
+  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
   <!-- Information: platform/frameworks/support is tagged with android-4.0.4_r2.1 --><project name="platform/frameworks/support" path="frameworks/support" revision="bfc8e01b7b0d5ea70ce89d0409b72b7f7d540f43"/>
   <!-- Information: platform/hardware/libhardware is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="a9b677fce432b29ab8f61e13796f34880dc0fe0f"/>
   <!-- Information: platform/hardware/libhardware_legacy is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="153d0f1a27e0a157cabb6ca9d0d88248630f5695"/>
   <!-- Information: platform/hardware/ril is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/ril" path="hardware/ril" revision="300105d1487f5238940c18792b879793826b61f4"/>
   <!-- Information: platform/libcore is tagged with android-4.0.4_r2.1 --><project name="platform/libcore" path="libcore" revision="fc294a48d80d9e2b2ac126edf93ad316f5f6cf72"/>
   <!-- Information: platform/ndk is tagged with android-4.0.4_r2.1 --><project name="platform/ndk" path="ndk" revision="2d77f5a05f60029c981f299b222cfe28db18ccf7"/>
   <!-- Information: platform/prebuilt is tagged with tungsten-bootloader-ics-aah --><project name="platform/prebuilt" path="prebuilt" revision="0e104261b6d33f87e9f86ff4249bcc0306ab278b"/>
   <!-- Information: platform/system/bluetooth is tagged with android-4.0.4_r2.1 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="2588cd802f322650ed737dfb7a10e9ad94064e99"/>
   <!-- Information: platform/system/core is tagged with android-4.0.4_r2.1 --><project name="platform/system/core" path="system/core" revision="c2db4ffb874783220abf967ca4ccd0e6cf1ba57f"/>
   <!-- Information: platform/system/extras is tagged with android-4.0.4_r2.1 --><project name="platform/system/extras" path="system/extras" revision="fa351ab265957fa8815df3c4ca1f3c105f253e8b"/>
   <!-- Information: platform/system/media is tagged with android-4.0.4_r2.1 --><project name="platform/system/media" path="system/media" revision="a8eea50f80327f15cb04bbdfee2d1cfcc4c3ce4a"/>
   <!-- Information: platform/system/netd is tagged with android-4.0.4_r2.1 --><project name="platform/system/netd" path="system/netd" revision="3c903b555975fa59d6688a0a6417ac7512c202e7"/>
   <!-- Information: platform/system/vold is tagged with android-4.0.4_r2.1 --><project name="platform/system/vold" path="system/vold" revision="3ad9072a5d6f6bda32123b367545649364e3c11d"/>
 
   <!-- Pandaboard specific things -->
-  <project name="android-device-panda" path="device/ti/panda" remote="b2g" revision="0e9a89187970d6fa99930c8d9cb438b935c2337c"/>
+  <project name="android-device-panda" path="device/ti/panda" remote="b2g" revision="eec93d3e9eb7765f63415e2ad42003a00b5996b4"/>
   <!-- Information: platform/hardware/ti/omap4xxx is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/ti/omap4xxx" path="hardware/ti/omap4xxx" revision="8be8e9a68c96b6cf43c08a58e7ecd7708737c599"/>
   <project name="platform/hardware/ti/wlan" path="hardware/ti/wlan" revision="60dfeb6e4448bfed707946ebca6612980f525e69"/>
   <project name="platform/hardware/ti/wpan" path="hardware/ti/wpan" revision="3ece7d9e08052989401e008bc397dbcd2557cfd0"/>
-  <project name="Negatus" path="external/negatus" remote="mozilla" revision="151697c638a6781e83c76d4a01fb001aabde4e79"/>
-  
+  <project name="Negatus" path="external/negatus" remote="mozilla" revision="83e11def08ae4bc590adda8dfc1de661585adb53"/>
+  <project name="orangutan" path="external/orangutan" remote="b2g" revision="1735c3c4d6008d7f9e929d55ed0e06b995156fa2"/>
+
 </manifest>
\ No newline at end of file
--- a/b2g/config/unagi/releng-unagi.tt
+++ b/b2g/config/unagi/releng-unagi.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 832272360,
-"digest": "bb7369106d32a184c61fc8c6658c4d1c64dd778e432a3dd39592b99a92ed0a8f4a9fede60399ec2c85ddaf077f27d77613848b253f0ac155383b23955446396f",
+"size": 832866776,
+"digest": "27b9e0754de94537d664d12f5e3a2767582ceedb4ee96eb06abe405e6e9b8a0937d56ffd84cb6ce4d197c25168124296806b1ad638175b004a11ab5293b99f08",
 "algorithm": "sha512",
 "filename": "gonk.tar.xz"
 },
 {
 "size": 8622080,
 "digest": "36681be904b20a52dbebf38b86466026430d59adb0e72428ae7557a442d037eb378d278aab181b04a753821ff0a99b6228380d59f86ddd5fbf291284fe54932b",
 "algorithm": "sha512",
 "filename": "boot.img"
--- a/b2g/config/unagi/sources.xml
+++ b/b2g/config/unagi/sources.xml
@@ -1,109 +1,110 @@
 <?xml version="1.0" ?><manifest>
   <!-- This is only a record of which revisions were pulled to generate the
        gonk.tar.xz snapshot referred to by releng-unagi.tt -->
 
   <remote fetch="https://android.googlesource.com/" name="aosp"/>
-  <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
+  <remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
+  <remote fetch="git://github.com/mozilla-b2g/" name="b2ggithub"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
-  <remote fetch="http://git.mozilla.org/" name="mozillaorg"/>
   <remote fetch="git://codeaurora.org/" name="caf"/>
   <remote fetch="git://android.git.linaro.org/" name="linaro"/>
+  <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
 
   <!-- Gonk specific things and forks -->
-  <project name="platform_build" path="build" remote="b2g" revision="0784cdcb29ae45e5bf903cc03fa1bc206162665b">
+  <project name="platform_build" path="build" remote="b2g" revision="43434d6cdbf702e6197e0791f19406860284edf6">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2f8c7d3546bda16b02a61b422786919875c19f15"/>
-  <project name="rilproxy" path="rilproxy" remote="b2g" revision="2d380d27c86263537f6b829cd0238f5dd702c735"/>
-  <project name="librecovery" path="librecovery" remote="b2g" revision="601fc18b28c9d7cf6954b281ddd3b705c74a9215"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
+  <!-- Information: fake-dalvik is tagged with B2G_1_0_0_20130125190500 --><project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8f016ce56fc7d7ef0aa7428ed509f6fb7cbde5b7"/>
+  <project name="rilproxy" path="rilproxy" remote="b2g" revision="f634b3d50effdd42828cc757c01fdbf74e562a36"/>
+  <!-- Information: librecovery is tagged with B2G_1_0_0_20130125190500 --><project name="librecovery" path="librecovery" remote="b2g" revision="601fc18b28c9d7cf6954b281ddd3b705c74a9215"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="62f94a26d34c1f1e1846efd58d34363c051e8c66"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <!-- Information: platform/bionic is tagged with M8960AAAAANLYA100715A --><project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <!-- Information: platform/bootable/recovery is tagged with M8960AAAAANLYA100715A --><project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <!-- Information: platform/development is tagged with M8960AAAAANLYA100715A --><project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
-  <!-- Information: device/common is tagged with M8960AAAAANLYA1005304 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
+  <!-- Information: device/common is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <!-- Information: device/sample is tagged with M8960AAAAANLYA100715A --><project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
-  <!-- Information: platform/external/apache-http is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/apache-http" path="external/apache-http" revision="6c9d8c58d3ed710f87c26820d903bb8aad81754f"/>
+  <project name="platform_external_apriori" path="external/apriori" remote="b2ggithub" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
   <!-- Information: platform/external/bluetooth/bluez is tagged with M76XXUSNEKNLYA2040 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="1023c91c66e9c3bd1132480051993bf7827770f6"/>
-  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
-  <!-- Information: platform/external/bluetooth/hcidump is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
-  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
-  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
+  <!-- Information: platform/external/bluetooth/hcidump is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
+  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
+  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
   <!-- Information: platform/external/dbus is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dbus" path="external/dbus" revision="c7517b6195dc6926728352113e6cc335da3f9c9e"/>
   <!-- Information: platform/external/dhcpcd is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="1e00fb67022d0921af0fead263f81762781b9ffa"/>
-  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
-  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
-  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
-  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
-  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
-  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
-  <!-- Information: platform/external/gtest is tagged with android-sdk-support_r11 --><project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="344e5f3db17615cc853073a02968a603efd39109"/>
-  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
-  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
-  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
-  <!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
-  <!-- Information: platform/external/jpeg is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
-  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
-  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
-  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
-  <!-- Information: platform/external/libphonenumber is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/libphonenumber" path="external/libphonenumber" revision="8d22c9a05eda1935c6dc27d188158e6ee38dc016"/>
+  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2ggithub" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
+  <project name="platform_external_elfutils" path="external/elfutils" remote="b2ggithub" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
+  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
+  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
+  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
+  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
+  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
+  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
+  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
+  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/jpeg is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
+  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
+  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
   <!-- Information: platform/external/libpng is tagged with M8960AAAAANLYA100715A --><project name="platform/external/libpng" path="external/libpng" revision="9c3730f0efa69f580f03463c237cd928f3196404"/>
   <!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
-  <!-- Information: platform/external/llvm is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
-  <!-- Information: platform/external/mksh is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
-  <project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
+  <!-- Information: platform/external/llvm is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
+  <!-- Information: platform/external/mksh is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
+  <!-- Information: platform_external_opensans is tagged with B2G_1_0_0_20130125190500 --><project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
   <!-- Information: platform/external/openssl is tagged with AU_LINUX_ANDROID_ICS.04.00.04.00.110 --><project name="platform/external/openssl" path="external/openssl" revision="27d333cce9a31c806b4bfa042925f045c727aecd"/>
-  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
-  <project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
+  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: screencap-gonk is tagged with B2G_1_0_0_20130125190500 --><project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
   <!-- Information: platform/external/skia is tagged with M8960AAAAANLYA100715A --><project name="platform/external/skia" path="external/skia" revision="7d90c85f2c0e3b747f7c7eff8bc9253b0063b439"/>
-  <!-- Information: platform/external/sonivox is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
-  <!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/sonivox is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
+  <!-- Information: platform/external/speex is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
   <project name="platform/external/sqlite" path="external/sqlite" revision="fb30e613139b8836fdc8e81e166cf3a76e5fa17f"/>
-  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
-  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
-  <!-- Information: platform/external/tinyalsa is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
-  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
-  <project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
-  <!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.081 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
-  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
-  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
+  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/tinyalsa is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
+  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: unbootimg is tagged with B2G_1_0_0_20130125190500 --><project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
+  <!-- Information: platform/external/webp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
+  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
+  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
   <!-- Information: platform/external/hostap is tagged with M8960AAAAANLYA1047 --><project name="platform/external/hostap" path="external/hostap" revision="bf04b0faadbdeb4b7943f2e2c4c5aa59df872bb1"/>
-  <!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
-  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
+  <!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
+  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
   <!-- Information: platform/frameworks/base is tagged with M76XXUSNEKNLYA2040 --><project name="platform/frameworks/base" path="frameworks/base" revision="eb2bc75803ca179353c24c364a9c8a8ce23e8b78"/>
-  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
-  <!-- Information: platform/frameworks/support is tagged with M8960AAAAANLYA1005304 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
+  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
+  <!-- Information: platform/frameworks/support is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
   <!-- Information: platform/hardware/libhardware is tagged with M8960AAAAANLYA1049B --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="4a619901847621f8a7305edf42dd07347a140484"/>
   <!-- Information: platform/hardware/libhardware_legacy is tagged with M8960AAAAANLYA153611 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="87b4d7afa8f854b445e2d0d95091f6f6069f2b30"/>
   <!-- Information: platform/libcore is tagged with M8960AAAAANLYA100715A --><project name="platform/libcore" path="libcore" revision="30841f9fba9ccd5c54f4f079f495994db97f283e"/>
-  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
-  <!-- Information: platform/prebuilt is tagged with M8960AAAAANLYA1005304 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
+  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
+  <!-- Information: platform/prebuilt is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
   <!-- Information: platform/system/bluetooth is tagged with M8960AAAAANLYA100703 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="7772cad4823f1f427ce1d4df84a55982386d6d18"/>
   <!-- Information: platform/system/core is tagged with M76XXUSNEKNLYA2040 --><project name="platform/system/core" path="system/core" revision="bf1970408676ce570b8f4dc3efa038e47552137f"/>
-  <!-- Information: platform/system/extras is tagged with M8960AAAAANLYA1005304 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
-  <!-- Information: platform/system/media is tagged with M8960AAAAANLYA1005304 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
+  <!-- Information: platform/system/extras is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
+  <!-- Information: platform/system/media is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
   <!-- Information: platform/system/netd is tagged with M8960AAAAANLYA1049 --><project name="platform/system/netd" path="system/netd" revision="306e765248e3900041bf2737e9f57b1b5694a4ce"/>
   <!-- Information: platform/system/vold is tagged with M8960AAAAANLYA100715A --><project name="platform/system/vold" path="system/vold" revision="99fff257d53cc045d1460841edca5d901dacfcf5"/>
 
   <!-- Otoro/Unagi specific things -->
   <!-- Information: device/qcom/common is tagged with M8960AAAAANLYA100715A --><project name="device/qcom/common" path="device/qcom/common" revision="b9cdab8e1e1a215a8c65b8d5816f666bec7be205"/>
   <!-- Information: platform/vendor/qcom/msm7627a is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="d920a502ba17cf4d716f8b1a615f07e796b0501a"/>
-  <project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="7662275433fc0b1d8b035f03185b24b7ca965ab4"/>
-  <project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="6c014552d1b26bee611d9a9b23bd4cd014e392ee"/>
-  <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
+  <!-- Information: android-device-otoro is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="7662275433fc0b1d8b035f03185b24b7ca965ab4"/>
+  <!-- Information: android-device-unagi is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="6c014552d1b26bee611d9a9b23bd4cd014e392ee"/>
+  <!-- Information: codeaurora_kernel_msm is tagged with B2G_1_0_0_20130125190500 --><project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
   <!-- Information: platform/hardware/qcom/camera is tagged with M76XXUSNEKNLYA2040 --><project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="1acf77a75e30f3fc8b1eed2057c97adf1cb1633f"/>
-  <project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
+  <!-- Information: hardware_qcom_display is tagged with B2G_1_0_0_20130125190500 --><project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
   <!-- Information: platform/hardware/qcom/media is tagged with M8960AAAAANLYA100715A --><project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="552c3ddb7174a01f3508782d40c4d8c845ab441a"/>
   <!-- Information: platform/hardware/qcom/gps is tagged with M8960AAAAANLYA100705 --><project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="23d5707b320d7fc69f8ba3b7d84d78a1c5681708"/>
-  <!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.183 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
+  <!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
   <!-- Information: platform/vendor/qcom-opensource/omx/mm-core is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom-opensource/omx/mm-core" path="vendor/qcom/opensource/omx/mm-core" revision="ab17ac9a074b4bb69986a8436336bdfbbaf9cd39"/>
   <!-- Information: platform/hardware/ril is tagged with M76XXUSNEKNLYA1610 --><project name="platform/hardware/ril" path="hardware/ril" remote="caf" revision="fe9a3f63922143b57e79ed570bab2328df8c83a5"/>
 </manifest>
\ No newline at end of file
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -317,22 +317,23 @@ function openLinkIn(url, where, params) 
                        postData: aPostData,
                        inBackground: loadInBackground,
                        allowThirdPartyFixup: aAllowThirdPartyFixup,
                        relatedToCurrent: aRelatedToCurrent,
                        isUTF8: aIsUTF8});
     break;
   }
 
-  // If this window is active, focus the target window. Otherwise, focus the
-  // content but don't raise the window, since the URI we just loaded may have
-  // resulted in a new frontmost window (e.g. "javascript:window.open('');").
+  // If this window is active, or the user created a new tab, focus the target
+  // window. Otherwise, focus the content but don't raise the window, since the
+  // URI we just loaded may have resulted in a new frontmost window
+  // (e.g. "javascript:window.open('');").
   var fm = Components.classes["@mozilla.org/focus-manager;1"].
              getService(Components.interfaces.nsIFocusManager);
-  if (window == fm.activeWindow)
+  if (window == fm.activeWindow || isBlankPageURL(url))
     w.focus();
   w.gBrowser.selectedBrowser.focus();
 
   if (!loadInBackground && isBlankPageURL(url))
     w.focusAndSelectUrlBar();
 }
 
 // Used as an onclick handler for UI elements with link-like behavior.
--- a/build/autoconf/config.status.m4
+++ b/build/autoconf/config.status.m4
@@ -108,16 +108,22 @@ substs = [(name[1:-1], value[1:-1]) for 
 EOF
 
 dnl The MOZ_DIVERSION_SUBST output diversion contains AC_SUBSTs, in the
 dnl expected format, but lacks the final comma (see above).
 sed 's/$/,/' >> $CONFIG_STATUS <<EOF
 undivert(MOZ_DIVERSION_SUBST)dnl
 EOF
 
+dnl Add in the output from the subconfigure script
+for ac_subst_arg in $_subconfigure_ac_subst_args; do
+  variable='$'$ac_subst_arg
+  echo "    (''' $ac_subst_arg ''', r''' `eval echo $variable` ''')," >> $CONFIG_STATUS
+done
+
 cat >> $CONFIG_STATUS <<\EOF
 ] ]
 
 dnl List of files to apply AC_SUBSTs to. This is the list of files given
 dnl as an argument to AC_OUTPUT ($1)
 files = [
 EOF
 
new file mode 100644
--- /dev/null
+++ b/build/autoconf/subconfigure.m4
@@ -0,0 +1,46 @@
+dnl We are not running in a real autoconf environment. So we're using real m4
+dnl here, not the crazier environment that autoconf provides.
+
+dnl Autoconf expects [] for quotes; give it to them
+changequote([, ])
+
+dnl AC_DEFUN is provided to use instead of define in autoconf. Provide it too.
+define([AC_DEFUN], [define($1, [$2])])
+
+dnl AC_ARG_ENABLE(FEATURE, HELP-STRING, IF-TRUE[, IF-FALSE])
+dnl We have to ignore the help string due to how help works in autoconf...
+AC_DEFUN([AC_ARG_ENABLE],
+[#] Check whether --enable-[$1] or --disable-[$1] was given.
+[if test "[${enable_]patsubst([$1], -, _)+set}" = set; then
+  enableval="[$enable_]patsubst([$1], -, _)"
+  $3
+ifelse([$4], , , [else
+  $4
+])dnl
+fi
+])
+
+dnl AC_MSG_ERROR(error-description)
+AC_DEFUN([AC_MSG_ERROR], [{ echo "configure: error: $1" 1>&2; exit 1; }])
+
+AC_DEFUN([AC_MSG_WARN],  [ echo "configure: warning: $1" 1>&2 ])
+
+dnl Add the variable to the list of substitution variables
+AC_DEFUN([AC_SUBST],
+[
+_subconfigure_ac_subst_args="$_subconfigure_ac_subst_args $1"
+])
+
+dnl Override for AC_DEFINE.
+AC_DEFUN([AC_DEFINE],
+[
+cat >>confdefs.h <<\EOF
+[#define] $1 ifelse($#, 2, [$2], $#, 3, [$2], 1)
+EOF
+cat >> confdefs.pytmp <<\EOF
+    (''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
+EOF
+])
+
+dnl AC_OUTPUT_SUBDIRS(subdirectory)
+AC_DEFUN([AC_OUTPUT_SUBDIRS], [do_output_subdirs "$1"])
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -118,25 +118,25 @@ class RemoteAutomation(Automation):
         return found_exception
 
     def checkForCrashes(self, directory, symbolsPath):
         logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters)
         javaException = self.checkForJavaException(logcat)
         if javaException:
             return True
         try:
+            dumpDir = tempfile.mkdtemp()
             remoteCrashDir = self._remoteProfile + '/minidumps/'
             if not self._devicemanager.dirExists(remoteCrashDir):
                 # As of this writing, the minidumps directory is automatically
                 # created when fennec (first) starts, so its lack of presence
                 # is a hint that something went wrong.
                 print "Automation Error: No crash directory (%s) found on remote device" % remoteCrashDir
                 # Whilst no crash was found, the run should still display as a failure
                 return True
-            dumpDir = tempfile.mkdtemp()
             self._devicemanager.getDirectory(remoteCrashDir, dumpDir)
             crashed = automationutils.checkForCrashes(dumpDir, symbolsPath,
                                             self.lastTestSeen)
         finally:
             try:
                 shutil.rmtree(dumpDir)
             except:
                 print "WARNING: unable to remove directory: %s" % dumpDir
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -487,18 +487,17 @@ nsPrincipal::SetDomain(nsIURI* aDomain)
   mDomain = NS_TryToMakeImmutable(aDomain);
   mDomainImmutable = URIIsImmutable(mDomain);
 
   // Domain has changed, forget cached security policy
   SetSecurityPolicy(nullptr);
 
   // Recompute all wrappers between compartments using this principal and other
   // non-chrome compartments.
-  JSContext *cx = nsContentUtils::GetSafeJSContext();
-  NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
+  SafeAutoJSContext cx;
   JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
   bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
                                        js::CompartmentsWithPrincipals(principals));
   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
   success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
                                   js::ContentCompartmentsOnly());
   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
 
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -21,16 +21,17 @@
 #include "nsNetCID.h"
 #include "nsIClassInfoImpl.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDocument.h"
 #include "jsfriendapi.h"
 #include "xpcprivate.h"
+#include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 
 ///////////////////////
 // nsSecurityNameSet //
 ///////////////////////
@@ -59,17 +60,17 @@ static JSFunctionSpec PrivilegeManager_s
 
 /*
  * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege,
  * et al. so that code that worked with 4.0 can still work.
  */
 NS_IMETHODIMP 
 nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext)
 {
-    JSContext* cx = aScriptContext->GetNativeContext();
+    AutoPushJSContext cx(aScriptContext->GetNativeContext());
     JSObject *global = JS_ObjectToInnerObject(cx, JS_GetGlobalObject(cx));
 
     /*
      * Find Object.prototype's class by walking up the global object's
      * prototype chain.
      */
     JSObject *obj = global;
     JSObject *proto;
--- a/configure.in
+++ b/configure.in
@@ -4356,16 +4356,33 @@ AC_SUBST(MOZ_UPDATE_CHANNEL)
 AC_MSG_CHECKING([if app-specific confvars.sh exists])
 if test -f "${srcdir}/${MOZ_BUILD_APP}/confvars.sh" ; then
   AC_MSG_RESULT([${srcdir}/${MOZ_BUILD_APP}/confvars.sh])
   . "${srcdir}/${MOZ_BUILD_APP}/confvars.sh"
 else
   AC_MSG_RESULT([no])
 fi
 
+# Allow the application to provide a subconfigure script
+if test -f "${srcdir}/${MOZ_BUILD_APP}/configure.in" ; then
+  do_output_subdirs() {
+    if test -n "$_subconfigure_subdirs"; then
+      AC_MSG_ERROR([Cannot specify more than one sub-sub-configure])
+     fi
+    _subconfigure_subdir="$1"
+    _subconfigure_config_args="$ac_configure_args"
+  }
+  tmpscript=`mktemp -t subscript.XXXXXX` || exit 1
+  m4 "${srcdir}/build/autoconf/subconfigure.m4" \
+     "${srcdir}/build/autoconf/altoptions.m4" \
+     "${srcdir}/${MOZ_BUILD_APP}/configure.in" > $tmpscript
+  . $tmpscript
+  rm -f $tmpscript
+fi
+
 # Allow someone to change MOZ_APP_NAME and MOZ_APP_BASENAME in mozconfig
 MOZ_ARG_WITH_STRING(app-name,
 [--with-app-name=APPNAME sets MOZ_APP_NAME to APPNAME],
 WITH_APP_NAME=$withval,
 )
 
 if test -n "$WITH_APP_NAME" ; then
     MOZ_APP_NAME="$WITH_APP_NAME"
@@ -9201,16 +9218,24 @@ if test -z "$direct_nspr_config"; then
     HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
     HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
     RC=
 fi
 
 unset MAKEFILES
 unset CONFIG_FILES
 
+# Run all configure scripts specified by a subconfigure
+if test -n "$_subconfigure_subdir"; then
+  _save_ac_configure_args="$ac_configure_args"
+  ac_configure_args="$_subconfigure_config_args"
+  AC_OUTPUT_SUBDIRS("$_subconfigure_subdir")
+  ac_configure_args="$_save_ac_configure_args"
+fi
+
 # No need to run subconfigures when building with LIBXUL_SDK_DIR
 if test "$COMPILE_ENVIRONMENT" -a -z "$LIBXUL_SDK_DIR"; then
 
 export WRAP_LDFLAGS
 
 if test -n "$_WRAP_MALLOC"; then
     # Avoid doubling wrap malloc arguments
     _SUBDIR_CONFIG_ARGS="`echo $_SUBDIR_CONFIG_ARGS | sed -e 's/--enable-wrap-malloc *//'`"
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -2200,27 +2200,27 @@ public:
 
   // Returns false if something erroneous happened.
   bool Push(nsIDOMEventTarget *aCurrentTarget);
   // If nothing has been pushed to stack, this works like Push.
   // Otherwise if context will change, Pop and Push will be called.
   bool RePush(nsIDOMEventTarget *aCurrentTarget);
   // If a null JSContext is passed to Push(), that will cause no
   // push to happen and false to be returned.
-  bool Push(JSContext *cx, bool aRequiresScriptContext = true);
+  void Push(JSContext *cx);
   // Explicitly push a null JSContext on the the stack
-  bool PushNull();
+  void PushNull();
 
   // Pop() will be a no-op if Push() or PushNull() fail
   void Pop();
 
   nsIScriptContext* GetCurrentScriptContext() { return mScx; }
 private:
   // Combined code for PushNull() and Push(JSContext*)
-  bool DoPush(JSContext* cx);
+  void DoPush(JSContext* cx);
 
   nsCOMPtr<nsIScriptContext> mScx;
   bool mScriptIsRunning;
   bool mPushedSomething;
 #ifdef DEBUG
   JSContext* mPushedContext;
   unsigned mCompartmentDepthOnEntry;
 #endif
@@ -2297,16 +2297,43 @@ private:
  * SafeAutoJSContext is similar to AutoJSContext but will only return the safe
  * JS context. That means it will never call ::GetCurrentJSContext().
  */
 class NS_STACK_CLASS SafeAutoJSContext : public AutoJSContext {
 public:
   SafeAutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
 };
 
+/**
+ * Use AutoPushJSContext when you want to use a specific JSContext that may or
+ * may not be already on the stack. This differs from nsCxPusher in that it only
+ * pushes in the case that the given cx is not the active cx on the JSContext
+ * stack, which avoids an expensive JS_SaveFrameChain in the common case.
+ *
+ * Most consumers of this should probably just use AutoJSContext. But the goal
+ * here is to preserve the existing behavior while ensure proper cx-stack
+ * semantics in edge cases where the context being used doesn't match the active
+ * context.
+ *
+ * NB: This will not push a null cx even if aCx is null. Make sure you know what
+ * you're doing.
+ */
+class NS_STACK_CLASS AutoPushJSContext {
+  nsCxPusher mPusher;
+  JSContext* mCx;
+
+public:
+    AutoPushJSContext(JSContext* aCx) : mCx(aCx) {
+      if (mCx && mCx != nsContentUtils::GetCurrentJSContext()) {
+        mPusher.Push(mCx);
+      }
+    }
+    operator JSContext*() { return mCx; }
+};
+
 } // namespace mozilla
 
 #define NS_INTERFACE_MAP_ENTRY_TEAROFF(_interface, _allocator)                \
   if (aIID.Equals(NS_GET_IID(_interface))) {                                  \
     foundInterface = static_cast<_interface *>(_allocator);                   \
     if (!foundInterface) {                                                    \
       *aInstancePtr = nullptr;                                                 \
       return NS_ERROR_OUT_OF_MEMORY;                                          \
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -1222,17 +1222,17 @@ EventSource::DispatchAllMessageEvents()
 
   // Let's play get the JSContext
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
   NS_ENSURE_TRUE_VOID(sgo);
 
   nsIScriptContext* scriptContext = sgo->GetContext();
   NS_ENSURE_TRUE_VOID(scriptContext);
 
-  JSContext* cx = scriptContext->GetNativeContext();
+  AutoPushJSContext cx(scriptContext->GetNativeContext());
   NS_ENSURE_TRUE_VOID(cx);
 
   while (mMessagesToDispatch.GetSize() > 0) {
     nsAutoPtr<Message>
       message(static_cast<Message*>(mMessagesToDispatch.PopFront()));
 
     // Now we can turn our string into a jsval
     jsval jsData;
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -876,17 +876,17 @@ WebSocket::CreateAndDispatchMessageEvent
 
   // Get the JSContext
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
   NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
 
   nsIScriptContext* scriptContext = sgo->GetContext();
   NS_ENSURE_TRUE(scriptContext, NS_ERROR_FAILURE);
 
-  JSContext* cx = scriptContext->GetNativeContext();
+  AutoPushJSContext cx(scriptContext->GetNativeContext());
   NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
   // Create appropriate JS object for message
   jsval jsData;
   {
     JSAutoRequest ar(cx);
     if (isBinary) {
       if (mBinaryType == BinaryTypeValues::Blob) {
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3010,29 +3010,24 @@ nsCxPusher::Push(nsIDOMEventTarget *aCur
       DoPush(cx);
     }
 
     // Nothing to do here, I guess.  Have to return true so that event firing
     // will still work correctly even if there is no associated JSContext
     return true;
   }
 
-  JSContext* cx = nullptr;
-
-  if (scx) {
-    cx = scx->GetNativeContext();
-    // Bad, no JSContext from script context!
-    NS_ENSURE_TRUE(cx, false);
-  }
+  JSContext* cx = scx ? scx->GetNativeContext() : nullptr;
 
   // If there's no native context in the script context it must be
   // in the process or being torn down. We don't want to notify the
   // script context about scripts having been evaluated in such a
   // case, calling with a null cx is fine in that case.
-  return Push(cx);
+  Push(cx);
+  return true;
 }
 
 bool
 nsCxPusher::RePush(nsIDOMEventTarget *aCurrentTarget)
 {
   if (!mPushedSomething) {
     return Push(aCurrentTarget);
   }
@@ -3053,74 +3048,60 @@ nsCxPusher::RePush(nsIDOMEventTarget *aC
       return true;
     }
   }
 
   Pop();
   return Push(aCurrentTarget);
 }
 
-bool
-nsCxPusher::Push(JSContext *cx, bool aRequiresScriptContext)
-{
-  if (mPushedSomething) {
-    NS_ERROR("Whaaa! No double pushing with nsCxPusher::Push()!");
-
-    return false;
-  }
-
-  if (!cx) {
-    return false;
-  }
+void
+nsCxPusher::Push(JSContext *cx)
+{
+  MOZ_ASSERT(!mPushedSomething, "No double pushing with nsCxPusher::Push()!");
+  MOZ_ASSERT(cx);
 
   // Hold a strong ref to the nsIScriptContext, just in case
   // XXXbz do we really need to?  If we don't get one of these in Pop(), is
   // that really a problem?  Or do we need to do this to effectively root |cx|?
   mScx = GetScriptContextFromJSContext(cx);
-  if (!mScx && aRequiresScriptContext) {
-    // Should probably return false. See bug 416916.
-    return true;
-  }
-
-  return DoPush(cx);
-}
-
-bool
+
+  DoPush(cx);
+}
+
+void
 nsCxPusher::DoPush(JSContext* cx)
 {
   nsIThreadJSContextStack* stack = nsContentUtils::ThreadJSContextStack();
   if (!stack) {
-    return true;
+    return;
   }
 
   if (cx && IsContextOnStack(stack, cx)) {
     // If the context is on the stack, that means that a script
     // is running at the moment in the context.
     mScriptIsRunning = true;
   }
 
   if (NS_FAILED(stack->Push(cx))) {
-    mScriptIsRunning = false;
-    mScx = nullptr;
-    return false;
+    MOZ_CRASH();
   }
 
   mPushedSomething = true;
 #ifdef DEBUG
   mPushedContext = cx;
   if (cx)
     mCompartmentDepthOnEntry = js::GetEnterCompartmentDepth(cx);
 #endif
-  return true;
-}
-
-bool
+}
+
+void
 nsCxPusher::PushNull()
 {
-  return DoPush(nullptr);
+  DoPush(nullptr);
 }
 
 void
 nsCxPusher::Pop()
 {
   nsIThreadJSContextStack* stack = nsContentUtils::ThreadJSContextStack();
   if (!mPushedSomething || !stack) {
     mScx = nullptr;
@@ -6426,18 +6407,18 @@ nsContentUtils::FindInternalContentViewe
 // static
 bool
 nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
                                   nsIDocument* aDocument)
 {
   NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)");
   NS_ENSURE_TRUE(aDocument->GetScriptGlobalObject(), true);
 
-  JSContext* cx = aDocument->GetScriptGlobalObject()->
-                                  GetContext()->GetNativeContext();
+  AutoPushJSContext cx(aDocument->GetScriptGlobalObject()->
+                       GetContext()->GetNativeContext());
   NS_ENSURE_TRUE(cx, true);
 
   JSAutoRequest ar(cx);
 
   // The pattern has to match the entire value.
   aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0);
   aPattern.Append(NS_LITERAL_STRING(")$"));
 
@@ -6833,20 +6814,17 @@ AutoJSContext::Init(bool aSafe MOZ_GUARD
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
   if (!aSafe) {
     mCx = nsContentUtils::GetCurrentJSContext();
   }
 
   if (!mCx) {
     mCx = nsContentUtils::GetSafeJSContext();
-    bool result = mPusher.Push(mCx);
-    if (!result || !mCx) {
-      MOZ_CRASH();
-    }
+    mPusher.Push(mCx);
   }
 }
 
 AutoJSContext::operator JSContext*()
 {
   return mCx;
 }
 
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -40,16 +40,18 @@ extern PRLogModuleInfo* GetDataChannelLo
 
 #include "DataChannel.h"
 
 #ifdef GetBinaryType
 // Windows apparently has a #define for GetBinaryType...
 #undef GetBinaryType
 #endif
 
+using namespace mozilla;
+
 class nsDOMDataChannel : public nsDOMEventTargetHelper,
                          public nsIDOMDataChannel,
                          public mozilla::DataChannelListener
 {
 public:
   nsDOMDataChannel(already_AddRefed<mozilla::DataChannel> aDataChannel)
     : mDataChannel(aDataChannel)
     , mBinaryType(DC_BINARY_TYPE_BLOB)
@@ -388,17 +390,17 @@ nsDOMDataChannel::DoOnMessageAvailable(c
     return NS_OK;
   }
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
   NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
 
   nsIScriptContext* sc = sgo->GetContext();
   NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
 
-  JSContext* cx = sc->GetNativeContext();
+  AutoPushJSContext cx(sc->GetNativeContext());
   NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
   JSAutoRequest ar(cx);
   jsval jsData;
 
   if (aBinary) {
     if (mBinaryType == DC_BINARY_TYPE_BLOB) {
       rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3978,29 +3978,18 @@ nsDocument::SetScriptGlobalObject(nsIScr
 
 #ifdef DEBUG
     if (!mWillReparent) {
       // We really shouldn't have a wrapper here but if we do we need to make sure
       // it has the correct parent.
       JSObject *obj = GetWrapperPreserveColor();
       if (obj) {
         JSObject *newScope = aScriptGlobalObject->GetGlobalJSObject();
-        nsIScriptContext *scx = aScriptGlobalObject->GetContext();
-        JSContext *cx = scx ? scx->GetNativeContext() : nullptr;
-        if (!cx) {
-          nsContentUtils::ThreadJSContextStack()->Peek(&cx);
-          if (!cx) {
-            cx = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext();
-            NS_ASSERTION(cx, "Uhoh, no context, this is bad!");
-          }
-        }
-        if (cx) {
-          NS_ASSERTION(JS_GetGlobalForObject(cx, obj) == newScope,
-                       "Wrong scope, this is really bad!");
-        }
+        NS_ASSERTION(js::GetGlobalForObjectCrossCompartment(obj) == newScope,
+                     "Wrong scope, this is really bad!");
       }
     }
 #endif
 
     if (mAllowDNSPrefetch) {
       nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
       if (docShell) {
 #ifdef DEBUG
@@ -6169,16 +6158,17 @@ private:
  * @param aOldDocument The document to try to get a context from.
  * @param aNewDocument The document to get aNewScope from.
  * @param aCx [out] Context gotten through one of the scopes, from the stack
  *                  or the safe context.
  * @param aNewScope [out] Scope gotten from aNewDocument.
  */
 static nsresult
 GetContextAndScope(nsIDocument* aOldDocument, nsIDocument* aNewDocument,
+                   nsCxPusher& aPusher,
                    JSContext** aCx, JSObject** aNewScope)
 {
   MOZ_ASSERT(aOldDocument);
   MOZ_ASSERT(aNewDocument);
 
   *aCx = nullptr;
   *aNewScope = nullptr;
 
@@ -6211,16 +6201,19 @@ GetContextAndScope(nsIDocument* aOldDocu
           NS_WARNING("No context reachable in GetContextAndScopes()!");
 
           return NS_ERROR_NOT_AVAILABLE;
         }
       }
     }
   }
 
+  if (cx) {
+    aPusher.Push(cx);
+  }
   if (!newScope && cx) {
     JS::Value v;
     nsresult rv = nsContentUtils::WrapNative(cx, global, aNewDocument,
                                              aNewDocument, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
     newScope = JSVAL_TO_OBJECT(v);
   }
@@ -6344,18 +6337,19 @@ nsIDocument::AdoptNode(nsINode& aAdopted
     }
   }
 
   nsCOMPtr<nsIDocument> oldDocument = adoptedNode->OwnerDoc();
   bool sameDocument = oldDocument == this;
 
   JSContext *cx = nullptr;
   JSObject *newScope = nullptr;
+  nsCxPusher pusher;
   if (!sameDocument) {
-    rv = GetContextAndScope(oldDocument, this, &cx, &newScope);
+    rv = GetContextAndScope(oldDocument, this, pusher, &cx, &newScope);
     if (rv.Failed()) {
       return nullptr;
     }
   }
 
   nsCOMArray<nsINode> nodesWithProperties;
   rv = nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
                           cx, newScope, nodesWithProperties);
@@ -6819,17 +6813,17 @@ nsDocument::IsScriptEnabled()
   NS_ENSURE_TRUE(sm, false);
 
   nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();
   NS_ENSURE_TRUE(globalObject, false);
 
   nsIScriptContext *scriptContext = globalObject->GetContext();
   NS_ENSURE_TRUE(scriptContext, false);
 
-  JSContext* cx = scriptContext->GetNativeContext();
+  AutoPushJSContext cx(scriptContext->GetNativeContext());
   NS_ENSURE_TRUE(cx, false);
 
   bool enabled;
   nsresult rv = sm->CanExecuteScripts(cx, NodePrincipal(), &enabled);
   NS_ENSURE_SUCCESS(rv, false);
   return enabled;
 }
 
@@ -8537,17 +8531,17 @@ nsDocument::GetStateObject(nsIVariant** 
   // Get the document's current state object. This is the object backing both
   // history.state and popStateEvent.state.
   //
   // mStateObjectContainer may be null; this just means that there's no
   // current state object.
 
   nsCOMPtr<nsIVariant> stateObj;
   if (!mStateObjectCached && mStateObjectContainer) {
-    JSContext *cx = nsContentUtils::GetContextFromDocument(this);
+    AutoPushJSContext cx(nsContentUtils::GetContextFromDocument(this));
     mStateObjectContainer->
       DeserializeToVariant(cx, getter_AddRefs(mStateObjectCached));
   }
 
   NS_IF_ADDREF(*aState = mStateObjectCached);
 
   return NS_OK;
 }
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -2358,17 +2358,17 @@ nsFrameLoader::EnsureMessageManager()
       mMessageManager->SetCallback(mRemoteBrowserShown ? this : nullptr);
     }
     return NS_OK;
   }
 
   nsIScriptContext* sctx = mOwnerContent->GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_STATE(sctx);
-  JSContext* cx = sctx->GetNativeContext();
+  AutoPushJSContext cx(sctx->GetNativeContext());
   NS_ENSURE_STATE(cx);
 
   nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
     do_QueryInterface(GetOwnerDoc()->GetWindow());
   nsCOMPtr<nsIMessageBroadcaster> parentManager;
   if (chromeWindow) {
     chromeWindow->GetMessageManager(getter_AddRefs(parentManager));
   }
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -646,17 +646,17 @@ nsFrameMessageManager::ReceiveMessage(ns
           continue;
         }
         JSObject* object = nullptr;
         wrappedJS->GetJSObject(&object);
         if (!object) {
           continue;
         }
         nsCxPusher pusher;
-        NS_ENSURE_STATE(pusher.Push(ctx, false));
+        pusher.Push(ctx);
 
         JSAutoRequest ar(ctx);
         JSAutoCompartment ac(ctx, object);
 
         // The parameter for the listener function.
         JSObject* param = JS_NewObject(ctx, NULL, NULL, NULL);
         NS_ENSURE_TRUE(param, NS_ERROR_OUT_OF_MEMORY);
 
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -2565,16 +2565,18 @@ nsObjectLoadingContent::NotifyContentObj
   if (!sgo)
     return;
 
   nsIScriptContext *scx = sgo->GetContext();
   if (!scx)
     return;
 
   JSContext *cx = scx->GetNativeContext();
+  nsCxPusher pusher;
+  pusher.Push(cx);
 
   nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
   nsContentUtils::XPConnect()->
   GetWrappedNativeOfNativeObject(cx, sgo->GetGlobalJSObject(), thisContent,
                                  NS_GET_IID(nsISupports),
                                  getter_AddRefs(wrapper));
 
   if (!wrapper) {
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -817,46 +817,45 @@ nsScriptLoader::EvaluateScript(nsScriptL
 
   // Make sure context is a strong reference since we access it after
   // we've executed a script, which may cause all other references to
   // the context to go away.
   nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
   if (!context) {
     return NS_ERROR_FAILURE;
   }
+  AutoPushJSContext cx(context->GetNativeContext());
 
   bool oldProcessingScriptTag = context->GetProcessingScriptTag();
   context->SetProcessingScriptTag(true);
 
   // Update our current script.
   nsCOMPtr<nsIScriptElement> oldCurrent = mCurrentScript;
   mCurrentScript = aRequest->mElement;
 
   // It's very important to use aRequest->mURI, not the final URI of the channel
   // aRequest ended up getting script data from, as the script filename.
   nsAutoCString url;
   nsContentUtils::GetWrapperSafeScriptFilename(mDocument, aRequest->mURI, url);
 
   JSVersion version = JSVersion(aRequest->mJSVersion);
   if (version != JSVERSION_UNKNOWN) {
-    JS::CompileOptions options(context->GetNativeContext());
+    JS::CompileOptions options(cx);
     options.setFileAndLine(url.get(), aRequest->mLineNo)
            .setVersion(JSVersion(aRequest->mJSVersion));
     if (aRequest->mOriginPrincipal) {
       options.setOriginPrincipals(nsJSPrincipals::get(aRequest->mOriginPrincipal));
     }
     rv = context->EvaluateString(aScript, *globalObject->GetGlobalJSObject(),
                                  options, /* aCoerceToString = */ false, nullptr);
   }
 
   // Put the old script back in case it wants to do anything else.
   mCurrentScript = oldCurrent;
 
-  JSContext *cx = nullptr; // Initialize this to keep GCC happy.
-  cx = context->GetNativeContext();
   JSAutoRequest ar(cx);
   context->SetProcessingScriptTag(oldProcessingScriptTag);
   return rv;
 }
 
 void
 nsScriptLoader::ProcessPendingRequestsAsync()
 {
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -813,18 +813,18 @@ nsEventListenerManager::CompileEventHand
       nsIURI *uri = doc->GetDocumentURI();
       if (uri) {
         uri->GetSpec(url);
         lineNo = 1;
       }
     }
 
     nsCxPusher pusher;
-    if (aNeedsCxPush && !pusher.Push(cx)) {
-      return NS_ERROR_FAILURE;
+    if (aNeedsCxPush) {
+      pusher.Push(cx);
     }
 
     uint32_t argCount;
     const char **argNames;
     // If no content, then just use kNameSpaceID_None for the
     // namespace ID.  In practice, it doesn't matter since SVG is
     // the only thing with weird arg names and SVG doesn't map event
     // listeners to the window.
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/HTMLDataElement.cpp
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "HTMLDataElement.h"
+#include "mozilla/dom/HTMLDataElementBinding.h"
+#include "nsGenericHTMLElement.h"
+
+NS_IMPL_NS_NEW_HTML_ELEMENT(Data)
+
+namespace mozilla {
+namespace dom {
+
+HTMLDataElement::HTMLDataElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : nsGenericHTMLElement(aNodeInfo)
+{
+  SetIsDOMBinding();
+}
+
+HTMLDataElement::~HTMLDataElement()
+{
+}
+
+NS_IMPL_ADDREF_INHERITED(HTMLDataElement, Element)
+NS_IMPL_RELEASE_INHERITED(HTMLDataElement, Element)
+
+NS_INTERFACE_TABLE_HEAD(HTMLDataElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE0(HTMLDataElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLDataElement,
+                                               nsGenericHTMLElement)
+NS_HTML_CONTENT_INTERFACE_MAP_END
+
+NS_IMPL_ELEMENT_CLONE(HTMLDataElement)
+
+JSObject*
+HTMLDataElement::WrapNode(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
+{
+  return HTMLDataElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+void
+HTMLDataElement::GetItemValueText(nsAString& text)
+{
+  GetValue(text);
+}
+
+void
+HTMLDataElement::SetItemValueText(const nsAString& text)
+{
+  ErrorResult rv;
+  SetValue(text, rv);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/HTMLDataElement.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_HTMLDataElement_h
+#define mozilla_dom_HTMLDataElement_h
+
+#include "nsIDOMHTMLElement.h"
+#include "nsGenericHTMLElement.h"
+#include "nsGkAtoms.h"
+
+namespace mozilla {
+namespace dom {
+
+class HTMLDataElement MOZ_FINAL : public nsGenericHTMLElement,
+                                  public nsIDOMHTMLElement
+{
+public:
+  HTMLDataElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~HTMLDataElement();
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
+
+  // HTMLDataElement WebIDL
+  void GetValue(nsAString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::value, aValue);
+  }
+
+  void SetValue(const nsAString& aValue, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::value, aValue, aError);
+  }
+
+  virtual void GetItemValueText(nsAString& text);
+  virtual void SetItemValueText(const nsAString& text);
+  virtual nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const;
+  virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+  virtual JSObject* WrapNode(JSContext* aCx, JSObject* aScope,
+                             bool* aTriedToWrap) MOZ_OVERRIDE;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_HTMLDataElement_h
--- a/content/html/content/src/HTMLFrameElement.h
+++ b/content/html/content/src/HTMLFrameElement.h
@@ -14,16 +14,18 @@ class nsIDOMDocument;
 
 namespace mozilla {
 namespace dom {
 
 class HTMLFrameElement : public nsGenericHTMLFrameElement,
                          public nsIDOMHTMLFrameElement
 {
 public:
+  using nsGenericHTMLFrameElement::SwapFrameLoaders;
+
   HTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                    FromParser aFromParser = NOT_FROM_PARSER);
   virtual ~HTMLFrameElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -29,16 +29,17 @@ EXPORTS		= \
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
 		HTMLAnchorElement.h \
 		HTMLAreaElement.h \
 		HTMLBodyElement.h \
 		HTMLBRElement.h \
 		HTMLButtonElement.h \
+		HTMLDataElement.h \
 		HTMLDataListElement.h \
 		HTMLDivElement.h \
 		HTMLFieldSetElement.h \
 		HTMLFontElement.h \
 		HTMLFrameElement.h \
 		HTMLFrameSetElement.h \
 		HTMLHeadingElement.h \
 		HTMLHRElement.h \
@@ -89,16 +90,17 @@ CPPSRCS		= \
 		nsTextEditorState.cpp \
 		HTMLElement.cpp \
 		HTMLAnchorElement.cpp \
 		HTMLAreaElement.cpp \
 		HTMLBRElement.cpp \
 		HTMLBodyElement.cpp \
 		HTMLButtonElement.cpp \
 		HTMLCanvasElement.cpp \
+		HTMLDataElement.cpp \
 		HTMLDataListElement.cpp \
 		HTMLDivElement.cpp \
 		HTMLFieldSetElement.cpp \
 		HTMLFontElement.cpp \
 		nsHTMLFormElement.cpp \
 		HTMLFrameElement.cpp \
 		HTMLFrameSetElement.cpp \
 		HTMLHRElement.cpp \
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -1910,16 +1910,17 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Area)
 #if defined(MOZ_MEDIA)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Audio)
 #endif
 NS_DECLARE_NS_NEW_HTML_ELEMENT(BR)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Body)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Button)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Canvas)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Mod)
+NS_DECLARE_NS_NEW_HTML_ELEMENT(Data)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(DataList)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Div)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(FieldSet)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Font)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Form)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Frame)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(FrameSet)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(HR)
--- a/content/html/content/src/nsGenericHTMLFrameElement.cpp
+++ b/content/html/content/src/nsGenericHTMLFrameElement.cpp
@@ -4,16 +4,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsGenericHTMLFrameElement.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ErrorResult.h"
 #include "nsIAppsService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDOMApplicationRegistry.h"
 #include "nsIPermissionManager.h"
 #include "sampler.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -389,8 +390,16 @@ nsGenericHTMLFrameElement::DisallowCreat
 NS_IMETHODIMP
 nsGenericHTMLFrameElement::AllowCreateFrameLoader()
 {
   MOZ_ASSERT(!mFrameLoader);
   MOZ_ASSERT(mFrameLoaderCreationDisallowed);
   mFrameLoaderCreationDisallowed = false;
   return NS_OK;
 }
+
+void
+nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherOwner,
+                                            ErrorResult& aError)
+{
+  aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
--- a/content/html/content/src/nsGenericHTMLFrameElement.h
+++ b/content/html/content/src/nsGenericHTMLFrameElement.h
@@ -4,19 +4,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsGenericHTMLElement.h"
 #include "nsIFrameLoader.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsIDOMEventListener.h"
+#include "mozilla/ErrorResult.h"
 
 #include "nsFrameLoader.h"
 
+class nsXULElement;
+
 /**
  * A helper class for frame elements
  */
 class nsGenericHTMLFrameElement : public nsGenericHTMLElement,
                                   public nsIFrameLoaderOwner,
                                   public nsIMozBrowserFrame
 {
 public:
@@ -55,16 +58,18 @@ public:
 
   nsresult CopyInnerTo(mozilla::dom::Element* aDest);
 
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsGenericHTMLFrameElement,
                                                      nsGenericHTMLElement)
 
+  void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& aError);
+
 protected:
   /**
    * Listens to titlechanged events from the document inside the iframe and
    * forwards them along to the iframe so it can fire a mozbrowsertitlechange
    * event if appropriate.
    */
   class TitleChangedListener MOZ_FINAL : public nsIDOMEventListener
   {
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -348,16 +348,17 @@ MOCHITEST_FILES = \
 		test_formelements.html \
 		test_rowscollection.html \
 		test_map_attributes_reflection.html \
 		test_meta_attributes_reflection.html \
 		test_mod_attributes_reflection.html \
 		test_mozaudiochannel.html \
 		test_style_attributes_reflection.html \
 		test_bug629801.html \
+		test_bug839371.html \
 		$(NULL)
 
 
 MOCHITEST_BROWSER_FILES = \
 		browser_bug649778.js \
 		file_bug649778.html \
 		file_bug649778.html^headers^ \
 		$(NULL)
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -121,16 +121,17 @@ HTML_TAG("br", "BR");
 HTML_TAG("button", "Button");
 HTML_TAG("canvas", "Canvas");
 HTML_TAG("caption", "TableCaption");
 HTML_TAG("center", "");
 HTML_TAG("cite", "");
 HTML_TAG("code", "");
 HTML_TAG("col", "TableCol");
 HTML_TAG("colgroup", "TableCol");
+HTML_TAG("data", "Data");
 HTML_TAG("datalist", "DataList");
 HTML_TAG("dd", "");
 HTML_TAG("del", "Mod");
 HTML_TAG("dfn", "");
 HTML_TAG("dir", "Directory");
 HTML_TAG("div", "Div");
 HTML_TAG("dl", "DList");
 HTML_TAG("dt", "");
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug839371.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=839371
+-->
+<head>
+  <title>Test for Bug 839371</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="reflect.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=839371">Mozilla Bug 839371</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+<div itemscope>
+  <data id="d1" itemprop="product-id" value="9678AOU879">The Instigator 2000</data>
+</div>
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 839371 **/
+
+var d1 = document.getElementById("d1"),
+    d2 = document.createElement("data");
+
+// .value IDL
+is(d1.value, "9678AOU879", "value property reflects content attribute");
+d1.value = "123";
+is(d1.value, "123", "value property can be set via setter");
+
+// .itemValue getter for <data>'s microdata
+var data = document.getItems()[0];
+is(data.properties["product-id"][0].itemValue, "123", "itemValue getter reflects value attribute");
+
+// .itemValue setter uses value
+data.properties["product-id"][0].itemValue = "456";
+is(data.properties["product-id"][0].value, "456", "setting itemValue updates value");
+is(data.properties["product-id"][0].itemValue, "456", "setting itemValue updates itemValue");
+
+// .value reflects value attribute
+reflectString({
+  element: d2,
+  attribute: "value"
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -1336,18 +1336,17 @@ IsScriptEnabled(nsIDocument *aDoc, nsIDo
     NS_ENSURE_TRUE(owner, true);
 
     globalObject = owner->GetScriptGlobalObject();
     NS_ENSURE_TRUE(globalObject, true);
   }
 
   nsIScriptContext *scriptContext = globalObject->GetContext();
   NS_ENSURE_TRUE(scriptContext, true);
-
-  JSContext* cx = scriptContext->GetNativeContext();
+  JSContext *cx = scriptContext->GetNativeContext();
   NS_ENSURE_TRUE(cx, true);
 
   bool enabled = true;
   nsContentUtils::GetSecurityManager()->
     CanExecuteScripts(cx, aDoc->NodePrincipal(), &enabled);
   return enabled;
 }
 
--- a/content/media/BufferMediaResource.h
+++ b/content/media/BufferMediaResource.h
@@ -131,17 +131,17 @@ public:
   virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
   {
     aRanges.AppendElement(MediaByteRange(0, mLength));
     return NS_OK;
   }
 
   bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
 
-  virtual const nsACString& GetContentType() const MOZ_OVERRIDE
+  virtual const nsCString& GetContentType() const MOZ_OVERRIDE
   {
     return mContentType;
   }
 
 private:
   const uint8_t * mBuffer;
   uint32_t mLength;
   uint32_t mOffset;
--- a/content/media/MediaResource.h
+++ b/content/media/MediaResource.h
@@ -366,17 +366,17 @@ public:
   virtual void FlushCache() { }
 
   // Notify that the last data byte range was loaded.
   virtual void NotifyLastByteRange() { }
 
   // Returns the content type of the resource. This is copied from the
   // nsIChannel when the MediaResource is created. Safe to call from
   // any thread.
-  virtual const nsACString& GetContentType() const = 0;
+  virtual const nsCString& GetContentType() const = 0;
 };
 
 class BaseMediaResource : public MediaResource {
 public:
   virtual nsIURI* URI() const { return mURI; }
   virtual void MoveLoadsToBackground();
 
 protected:
@@ -393,17 +393,17 @@ protected:
     MOZ_COUNT_CTOR(BaseMediaResource);
     NS_ASSERTION(!mContentType.IsEmpty(), "Must know content type");
   }
   virtual ~BaseMediaResource()
   {
     MOZ_COUNT_DTOR(BaseMediaResource);
   }
 
-  virtual const nsACString& GetContentType() const MOZ_OVERRIDE
+  virtual const nsCString& GetContentType() const MOZ_OVERRIDE
   {
     return mContentType;
   }
 
   // Set the request's load flags to aFlags.  If the request is part of a
   // load group, the request is removed from the group, the flags are set, and
   // then the request is added back to the load group.
   void ModifyLoadFlags(nsLoadFlags aFlags);
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -658,17 +658,17 @@ MediaDecodeTask::CallbackTheResult()
 
 bool
 WebAudioDecodeJob::FinalizeBufferData()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mOutput);
   MOZ_ASSERT(mChannels == mChannelBuffers.Length());
 
-  JSContext* cx = GetJSContext();
+  AutoPushJSContext cx(GetJSContext());
   if (!cx) {
     return false;
   }
 
   for (uint32_t i = 0; i < mChannels; ++i) {
     mOutput->SetChannelDataFromArrayBufferContents(cx, i, mChannelBuffers[i].first);
   }
 
@@ -691,17 +691,17 @@ WebAudioDecodeJob::GetJSContext() const
 
 bool
 WebAudioDecodeJob::AllocateBuffer()
 {
   MOZ_ASSERT(!mOutput);
   MOZ_ASSERT(NS_IsMainThread());
 
   // First, get a JSContext
-  JSContext* cx = GetJSContext();
+  AutoPushJSContext cx(GetJSContext());
   if (!cx) {
     return false;
   }
 
   // Now create the AudioBuffer
   mOutput = new AudioBuffer(mContext, mResampledFrames, mContext->SampleRate());
   if (!mOutput->InitializeBuffers(mChannels, cx)) {
     return false;
--- a/content/media/wmf/WMFByteStream.cpp
+++ b/content/media/wmf/WMFByteStream.cpp
@@ -157,17 +157,17 @@ WMFByteStream::Init()
   if (!contentTypeUTF16.IsEmpty()) {
     HRESULT hr = wmf::MFCreateAttributes(byRef(mAttributes), 1);
     NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
 
     hr = mAttributes->SetString(MF_BYTESTREAM_CONTENT_TYPE,
                                 contentTypeUTF16.get());
     NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
 
-    LOG("WMFByteStream has Content-Type=%s", mResource->GetContentType());
+    LOG("WMFByteStream has Content-Type=%s", mResource->GetContentType().get());
   }
   return NS_OK;
 }
 
 nsresult
 WMFByteStream::Shutdown()
 {
   {
--- a/content/svg/content/src/SVGMarkerElement.cpp
+++ b/content/svg/content/src/SVGMarkerElement.cpp
@@ -316,17 +316,17 @@ SVGMarkerElement::GetMarkerTransform(flo
   return gfxMatrix(cos(angle) * scale,   sin(angle) * scale,
                    -sin(angle) * scale,  cos(angle) * scale,
                    aX,                    aY);
 }
 
 nsSVGViewBoxRect
 SVGMarkerElement::GetViewBoxRect()
 {
-  if (mViewBox.IsExplicitlySet()) {
+  if (mViewBox.HasRect()) {
     return mViewBox.GetAnimValue();
   }
   return nsSVGViewBoxRect(
            0, 0,
            mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
            mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx));
 }
 
--- a/content/svg/content/src/SVGSVGElement.cpp
+++ b/content/svg/content/src/SVGSVGElement.cpp
@@ -842,22 +842,22 @@ SVGSVGElement::GetCurrentViewElement() c
   }
   return nullptr;
 }
 
 nsSVGViewBoxRect
 SVGSVGElement::GetViewBoxWithSynthesis(
   float aViewportWidth, float aViewportHeight) const
 {
-  // The logic here should match HasViewBox().
+  // The logic here should match HasViewBoxRect().
   SVGViewElement* viewElement = GetCurrentViewElement();
-  if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
+  if (viewElement && viewElement->mViewBox.HasRect()) {
     return viewElement->mViewBox.GetAnimValue();
   }
-  if (mViewBox.IsExplicitlySet()) {
+  if (mViewBox.HasRect()) {
     return mViewBox.GetAnimValue();
   }
 
   if (ShouldSynthesizeViewBox()) {
     // Special case -- fake a viewBox, using height & width attrs.
     // (Use |this| as context, since if we get here, we're outermost <svg>.)
     return nsSVGViewBoxRect(0, 0,
               ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_WIDTH],
@@ -880,21 +880,21 @@ SVGSVGElement::GetPreserveAspectRatioWit
     const SVGPreserveAspectRatio *pAROverridePtr = GetPreserveAspectRatioProperty();
     if (pAROverridePtr) {
       return *pAROverridePtr;
     }
   }
 
   SVGViewElement* viewElement = GetCurrentViewElement();
 
-  // This check is equivalent to "!HasViewBox() && ShouldSynthesizeViewBox()".
-  // We're just holding onto the viewElement that HasViewBox() would look up,
+  // This check is equivalent to "!HasViewBoxRect() && ShouldSynthesizeViewBox()".
+  // We're just holding onto the viewElement that HasViewBoxRect() would look up,
   // so that we don't have to look it up again later.
-  if (!((viewElement && viewElement->mViewBox.IsExplicitlySet()) ||
-        mViewBox.IsExplicitlySet()) &&
+  if (!((viewElement && viewElement->mViewBox.HasRect()) ||
+        mViewBox.HasRect()) &&
       ShouldSynthesizeViewBox()) {
     // If we're synthesizing a viewBox, use preserveAspectRatio="none";
     return SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_SLICE);
   }
 
   if (viewElement && viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
     return viewElement->mPreserveAspectRatio.GetAnimValue();
   }
@@ -907,20 +907,20 @@ SVGSVGElement::GetPreserveAspectRatioWit
 float
 SVGSVGElement::GetLength(uint8_t aCtxType)
 {
   float h, w;
 
   SVGViewElement* viewElement = GetCurrentViewElement();
   const nsSVGViewBoxRect* viewbox = nullptr;
 
-  // The logic here should match HasViewBox().
-  if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
+  // The logic here should match HasViewBoxRect().
+  if (viewElement && viewElement->mViewBox.HasRect()) {
     viewbox = &viewElement->mViewBox.GetAnimValue();
-  } else if (mViewBox.IsExplicitlySet()) {
+  } else if (mViewBox.HasRect()) {
     viewbox = &mViewBox.GetAnimValue();
   }
 
   if (viewbox) {
     w = viewbox->width;
     h = viewbox->height;
   } else if (IsInner()) {
     SVGSVGElement *ctx = GetCtx();
@@ -1024,29 +1024,29 @@ SVGSVGElement::GetViewBox()
 
 SVGAnimatedPreserveAspectRatio *
 SVGSVGElement::GetPreserveAspectRatio()
 {
   return &mPreserveAspectRatio;
 }
 
 bool
-SVGSVGElement::HasViewBox() const
+SVGSVGElement::HasViewBoxRect() const
 {
   SVGViewElement* viewElement = GetCurrentViewElement();
-  if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
+  if (viewElement && viewElement->mViewBox.HasRect()) {
     return true;
   }
-  return mViewBox.IsExplicitlySet();
+  return mViewBox.HasRect();
 }
 
 bool
 SVGSVGElement::ShouldSynthesizeViewBox() const
 {
-  NS_ABORT_IF_FALSE(!HasViewBox(),
+  NS_ABORT_IF_FALSE(!HasViewBoxRect(),
                     "Should only be called if we lack a viewBox");
 
   nsIDocument* doc = GetCurrentDoc();
   return doc &&
     doc->IsBeingUsedAsImage() &&
     !mIsPaintingSVGImageElement &&
     !GetParent();
 }
@@ -1105,26 +1105,26 @@ void
 SVGSVGElement::
   SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR)
 {
 #ifdef DEBUG
   NS_ABORT_IF_FALSE(GetCurrentDoc()->IsBeingUsedAsImage(),
                     "should only override preserveAspectRatio in images");
 #endif
 
-  bool hasViewBox = HasViewBox();
-  if (!hasViewBox && ShouldSynthesizeViewBox()) {
+  bool hasViewBoxRect = HasViewBoxRect();
+  if (!hasViewBoxRect && ShouldSynthesizeViewBox()) {
     // My non-<svg:image> clients will have been painting me with a synthesized
     // viewBox, but my <svg:image> client that's about to paint me now does NOT
     // want that.  Need to tell ourselves to flush our transform.
     mImageNeedsTransformInvalidation = true;
   }
   mIsPaintingSVGImageElement = true;
 
-  if (!hasViewBox) {
+  if (!hasViewBoxRect) {
     return; // preserveAspectRatio irrelevant (only matters if we have viewBox)
   }
 
   if (aPAR.GetDefer() && HasPreserveAspectRatio()) {
     return; // Referring element defers to my own preserveAspectRatio value.
   }
 
   if (SetPreserveAspectRatioProperty(aPAR)) {
@@ -1136,17 +1136,17 @@ void
 SVGSVGElement::ClearImageOverridePreserveAspectRatio()
 {
 #ifdef DEBUG
   NS_ABORT_IF_FALSE(GetCurrentDoc()->IsBeingUsedAsImage(),
                     "should only override image preserveAspectRatio in images");
 #endif
 
   mIsPaintingSVGImageElement = false;
-  if (!HasViewBox() && ShouldSynthesizeViewBox()) {
+  if (!HasViewBoxRect() && ShouldSynthesizeViewBox()) {
     // My non-<svg:image> clients will want to paint me with a synthesized
     // viewBox, but my <svg:image> client that just painted me did NOT
     // use that.  Need to tell ourselves to flush our transform.
     mImageNeedsTransformInvalidation = true;
   }
 
   if (ClearPreserveAspectRatioProperty()) {
     mImageNeedsTransformInvalidation = true;
--- a/content/svg/content/src/SVGSVGElement.h
+++ b/content/svg/content/src/SVGSVGElement.h
@@ -149,29 +149,29 @@ public:
    * has a valid viewBox.
    *
    * Note that this does not check whether we need to synthesize a viewBox,
    * so you must call ShouldSynthesizeViewBox() if you need to check that too.
    *
    * Note also that this method does not pay attention to whether the width or
    * height values of the viewBox rect are positive!
    */
-  bool HasViewBox() const;
+  bool HasViewBoxRect() const;
 
   /**
    * Returns true if we should synthesize a viewBox for ourselves (that is, if
    * we're the root element in an image document, and we're not currently being
    * painted for an <svg:image> element).
    *
-   * Only call this method if HasViewBox() returns false.
+   * Only call this method if HasViewBoxRect() returns false.
    */
   bool ShouldSynthesizeViewBox() const;
 
   bool HasViewBoxOrSyntheticViewBox() const {
-    return HasViewBox() || ShouldSynthesizeViewBox();
+    return HasViewBoxRect() || ShouldSynthesizeViewBox();
   }
 
   gfxMatrix GetViewBoxTransform() const;
 
   bool HasChildrenOnlyTransform() const {
     return mHasChildrenOnlyTransform;
   }
 
--- a/content/svg/content/src/SVGViewBoxSMILType.cpp
+++ b/content/svg/content/src/SVGViewBoxSMILType.cpp
@@ -13,18 +13,17 @@ namespace mozilla {
   
 /*static*/ SVGViewBoxSMILType SVGViewBoxSMILType::sSingleton;
 
 void
 SVGViewBoxSMILType::Init(nsSMILValue& aValue) const
 {
   NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type");
 
-  nsSVGViewBoxRect* viewBox = new nsSVGViewBoxRect();
-  aValue.mU.mPtr = viewBox;
+  aValue.mU.mPtr = new nsSVGViewBoxRect();
   aValue.mType = this;
 }
 
 void
 SVGViewBoxSMILType::Destroy(nsSMILValue& aValue) const
 {
   NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
   delete static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
@@ -79,16 +78,20 @@ SVGViewBoxSMILType::ComputeDistance(cons
                                     double& aDistance) const
 {
   NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
   NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
 
   const nsSVGViewBoxRect* from = static_cast<const nsSVGViewBoxRect*>(aFrom.mU.mPtr);
   const nsSVGViewBoxRect* to = static_cast<const nsSVGViewBoxRect*>(aTo.mU.mPtr);
 
+  if (from->none || to->none) {
+    return NS_ERROR_FAILURE;
+  }
+
   // We use the distances between the edges rather than the difference between
   // the x, y, width and height for the "distance". This is necessary in
   // order for the "distance" result that we calculate to be the same for a
   // given change in the left side as it is for an equal change in the opposite
   // side. See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c12
 
   float dLeft = to->x - from->x;
   float dTop = to->y - from->y;
@@ -106,19 +109,24 @@ SVGViewBoxSMILType::Interpolate(const ns
                                 double aUnitDistance,
                                 nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
-  
+
   const nsSVGViewBoxRect* start = static_cast<const nsSVGViewBoxRect*>(aStartVal.mU.mPtr);
   const nsSVGViewBoxRect* end = static_cast<const nsSVGViewBoxRect*>(aEndVal.mU.mPtr);
+
+  if (start->none || end->none) {
+    return NS_ERROR_FAILURE;
+  }
+
   nsSVGViewBoxRect* current = static_cast<nsSVGViewBoxRect*>(aResult.mU.mPtr);
 
   float x = (start->x + (end->x - start->x) * aUnitDistance);
   float y = (start->y + (end->y - start->y) * aUnitDistance);
   float width = (start->width + (end->width - start->width) * aUnitDistance);
   float height = (start->height + (end->height - start->height) * aUnitDistance);
 
   *current = nsSVGViewBoxRect(x, y, width, height);
--- a/content/svg/content/src/nsSVGViewBox.cpp
+++ b/content/svg/content/src/nsSVGViewBox.cpp
@@ -20,20 +20,22 @@ using namespace mozilla;
 /* Implementation of nsSVGViewBoxRect methods */
 
 bool
 nsSVGViewBoxRect::operator==(const nsSVGViewBoxRect& aOther) const
 {
   if (&aOther == this)
     return true;
 
-  return x == aOther.x &&
-    y == aOther.y &&
-    width == aOther.width &&
-    height == aOther.height;
+  return (none && aOther.none) ||
+    (!none && !aOther.none &&
+     x == aOther.x &&
+     y == aOther.y &&
+     width == aOther.width &&
+     height == aOther.height);
 }
 
 /* Cycle collection macros for nsSVGViewBox */
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMBaseVal, mSVGElement)
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimVal, mSVGElement)
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimatedRect, mSVGElement)
 
@@ -74,43 +76,46 @@ static nsSVGAttrTearoffTable<nsSVGViewBo
   sAnimSVGViewBoxTearoffTable;
 
 
 /* Implementation of nsSVGViewBox methods */
 
 void
 nsSVGViewBox::Init()
 {
-  mBaseVal = nsSVGViewBoxRect();
+  mHasBaseVal = false;
   mAnimVal = nullptr;
-  mHasBaseVal = false;
 }
 
 void
-nsSVGViewBox::SetAnimValue(float aX, float aY, float aWidth, float aHeight,
+nsSVGViewBox::SetAnimValue(const nsSVGViewBoxRect& aRect,
                            nsSVGElement *aSVGElement)
 {
   if (!mAnimVal) {
     // it's okay if allocation fails - and no point in reporting that
-    mAnimVal = new nsSVGViewBoxRect(aX, aY, aWidth, aHeight);
+    mAnimVal = new nsSVGViewBoxRect(aRect);
   } else {
-    nsSVGViewBoxRect rect(aX, aY, aWidth, aHeight);
-    if (rect == *mAnimVal) {
+    if (aRect == *mAnimVal) {
       return;
     }
-    *mAnimVal = rect;
+    *mAnimVal = aRect;
   }
   aSVGElement->DidAnimateViewBox();
 }
 
 void
 nsSVGViewBox::SetBaseValue(const nsSVGViewBoxRect& aRect,
                            nsSVGElement *aSVGElement)
 {
-  if (mHasBaseVal && mBaseVal == aRect) {
+  if (!mHasBaseVal || mBaseVal == aRect) {
+    // This method is used to set a single x, y, width
+    // or height value. It can't create a base value
+    // as the other components may be undefined. We record
+    // the new value though, so as not to lose data.
+    mBaseVal = aRect;
     return;
   }
 
   nsAttrValue emptyOrOldValue = aSVGElement->WillChangeViewBox();
 
   mBaseVal = aRect;
   mHasBaseVal = true;
 
@@ -118,16 +123,21 @@ nsSVGViewBox::SetBaseValue(const nsSVGVi
   if (mAnimVal) {
     aSVGElement->AnimationNeedsResample();
   }
 }
 
 static nsresult
 ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
 {
+  if (aStr.EqualsLiteral("none")) {
+    aViewBox->none = true;
+    return NS_OK;
+  }
+
   nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
     tokenizer(aStr, ',',
               nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
   float vals[NUM_VIEWBOX_COMPONENTS];
   uint32_t i;
   for (i = 0; i < NUM_VIEWBOX_COMPONENTS && tokenizer.hasMoreTokens(); ++i) {
     NS_ConvertUTF16toUTF8 utf8Token(tokenizer.nextToken());
     const char *token = utf8Token.get();
@@ -147,48 +157,59 @@ ToSVGViewBoxRect(const nsAString& aStr, 
       tokenizer.lastTokenEndedWithSeparator()) {  // Trailing comma.
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   aViewBox->x = vals[0];
   aViewBox->y = vals[1];
   aViewBox->width = vals[2];
   aViewBox->height = vals[3];
+  aViewBox->none = false;
 
   return NS_OK;
 }
 
 nsresult
 nsSVGViewBox::SetBaseValueString(const nsAString& aValue,
                                  nsSVGElement *aSVGElement,
                                  bool aDoSetAttr)
 {
   nsSVGViewBoxRect viewBox;
-  nsresult res = ToSVGViewBoxRect(aValue, &viewBox);
-  if (NS_SUCCEEDED(res)) {
-    nsAttrValue emptyOrOldValue;
-    if (aDoSetAttr) {
-      emptyOrOldValue = aSVGElement->WillChangeViewBox();
-    }
-    mBaseVal = nsSVGViewBoxRect(viewBox.x, viewBox.y, viewBox.width, viewBox.height);
-    mHasBaseVal = true;
+
+  nsresult rv = ToSVGViewBoxRect(aValue, &viewBox);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  if (viewBox == mBaseVal) {
+    return NS_OK;
+  }
 
-    if (aDoSetAttr) {
-      aSVGElement->DidChangeViewBox(emptyOrOldValue);
-    }
-    if (mAnimVal) {
-      aSVGElement->AnimationNeedsResample();
-    }
+  nsAttrValue emptyOrOldValue;
+  if (aDoSetAttr) {
+    emptyOrOldValue = aSVGElement->WillChangeViewBox();
   }
-  return res;
+  mHasBaseVal = true;
+  mBaseVal = viewBox;
+
+  if (aDoSetAttr) {
+    aSVGElement->DidChangeViewBox(emptyOrOldValue);
+  }
+  if (mAnimVal) {
+    aSVGElement->AnimationNeedsResample();
+  }
+  return NS_OK;
 }
 
 void
 nsSVGViewBox::GetBaseValueString(nsAString& aValue) const
 {
+  if (mBaseVal.none) {
+    aValue.AssignLiteral("none");
+    return;
+  }
   PRUnichar buf[200];
   nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
                             NS_LITERAL_STRING("%g %g %g %g").get(),
                             (double)mBaseVal.x, (double)mBaseVal.y,
                             (double)mBaseVal.width, (double)mBaseVal.height);
   aValue.Assign(buf);
 }
 
@@ -210,16 +231,20 @@ nsSVGViewBox::ToDOMAnimatedRect(nsIDOMSV
 nsSVGViewBox::DOMAnimatedRect::~DOMAnimatedRect()
 {
   sSVGAnimatedRectTearoffTable.RemoveTearoff(mVal);
 }
 
 nsresult
 nsSVGViewBox::ToDOMBaseVal(nsIDOMSVGRect **aResult, nsSVGElement *aSVGElement)
 {
+  if (!mHasBaseVal || mBaseVal.none) {
+    *aResult = nullptr;
+    return NS_OK;
+  }
   nsRefPtr<DOMBaseVal> domBaseVal =
     sBaseSVGViewBoxTearoffTable.GetTearoff(this);
   if (!domBaseVal) {
     domBaseVal = new DOMBaseVal(this, aSVGElement);
     sBaseSVGViewBoxTearoffTable.AddTearoff(this, domBaseVal);
   }
 
   domBaseVal.forget(aResult);
@@ -229,16 +254,21 @@ nsSVGViewBox::ToDOMBaseVal(nsIDOMSVGRect
 nsSVGViewBox::DOMBaseVal::~DOMBaseVal()
 {
   sBaseSVGViewBoxTearoffTable.RemoveTearoff(mVal);
 }
 
 nsresult
 nsSVGViewBox::ToDOMAnimVal(nsIDOMSVGRect **aResult, nsSVGElement *aSVGElement)
 {
+  if ((mAnimVal && mAnimVal->none) ||
+      (!mAnimVal && (!mHasBaseVal || mBaseVal.none))) {
+    *aResult = nullptr;
+    return NS_OK;
+  }
   nsRefPtr<DOMAnimVal> domAnimVal =
     sAnimSVGViewBoxTearoffTable.GetTearoff(this);
   if (!domAnimVal) {
     domAnimVal = new DOMAnimVal(this, aSVGElement);
     sAnimSVGViewBoxTearoffTable.AddTearoff(this, domAnimVal);
   }
 
   domAnimVal.forget(aResult);
@@ -250,48 +280,44 @@ nsSVGViewBox::DOMAnimVal::~DOMAnimVal()
   sAnimSVGViewBoxTearoffTable.RemoveTearoff(mVal);
 }
 
 NS_IMETHODIMP
 nsSVGViewBox::DOMBaseVal::SetX(float aX)
 {
   nsSVGViewBoxRect rect = mVal->GetBaseValue();
   rect.x = aX;
-  mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
-                     mSVGElement);
+  mVal->SetBaseValue(rect, mSVGElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGViewBox::DOMBaseVal::SetY(float aY)
 {
   nsSVGViewBoxRect rect = mVal->GetBaseValue();
   rect.y = aY;
-  mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
-                     mSVGElement);
+  mVal->SetBaseValue(rect, mSVGElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGViewBox::DOMBaseVal::SetWidth(float aWidth)
 {
   nsSVGViewBoxRect rect = mVal->GetBaseValue();
   rect.width = aWidth;
-  mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
-                     mSVGElement);
+  mVal->SetBaseValue(rect, mSVGElement);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGViewBox::DOMBaseVal::SetHeight(float aHeight)
 {
   nsSVGViewBoxRect rect = mVal->GetBaseValue();
   rect.height = aHeight;
-  mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
-                     mSVGElement);
+  mVal->SetBaseValue(rect, mSVGElement);
   return NS_OK;
 }
 
 nsISMILAttr*
 nsSVGViewBox::ToSMILAttr(nsSVGElement *aSVGElement)
 {
   return new SMILViewBox(this, aSVGElement);
 }
@@ -335,12 +361,12 @@ nsSVGViewBox::SMILViewBox::ClearAnimValu
 
 nsresult
 nsSVGViewBox::SMILViewBox::SetAnimValue(const nsSMILValue& aValue)
 {
   NS_ASSERTION(aValue.mType == &SVGViewBoxSMILType::sSingleton,
                "Unexpected type to assign animated value");
   if (aValue.mType == &SVGViewBoxSMILType::sSingleton) {
     nsSVGViewBoxRect &vb = *static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
-    mVal->SetAnimValue(vb.x, vb.y, vb.width, vb.height, mSVGElement);
+    mVal->SetAnimValue(vb, mSVGElement);
   }
   return NS_OK;
 }
--- a/content/svg/content/src/nsSVGViewBox.h
+++ b/content/svg/content/src/nsSVGViewBox.h
@@ -17,22 +17,23 @@
 
 class nsISMILAnimationElement;
 class nsSMILValue;
 
 struct nsSVGViewBoxRect
 {
   float x, y;
   float width, height;
+  bool none;
 
-  nsSVGViewBoxRect() : x(0), y(0), width(0), height(0) {}
+  nsSVGViewBoxRect() : none(true) {}
   nsSVGViewBoxRect(float aX, float aY, float aWidth, float aHeight) :
-    x(aX), y(aY), width(aWidth), height(aHeight) {}
+    x(aX), y(aY), width(aWidth), height(aHeight), none(false) {}
   nsSVGViewBoxRect(const nsSVGViewBoxRect& rhs) :
-    x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height) {}
+    x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height), none(rhs.none) {}
   bool operator==(const nsSVGViewBoxRect& aOther) const;
 };
 
 class nsSVGViewBox
 {
 
 public:
 
@@ -43,29 +44,34 @@ public:
    * with finite values. Returns false if the viewBox was set to an invalid
    * string, or if any of the four rect values were too big to store in a
    * float.
    *
    * This method does not check whether the width or height values are
    * positive, so callers must check whether the viewBox rect is valid where
    * necessary!
    */
+  bool HasRect() const
+    { return (mAnimVal && !mAnimVal->none) ||
+             (!mAnimVal && mHasBaseVal && !mBaseVal.none); }
+
+  /**
+   * Returns true if the corresponding "viewBox" attribute either defined a
+   * rectangle with finite values or the special "none" value.
+   */
   bool IsExplicitlySet() const
-    { return (mHasBaseVal || mAnimVal); }
+    { return mAnimVal || mHasBaseVal; }
 
   const nsSVGViewBoxRect& GetBaseValue() const
     { return mBaseVal; }
   void SetBaseValue(const nsSVGViewBoxRect& aRect,
                     nsSVGElement *aSVGElement);
-  void SetBaseValue(float aX, float aY, float aWidth, float aHeight,
-                    nsSVGElement *aSVGElement)
-    { SetBaseValue(nsSVGViewBoxRect(aX, aY, aWidth, aHeight), aSVGElement); }
   const nsSVGViewBoxRect& GetAnimValue() const
     { return mAnimVal ? *mAnimVal : mBaseVal; }
-  void SetAnimValue(float aX, float aY, float aWidth, float aHeight,
+  void SetAnimValue(const nsSVGViewBoxRect& aRect,
                     nsSVGElement *aSVGElement);
 
   nsresult SetBaseValueString(const nsAString& aValue,
                               nsSVGElement *aSVGElement,
                               bool aDoSetAttr);
   void GetBaseValueString(nsAString& aValue) const;
 
   nsresult ToDOMAnimatedRect(nsIDOMSVGAnimatedRect **aResult,
--- a/content/svg/content/test/test_dataTypes.html
+++ b/content/svg/content/test/test_dataTypes.html
@@ -243,29 +243,18 @@ function runTests()
      "empty preserveAspectRatio attribute");
   marker.removeAttribute("preserveAspectRatio");
   ok(marker.getAttribute("preserveAspectRatio") === null,
      "removed preserveAspectRatio attribute");
 
   // viewBox attribute
   var baseViewBox = marker.viewBox.baseVal;
   var animViewBox = marker.viewBox.animVal;
-  is(baseViewBox.x, 0, "viewBox baseVal");
-  is(animViewBox.x, 0, "viewBox baseVal");
-  is(baseViewBox.y, 0, "viewBox baseVal");
-  is(animViewBox.y, 0, "viewBox baseVal");
-  is(baseViewBox.width, 0, "viewBox baseVal");
-  is(animViewBox.width, 0, "viewBox baseVal");
-  is(baseViewBox.height, 0, "viewBox baseVal");
-  is(animViewBox.height, 0, "viewBox baseVal");
-  baseViewBox.x = 10;
-  baseViewBox.y = 11;
-  baseViewBox.width = 12;
-  baseViewBox.height = 13;
-  is(marker.getAttribute("viewBox"), "10 11 12 13", "viewBox attribute");
+  is(baseViewBox, null, "viewBox baseVal");
+  is(animViewBox, null, "viewBox animVal");
 
   marker.setAttribute("viewBox", "1 2 3 4");
   is(marker.viewBox.baseVal.x, 1, "viewBox.x baseVal");
   is(marker.viewBox.animVal.x, 1, "viewBox.x animVal");
   is(marker.viewBox.baseVal.y, 2, "viewbox.y baseVal");
   is(marker.viewBox.animVal.y, 2, "viewbox.y animVal");
   is(marker.viewBox.baseVal.width, 3, "viewbox.width baseVal");
   is(marker.viewBox.animVal.width, 3, "viewbox.width animVal");
@@ -275,21 +264,38 @@ function runTests()
   is(marker.viewBox.animVal.x, 5, "viewBox.x animVal");
   marker.viewBox.baseVal.y = 6;
   is(marker.viewBox.animVal.y, 6, "viewBox.y animVal");
   marker.viewBox.baseVal.width = 7;
   is(marker.viewBox.animVal.width, 7, "viewBox.width animVal");
   marker.viewBox.baseVal.height = 8;
   is(marker.viewBox.animVal.height, 8, "viewBox.height animVal");
   is(marker.getAttribute("viewBox"), "5 6 7 8", "viewBox attribute");
+  var storedViewBox = marker.viewBox.baseVal;
   marker.removeAttribute("viewBox");
   is(marker.hasAttribute("viewBox"), false, "viewBox hasAttribute");
   ok(marker.getAttribute("viewBox") === null, "removed viewBox attribute");
+  is(marker.viewBox.baseVal, null, "viewBox baseVal");
+  is(marker.viewBox.animVal, null, "viewBox animVal");
+
+  is(storedViewBox.width, 7, "Should not lose values");
+  storedViewBox.width = 200;
+  is(storedViewBox.width, 200, "Should be able to change detached viewBox rect");
+  is(marker.hasAttribute("viewBox"), false, "viewBox hasAttribute should still be false");
+  ok(marker.getAttribute("viewBox") === null, "viewBox attribute should still be null");
+  is(marker.viewBox.baseVal, null, "viewBox baseVal");
+  is(marker.viewBox.animVal, null, "viewBox animVal");
+
+  marker.setAttribute("viewBox", "none");
+  is(marker.hasAttribute("viewBox"), true, "viewBox hasAttribute");
+  is(marker.viewBox.baseVal, null, "viewBox baseVal");
+  is(marker.viewBox.animVal, null, "viewBox animVal");
 
   marker.setAttribute("viewBox", "");
+  is(marker.hasAttribute("viewBox"), true, "viewBox hasAttribute");
   ok(marker.getAttribute("viewBox") === "", "empty viewBox attribute");
 
   SimpleTest.finish();
 }
 
 window.addEventListener("load", runTests, false);
 </script>
 </pre>
--- a/content/svg/content/test/test_dataTypesModEvents.html
+++ b/content/svg/content/test/test_dataTypesModEvents.html
@@ -231,17 +231,18 @@ function runTests()
   // viewBox attribute
 
   eventChecker.watchAttr(marker, "viewBox");
   eventChecker.expect("add modify remove add");
   marker.setAttribute("viewBox", "1 2 3 4");
   marker.viewBox.baseVal.height = 5;
   marker.removeAttribute("viewBox");
   marker.removeAttributeNS(null, "viewBox");
-  marker.viewBox.baseVal.height = 4;
+  marker.setAttribute("viewBox", "none");
+  marker.setAttribute("viewBox", "none");
 
   eventChecker.ignoreEvents();
   marker.setAttribute("viewBox", "1 2 3 4");
   eventChecker.expect("");
   marker.viewBox.baseVal.height = 4;
   marker.viewBox.baseVal.x = 1;
   marker.setAttribute("viewBox", "1 2 3 4");
 
--- a/content/svg/content/test/test_fragments.html
+++ b/content/svg/content/test/test_fragments.html
@@ -34,16 +34,17 @@ function runTests()
   var svg = $("svg");
   var doc = svg.contentWindow.document;
   
   var tests = [
       new Test("unknown", false, null, null, null),
       new Test("svgView(viewBox(0,0,200,200))", true, "0 0 200 200", null, null),
       new Test("svgView(preserveAspectRatio(xMaxYMin slice))", true, null, "xMaxYMin slice", null),
       new Test("svgView(viewBox(1,2,3,4);preserveAspectRatio(xMinYMax))", true, "1 2 3 4", "xMinYMax meet", null),
+      new Test("svgView(viewBox(none))", true, "none", null, null),
       new Test("svgView(zoomAndPan(disable))", true, null, null, "disable"),
       new Test("svgView(transform(translate(-10,-20) scale(2) rotate(45) translate(5,10)))", true, null, null, null),
       // No duplicates allowed
       new Test("svgView(zoomAndPan(disable);zoomAndPan(disable))", false, null, null, null),
       new Test("svgView(viewBox(0,0,200,200);viewBox(0,0,200,200))", false, null, null, null),
       new Test("svgView(preserveAspectRatio(xMaxYMin);preserveAspectRatio(xMaxYMin))", false, null, null, null),
       new Test("svgView(transform(translate(0,200));transform(translate(0,200)))", false, null, null, null),
       // No invalid values allowed
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -40,16 +40,18 @@
 #include "nsTHashtable.h"
 
 #include "nsIScriptContext.h"
 #include "nsBindingManager.h"
 
 #include "nsThreadUtils.h"
 #include "mozilla/dom/NodeListBinding.h"
 
+using namespace mozilla;
+
 // ==================================================================
 // = nsAnonymousContentList 
 // ==================================================================
 
 #define NS_ANONYMOUS_CONTENT_LIST_IID \
   { 0xbfb5d8e7, 0xf718, 0x4a46, \
     { 0xb2, 0x2b, 0x22, 0x4a, 0x44, 0x4c, 0xb9, 0x77 } }
 
@@ -1172,17 +1174,17 @@ nsBindingManager::GetBindingImplementati
       nsIScriptGlobalObject *global = doc->GetScriptGlobalObject();
       if (!global)
         return NS_NOINTERFACE;
 
       nsIScriptContext *context = global->GetContext();
       if (!context)
         return NS_NOINTERFACE;
 
-      JSContext* jscontext = context->GetNativeContext();
+      AutoPushJSContext jscontext(context->GetNativeContext());
       if (!jscontext)
         return NS_NOINTERFACE;
 
       nsIXPConnect *xpConnect = nsContentUtils::XPConnect();
 
       JSObject* jsobj = aContent->GetWrapper();
       NS_ENSURE_TRUE(jsobj, NS_NOINTERFACE);
 
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -1258,17 +1258,17 @@ nsXBLBinding::AllowScripts()
     return false;
   }
 
   nsCOMPtr<nsIScriptContext> context = global->GetContext();
   if (!context) {
     return false;
   }
   
-  JSContext* cx = context->GetNativeContext();
+  AutoPushJSContext cx(context->GetNativeContext());
 
   nsCOMPtr<nsIDocument> ourDocument =
     mPrototypeBinding->XBLDocumentInfo()->GetDocument();
   bool canExecute;
   nsresult rv =
     mgr->CanExecuteScripts(cx, ourDocument->NodePrincipal(), &canExecute);
   return NS_SUCCEEDED(rv) && canExecute;
 }
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -267,17 +267,17 @@ nsXBLDocGlobalObject::EnsureScriptEnviro
   // hook up to the existing nsIScriptGlobalObject global setup by
   // nsGlobalWindow.
   DebugOnly<nsresult> rv = newCtx->InitContext();
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Script Language's InitContext failed");
   newCtx->DidInitializeContext();
 
   mScriptContext = newCtx;
 
-  JSContext *cx = mScriptContext->GetNativeContext();
+  AutoPushJSContext cx(mScriptContext->GetNativeContext());
   JSAutoRequest ar(cx);
 
   // nsJSEnvironment set the error reporter to NS_ScriptErrorReporter so
   // we must apparently override that with our own (although it isn't clear 
   // why - see bug 339647)
   JS_SetErrorReporter(cx, XBL_ProtoErrorReporter);
 
   mJSObject = JS_NewGlobalObject(cx, &gSharedGlobalClass,
--- a/content/xbl/src/nsXBLProtoImpl.cpp
+++ b/content/xbl/src/nsXBLProtoImpl.cpp
@@ -81,17 +81,17 @@ nsXBLProtoImpl::InstallImplementation(ns
 
   // If the prototype already existed, we don't need to install anything. return early.
   if (!targetObjectIsNew)
     return NS_OK;
 
   JSObject * targetScriptObject;
   holder->GetJSObject(&targetScriptObject);
 
-  JSContext *cx = context->GetNativeContext();
+  AutoPushJSContext cx(context->GetNativeContext());
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, targetClassObject);
   AutoVersionChecker avc(cx);
 
   // Walk our member list and install each one in turn.
   for (nsXBLProtoImplMember* curr = mMembers;
        curr;
        curr = curr->GetNext())
@@ -167,17 +167,17 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLP
   nsIScriptGlobalObject *sgo;
 
   if (!(sgo = ownerDoc->GetScopeObject())) {
     return NS_ERROR_UNEXPECTED;
   }
 
   // Because our prototype implementation has a class, we need to build up a corresponding
   // class for the concrete implementation in the bound document.
-  JSContext* jscontext = aContext->GetNativeContext();
+  AutoPushJSContext jscontext(aContext->GetNativeContext());
   JSObject* global = sgo->GetGlobalJSObject();
   nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
   jsval v;
   rv = nsContentUtils::WrapNative(jscontext, global, aBoundElement, &v,
                                   getter_AddRefs(wrapper));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // All of the above code was just obtaining the bound element's script object and its immediate
@@ -206,17 +206,17 @@ nsXBLProtoImpl::CompilePrototypeMembers(
   nsCOMPtr<nsIScriptGlobalObjectOwner> globalOwner(
       do_QueryObject(aBinding->XBLDocumentInfo()));
   nsIScriptGlobalObject* globalObject = globalOwner->GetScriptGlobalObject();
   NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED);
 
   nsIScriptContext *context = globalObject->GetContext();
   NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY);
 
-  JSContext *cx = context->GetNativeContext();
+  AutoPushJSContext cx(context->GetNativeContext());
   JSObject *global = globalObject->GetGlobalJSObject();
   
 
   JSObject* classObject;
   bool classObjectIsNew = false;
   nsresult rv = aBinding->InitClass(mClassName, cx, global, global,
                                     &classObject, &classObjectIsNew);
   if (NS_FAILED(rv))
@@ -343,17 +343,17 @@ nsXBLProtoImpl::DestroyMembers()
 
 nsresult
 nsXBLProtoImpl::Read(nsIScriptContext* aContext,
                      nsIObjectInputStream* aStream,
                      nsXBLPrototypeBinding* aBinding,
                      nsIScriptGlobalObject* aGlobal)
 {
   // Set up a class object first so that deserialization is possible
-  JSContext *cx = aContext->GetNativeContext();
+  AutoPushJSContext cx(aContext->GetNativeContext());
   JSObject *global = aGlobal->GetGlobalJSObject();
 
   JSObject* classObject;
   bool classObjectIsNew = false;
   nsresult rv = aBinding->InitClass(mClassName, cx, global, global, &classObject,
                                     &classObjectIsNew);
   NS_ENSURE_SUCCESS(rv, rv);
   MOZ_ASSERT(classObject);
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -395,17 +395,17 @@ nsXBLProtoImplField::InstallField(nsIScr
 
   // EvaluateString and JS_DefineUCProperty can both trigger GC, so
   // protect |result| here.
   nsresult rv;
 
   nsAutoCString uriSpec;
   aBindingDocURI->GetSpec(uriSpec);
   
-  JSContext* cx = aContext->GetNativeContext();
+  AutoPushJSContext cx(aContext->GetNativeContext());
   NS_ASSERTION(!::JS_IsExceptionPending(cx),
                "Shouldn't get here when an exception is pending!");
   
   // compile the literal string
   nsCOMPtr<nsIScriptContext> context = aContext;
 
   JSAutoRequest ar(cx);
 
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -15,16 +15,18 @@
 #include "nsIScriptContext.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "xpcpublic.h"
 #include "nsXBLPrototypeBinding.h"
 
+using namespace mozilla;
+
 nsXBLProtoImplMethod::nsXBLProtoImplMethod(const PRUnichar* aName) :
   nsXBLProtoImplMember(aName), 
   mUncompiledMethod(BIT_UNCOMPILED)
 {
   MOZ_COUNT_CTOR(nsXBLProtoImplMethod);
 }
 
 nsXBLProtoImplMethod::~nsXBLProtoImplMethod()
@@ -187,17 +189,17 @@ nsXBLProtoImplMethod::CompileMember(nsIS
   NS_ConvertUTF16toUTF8 cname(mName);
   nsAutoCString functionUri(aClassStr);
   int32_t hash = functionUri.RFindChar('#');
   if (hash != kNotFound) {
     functionUri.Truncate(hash);
   }
 
   JSObject* methodObject = nullptr;
-  JSContext* cx = aContext->GetNativeContext();
+  AutoPushJSContext cx(aContext->GetNativeContext());
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, aClassObject);
   JS::CompileOptions options(cx);
   options.setFileAndLine(functionUri.get(),
                          uncompiledMethod->mBodyText.GetLineNumber())
          .setVersion(JSVERSION_LATEST)
          .setUserBit(true); // Flag us as XBL
   js::RootedObject rootedNull(cx, nullptr); // See bug 781070.
@@ -282,17 +284,17 @@ nsXBLProtoImplAnonymousMethod::Execute(n
 
   nsCOMPtr<nsIScriptContext> context = global->GetContext();
   if (!context) {
     return NS_OK;
   }
 
   nsAutoMicroTask mt;
 
-  JSContext* cx = context->GetNativeContext();
+  AutoPushJSContext cx(context->GetNativeContext());
 
   JSObject* globalObject = global->GetGlobalJSObject();
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
   jsval v;
   nsresult rv =
     nsContentUtils::WrapNative(cx, globalObject, aBoundElement, &v,
                                getter_AddRefs(wrapper));
--- a/content/xbl/src/nsXBLProtoImplProperty.cpp
+++ b/content/xbl/src/nsXBLProtoImplProperty.cpp
@@ -4,24 +4,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "jsapi.h"
 #include "nsIContent.h"
 #include "nsXBLProtoImplProperty.h"
 #include "nsUnicharUtils.h"
+#include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "nsIScriptContext.h"
 #include "nsJSUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsXBLSerialize.h"
 #include "xpcpublic.h"
 
+using namespace mozilla;
+
 nsXBLProtoImplProperty::nsXBLProtoImplProperty(const PRUnichar* aName,
                                                const PRUnichar* aGetter, 
                                                const PRUnichar* aSetter,
                                                const PRUnichar* aReadOnly,
                                                uint32_t aLineNumber) :
   nsXBLProtoImplMember(aName), 
   mGetterText(nullptr),
   mSetterText(nullptr),
@@ -202,17 +205,17 @@ nsXBLProtoImplProperty::CompileMember(ns
   }
 
   bool deletedGetter = false;
   if (mGetterText && mGetterText->GetText()) {
     nsDependentString getter(mGetterText->GetText());
     if (!getter.IsEmpty()) {
       // Compile into a temp object so we don't wipe out mGetterText
       JSObject* getterObject = nullptr;
-      JSContext* cx = aContext->GetNativeContext();
+      AutoPushJSContext cx(aContext->GetNativeContext());
       JSAutoRequest ar(cx);
       JSAutoCompartment ac(cx, aClassObject);
       JS::CompileOptions options(cx);
       options.setFileAndLine(functionUri.get(), mGetterText->GetLineNumber())
              .setVersion(JSVERSION_LATEST)
              .setUserBit(true); // Flag us as XBL
       nsCString name = NS_LITERAL_CSTRING("get_") + NS_ConvertUTF16toUTF8(mName);
       js::RootedObject rootedNull(cx, nullptr); // See bug 781070.
@@ -252,17 +255,17 @@ nsXBLProtoImplProperty::CompileMember(ns
   }
 
   bool deletedSetter = false;
   if (mSetterText && mSetterText->GetText()) {
     nsDependentString setter(mSetterText->GetText());
     if (!setter.IsEmpty()) {
       // Compile into a temp object so we don't wipe out mSetterText
       JSObject* setterObject = nullptr;
-      JSContext* cx = aContext->GetNativeContext();
+      AutoPushJSContext cx(aContext->GetNativeContext());
       JSAutoRequest ar(cx);
       JSAutoCompartment ac(cx, aClassObject);
       JS::CompileOptions options(cx);
       options.setFileAndLine(functionUri.get(), mSetterText->GetLineNumber())
              .setVersion(JSVERSION_LATEST)
              .setUserBit(true); // Flag us as XBL
       nsCString name = NS_LITERAL_CSTRING("set_") + NS_ConvertUTF16toUTF8(mName);
       js::RootedObject rootedNull(cx, nullptr); // See bug 781070.
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -285,17 +285,17 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
   // responsible for pushing the context of the event target. See the similar
   // comment in nsEventManagerListener.cpp.
   nsCxPusher pusher;
   NS_ENSURE_STATE(pusher.Push(aTarget));
 
   rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  JSContext* cx = boundContext->GetNativeContext();
+  AutoPushJSContext cx(boundContext->GetNativeContext());
   JSAutoRequest ar(cx);
   JSObject* globalObject = boundGlobal->GetGlobalJSObject();
   JSObject* scopeObject = xpc::GetXBLScope(cx, globalObject);
 
   // Bind it to the bound element. Note that if we're using a separate XBL scope,
   // we'll actually be binding the event handler to a cross-compartment wrapper
   // to the bound element's reflector.
 
@@ -365,17 +365,17 @@ nsXBLPrototypeHandler::EnsureEventHandle
       return NS_OK;
     }
   }
 
   // Ensure that we have something to compile
   nsDependentString handlerText(mHandlerText);
   NS_ENSURE_TRUE(!handlerText.IsEmpty(), NS_ERROR_FAILURE);
 
-  JSContext* cx = aBoundContext->GetNativeContext();
+  AutoPushJSContext cx(aBoundContext->GetNativeContext());
   JSObject* globalObject = aGlobal->GetGlobalJSObject();
   JSObject* scopeObject = xpc::GetXBLScope(cx, globalObject);
 
   nsAutoCString bindingURI;
   mPrototypeBinding->DocURI()->GetSpec(bindingURI);
 
   uint32_t argCount;
   const char **argNames;
--- a/content/xbl/src/nsXBLSerialize.cpp
+++ b/content/xbl/src/nsXBLSerialize.cpp
@@ -3,31 +3,33 @@
  * 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 "nsXBLSerialize.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsContentUtils.h"
 #include "jsdbgapi.h"
 
+using namespace mozilla;
+
 nsresult
 XBL_SerializeFunction(nsIScriptContext* aContext,
                       nsIObjectOutputStream* aStream,
                       JSObject* aFunctionObject)
 {
-  JSContext* cx = aContext->GetNativeContext();
+  AutoPushJSContext cx(aContext->GetNativeContext());
   return nsContentUtils::XPConnect()->WriteFunction(aStream, cx, aFunctionObject);
 }
 
 nsresult
 XBL_DeserializeFunction(nsIScriptContext* aContext,
                         nsIObjectInputStream* aStream,
                         JSObject** aFunctionObjectp)
 {
-  JSContext* cx = aContext->GetNativeContext();
+  AutoPushJSContext cx(aContext->GetNativeContext());
   nsresult rv = nsContentUtils::XPConnect()->ReadFunction(aStream, cx, aFunctionObjectp);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Mark the script as XBL.
   //
   // This might be more elegantly handled as a flag via the XPConnect serialization
   // code, but that would involve profile compat issues between different builds.
   // Given that we know this code is XBL, just flag it as such.
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -28,16 +28,17 @@
 #include "nsNodeInfoManager.h"
 #include "nsContentUtils.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
 #include "xpcpublic.h"
 #include "mozilla/dom/BindingUtils.h"
 
 using mozilla::dom::DestroyProtoAndIfaceCache;
+using mozilla::AutoPushJSContext;
 
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
                      NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 
 class nsXULPDGlobalObject : public nsIScriptGlobalObject,
                             public nsIScriptObjectPrincipal
 {
@@ -752,17 +753,17 @@ nsXULPDGlobalObject::EnsureScriptEnviron
 
   nsCOMPtr<nsIScriptContext> ctxNew = languageRuntime->CreateContext(false, nullptr);
   MOZ_ASSERT(ctxNew);
 
   // We have to setup a special global object.  We do this then
   // attach it as the global for this context.  Then, we
   // will re-fetch the global and set it up in our language globals array.
   {
-    JSContext *cx = ctxNew->GetNativeContext();
+    AutoPushJSContext cx(ctxNew->GetNativeContext());
     JSAutoRequest ar(cx);
 
     JSObject *newGlob = JS_NewGlobalObject(cx, &gSharedGlobalClass,
                                            nsJSPrincipals::get(GetPrincipal()));
     if (!newGlob)
         return NS_OK;
 
     ::JS_SetGlobalObject(cx, newGlob);
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -66,16 +66,17 @@
 #include "nsNetUtil.h"
 #include "nsXULTemplateBuilder.h"
 #include "nsXULTemplateQueryProcessorRDF.h"
 #include "nsXULTemplateQueryProcessorXML.h"
 #include "nsXULTemplateQueryProcessorStorage.h"
 #include "nsContentUtils.h"
 
 using namespace mozilla::dom;
+using namespace mozilla;
 
 //----------------------------------------------------------------------
 
 static NS_DEFINE_CID(kRDFContainerUtilsCID,      NS_RDFCONTAINERUTILS_CID);
 static NS_DEFINE_CID(kRDFServiceCID,             NS_RDFSERVICE_CID);
 
 //----------------------------------------------------------------------
 //
@@ -1382,17 +1383,17 @@ nsXULTemplateBuilder::InitHTMLTemplateRo
         return NS_ERROR_UNEXPECTED;
 
     JSObject *scope = global->GetGlobalJSObject();
 
     nsIScriptContext *context = global->GetContext();
     if (! context)
         return NS_ERROR_UNEXPECTED;
 
-    JSContext* jscontext = context->GetNativeContext();
+    AutoPushJSContext jscontext(context->GetNativeContext());
     NS_ASSERTION(context != nullptr, "no jscontext");
     if (! jscontext)
         return NS_ERROR_UNEXPECTED;
 
     JSAutoRequest ar(jscontext);
 
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10194,18 +10194,20 @@ nsDocShell::AddState(nsIVariant *aData, 
         nsCOMPtr<nsIDocument> origDocument =
             do_GetInterface(GetAsSupports(this));
         if (!origDocument)
             return NS_ERROR_DOM_SECURITY_ERR;
         nsCOMPtr<nsIPrincipal> origPrincipal = origDocument->NodePrincipal();
 
         scContainer = new nsStructuredCloneContainer();
         JSContext *cx = aCx;
+        nsCxPusher pusher;
         if (!cx) {
             cx = nsContentUtils::GetContextFromDocument(document);
+            pusher.Push(cx);
         }
         rv = scContainer->InitFromVariant(aData, cx);
 
         // If we're running in the document's context and the structured clone
         // failed, clear the context's pending exception.  See bug 637116.
         if (NS_FAILED(rv) && !aCx) {
             JS_ClearPendingException(aCx);
         }
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -11,18 +11,16 @@
 
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "mozilla/Util.h"
 
 #include "mozilla/dom/ContentParent.h"
 
-#include "base/basictypes.h"
-
 #include "nsThreadUtils.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsIAudioManager.h"
 #endif
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
@@ -125,16 +123,17 @@ AudioChannelService::UnregisterAudioChan
 void
 AudioChannelService::UnregisterType(AudioChannelType aType,
                                     bool aElementHidden,
                                     uint64_t aChildID)
 {
   // The array may contain multiple occurrence of this appId but
   // this should remove only the first one.
   AudioChannelInternalType type = GetInternalType(aType, aElementHidden);
+  MOZ_ASSERT(!mChannelCounters[type].IsEmpty());
   mChannelCounters[type].RemoveElement(aChildID);
 
   // In order to avoid race conditions, it's safer to notify any existing
   // agent any time a new one is registered.
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     // We only remove ChildID when it is in the foreground.
     // If in the background, we kept ChildID for allowing it to play next song.
     if (aType == AUDIO_CHANNEL_CONTENT &&
@@ -143,16 +142,32 @@ AudioChannelService::UnregisterType(Audi
          !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].Contains(aChildID))) {
       mActiveContentChildIDs.RemoveElement(aChildID);
     }
     SendAudioChannelChangedNotification();
     Notify();
   }
 }
 
+void
+AudioChannelService::UpdateChannelType(AudioChannelType aType,
+                                       uint64_t aChildID,
+                                       bool aElementHidden,
+                                       bool aElementWasHidden)
+{
+  // Calculate the new and old internal type and update the hashtable if needed.
+  AudioChannelInternalType newType = GetInternalType(aType, aElementHidden);
+  AudioChannelInternalType oldType = GetInternalType(aType, aElementWasHidden);
+
+  if (newType != oldType) {
+    mChannelCounters[newType].AppendElement(aChildID);
+    mChannelCounters[oldType].RemoveElement(aChildID);
+  }
+}
+
 bool
 AudioChannelService::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden)
 {
   AudioChannelAgentData* data;
   if (!mAgents.Get(aAgent, &data)) {
     return true;
   }
 
@@ -167,25 +182,22 @@ AudioChannelService::GetMuted(AudioChann
   SendAudioChannelChangedNotification();
   return muted;
 }
 
 bool
 AudioChannelService::GetMutedInternal(AudioChannelType aType, uint64_t aChildID,
                                       bool aElementHidden, bool aElementWasHidden)
 {
+  UpdateChannelType(aType, aChildID, aElementHidden, aElementWasHidden);
+
   // Calculating the new and old type and update the hashtable if needed.
   AudioChannelInternalType newType = GetInternalType(aType, aElementHidden);
   AudioChannelInternalType oldType = GetInternalType(aType, aElementWasHidden);
 
-  if (newType != oldType) {
-    mChannelCounters[newType].AppendElement(aChildID);
-    mChannelCounters[oldType].RemoveElement(aChildID);
-  }
-
   // If the audio content channel is visible, let's remember this ChildID.
   if (newType == AUDIO_CHANNEL_INT_CONTENT &&
       oldType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN) {
 
     if (mActiveContentChildIDsFrozen) {
       mActiveContentChildIDsFrozen = false;
       mActiveContentChildIDs.Clear();
     }
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -70,16 +70,20 @@ protected:
   /* Register/Unregister IPC types: */
   void RegisterType(AudioChannelType aType, uint64_t aChildID);
   void UnregisterType(AudioChannelType aType, bool aElementHidden,
                       uint64_t aChildID);
 
   bool GetMutedInternal(AudioChannelType aType, uint64_t aChildID,
                         bool aElementHidden, bool aElementWasHidden);
 
+  /* Update the internal type value following the visibility changes */
+  void UpdateChannelType(AudioChannelType aType, uint64_t aChildID,
+                         bool aElementHidden, bool aElementWasHidden);
+
   AudioChannelService();
   virtual ~AudioChannelService();
 
   enum AudioChannelInternalType {
     AUDIO_CHANNEL_INT_NORMAL = 0,
     AUDIO_CHANNEL_INT_NORMAL_HIDDEN,
     AUDIO_CHANNEL_INT_CONTENT,
     AUDIO_CHANNEL_INT_CONTENT_HIDDEN,
--- a/dom/audiochannel/AudioChannelServiceChild.cpp
+++ b/dom/audiochannel/AudioChannelServiceChild.cpp
@@ -8,21 +8,23 @@
 
 #include "base/basictypes.h"
 
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "mozilla/Util.h"
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/ContentParent.h"
 #include "nsIObserverService.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::hal;
 
 StaticRefPtr<AudioChannelServiceChild> gAudioChannelServiceChild;
 
 // static
 AudioChannelService*
 AudioChannelServiceChild::GetAudioChannelService()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -63,16 +65,18 @@ AudioChannelServiceChild::GetMuted(Audio
   if (!mAgents.Get(aAgent, &data)) {
     return true;
   }
 
   ContentChild *cc = ContentChild::GetSingleton();
   bool muted = true;
   bool oldElementHidden = data->mElementHidden;
 
+  UpdateChannelType(data->mType, CONTENT_PROCESS_ID_MAIN, aElementHidden, oldElementHidden);
+
   // Update visibility.
   data->mElementHidden = aElementHidden;
 
   if (cc) {
     cc->SendAudioChannelGetMuted(data->mType, aElementHidden, oldElementHidden, &muted);
   }
   data->mMuted = muted;
 
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -13,16 +13,17 @@
 #include "nsDOMEvent.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "DOMCursor.h"
 
 using mozilla::dom::DOMRequest;
 using mozilla::dom::DOMRequestService;
 using mozilla::dom::DOMCursor;
+using mozilla::AutoPushJSContext;
 
 DOMRequest::DOMRequest(nsIDOMWindow* aWindow)
   : mResult(JSVAL_VOID)
   , mDone(false)
   , mRooted(false)
 {
   Init(aWindow);
 }
@@ -235,39 +236,41 @@ public:
   FireSuccessAsyncTask(DOMRequest* aRequest,
                        const jsval& aResult) :
     mReq(aRequest),
     mResult(aResult)
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     nsresult rv;
     nsIScriptContext* sc = mReq->GetContextForEventHandlers(&rv);
-    MOZ_ASSERT(NS_SUCCEEDED(rv) && sc->GetNativeContext());
-    JSAutoRequest ar(sc->GetNativeContext());
-    JS_AddValueRoot(sc->GetNativeContext(), &mResult);
+    AutoPushJSContext cx(sc->GetNativeContext());
+    MOZ_ASSERT(NS_SUCCEEDED(rv) && cx);
+    JSAutoRequest ar(cx);
+    JS_AddValueRoot(cx, &mResult);
   }
 
   NS_IMETHODIMP
   Run()
   {
     mReq->FireSuccess(mResult);
     return NS_OK;
   }
 
   ~FireSuccessAsyncTask()
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     nsresult rv;
     nsIScriptContext* sc = mReq->GetContextForEventHandlers(&rv);
-    MOZ_ASSERT(NS_SUCCEEDED(rv) && sc->GetNativeContext());
+    AutoPushJSContext cx(sc->GetNativeContext());
+    MOZ_ASSERT(NS_SUCCEEDED(rv) && cx);
 
     // We need to build a new request, otherwise we assert since there won't be
     // a request available yet.
-    JSAutoRequest ar(sc->GetNativeContext());
-    JS_RemoveValueRoot(sc->GetNativeContext(), &mResult);
+    JSAutoRequest ar(cx);
+    JS_RemoveValueRoot(cx, &mResult);
   }
 private:
   nsRefPtr<DOMRequest> mReq;
   jsval mResult;
 };
 
 class FireErrorAsyncTask : public nsRunnable
 {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4077,17 +4077,17 @@ BaseStubConstructor(nsIWeakReference* aW
 
       JSObject* object = nullptr;
       wrappedJS->GetJSObject(&object);
       if (!object) {
         return NS_ERROR_UNEXPECTED;
       }
 
       nsCxPusher pusher;
-      NS_ENSURE_STATE(pusher.Push(cx, false));
+      pusher.Push(cx);
 
       JSAutoRequest ar(cx);
       JSAutoCompartment ac(cx, object);
 
       JS::Value thisValue = JSVAL_VOID;
       JS::Value funval;
       if (!JS_GetProperty(cx, object, "constructor", &funval) || !funval.isObject()) {
         return NS_ERROR_UNEXPECTED;
@@ -4569,34 +4569,29 @@ nsDOMConstructor::HasInstance(nsIXPConne
   *bp = false;
   if (JSVAL_IS_PRIMITIVE(v)) {
     return NS_OK;
   }
 
   JSObject *dom_obj = JSVAL_TO_OBJECT(v);
   NS_ASSERTION(dom_obj, "nsDOMConstructor::HasInstance couldn't get object");
 
-  // This might not be the right object, if XPCNativeWrapping
-  // happened.  Get the wrapped native for this object, then get its
-  // JS object.
-  JSObject *wrapped_obj;
-  nsresult rv = nsContentUtils::XPConnect()->GetJSObjectOfWrapper(cx, dom_obj,
-                                                                  &wrapped_obj);
-  if (NS_SUCCEEDED(rv)) {
-    dom_obj = wrapped_obj;
-  }
+  // This might not be the right object, if there are wrappers. Unwrap if we can.
+  JSObject *wrapped_obj = js::UnwrapObjectChecked(dom_obj, /* stopAtOuter = */ false);
+  if (wrapped_obj)
+      dom_obj = wrapped_obj;
 
   JSClass *dom_class = JS_GetClass(dom_obj);
   if (!dom_class) {
     NS_ERROR("nsDOMConstructor::HasInstance can't get class.");
     return NS_ERROR_UNEXPECTED;
   }
 
   const nsGlobalNameStruct *name_struct;
-  rv = GetNameStruct(NS_ConvertASCIItoUTF16(dom_class->name), &name_struct);
+  nsresult rv = GetNameStruct(NS_ConvertASCIItoUTF16(dom_class->name), &name_struct);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (!name_struct) {
     // This isn't a normal DOM object, see if this constructor lives on its
     // prototype chain.
     jsval val;
@@ -5440,25 +5435,27 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
   // window's own context (not on some other window-caller's
   // context).
   if (!ObjectIsNativeWrapper(cx, obj)) {
     JSBool did_resolve = JS_FALSE;
     JSBool ok = JS_TRUE;
     JS::Value exn = JSVAL_VOID;
 
     {
+      nsCxPusher pusher;
       Maybe<JSAutoCompartment> ac;
 
       JSContext* my_cx;
       if (!my_context) {
         my_cx = cx;
       } else {
         my_cx = my_context->GetNativeContext();
 
         if (my_cx != cx) {
+          pusher.Push(my_cx);
           ac.construct(my_cx, obj);
         }
       }
 
       JSAutoRequest transfer(my_cx);
 
       // Don't resolve standard classes on XPCNativeWrapper etc, only
       // resolve them if we're resolving on the real global object.
@@ -7773,27 +7770,20 @@ public:
                                   nsIScriptContext* scriptContext)
     : mWrapper(wrapper),
       mContext(scriptContext)
   {
   }
 
   NS_IMETHOD Run()
   {
-    JSContext* cx = nullptr;
-    if (mContext) {
-      cx = mContext->GetNativeContext();
-    } else {
-      nsCOMPtr<nsIThreadJSContextStack> stack =
-        do_GetService("@mozilla.org/js/xpc/ContextStack;1");
-      NS_ENSURE_TRUE(stack, NS_OK);
-
-      cx = stack->GetSafeJSContext();
-      NS_ENSURE_TRUE(cx, NS_OK);
-    }
+    nsCxPusher pusher;
+    JSContext* cx = mContext ? mContext->GetNativeContext()
+                             : nsContentUtils::GetSafeJSContext();
+    pusher.Push(cx);
 
     JSObject* obj = nullptr;
     mWrapper->GetJSObject(&obj);
     NS_ASSERTION(obj, "Should never be null");
     nsHTMLPluginObjElementSH::SetupProtoChain(mWrapper, cx, obj);
     return NS_OK;
   }
 
@@ -7807,21 +7797,17 @@ NS_IMPL_ISUPPORTS1(nsPluginProtoChainIns
 // static
 nsresult
 nsHTMLPluginObjElementSH::SetupProtoChain(nsIXPConnectWrappedNative *wrapper,
                                           JSContext *cx,
                                           JSObject *obj)
 {
   NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
                "Shouldn't have gotten in here");
-
-  nsCxPusher cxPusher;
-  if (!cxPusher.Push(cx)) {
-    return NS_OK;
-  }
+  MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
 
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, obj);
 
   nsRefPtr<nsNPAPIPluginInstance> pi;
   nsresult rv = GetPluginInstanceIfSafe(wrapper, obj, cx, getter_AddRefs(pi));
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1334,17 +1334,17 @@ nsGlobalWindow::FreeInnerObjects()
 
   // Make sure that this is called before we null out the document and
   // other members that the window destroyed observers could
   // re-create.
   NotifyDOMWindowDestroyed(this);
 
   // Kill all of the workers for this window.
   nsIScriptContext *scx = GetContextInternal();
-  JSContext *cx = scx ? scx->GetNativeContext() : nullptr;
+  AutoPushJSContext cx(scx ? scx->GetNativeContext() : nullptr);
   mozilla::dom::workers::CancelWorkersForWindow(cx, this);
 
   // Close all IndexedDB databases for this window.
   indexedDB::IndexedDatabaseManager* idbManager =
     indexedDB::IndexedDatabaseManager::Get();
   if (idbManager) {
     idbManager->AbortCloseDatabasesForWindow(this);
   }
@@ -1888,17 +1888,17 @@ WindowStateHolder::~WindowStateHolder()
   }
 }
 
 NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder)
 
 nsresult
 nsGlobalWindow::CreateOuterObject(nsGlobalWindow* aNewInner)
 {
-  JSContext* cx = mContext->GetNativeContext();
+  AutoPushJSContext cx(mContext->GetNativeContext());
 
   JSObject* outer = NewOuterWindowProxy(cx, aNewInner->FastGetGlobalJSObject(),
                                         IsChromeWindow());
   if (!outer) {
     return NS_ERROR_FAILURE;
   }
 
   js::SetProxyExtra(outer, 0, js::PrivateValue(ToSupports(this)));
@@ -2072,19 +2072,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
   }
 
   nsRefPtr<nsGlobalWindow> newInnerWindow;
   bool createdInnerWindow = false;
 
   bool thisChrome = IsChromeWindow();
 
   nsCxPusher cxPusher;
-  if (!cxPusher.Push(cx)) {
-    return NS_ERROR_FAILURE;
-  }
+  cxPusher.Push(cx);
 
   XPCAutoRequest ar(cx);
 
   nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
   NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
 
   if (reUseInnerWindow) {
     // We're reusing the current inner window.
@@ -2992,21 +2990,20 @@ nsGlobalWindow::SetArguments(nsIArray *a
 
   return currentInner ?
     currentInner->DefineArgumentsProperty(aArguments) : NS_OK;
 }
 
 nsresult
 nsGlobalWindow::DefineArgumentsProperty(nsIArray *aArguments)
 {
-  JSContext *cx;
   nsIScriptContext *ctx = GetOuterWindowInternal()->mContext;
-  NS_ENSURE_TRUE(aArguments && ctx &&
-                 (cx = ctx->GetNativeContext()),
-                 NS_ERROR_NOT_INITIALIZED);
+  NS_ENSURE_TRUE(aArguments && ctx, NS_ERROR_NOT_INITIALIZED);
+  AutoPushJSContext cx(ctx->GetNativeContext());
+  NS_ENSURE_TRUE(cx, NS_ERROR_NOT_INITIALIZED);
 
   if (mIsModalContentWindow) {
     // Modal content windows don't have an "arguments" property, they
     // have a "dialogArguments" property which is handled
     // separately. See nsWindowSH::NewResolve().
 
     return NS_OK;
   }
@@ -6483,35 +6480,20 @@ NS_IMETHODIMP
 PostMessageEvent::Run()
 {
   NS_ABORT_IF_FALSE(mTargetWindow->IsOuterWindow(),
                     "should have been passed an outer window!");
   NS_ABORT_IF_FALSE(!mSource || mSource->IsOuterWindow(),
                     "should have been passed an outer window!");
 
   // Get the JSContext for the target window
-  JSContext* cx = nullptr;
   nsIScriptContext* scriptContext = mTargetWindow->GetContext();
-  if (scriptContext) {
-    cx = scriptContext->GetNativeContext();
-  }
-
-  if (!cx) {
-    // This can happen if mTargetWindow has been closed.  To avoid leaking,
-    // we need to find a JSContext.
-    nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
-    if (cxStack) {
-      cx = cxStack->GetSafeJSContext();
-    }
-
-    if (!cx) {
-      NS_WARNING("Cannot find a JSContext!  Leaking PostMessage buffer.");
-      return NS_ERROR_FAILURE;
-    }
-  }
+  AutoPushJSContext cx(scriptContext ? scriptContext->GetNativeContext()
+                                     : nsContentUtils::GetSafeJSContext());
+  MOZ_ASSERT(cx);
 
   // If we bailed before this point we're going to leak mMessage, but
   // that's probably better than crashing.
 
   // Ensure that the buffer is freed even if we fail to post the message
   JSAutoStructuredCloneBuffer buffer;
   buffer.adopt(mMessage, mMessageLen);
   mMessage = nullptr;
@@ -9957,17 +9939,18 @@ nsGlobalWindow::RunTimeoutHandler(nsTime
     // Evaluate the timeout expression.
     const PRUnichar* script = handler->GetHandlerText();
     NS_ASSERTION(script, "timeout has no script nor handler text!");
 
     const char* filename = nullptr;
     uint32_t lineNo = 0;
     handler->GetLocation(&filename, &lineNo);
 
-    JS::CompileOptions options(aScx->GetNativeContext());
+    AutoPushJSContext cx(aScx->GetNativeContext());
+    JS::CompileOptions options(cx);
     options.setFileAndLine(filename, lineNo)
            .setVersion(JSVERSION_DEFAULT);
     aScx->EvaluateString(nsDependentString(script), *FastGetGlobalJSObject(),
                          options, /*aCoerceToString = */ false, nullptr);
   } else {
     nsCOMPtr<nsIVariant> dummy;
     nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
     aScx->CallEventHandler(me, FastGetGlobalJSObject(),
@@ -10100,21 +10083,21 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
   nsCOMPtr<nsIScriptGlobalObject> windowKungFuDeathGrip(this);
 
   // A native timer has gone off. See which of our timeouts need
   // servicing
   TimeStamp now = TimeStamp::Now();
   TimeStamp deadline;
 
   if (aTimeout && aTimeout->mWhen > now) {
-    // The OS timer fired early (yikes!), and possibly out of order
-    // too. Set |deadline| to be the time when the OS timer *should*
-    // have fired so that any timers that *should* have fired before
-    // aTimeout *will* be fired now. This happens most of the time on
-    // Win2k.
+    // The OS timer fired early (which can happen due to the timers
+    // having lower precision than TimeStamp does).  Set |deadline| to
+    // be the time when the OS timer *should* have fired so that any
+    // timers that *should* have fired before aTimeout *will* be fired
+    // now.
 
     deadline = aTimeout->mWhen;
   } else {
     deadline = now;
   }
 
   // The timeout list is kept in deadline order. Discover the latest
   // timeout whose deadline has expired. On some platforms, native
@@ -10750,17 +10733,17 @@ nsGlobalWindow::SuspendTimeouts(uint32_t
     nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
     if (ac) {
       for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
         ac->RemoveWindowListener(mEnabledSensors[i], this);
     }
 
     // Suspend all of the workers for this window.
     nsIScriptContext *scx = GetContextInternal();
-    JSContext *cx = scx ? scx->GetNativeContext() : nullptr;
+    AutoPushJSContext cx(scx ? scx->GetNativeContext() : nullptr);
     mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
 
     TimeStamp now = TimeStamp::Now();
     for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
       // Set mTimeRemaining to be the time remaining for this timer.
       if (t->mWhen > now)
         t->mTimeRemaining = t->mWhen - now;
       else
@@ -10830,17 +10813,17 @@ nsGlobalWindow::ResumeTimeouts(bool aTha
     nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
     if (ac) {
       for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
         ac->AddWindowListener(mEnabledSensors[i], this);
     }
 
     // Resume all of the workers for this window.
     nsIScriptContext *scx = GetContextInternal();
-    JSContext *cx = scx ? scx->GetNativeContext() : nullptr;
+    AutoPushJSContext cx(scx ? scx->GetNativeContext() : nullptr);
     mozilla::dom::workers::ResumeWorkersForWindow(cx, this);
 
     // Restore all of the timeouts, using the stored time remaining
     // (stored in timeout->mTimeRemaining).
 
     TimeStamp now = TimeStamp::Now();
 
 #ifdef DEBUG
@@ -11332,17 +11315,17 @@ nsGlobalChromeWindow::NotifyDefaultButto
 
 NS_IMETHODIMP
 nsGlobalChromeWindow::GetMessageManager(nsIMessageBroadcaster** aManager)
 {
   FORWARD_TO_INNER_CHROME(GetMessageManager, (aManager), NS_ERROR_FAILURE);
   if (!mMessageManager) {
     nsIScriptContext* scx = GetContextInternal();
     NS_ENSURE_STATE(scx);
-    JSContext* cx = scx->GetNativeContext();
+    AutoPushJSContext cx(scx->GetNativeContext());
     NS_ENSURE_STATE(cx);
     nsCOMPtr<nsIMessageBroadcaster> globalMM =
       do_GetService("@mozilla.org/globalmessagemanager;1");
     mMessageManager =
       new nsFrameMessageManager(nullptr,
                                 static_cast<nsFrameMessageManager*>(globalMM.get()),
                                 cx,
                                 MM_CHROME | MM_BROADCASTER);
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1255,18 +1255,17 @@ nsJSContext::EvaluateString(const nsAStr
     *aRetValue = JSVAL_VOID;
   }
 
   if (!mScriptsEnabled) {
     return NS_OK;
   }
 
   nsCxPusher pusher;
-  if (!pusher.Push(mContext))
-    return NS_ERROR_FAILURE;
+  pusher.Push(mContext);
 
   xpc_UnmarkGrayObject(&aScopeObject);
   nsAutoMicroTask mt;
 
   JSPrincipals* p = JS_GetCompartmentPrincipals(js::GetObjectCompartment(&aScopeObject));
   aOptions.setPrincipals(p);
 
   bool ok = false;
@@ -1395,46 +1394,45 @@ nsJSContext::ExecuteScript(JSScript* aSc
     aScopeObject = JS_GetGlobalObject(mContext);
   }
 
   xpc_UnmarkGrayScript(aScriptObject);
   xpc_UnmarkGrayObject(aScopeObject);
 
   // Push our JSContext on our thread's context stack, in case native code
   // called from JS calls back into JS via XPConnect.
-  nsresult rv;
-  nsCOMPtr<nsIJSContextStack> stack =
-           do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
-  if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
-    return NS_ERROR_FAILURE;
-  }
+  nsCxPusher pusher;
+  pusher.Push(mContext);
 
   nsJSContext::TerminationFuncHolder holder(this);
   XPCAutoRequest ar(mContext);
-  JSAutoCompartment ac(mContext, aScopeObject);
-  ++mExecuteDepth;
-
-  // The result of evaluation, used only if there were no errors. This need
-  // not be a GC root currently, provided we run the GC only from the
-  // operation callback or from ScriptEvaluated.
-  jsval val;
-  if (!JS_ExecuteScript(mContext, aScopeObject, aScriptObject, &val)) {
-    ReportPendingException();
+
+  // Scope the JSAutoCompartment so that it gets destroyed before we pop the
+  // cx and potentially call JS_RestoreFrameChain.
+  {
+    JSAutoCompartment ac(mContext, aScopeObject);
+    ++mExecuteDepth;
+
+    // The result of evaluation, used only if there were no errors. This need
+    // not be a GC root currently, provided we run the GC only from the
+    // operation callback or from ScriptEvaluated.
+    jsval val;
+    if (!JS_ExecuteScript(mContext, aScopeObject, aScriptObject, &val)) {
+      ReportPendingException();
+    }
+    --mExecuteDepth;
   }
-  --mExecuteDepth;
 
   // Pop here, after JS_ValueToString and any other possible evaluation.
-  if (NS_FAILED(stack->Pop(nullptr))) {
-    rv = NS_ERROR_FAILURE;
-  }
+  pusher.Pop();
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
-  return rv;
+  return NS_OK;
 }
 
 
 #ifdef DEBUG
 bool
 AtomIsEventHandlerName(nsIAtom *aName)
 {
   const PRUnichar *name = aName->GetUTF16String();
@@ -1496,33 +1494,32 @@ nsJSContext::CallEventHandler(nsISupport
   }
 
   SAMPLE_LABEL("JS", "CallEventHandler");
 
   nsAutoMicroTask mt;
   xpc_UnmarkGrayObject(aScope);
   xpc_UnmarkGrayObject(aHandler);
 
+  nsCxPusher pusher;
+  pusher.Push(mContext);
   XPCAutoRequest ar(mContext);
+
   JSObject* target = nullptr;
   nsresult rv = JSObjectFromInterface(aTarget, aScope, &target);
   NS_ENSURE_SUCCESS(rv, rv);
 
   JS::AutoObjectRooter targetVal(mContext, target);
   jsval rval = JSVAL_VOID;
 
   // This one's a lot easier than EvaluateString because we don't have to
   // hassle with principals: they're already compiled into the JS function.
   // xxxmarkh - this comment is no longer true - principals are not used at
   // all now, and never were in some cases.
 
-  nsCxPusher pusher;
-  if (!pusher.Push(mContext, true))
-    return NS_ERROR_FAILURE;
-
   // check if the event handler can be run on the object in question
   rv = sSecurityManager->CheckFunctionAccess(mContext, aHandler, target);
 
   nsJSContext::TerminationFuncHolder holder(this);
 
   if (NS_SUCCEEDED(rv)) {
     // Convert args to jsvals.
     uint32_t argc = 0;
@@ -1745,16 +1742,18 @@ nsJSContext::InitializeExternalClasses()
 }
 
 nsresult
 nsJSContext::SetProperty(JSObject* aTarget, const char* aPropName, nsISupports* aArgs)
 {
   uint32_t  argc;
   jsval    *argv = nullptr;
 
+  nsCxPusher pusher;
+  pusher.Push(mContext);
   XPCAutoRequest ar(mContext);
 
   Maybe<nsRootedJSValueArray> tempStorage;
 
   nsresult rv =
     ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, &argv, tempStorage);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -45,23 +45,21 @@ nsStructuredCloneContainer::InitFromVari
 
   // First, try to extract a jsval from the variant |aData|.  This works only
   // if the variant implements GetAsJSVal.
   jsval jsData;
   nsresult rv = aData->GetAsJSVal(&jsData);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
 
   // Make sure that we serialize in the right context.
+  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   JSAutoRequest ar(aCx);
   JSAutoCompartment ac(aCx, JS_GetGlobalObject(aCx));
   JS_WrapValue(aCx, &jsData);
 
-  nsCxPusher cxPusher;
-  cxPusher.Push(aCx);
-
   uint64_t* jsBytes = nullptr;
   bool success = JS_WriteStructuredClone(aCx, jsData, &jsBytes, &mSize,
                                            nullptr, nullptr, JSVAL_VOID);
   NS_ENSURE_STATE(success);
   NS_ENSURE_STATE(jsBytes);
 
   // Copy jsBytes into our own buffer.
   mData = (uint64_t*) malloc(mSize);
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -86,19 +86,17 @@ CallbackObject::CallSetup::CallSetup(JSO
     // back on using the safe context.
     cx = nsContentUtils::GetSafeJSContext();
   }
 
   // Victory!  We have a JSContext.  Now do the things we need a JSContext for.
   mAr.construct(cx);
 
   // Make sure our JSContext is pushed on the stack.
-  if (!mCxPusher.Push(cx, false)) {
-    return;
-  }
+  mCxPusher.Push(cx);
 
   // After this point we guarantee calling ScriptEvaluated() if we
   // have an nsIScriptContext.
   // XXXbz Why, if, say CheckFunctionAccess fails?  I know that's how
   // nsJSContext::CallEventHandler works, but is it required?
   // FIXME: Bug 807369.
   mCtx = ctx;
 
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -796,17 +796,17 @@ jsval InterfaceToJsval(nsPIDOMWindow* aW
     return JSVAL_NULL;
   }
 
   nsIScriptContext *scriptContext = sgo->GetScriptContext();
   if (!scriptContext) {
     return JSVAL_NULL;
   }
 
-  JSContext *cx = scriptContext->GetNativeContext();
+  AutoPushJSContext cx(scriptContext->GetNativeContext());
   if (!cx) {
     return JSVAL_NULL;
   }
 
   jsval someJsVal;
   nsresult rv = nsContentUtils::WrapNative(cx,
                                            JS_GetGlobalObject(cx),
                                            aObject,
@@ -848,17 +848,17 @@ jsval StringToJsval(nsPIDOMWindow* aWind
     return JSVAL_NULL;
   }
 
   nsIScriptContext *scriptContext = sgo->GetScriptContext();
   if (!scriptContext) {
     return JSVAL_NULL;
   }
 
-  JSContext *cx = scriptContext->GetNativeContext();
+  AutoPushJSContext cx(scriptContext->GetNativeContext());
   if (!cx) {
     return JSVAL_NULL;
   }
 
   JSAutoRequest ar(cx);
 
   jsval result = JSVAL_NULL;
   if (!xpc::StringToJsval(cx, aString, &result)) {
--- a/dom/file/ArchiveRequest.cpp
+++ b/dom/file/ArchiveRequest.cpp
@@ -124,17 +124,17 @@ ArchiveRequest::ReaderReady(nsTArray<nsC
   }
 
   JS::Value result;
   nsresult rv;
 
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_STATE(sc);
 
-  JSContext* cx = sc->GetNativeContext();
+  AutoPushJSContext cx(sc->GetNativeContext());
   NS_ASSERTION(cx, "Failed to get a context!");
 
   JSObject* global = sc->GetNativeGlobal();
   NS_ASSERTION(global, "Failed to get global object!");
 
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, global);
 
--- a/dom/file/FileRequest.cpp
+++ b/dom/file/FileRequest.cpp
@@ -68,17 +68,17 @@ FileRequest::NotifyHelperCompleted(FileH
   }
 
   // Otherwise we need to get the result from the helper.
   jsval result;
 
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_STATE(sc);
 
-  JSContext* cx = sc->GetNativeContext();
+  AutoPushJSContext cx(sc->GetNativeContext());
   NS_ASSERTION(cx, "Failed to get a context!");
 
   JSObject* global = sc->GetNativeGlobal();
   NS_ASSERTION(global, "Failed to get global object!");
 
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, global);
 
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -209,25 +209,17 @@ IDBFactory::Create(ContentParent* aConte
     }
   }
 #endif
 
   nsCOMPtr<nsIPrincipal> principal =
     do_CreateInstance("@mozilla.org/nullprincipal;1");
   NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
 
-  JSContext* cx = nsContentUtils::GetSafeJSContext();
-  NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
-
-  nsCxPusher pusher;
-  if (!pusher.Push(cx)) {
-    NS_WARNING("Failed to push safe JS context!");
-    return NS_ERROR_FAILURE;
-  }
-
+  SafeAutoJSContext cx;
   JSAutoRequest ar(cx);
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   NS_ASSERTION(xpc, "This should never be null!");
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> globalHolder;
   nsresult rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(globalHolder));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -91,17 +91,17 @@ IDBRequest::NotifyHelperCompleted(Helper
 
   // See if our window is still valid. If not then we're going to pretend that
   // we never completed.
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return NS_OK;
   }
 
   // Otherwise we need to get the result from the helper.
-  JSContext* cx = GetJSContext();
+  AutoPushJSContext cx(GetJSContext());
   if (!cx) {
     NS_WARNING("Failed to get safe JSContext!");
     rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     SetError(rv);
     return rv;
   }
 
   JSObject* global = GetParentObject();
--- a/dom/interfaces/geolocation/Makefile.in
+++ b/dom/interfaces/geolocation/Makefile.in
@@ -17,15 +17,16 @@ GRE_MODULE     = 1
 XPIDLSRCS =                                    \
             nsIDOMGeoGeolocation.idl           \
             nsIDOMGeoPosition.idl              \
             nsIDOMGeoPositionCoords.idl        \
             nsIDOMGeoPositionCallback.idl      \
             nsIDOMGeoPositionError.idl         \
             nsIDOMGeoPositionErrorCallback.idl \
             nsIDOMNavigatorGeolocation.idl     \
+            nsIGeolocation.idl \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/interfaces/base \
   $(NULL)
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/geolocation/nsIGeolocation.idl
@@ -0,0 +1,29 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+
+interface nsIDOMGeoPositionCallback;
+interface nsIDOMGeoPositionErrorCallback;
+[ptr] native GeoPositionOptions(mozilla::idl::GeoPositionOptions);
+
+%{C++
+namespace mozilla {
+namespace idl {
+class GeoPositionOptions;
+}
+}
+%}
+
+[scriptable, builtinclass, uuid(d8e6449f-92c8-4c6a-aa9f-fef70157ec29)]
+interface nsIGeolocation : nsISupports
+{
+  // Versions of the DOM APIs that don't require JS option values
+  int32_t watchPosition(in nsIDOMGeoPositionCallback callback,
+                        in nsIDOMGeoPositionErrorCallback errorCallback,
+                        in GeoPositionOptions options);
+  void getCurrentPosition(in nsIDOMGeoPositionCallback callback,
+                          in nsIDOMGeoPositionErrorCallback errorCallback,
+                          in GeoPositionOptions options);
+};
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -120,16 +120,17 @@ static const char* sClipboardTextFlavors
 using base::ChildPrivileges;
 using base::KillProcess;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::dom::power;
 using namespace mozilla::dom::sms;
 using namespace mozilla::hal;
+using namespace mozilla::idl;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::net;
 
 namespace mozilla {
 namespace dom {
 
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
@@ -2278,18 +2279,34 @@ ContentParent::RecvFilePathUpdateNotify(
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (!obs) {
         return false;
     }
     obs->NotifyObservers(dsf, "file-watcher-update", NS_ConvertASCIItoUTF16(aReason).get());
     return true;
 }
 
+static int32_t
+AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy)
+{
+  nsCOMPtr<nsIGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
+  if (!geo) {
+    return -1;
+  }
+
+  GeoPositionOptions* options = new GeoPositionOptions();
+  options->enableHighAccuracy = highAccuracy;
+  int32_t retval = 1;
+  geo->WatchPosition(watcher, nullptr, options, &retval);
+  return retval;
+}
+
 bool
-ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal)
+ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
+                                          const bool& aHighAccuracy)
 {
 #ifdef MOZ_PERMISSIONS
   if (Preferences::GetBool("geo.testing.ignore_ipc_principal", false) == false) {
     nsIPrincipal* principal = aPrincipal;
     if (principal == nullptr) {
       KillHard();
       return true;
     }
@@ -2331,27 +2348,17 @@ ContentParent::RecvAddGeolocationListene
       return true;
     }
   }
 #endif
 
   // To ensure no geolocation updates are skipped, we always force the
   // creation of a new listener.
   RecvRemoveGeolocationListener();
-
-  nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
-  if (!geo) {
-    return true;
-  }
-
-  nsRefPtr<nsGeolocation> geosvc = static_cast<nsGeolocation*>(geo.get());
-  nsAutoPtr<mozilla::idl::GeoPositionOptions> options(new mozilla::idl::GeoPositionOptions());
-  jsval null = JS::NullValue();
-  options->Init(nullptr, &null);
-  geosvc->WatchPosition(this, nullptr, options.forget(), &mGeolocationWatchID);
+  mGeolocationWatchID = AddGeolocationListener(this, aHighAccuracy);
   return true;
 }
 
 bool
 ContentParent::RecvRemoveGeolocationListener()
 {
   if (mGeolocationWatchID != -1) {
     nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
@@ -2362,22 +2369,23 @@ ContentParent::RecvRemoveGeolocationList
     mGeolocationWatchID = -1;
   }
   return true;
 }
 
 bool
 ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable)
 {
-    nsRefPtr<nsGeolocationService> geoSvc =
-        nsGeolocationService::GetGeolocationService();
-    if (geoSvc) {
-        geoSvc->SetHigherAccuracy(aEnable);
-    }
-    return true;
+  // This should never be called without a listener already present,
+  // so this check allows us to forgo securing privileges.
+  if (mGeolocationWatchID != -1) {
+    RecvRemoveGeolocationListener();
+    mGeolocationWatchID = AddGeolocationListener(this, aEnable);
+  }
+  return true;
 }
 
 NS_IMETHODIMP
 ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
 {
   unused << SendGeolocationUpdate(GeoPosition(postion));
   return NS_OK;
 }
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -334,17 +334,18 @@ private:
                                  InfallibleTArray<nsString>* aRetvals);
     virtual bool RecvAsyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData);
 
     virtual bool RecvFilePathUpdateNotify(const nsString& aType,
                                           const nsString& aFilePath,
                                           const nsCString& aReason);
 
-    virtual bool RecvAddGeolocationListener(const IPC::Principal& aPrincipal);
+    virtual bool RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
+                                            const bool& aHighAccuracy);
     virtual bool RecvRemoveGeolocationListener();
     virtual bool RecvSetGeolocationHigherAccuracy(const bool& aEnable);
 
     virtual bool RecvConsoleMessage(const nsString& aMessage);
     virtual bool RecvScriptError(const nsString& aMessage,
                                  const nsString& aSourceName,
                                  const nsString& aSourceLine,
                                  const uint32_t& aLineNumber,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -425,17 +425,17 @@ parent:
                           bool textClickable,
                           nsString cookie,
                           nsString name);
 
     PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType,
                        nsCString aContentDisposition, bool aForceSave,
                        int64_t aContentLength, OptionalURIParams aReferrer);
 
-    AddGeolocationListener(Principal principal);
+    AddGeolocationListener(Principal principal, bool highAccuracy);
     RemoveGeolocationListener();
     SetGeolocationHigherAccuracy(bool enable);
 
     ConsoleMessage(nsString message);
     ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                 uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
                 nsCString category); 
 
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -207,17 +207,17 @@ MobileConnection::Observe(nsISupports* a
     nsString lockType;
     int32_t retryCount = -1;
 
     // Decode the json string "errorMsg" and retrieve its properties:
     // "lockType" and "retryCount".
     nsresult rv;
     nsIScriptContext* sc = GetContextForEventHandlers(&rv);
     NS_ENSURE_STATE(sc);
-    JSContext* cx = sc->GetNativeContext();
+    AutoPushJSContext cx(sc->GetNativeContext());
     NS_ASSERTION(cx, "Failed to get a context!");
 
     nsCOMPtr<nsIJSON> json(new nsJSON());
     jsval error;
     rv = json->DecodeToJSVal(errorMsg, cx, &error);
     NS_ENSURE_SUCCESS(rv, rv);
 
     jsval type;
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -39,25 +39,18 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSock
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPSocketParent)
   NS_INTERFACE_MAP_ENTRY(nsITCPSocketParent)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 bool
 TCPSocketParent::Init(const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL,
-                      const nsString& aBinaryType, PBrowserParent* aBrowser)
+                      const nsString& aBinaryType)
 {
-  // We don't have browser actors in xpcshell, and hence can't run automated
-  // tests without this loophole.
-  if (aBrowser && !AssertAppProcessPermission(aBrowser, "tcp-socket")) {
-    FireInteralError(this, __LINE__);
-    return true;
-  }
-
   nsresult rv;
   mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv);
   if (NS_FAILED(rv)) {
     FireInteralError(this, __LINE__);
     return true;
   }
 
   rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, getter_AddRefs(mSocket));
--- a/dom/network/src/TCPSocketParent.h
+++ b/dom/network/src/TCPSocketParent.h
@@ -22,18 +22,17 @@ class TCPSocketParent : public mozilla::
 public:
   NS_DECL_CYCLE_COLLECTION_CLASS(TCPSocketParent)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSITCPSOCKETPARENT
 
   TCPSocketParent() : mIntermediaryObj(nullptr), mIPCOpen(true) {}
 
   bool Init(const nsString& aHost, const uint16_t& aPort,
-            const bool& useSSL, const nsString& aBinaryType,
-            PBrowserParent* aBrowser);
+            const bool& useSSL, const nsString& aBinaryType);
 
   virtual bool RecvSuspend() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
   virtual bool RecvClose() MOZ_OVERRIDE;
   virtual bool RecvData(const SendableData& aData) MOZ_OVERRIDE;
   virtual bool RecvRequestDelete() MOZ_OVERRIDE;
 
 private:
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1216,17 +1216,17 @@ void NP_CALLBACK
 
 NPObject* NP_CALLBACK
 _getwindowobject(NPP npp)
 {
   if (!NS_IsMainThread()) {
     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getwindowobject called from the wrong thread\n"));
     return nullptr;
   }
-  JSContext *cx = GetJSContextFromNPP(npp);
+  AutoPushJSContext cx(GetJSContextFromNPP(npp));
   NS_ENSURE_TRUE(cx, nullptr);
 
   // Using ::JS_GetGlobalObject(cx) is ok here since the window we
   // want to return here is the outer window, *not* the inner (since
   // we don't know what the plugin will do with it).
   return nsJSObjWrapper::GetNewOrUsed(npp, cx, ::JS_GetGlobalObject(cx));
 }
 
@@ -1243,17 +1243,17 @@ NPObject* NP_CALLBACK
     return nullptr;
 
   nsCOMPtr<nsIDOMElement> element;
   inst->GetDOMElement(getter_AddRefs(element));
 
   if (!element)
     return nullptr;
 
-  JSContext *cx = GetJSContextFromNPP(npp);
+  AutoPushJSContext cx(GetJSContextFromNPP(npp));
   NS_ENSURE_TRUE(cx, nullptr);
 
   nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
   NS_ENSURE_TRUE(xpc, nullptr);
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
   xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), element,
                   NS_GET_IID(nsIDOMElement),
@@ -1514,17 +1514,17 @@ bool NP_CALLBACK
   if (!npp)
     return false;
 
   NPPAutoPusher nppPusher(npp);
 
   nsIDocument *doc = GetDocumentFromNPP(npp);
   NS_ENSURE_TRUE(doc, false);
 
-  JSContext *cx = GetJSContextFromDoc(doc);
+  AutoPushJSContext cx(GetJSContextFromDoc(doc));
   NS_ENSURE_TRUE(cx, false);
 
   nsCOMPtr<nsIScriptContext> scx = GetScriptContextFromJSContext(cx);
   NS_ENSURE_TRUE(scx, false);
 
   JSAutoRequest req(cx);
 
   JSObject *obj =
--- a/dom/sms/src/SmsManager.cpp
+++ b/dom/sms/src/SmsManager.cpp
@@ -166,17 +166,17 @@ SmsManager::Send(JSContext* aCx, JSObjec
 }
 
 NS_IMETHODIMP
 SmsManager::Send(const jsval& aNumber, const nsAString& aMessage, jsval* aReturn)
 {
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_STATE(sc);
-  JSContext* cx = sc->GetNativeContext();
+  AutoPushJSContext cx(sc->GetNativeContext());
   NS_ASSERTION(cx, "Failed to get a context!");
 
   if (!aNumber.isString() &&
       !(aNumber.isObject() && JS_IsArrayObject(cx, &aNumber.toObject()))) {
     return NS_ERROR_INVALID_ARG;
   }
 
   JSObject* global = sc->GetNativeGlobal();
@@ -248,20 +248,20 @@ SmsManager::Delete(const jsval& aParam, 
   }
 
   if (!aParam.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
+  AutoPushJSContext cx(sc->GetNativeContext());
   NS_ENSURE_STATE(sc);
   nsCOMPtr<nsIDOMMozSmsMessage> message =
-    do_QueryInterface(nsContentUtils::XPConnect()->GetNativeOfWrapper(
-          sc->GetNativeContext(), &aParam.toObject()));
+    do_QueryInterface(nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, &aParam.toObject()));
   NS_ENSURE_TRUE(message, NS_ERROR_INVALID_ARG);
 
   int32_t id;
   message->GetId(&id);
 
   return Delete(id, aRequest);
 }
 
--- a/dom/sms/src/SmsRequest.cpp
+++ b/dom/sms/src/SmsRequest.cpp
@@ -185,17 +185,17 @@ SmsRequest::SetSuccessInternal(nsISuppor
 
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   if (!sc) {
     SetError(nsISmsRequest::INTERNAL_ERROR);
     return false;
   }
 
-  JSContext* cx = sc->GetNativeContext();    
+  AutoPushJSContext cx(sc->GetNativeContext());
   NS_ASSERTION(cx, "Failed to get a context!");
 
   JSObject* global = sc->GetNativeGlobal();
   NS_ASSERTION(global, "Failed to get global object!");
 
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, global);
 
@@ -509,26 +509,26 @@ SmsRequest::NotifyThreadList(const Infal
   MOZ_ASSERT(!mParent);
   MOZ_ASSERT(GetOwner());
 
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS_VOID(rv);
   NS_ENSURE_TRUE_VOID(sc);
 
-  JSContext* cx = sc->GetNativeContext();
+  AutoPushJSContext cx(sc->GetNativeContext());
   MOZ_ASSERT(cx);
 
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
 
   JSObject* ownerObj = sgo->GetGlobalJSObject();
   NS_ENSURE_TRUE_VOID(ownerObj);
 
   nsCxPusher pusher;
-  NS_ENSURE_TRUE_VOID(pusher.Push(cx, false));
+  pusher.Push(cx);
 
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, ownerObj);
 
   JSObject* array = JS_NewArrayObject(cx, aItems.Length(), nullptr);
   NS_ENSURE_TRUE_VOID(array);
 
   bool ok;
--- a/dom/src/geolocation/Makefile.in
+++ b/dom/src/geolocation/Makefile.in
@@ -12,17 +12,16 @@ include $(DEPTH)/config/autoconf.mk
 MODULE         = dom
 LIBRARY_NAME   = jsdomgeolocation_s
 LIBXUL_LIBRARY = 1
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 FAIL_ON_WARNINGS := 1
 
-
 CPPSRCS		= \
 		nsGeolocation.cpp \
 		nsGeoPosition.cpp \
 		$(NULL)
 
 LOCAL_INCLUDES = \
 		-I$(topsrcdir)/dom/base \
 		-I$(topsrcdir)/dom/ipc \
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -454,20 +454,18 @@ nsGeolocationRequest::Allow()
   // -or-
   // b) the cached position time is some reasonable value to return to the user (<30s)
 
   uint32_t maximumAge = 30 * PR_MSEC_PER_SEC;
   if (mOptions) {
     if (mOptions->maximumAge >= 0) {
       maximumAge = mOptions->maximumAge;
     }
-    if (mOptions->enableHighAccuracy) {
-      gs->SetHigherAccuracy(true);
-    }
   }
+  gs->SetHigherAccuracy(mOptions && mOptions->enableHighAccuracy);
 
   if (lastPosition && maximumAge > 0 &&
       ( PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
         PRTime(cachedPositionTime) )) {
     // okay, we can return a cached position
     mAllowed = true;
 
     nsCOMPtr<nsIRunnable> ev = new RequestSendLocationEvent(lastPosition,
@@ -583,30 +581,32 @@ nsGeolocationRequest::Update(nsIDOMGeoPo
   }
   NS_DispatchToMainThread(ev);
   return true;
 }
 
 void
 nsGeolocationRequest::Shutdown()
 {
-  if (mOptions && mOptions->enableHighAccuracy) {
-    nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
-    if (gs) {
-      gs->SetHigherAccuracy(false);
-    }
-  }
-
   if (mTimeoutTimer) {
     mTimeoutTimer->Cancel();
     mTimeoutTimer = nullptr;
   }
   mCleared = true;
   mCallback = nullptr;
   mErrorCallback = nullptr;
+
+  // This should happen last, to ensure that this request isn't taken into consideration
+  // when deciding whether existing requests still require high accuracy.
+  if (mOptions && mOptions->enableHighAccuracy) {
+    nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
+    if (gs) {
+      gs->SetHigherAccuracy(false);
+    }
+  }
 }
 
 bool nsGeolocationRequest::Recv__delete__(const bool& allow)
 {
   if (allow) {
     (void) Allow();
   } else {
     (void) Cancel();
@@ -974,17 +974,18 @@ nsGeolocationService::StartDevice(nsIPri
 
   // we do not want to keep the geolocation devices online
   // indefinitely.  Close them down after a reasonable period of
   // inactivivity
   SetDisconnectTimer();
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild* cpc = ContentChild::GetSingleton();
-    cpc->SendAddGeolocationListener(IPC::Principal(aPrincipal));
+    cpc->SendAddGeolocationListener(IPC::Principal(aPrincipal),
+                                    HighAccuracyRequested());
     return NS_OK;
   }
 
   // Start them up!
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (!obs) {
     return NS_ERROR_FAILURE;
   }
@@ -1009,38 +1010,51 @@ nsGeolocationService::SetDisconnectTimer
     mDisconnectTimer->Cancel();
   }
 
   mDisconnectTimer->Init(this,
                          sProviderTimeout,
                          nsITimer::TYPE_ONE_SHOT);
 }
 
+bool
+nsGeolocationService::HighAccuracyRequested()
+{
+  for (uint32_t i = 0; i < mGeolocators.Length(); i++) {
+    if (mGeolocators[i]->HighAccuracyRequested()) {
+      return true;
+    }
+  }
+  return false;
+}
+
 void
 nsGeolocationService::SetHigherAccuracy(bool aEnable)
 {
+  bool highRequired = aEnable || HighAccuracyRequested();
+
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild* cpc = ContentChild::GetSingleton();
-    cpc->SendSetGeolocationHigherAccuracy(aEnable);
+    cpc->SendSetGeolocationHigherAccuracy(highRequired);
     return;
   }
 
-  if (!mHigherAccuracy && aEnable) {
+  if (!mHigherAccuracy && highRequired) {
     for (int32_t i = 0; i < mProviders.Count(); i++) {
       mProviders[i]->SetHighAccuracy(true);
     }
   }
 
-  if (mHigherAccuracy && !aEnable) {
+  if (mHigherAccuracy && !highRequired) {
     for (int32_t i = 0; i < mProviders.Count(); i++) {
       mProviders[i]->SetHighAccuracy(false);
     }
   }
 
-  mHigherAccuracy = aEnable;
+  mHigherAccuracy = highRequired;
 }
 
 void
 nsGeolocationService::StopDevice()
 {
   if(mDisconnectTimer) {
     mDisconnectTimer->Cancel();
     mDisconnectTimer = nullptr;
@@ -1101,16 +1115,17 @@ nsGeolocationService::RemoveLocator(nsGe
 // nsGeolocation
 ////////////////////////////////////////////////////
 
 DOMCI_DATA(GeoGeolocation, nsGeolocation)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGeolocation)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoGeolocation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMGeoGeolocation)
+  NS_INTERFACE_MAP_ENTRY(nsIGeolocation)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoGeolocation)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGeolocation)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGeolocation)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGeolocation)
   tmp->mPendingRequests.Clear();
@@ -1205,16 +1220,36 @@ nsGeolocation::HasActiveCallbacks()
     if (mWatchingCallbacks[i]->IsActive()) {
       return true;
     }
   }
 
   return mPendingCallbacks.Length() != 0;
 }
 
+bool
+nsGeolocation::HighAccuracyRequested()
+{
+  for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
+    if (mWatchingCallbacks[i]->IsActive() &&
+        mWatchingCallbacks[i]->WantsHighAccuracy()) {
+      return true;
+    }
+  }
+
+  for (uint32_t i = 0; i < mPendingCallbacks.Length(); i++) {
+    if (mPendingCallbacks[i]->IsActive() &&
+        mPendingCallbacks[i]->WantsHighAccuracy()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 void
 nsGeolocation::RemoveRequest(nsGeolocationRequest* aRequest)
 {
   mPendingCallbacks.RemoveElement(aRequest);
 
   // if it is in the mWatchingCallbacks, we can't do much
   // since we passed back the position in the array to who
   // ever called WatchPosition() and we do not want to mess
@@ -1251,17 +1286,17 @@ nsGeolocation::GetCurrentPosition(nsIDOM
 {
   nsresult rv;
   nsAutoPtr<mozilla::idl::GeoPositionOptions> options(
       OptionsFromJSOptions(cx, jsoptions, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
   return GetCurrentPosition(callback, errorCallback, options.forget());
 }
 
-nsresult
+NS_IMETHODIMP
 nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
                                   nsIDOMGeoPositionErrorCallback *errorCallback,
                                   mozilla::idl::GeoPositionOptions *options)
 {
   NS_ENSURE_ARG_POINTER(callback);
 
   if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -1324,17 +1359,17 @@ nsGeolocation::WatchPosition(nsIDOMGeoPo
 {
   nsresult rv;
   nsAutoPtr<mozilla::idl::GeoPositionOptions> options(
       OptionsFromJSOptions(cx, jsoptions, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
   return WatchPosition(callback, errorCallback, options.forget(), _retval);
 }
 
-nsresult
+NS_IMETHODIMP
 nsGeolocation::WatchPosition(nsIDOMGeoPositionCallback *callback,
                              nsIDOMGeoPositionErrorCallback *errorCallback,
                              mozilla::idl::GeoPositionOptions *options,
                              int32_t *_retval)
 {
   NS_ENSURE_ARG_POINTER(callback);
 
   if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -21,16 +21,17 @@
 #include "nsCycleCollectionParticipant.h"
 
 #include "nsIDOMGeoGeolocation.h"
 #include "nsIDOMGeoPosition.h"
 #include "nsIDOMGeoPositionError.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIDOMGeoPositionErrorCallback.h"
 #include "nsIDOMNavigatorGeolocation.h"
+#include "nsIGeolocation.h"
 
 #include "nsPIDOMWindow.h"
 
 #include "nsIGeolocationProvider.h"
 #include "nsIContentPermissionPrompt.h"
 #include "DictionaryHelpers.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "mozilla/Attributes.h"
@@ -59,16 +60,17 @@ class nsGeolocationRequest
   void Shutdown();
 
   // Called by the geolocation device to notify that a location has changed.
   // isBetter: the accuracy is as good or better than the previous position. 
   bool Update(nsIDOMGeoPosition* aPosition, bool aIsBetter);
 
   void SendLocation(nsIDOMGeoPosition* location);
   void MarkCleared();
+  bool WantsHighAccuracy() {return mOptions && mOptions->enableHighAccuracy;}
   bool IsActive() {return !mCleared;}
   bool Allowed() {return mAllowed;}
   void SetTimeoutTimer();
   nsIPrincipal* GetPrincipal();
 
   ~nsGeolocationRequest();
 
   bool Recv__delete__(const bool& allow);
@@ -130,16 +132,17 @@ public:
   // Stop the started geolocation device (gps, nmea, etc.)
   void     StopDevice();
 
   // create, or reinitalize the callback timer
   void     SetDisconnectTimer();
 
   // request higher accuracy, if possible
   void     SetHigherAccuracy(bool aEnable);
+  bool     HighAccuracyRequested();
 
 private:
 
   ~nsGeolocationService();
 
   // Disconnect timer.  When this timer expires, it clears all pending callbacks
   // and closes down the provider, unless we are watching a point, and in that
   // case, we disable the disconnect timer.
@@ -159,24 +162,26 @@ private:
   // Current state of requests for higher accuracy
   bool mHigherAccuracy;
 };
 
 
 /**
  * Can return a geolocation info
  */
-class nsGeolocation MOZ_FINAL : public nsIDOMGeoGeolocation
+class nsGeolocation MOZ_FINAL : public nsIDOMGeoGeolocation,
+                                public nsIGeolocation
 {
 public:
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIDOMGEOGEOLOCATION
+  NS_DECL_NSIGEOLOCATION
 
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsGeolocation)
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGeolocation, nsIDOMGeoGeolocation)
 
   nsGeolocation();
 
   nsresult Init(nsIDOMWindow* contentDom=nullptr);
 
   // Called by the geolocation device to notify that a location has changed.
   void Update(nsIDOMGeoPosition* aPosition, bool aIsBetter);
 
@@ -193,27 +198,22 @@ public:
   nsIPrincipal* GetPrincipal() { return mPrincipal; }
 
   // Getter for the window that this nsGeolocation is owned by
   nsIWeakReference* GetOwner() { return mOwner; }
 
   // Check to see if the widnow still exists
   bool WindowOwnerStillExists();
 
+  // Check to see if any active request requires high accuracy
+  bool HighAccuracyRequested();
+
   // Notification from the service:
   void ServiceReady();
 
-  // Versions of the DOM APIs that don't require JS option values
-  nsresult WatchPosition(nsIDOMGeoPositionCallback *callback,
-                         nsIDOMGeoPositionErrorCallback *errorCallback,
-                         mozilla::idl::GeoPositionOptions *options,
-                         int32_t *_retval);
-  nsresult GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
-                              nsIDOMGeoPositionErrorCallback *errorCallback,
-                              mozilla::idl::GeoPositionOptions *options);
 private:
 
   ~nsGeolocation();
 
   bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
 
   // Methods for the service when it's ready to process requests:
   nsresult GetCurrentPositionReady(nsGeolocationRequest* aRequest);
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -42,16 +42,18 @@
 #include "nsIScriptChannel.h"
 #include "nsIDocument.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsSandboxFlags.h"
 
+using mozilla::AutoPushJSContext;
+
 static NS_DEFINE_CID(kJSURICID, NS_JSURI_CID);
 
 class nsJSThunk : public nsIInputStream
 {
 public:
     nsJSThunk();
 
     NS_DECL_ISUPPORTS
@@ -234,36 +236,30 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         return rv;
 
     bool useSandbox =
         (aExecutionPolicy == nsIScriptChannel::EXECUTE_IN_SANDBOX);
 
     if (!useSandbox) {
         //-- Don't outside a sandbox unless the script principal subsumes the
         //   principal of the context.
-        nsCOMPtr<nsIPrincipal> objectPrincipal;
-        rv = securityManager->
-            GetObjectPrincipal(scriptContext->GetNativeContext(),
-                               globalJSObject,
-                               getter_AddRefs(objectPrincipal));
-        if (NS_FAILED(rv))
-            return rv;
+        nsIPrincipal* objectPrincipal = nsContentUtils::GetObjectPrincipal(globalJSObject);
 
         bool subsumes;
         rv = principal->Subsumes(objectPrincipal, &subsumes);
         if (NS_FAILED(rv))
             return rv;
 
         useSandbox = !subsumes;
     }
 
     JS::Value v = JS::UndefinedValue();
     // Finally, we have everything needed to evaluate the expression.
 
-    JSContext *cx = scriptContext->GetNativeContext();
+    AutoPushJSContext cx(scriptContext->GetNativeContext());
     JSAutoRequest ar(cx);
     if (useSandbox) {
         // We were asked to use a sandbox, or the channel owner isn't allowed
         // to execute in this context.  Evaluate the javascript URL in a
         // sandbox to prevent it from accessing data it doesn't have
         // permissions to access.
 
         // First check to make sure it's OK to evaluate this script to
--- a/dom/system/OSFileConstants.cpp
+++ b/dom/system/OSFileConstants.cpp
@@ -583,16 +583,17 @@ static dom::ConstantSpec gWinProperties[
 
   // Errors
   INT_CONSTANT(ERROR_ACCESS_DENIED),
   INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
   INT_CONSTANT(ERROR_FILE_EXISTS),
   INT_CONSTANT(ERROR_ALREADY_EXISTS),
   INT_CONSTANT(ERROR_FILE_NOT_FOUND),
   INT_CONSTANT(ERROR_NO_MORE_FILES),
+  INT_CONSTANT(ERROR_PATH_NOT_FOUND),
 
   PROP_END
 };
 #endif // defined(XP_WIN)
 
 
 /**
  * Get a field of an object as an object.
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -337,23 +337,17 @@ SystemWorkerManager::Init()
 {
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread");
   NS_ASSERTION(!mShutdown, "Already shutdown!");
 
-  JSContext* cx = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext();
-  NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
-
-  nsCxPusher pusher;
-  if (!pusher.Push(cx, false)) {
-    return NS_ERROR_FAILURE;
-  }
+  mozilla::SafeAutoJSContext cx;
 
   nsresult rv = InitWifi(cx);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to initialize WiFi Networking!");
     return rv;
   }
 
 #ifdef MOZ_WIDGET_GONK
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -269,36 +269,37 @@ Telephony::GetActive(jsval* aActive)
   if (!mActiveCall) {
     aActive->setNull();
     return NS_OK;
   }
 
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
+  AutoPushJSContext cx(sc ? sc->GetNativeContext() : nullptr);
   if (sc) {
     rv =
-      nsContentUtils::WrapNative(sc->GetNativeContext(),
-                                 sc->GetNativeGlobal(),
+      nsContentUtils::WrapNative(cx, sc->GetNativeGlobal(),
                                  mActiveCall->ToISupports(), aActive);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Telephony::GetCalls(jsval* aCalls)
 {
   JSObject* calls = mCallsArray;
   if (!calls) {
     nsresult rv;
     nsIScriptContext* sc = GetContextForEventHandlers(&rv);
     NS_ENSURE_SUCCESS(rv, rv);
+    AutoPushJSContext cx(sc ? sc->GetNativeContext() : nullptr);
     if (sc) {
-      rv = nsTArrayToJSArray(sc->GetNativeContext(), mCalls, &calls);
+      rv = nsTArrayToJSArray(cx, mCalls, &calls);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (!mRooted) {
         NS_HOLD_JS_OBJECTS(this, Telephony);
         mRooted = true;
       }
 
       mCallsArray = calls;
new file mode 100644
--- /dev/null
+++ b/dom/tests/unit/test_geo_provider_accuracy.js
@@ -0,0 +1,81 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
+const providerContract = "@mozilla.org/geolocation/unittest/geoprovider;1";
+
+const categoryName = "geolocation-provider";
+
+var provider = {
+  QueryInterface: function eventsink_qi(iid) {
+    if (iid.equals(Components.interfaces.nsISupports) ||
+        iid.equals(Components.interfaces.nsIFactory) ||
+        iid.equals(Components.interfaces.nsIGeolocationProvider))
+      return this;
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+  },
+  createInstance: function eventsink_ci(outer, iid) {
+    if (outer)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return this.QueryInterface(iid);
+  },
+  lockFactory: function eventsink_lockf(lock) {
+    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  startup: function() {
+  },
+  watch: function(callback, isPrivate) {
+    do_execute_soon(function() {
+      callback.update({coords: {latitude: 42, longitude: 42}, timestamp: 0});
+    });
+  },
+  shutdown: function() {
+  },
+  setHighAccuracy: function(enable) {
+    if (enable) {
+      this._seenHigh = true;
+    } else {
+      this._seenNotHigh = true;
+    }
+  },
+  _seenHigh: false,
+  _seenNotHigh: false
+};
+
+let runningInParent = true;
+try {
+  runningInParent = Components.classes["@mozilla.org/xre/runtime;1"].
+                    getService(Components.interfaces.nsIXULRuntime).processType
+                    == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+}
+catch (e) { }
+
+var geolocation;
+function run_test()
+{
+  do_test_pending();
+
+  if (runningInParent) {
+    Components.manager.nsIComponentRegistrar.registerFactory(providerCID,
+      "Unit test geo provider", providerContract, provider);
+    var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+                           .getService(Components.interfaces.nsICategoryManager);
+    catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
+                                               providerContract, false, true);
+
+    var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+    prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
+    prefs.setBoolPref("geo.wifi.scan", false);
+  }
+
+  geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsIDOMGeoGeolocation);
+  geolocation.getCurrentPosition(function() {
+    geolocation.getCurrentPosition(function() {
+      if (runningInParent) {
+        do_check_true(provider._seenNotHigh);
+        do_check_true(provider._seenHigh);
+      }
+      do_test_finished();
+    }, null, {enableHighAccuracy: false, maxAge: 0});
+  }, null, {enableHighAccuracy: true, maxAge: 0});
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/tests/unit/test_geo_provider_accuracy_wrap.js
@@ -0,0 +1,62 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
+const providerContract = "@mozilla.org/geolocation/unittest/geoprovider;1";
+
+const categoryName = "geolocation-provider";
+
+var provider = {
+  QueryInterface: function eventsink_qi(iid) {
+    if (iid.equals(Components.interfaces.nsISupports) ||
+        iid.equals(Components.interfaces.nsIFactory) ||
+        iid.equals(Components.interfaces.nsIGeolocationProvider))
+      return this;
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+  },
+  createInstance: function eventsink_ci(outer, iid) {
+    if (outer)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return this.QueryInterface(iid);
+  },
+  lockFactory: function eventsink_lockf(lock) {
+    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  startup: function() {
+  },
+  watch: function(callback, isPrivate) {
+    do_execute_soon(function() {
+      callback.update({coords: {latitude: 42, longitude: 42}, timestamp: 0});
+    });
+  },
+  shutdown: function() {
+  },
+  setHighAccuracy: function(enable) {
+    if (enable) {
+      this._seenHigh = true;
+    } else {
+      this._seenNotHigh = true;
+    }
+  },
+  _seenHigh: false,
+  _seenNotHigh: false
+};
+
+function run_test()
+{
+  Components.manager.nsIComponentRegistrar.registerFactory(providerCID,
+    "Unit test geo provider", providerContract, provider);
+  var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+                         .getService(Components.interfaces.nsICategoryManager);
+  catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
+                                             providerContract, false, true);
+
+  var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+  prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
+  prefs.setBoolPref("geo.wifi.scan", false);
+  run_test_in_child("test_geo_provider_accuracy.js", function() {
+    do_check_true(provider._seenNotHigh);
+    do_check_true(provider._seenHigh);
+      do_test_finished();
+  });
+}
\ No newline at end of file
--- a/dom/tests/unit/test_geolocation_provider.js
+++ b/dom/tests/unit/test_geolocation_provider.js
@@ -70,16 +70,17 @@ function run_test()
 
     httpserver = new HttpServer();
     httpserver.registerPathHandler("/geo", geoHandler);
     httpserver.start(4444);
 
     var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
     prefs.setCharPref("geo.wifi.uri", "http://localhost:4444/geo");
     prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
+    prefs.setBoolPref("geo.wifi.scan", false);
 
     var obs = Cc["@mozilla.org/observer-service;1"].getService();
     obs = obs.QueryInterface(Ci.nsIObserverService);
     obs.addObserver(observer, "geolocation-device-events", false);
 
     geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsIDOMGeoGeolocation);
     watchID = geolocation.watchPosition(successCallback, errorCallback);
 }
--- a/dom/tests/unit/xpcshell.ini
+++ b/dom/tests/unit/xpcshell.ini
@@ -5,11 +5,14 @@ tail =
 [test_bug319968.js]
 [test_bug465752.js]
 [test_geolocation_provider.js]
 # Bug 684962: test hangs consistently on Android
 skip-if = os == "android"
 [test_geolocation_timeout.js]
 [test_geolocation_timeout_wrap.js]
 skip-if = os == "mac"
+[test_geo_provider_accuracy.js]
+[test_geo_provider_accuracy_wrap.js]
+skip-if = os == "mac"
 [test_multiple_geo_listeners.js]
 [test_multiple_geo_listeners_wrap.js]
 skip-if = os == "mac"
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLDataElement.webidl
@@ -0,0 +1,13 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-data-element
+ */
+
+interface HTMLDataElement : HTMLElement {
+           [SetterThrows]
+           attribute DOMString value;
+};
--- a/dom/webidl/HTMLFrameElement.webidl
+++ b/dom/webidl/HTMLFrameElement.webidl
@@ -27,8 +27,10 @@ interface HTMLFrameElement : HTMLElement
   [GetterThrows]
   readonly attribute Document? contentDocument;
   [GetterThrows]
   readonly attribute WindowProxy? contentWindow;
 
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString marginHeight;
   [TreatNullAs=EmptyString, SetterThrows] attribute DOMString marginWidth;
 };
+
+HTMLFrameElement implements MozFrameLoaderOwner;
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -58,16 +58,17 @@ webidl_files = \
   GainNode.webidl \
   HTMLAnchorElement.webidl \
   HTMLAreaElement.webidl \
   HTMLBaseElement.webidl \
   HTMLBodyElement.webidl \
   HTMLBRElement.webidl \
   HTMLButtonElement.webidl \
   HTMLCollection.webidl \
+  HTMLDataElement.webidl \
   HTMLDataListElement.webidl \
   HTMLDirectoryElement.webidl \
   HTMLDivElement.webidl \
   HTMLDListElement.webidl \
   HTMLDocument.webidl \
   HTMLElement.webidl \
   HTMLFieldSetElement.webidl \
   HTMLFontElement.webidl \
--- a/editor/libeditor/base/nsEditPropertyAtomList.h
+++ b/editor/libeditor/base/nsEditPropertyAtomList.h
@@ -75,16 +75,17 @@ EDITOR_ATOM(cssPxUnit, "px")
 EDITOR_ATOM(cssRight, "right")
 EDITOR_ATOM(cssTextAlign, "text-align")
 EDITOR_ATOM(cssTextDecoration, "text-decoration")
 EDITOR_ATOM(cssTop, "top")
 EDITOR_ATOM(cssVerticalAlign, "vertical-align")
 EDITOR_ATOM(cssWhitespace, "white-space")
 EDITOR_ATOM(cssWidth, "width")
 EDITOR_ATOM(cssZIndex, "z-index")
+EDITOR_ATOM(data, "data")
 EDITOR_ATOM(datalist, "datalist")
 EDITOR_ATOM(dd, "dd")
 EDITOR_ATOM(dfn, "dfn")
 EDITOR_ATOM(div, "div")
 EDITOR_ATOM(dl, "dl")
 EDITOR_ATOM(dt, "dt")
 EDITOR_ATOM(em, "em")
 EDITOR_ATOM(face, "face")
--- a/editor/libeditor/html/nsHTMLEditUtils.cpp
+++ b/editor/libeditor/html/nsHTMLEditUtils.cpp
@@ -641,16 +641,17 @@ static const nsElementInfo kElements[eHT
   ELEM(canvas, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(caption, true, true, GROUP_NONE, GROUP_INLINE_ELEMENT),
   ELEM(center, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(cite, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(code, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(col, false, false, GROUP_TABLE_CONTENT | GROUP_COLGROUP_CONTENT,
        GROUP_NONE),
   ELEM(colgroup, true, false, GROUP_NONE, GROUP_COLGROUP_CONTENT),
+  ELEM(data, true, false, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(datalist, true, false, GROUP_PHRASE,
        GROUP_OPTIONS | GROUP_INLINE_ELEMENT),
   ELEM(dd, true, false, GROUP_DL_CONTENT, GROUP_FLOW_ELEMENT),
   ELEM(del, true, true, GROUP_PHRASE | GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(dfn, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(dir, true, false, GROUP_BLOCK, GROUP_LI),
   ELEM(div, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(dl, true, false, GROUP_BLOCK, GROUP_DL_CONTENT),
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -211,31 +211,32 @@ SharedSurface_ANGLEShareHandle::Create(G
     // Declare everything before 'goto's.
     HANDLE shareHandle = nullptr;
     nsRefPtr<ID3D10Texture2D> texture;
     nsRefPtr<ID3D10ShaderResourceView> srv;
 
     // On failure, goto CleanUpIfFailed.
     // If |failed|, CleanUpIfFailed will clean up and return null.
     bool failed = true;
+    HRESULT hr;
 
     // Off to the races!
     if (!egl->fQuerySurfacePointerANGLE(
             display,
             pbuffer,
             LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
             &shareHandle))
     {
         NS_ERROR("Failed to grab ShareHandle for PBuffer!");
         goto CleanUpIfFailed;
     }
 
     // Ok, we have a valid PBuffer with ShareHandle.
     // Let's attach it to D3D.
-    HRESULT hr = d3d->OpenSharedResource(shareHandle,
+    hr = d3d->OpenSharedResource(shareHandle,
                                          __uuidof(ID3D10Texture2D),
                                          getter_AddRefs(texture));
     if (FAILED(hr))
         goto CleanUpIfFailed;
 
     hr = d3d->CreateShaderResourceView(texture, nullptr, getter_AddRefs(srv));
     if (FAILED(hr))
         goto CleanUpIfFailed;
--- a/hal/cocoa/CocoaSensor.mm
+++ b/hal/cocoa/CocoaSensor.mm
@@ -1,75 +1,148 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
 #include "Hal.h"
 #include "nsITimer.h"
+#include "smslib.h"
 
-#include "smslib.h"
+#include <mach/mach.h>
+#include <cmath>
+#import <IOKit/IOKitLib.h>
+
 #define MEAN_GRAVITY 9.80665
 #define DEFAULT_SENSOR_POLL 100
-
 using namespace mozilla::hal;
-
 namespace mozilla {
 namespace hal_impl {
-
 static nsITimer* sUpdateTimer = nullptr;
+static bool sActiveSensors[NUM_SENSOR_TYPE];
+static io_connect_t sDataPort = IO_OBJECT_NULL;
+static uint64_t sLastMean = -1;
+static float
+LMUvalueToLux(uint64_t aValue)
+{
+  //Conversion formula from regression. See Bug 793728.
+  // -3*(10^-27)*x^4 + 2.6*(10^-19)*x^3 + -3.4*(10^-12)*x^2 + 3.9*(10^-5)*x - 0.19
+  long double powerC4 = 1/pow((long double)10,27);
+  long double powerC3 = 1/pow((long double)10,19);
+  long double powerC2 = 1/pow((long double)10,12);
+  long double powerC1 = 1/pow((long double)10,5);
 
-void UpdateHandler(nsITimer *aTimer, void *aClosure)
-{
-  sms_acceleration accel;
-  smsGetData(&accel);
+  long double term4 = -3.0 * powerC4 * pow(aValue,4);
+  long double term3 =  2.6 * powerC3 * pow(aValue,3);
+  long double term2 = -3.4 * powerC2 * pow(aValue,2);
+  long double term1 =  3.9 * powerC1 * aValue;
 
-  InfallibleTArray<float> values;
-  values.AppendElement(accel.x * MEAN_GRAVITY);
-  values.AppendElement(accel.y * MEAN_GRAVITY);
-  values.AppendElement(accel.z * MEAN_GRAVITY);
-  hal::SensorData sdata(hal::SENSOR_ACCELERATION,
-			PR_Now(),
-			values,
-			hal::SENSOR_ACCURACY_UNKNOWN);
-  hal::NotifySensorChange(sdata);
+  float lux = ceil(static_cast<float>(term4 + term3 + term2 + term1 - 0.19));
+  return lux > 0 ? lux : 0;
 }
+void
+UpdateHandler(nsITimer *aTimer, void *aClosure)
+{
+  for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
+    if (!sActiveSensors[i]) {
+      continue;
+    }
+    SensorType sensor = static_cast<SensorType>(i);
+    InfallibleTArray<float> values;
+    if (sensor == SENSOR_ACCELERATION) {
+      sms_acceleration accel;
+      smsGetData(&accel);
 
+      values.AppendElement(accel.x * MEAN_GRAVITY);
+      values.AppendElement(accel.y * MEAN_GRAVITY);
+      values.AppendElement(accel.z * MEAN_GRAVITY);
+    } else if (sensor == SENSOR_LIGHT && sDataPort != IO_OBJECT_NULL) {
+      kern_return_t kr;
+      uint32_t outputs = 2;
+      uint64_t lightLMU[outputs];
+
+      kr = IOConnectCallMethod(sDataPort, 0, nil, 0, nil, 0, lightLMU, &outputs, nil, 0);
+      if (kr == KERN_SUCCESS) {
+        uint64_t mean = (lightLMU[0] + lightLMU[1]) / 2;
+        if (mean == sLastMean) {
+          continue;
+        }
+        sLastMean = mean;
+        values.AppendElement(LMUvalueToLux(mean));
+      } else if (kr == kIOReturnBusy) {
+        continue;
+      }
+    }
+
+    hal::SensorData sdata(sensor,
+                          PR_Now(),
+                          values,
+                          hal::SENSOR_ACCURACY_UNKNOWN);
+    hal::NotifySensorChange(sdata);
+  }
+}
 void
 EnableSensorNotifications(SensorType aSensor)
 {
-  if (aSensor != SENSOR_ACCELERATION)
-    return;
+  if (aSensor == SENSOR_ACCELERATION) {
+    int result = smsStartup(nil, nil);
+
+    if (result != SMS_SUCCESS) {
+      return;
+    }
 
-  if (sUpdateTimer)
-    return;
-
-  int result = smsStartup(nil, nil);
-  if (result != SMS_SUCCESS) {
+    if (!smsLoadCalibration()) {
+      return;
+    }
+  } else if (aSensor == SENSOR_LIGHT) {
+    io_service_t serviceObject;
+    serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault,
+                                                IOServiceMatching("AppleLMUController"));
+    if (!serviceObject) {
+      return;
+    }
+    kern_return_t kr;
+    kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &sDataPort);
+    IOObjectRelease(serviceObject);
+    if (kr != KERN_SUCCESS) {
+      return;
+    }
+  } else {
+    NS_WARNING("EnableSensorNotifications called on an unknown sensor type");
     return;
   }
+  sActiveSensors[aSensor] = true;
 
-  if (!smsLoadCalibration()) {
+  if (!sUpdateTimer) {
+    CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
+    if (sUpdateTimer) {
+        sUpdateTimer->InitWithFuncCallback(UpdateHandler,
+                                           nullptr,
+                                           DEFAULT_SENSOR_POLL,
+                                           nsITimer::TYPE_REPEATING_SLACK);
+    }
+  }
+}
+void
+DisableSensorNotifications(SensorType aSensor)
+{
+  if (!sActiveSensors[aSensor] || (aSensor != SENSOR_ACCELERATION && aSensor != SENSOR_LIGHT)) {
     return;
   }
 
-  CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
-  if (sUpdateTimer)
-    sUpdateTimer->InitWithFuncCallback(UpdateHandler,
-                                       NULL,
-                                       DEFAULT_SENSOR_POLL,
-                                       nsITimer::TYPE_REPEATING_SLACK);
-}
+  sActiveSensors[aSensor] = false;
 
-void
-DisableSensorNotifications(SensorType aSensor)
-{
-  if (aSensor != SENSOR_ACCELERATION)
-    return;
-
+  if (aSensor == SENSOR_ACCELERATION) {
+    smsShutdown();
+  } else if (aSensor == SENSOR_LIGHT) {
+    IOServiceClose(sDataPort);
+  }
+  // If all sensors are disabled, cancel the update timer.
   if (sUpdateTimer) {
+    for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
+      if (sActiveSensors[i]) {
+        return;
+      }
+    }
     sUpdateTimer->Cancel();
     NS_RELEASE(sUpdateTimer);
   }
-  smsShutdown();
 }
-
 } // hal_impl
 } // mozilla
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -129,18 +129,20 @@ public:
     nsRefPtr<SVGParseCompleteListener> kungFuDeathGroup(this);
 
     mImage->OnSVGDocumentParsed();
   }
 
   void Cancel()
   {
     NS_ABORT_IF_FALSE(mDocument, "Duplicate call to Cancel");
-    mDocument->RemoveObserver(this);
-    mDocument = nullptr;
+    if (mDocument) {
+      mDocument->RemoveObserver(this);
+      mDocument = nullptr;
+    }
   }
 
 private:
   nsCOMPtr<nsIDocument> mDocument;
   VectorImage* mImage; // Raw pointer to owner.
 };
 
 NS_IMPL_ISUPPORTS1(SVGParseCompleteListener, nsIDocumentObserver)
@@ -194,20 +196,22 @@ public:
     }
 
     return NS_OK;
   }
 
   void Cancel()
   {
     NS_ABORT_IF_FALSE(mDocument, "Duplicate call to Cancel");
-    mDocument->RemoveEventListener(NS_LITERAL_STRING("MozSVGAsImageDocumentLoad"), this, true);
-    mDocument->RemoveEventListener(NS_LITERAL_STRING("SVGAbort"), this, true);
-    mDocument->RemoveEventListener(NS_LITERAL_STRING("SVGError"), this, true);
-    mDocument = nullptr;
+    if (mDocument) {
+      mDocument->RemoveEventListener(NS_LITERAL_STRING("MozSVGAsImageDocumentLoad"), this, true);
+      mDocument->RemoveEventListener(NS_LITERAL_STRING("SVGAbort"), this, true);
+      mDocument->RemoveEventListener(NS_LITERAL_STRING("SVGError"), this, true);
+      mDocument = nullptr;
+    }
   }
 
 private:
   nsCOMPtr<nsIDocument> mDocument;
   VectorImage* mImage; // Raw pointer to owner.
 };
 
 NS_IMPL_ISUPPORTS1(SVGLoadEventListener, nsIDOMEventListener)
--- a/ipc/dbus/DBusThread.cpp
+++ b/ipc/dbus/DBusThread.cpp
@@ -64,18 +64,16 @@
 #define LOG(args...) if (BTDEBUG) printf(args);
 #endif
 
 #define DEFAULT_INITIAL_POLLFD_COUNT 8
 
 // Functions for converting between unix events in the poll struct,
 // and their dbus definitions
 
-// TODO Add Wakeup to this list once we've moved to ics
-
 enum {
   DBUS_EVENT_LOOP_EXIT = 1,
   DBUS_EVENT_LOOP_ADD = 2,
   DBUS_EVENT_LOOP_REMOVE = 3,
   DBUS_EVENT_LOOP_WAKEUP = 4,
 } DBusEventTypes;
 
 static unsigned int UnixEventsToDBusFlags(short events)
@@ -362,16 +360,18 @@ DBusThread::EventLoop()
                != -1) {
           switch (data) {
           case DBUS_EVENT_LOOP_EXIT:
 #ifdef DEBUG
             LOG("DBus Event Loop Exiting\n");
 #endif
             dbus_connection_set_watch_functions(mConnection,
                                                 NULL, NULL, NULL, NULL, NULL);
+            dbus_connection_set_wakeup_main_function(mConnection, NULL, NULL,
+                                                     NULL);
             return;
           case DBUS_EVENT_LOOP_ADD:
             HandleWatchAdd(this);
             break;
           case DBUS_EVENT_LOOP_REMOVE:
             HandleWatchRemove(this);
             break;
           case DBUS_EVENT_LOOP_WAKEUP:
--- a/js/ipc/ObjectWrapperChild.cpp
+++ b/js/ipc/ObjectWrapperChild.cpp
@@ -37,17 +37,17 @@ namespace {
         AutoContextPusher(JSContext* cx
                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
             : mRequest(cx)
             , mContext(cx)
             , mSavedOptions(JS_SetOptions(cx, (JS_GetOptions(cx) |
                                                JSOPTION_DONT_REPORT_UNCAUGHT)))
         {
             MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-            mStack.Push(cx, false);
+            mStack.Push(cx);
         }
 
         ~AutoContextPusher() {
             mStack.Pop();
             JS_SetOptions(mContext, mSavedOptions);
         }
 
     };
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -80,16 +80,20 @@ class HashMap
     //     assert(p->key == 3);     // Entry contains the key
     //     char val = p->value;     // and value
     //   }
     //
     // Also see the definition of Ptr in HashTable above (with T = Entry).
     typedef typename Impl::Ptr Ptr;
     Ptr lookup(const Lookup &l) const                 { return impl.lookup(l); }
 
+    // Like lookup, but does not assert if two threads call lookup at the same
+    // time. Only use this method when none of the threads will modify the map.
+    Ptr readonlyThreadsafeLookup(const Lookup &l) const { return impl.readonlyThreadsafeLookup(l); }
+
     // Assuming |p.found()|, remove |*p|.
     void remove(Ptr p)                                { impl.remove(p); }
 
     // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient
     // insertion of Key |k| (where |HashPolicy::match(k,l) == true|) using
     // |add(p,k,v)|. After |add(p,k,v)|, |p| points to the new Entry. E.g.:
     //
     //   typedef HashMap<int,char> HM;
@@ -1338,16 +1342,22 @@ class HashTable : private AllocPolicy
 
     Ptr lookup(const Lookup &l) const
     {
         ReentrancyGuard g(*this);
         HashNumber keyHash = prepareHash(l);
         return Ptr(lookup(l, keyHash, 0));
     }
 
+    Ptr readonlyThreadsafeLookup(const Lookup &l) const
+    {
+        HashNumber keyHash = prepareHash(l);
+        return Ptr(lookup(l, keyHash, 0));
+    }
+
     AddPtr lookupForAdd(const Lookup &l) const
     {
         ReentrancyGuard g(*this);
         HashNumber keyHash = prepareHash(l);
         Entry &entry = lookup(l, keyHash, sCollisionBit);
         AddPtr p(entry, keyHash);
         p.mutationCount = mutationCount;
         return p;
--- a/js/src/build/autoconf/config.status.m4
+++ b/js/src/build/autoconf/config.status.m4
@@ -108,16 +108,22 @@ substs = [(name[1:-1], value[1:-1]) for 
 EOF
 
 dnl The MOZ_DIVERSION_SUBST output diversion contains AC_SUBSTs, in the
 dnl expected format, but lacks the final comma (see above).
 sed 's/$/,/' >> $CONFIG_STATUS <<EOF
 undivert(MOZ_DIVERSION_SUBST)dnl
 EOF
 
+dnl Add in the output from the subconfigure script
+for ac_subst_arg in $_subconfigure_ac_subst_args; do
+  variable='$'$ac_subst_arg
+  echo "    (''' $ac_subst_arg ''', r''' `eval echo $variable` ''')," >> $CONFIG_STATUS
+done
+
 cat >> $CONFIG_STATUS <<\EOF
 ] ]
 
 dnl List of files to apply AC_SUBSTs to. This is the list of files given
 dnl as an argument to AC_OUTPUT ($1)
 files = [
 EOF
 
new file mode 100644
--- /dev/null
+++ b/js/src/build/autoconf/subconfigure.m4
@@ -0,0 +1,46 @@
+dnl We are not running in a real autoconf environment. So we're using real m4
+dnl here, not the crazier environment that autoconf provides.
+
+dnl Autoconf expects [] for quotes; give it to them
+changequote([, ])
+
+dnl AC_DEFUN is provided to use instead of define in autoconf. Provide it too.
+define([AC_DEFUN], [define($1, [$2])])
+
+dnl AC_ARG_ENABLE(FEATURE, HELP-STRING, IF-TRUE[, IF-FALSE])
+dnl We have to ignore the help string due to how help works in autoconf...
+AC_DEFUN([AC_ARG_ENABLE],
+[#] Check whether --enable-[$1] or --disable-[$1] was given.
+[if test "[${enable_]patsubst([$1], -, _)+set}" = set; then
+  enableval="[$enable_]patsubst([$1], -, _)"
+  $3
+ifelse([$4], , , [else
+  $4
+])dnl
+fi
+])
+
+dnl AC_MSG_ERROR(error-description)
+AC_DEFUN([AC_MSG_ERROR], [{ echo "configure: error: $1" 1>&2; exit 1; }])
+
+AC_DEFUN([AC_MSG_WARN],  [ echo "configure: warning: $1" 1>&2 ])
+
+dnl Add the variable to the list of substitution variables
+AC_DEFUN([AC_SUBST],
+[
+_subconfigure_ac_subst_args="$_subconfigure_ac_subst_args $1"
+])
+
+dnl Override for AC_DEFINE.
+AC_DEFUN([AC_DEFINE],
+[
+cat >>confdefs.h <<\EOF
+[#define] $1 ifelse($#, 2, [$2], $#, 3, [$2], 1)
+EOF
+cat >> confdefs.pytmp <<\EOF
+    (''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
+EOF
+])
+
+dnl AC_OUTPUT_SUBDIRS(subdirectory)
+AC_DEFUN([AC_OUTPUT_SUBDIRS], [do_output_subdirs "$1"])
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -159,17 +159,17 @@ InitCollatorClass(JSContext *cx, HandleO
         return NULL;
 
     /*
      * Install the getter for Collator.prototype.compare, which returns a bound
      * comparison function for the specified Collator object (suitable for
      * passing to methods like Array.prototype.sort).
      */
     RootedValue getter(cx);
-    if (!cx->global()->getIntrinsicValue(cx, cx->names().CollatorCompare, &getter))
+    if (!cx->global()->getIntrinsicValue(cx, cx->names().CollatorCompareGet, &getter))
         return NULL;
     RootedValue undefinedValue(cx, UndefinedValue());
     if (!JSObject::defineProperty(cx, proto, cx->names().compare, undefinedValue,
                                   JS_DATA_TO_FUNC_PTR(JSPropertyOp, &getter.toObject()),
                                   NULL, JSPROP_GETTER)) {
         return NULL;
     }
 
@@ -311,17 +311,17 @@ InitNumberFormatClass(JSContext *cx, Han
         return NULL;
 
     /*
      * Install the getter for NumberFormat.prototype.format, which returns a
      * bound formatting function for the specified NumberFormat object (suitable
      * for passing to methods like Array.prototype.map).
      */
     RootedValue getter(cx);
-    if (!cx->global()->getIntrinsicValue(cx, cx->names().NumberFormatFormat, &getter))
+    if (!cx->global()->getIntrinsicValue(cx, cx->names().NumberFormatFormatGet, &getter))
         return NULL;
     RootedValue undefinedValue(cx, UndefinedValue());
     if (!JSObject::defineProperty(cx, proto, cx->names().format, undefinedValue,
                                   JS_DATA_TO_FUNC_PTR(JSPropertyOp, &getter.toObject()),
                                   NULL, JSPROP_GETTER)) {
         return NULL;
     }
 
@@ -463,17 +463,17 @@ InitDateTimeFormatClass(JSContext *cx, H
         return NULL;
 
     /*
      * Install the getter for DateTimeFormat.prototype.format, which returns a
      * bound formatting function for the specified DateTimeFormat object
      * (suitable for passing to methods like Array.prototype.map).
      */
     RootedValue getter(cx);
-    if (!cx->global()->getIntrinsicValue(cx, cx->names().DateTimeFormatFormat, &getter))
+    if (!cx->global()->getIntrinsicValue(cx, cx->names().DateTimeFormatFormatGet, &getter))
         return NULL;
     RootedValue undefinedValue(cx, UndefinedValue());
     if (!JSObject::defineProperty(cx, proto, cx->names().format, undefinedValue,
                                   JS_DATA_TO_FUNC_PTR(JSPropertyOp, &getter.toObject()),
                                   NULL, JSPROP_GETTER)) {
         return NULL;
     }
 
--- a/js/src/builtin/Intl.js
+++ b/js/src/builtin/Intl.js
@@ -371,16 +371,53 @@ function CanonicalizeLanguageTag(locale)
         else
             canonical = privateUse;
     }
 
     return canonical;
 }
 
 
+// mappings from some commonly used old-style language tags to current flavors
+// with script codes
+var oldStyleLanguageTagMappings = {
+    "pa-PK": "pa-Arab-PK",
+    "zh-CN": "zh-Hans-CN",
+    "zh-HK": "zh-Hant-HK",
+    "zh-SG": "zh-Hans-SG",
+    "zh-TW": "zh-Hant-TW"
+};
+
+
+/**
+ * Returns the BCP 47 language tag for the host environment's current locale.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 6.2.4.
+ */
+function DefaultLocale() {
+    var localeOfLastResort = "und";
+
+    var locale = RuntimeDefaultLocale();
+    if (!IsStructurallyValidLanguageTag(locale))
+        return localeOfLastResort;
+
+    locale = CanonicalizeLanguageTag(locale);
+    if (callFunction(std_Object_hasOwnProperty, oldStyleLanguageTagMappings, locale))
+        locale = oldStyleLanguageTagMappings[locale];
+
+    if (!(collatorInternalProperties.availableLocales[locale] &&
+          numberFormatInternalProperties.availableLocales[locale] &&
+          dateTimeFormatInternalProperties.availableLocales[locale]))
+    {
+        locale = localeOfLastResort;
+    }
+    return locale;
+}
+
+
 /**
  * Verifies that the given string is a well-formed ISO 4217 currency code.
  *
  * Spec: ECMAScript Internationalization API Specification, 6.3.1.
  */
 function IsWellFormedCurrencyCode(currency) {
     var c = ToString(currency);
     var normalized = toASCIIUpperCase(c);
@@ -396,27 +433,22 @@ function IsWellFormedCurrencyCode(curren
 /**
  * Add old-style language tags without script code for locales that in current
  * usage would include a script subtag. Returns the availableLocales argument
  * provided.
  *
  * Spec: ECMAScript Internationalization API Specification, 9.1.
  */
 function addOldStyleLanguageTags(availableLocales) {
-    // checking for commonly used old-style language tags only
-    if (availableLocales["pa-Arab-PK"])
-        availableLocales["pa-PK"] = true;
-    if (availableLocales["zh-Hans-CN"])
-        availableLocales["zh-CN"] = true;
-    if (availableLocales["zh-Hans-SG"])
-        availableLocales["zh-SG"] = true;
-    if (availableLocales["zh-Hant-HK"])
-        availableLocales["zh-HK"] = true;
-    if (availableLocales["zh-Hant-TW"])
-        availableLocales["zh-TW"] = true;
+    var oldStyleLocales = std_Object_getOwnPropertyNames(oldStyleLanguageTagMappings);
+    for (var i = 0; i < oldStyleLocales.length; i++) {
+        var oldStyleLocale = oldStyleLocales[i];
+        if (availableLocales[oldStyleLanguageTagMappings[oldStyleLocale]])
+            availableLocales[oldStyleLocale] = true;
+    }
     return availableLocales;
 }
 
 
 /**
  * Canonicalizes a locale list.
  *
  * Spec: ECMAScript Internationalization API Specification, 9.2.1.
@@ -498,26 +530,26 @@ function LookupMatcher(availableLocales,
         locale = requestedLocales[i];
         noExtensionsLocale = callFunction(std_String_replace, locale, unicodeLocaleExtensionSequenceGlobalRE, "");
         availableLocale = BestAvailableLocale(availableLocales, noExtensionsLocale);
         i++;
     }
 
     var result = new Record();
     if (availableLocale !== undefined) {
-        result.__locale = availableLocale;
+        result.locale = availableLocale;
         if (locale !== noExtensionsLocale) {
             var extensionMatch = callFunction(std_String_match, locale, unicodeLocaleExtensionSequenceRE);
             var extension = extensionMatch[0];
             var extensionIndex = extensionMatch.index;
-            result.__extension = extension;
-            result.__extensionIndex = extensionIndex;
+            result.extension = extension;
+            result.extensionIndex = extensionIndex;
         }
     } else {
-        result.__locale = DefaultLocale();
+        result.locale = DefaultLocale();
     }
     return result;
 }
 
 
 /**
  * Compares a BCP 47 language priority list against the set of locales in
  * availableLocales and determines the best available language to meet the
@@ -526,8 +558,657 @@ function LookupMatcher(availableLocales,
  * separately.
  *
  * Spec: ECMAScript Internationalization API Specification, 9.2.4.
  */
 function BestFitMatcher(availableLocales, requestedLocales) {
     // this implementation doesn't have anything better
     return LookupMatcher(availableLocales, requestedLocales);
 }
+
+
+/**
+ * Compares a BCP 47 language priority list against availableLocales and
+ * determines the best available language to meet the request. Options specified
+ * through Unicode extension subsequences are negotiated separately, taking the
+ * caller's relevant extensions and locale data as well as client-provided
+ * options into consideration.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.2.5.
+ */
+function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData) {
+    /*jshint laxbreak: true */
+
+    // Steps 1-3.
+    var matcher = options.localeMatcher;
+    var r = (matcher === "lookup")
+            ? LookupMatcher(availableLocales, requestedLocales)
+            : BestFitMatcher(availableLocales, requestedLocales);
+
+    // Step 4.
+    var foundLocale = r.locale;
+
+    // Step 5.a.
+    var extension = r.extension;
+    var extensionIndex, extensionSubtags, extensionSubtagsLength;
+
+    // Step 5.
+    if (extension !== undefined) {
+        // Step 5.b.
+        extensionIndex = r.extensionIndex;
+
+        // Steps 5.d-e.
+        extensionSubtags = callFunction(std_String_split, extension, "-");
+        extensionSubtagsLength = extensionSubtags.length;
+    }
+
+    // Steps 6-7.
+    var result = new Record();
+    result.dataLocale = foundLocale;
+
+    // Step 8.
+    var supportedExtension = "-u";
+
+    // Steps 9-11.
+    var i = 0;
+    var len = relevantExtensionKeys.length;
+    while (i < len) {
+        // Steps 11.a-c.
+        var key = relevantExtensionKeys[i];
+
+        // In this implementation, localeData is a function, not an object.
+        var foundLocaleData = localeData(foundLocale);
+        var keyLocaleData = foundLocaleData[key];
+
+        // Locale data provides default value.
+        // Step 11.d.
+        var value = keyLocaleData[0];
+
+        // Locale tag may override.
+
+        // Step 11.e.
+        var supportedExtensionAddition = "";
+
+        // Step 11.f is implemented by Utilities.js.
+
+        var valuePos;
+
+        // Step 11.g.
+        if (extensionSubtags !== undefined) {
+            // Step 11.g.i.
+            var keyPos = callFunction(std_Array_indexOf, extensionSubtags, key);
+
+            // Step 11.g.ii.
+            if (keyPos !== -1) {
+                // Step 11.g.ii.1.
+                if (keyPos + 1 < extensionSubtagsLength &&
+                    extensionSubtags[keyPos + 1].length > 2)
+                {
+                    // Step 11.g.ii.1.a.
+                    var requestedValue = extensionSubtags[keyPos + 1];
+
+                    // Step 11.g.ii.1.b.
+                    valuePos = callFunction(std_Array_indexOf, keyLocaleData, requestedValue);
+
+                    // Step 11.g.ii.1.c.
+                    if (valuePos !== -1) {
+                        value = requestedValue;
+                        supportedExtensionAddition = "-" + key + "-" + value;
+                    }
+                } else {
+                    // Step 11.g.ii.2.
+
+                    // According to the LDML spec, if there's no type value,
+                    // and true is an allowed value, it's used.
+
+                    // Step 11.g.ii.2.a.
+                    valuePos = callFunction(std_Array_indexOf, keyLocaleData, "true");
+
+                    // Step 11.g.ii.2.b.
+                    if (valuePos !== -1)
+                        value = "true";
+                }
+            }
+        }
+
+        // Options override all.
+
+        // Step 11.h.i.
+        var optionsValue = options[key];
+
+        // Step 11.h, 11.h.ii.
+        if (optionsValue !== undefined &&
+            callFunction(std_Array_indexOf, keyLocaleData, optionsValue) !== -1)
+        {
+            // Step 11.h.ii.1.
+            if (optionsValue !== value) {
+                value = optionsValue;
+                supportedExtensionAddition = "";
+            }
+        }
+
+        // Steps 11.i-k.
+        result[key] = value;
+        supportedExtension += supportedExtensionAddition;
+        i++;
+    }
+
+    // Step 12.
+    if (supportedExtension.length > 2) {
+        var preExtension = callFunction(std_String_substring, foundLocale, 0, extensionIndex);
+        var postExtension = callFunction(std_String_substring, foundLocale, extensionIndex);
+        foundLocale = preExtension + supportedExtension + postExtension;
+    }
+
+    // Steps 13-14.
+    result.locale = foundLocale;
+    return result;
+}
+
+
+/**
+ * Returns the subset of requestedLocales for which availableLocales has a
+ * matching (possibly fallback) locale. Locales appear in the same order in the
+ * returned list as in the input list.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.2.6.
+ */
+function LookupSupportedLocales(availableLocales, requestedLocales) {
+    // Steps 1-2.
+    var len = requestedLocales.length;
+    var subset = new List();
+
+    // Steps 3-4.
+    var k = 0;
+    while (k < len) {
+        // Steps 4.a-b.
+        var locale = requestedLocales[k];
+        var noExtensionsLocale = callFunction(std_String_replace, locale, unicodeLocaleExtensionSequenceGlobalRE, "");
+
+        // Step 4.c-d.
+        var availableLocale = BestAvailableLocale(availableLocales, noExtensionsLocale);
+        if (availableLocale !== undefined)
+            subset.push(locale);
+
+        // Step 4.e.
+        k++;
+    }
+
+    // Steps 5-6.
+    return subset.slice(0);
+}
+
+
+/**
+ * Returns the subset of requestedLocales for which availableLocales has a
+ * matching (possibly fallback) locale. Locales appear in the same order in the
+ * returned list as in the input list.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.2.7.
+ */
+function BestFitSupportedLocales(availableLocales, requestedLocales) {
+    // don't have anything better
+    return LookupSupportedLocales(availableLocales, requestedLocales);
+}
+
+
+/**
+ * Returns the subset of requestedLocales for which availableLocales has a
+ * matching (possibly fallback) locale. Locales appear in the same order in the
+ * returned list as in the input list.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.2.8.
+ */
+function SupportedLocales(availableLocales, requestedLocales, options) {
+    /*jshint laxbreak: true */
+
+    // Step 1.
+    var matcher;
+    if (options !== undefined) {
+        // Steps 1.a-b.
+        options = ToObject(options);
+        matcher = options.localeMatcher;
+
+        // Step 1.c.
+        if (matcher !== undefined) {
+            matcher = ToString(matcher);
+            if (matcher !== "lookup" && matcher !== "best fit")
+                ThrowError(JSMSG_INVALID_LOCALE_MATCHER, matcher);
+        }
+    }
+
+    // Steps 2-3.
+    var subset = (matcher === undefined || matcher === "best fit")
+                 ? BestFitSupportedLocales(availableLocales, requestedLocales)
+                 : LookupSupportedLocales(availableLocales, requestedLocales);
+
+    // Step 4.
+    for (var i = 0; i < subset.length; i++)
+        std_Object_defineProperty(subset, i, {value: subset[i], writable: false, enumerable: true, configurable: false});
+//    ??? commented out because of SpiderMonkey bugs 591059 and 598996
+//    std_Object_defineProperty(subset, "length", {value: subset.length, writable: false, enumerable: false, configurable: false});
+
+    // Step 5.
+    return subset;
+}
+
+
+/**
+ * Extracts a property value from the provided options object, converts it to
+ * the required type, checks whether it is one of a list of allowed values,
+ * and fills in a fallback value if necessary.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.2.9.
+ */
+function GetOption(options, property, type, values, fallback) {
+    // Step 1.
+    var value = options[property];
+
+    // Step 2.
+    if (value !== undefined) {
+        // Steps 2.a-c.
+        if (type === "boolean")
+            value = ToBoolean(value);
+        else if (type === "string")
+            value = ToString(value);
+        else
+            assert(false, "GetOption");
+
+        // Step 2.d.
+        if (values !== undefined && callFunction(std_Array_indexOf, values, value) === -1)
+            ThrowError(JSMSG_INVALID_OPTION_VALUE, property, value);
+
+        // Step 2.e.
+        return value;
+    }
+
+    // Step 3.
+    return fallback;
+}
+
+/**
+ * Extracts a property value from the provided options object, converts it to a
+ * Number value, checks whether it is in the allowed range, and fills in a
+ * fallback value if necessary.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.2.10.
+ */
+function GetNumberOption(options, property, minimum, maximum, fallback) {
+    assert(typeof minimum === "number", "GetNumberOption");
+    assert(typeof maximum === "number", "GetNumberOption");
+    assert(fallback === undefined || (fallback >= minimum && fallback <= maximum), "GetNumberOption");
+
+    // Step 1.
+    var value = options[property];
+
+    // Step 2.
+    if (value !== undefined) {
+        value = ToNumber(value);
+        if (std_isNaN(value) || value < minimum || value > maximum)
+            ThrowError(JSMSG_INVALID_DIGITS_VALUE, value);
+        return std_Math_floor(value);
+    }
+
+    // Step 3.
+    return fallback;
+}
+
+
+// ??? stub
+var runtimeAvailableLocales = (function () {
+    var o = std_Object_create(null);
+    o[RuntimeDefaultLocale()] = true;
+    return addOldStyleLanguageTags(o);
+}());
+
+
+/********** Property access for Intl objects **********/
+
+
+/**
+ * Set a normal public property p of o to value v, but use Object.defineProperty
+ * to avoid interference from setters on Object.prototype.
+ */
+function defineProperty(o, p, v) {
+    std_Object_defineProperty(o, p, {value: v, writable: true, enumerable: true, configurable: true});
+}
+
+
+/**
+ * Weak map holding objects with the properties specified as "internal" for
+ * all Intl API objects. Presence of an object as a key within this map is
+ * considered equivalent to having the [[initializedIntlObject]] internal
+ * property set to true on this object.
+ *
+ * Ideally we'd be using private symbols for internal properties, but
+ * SpiderMonkey doesn't have those yet.
+ */
+var internalsMap = new WeakMap();
+
+
+/**
+ * Create an object holding the properties specified as "internal" for
+ * an Intl API object. This call is equivalent to setting the
+ * [[initializedIntlObject]] internal property of o to true.
+ */
+function initializeIntlObject(o) {
+    assert(IsObject(o), "initializeIntlObject");
+    var internals = std_Object_create(null);
+    callFunction(std_WeakMap_set, internalsMap, o, internals);
+    return internals;
+}
+
+
+/**
+ * Return whether the object has been initialized as an Intl object, equivalent
+ * to testing whether the [[initializedIntlObject]] internal property of o is
+ * true.
+ */
+function isInitializedIntlObject(o) {
+    return callFunction(std_WeakMap_has, internalsMap, o);
+}
+
+
+/**
+ * Returns the object holding the internal properties of o.
+ */
+function getInternals(o) {
+    return callFunction(std_WeakMap_get, internalsMap, o);
+}
+
+
+/**
+ * Check that the object on which certain functions are called
+ * meet the requirements for "this Collator object", "this NumberFormat object",
+ * "this DateTimeFormat object". If it meets the requirements, return the
+ * object holding its internal properties.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.3.
+ * Spec: ECMAScript Internationalization API Specification, 11.3.
+ * Spec: ECMAScript Internationalization API Specification, 12.3.
+ */
+function checkIntlAPIObject(o, className, methodName) {
+    assert(typeof className === "string", "checkIntlAPIObject");
+    var internals = getInternals(o);
+    if (internals === undefined || internals["initialized" + className] !== true)
+        ThrowError(JSMSG_INTL_OBJECT_NOT_INITED, className, methodName, className);
+    assert(IsObject(o), "checkIntlAPIObject");
+    return internals;
+}
+
+
+/********** Intl.Collator **********/
+
+
+/**
+ * Mapping from Unicode extension keys for collation to options properties,
+ * their types and permissible values.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.1.1.
+ */
+var collatorKeyMappings = {
+    kn: {property: "numeric", type: "boolean"},
+    kf: {property: "caseFirst", type: "string", values: ["upper", "lower", "false"]}
+};
+
+
+/**
+ * Initializes an object as a Collator.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.1.1.
+ */
+function InitializeCollator(collator, locales, options) {
+    assert(IsObject(collator), "InitializeCollator");
+
+    // Step 1.
+    if (isInitializedIntlObject(collator))
+        ThrowError(JSMSG_INTL_OBJECT_REINITED);
+
+    // Step 2.
+    var internals = initializeIntlObject(collator);
+
+    // Step 3.
+    var requestedLocales = CanonicalizeLocaleList(locales);
+
+    // Steps 4-5.
+    if (options === undefined)
+        options = {};
+    else
+        options = ToObject(options);
+
+    // Compute options that impact interpretation of locale.
+    // Steps 6-7.
+    var u = GetOption(options, "usage", "string", ["sort", "search"], "sort");
+    internals.usage = u;
+
+    // Step 8.
+    var Collator = collatorInternalProperties;
+
+    // Step 9.
+    var localeData = u === "sort" ? Collator.sortLocaleData : Collator.searchLocaleData;
+
+    // Step 10.
+    var opt = new Record();
+
+    // Steps 11-12.
+    var matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
+    opt.localeMatcher = matcher;
+
+    // Check all allowed options properties and convert them to extension keys.
+    // Steps 13-13.a.
+    var key, mapping, property, value;
+    for (key in collatorKeyMappings) {
+        if (callFunction(std_Object_hasOwnProperty, collatorKeyMappings, key)) {
+            mapping = collatorKeyMappings[key];
+
+            // Step 13.b.
+            value = GetOption(options, mapping.property, mapping.type, mapping.values, undefined);
+
+            // Step 13.c.
+            if (mapping.type === "boolean" && value !== undefined)
+                value = callFunction(std_Boolean_toString, value);
+
+            // Step 13.d.
+            opt[key] = value;
+        }
+    }
+
+    // Compute effective locale.
+    // Step 14.
+    var relevantExtensionKeys = Collator.relevantExtensionKeys;
+
+    // Step 15.
+    var r = ResolveLocale(Collator.availableLocales,
+                          requestedLocales, opt,
+                          relevantExtensionKeys,
+                          localeData);
+    // Step 16.
+    internals.locale = r.locale;
+
+    // Steps 17-19.
+    var i = 0, len = relevantExtensionKeys.length;
+    while (i < len) {
+        // Step 19.a.
+        key = relevantExtensionKeys[i];
+        if (key === "co") {
+            // Step 19.b.
+            property = "collation";
+            value = r.co === null ? "default" : r.co;
+        } else {
+            // Step 19.c.
+            mapping = collatorKeyMappings[key];
+            property = mapping.property;
+            value = r[key];
+            if (mapping.type === "boolean")
+                value = value === "true";
+        }
+
+        // Step 19.d.
+        internals[property] = value;
+
+        // Step 19.e.
+        i++;
+    }
+
+    // Compute remaining collation options.
+    // Steps 20-21.
+    var s = GetOption(options, "sensitivity", "string",
+                      ["base", "accent", "case", "variant"], undefined);
+    if (s === undefined) {
+        if (u === "sort") {
+            // Step 21.a.
+            s = "variant";
+        } else {
+            // Step 21.b.
+            var dataLocale = r.dataLocale;
+            var dataLocaleData = localeData(dataLocale);
+            s = dataLocaleData.sensitivity;
+        }
+    }
+
+    // Step 22.
+    internals.sensitivity = s;
+
+    // Steps 23-24.
+    var ip = GetOption(options, "ignorePunctuation", "boolean", undefined, false);
+    internals.ignorePunctuation = ip;
+
+    // Step 25.
+    internals.boundFormat = undefined;
+
+    // Step 26.
+    internals.initializedCollator = true;
+}
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list has a
+ * matching (possibly fallback) locale. Locales appear in the same order in the
+ * returned list as in the input list.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.2.2.
+ */
+function Intl_Collator_supportedLocalesOf(locales /*, options*/) {
+    var options = arguments.length > 1 ? arguments[1] : undefined;
+
+    var availableLocales = collatorInternalProperties.availableLocales;
+    var requestedLocales = CanonicalizeLocaleList(locales);
+    return SupportedLocales(availableLocales, requestedLocales, options);
+}
+
+
+/**
+ * Collator internal properties.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 9.1 and 10.2.3.
+ */
+var collatorInternalProperties = {
+    sortLocaleData: collatorSortLocaleData,
+    searchLocaleData: collatorSearchLocaleData,
+    availableLocales: runtimeAvailableLocales, // stub
+    relevantExtensionKeys: ["co", "kn"]
+};
+
+
+function collatorSortLocaleData(locale) {
+    // the following data may or may not match any actual locale support
+    return {
+        co: [null],
+        kn: ["false", "true"]
+    };
+}
+
+
+function collatorSearchLocaleData(locale) {
+    // the following data may or may not match any actual locale support
+    return {
+        co: [null],
+        kn: ["false", "true"],
+        sensitivity: "variant"
+    };
+}
+
+
+/**
+ * Function to be bound and returned by Intl.Collator.prototype.format.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 12.3.2.
+ */
+function collatorCompareToBind(x, y) {
+    // Steps 1.a.i-ii implemented by ECMAScript declaration binding instantiation,
+    // ES5.1 10.5, step 4.d.ii.
+
+    // Step 1.a.iii-v.
+    var X = ToString(x);
+    var Y = ToString(y);
+    return CompareStrings(this, X, Y);
+}
+
+
+/**
+ * Returns a function bound to this Collator that compares x (converted to a
+ * String value) and y (converted to a String value),
+ * and returns a number less than 0 if x < y, 0 if x = y, or a number greater
+ * than 0 if x > y according to the sort order for the locale and collation
+ * options of this Collator object.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.3.2.
+ */
+function Intl_Collator_compare_get() {
+    // Check "this Collator object" per introduction of section 10.3.
+    var internals = checkIntlAPIObject(this, "Collator", "compare");
+
+    // Step 1.
+    if (internals.boundCompare === undefined) {
+        // Step 1.a.
+        var F = collatorCompareToBind;
+
+        // Step 1.b-d.
+        var bc = callFunction(std_Function_bind, F, this);
+        internals.boundCompare = bc;
+    }
+
+    // Step 2.
+    return internals.boundCompare;
+}
+
+
+/**
+ * Compares x (converted to a String value) and y (converted to a String value),
+ * and returns a number less than 0 if x < y, 0 if x = y, or a number greater
+ * than 0 if x > y according to the sort order for the locale and collation
+ * options of this Collator object.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.3.2.
+ */
+function CompareStrings(collator, x, y) {
+    assert(typeof x === "string", "CompareStrings");
+    assert(typeof y === "string", "CompareStrings");
+
+    // ??? stub
+    return x.localeCompare(y);
+}
+
+
+/**
+ * Returns the resolved options for a Collator object.
+ *
+ * Spec: ECMAScript Internationalization API Specification, 10.3.3 and 10.4.
+ */
+function Intl_Collator_resolvedOptions() {
+    // Check "this Collator object" per introduction of section 10.3.
+    var internals = checkIntlAPIObject(this, "Collator", "resolvedOptions");
+
+    var result = {
+        locale: internals.locale,
+        usage: internals.usage,
+        sensitivity: internals.sensitivity,
+        ignorePunctuation: internals.ignorePunctuation
+    };
+
+    var relevantExtensionKeys = collatorInternalProperties.relevantExtensionKeys;
+    for (var i = 0; i < relevantExtensionKeys.length; i++) {
+        var key = relevantExtensionKeys[i];
+        var property = (key === "co") ? "collation" : collatorKeyMappings[key].property;
+        defineProperty(result, property, internals[property]);
+    }
+    return result;
+}
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -45,16 +45,19 @@ var std_String_indexOf = String.prototyp
 var std_String_lastIndexOf = String.prototype.lastIndexOf;
 var std_String_match = String.prototype.match;
 var std_String_replace = String.prototype.replace;
 var std_String_split = String.prototype.split;
 var std_String_startsWith = String.prototype.startsWith;
 var std_String_substring = String.prototype.substring;
 var std_String_toLowerCase = String.prototype.toLowerCase;
 var std_String_toUpperCase = String.prototype.toUpperCase;
+var std_WeakMap_get = WeakMap.prototype.get;
+var std_WeakMap_has = WeakMap.prototype.has;
+var std_WeakMap_set = WeakMap.prototype.set;
 
 
 /********** List specification type **********/
 
 
 /* Spec: ECMAScript Language Specification, 5.1 edition, 8.8 */
 function List() {
     if (IS_UNDEFINED(List.prototype)) {
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -12,16 +12,17 @@
 #include "frontend/BytecodeEmitter.h"
 #include "frontend/FoldConstants.h"
 #include "frontend/NameFunctions.h"
 #include "vm/GlobalObject.h"
 
 #include "jsinferinlines.h"
 
 #include "frontend/ParseMaps-inl.h"
+#include "frontend/ParseNode-inl.h"
 #include "frontend/Parser-inl.h"
 #include "frontend/SharedContext-inl.h"
 
 using namespace js;
 using namespace js::frontend;
 
 static bool
 CheckLength(JSContext *cx, size_t length)
@@ -42,22 +43,22 @@ SetSourceMap(JSContext *cx, TokenStream 
     if (tokenStream.hasSourceMap()) {
         if (!ss->setSourceMap(cx, tokenStream.releaseSourceMap(), script->filename))
             return false;
     }
     return true;
 }
 
 static bool
-CheckArgumentsWithinEval(JSContext *cx, Parser &parser, HandleFunction fun)
+CheckArgumentsWithinEval(JSContext *cx, Parser<FullParseHandler> &parser, HandleFunction fun)
 {
     if (fun->hasRest()) {
         // It's an error to use |arguments| in a function that has a rest
         // parameter.
-        parser.reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
+        parser.report(ParseError, false, NULL, JSMSG_ARGUMENTS_AND_REST);
         return false;
     }
 
     // Force construction of arguments objects for functions that use
     // |arguments| within an eval.
     RootedScript script(cx, fun->nonLazyScript());
     if (script->argumentsHasVarBinding()) {
         if (!JSScript::argumentsOptimizationFailed(cx, script))
@@ -114,24 +115,24 @@ frontend::CompileScript(JSContext *cx, H
         break;
       case CompileOptions::LAZY_SOURCE:
         ss->setSourceRetrievable();
         break;
       case CompileOptions::NO_SOURCE:
         break;
     }
 
-    Parser parser(cx, options, chars, length, /* foldConstants = */ true);
+    Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true);
     if (!parser.init())
         return UnrootedScript(NULL);
     parser.sct = sct;
 
     GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
 
-    ParseContext pc(&parser, &globalsc, staticLevel, /* bodyid = */ 0);
+    ParseContext<FullParseHandler> pc(&parser, &globalsc, staticLevel, /* bodyid = */ 0);
     if (!pc.init())
         return UnrootedScript(NULL);
 
     bool savedCallerFun =
         options.compileAndGo &&
         evalCaller &&
         (evalCaller->function() || evalCaller->savedCallerFun);
     Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), savedCallerFun,
@@ -180,20 +181,19 @@ frontend::CompileScript(JSContext *cx, H
             JSFunction *fun = evalCaller->functionOrCallerFunction();
             ObjectBox *funbox = parser.newFunctionBox(fun, &pc, fun->strict());
             if (!funbox)
                 return UnrootedScript(NULL);
             bce.objectList.add(funbox);
         }
     }
 
-    TokenStream &tokenStream = parser.tokenStream;
     bool canHaveDirectives = true;
     for (;;) {
-        TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
+        TokenKind tt = parser.tokenStream.peekToken(TSF_OPERAND);
         if (tt <= TOK_EOF) {
             if (tt == TOK_EOF)
                 break;
             JS_ASSERT(tt == TOK_ERROR);
             return UnrootedScript(NULL);
         }
 
         ParseNode *pn = parser.statement();
@@ -208,20 +208,20 @@ frontend::CompileScript(JSContext *cx, H
         if (!FoldConstants(cx, &pn, &parser))
             return UnrootedScript(NULL);
         if (!NameFunctions(cx, pn))
             return UnrootedScript(NULL);
 
         if (!EmitTree(cx, &bce, pn))
             return UnrootedScript(NULL);
 
-        parser.freeTree(pn);
+        parser.handler.freeTree(pn);
     }
 
-    if (!SetSourceMap(cx, tokenStream, ss, script))
+    if (!SetSourceMap(cx, parser.tokenStream, ss, script))
         return UnrootedScript(NULL);
 
     if (evalCaller && evalCaller->functionOrCallerFunction()) {
         // Watch for uses of 'arguments' within the evaluated script, both as
         // free variables and as variables redeclared with 'var'.
         RootedFunction fun(cx, evalCaller->functionOrCallerFunction());
         HandlePropertyName arguments = cx->names().arguments;
         for (AtomDefnRange r = pc.lexdeps->all(); !r.empty(); r.popFront()) {
@@ -268,16 +268,56 @@ frontend::CompileScript(JSContext *cx, H
     bce.tellDebuggerAboutCompiledScript(cx);
 
     if (sct == &mysct && !sct->complete())
         return UnrootedScript(NULL);
 
     return script;
 }
 
+bool
+frontend::ParseScript(JSContext *cx, HandleObject scopeChain,
+                      const CompileOptions &options, StableCharPtr chars, size_t length)
+{
+    if (!CheckLength(cx, length))
+        return false;
+
+    Parser<SyntaxParseHandler> parser(cx, options, chars.get(), length, /* foldConstants = */ false);
+    if (!parser.init()) {
+        cx->clearPendingException();
+        return false;
+    }
+
+    GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
+
+    ParseContext<SyntaxParseHandler> pc(&parser, &globalsc, 0, /* bodyid = */ 0);
+    if (!pc.init()) {
+        cx->clearPendingException();
+        return false;
+    }
+
+    for (;;) {
+        TokenKind tt = parser.tokenStream.peekToken(TSF_OPERAND);
+        if (tt <= TOK_EOF) {
+            if (tt == TOK_EOF)
+                break;
+            JS_ASSERT(tt == TOK_ERROR);
+            cx->clearPendingException();
+            return false;
+        }
+
+        if (!parser.statement()) {
+            cx->clearPendingException();
+            return false;
+        }
+    }
+
+    return true;
+}
+
 // Compile a JS function body, which might appear as the value of an event
 // handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
 bool
 frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions options,
                               const AutoNameVector &formals, const jschar *chars, size_t length)
 {
     if (!CheckLength(cx, length))
         return false;
@@ -288,35 +328,35 @@ frontend::CompileFunctionBody(JSContext 
     SourceCompressionToken sct(cx);
     JS_ASSERT(options.sourcePolicy != CompileOptions::LAZY_SOURCE);
     if (options.sourcePolicy == CompileOptions::SAVE_SOURCE) {
         if (!ss->setSourceCopy(cx, chars, length, true, &sct))
             return false;
     }
 
     options.setCompileAndGo(false);
-    Parser parser(cx, options, chars, length, /* foldConstants = */ true);
+    Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true);
     if (!parser.init())
         return false;
     parser.sct = &sct;
 
     JS_ASSERT(fun);
 
     fun->setArgCount(formals.length());
 
     /* FIXME: make Function format the source for a function definition. */
-    ParseNode *fn = CodeNode::create(PNK_FUNCTION, &parser);
+    ParseNode *fn = CodeNode::create(PNK_FUNCTION, &parser.handler);
     if (!fn)
         return false;
 
     fn->pn_body = NULL;
     fn->pn_funbox = NULL;
     fn->pn_cookie.makeFree();
 
-    ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser);
+    ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser.handler);
     if (!argsbody)
         return false;
     argsbody->setOp(JSOP_NOP);
     argsbody->makeEmpty();
     fn->pn_body = argsbody;
 
     Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
                                                   /* staticLevel = */ 0, ss,
--- a/js/src/frontend/BytecodeCompiler.h
+++ b/js/src/frontend/BytecodeCompiler.h
@@ -15,15 +15,19 @@ namespace frontend {
 
 UnrootedScript
 CompileScript(JSContext *cx, HandleObject scopeChain, HandleScript evalCaller,
               const CompileOptions &options, const jschar *chars, size_t length,
               JSString *source_ = NULL, unsigned staticLevel = 0,
               SourceCompressionToken *extraSct = NULL);
 
 bool
+ParseScript(JSContext *cx, HandleObject scopeChain,
+            const CompileOptions &options, StableCharPtr chars, size_t length);
+
+bool
 CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions options,
                     const AutoNameVector &formals, const jschar *chars, size_t length);
 
 } /* namespace frontend */
 } /* namespace js */
 
 #endif /* BytecodeCompiler_h__ */
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -81,17 +81,18 @@ struct frontend::StmtInfoBCE : public St
     }
 
     ptrdiff_t &guardJump() {
         JS_ASSERT(type == STMT_TRY || type == STMT_FINALLY);
         return continues;
     }
 };
 
-BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
+BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent,
+                                 Parser<FullParseHandler> *parser, SharedContext *sc,
                                  HandleScript script, HandleScript evalCaller, bool hasGlobalScope,
                                  unsigned lineno, bool selfHostingMode)
   : sc(sc),
     parent(parent),
     script(sc->context, script),
     prolog(sc->context, lineno),
     main(sc->context, lineno),
     current(&main),
@@ -1660,37 +1661,37 @@ BytecodeEmitter::tellDebuggerAboutCompil
     }
 }
 
 bool
 BytecodeEmitter::reportError(ParseNode *pn, unsigned errorNumber, ...)
 {
     va_list args;
     va_start(args, errorNumber);
-    bool result = tokenStream()->reportCompileErrorNumberVA(pn, JSREPORT_ERROR, errorNumber, args);
+    bool result = tokenStream()->reportCompileErrorNumberVA(pn->pn_pos, JSREPORT_ERROR, errorNumber, args);
     va_end(args);
     return result;
 }
 
 bool
 BytecodeEmitter::reportStrictWarning(ParseNode *pn, unsigned errorNumber, ...)
 {
     va_list args;
     va_start(args, errorNumber);
-    bool result = tokenStream()->reportStrictWarningErrorNumberVA(pn, errorNumber, args);
+    bool result = tokenStream()->reportStrictWarningErrorNumberVA(pn->pn_pos, errorNumber, args);
     va_end(args);
     return result;
 }
 
 bool
 BytecodeEmitter::reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...)
 {
     va_list args;
     va_start(args, errorNumber);
-    bool result = tokenStream()->reportStrictModeErrorNumberVA(pn, sc->strict, errorNumber, args);
+    bool result = tokenStream()->reportStrictModeErrorNumberVA(pn->pn_pos, sc->strict, errorNumber, args);
     va_end(args);
     return result;
 }
 
 static bool
 EmitNameOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
 {
     JSOp op;
@@ -1938,39 +1939,39 @@ EmitNameIncDec(JSContext *cx, ParseNode 
     if (post && Emit1(cx, bce, JSOP_POP) < 0)       // RESULT
         return false;
 
     UpdateDecomposeLength(bce, start);
 
     return true;
 }
 
-static bool
-EmitElemOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
+bool
+frontend::EmitElemOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
 {
     ParseNode *left, *right;
 
     if (pn->isArity(PN_NAME)) {
         /*
          * Set left and right so pn appears to be a PNK_ELEM node, instead of
          * a PNK_DOT node. See the PNK_FOR/IN case in EmitTree, and
          * EmitDestructuringOps nearer below. In the destructuring case, the
          * base expression (pn_expr) of the name may be null, which means we
          * have to emit a JSOP_BINDNAME.
          */
         left = pn->maybeExpr();
         if (!left) {
-            left = NullaryNode::create(PNK_STRING, bce->parser);
+            left = NullaryNode::create(PNK_STRING, &bce->parser->handler);
             if (!left)
                 return false;
             left->setOp(JSOP_BINDNAME);
             left->pn_pos = pn->pn_pos;
             left->pn_atom = pn->pn_atom;
         }
-        right = NullaryNode::create(PNK_STRING, bce->parser);
+        right = NullaryNode::create(PNK_STRING, &bce->parser->handler);
         if (!right)
             return false;
         right->setOp(JSOP_STRING);
         right->pn_pos = pn->pn_pos;
         right->pn_atom = pn->pn_atom;
     } else {
         JS_ASSERT(pn->isArity(PN_BINARY));
         left = pn->pn_left;
@@ -2174,16 +2175,22 @@ EmitSwitch(JSContext *cx, BytecodeEmitte
         pn2 = pn2->expr();
     }
 #endif
 
     uint32_t caseCount = pn2->pn_count;
     uint32_t tableLength = 0;
     ScopedJSFreePtr<ParseNode*> table(NULL);
 
+    if (caseCount > JS_BIT(16)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_TOO_MANY_CASES);
+        return false;
+    }
+
     if (caseCount == 0 ||
         (caseCount == 1 &&
          (hasDefault = (pn2->pn_head->isKind(PNK_DEFAULT))))) {
         caseCount = 0;
         low = 0;
         high = -1;
     } else {
         bool ok = true;
@@ -4798,16 +4805,23 @@ EmitCallOrNew(JSContext *cx, BytecodeEmi
      * JSOP_{SET,INIT}PROP.
      *
      * Then (or in a call case that has no explicit reference-base
      * object) we emit JSOP_UNDEFINED to produce the undefined |this|
      * value required for calls (which non-strict mode functions
      * will box into the global object).
      */
     uint32_t argc = pn->pn_count - 1;
+
+    if (argc >= ARGC_LIMIT) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             callop ? JSMSG_TOO_MANY_FUN_ARGS : JSMSG_TOO_MANY_CON_ARGS);
+        return false;
+    }
+
     bool emitArgs = true;
     ParseNode *pn2 = pn->pn_head;
     switch (pn2->getKind()) {
       case PNK_NAME:
         if (bce->selfHostingMode && pn2->name() == cx->names().callFunction)
         {
             /*
              * Special-casing of callFunction to emit bytecode that directly
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -88,17 +88,18 @@ struct BytecodeEmitter
             // Start them off moderately large, to avoid repeated resizings
             // early on.
             code.reserve(1024);
             notes.reserve(1024);
         }
     };
     EmitSection prolog, main, *current;
 
-    Parser          *const parser;  /* the parser */
+    /* the parser */
+    Parser<FullParseHandler> *const parser;
 
     HandleScript    evalCaller;     /* scripted caller info for eval and dbgapi */
 
     StmtInfoBCE     *topStmt;       /* top of statement info stack */
     StmtInfoBCE     *topScopeStmt;  /* top lexical scope statement */
     Rooted<StaticBlockObject *> blockChain;
                                     /* compile time block scope chain */
 
@@ -138,17 +139,17 @@ struct BytecodeEmitter
                                            the field |selfHostingMode| in Parser.h for details. */
 
     /*
      * Note that BytecodeEmitters are magic: they own the arena "top-of-stack"
      * space above their tempMark points. This means that you cannot alloc from
      * tempLifoAlloc and save the pointer beyond the next BytecodeEmitter
      * destruction.
      */
-    BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
+    BytecodeEmitter(BytecodeEmitter *parent, Parser<FullParseHandler> *parser, SharedContext *sc,
                     HandleScript script, HandleScript evalCaller, bool hasGlobalScope,
                     unsigned lineno, bool selfHostingMode = false);
     bool init();
 
     ~BytecodeEmitter();
 
     bool isAliasedName(ParseNode *pn);
 
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -103,17 +103,17 @@ FoldType(JSContext *cx, ParseNode *pn, P
 
 /*
  * Fold two numeric constants.  Beware that pn1 and pn2 are recycled, unless
  * one of them aliases pn, so you can't safely fetch pn2->pn_next, e.g., after
  * a successful call to this function.
  */
 static bool
 FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
-                  ParseNode *pn, Parser *parser)
+                  ParseNode *pn, Parser<FullParseHandler> *parser)
 {
     double d, d2;
     int32_t i, j;
 
     JS_ASSERT(pn1->isKind(PNK_NUMBER) && pn2->isKind(PNK_NUMBER));
     d = pn1->pn_dval;
     d2 = pn2->pn_dval;
     switch (op) {
@@ -169,20 +169,16 @@ FoldBinaryNumeric(JSContext *cx, JSOp op
             d = js_fmod(d, d2);
         }
         break;
 
       default:;
     }
 
     /* Take care to allow pn1 or pn2 to alias pn. */
-    if (pn1 != pn)
-        parser->freeTree(pn1);
-    if (pn2 != pn)
-        parser->freeTree(pn2);
     pn->setKind(PNK_NUMBER);
     pn->setOp(JSOP_DOUBLE);
     pn->setArity(PN_NULLARY);
     pn->pn_dval = d;
     return true;
 }
 
 // Remove a ParseNode, **pnp, from a parse tree, putting another ParseNode,
@@ -239,19 +235,24 @@ Boolish(ParseNode *pn)
       case JSOP_FALSE:
         return Falsy;
 
       default:
         return Unknown;
     }
 }
 
+namespace js {
+namespace frontend {
+
+template <>
 bool
-frontend::FoldConstants(JSContext *cx, ParseNode **pnp, Parser *parser, bool inGenexpLambda,
-                        bool inCond)
+FoldConstants<FullParseHandler>(JSContext *cx, ParseNode **pnp,
+                                Parser<FullParseHandler> *parser,
+                                bool inGenexpLambda, bool inCond)
 {
     ParseNode *pn = *pnp;
     ParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
 
     JS_CHECK_RECURSION(cx, return false);
 
     switch (pn->getArity()) {
       case PN_CODE:
@@ -296,17 +297,17 @@ frontend::FoldConstants(JSContext *cx, P
                 return false;
         }
         pn1 = pn->pn_kid1;
 
         if (pn->pn_kid2) {
             if (!FoldConstants(cx, &pn->pn_kid2, parser, inGenexpLambda, pn->isKind(PNK_FORHEAD)))
                 return false;
             if (pn->isKind(PNK_FORHEAD) && pn->pn_kid2->isOp(JSOP_TRUE)) {
-                parser->freeTree(pn->pn_kid2);
+                parser->handler.freeTree(pn->pn_kid2);
                 pn->pn_kid2 = NULL;
             }
         }
         pn2 = pn->pn_kid2;
 
         if (pn->pn_kid3) {
             if (!FoldConstants(cx, &pn->pn_kid3, parser, inGenexpLambda))
                 return false;
@@ -422,17 +423,17 @@ frontend::FoldConstants(JSContext *cx, P
              * NB: pn must be a PNK_IF as PNK_CONDITIONAL can never have a null
              * kid or an empty statement for a child.
              */
             pn->setKind(PNK_STATEMENTLIST);
             pn->setArity(PN_LIST);
             pn->makeEmpty();
         }
         if (pn3 && pn3 != pn2)
-            parser->freeTree(pn3);
+            parser->handler.freeTree(pn3);
         break;
 
       case PNK_OR:
       case PNK_AND:
         if (inCond) {
             if (pn->isArity(PN_LIST)) {
                 ParseNode **listp = &pn->pn_head;
                 JS_ASSERT(*listp == pn1);
@@ -441,27 +442,27 @@ frontend::FoldConstants(JSContext *cx, P
                     Truthiness t = Boolish(pn1);
                     if (t == Unknown) {
                         listp = &pn1->pn_next;
                         continue;
                     }
                     if ((t == Truthy) == pn->isKind(PNK_OR)) {
                         for (pn2 = pn1->pn_next; pn2; pn2 = pn3) {
                             pn3 = pn2->pn_next;
-                            parser->freeTree(pn2);
+                            parser->handler.freeTree(pn2);
                             --pn->pn_count;
                         }
                         pn1->pn_next = NULL;
                         break;
                     }
                     JS_ASSERT((t == Truthy) == pn->isKind(PNK_AND));
                     if (pn->pn_count == 1)
                         break;
                     *listp = pn1->pn_next;
-                    parser->freeTree(pn1);
+                    parser->handler.freeTree(pn1);
                     --pn->pn_count;
                 } while ((pn1 = *listp) != NULL);
 
                 // We may have to change arity from LIST to BINARY.
                 pn1 = pn->pn_head;
                 if (pn->pn_count == 2) {
                     pn2 = pn1->pn_next;
                     pn1->pn_next = NULL;
@@ -478,22 +479,22 @@ frontend::FoldConstants(JSContext *cx, P
                     for (; pn1; pn2 = pn1, pn1 = pn1->pn_next)
                         ;
                     pn->pn_tail = &pn2->pn_next;
                 }
             } else {
                 Truthiness t = Boolish(pn1);
                 if (t != Unknown) {
                     if ((t == Truthy) == pn->isKind(PNK_OR)) {
-                        parser->freeTree(pn2);
+                        parser->handler.freeTree(pn2);
                         ReplaceNode(pnp, pn1);
                         pn = pn1;
                     } else {
                         JS_ASSERT((t == Truthy) == pn->isKind(PNK_AND));
-                        parser->freeTree(pn1);
+                        parser->handler.freeTree(pn1);
                         ReplaceNode(pnp, pn2);
                         pn = pn2;
                     }
                 }
             }
         }
         break;
 
@@ -550,17 +551,17 @@ frontend::FoldConstants(JSContext *cx, P
             chars[length] = 0;
             JSString *str = js_NewString<CanGC>(cx, chars, length);
             if (!str) {
                 js_free(chars);
                 return false;
             }
 
             /* Fill the buffer, advancing chars and recycling kids as we go. */
-            for (pn2 = pn1; pn2; pn2 = parser->freeTree(pn2)) {
+            for (pn2 = pn1; pn2; pn2 = parser->handler.freeTree(pn2)) {
                 JSAtom *atom = pn2->pn_atom;
                 size_t length2 = atom->length();
                 js_strncpy(chars, atom->chars(), length2);
                 chars += length2;
             }
             JS_ASSERT(*chars == 0);
 
             /* Atomize the result string and mutate pn to refer to it. */
@@ -586,18 +587,18 @@ frontend::FoldConstants(JSContext *cx, P
             if (!str)
                 return false;
             pn->pn_atom = AtomizeString<CanGC>(cx, str);
             if (!pn->pn_atom)
                 return false;
             pn->setKind(PNK_STRING);
             pn->setOp(JSOP_STRING);
             pn->setArity(PN_NULLARY);
-            parser->freeTree(pn1);
-            parser->freeTree(pn2);
+            parser->handler.freeTree(pn1);
+            parser->handler.freeTree(pn2);
             break;
         }
 
         /* Can't concatenate string literals, let's try numbers. */
         goto do_binary_op;
 
       case PNK_SUB:
       case PNK_STAR:
@@ -681,17 +682,17 @@ frontend::FoldConstants(JSContext *cx, P
               default:
                 /* Return early to dodge the common PNK_NUMBER code. */
                 return true;
             }
             pn->setKind(PNK_NUMBER);
             pn->setOp(JSOP_DOUBLE);
             pn->setArity(PN_NULLARY);
             pn->pn_dval = d;
-            parser->freeTree(pn1);
+            parser->handler.freeTree(pn1);
         } else if (pn1->isKind(PNK_TRUE) || pn1->isKind(PNK_FALSE)) {
             if (pn->isOp(JSOP_NOT)) {
                 ReplaceNode(pnp, pn1);
                 pn = pn1;
                 if (pn->isKind(PNK_TRUE)) {
                     pn->setKind(PNK_FALSE);
                     pn->setOp(JSOP_FALSE);
                 } else {
@@ -709,22 +710,34 @@ frontend::FoldConstants(JSContext *cx, P
         Truthiness t = Boolish(pn);
         if (t != Unknown) {
             /*
              * We can turn function nodes into constant nodes here, but mutating function
              * nodes is tricky --- in particular, mutating a function node that appears on
              * a method list corrupts the method list. However, methods are M's in
              * statements of the form 'this.foo = M;', which we never fold, so we're okay.
              */
-            parser->allocator.prepareNodeForMutation(pn);
+            parser->handler.prepareNodeForMutation(pn);
             if (t == Truthy) {
                 pn->setKind(PNK_TRUE);
                 pn->setOp(JSOP_TRUE);
             } else {
                 pn->setKind(PNK_FALSE);
                 pn->setOp(JSOP_FALSE);
             }
             pn->setArity(PN_NULLARY);
         }
     }
 
     return true;
 }
+
+template <>
+bool
+FoldConstants<SyntaxParseHandler>(JSContext *cx, SyntaxParseHandler::Node *pnp,
+                                  Parser<SyntaxParseHandler> *parser,
+                                  bool inGenexpLambda, bool inCond)
+{
+    return true;
+}
+
+} /* namespace frontend */
+} /* namespace js */
--- a/js/src/frontend/FoldConstants.h
+++ b/js/src/frontend/FoldConstants.h
@@ -21,16 +21,18 @@ namespace frontend {
 // the same node (unchanged or modified in place) or a new node.
 //
 // Usage:
 //    pn = parser->statement();
 //    if (!pn)
 //        return false;
 //    if (!FoldConstants(cx, &pn, parser))
 //        return false;
+template <typename ParseHandler>
 bool
-FoldConstants(JSContext *cx, ParseNode **pnp, Parser *parser, bool inGenexpLambda = false,
-              bool inCond = false);
+FoldConstants(JSContext *cx, typename ParseHandler::Node *pnp,
+              Parser<ParseHandler> *parser,
+              bool inGenexpLambda = false, bool inCond = false);
 
 } /* namespace frontend */
 } /* namespace js */
 
 #endif /* FoldConstants_h__ */
new file mode 100644
--- /dev/null
+++ b/js/src/frontend/FullParseHandler.h
@@ -0,0 +1,373 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=78:
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef FullParseHandler_h__
+#define FullParseHandler_h__
+
+#include "ParseNode.h"
+#include "SharedContext.h"
+
+namespace js {
+namespace frontend {
+
+class FullParseHandler
+{
+    ParseNodeAllocator allocator;
+    TokenStream &tokenStream;
+    bool foldConstants;
+
+    ParseNode *allocParseNode(size_t size) {
+        JS_ASSERT(size == sizeof(ParseNode));
+        return static_cast<ParseNode *>(allocator.allocNode());
+    }
+
+    ParseNode *cloneNode(const ParseNode &other) {
+        ParseNode *node = allocParseNode(sizeof(ParseNode));
+        if (!node)
+            return NULL;
+        PodAssign(node, &other);
+        return node;
+    }
+
+  public:
+    /* new_ methods for creating parse nodes. These report OOM on context. */
+    JS_DECLARE_NEW_METHODS(new_, allocParseNode, inline)
+
+    typedef ParseNode *Node;
+    typedef Definition *DefinitionNode;
+
+    FullParseHandler(JSContext *cx, TokenStream &tokenStream, bool foldConstants)
+      : allocator(cx),
+        tokenStream(tokenStream),
+        foldConstants(foldConstants)
+    {}
+
+    static Definition *null() { return NULL; }
+
+    ParseNode *freeTree(ParseNode *pn) { return allocator.freeTree(pn); }
+    void prepareNodeForMutation(ParseNode *pn) { return allocator.prepareNodeForMutation(pn); }
+    const Token &currentToken() { return tokenStream.currentToken(); }
+
+    ParseNode *newName(PropertyName *name, ParseContext<FullParseHandler> *pc,
+                       ParseNodeKind kind = PNK_NAME) {
+        ParseNode *pn = NameNode::create(kind, name, this, pc);
+        if (!pn)
+            return NULL;
+        pn->setOp(JSOP_NAME);
+        return pn;
+    }
+    ParseNode *newAtom(ParseNodeKind kind, JSAtom *atom, JSOp op = JSOP_NOP) {
+        ParseNode *pn = NullaryNode::create(kind, this);
+        if (!pn)
+            return NULL;
+        pn->setOp(op);
+        pn->pn_atom = atom;
+        return pn;
+    }
+    ParseNode *newNumber(double value, DecimalPoint decimalPoint = NoDecimal) {
+        ParseNode *pn = NullaryNode::create(PNK_NUMBER, this);
+        if (!pn)
+            return NULL;
+        pn->initNumber(value, decimalPoint);
+        return pn;
+    }
+    ParseNode *newNumber(const Token &tok) {
+        return newNumber(tok.number(), tok.decimalPoint());
+    }
+    ParseNode *newBooleanLiteral(bool cond, const TokenPos &pos) {
+        return new_<BooleanLiteral>(cond, pos);
+    }
+    ParseNode *newThisLiteral(const TokenPos &pos) {
+        return new_<ThisLiteral>(pos);
+    }
+    ParseNode *newNullLiteral(const TokenPos &pos) {
+        return new_<NullLiteral>(pos);
+    }
+    ParseNode *newConditional(ParseNode *cond, ParseNode *thenExpr, ParseNode *elseExpr) {
+        return new_<ConditionalExpression>(cond, thenExpr, elseExpr);
+    }
+
+    ParseNode *newNullary(ParseNodeKind kind) {
+        return NullaryNode::create(kind, this);
+    }
+
+    ParseNode *newUnary(ParseNodeKind kind, ParseNode *kid, JSOp op = JSOP_NOP) {
+        return new_<UnaryNode>(kind, op, kid->pn_pos, kid);
+    }
+    ParseNode *newUnary(ParseNodeKind kind, JSOp op = JSOP_NOP) {
+        return new_<UnaryNode>(kind, op, tokenStream.currentToken().pos, (ParseNode *) NULL);
+    }
+    void setUnaryKid(ParseNode *pn, ParseNode *kid) {
+        pn->pn_kid = kid;
+        pn->pn_pos.end = kid->pn_pos.end;
+    }
+
+    ParseNode *newBinary(ParseNodeKind kind, JSOp op = JSOP_NOP) {
+        return new_<BinaryNode>(kind, op, tokenStream.currentToken().pos,
+                                (ParseNode *) NULL, (ParseNode *) NULL);
+    }
+    ParseNode *newBinary(ParseNodeKind kind, ParseNode *left,
+                         JSOp op = JSOP_NOP) {
+        return new_<BinaryNode>(kind, op, left->pn_pos, left, (ParseNode *) NULL);
+    }
+    ParseNode *newBinary(ParseNodeKind kind, ParseNode *left, ParseNode *right,
+                         JSOp op = JSOP_NOP) {
+        TokenPos pos = TokenPos::make(left->pn_pos.begin, right->pn_pos.end);
+        return new_<BinaryNode>(kind, op, pos, left, right);
+    }
+    ParseNode *newBinaryOrAppend(ParseNodeKind kind, ParseNode *left, ParseNode *right,
+                                 JSOp op = JSOP_NOP) {
+        return ParseNode::newBinaryOrAppend(kind, op, left, right, this, foldConstants);
+    }
+    void setBinaryRHS(ParseNode *pn, ParseNode *rhs) {
+        JS_ASSERT(pn->isArity(PN_BINARY));
+        pn->pn_right = rhs;
+        pn->pn_pos.end = rhs->pn_pos.end;
+    }
+
+    ParseNode *newTernary(ParseNodeKind kind,
+                          ParseNode *first, ParseNode *second, ParseNode *third,
+                          JSOp op = JSOP_NOP) {
+        return new_<TernaryNode>(kind, op, first, second, third);
+    }
+
+    ParseNode *newBreak(PropertyName *label, const TokenPtr &begin, const TokenPtr &end) {
+        return new_<BreakStatement>(label, begin, end);
+    }
+    ParseNode *newContinue(PropertyName *label, const TokenPtr &begin, const TokenPtr &end) {
+        return new_<ContinueStatement>(label, begin, end);
+    }
+    ParseNode *newDebuggerStatement(const TokenPos &pos) {
+        return new_<DebuggerStatement>(pos);
+    }
+    ParseNode *newPropertyAccess(ParseNode *pn, PropertyName *name, const TokenPtr &end) {
+        return new_<PropertyAccess>(pn, name, pn->pn_pos.begin, end);
+    }
+    ParseNode *newPropertyByValue(ParseNode *pn, ParseNode *kid, const TokenPtr &end) {
+        return new_<PropertyByValue>(pn, kid, pn->pn_pos.begin, end);
+    }
+
+    inline bool addCatchBlock(ParseNode *catchList, ParseNode *letBlock,
+                              ParseNode *catchName, ParseNode *catchGuard, ParseNode *catchBody);
+
+    inline void morphNameIntoLabel(ParseNode *name, ParseNode *statement);
+
+    inline void setLeaveBlockResult(ParseNode *block, ParseNode *kid, bool leaveBlockExpr);
+
+    inline void setLastFunctionArgumentDefault(ParseNode *funcpn, ParseNode *pn);
+    inline ParseNode *newFunctionDefinition();
+    void setFunctionBody(ParseNode *pn, ParseNode *kid) {
+        pn->pn_body = kid;
+    }
+    void setFunctionBox(ParseNode *pn, FunctionBox *funbox) {
+        pn->pn_funbox = funbox;
+    }
+    bool isOperationWithoutParens(ParseNode *pn, ParseNodeKind kind) {
+        return pn->isKind(kind) && !pn->isInParens();
+    }
+
+    inline void noteLValue(ParseNode *pn);
+    inline bool finishInitializerAssignment(ParseNode *pn, ParseNode *init, JSOp op);
+
+    void setBeginPosition(ParseNode *pn, ParseNode *oth) {
+        setBeginPosition(pn, oth->pn_pos.begin);
+    }
+    void setBeginPosition(ParseNode *pn, const TokenPtr &begin) {
+        pn->pn_pos.begin = begin;
+        JS_ASSERT(pn->pn_pos.begin <= pn->pn_pos.end);
+    }
+
+    void setEndPosition(ParseNode *pn, ParseNode *oth) {
+        setEndPosition(pn, oth->pn_pos.end);
+    }
+    void setEndPosition(ParseNode *pn, const TokenPtr &end) {
+        pn->pn_pos.end = end;
+        JS_ASSERT(pn->pn_pos.begin <= pn->pn_pos.end);
+    }
+
+    TokenPos getPosition(ParseNode *pn) {
+        return pn->pn_pos;
+    }
+
+    ParseNode *newList(ParseNodeKind kind, ParseNode *kid = NULL, JSOp op = JSOP_NOP) {
+        ParseNode *pn = ListNode::create(kind, this);
+        if (!pn)
+            return NULL;
+        pn->setOp(op);
+        pn->makeEmpty();
+        if (kid) {
+            pn->pn_pos.begin = kid->pn_pos.begin;
+            pn->append(kid);
+        }
+        return pn;
+    }
+    void addList(ParseNode *pn, ParseNode *kid) {
+        pn->append(kid);
+    }
+
+    void setOp(ParseNode *pn, JSOp op) {
+        pn->setOp(op);
+    }
+    void setBlockId(ParseNode *pn, unsigned blockid) {
+        pn->pn_blockid = blockid;
+    }
+    void setFlag(ParseNode *pn, unsigned flag) {
+        pn->pn_dflags |= flag;
+    }
+    void setListFlag(ParseNode *pn, unsigned flag) {
+        JS_ASSERT(pn->isArity(PN_LIST));
+        pn->pn_xflags |= flag;
+    }
+    ParseNode *setInParens(ParseNode *pn) {
+        pn->setInParens(true);
+        return pn;
+    }
+    void setPrologue(ParseNode *pn) {
+        pn->pn_prologue = true;
+    }
+
+    bool isConstant(ParseNode *pn) {
+        return pn->isConstant();
+    }
+    PropertyName *isName(ParseNode *pn) {
+        return pn->isKind(PNK_NAME) ? pn->pn_atom->asPropertyName() : NULL;
+    }
+    PropertyName *isGetProp(ParseNode *pn) {
+        return pn->isOp(JSOP_GETPROP) ? pn->pn_atom->asPropertyName() : NULL;
+    }
+    JSAtom *isStringExprStatement(ParseNode *pn, TokenPos *pos) {
+        if (JSAtom *atom = pn->isStringExprStatement()) {
+            *pos = pn->pn_pos;
+            return atom;
+        }
+        return NULL;
+    }
+    bool isEmptySemicolon(ParseNode *pn) {
+        return pn->isKind(PNK_SEMI) && !pn->pn_kid;
+    }
+
+    inline ParseNode *makeAssignment(ParseNode *pn, ParseNode *rhs);
+};
+
+inline bool
+FullParseHandler::addCatchBlock(ParseNode *catchList, ParseNode *letBlock,
+                                ParseNode *catchName, ParseNode *catchGuard, ParseNode *catchBody)
+{
+    ParseNode *catchpn = newTernary(PNK_CATCH, catchName, catchGuard, catchBody);
+    if (!catchpn)
+        return false;
+
+    catchList->append(letBlock);
+    letBlock->pn_expr = catchpn;
+    return true;
+}
+
+inline void
+FullParseHandler::morphNameIntoLabel(ParseNode *name, ParseNode *statement)
+{
+    name->setKind(PNK_COLON);
+    name->pn_pos.end = statement->pn_pos.end;
+    name->pn_expr = statement;
+}
+
+inline void
+FullParseHandler::setLeaveBlockResult(ParseNode *block, ParseNode *kid, bool leaveBlockExpr)
+{
+    JS_ASSERT(block->isOp(JSOP_LEAVEBLOCK));
+    if (leaveBlockExpr)
+        block->setOp(JSOP_LEAVEBLOCKEXPR);
+    block->pn_expr = kid;
+}
+
+inline void
+FullParseHandler::setLastFunctionArgumentDefault(ParseNode *funcpn, ParseNode *defaultValue)
+{
+    ParseNode *arg = funcpn->pn_body->last();
+    arg->pn_dflags |= PND_DEFAULT;
+    arg->pn_expr = defaultValue;
+}
+
+inline ParseNode *
+FullParseHandler::newFunctionDefinition()
+{
+    ParseNode *pn = CodeNode::create(PNK_FUNCTION, this);
+    if (!pn)
+        return NULL;
+    pn->pn_body = NULL;
+    pn->pn_funbox = NULL;
+    pn->pn_cookie.makeFree();
+    pn->pn_dflags = 0;
+    return pn;
+}
+
+inline void
+FullParseHandler::noteLValue(ParseNode *pn)
+{
+    if (pn->isUsed())
+        pn->pn_lexdef->pn_dflags |= PND_ASSIGNED;
+
+    pn->pn_dflags |= PND_ASSIGNED;
+}
+
+inline bool
+FullParseHandler::finishInitializerAssignment(ParseNode *pn, ParseNode *init, JSOp op)
+{
+    if (pn->isUsed()) {
+        pn = makeAssignment(pn, init);
+        if (!pn)
+            return false;
+    } else {
+        pn->pn_expr = init;
+    }
+
+    pn->setOp((pn->pn_dflags & PND_BOUND)
+              ? JSOP_SETLOCAL
+              : (op == JSOP_DEFCONST)
+              ? JSOP_SETCONST
+              : JSOP_SETNAME);
+
+    noteLValue(pn);
+
+    /* The declarator's position must include the initializer. */
+    pn->pn_pos.end = init->pn_pos.end;
+    return true;
+}
+
+inline ParseNode *
+FullParseHandler::makeAssignment(ParseNode *pn, ParseNode *rhs)
+{
+    ParseNode *lhs = cloneNode(*pn);
+    if (!lhs)
+        return NULL;
+
+    if (pn->isUsed()) {
+        Definition *dn = pn->pn_lexdef;
+        ParseNode **pnup = &dn->dn_uses;
+
+        while (*pnup != pn)
+            pnup = &(*pnup)->pn_link;
+        *pnup = lhs;
+        lhs->pn_link = pn->pn_link;
+        pn->pn_link = NULL;
+    }
+
+    pn->setKind(PNK_ASSIGN);
+    pn->setOp(JSOP_NOP);
+    pn->setArity(PN_BINARY);
+    pn->setInParens(false);
+    pn->setUsed(false);
+    pn->setDefn(false);
+    pn->pn_left = lhs;
+    pn->pn_right = rhs;
+    pn->pn_pos.end = rhs->pn_pos.end;
+    return lhs;
+}
+
+} // frontend
+} // js
+
+#endif /* FullParseHandler_h__ */
--- a/js/src/frontend/ParseNode-inl.h
+++ b/js/src/frontend/ParseNode-inl.h
@@ -38,38 +38,18 @@ ParseNode::name() const
 
 inline JSAtom *
 ParseNode::atom() const
 {
     JS_ASSERT(isKind(PNK_MODULE) || isKind(PNK_STRING));
     return isKind(PNK_MODULE) ? pn_modulebox->module()->atom() : pn_atom;
 }
 
-inline bool
-ParseNode::isConstant()
-{
-    switch (pn_type) {
-      case PNK_NUMBER:
-      case PNK_STRING:
-      case PNK_NULL:
-      case PNK_FALSE:
-      case PNK_TRUE:
-        return true;
-      case PNK_ARRAY:
-      case PNK_OBJECT:
-        return isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST);
-      default:
-        return false;
-    }
-}
-
-struct ParseContext;
-
 inline void
-NameNode::initCommon(ParseContext *pc)
+NameNode::initCommon(ParseContext<FullParseHandler> *pc)
 {
     pn_expr = NULL;
     pn_cookie.makeFree();
     pn_dflags = (!pc->topStmt || pc->topStmt->type == STMT_BLOCK)
                 ? PND_BLOCKCHILD
                 : 0;
     pn_blockid = pc->blockid();
 }
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -249,36 +249,37 @@ ParseNodeAllocator::allocNode()
     if (!p)
         js_ReportOutOfMemory(cx);
     return p;
 }
 
 /* used only by static create methods of subclasses */
 
 ParseNode *
-ParseNode::create(ParseNodeKind kind, ParseNodeArity arity, Parser *parser)
+ParseNode::create(ParseNodeKind kind, ParseNodeArity arity, FullParseHandler *handler)
 {
-    const Token &tok = parser->tokenStream.currentToken();
-    return parser->new_<ParseNode>(kind, JSOP_NOP, arity, tok.pos);
+    const Token &tok = handler->currentToken();
+    return handler->new_<ParseNode>(kind, JSOP_NOP, arity, tok.pos);
 }
 
 ParseNode *
-ParseNode::append(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right, Parser *parser)
+ParseNode::append(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right,
+                  FullParseHandler *handler)
 {
     if (!left || !right)
         return NULL;
 
     JS_ASSERT(left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC));
 
     ListNode *list;
     if (left->pn_arity == PN_LIST) {
         list = &left->as<ListNode>();
     } else {
         ParseNode *pn1 = left->pn_left, *pn2 = left->pn_right;
-        list = parser->new_<ListNode>(kind, op, pn1);
+        list = handler->new_<ListNode>(kind, op, pn1);
         if (!list)
             return NULL;
         list->append(pn2);
         if (kind == PNK_ADD) {
             if (pn1->isKind(PNK_STRING))
                 list->pn_xflags |= PNX_STRCAT;
             else if (!pn1->isKind(PNK_NUMBER))
                 list->pn_xflags |= PNX_CANTFOLD;
@@ -298,56 +299,56 @@ ParseNode::append(ParseNodeKind kind, JS
             list->pn_xflags |= PNX_CANTFOLD;
     }
 
     return list;
 }
 
 ParseNode *
 ParseNode::newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right,
-                             Parser *parser)
+                             FullParseHandler *handler, bool foldConstants)
 {
     if (!left || !right)
         return NULL;
 
     /*
      * Flatten a left-associative (left-heavy) tree of a given operator into
      * a list to reduce js::FoldConstants and js::frontend::EmitTree recursion.
      */
     if (left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC))
-        return append(kind, op, left, right, parser);
+        return append(kind, op, left, right, handler);
 
     /*
      * Fold constant addition immediately, to conserve node space and, what's
      * more, so js::FoldConstants never sees mixed addition and concatenation
      * operations with more than one leading non-string operand in a PN_LIST
      * generated for expressions such as 1 + 2 + "pt" (which should evaluate
      * to "3pt", not "12pt").
      */
     if (kind == PNK_ADD &&
         left->isKind(PNK_NUMBER) &&
         right->isKind(PNK_NUMBER) &&
-        parser->foldConstants)
+        foldConstants)
     {
         left->pn_dval += right->pn_dval;
         left->pn_pos.end = right->pn_pos.end;
-        parser->freeTree(right);
+        handler->freeTree(right);
         return left;
     }
 
-    return parser->new_<BinaryNode>(kind, op, left, right);
+    return handler->new_<BinaryNode>(kind, op, left, right);
 }
 
-// Nb: unlike most functions that are passed a Parser, this one gets a
-// SharedContext passed in separately, because in this case |pc| may not equal
-// |parser->pc|.
+// Note: the parse context passed into this may not equal the associated
+// parser's current context.
 NameNode *
-NameNode::create(ParseNodeKind kind, JSAtom *atom, Parser *parser, ParseContext *pc)
+NameNode::create(ParseNodeKind kind, JSAtom *atom, FullParseHandler *handler,
+                 ParseContext<FullParseHandler> *pc)
 {
-    ParseNode *pn = ParseNode::create(kind, PN_NAME, parser);
+    ParseNode *pn = ParseNode::create(kind, PN_NAME, handler);
     if (pn) {
         pn->pn_atom = atom;
         ((NameNode *)pn)->initCommon(pc);
     }
     return (NameNode *)pn;
 }
 
 const char *
@@ -356,98 +357,100 @@ Definition::kindString(Kind kind)
     static const char *table[] = {
         js_var_str, js_const_str, js_let_str, js_function_str, "argument", "unknown"
     };
 
     JS_ASSERT(unsigned(kind) <= unsigned(ARG));
     return table[kind];
 }
 
+namespace js {
+namespace frontend {
+
 #if JS_HAS_DESTRUCTURING
 
 /*
  * This function assumes the cloned tree is for use in the same statement and
  * binding context as the original tree.
  */
-static ParseNode *
-CloneParseTree(ParseNode *opn, Parser *parser)
+template <>
+ParseNode *
+Parser<FullParseHandler>::cloneParseTree(ParseNode *opn)
 {
-    ParseContext *pc = parser->pc;
+    JS_CHECK_RECURSION(context, return NULL);
 
-    JS_CHECK_RECURSION(pc->sc->context, return NULL);
-
-    ParseNode *pn = parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
+    ParseNode *pn = handler.new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
                                             opn->pn_pos);
     if (!pn)
         return NULL;
     pn->setInParens(opn->isInParens());
     pn->setDefn(opn->isDefn());
     pn->setUsed(opn->isUsed());
 
     switch (pn->getArity()) {
 #define NULLCHECK(e)    JS_BEGIN_MACRO if (!(e)) return NULL; JS_END_MACRO
 
       case PN_CODE:
         if (pn->getKind() == PNK_MODULE) {
             JS_NOT_REACHED("module nodes cannot be cloned");
             return NULL;
         } else {
             NULLCHECK(pn->pn_funbox =
-                      parser->newFunctionBox(opn->pn_funbox->function(), pc, opn->pn_funbox->strict));
-            NULLCHECK(pn->pn_body = CloneParseTree(opn->pn_body, parser));
+                      newFunctionBox(opn->pn_funbox->function(), pc, opn->pn_funbox->strict));
+            NULLCHECK(pn->pn_body = cloneParseTree(opn->pn_body));
             pn->pn_cookie = opn->pn_cookie;
             pn->pn_dflags = opn->pn_dflags;
             pn->pn_blockid = opn->pn_blockid;
         }
         break;
 
       case PN_LIST:
         pn->makeEmpty();
         for (ParseNode *opn2 = opn->pn_head; opn2; opn2 = opn2->pn_next) {
             ParseNode *pn2;
-            NULLCHECK(pn2 = CloneParseTree(opn2, parser));
+            NULLCHECK(pn2 = cloneParseTree(opn2));
             pn->append(pn2);
         }
         pn->pn_xflags = opn->pn_xflags;
         break;
 
       case PN_TERNARY:
-        NULLCHECK(pn->pn_kid1 = CloneParseTree(opn->pn_kid1, parser));
-        NULLCHECK(pn->pn_kid2 = CloneParseTree(opn->pn_kid2, parser));
-        NULLCHECK(pn->pn_kid3 = CloneParseTree(opn->pn_kid3, parser));
+        NULLCHECK(pn->pn_kid1 = cloneParseTree(opn->pn_kid1));
+        NULLCHECK(pn->pn_kid2 = cloneParseTree(opn->pn_kid2));
+        NULLCHECK(pn->pn_kid3 = cloneParseTree(opn->pn_kid3));
         break;
 
       case PN_BINARY:
-        NULLCHECK(pn->pn_left = CloneParseTree(opn->pn_left, parser));
+        NULLCHECK(pn->pn_left = cloneParseTree(opn->pn_left));
         if (opn->pn_right != opn->pn_left)
-            NULLCHECK(pn->pn_right = CloneParseTree(opn->pn_right, parser));
+            NULLCHECK(pn->pn_right = cloneParseTree(opn->pn_right));
         else
             pn->pn_right = pn->pn_left;
         pn->pn_iflags = opn->pn_iflags;
         break;
 
       case PN_UNARY:
-        NULLCHECK(pn->pn_kid = CloneParseTree(opn->pn_kid, parser));
+        NULLCHECK(pn->pn_kid = cloneParseTree(opn->pn_kid));
         pn->pn_hidden = opn->pn_hidden;
         break;
 
       case PN_NAME:
         // PN_NAME could mean several arms in pn_u, so copy the whole thing.
         pn->pn_u = opn->pn_u;
         if (opn->isUsed()) {
             /*
              * The old name is a use of its pn_lexdef. Make the clone also be a
              * use of that definition.
              */
             Definition *dn = pn->pn_lexdef;
 
             pn->pn_link = dn->dn_uses;
             dn->dn_uses = pn;
         } else if (opn->pn_expr) {
-            NULLCHECK(pn->pn_expr = CloneParseTree(opn->pn_expr, parser));
+            NULLCHECK(pn->pn_expr = cloneParseTree(opn->pn_expr));
 
             /*
              * If the old name is a definition, the new one has pn_defn set.
              * Make the old name a use of the new node.
              */
             if (opn->isDefn()) {
                 opn->setDefn(false);
                 LinkUseToDef(opn, (Definition *) pn);
@@ -471,20 +474,21 @@ CloneParseTree(ParseNode *opn, Parser *p
  *   for (var/const/let TARGET in EXPR)
  *
  * opn must be the pn_head of a node produced by Parser::variables, so its form
  * is known to be LHS = NAME | [LHS] | {id:LHS}.
  *
  * The cloned tree is for use only in the same statement and binding context as
  * the original tree.
  */
+template <>
 ParseNode *
-frontend::CloneLeftHandSide(ParseNode *opn, Parser *parser)
+Parser<FullParseHandler>::cloneLeftHandSide(ParseNode *opn)
 {
-    ParseNode *pn = parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
+    ParseNode *pn = handler.new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
                                             opn->pn_pos);
     if (!pn)
         return NULL;
     pn->setInParens(opn->isInParens());
     pn->setDefn(opn->isDefn());
     pn->setUsed(opn->isUsed());
 
 #if JS_HAS_DESTRUCTURING
@@ -492,29 +496,29 @@ frontend::CloneLeftHandSide(ParseNode *o
         JS_ASSERT(opn->isKind(PNK_ARRAY) || opn->isKind(PNK_OBJECT));
         pn->makeEmpty();
         for (ParseNode *opn2 = opn->pn_head; opn2; opn2 = opn2->pn_next) {
             ParseNode *pn2;
             if (opn->isKind(PNK_OBJECT)) {
                 JS_ASSERT(opn2->isArity(PN_BINARY));
                 JS_ASSERT(opn2->isKind(PNK_COLON));
 
-                ParseNode *tag = CloneParseTree(opn2->pn_left, parser);
+                ParseNode *tag = cloneParseTree(opn2->pn_left);
                 if (!tag)
                     return NULL;
-                ParseNode *target = CloneLeftHandSide(opn2->pn_right, parser);
+                ParseNode *target = cloneLeftHandSide(opn2->pn_right);
                 if (!target)
                     return NULL;
 
-                pn2 = parser->new_<BinaryNode>(PNK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
+                pn2 = handler.new_<BinaryNode>(PNK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
             } else if (opn2->isArity(PN_NULLARY)) {
                 JS_ASSERT(opn2->isKind(PNK_COMMA));
-                pn2 = CloneParseTree(opn2, parser);
+                pn2 = cloneParseTree(opn2);
             } else {
-                pn2 = CloneLeftHandSide(opn2, parser);
+                pn2 = cloneLeftHandSide(opn2);
             }
 
             if (!pn2)
                 return NULL;
             pn->append(pn2);
         }
         pn->pn_xflags = opn->pn_xflags;
         return pn;
@@ -541,16 +545,19 @@ frontend::CloneLeftHandSide(ParseNode *o
             pn->setDefn(false);
 
             LinkUseToDef(pn, (Definition *) opn);
         }
     }
     return pn;
 }
 
+} /* namespace frontend */
+} /* namespace js */
+
 #ifdef DEBUG
 
 static const char *parseNodeNames[] = {
 #define STRINGIFY(name) #name,
     FOR_EACH_PARSE_NODE_KIND(STRINGIFY)
 #undef STRINGIFY
 };
 
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -13,18 +13,21 @@
 #include "jsscript.h"
 
 #include "frontend/ParseMaps.h"
 #include "frontend/TokenStream.h"
 
 namespace js {
 namespace frontend {
 
+template <typename ParseHandler>
 struct ParseContext;
 
+class FullParseHandler;
+
 /*
  * Indicates a location in the stack that an upvar value can be retrieved from
  * as a two tuple of (level, slot).
  *
  * Some existing client code uses the level value as a delta, or level "skip"
  * quantity. We could probably document that through use of more types at some
  * point in the future.
  */
@@ -565,34 +568,34 @@ struct ParseNode {
         pn_op = op;
         pn_arity = arity;
         pn_parens = false;
         JS_ASSERT(!pn_used);
         JS_ASSERT(!pn_defn);
         pn_next = pn_link = NULL;
     }
 
-    static ParseNode *create(ParseNodeKind kind, ParseNodeArity arity, Parser *parser);
+    static ParseNode *create(ParseNodeKind kind, ParseNodeArity arity, FullParseHandler *handler);
 
   public:
     /*
      * Append right to left, forming a list node.  |left| must have the given
      * kind and op, and op must be left-associative.
      */
     static ParseNode *
-    append(ParseNodeKind tt, JSOp op, ParseNode *left, ParseNode *right, Parser *parser);
+    append(ParseNodeKind tt, JSOp op, ParseNode *left, ParseNode *right, FullParseHandler *handler);
 
     /*
      * Either append right to left, if left meets the conditions necessary to
      * append (see append), or form a binary node whose children are right and
      * left.
      */
     static ParseNode *
     newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right,
-                      Parser *parser);
+                      FullParseHandler *handler, bool foldConstants);
 
     inline PropertyName *name() const;
     inline JSAtom *atom() const;
 
     /*
      * The pn_expr and lexdef members are arms of an unsafe union. Unless you
      * know exactly what you're doing, use only the following methods to access
      * them. For less overhead and assertions for protection, use pn->expr()
@@ -683,44 +686,25 @@ struct ParseNode {
      * This considers only the node and its children, not its context. After
      * parsing, check the node's pn_prologue flag to see if it is indeed part of
      * a directive prologue.
      *
      * Note that a Directive Prologue can contain statements that cannot
      * themselves be directives (string literals that include escape sequences
      * or escaped newlines, say). This member function returns true for such
      * nodes; we use it to determine the extent of the prologue.
-     * isEscapeFreeStringLiteral, below, checks whether the node itself could be
-     * a directive.
      */
-    bool isStringExprStatement() const {
+    JSAtom *isStringExprStatement() const {
         if (getKind() == PNK_SEMI) {
             JS_ASSERT(pn_arity == PN_UNARY);
             ParseNode *kid = pn_kid;
-            return kid && kid->getKind() == PNK_STRING && !kid->pn_parens;
+            if (kid && kid->getKind() == PNK_STRING && !kid->pn_parens)
+                return kid->pn_atom;
         }
-        return false;
-    }
-
-    /*
-     * Return true if this node, known to be an unparenthesized string literal,
-     * could be the string of a directive in a Directive Prologue. Directive
-     * strings never contain escape sequences or line continuations.
-     */
-    bool isEscapeFreeStringLiteral() const {
-        JS_ASSERT(isKind(PNK_STRING) && !pn_parens);
-
-        /*
-         * If the string's length in the source code is its length as a value,
-         * accounting for the quotes, then it must not contain any escape
-         * sequences or line continuations.
-         */
-        JSString *str = pn_atom;
-        return (pn_pos.begin.lineno == pn_pos.end.lineno &&
-                pn_pos.begin.index + str->length() + 2 == pn_pos.end.index);
+        return NULL;
     }
 
     inline bool test(unsigned flag) const;
 
     bool isLet() const          { return test(PND_LET); }
     bool isConst() const        { return test(PND_CONST); }
     bool isBlockChild() const   { return test(PND_BLOCKCHILD); }
     bool isPlaceholder() const  { return test(PND_PLACEHOLDER); }
@@ -762,21 +746,21 @@ struct ParseNode {
      * must be non-empty for correct PN_LAST usage -- this is asserted!
      */
     ParseNode *last() const {
         JS_ASSERT(pn_arity == PN_LIST);
         JS_ASSERT(pn_count != 0);
         return (ParseNode *)(uintptr_t(pn_tail) - offsetof(ParseNode, pn_next));
     }
 
-    void initNumber(const Token &tok) {
+    void initNumber(double value, DecimalPoint decimalPoint) {
         JS_ASSERT(pn_arity == PN_NULLARY);
         JS_ASSERT(getKind() == PNK_NUMBER);
-        pn_u.number.value = tok.number();
-        pn_u.number.decimalPoint = tok.decimalPoint();
+        pn_u.number.value = value;
+        pn_u.number.decimalPoint = decimalPoint;
     }
 
     void makeEmpty() {
         JS_ASSERT(pn_arity == PN_LIST);
         pn_head = NULL;
         pn_tail = &pn_head;
         pn_count = 0;
         pn_xflags = 0;
@@ -828,18 +812,18 @@ struct ParseNode {
 
 #ifdef DEBUG
     void dump();
     void dump(int indent);
 #endif
 };
 
 struct NullaryNode : public ParseNode {
-    static inline NullaryNode *create(ParseNodeKind kind, Parser *parser) {
-        return (NullaryNode *) ParseNode::create(kind, PN_NULLARY, parser);
+    static inline NullaryNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (NullaryNode *) ParseNode::create(kind, PN_NULLARY, handler);
     }
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_NULLARY);
     }
 
 #ifdef DEBUG
     void dump();
@@ -848,18 +832,18 @@ struct NullaryNode : public ParseNode {
 
 struct UnaryNode : public ParseNode {
     UnaryNode(ParseNodeKind kind, JSOp op, const TokenPos &pos, ParseNode *kid)
       : ParseNode(kind, op, PN_UNARY, pos)
     {
         pn_kid = kid;
     }
 
-    static inline UnaryNode *create(ParseNodeKind kind, Parser *parser) {
-        return (UnaryNode *) ParseNode::create(kind, PN_UNARY, parser);
+    static inline UnaryNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (UnaryNode *) ParseNode::create(kind, PN_UNARY, handler);
     }
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_UNARY);
     }
 
 #ifdef DEBUG
     void dump(int indent);
@@ -876,18 +860,18 @@ struct BinaryNode : public ParseNode {
 
     BinaryNode(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right)
       : ParseNode(kind, op, PN_BINARY, TokenPos::box(left->pn_pos, right->pn_pos))
     {
         pn_left = left;
         pn_right = right;
     }
 
-    static inline BinaryNode *create(ParseNodeKind kind, Parser *parser) {
-        return (BinaryNode *) ParseNode::create(kind, PN_BINARY, parser);
+    static inline BinaryNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (BinaryNode *) ParseNode::create(kind, PN_BINARY, handler);
     }
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_BINARY);
     }
 
 #ifdef DEBUG
     void dump(int indent);
@@ -900,18 +884,18 @@ struct TernaryNode : public ParseNode {
                   TokenPos::make((kid1 ? kid1 : kid2 ? kid2 : kid3)->pn_pos.begin,
                                  (kid3 ? kid3 : kid2 ? kid2 : kid1)->pn_pos.end))
     {
         pn_kid1 = kid1;
         pn_kid2 = kid2;
         pn_kid3 = kid3;
     }
 
-    static inline TernaryNode *create(ParseNodeKind kind, Parser *parser) {
-        return (TernaryNode *) ParseNode::create(kind, PN_TERNARY, parser);
+    static inline TernaryNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (TernaryNode *) ParseNode::create(kind, PN_TERNARY, handler);
     }
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_TERNARY);
     }
 
 #ifdef DEBUG
     void dump(int indent);
@@ -922,60 +906,61 @@ struct ListNode : public ParseNode
 {
     ListNode(ParseNodeKind kind, JSOp op, ParseNode *kid)
       : ParseNode(kind, op, PN_LIST)
     {
         pn_pos = kid->pn_pos;
         initList(kid);
     }
 
-    static inline ListNode *create(ParseNodeKind kind, Parser *parser) {
-        return (ListNode *) ParseNode::create(kind, PN_LIST, parser);
+    static inline ListNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (ListNode *) ParseNode::create(kind, PN_LIST, handler);
     }
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_LIST);
     }
 
 #ifdef DEBUG
     void dump(int indent);
 #endif
 };
 
 struct CodeNode : public ParseNode {
-    static inline CodeNode *create(ParseNodeKind kind, Parser *parser) {
-        return (CodeNode *) ParseNode::create(kind, PN_CODE, parser);
+    static inline CodeNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (CodeNode *) ParseNode::create(kind, PN_CODE, handler);
     }
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_CODE);
     }
 
 #ifdef DEBUG
     void dump(int indent);
 #endif
 };
 
 struct NameNode : public ParseNode {
-    static NameNode *create(ParseNodeKind kind, JSAtom *atom, Parser *parser, ParseContext *pc);
+    static NameNode *create(ParseNodeKind kind, JSAtom *atom,
+                            FullParseHandler *handler, ParseContext<FullParseHandler> *pc);
 
-    inline void initCommon(ParseContext *pc);
+    inline void initCommon(ParseContext<FullParseHandler> *pc);
 
     static bool test(const ParseNode &node) {
         return node.isArity(PN_NAME);
     }
 
 #ifdef DEBUG
     void dump(int indent);
 #endif
 };
 
 struct LexicalScopeNode : public ParseNode {
-    static inline LexicalScopeNode *create(ParseNodeKind kind, Parser *parser) {
-        return (LexicalScopeNode *) ParseNode::create(kind, PN_NAME, parser);
+    static inline LexicalScopeNode *create(ParseNodeKind kind, FullParseHandler *handler) {
+        return (LexicalScopeNode *) ParseNode::create(kind, PN_NAME, handler);
     }
 };
 
 class LoopControlStatement : public ParseNode {
   protected:
     LoopControlStatement(ParseNodeKind kind, PropertyName *label,
                          const TokenPtr &begin, const TokenPtr &end)
       : ParseNode(kind, JSOP_NOP, PN_NULLARY, TokenPos::make(begin, end))
@@ -1117,19 +1102,16 @@ class PropertyByValue : public ParseNode
                     const TokenPtr &begin, const TokenPtr &end)
       : ParseNode(PNK_ELEM, JSOP_GETELEM, PN_BINARY, TokenPos::make(begin, end))
     {
         pn_u.binary.left = lhs;
         pn_u.binary.right = propExpr;
     }
 };
 
-ParseNode *
-CloneLeftHandSide(ParseNode *opn, Parser *parser);
-
 #ifdef DEBUG
 void DumpParseTree(ParseNode *pn, int indent = 0);
 #endif
 
 /*
  * js::Definition is a degenerate subtype of the PN_FUNC and PN_NAME variants
  * of js::ParseNode, allocated only for function, var, const, and let
  * declarations that define truly lexical bindings. This means that a child of
@@ -1296,16 +1278,34 @@ inline Definition *
 ParseNode::resolve()
 {
     if (isDefn())
         return (Definition *)this;
     JS_ASSERT(lexdef()->isDefn());
     return (Definition *)lexdef();
 }
 
+inline bool
+ParseNode::isConstant()
+{
+    switch (pn_type) {
+      case PNK_NUMBER:
+      case PNK_STRING:
+      case PNK_NULL:
+      case PNK_FALSE:
+      case PNK_TRUE:
+        return true;
+      case PNK_ARRAY:
+      case PNK_OBJECT:
+        return isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST);
+      default:
+        return false;
+    }
+}
+
 inline void
 LinkUseToDef(ParseNode *pn, Definition *dn)
 {
     JS_ASSERT(!pn->isUsed());
     JS_ASSERT(!pn->isDefn());
     JS_ASSERT(pn != dn->dn_uses);
     pn->pn_link = dn->dn_uses;
     dn->dn_uses = pn;
@@ -1330,12 +1330,21 @@ class ObjectBox {
 
     ObjectBox *traceLink;
     ObjectBox *emitLink;
 
     ObjectBox(JSFunction *function, ObjectBox *traceLink);
     ObjectBox(Module *module, ObjectBox *traceLink);
 };
 
+enum ParseReportKind {
+    ParseError,
+    ParseWarning,
+    ParseStrictWarning,
+    ParseStrictError
+};
+
+enum FunctionSyntaxKind { Expression, Statement };
+
 } /* namespace frontend */
 } /* namespace js */
 
 #endif /* ParseNode_h__ */
--- a/js/src/frontend/Parser-inl.h
+++ b/js/src/frontend/Parser-inl.h
@@ -8,74 +8,107 @@
 #ifndef Parser_inl_h__
 #define Parser_inl_h__
 
 #include "frontend/Parser.h"
 
 namespace js {
 namespace frontend {
 
+template <typename ParseHandler>
 inline unsigned
-ParseContext::blockid()
+ParseContext<ParseHandler>::blockid()
 {
     return topStmt ? topStmt->blockid : bodyid;
 }
 
+template <typename ParseHandler>
 inline bool
-ParseContext::atBodyLevel()
+ParseContext<ParseHandler>::atBodyLevel()
 {
     return !topStmt;
 }
 
+template <typename ParseHandler>
 inline
-ParseContext::ParseContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid)
+ParseContext<ParseHandler>::ParseContext(Parser<ParseHandler> *prs, SharedContext *sc,
+                                      unsigned staticLevel, uint32_t bodyid)
   : sc(sc),
     bodyid(0),           // initialized in init()
     blockidGen(bodyid),  // used to set |bodyid| and subsequently incremented in init()
     topStmt(NULL),
     topScopeStmt(NULL),
     blockChain(prs->context),
     staticLevel(staticLevel),
     parenDepth(0),
     yieldCount(0),
-    blockNode(NULL),
+    blockNode(ParseHandler::null()),
     decls_(prs->context),
     args_(prs->context),
     vars_(prs->context),
-    yieldNode(NULL),
+    yieldNode(ParseHandler::null()),
     parserPC(&prs->pc),
     lexdeps(prs->context),
     parent(prs->pc),
     funcStmts(NULL),
     funHasReturnExpr(false),
     funHasReturnVoid(false),
     parsingForInit(false),
     parsingWith(prs->pc ? prs->pc->parsingWith : false), // inherit from parent context
     inDeclDestructuring(false),
     funBecameStrict(false)
 {
     prs->pc = this;
 }
 
+template <typename ParseHandler>
 inline bool
-ParseContext::init()
+ParseContext<ParseHandler>::init()
 {
     if (!frontend::GenerateBlockId(this, this->bodyid))
         return false;
 
     return decls_.init() && lexdeps.ensureMap(sc->context);
 }
 
+template <typename ParseHandler>
 inline
-ParseContext::~ParseContext()
+ParseContext<ParseHandler>::~ParseContext()
 {
     // |*parserPC| pointed to this object.  Now that this object is about to
     // die, make |*parserPC| point to this object's parent.
     JS_ASSERT(*parserPC == this);
     *parserPC = this->parent;
     js_delete(funcStmts);
 }
 
+/*
+ * Check that it is permitted to introduce a binding for atom.  Strict mode
+ * forbids introducing new definitions for 'eval', 'arguments', or for any
+ * strict mode reserved keyword.  Use pn for reporting error locations, or use
+ * pc's token stream if pn is NULL.
+ */
+template <typename ParseHandler>
+static bool
+CheckStrictBinding(JSContext *cx, ParseHandler *handler, ParseContext<ParseHandler> *pc,
+                   HandlePropertyName name, ParseNode *pn)
+{
+    if (!pc->sc->needStrictChecks())
+        return true;
+
+    if (name == cx->names().eval ||
+        name == cx->names().arguments ||
+        FindKeyword(name->charsZ(), name->length()))
+    {
+        JSAutoByteString bytes;
+        if (!js_AtomToPrintableString(cx, name, &bytes))
+            return false;
+        return handler->report(ParseStrictError, pn, JSMSG_BAD_BINDING, bytes.ptr());
+    }
+
+    return true;
+}
+
 } // namespace frontend
 } // namespace js
 
 #endif // Parser_inl_h__
 
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -55,64 +55,70 @@
 #include "frontend/Parser-inl.h"
 #include "frontend/SharedContext-inl.h"
 
 #include "vm/NumericConversions.h"
 #include "vm/RegExpObject-inl.h"
 
 using namespace js;
 using namespace js::gc;
-using namespace js::frontend;
+
+namespace js {
+namespace frontend {
 
 typedef Rooted<StaticBlockObject*> RootedStaticBlockObject;
 typedef Handle<StaticBlockObject*> HandleStaticBlockObject;
 
 typedef MutableHandle<PropertyName*> MutableHandlePropertyName;
 
 /*
  * Insist that the next token be of type tt, or report errno and return null.
  * NB: this macro uses cx and ts from its lexical environment.
  */
 #define MUST_MATCH_TOKEN_WITH_FLAGS(tt, errno, __flags)                                     \
     JS_BEGIN_MACRO                                                                          \
         if (tokenStream.getToken((__flags)) != tt) {                                        \
-            reportError(NULL, errno);                                                       \
-            return NULL;                                                                    \
+            report(ParseError, false, null(), errno);                                       \
+            return null();                                                                  \
         }                                                                                   \
     JS_END_MACRO
 #define MUST_MATCH_TOKEN(tt, errno) MUST_MATCH_TOKEN_WITH_FLAGS(tt, errno, 0)
 
+template <typename ParseHandler>
 bool
-StrictModeGetter::get() const
-{
-    return parser->pc->sc->strict;
-}
-
-bool
-frontend::GenerateBlockId(ParseContext *pc, uint32_t &blockid)
+GenerateBlockId(ParseContext<ParseHandler> *pc, uint32_t &blockid)
 {
     if (pc->blockidGen == JS_BIT(20)) {
         JS_ReportErrorNumber(pc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program");
         return false;
     }
     JS_ASSERT(pc->blockidGen < JS_BIT(20));
     blockid = pc->blockidGen++;
     return true;
 }
 
+template bool
+GenerateBlockId(ParseContext<SyntaxParseHandler> *pc, uint32_t &blockid);
+
+template bool
+GenerateBlockId(ParseContext<FullParseHandler> *pc, uint32_t &blockid);
+
+template <typename ParseHandler>
 static void
-PushStatementPC(ParseContext *pc, StmtInfoPC *stmt, StmtType type)
+PushStatementPC(ParseContext<ParseHandler> *pc, StmtInfoPC *stmt, StmtType type)
 {
     stmt->blockid = pc->blockid();
     PushStatement(pc, stmt, type);
 }
 
 // See comment on member function declaration.
+template <>
 bool
-ParseContext::define(JSContext *cx, HandlePropertyName name, ParseNode *pn, Definition::Kind kind)
+ParseContext<FullParseHandler>::define(JSContext *cx, HandlePropertyName name,
+                                       ParseNode *pn, Definition::Kind kind)
 {
     JS_ASSERT(!pn->isUsed());
     JS_ASSERT_IF(pn->isDefn(), pn->isPlaceholder());
 
     Definition *prevDef = NULL;
     if (kind == Definition::LET)
         prevDef = decls_.lookupFirst(name);
     else
@@ -180,41 +186,51 @@ ParseContext::define(JSContext *cx, Hand
         }
         if (!decls_.addUnique(name, dn))
             return false;
         break;
 
       case Definition::LET:
         dn->setOp(JSOP_GETLOCAL);
         dn->pn_dflags |= (PND_LET | PND_BOUND);
-        JS_ASSERT(dn->pn_cookie.level() == staticLevel); /* see BindLet */
+        JS_ASSERT(dn->pn_cookie.level() == staticLevel); /* see bindLet */
         if (!decls_.addShadow(name, dn))
             return false;
         break;
 
       case Definition::PLACEHOLDER:
       case Definition::NAMED_LAMBDA:
         JS_NOT_REACHED("unexpected kind");
         break;
     }
 
     return true;
 }
 
+template <>
+bool
+ParseContext<SyntaxParseHandler>::define(JSContext *cx, HandlePropertyName name, Node pn,
+                                         Definition::Kind kind)
+{
+    return true;
+}
+
+template <typename ParseHandler>
 void
-ParseContext::prepareToAddDuplicateArg(Definition *prevDecl)
+ParseContext<ParseHandler>::prepareToAddDuplicateArg(Definition *prevDecl)
 {
     JS_ASSERT(prevDecl->kind() == Definition::ARG);
     JS_ASSERT(decls_.lookupFirst(prevDecl->name()) == prevDecl);
     JS_ASSERT(!prevDecl->isClosed());
     decls_.remove(prevDecl->name());
 }
 
+template <typename ParseHandler>
 void
-ParseContext::updateDecl(JSAtom *atom, ParseNode *pn)
+ParseContext<ParseHandler>::updateDecl(JSAtom *atom, Node pn)
 {
     Definition *oldDecl = decls_.lookupFirst(atom);
 
     pn->setDefn(true);
     Definition *newDecl = (Definition *)pn;
     decls_.updateFirst(atom, newDecl);
 
     if (!sc->isFunctionBox()) {
@@ -233,25 +249,27 @@ ParseContext::updateDecl(JSAtom *atom, P
     } else {
         JS_ASSERT(JOF_OPTYPE(oldDecl->getOp()) == JOF_LOCAL);
         newDecl->setOp(JSOP_GETLOCAL);
         JS_ASSERT(vars_[oldDecl->pn_cookie.slot()] == oldDecl);
         vars_[oldDecl->pn_cookie.slot()] = newDecl;
     }
 }
 
+template <typename ParseHandler>
 void
-ParseContext::popLetDecl(JSAtom *atom)
+ParseContext<ParseHandler>::popLetDecl(JSAtom *atom)
 {
     JS_ASSERT(decls_.lookupFirst(atom)->isLet());
     decls_.remove(atom);
 }
 
+template <typename ParseHandler>
 static void
-AppendPackedBindings(const ParseContext *pc, const DeclVector &vec, Binding *dst)
+AppendPackedBindings(const ParseContext<ParseHandler> *pc, const DeclVector &vec, Binding *dst)
 {
     for (unsigned i = 0; i < vec.length(); ++i, ++dst) {
         Definition *dn = vec[i];
         PropertyName *name = dn->name();
 
         BindingKind kind;
         switch (dn->kind()) {
           case Definition::VAR:
@@ -278,18 +296,19 @@ AppendPackedBindings(const ParseContext 
         bool aliased = dn->isClosed() ||
                        (pc->sc->bindingsAccessedDynamically() &&
                         pc->decls().lookupFirst(name) == dn);
 
         *dst = Binding(name, kind, aliased);
     }
 }
 
+template <typename ParseHandler>
 bool
-ParseContext::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const
+ParseContext<ParseHandler>::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const
 {
     JS_ASSERT(sc->isFunctionBox());
 
     unsigned count = args_.length() + vars_.length();
     Binding *packedBindings = cx->tempLifoAlloc().newArrayUninitialized<Binding>(count);
     if (!packedBindings) {
         js_ReportOutOfMemory(cx);
         return false;
@@ -306,54 +325,85 @@ ParseContext::generateFunctionBindings(J
 
     FunctionBox *funbox = sc->asFunctionBox();
     if (bindings->hasAnyAliasedBindings() || funbox->hasExtensibleScope())
         funbox->function()->setIsHeavyweight();
 
     return true;
 }
 
-Parser::Parser(JSContext *cx, const CompileOptions &options,
-               const jschar *chars, size_t length, bool foldConstants)
+template <typename ParseHandler>
+bool
+Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...)
+{
+    TokenPos pos = pn ? handler.getPosition(pn) : tokenStream.currentToken().pos;
+
+    va_list args;
+    va_start(args, errorNumber);
+    bool result = false;
+    switch (kind) {
+      case ParseError:
+        result = tokenStream.reportCompileErrorNumberVA(pos, JSREPORT_ERROR, errorNumber, args);
+        break;
+      case ParseWarning:
+        result = tokenStream.reportCompileErrorNumberVA(pos, JSREPORT_WARNING, errorNumber, args);
+        break;
+      case ParseStrictWarning:
+        result = tokenStream.reportStrictWarningErrorNumberVA(pos, errorNumber, args);
+        break;
+      case ParseStrictError:
+        result = tokenStream.reportStrictModeErrorNumberVA(pos, strict, errorNumber, args);
+        break;
+    }
+    va_end(args);
+    return result;
+}
+
+template <typename ParseHandler>
+Parser<ParseHandler>::Parser(JSContext *cx, const CompileOptions &options,
+                             const jschar *chars, size_t length, bool foldConstants)
   : AutoGCRooter(cx, PARSER),
     context(cx),
-    strictModeGetter(thisForCtor()),
-    tokenStream(cx, options, chars, length, &strictModeGetter),
+    tokenStream(cx, options, chars, length, thisForCtor()),
     tempPoolMark(NULL),
-    allocator(cx),
     traceListHead(NULL),
     pc(NULL),
     sct(NULL),
     keepAtoms(cx->runtime),
     foldConstants(foldConstants),
     compileAndGo(options.compileAndGo),
-    selfHostingMode(options.selfHostingMode)
+    selfHostingMode(options.selfHostingMode),
+    unknownResult(false),
+    handler(cx, tokenStream, foldConstants)
 {
     cx->activeCompilations++;
 }
 
+template <typename ParseHandler>
 bool
-Parser::init()
+Parser<ParseHandler>::init()
 {
     if (!context->ensureParseMapPool())
         return false;
 
     tempPoolMark = context->tempLifoAlloc().mark();
     return true;
 }
 
-Parser::~Parser()
+template <typename ParseHandler>
+Parser<ParseHandler>::~Parser()
 {
     JSContext *cx = context;
     cx->tempLifoAlloc().release(tempPoolMark);
     cx->activeCompilations--;
 }
 
+template <typename ParseHandler>
 ObjectBox *
-Parser::newObjectBox(JSObject *obj)
+Parser<ParseHandler>::newObjectBox(JSObject *obj)
 {
     JS_ASSERT(obj && !IsPoisonedPtr(obj));
 
     /*
      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
      * arenas containing the entries must be alive until we are done with
      * scanning, parsing and code generation for the whole script or top-level
@@ -366,18 +416,19 @@ Parser::newObjectBox(JSObject *obj)
         return NULL;
     }
 
     traceListHead = objbox;
 
     return objbox;
 }
 
+template <typename ParseHandler>
 FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun,
-                         ParseContext *outerpc, bool strict)
+                         ParseContext<ParseHandler> *outerpc, bool strict)
   : ObjectBox(fun, traceListHead),
     SharedContext(cx, strict),
     bindings(),
     bufStart(0),
     bufEnd(0),
     ndefaults(0),
     inWith(false),                  // initialized below
     inGenexpLambda(false),
@@ -421,18 +472,20 @@ FunctionBox::FunctionBox(JSContext *cx, 
         // In this case, the inner anonymous function needs to inherit the
         // setting of |inWith| from the outer one.
         FunctionBox *parent = outerpc->sc->asFunctionBox();
         if (parent && parent->inWith)
             inWith = true;
     }
 }
 
+template <typename ParseHandler>
 FunctionBox *
-Parser::newFunctionBox(JSFunction *fun, ParseContext *outerpc, bool strict)
+Parser<ParseHandler>::newFunctionBox(JSFunction *fun,
+                                     ParseContext<ParseHandler> *outerpc, bool strict)
 {
     JS_ASSERT(fun && !IsPoisonedPtr(fun));
 
     /*
      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
      * arenas containing the entries must be alive until we are done with
      * scanning, parsing and code generation for the whole script or top-level
@@ -445,24 +498,26 @@ Parser::newFunctionBox(JSFunction *fun, 
         return NULL;
     }
 
     traceListHead = funbox;
 
     return funbox;
 }
 
-ModuleBox::ModuleBox(JSContext *cx, ObjectBox *traceListHead, Module *module, ParseContext *pc)
+ModuleBox::ModuleBox(JSContext *cx, ObjectBox *traceListHead, Module *module,
+                     ParseContext<FullParseHandler> *pc)
     : ObjectBox(module, traceListHead),
       SharedContext(cx, true)
 {
 }
 
+template <>
 ModuleBox *
-Parser::newModuleBox(Module *module, ParseContext *outerpc)
+Parser<FullParseHandler>::newModuleBox(Module *module, ParseContext<FullParseHandler> *outerpc)
 {
     JS_ASSERT(module && !IsPoisonedPtr(module));
 
     /*
      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
      * arenas containing the entries must be alive until we are done with
      * scanning, parsing and code generation for the whole script or top-level
@@ -475,75 +530,68 @@ Parser::newModuleBox(Module *module, Par
         return NULL;
     }
 
     traceListHead = modulebox;
 
     return modulebox;
 }
 
+template <typename ParseHandler>
 void
-Parser::trace(JSTracer *trc)
+Parser<ParseHandler>::trace(JSTracer *trc)
 {
     traceListHead->trace(trc);
 }
 
-static bool
-GenerateBlockIdForStmtNode(ParseNode *pn, ParseContext *pc)
-{
-    JS_ASSERT(pc->topStmt);
-    JS_ASSERT(pc->topStmt->maybeScope());
-    JS_ASSERT(pn->isKind(PNK_STATEMENTLIST) || pn->isKind(PNK_LEXICALSCOPE));
-    if (!GenerateBlockId(pc, pc->topStmt->blockid))
-        return false;
-    pn->pn_blockid = pc->topStmt->blockid;
-    return true;
-}
-
 /*
  * Parse a top-level JS script.
  */
-ParseNode *
-Parser::parse(JSObject *chain)
+template <typename ParseHandler>
+typename ParseHandler::Node
+Parser<ParseHandler>::parse(JSObject *chain)
 {
     /*
      * Protect atoms from being collected by a GC activation, which might
      * - nest on this thread due to out of memory (the so-called "last ditch"
      *   GC attempted within js_NewGCThing), or
      * - run for any reason on another thread if this thread is suspended on
      *   an object lock before it finishes generating bytecode into a script
      *   protected from the GC by a root or a stack frame reference.
      */
     GlobalSharedContext globalsc(context, chain, StrictModeFromContext(context));
-    ParseContext globalpc(this, &globalsc, /* staticLevel = */ 0, /* bodyid = */ 0);
+    ParseContext<ParseHandler> globalpc(this, &globalsc, /* staticLevel = */ 0, /* bodyid = */ 0);
     if (!globalpc.init())
-        return NULL;
-
-    ParseNode *pn = statements();
+        return null();
+
+    Node pn = statements();
     if (pn) {
         if (!tokenStream.matchToken(TOK_EOF)) {
-            reportError(NULL, JSMSG_SYNTAX_ERROR);
-            pn = NULL;
-        } else if (foldConstants) {
+            report(ParseError, false, null(), JSMSG_SYNTAX_ERROR);
+            return null();
+        }
+        if (foldConstants) {
             if (!FoldConstants(context, &pn, this))
-                pn = NULL;
+                return null();
         }
     }
     return pn;
 }
 
 /*
  * Insist on a final return before control flows out of pn.  Try to be a bit
  * smart about loops: do {...; return e2;} while(0) at the end of a function
  * that contains an early return e1 will get a strict warning.  Similarly for
  * iloops: while (true){...} is treated as though ... returns.
  */
-#define ENDS_IN_OTHER   0
-#define ENDS_IN_RETURN  1
-#define ENDS_IN_BREAK   2
+enum {
+    ENDS_IN_OTHER = 0,
+    ENDS_IN_RETURN = 1,
+    ENDS_IN_BREAK = 2
+};
 
 static int
 HasFinalReturn(ParseNode *pn)
 {
     ParseNode *pn2, *pn3;
     unsigned rv, rv2, hasDefault;
 
     switch (pn->getKind()) {
@@ -650,172 +698,156 @@ HasFinalReturn(ParseNode *pn)
             return ENDS_IN_OTHER;
         return HasFinalReturn(pn->pn_right);
 
       default:
         return ENDS_IN_OTHER;
     }
 }
 
-static bool
-ReportBadReturn(JSContext *cx, Parser *parser, ParseNode *pn, Parser::Reporter reporter,
-                unsigned errnum, unsigned anonerrnum)
+static int
+HasFinalReturn(SyntaxParseHandler::Node pn)
+{
+    return ENDS_IN_RETURN;
+}
+
+template <typename ParseHandler>
+bool
+Parser<ParseHandler>::reportBadReturn(Node pn, ParseReportKind kind,
+                                      unsigned errnum, unsigned anonerrnum)
 {
     JSAutoByteString name;
-    JSAtom *atom = parser->pc->sc->asFunctionBox()->function()->atom();
+    JSAtom *atom = pc->sc->asFunctionBox()->function()->atom();
     if (atom) {
-        if (!js_AtomToPrintableString(cx, atom, &name))
+        if (!js_AtomToPrintableString(context, atom, &name))
             return false;
     } else {
         errnum = anonerrnum;
     }
-    return (parser->*reporter)(pn, errnum, name.ptr());
+    return report(kind, pc->sc->strict, pn, errnum, name.ptr());
 }
 
-static bool
-CheckFinalReturn(JSContext *cx, Parser *parser, ParseNode *pn)
+template <typename ParseHandler>
+bool
+Parser<ParseHandler>::checkFinalReturn(Node pn)
 {
-    JS_ASSERT(parser->pc->sc->isFunctionBox());
+    JS_ASSERT(pc->sc->isFunctionBox());
     return HasFinalReturn(pn) == ENDS_IN_RETURN ||
-           ReportBadReturn(cx, parser, pn, &Parser::reportStrictWarning,
+           reportBadReturn(pn, ParseStrictWarning,
                            JSMSG_NO_RETURN_VALUE, JSMSG_ANON_NO_RETURN_VALUE);
 }
 
 /*
  * Check that it is permitted to assign to lhs.  Strict mode code may not
  * assign to 'eval' or 'arguments'.
  */
-static bool
-CheckStrictAssignment(JSContext *cx, Parser *parser, ParseNode *lhs)
+template <typename ParseHandler>
+bool
+Parser<ParseHandler>::checkStrictAssignment(Node lhs)
 {
-    if (parser->pc->sc->needStrictChecks() && lhs->isKind(PNK_NAME)) {
-        JSAtom *atom = lhs->pn_atom;
-        if (atom == cx->names().eval || atom == cx->names().arguments) {
-            JSAutoByteString name;
-            if (!js_AtomToPrintableString(cx, atom, &name) ||
-                !parser->reportStrictModeError(lhs, JSMSG_DEPRECATED_ASSIGN, name.ptr()))
-            {
-                return false;
-            }
+    if (!pc->sc->needStrictChecks())
+        return true;
+
+    JSAtom *atom = handler.isName(lhs);
+    if (!atom)
+        return true;
+
+    if (atom == context->names().eval || atom == context->names().arguments) {
+        JSAutoByteString name;
+        if (!js_AtomToPrintableString(context, atom, &name) ||
+            !report(ParseStrictError, pc->sc->strict, lhs,
+                    JSMSG_DEPRECATED_ASSIGN, name.ptr()))
+        {
+            return false;
         }
     }
     return true;
 }
 
 /*
  * Check that it is permitted to introduce a binding for atom.  Strict mode
  * forbids introducing new definitions for 'eval', 'arguments', or for any
  * strict mode reserved keyword.  Use pn for reporting error locations, or use
  * pc's token stream if pn is NULL.
  */
+template <typename ParseHandler>
 bool
-CheckStrictBinding(JSContext *cx, Parser *parser, HandlePropertyName name, ParseNode *pn)
+Parser<ParseHandler>::checkStrictBinding(HandlePropertyName name, Node pn)
 {
-    if (!parser->pc->sc->needStrictChecks())
+    if (!pc->sc->needStrictChecks())
         return true;
 
-    if (name == cx->names().eval ||
-        name == cx->names().arguments ||
+    if (name == context->names().eval ||
+        name == context->names().arguments ||
         FindKeyword(name->charsZ(), name->length()))
     {
         JSAutoByteString bytes;
-        if (!js_AtomToPrintableString(cx, name, &bytes))
+        if (!js_AtomToPrintableString(context, name, &bytes))
             return false;
-        return parser->reportStrictModeError(pn, JSMSG_BAD_BINDING, bytes.ptr());
+        return report(ParseStrictError, pc->sc->strict, pn,
+                      JSMSG_BAD_BINDING, bytes.ptr());
     }
 
     return true;
 }
 
+template <>
+bool
+Parser<FullParseHandler>::defineArg(ParseNode *funcpn, HandlePropertyName name,
+                                    bool disallowDuplicateArgs, Definition **duplicatedArg);
+
+template <>
 ParseNode *
-Parser::standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals, HandleScript script,
-                               ParseNode *fn, FunctionBox **funbox, bool strict, bool *becameStrict)
+Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals,
+                                                 HandleScript script, Node fn, FunctionBox **funbox,
+                                                 bool strict, bool *becameStrict)
 {
     if (becameStrict)
         *becameStrict = false;
 
     *funbox = newFunctionBox(fun, /* outerpc = */ NULL, strict);
     if (!funbox)
-        return NULL;
-
-    fn->pn_funbox = *funbox;
-
-    ParseContext funpc(this, *funbox, 0, /* staticLevel = */ 0);
+        return null();
+    handler.setFunctionBox(fn, *funbox);
+
+    ParseContext<FullParseHandler> funpc(this, *funbox, 0, /* staticLevel = */ 0);
     if (!funpc.init())
-        return NULL;
+        return null();
 
     for (unsigned i = 0; i < formals.length(); i++) {
-        if (!DefineArg(this, fn, formals[i]))
-            return NULL;
+        if (!defineArg(fn, formals[i]))
+            return null();
     }
 
     ParseNode *pn = functionBody(StatementListBody);
     if (!pn) {
         if (becameStrict && pc->funBecameStrict)
             *becameStrict = true;
-        return NULL;
+        return null();
     }
 
     if (!tokenStream.matchToken(TOK_EOF)) {
-        reportError(NULL, JSMSG_SYNTAX_ERROR);
-        return NULL;
+        report(ParseError, false, null(), JSMSG_SYNTAX_ERROR);
+        return null();
     }
 
     if (!FoldConstants(context, &pn, this))
-        return NULL;
+        return null();
 
     InternalHandle<Bindings*> bindings(script, &script->bindings);
     if (!funpc.generateFunctionBindings(context, bindings))
-        return NULL;
+        return null();
 
     return pn;
 }
 
-ParseNode *
-Parser::functionBody(FunctionBodyType type)
+template <>
+bool
+Parser<FullParseHandler>::checkFunctionArguments()
 {
-    JS_ASSERT(pc->sc->isFunctionBox());
-    JS_ASSERT(!pc->funHasReturnExpr && !pc->funHasReturnVoid);
-
-    ParseNode *pn;
-    if (type == StatementListBody) {
-        pn = statements();
-    } else {
-        JS_ASSERT(type == ExpressionBody);
-        JS_ASSERT(JS_HAS_EXPR_CLOSURES);
-
-        pn = UnaryNode::create(PNK_RETURN, this);
-        if (pn) {
-            pn->pn_kid = assignExpr();
-            if (!pn->pn_kid) {
-                pn = NULL;
-            } else {
-                if (pc->sc->asFunctionBox()->isGenerator()) {
-                    ReportBadReturn(context, this, pn, &Parser::reportError,
-                                    JSMSG_BAD_GENERATOR_RETURN,
-                                    JSMSG_BAD_ANON_GENERATOR_RETURN);
-                    pn = NULL;
-                } else {
-                    pn->setOp(JSOP_RETURN);
-                    pn->pn_pos.end = pn->pn_kid->pn_pos.end;
-                }
-            }
-        }
-    }
-
-    if (!pn)
-        return NULL;
-
-    /* Check for falling off the end of a function that returns a value. */
-    if (context->hasStrictOption() && pc->funHasReturnExpr &&
-        !CheckFinalReturn(context, this, pn))
-    {
-        pn = NULL;
-    }
-
     /* Time to implement the odd semantics of 'arguments'. */
     HandlePropertyName arguments = context->names().arguments;
 
     /*
      * Non-top-level functions use JSOP_DEFFUN which is a dynamic scope
      * operation which means it aliases any bindings with the same name.
      * Due to the implicit declaration mechanism (below), 'arguments' will not
      * have decls and, even if it did, they will not be noted as closed in the
@@ -838,45 +870,45 @@ Parser::functionBody(FunctionBodyType ty
      * the function body.
      */
     for (AtomDefnRange r = pc->lexdeps->all(); !r.empty(); r.popFront()) {
         if (r.front().key() == arguments) {
             Definition *dn = r.front().value();
             pc->lexdeps->remove(arguments);
             dn->pn_dflags |= PND_IMPLICITARGUMENTS;
             if (!pc->define(context, arguments, dn, Definition::VAR))
-                return NULL;
+                return false;
             break;
         }
     }
 
     /*
      * Report error if both rest parameters and 'arguments' are used. Do this
      * check before adding artificial 'arguments' below.
      */
     Definition *maybeArgDef = pc->decls().lookupFirst(arguments);
     bool argumentsHasBinding = !!maybeArgDef;
     bool argumentsHasLocalBinding = maybeArgDef && maybeArgDef->kind() != Definition::ARG;
     bool hasRest = pc->sc->asFunctionBox()->function()->hasRest();
     if (hasRest && argumentsHasLocalBinding) {
-        reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
-        return NULL;
+        report(ParseError, false, NULL, JSMSG_ARGUMENTS_AND_REST);
+        return false;
     }
 
     /*
      * Even if 'arguments' isn't explicitly mentioned, dynamic name lookup
      * forces an 'arguments' binding. The exception is that functions with rest
      * parameters are free from 'arguments'.
      */
     if (!argumentsHasBinding && pc->sc->bindingsAccessedDynamically() && !hasRest) {
-        ParseNode *pn = NameNode::create(PNK_NAME, arguments, this, pc);
+        ParseNode *pn = NameNode::create(PNK_NAME, arguments, &handler, pc);
         if (!pn)
-            return NULL;
+            return false;
         if (!pc->define(context, arguments, pn, Definition::VAR))
-            return NULL;
+            return false;
         argumentsHasBinding = true;
         argumentsHasLocalBinding = true;
     }
 
     /*
      * Now that all possible 'arguments' bindings have been added, note whether
      * 'arguments' has a local binding and whether it unconditionally needs an
      * arguments object. (Also see the flags' comments in ContextFlags.)
@@ -911,40 +943,86 @@ Parser::functionBody(FunctionBodyType ty
          * to any mutation we create it eagerly whenever parameters are (or
          * might, in the case of calls to eval) be assigned.
          */
         if (pc->sc->needStrictChecks()) {
             for (AtomDefnListMap::Range r = pc->decls().all(); !r.empty(); r.popFront()) {
                 DefinitionList &dlist = r.front().value();
                 for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) {
                     Definition *dn = dr.front();
-                    if (dn->kind() == Definition::ARG && dn->isAssigned()) {
+                    if (dn->kind() == Definition::ARG && dn->isAssigned())
                         funbox->setDefinitelyNeedsArgsObj();
-                        goto exitLoop;
-                    }
                 }
             }
             /* Watch for mutation of arguments through e.g. eval(). */
             if (pc->sc->bindingsAccessedDynamically())
                 funbox->setDefinitelyNeedsArgsObj();
-          exitLoop: ;
         }
     }
 
+    return true;
+}
+
+template <>
+bool
+Parser<SyntaxParseHandler>::checkFunctionArguments()
+{
+    return true;
+}
+
+template <typename ParseHandler>
+typename ParseHandler::Node
+Parser<ParseHandler>::functionBody(FunctionBodyType type)
+{
+    JS_ASSERT(pc->sc->isFunctionBox());
+    JS_ASSERT(!pc->funHasReturnExpr && !pc->funHasReturnVoid);
+
+    Node pn;
+    if (type == StatementListBody) {
+        pn = statements();
+        if (!pn)
+            return null();
+    } else {
+        JS_ASSERT(type == ExpressionBody);
+        JS_ASSERT(JS_HAS_EXPR_CLOSURES);
+
+        Node kid = assignExpr();
+        if (!kid)
+            return null();
+
+        pn = handler.newUnary(PNK_RETURN, kid, JSOP_RETURN);
+        if (!pn)
+            return null();
+
+        if (pc->sc->asFunctionBox()->isGenerator()) {
+            reportBadReturn(pn, ParseError,
+                            JSMSG_BAD_GENERATOR_RETURN,
+                            JSMSG_BAD_ANON_GENERATOR_RETURN);
+            return null();
+        }
+    }
+
+    /* Check for falling off the end of a function that returns a value. */
+    if (context->hasStrictOption() && pc->funHasReturnExpr && !checkFinalReturn(pn))
+        return null();
+
+    if (!checkFunctionArguments())
+        return null();
+
     return pn;
 }
 
 // Create a placeholder Definition node for |atom|.
 // Nb: unlike most functions that are passed a Parser, this one gets a
 // SharedContext passed in separately, because in this case |pc| may not equal
 // |parser->pc|.
 static Definition *
-MakePlaceholder(ParseNode *pn, Parser *parser, ParseContext *pc)
+MakePlaceholder(ParseNode *pn, FullParseHandler *handler, ParseContext<FullParseHandler> *pc)
 {
-    Definition *dn = (Definition *) NameNode::create(PNK_NAME, pn->pn_atom, parser, pc);
+    Definition *dn = (Definition *) NameNode::create(PNK_NAME, pn->pn_atom, handler, pc);
     if (!dn)
         return NULL;
 
     dn->setOp(JSOP_NOP);
     dn->setDefn(true);
     dn->pn_dflags |= PND_PLACEHOLDER;
     return dn;
 }
@@ -960,52 +1038,28 @@ ForgetUse(ParseNode *pn)
     ParseNode **pnup = &pn->lexdef()->dn_uses;
     ParseNode *pnu;
     while ((pnu = *pnup) != pn)
         pnup = &pnu->pn_link;
     *pnup = pn->pn_link;
     pn->setUsed(false);
 }
 
-static ParseNode *
-MakeAssignment(ParseNode *pn, ParseNode *rhs, Parser *parser)
+static void
+ForgetUse(SyntaxParseHandler::Node pn)
 {
-    ParseNode *lhs = parser->cloneNode(*pn);
-    if (!lhs)
-        return NULL;
-
-    if (pn->isUsed()) {
-        Definition *dn = pn->pn_lexdef;
-        ParseNode **pnup = &dn->dn_uses;
-
-        while (*pnup != pn)
-            pnup = &(*pnup)->pn_link;
-        *pnup = lhs;
-        lhs->pn_link = pn->pn_link;
-        pn->pn_link = NULL;
-    }
-
-    pn->setKind(PNK_ASSIGN);
-    pn->setOp(JSOP_NOP);
-    pn->setArity(PN_BINARY);
-    pn->setInParens(false);
-    pn->setUsed(false);
-    pn->setDefn(false);
-    pn->pn_left = lhs;
-    pn->pn_right = rhs;
-    pn->pn_pos.end = rhs->pn_pos.end;
-    return lhs;
 }
 
 /* See comment for use in Parser::functionDef. */
-static bool
-MakeDefIntoUse(Definition *dn, ParseNode *pn, JSAtom *atom, Parser *parser)
+template <>
+bool
+Parser<FullParseHandler>::makeDefIntoUse(Definition *dn, ParseNode *pn, JSAtom *atom)
 {
     /* Turn pn into a definition. */
-    parser->pc->updateDecl(atom, pn);
+    pc->updateDecl(atom, pn);
 
     /* Change all uses of dn to be uses of pn. */
     for (ParseNode *pnu = dn->dn_uses; pnu; pnu = pnu->pn_link) {
         JS_ASSERT(pnu->isUsed());
         JS_ASSERT(!pnu->isDefn());
         pnu->pn_lexdef = (Definition *) pn;
         pn->pn_dflags |= pnu->pn_dflags & PND_USE2DEF_FLAGS;
     }
@@ -1025,30 +1079,30 @@ MakeDefIntoUse(Definition *dn, ParseNode
      *     assertEq(g(), 2);
      *   }
      *
      * both asserts are valid.
      */
     if (dn->getKind() == PNK_FUNCTION) {
         JS_ASSERT(dn->functionIsHoisted());
         pn->dn_uses = dn->pn_link;
-        parser->prepareNodeForMutation(dn);
+        handler.prepareNodeForMutation(dn);
         dn->setKind(PNK_NOP);
         dn->setArity(PN_NULLARY);
         return true;
     }
 
     /*
      * If dn is arg, or in [var, const, let] and has an initializer, then we
      * must rewrite it to be an assignment node, whose freshly allocated
      * left-hand side becomes a use of pn.
      */
     if (dn->canHaveInitializer()) {
         if (ParseNode *rhs = dn->expr()) {
-            ParseNode *lhs = MakeAssignment(dn, rhs, parser);
+            ParseNode *lhs = handler.makeAssignment(dn, rhs);
             if (!lhs)
                 return false;
             pn->dn_uses = lhs;
             dn->pn_link = NULL;
             dn = (Definition *) lhs;
         }
     }
 
@@ -1067,57 +1121,57 @@ MakeDefIntoUse(Definition *dn, ParseNode
 
 /*
  * Parameter block types for the several Binder functions.  We use a common
  * helper function signature in order to share code among destructuring and
  * simple variable declaration parsers.  In the destructuring case, the binder
  * function is called indirectly from the variable declaration parser by way
  * of CheckDestructuring and its friends.
  */
-typedef bool
-(*Binder)(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
-
-static bool
-BindLet(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
-
-static bool
-BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser);
-
-struct frontend::BindData {
+
+template <typename ParseHandler>
+struct BindData
+{
     BindData(JSContext *cx) : let(cx) {}
 
-    ParseNode       *pn;        /* name node for definition processing and
-                                   error source coordinates */
+    typedef bool
+    (*Binder)(JSContext *cx, BindData *data, HandlePropertyName name, Parser<ParseHandler> *parser);
+
+    /* name node for definition processing and error source coordinates */
+    typename ParseHandler::Node pn;
+
     JSOp            op;         /* prolog bytecode or nop */
     Binder          binder;     /* binder, discriminates u */
 
     struct LetData {
         LetData(JSContext *cx) : blockObj(cx) {}
         VarContext varContext;
         RootedStaticBlockObject blockObj;
         unsigned   overflow;
     } let;
 
     void initLet(VarContext varContext, StaticBlockObject &blockObj, unsigned overflow) {
-        this->pn = NULL;
+        this->pn = ParseHandler::null();
         this->op = JSOP_NOP;
-        this->binder = BindLet;
+        this->binder = Parser<ParseHandler>::bindLet;
         this->let.varContext = varContext;
         this->let.blockObj = &blockObj;
         this->let.overflow = overflow;
     }
 
     void initVarOrConst(JSOp op) {
         this->op = op;
-        this->binder = BindVarOrConst;
+        this->binder = Parser<ParseHandler>::bindVarOrConst;
     }
 };
 
+template <typename ParseHandler>
 JSFunction *
-Parser::newFunction(ParseContext *pc, HandleAtom atom, FunctionSyntaxKind kind)
+Parser<ParseHandler>::newFunction(ParseContext<ParseHandler> *pc, HandleAtom atom,
+                                  FunctionSyntaxKind kind)
 {
     JS_ASSERT_IF(kind == Statement, atom != NULL);
 
     /*
      * Find the global compilation context in order to pre-set the newborn
      * function's parent slot to pc->sc->asGlobal()->scopeChain. If the global
      * context is a compile-and-go one, we leave the pre-set parent intact;
      * otherwise we clear parent and proto.
@@ -1180,23 +1234,23 @@ DeoptimizeUsesWithin(Definition *dn, con
 }
 
 /*
  * Beware: this function is called for functions nested in other functions or
  * global scripts but not for functions compiled through the Function
  * constructor or JSAPI. To always execute code when a function has finished
  * parsing, use Parser::functionBody.
  */
-static bool
-LeaveFunction(ParseNode *fn, Parser *parser, HandlePropertyName funName,
-              FunctionSyntaxKind kind = Expression)
+template <>
+bool
+Parser<FullParseHandler>::leaveFunction(ParseNode *fn, HandlePropertyName funName,
+                                        FunctionSyntaxKind kind)
 {
-    JSContext *cx = parser->context;
-    ParseContext *funpc = parser->pc;
-    ParseContext *pc = funpc->parent;
+    ParseContext<FullParseHandler> *funpc = pc;
+    ParseContext<FullParseHandler> *pc = funpc->parent;
     pc->blockidGen = funpc->blockidGen;
 
     FunctionBox *funbox = fn->pn_funbox;
     JS_ASSERT(funbox == funpc->sc->asFunctionBox());
 
     if (!pc->topStmt || pc->topStmt->type == STMT_BLOCK)
         fn->pn_dflags |= PND_BLOCKCHILD;
 
@@ -1204,17 +1258,17 @@ LeaveFunction(ParseNode *fn, Parser *par
     if (funpc->lexdeps->count()) {
         for (AtomDefnRange r = funpc->lexdeps->all(); !r.empty(); r.popFront()) {
             JSAtom *atom = r.front().key();
             Definition *dn = r.front().value();
             JS_ASSERT(dn->isPlaceholder());
 
             if (atom == funName && kind == Expression) {
                 dn->setOp(JSOP_CALLEE);
-                if (!dn->pn_cookie.set(cx, funpc->staticLevel,
+                if (!dn->pn_cookie.set(context, funpc->staticLevel,
                                        UpvarCookie::CALLEE_SLOT))
                     return false;
                 dn->pn_dflags |= PND_BOUND;
                 JS_ASSERT(dn->kind() == Definition::NAMED_LAMBDA);
 
                 /*
                  * Since 'dn' is a placeholder, it has not been defined in the
                  * ParseContext and hence we must manually flag a closed-over
@@ -1262,17 +1316,17 @@ LeaveFunction(ParseNode *fn, Parser *par
                      *   function f() { x; { function g() { x; } let x; } }
                      *
                      * Here, the 'let' must not capture all the uses of f's
                      * lexdep entry for x, but it must capture the x node
                      * referred to from g's TOK_UPVARS node.  Always turning
                      * inherited lexdeps into uses of a new outer definition
                      * allows us to handle both these cases in a natural way.
                      */
-                    outer_dn = MakePlaceholder(dn, parser, pc);
+                    outer_dn = MakePlaceholder(dn, &handler, pc);
                     if (!outer_dn || !pc->lexdeps->add(p, atom, outer_dn))
                         return false;
                 }
             }
 
             /*
              * Insert dn's uses list at the front of outer_dn's list.
              *
@@ -1304,308 +1358,317 @@ LeaveFunction(ParseNode *fn, Parser *par
 
             /* Mark the outer dn as escaping. */
             outer_dn->pn_dflags |= PND_CLOSED;
         }
     }
 
     InternalHandle<Bindings*> bindings =
         InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
-    if (!funpc->generateFunctionBindings(cx, bindings))
+    if (!funpc->generateFunctionBindings(context, bindings))
         return false;
 
-    funpc->lexdeps.releaseMap(cx);
+    funpc->lexdeps.releaseMap(context);
+    return true;
+}
+
+template <>
+bool
+Parser<SyntaxParseHandler>::leaveFunction(Node fn, HandlePropertyName funName,
+                                          FunctionSyntaxKind kind)
+{
+    pc->lexdeps.releaseMap(context);
     return true;
 }
 
 /*
- * DefineArg is called for both the arguments of a regular function definition
+ * defineArg is called for both the arguments of a regular function definition
  * and the arguments specified by the Function constructor.
  *
  * The 'disallowDuplicateArgs' bool indicates whether the use of another
  * feature (destructuring or default arguments) disables duplicate arguments.
  * (ECMA-262 requires us to support duplicate parameter names, but, for newer
  * features, we consider the code to have "opted in" to higher standards and
  * forbid duplicates.)
  *
  * If 'duplicatedArg' is non-null, then DefineArg assigns to it any previous
  * argument with the same name. The caller may use this to report an error when
  * one of the abovementioned features occurs after a duplicate.
  */
+template <>
 bool
-frontend::DefineArg(Parser *parser, ParseNode *funcpn, HandlePropertyName name,
-                    bool disallowDuplicateArgs, Definition **duplicatedArg)
+Parser<FullParseHandler>::defineArg(ParseNode *funcpn, HandlePropertyName name,
+                                    bool disallowDuplicateArgs, Definition **duplicatedArg)
 {
-    JSContext *cx = parser->context;
-    ParseContext *pc = parser->pc;
     SharedContext *sc = pc->sc;
 
     /* Handle duplicate argument names. */
     if (Definition *prevDecl = pc->decls().lookupFirst(name)) {
         /*
          * Strict-mode disallows duplicate args. We may not know whether we are
          * in strict mode or not (since the function body hasn't been parsed).
          * In such cases, reportStrictModeError will queue up the potential
          * error and return 'true'.
          */
         if (sc->needStrictChecks()) {
             JSAutoByteString bytes;
-            if (!js_AtomToPrintableString(cx, name, &bytes))
+            if (!js_AtomToPrintableString(context, name, &bytes))
                 return false;
-            if (!parser->reportStrictModeError(prevDecl, JSMSG_DUPLICATE_FORMAL, bytes.ptr()))
+            if (!report(ParseStrictError, pc->sc->strict, prevDecl,
+                        JSMSG_DUPLICATE_FORMAL, bytes.ptr()))
+            {
                 return false;
+            }
         }
 
         if (disallowDuplicateArgs) {
-            parser->reportError(prevDecl, JSMSG_BAD_DUP_ARGS);
+            report(ParseError, false, prevDecl, JSMSG_BAD_DUP_ARGS);
             return false;
         }
 
         if (duplicatedArg)
             *duplicatedArg = prevDecl;
 
         /* ParseContext::define assumes and asserts prevDecl is not in decls. */
         pc->prepareToAddDuplicateArg(prevDecl);
     }
 
-    ParseNode *argpn = NameNode::create(PNK_NAME, name, parser, parser->pc);
+    ParseNode *argpn = handler.newName(name, pc);
     if (!argpn)
         return false;
 
-    if (!CheckStrictBinding(parser->context, parser, name, argpn))
+    if (!checkStrictBinding(name, argpn))
         return false;
 
     funcpn->pn_body->append(argpn);
-    return parser->pc->define(parser->context, name, argpn, Definition::ARG);
+    return pc->define(context, name, argpn, Definition::ARG);
+}
+
+template <>
+bool
+Parser<SyntaxParseHandler>::defineArg(Node funcpn, HandlePropertyName name,
+                                      bool disallowDuplicateArgs, DefinitionNode *duplicatedArg)
+{
+    return true;
 }
 
 #if JS_HAS_DESTRUCTURING
-static bool
-BindDestructuringArg(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
+template <typename ParseHandler>
+/* static */ bool
+Parser<ParseHandler>::bindDestructuringArg(JSContext *cx, BindData<ParseHandler> *data,
+                                           HandlePropertyName name, Parser<ParseHandler> *parser)
 {
-    ParseContext *pc = parser->pc;
+    ParseContext<ParseHandler> *pc = parser->pc;
     JS_ASSERT(pc->sc->isFunctionBox());
 
     if (pc->decls().lookupFirst(name)) {
-        parser->reportError(NULL, JSMSG_BAD_DUP_ARGS);
+        parser->report(ParseError, false, null(), JSMSG_BAD_DUP_ARGS);
         return false;
     }
 
-    if (!CheckStrictBinding(cx, parser, name, data->pn))
+    if (!parser->checkStrictBinding(name, data->pn))
         return false;
 
     return pc->define(cx, name, data->pn, Definition::VAR);
 }
 #endif /* JS_HAS_DESTRUCTURING */
 
+template <typename ParseHandler>
 bool
-Parser::functionArguments(ParseNode **listp, ParseNode* funcpn, bool &hasRest)
+Parser<ParseHandler>::functionArguments(Node *listp, Node funcpn, bool &hasRest)
 {
     if (tokenStream.getToken() != TOK_LP) {
-        reportError(NULL, JSMSG_PAREN_BEFORE_FORMAL);
+        report(ParseError, false, null(), JSMSG_PAREN_BEFORE_FORMAL);
         return false;
     }
 
     FunctionBox *funbox = pc->sc->asFunctionBox();
     funbox->bufStart = tokenStream.offsetOfToken(tokenStream.currentToken());
 
     hasRest = false;
 
-    ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, this);
+    Node argsbody = handler.newList(PNK_ARGSBODY);
     if (!argsbody)
         return false;
-    argsbody->setOp(JSOP_NOP);
-    argsbody->makeEmpty();
-
-    funcpn->pn_body = argsbody;
+    handler.setFunctionBody(funcpn, argsbody);
 
     if (!tokenStream.matchToken(TOK_RP)) {
         bool hasDefaults = false;
-        Definition *duplicatedArg = NULL;
+        DefinitionNode duplicatedArg = null();
         bool destructuringArg = false;
 #if JS_HAS_DESTRUCTURING
-        ParseNode *list = NULL;
+        Node list = null();
 #endif
 
         do {
             if (hasRest) {
-                reportError(NULL, JSMSG_PARAMETER_AFTER_REST);
+                report(ParseError, false, null(), JSMSG_PARAMETER_AFTER_REST);
                 return false;
             }
             switch (TokenKind tt = tokenStream.getToken()) {
 #if JS_HAS_DESTRUCTURING
               case TOK_LB:
               case TOK_LC:
               {
                 /* See comment below in the TOK_NAME case. */
                 if (duplicatedArg) {
-                    reportError(duplicatedArg, JSMSG_BAD_DUP_ARGS);
+                    report(ParseError, false, duplicatedArg, JSMSG_BAD_DUP_ARGS);
                     return false;
                 }
 
                 if (hasDefaults) {
-                    reportError(NULL, JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT);
+                    report(ParseError, false, null(), JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT);
                     return false;
                 }
 
                 destructuringArg = true;
 
                 /*
                  * A destructuring formal parameter turns into one or more
                  * local variables initialized from properties of a single
                  * anonymous positional parameter, so here we must tweak our
                  * binder and its data.
                  */
-                BindData data(context);
-                data.pn = NULL;
+                BindData<ParseHandler> data(context);
+                data.pn = ParseHandler::null();
                 data.op = JSOP_DEFVAR;
-                data.binder = BindDestructuringArg;
-                ParseNode *lhs = destructuringExpr(&data, tt);
+                data.binder = bindDestructuringArg;
+                Node lhs = destructuringExpr(&data, tt);
                 if (!lhs)
                     return false;
 
                 /*
                  * Synthesize a destructuring assignment from the single
                  * anonymous positional parameter into the destructuring
                  * left-hand-side expression and accumulate it in list.
                  */
                 HandlePropertyName name = context->names().empty;
-                ParseNode *rhs = NameNode::create(PNK_NAME, name, this, this->pc);
+                Node rhs = handler.newName(name, pc);
                 if (!rhs)
                     return false;
 
                 if (!pc->define(context, name, rhs, Definition::ARG))
                     return false;
 
-                ParseNode *item = new_<BinaryNode>(PNK_ASSIGN, JSOP_NOP, lhs->pn_pos, lhs, rhs);
+                Node item = handler.newBinary(PNK_ASSIGN, lhs, rhs);
                 if (!item)
                     return false;
                 if (list) {
-                    list->append(item);
+                    handler.addList(list, item);
                 } else {
-                    list = ListNode::create(PNK_VAR, this);
+                    list = handler.newList(PNK_VAR, item);
                     if (!list)
                         return false;
-                    list->initList(item);
                     *listp = list;
                 }
                 break;
               }
 #endif /* JS_HAS_DESTRUCTURING */
 
               case TOK_TRIPLEDOT:
               {
                 hasRest = true;
                 tt = tokenStream.getToken();
                 if (tt != TOK_NAME) {
                     if (tt != TOK_ERROR)
-                        reportError(NULL, JSMSG_NO_REST_NAME);
+                        report(ParseError, false, null(), JSMSG_NO_REST_NAME);
                     return false;
                 }
                 /* Fall through */
               }
 
               case TOK_NAME:
               {
                 RootedPropertyName name(context, tokenStream.currentToken().name());
                 bool disallowDuplicateArgs = destructuringArg || hasDefaults;
-                if (!DefineArg(this, funcpn, name, disallowDuplicateArgs, &duplicatedArg))
+                if (!defineArg(funcpn, name, disallowDuplicateArgs, &duplicatedArg))
                     return false;
 
                 if (tokenStream.matchToken(TOK_ASSIGN)) {
                     if (hasRest) {
-                        reportError(NULL, JSMSG_REST_WITH_DEFAULT);
+                        report(ParseError, false, null(), JSMSG_REST_WITH_DEFAULT);
                         return false;
                     }
                     if (duplicatedArg) {
-                        reportError(duplicatedArg, JSMSG_BAD_DUP_ARGS);
+                        report(ParseError, false, duplicatedArg, JSMSG_BAD_DUP_ARGS);
                         return false;
                     }
                     hasDefaults = true;
-                    ParseNode *def_expr = assignExprWithoutYield(JSMSG_YIELD_IN_DEFAULT);
+                    Node def_expr = assignExprWithoutYield(JSMSG_YIELD_IN_DEFAULT);
                     if (!def_expr)
                         return false;
-                    ParseNode *arg = funcpn->pn_body->last();
-                    arg->pn_dflags |= PND_DEFAULT;
-                    arg->pn_expr = def_expr;
+                    handler.setLastFunctionArgumentDefault(funcpn, def_expr);
                     funbox->ndefaults++;
                 } else if (!hasRest && hasDefaults) {
-                    reportError(NULL, JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT);
+                    report(ParseError, false, null(), JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT);
                     return false;
                 }
 
                 break;
               }
 
               default:
-                reportError(NULL, JSMSG_MISSING_FORMAL);
+                report(ParseError, false, null(), JSMSG_MISSING_FORMAL);
                 /* FALL THROUGH */
               case TOK_ERROR:
                 return false;
             }
         } while (tokenStream.matchToken(TOK_COMMA));
 
         if (tokenStream.getToken() != TOK_RP) {
-            reportError(NULL, JSMSG_PAREN_AFTER_FORMAL);
+            report(ParseError, false, null(), JSMSG_PAREN_AFTER_FORMAL);
             return false;
         }
     }
 
     return true;
 }
 
-ParseNode *
-Parser::functionDef(HandlePropertyName funName, const TokenStream::Position &start,
-                    FunctionType type, FunctionSyntaxKind kind)
+template <>
+bool
+Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
+                                                  ParseNode **pn_, FunctionSyntaxKind kind)
 {
-    JS_ASSERT_IF(kind == Statement, funName);
-
-    /* Make a TOK_FUNCTION node. */
-    ParseNode *pn = CodeNode::create(PNK_FUNCTION, this);
-    if (!pn)
-        return NULL;
-    pn->pn_body = NULL;
-    pn->pn_funbox = NULL;
-    pn->pn_cookie.makeFree();
-    pn->pn_dflags = 0;
+    ParseNode *&pn = *pn_;
 
     /* Function statements add a binding to the enclosing scope. */
     bool bodyLevel = pc->atBodyLevel();
+
     if (kind == Statement) {
         /*
          * Handle redeclaration and optimize cases where we can statically bind the
          * function (thereby avoiding JSOP_DEFFUN and dynamic name lookup).
          */
         if (Definition *dn = pc->decls().lookupFirst(funName)) {
             JS_ASSERT(!dn->isUsed());
             JS_ASSERT(dn->isDefn());
 
             if (context->hasStrictOption() || dn->kind() == Definition::CONST) {
                 JSAutoByteString name;
-                Reporter reporter = (dn->kind() != Definition::CONST)
-                                    ? &Parser::reportStrictWarning
-                                    : &Parser::reportError;
+                ParseReportKind reporter = (dn->kind() != Definition::CONST)
+                                           ? ParseStrictWarning
+                                           : ParseError;
                 if (!js_AtomToPrintableString(context, funName, &name) ||
-                    !(this->*reporter)(NULL, JSMSG_REDECLARED_VAR, Definition::kindString(dn->kind()),
-                                       name.ptr()))
+                    !report(reporter, false, NULL, JSMSG_REDECLARED_VAR,
+                            Definition::kindString(dn->kind()), name.ptr()))
                 {
-                    return NULL;
+                    return false;
                 }
             }
 
             /*
              * Body-level function statements are effectively variable
              * declarations where the initialization is hoisted to the