Merge m-c to fx-team, a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 11 Jun 2015 17:55:46 -0700
changeset 279287 40dff0df156e88d614c4e1104a1e9e795f3b8543
parent 279286 a3399f552e3bb8b671df36456ef9107381279837 (current diff)
parent 279233 c2a414f8bd73d5c588e223cf9f36b8e5507818cb (diff)
child 279288 02a04654e99466534ed92c6d646e5883f83538ef
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.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 fx-team, a=merge CLOSED TREE
browser/devtools/performance/test/browser.ini
dom/webidl/SystemDictionaries.webidl
security/manager/ssl/tests/unit/test_cert_eku/ca.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_EP_NS_OS_SA_TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_NS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_OS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_SA-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-CA_TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_NS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_OS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_SA-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-EP_TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NONE-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_OS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_SA-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-NS_TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_SA-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-OS_TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-SA_TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/ee-EKU-TS-int-EKU-TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA_EP.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA_EP_NS_OS_SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA_NS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA_OS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA_SA.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-CA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-EP.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-EP_NS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-EP_OS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-EP_SA.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-EP_TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-NONE.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-NS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-NS_OS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-NS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-NS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-OS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-OS_SA.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-OS_TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-SA.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-SA_TS.der
security/manager/ssl/tests/unit/test_cert_eku/int-EKU-TS.der
testing/profiles/prefs_general.js
xpcom/glue/nsTHashtable.cpp
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -6,16 +6,17 @@
 
 #include "AccessibleWrap.h"
 
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "InterfaceInitFuncs.h"
 #include "nsAccUtils.h"
 #include "mozilla/a11y/PDocAccessible.h"
+#include "OuterDocAccessible.h"
 #include "ProxyAccessible.h"
 #include "RootAccessible.h"
 #include "nsMai.h"
 #include "nsMaiHyperlink.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "prprf.h"
 #include "nsStateMap.h"
@@ -91,17 +92,17 @@ static GType GetAtkTypeForMai(MaiInterfa
     case MAI_INTERFACE_DOCUMENT:
       return ATK_TYPE_DOCUMENT;
     case MAI_INTERFACE_IMAGE:
       return ATK_TYPE_IMAGE;
   }
   return G_TYPE_INVALID;
 }
 
-static const char* kNonUserInputEvent = ":system";
+#define NON_USER_EVENT ":system"
     
 static const GInterfaceInfo atk_if_infos[] = {
     {(GInterfaceInitFunc)componentInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr}, 
     {(GInterfaceInitFunc)actionInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)valueInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr},
@@ -823,36 +824,55 @@ getChildCountCB(AtkObject *aAtkObj)
     }
 
     return static_cast<gint>(accWrap->EmbeddedChildCount());
 }
 
 AtkObject *
 refChildCB(AtkObject *aAtkObj, gint aChildIndex)
 {
-    // aChildIndex should not be less than zero
-    if (aChildIndex < 0) {
+  // aChildIndex should not be less than zero
+  if (aChildIndex < 0) {
+    return nullptr;
+  }
+
+  AtkObject* childAtkObj = nullptr;
+  AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
+  if (accWrap) {
+    if (nsAccUtils::MustPrune(accWrap)) {
       return nullptr;
     }
 
-    AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
-    if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
-        return nullptr;
+    Accessible* accChild = accWrap->GetEmbeddedChildAt(aChildIndex);
+    if (accChild) {
+      childAtkObj = AccessibleWrap::GetAtkObject(accChild);
+    } else {
+      OuterDocAccessible* docOwner = accWrap->AsOuterDoc();
+      if (docOwner) {
+        ProxyAccessible* proxyDoc = docOwner->RemoteChildDoc();
+        if (proxyDoc)
+          childAtkObj = GetWrapperFor(proxyDoc);
+      }
     }
+  } else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
+    if (proxy->MustPruneChildren())
+      return nullptr;
 
-    Accessible* accChild = accWrap->GetEmbeddedChildAt(aChildIndex);
-    if (!accChild)
-        return nullptr;
+    ProxyAccessible* child = proxy->EmbeddedChildAt(aChildIndex);
+    if (child)
+      childAtkObj = GetWrapperFor(child);
+  } else {
+    return nullptr;
+  }
 
-    AtkObject* childAtkObj = AccessibleWrap::GetAtkObject(accChild);
+  NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
+  if (!childAtkObj)
+    return nullptr;
 
-    NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
-    if (!childAtkObj)
-        return nullptr;
-    g_object_ref(childAtkObj);
+  g_object_ref(childAtkObj);
 
   if (aAtkObj != childAtkObj->accessible_parent)
     atk_object_set_parent(childAtkObj, aAtkObj);
 
   return childAtkObj;
 }
 
 gint
@@ -1426,63 +1446,81 @@ MaiAtkObject::FireStateChangeEvent(uint6
             // Fire state change for first state if there is one to map
             atk_object_notify_state_change(&parent,
                                            gAtkStateMap[stateIndex].atkState,
                                            aEnabled);
         }
     }
 }
 
+#define OLD_TEXT_INSERTED "text_changed::insert"
+#define OLD_TEXT_REMOVED "text_changed::delete"
+static const char* oldTextChangeStrings[2][2] = {
+  { OLD_TEXT_REMOVED NON_USER_EVENT, OLD_TEXT_INSERTED NON_USER_EVENT },
+  { OLD_TEXT_REMOVED, OLD_TEXT_INSERTED }
+};
+
+#define TEXT_INSERTED "text-insert"
+#define TEXT_REMOVED "text-remove"
+#define NON_USER_DETAIL "::system"
+static const char* textChangedStrings[2][2] = {
+  { TEXT_REMOVED NON_USER_DETAIL, TEXT_INSERTED NON_USER_DETAIL },
+  { TEXT_REMOVED, TEXT_INSERTED}
+};
+
 nsresult
 AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
                                         AtkObject* aObject)
 {
     AccTextChangeEvent* event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
     int32_t start = event->GetStartOffset();
     uint32_t length = event->GetLength();
     bool isInserted = event->IsTextInserted();
     bool isFromUserInput = aEvent->IsFromUserInput();
-    char* signal_name = nullptr;
 
   if (gAvailableAtkSignals == eUnknown)
     gAvailableAtkSignals =
       g_signal_lookup("text-insert", G_OBJECT_TYPE(aObject)) ?
         eHaveNewAtkTextSignals : eNoNewAtkSignals;
 
   if (gAvailableAtkSignals == eNoNewAtkSignals) {
     // XXX remove this code and the gHaveNewTextSignals check when we can
     // stop supporting old atk since it doesn't really work anyway
     // see bug 619002
-    signal_name = g_strconcat(isInserted ? "text_changed::insert" :
-                              "text_changed::delete",
-                              isFromUserInput ? "" : kNonUserInputEvent, nullptr);
+    const char* signal_name =
+      oldTextChangeStrings[isFromUserInput][isInserted];
     g_signal_emit_by_name(aObject, signal_name, start, length);
   } else {
     nsAutoString text;
     event->GetModifiedText(text);
-    signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove",
-                              isFromUserInput ? "" : "::system", nullptr);
+    const char* signal_name =
+      textChangedStrings[isFromUserInput][isInserted];
     g_signal_emit_by_name(aObject, signal_name, start, length,
                           NS_ConvertUTF16toUTF8(text).get());
   }
 
-  g_free(signal_name);
   return NS_OK;
 }
 
+#define ADD_EVENT "children_changed::add"
+#define HIDE_EVENT "children_changed::remove"
+
+static const char *kMutationStrings[2][2] = {
+  { HIDE_EVENT NON_USER_EVENT, ADD_EVENT NON_USER_EVENT },
+  { HIDE_EVENT, ADD_EVENT },
+};
+
 nsresult
 AccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
                                      AtkObject* aObject, bool aIsAdded)
 {
     int32_t indexInParent = getIndexInParentCB(aObject);
     AtkObject *parentObject = getParentCB(aObject);
     NS_ENSURE_STATE(parentObject);
 
     bool isFromUserInput = aEvent->IsFromUserInput();
-    char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" :  "children_changed::remove",
-                                    isFromUserInput ? "" : kNonUserInputEvent, nullptr);
+    const char *signal_name = kMutationStrings[isFromUserInput][aIsAdded];
     g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, nullptr);
-    g_free(signal_name);
 
     return NS_OK;
 }
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -33,16 +33,17 @@ class AccGroupInfo;
 class ApplicationAccessible;
 class DocAccessible;
 class EmbeddedObjCollector;
 class HTMLImageMapAccessible;
 class HTMLLIAccessible;
 class HyperTextAccessible;
 class ImageAccessible;
 class KeyBinding;
+class OuterDocAccessible;
 class ProxyAccessible;
 class Relation;
 class RootAccessible;
 class TableAccessible;
 class TableCellAccessible;
 class TextLeafAccessible;
 class XULLabelAccessible;
 class XULTreeAccessible;
@@ -614,16 +615,19 @@ public:
 
   bool IsProxy() const { return mType == eProxyType; }
   ProxyAccessible* Proxy() const
   {
     MOZ_ASSERT(IsProxy());
     return mBits.proxy;
   }
 
+  bool IsOuterDoc() const { return mType == eOuterDocType; }
+  OuterDocAccessible* AsOuterDoc();
+
   bool IsProgress() const { return mType == eProgressType; }
 
   bool IsRoot() const { return mType == eRootType; }
   a11y::RootAccessible* AsRoot();
 
   bool IsSearchbox() const;
 
   bool IsSelect() const { return HasGenericType(eSelect); }
--- a/accessible/generic/OuterDocAccessible.cpp
+++ b/accessible/generic/OuterDocAccessible.cpp
@@ -3,16 +3,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "OuterDocAccessible.h"
 
 #include "Accessible-inl.h"
 #include "nsAccUtils.h"
 #include "DocAccessible-inl.h"
+#include "mozilla/a11y/DocAccessibleParent.h"
+#include "mozilla/dom/TabParent.h"
 #include "Role.h"
 #include "States.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 using namespace mozilla;
@@ -21,16 +23,17 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 // OuterDocAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 OuterDocAccessible::
   OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
+  mType = eOuterDocType;
 }
 
 OuterDocAccessible::~OuterDocAccessible()
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
@@ -176,8 +179,29 @@ OuterDocAccessible::CacheChildren()
   // created. It will appended to outerdoc accessible children asynchronously.
   nsIDocument* outerDoc = mContent->GetCurrentDoc();
   if (outerDoc) {
     nsIDocument* innerDoc = outerDoc->GetSubDocumentFor(mContent);
     if (innerDoc)
       GetAccService()->GetDocAccessible(innerDoc);
   }
 }
+
+ProxyAccessible*
+OuterDocAccessible::RemoteChildDoc() const
+{
+  dom::TabParent* tab = dom::TabParent::GetFrom(GetContent());
+  if (!tab)
+    return nullptr;
+
+  // XXX Consider managing non top level remote documents with there parent
+  // document.
+  const nsTArray<PDocAccessibleParent*>& docs = tab->ManagedPDocAccessibleParent();
+  size_t docCount = docs.Length();
+  for (size_t i = 0; i < docCount; i++) {
+    auto doc = static_cast<DocAccessibleParent*>(docs[i]);
+    if (!doc->ParentDoc())
+      return doc;
+  }
+
+  MOZ_ASSERT(false, "no top level tab document?");
+  return nullptr;
+}
--- a/accessible/generic/OuterDocAccessible.h
+++ b/accessible/generic/OuterDocAccessible.h
@@ -5,16 +5,17 @@
 
 #ifndef MOZILLA_A11Y_OUTERDOCACCESSIBLE_H_
 #define MOZILLA_A11Y_OUTERDOCACCESSIBLE_H_
 
 #include "AccessibleWrap.h"
 
 namespace mozilla {
 namespace a11y {
+class ProxyAccessible;
 
 /**
  * Used for <browser>, <frame>, <iframe>, <page> or editor> elements.
  * 
  * In these variable names, "outer" relates to the OuterDocAccessible as
  * opposed to the DocAccessibleWrap which is "inner". The outer node is
  * a something like tags listed above, whereas the inner node corresponds to
  * the inner document root.
@@ -22,16 +23,18 @@ namespace a11y {
 
 class OuterDocAccessible final : public AccessibleWrap
 {
 public:
   OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   NS_DECL_ISUPPORTS_INHERITED
 
+  ProxyAccessible* RemoteChildDoc() const;
+
   // Accessible
   virtual void Shutdown() override;
   virtual mozilla::a11y::role NativeRole() override;
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild) override;
 
   virtual void InvalidateChildren() override;
   virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) override;
@@ -39,12 +42,17 @@ public:
 
 protected:
   virtual ~OuterDocAccessible() override;
 
   // Accessible
   virtual void CacheChildren() override;
 };
 
+inline OuterDocAccessible*
+Accessible::AsOuterDoc()
+{
+  return IsOuterDoc() ? static_cast<OuterDocAccessible*>(this) : nullptr;
+}
 } // namespace a11y
 } // namespace mozilla
 
 #endif  
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -1633,16 +1633,31 @@ DocAccessibleChild::RecvIndexOfEmbeddedC
   if (!parent || !child)
     return true;
 
   *aChildIdx = parent->GetIndexOfEmbeddedChild(child);
   return true;
 }
 
 bool
+DocAccessibleChild::RecvEmbeddedChildAt(const uint64_t& aID,
+                                        const uint32_t& aIdx,
+                                        uint64_t* aChildID)
+{
+  *aChildID = 0;
+
+  Accessible* acc = IdToAccessible(aID);
+  if (!acc)
+    return true;
+
+  *aChildID = reinterpret_cast<uintptr_t>(acc->GetEmbeddedChildAt(aIdx));
+  return true;
+}
+
+bool
 DocAccessibleChild::RecvChildAtPoint(const uint64_t& aID,
                                      const int32_t& aX,
                                      const int32_t& aY,
                                      const uint32_t& aWhich,
                                      uint64_t* aChild,
                                      bool* aOk)
 {
   *aChild = 0;
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -403,16 +403,19 @@ public:
                         double* aStep) override;
 
   virtual bool RecvTakeFocus(const uint64_t& aID) override;
 
   virtual bool RecvIndexOfEmbeddedChild(const uint64_t& aID,
                                         const uint64_t& aChildID,
                                         uint32_t* aChildIdx) override final;
 
+  virtual bool RecvEmbeddedChildAt(const uint64_t& aID, const uint32_t& aIdx,
+                                   uint64_t* aChildID) override final;
+
   virtual bool RecvChildAtPoint(const uint64_t& aID,
                                 const int32_t& aX,
                                 const int32_t& aY,
                                 const uint32_t& aWhich,
                                 uint64_t* aChild,
                                 bool* aOk) override;
 
   virtual bool RecvBounds(const uint64_t& aID, nsIntRect* aRect) override;
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -208,13 +208,16 @@ DocAccessibleParent::Destroy()
   mShutdown = true;
 
   uint32_t childDocCount = mChildDocs.Length();
   for (uint32_t i = childDocCount - 1; i < childDocCount; i--)
     mChildDocs[i]->Destroy();
 
   mAccessibles.EnumerateEntries(ShutdownAccessibles, nullptr);
   ProxyDestroyed(this);
-  mParentDoc ? mParentDoc->RemoveChildDoc(this)
-    : GetAccService()->RemoteDocShutdown(this);
+  if (mParentDoc)
+    mParentDoc->RemoveChildDoc(this);
+  else if (IsTopLevel())
+    GetAccService()->RemoteDocShutdown(this);
 }
-}
-}
+
+} // a11y
+} // mozilla
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -21,25 +21,29 @@ namespace a11y {
  * These objects live in the main process and comunicate with and represent
  * an accessible document in a content process.
  */
 class DocAccessibleParent : public ProxyAccessible,
     public PDocAccessibleParent
 {
 public:
   DocAccessibleParent() :
-    ProxyAccessible(this), mParentDoc(nullptr), mShutdown(false)
+    ProxyAccessible(this), mParentDoc(nullptr),
+    mTopLevel(false), mShutdown(false)
   { MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
   ~DocAccessibleParent()
   {
     MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
     MOZ_ASSERT(mChildDocs.Length() == 0);
     MOZ_ASSERT(!ParentDoc());
   }
 
+  void SetTopLevel() { mTopLevel = true; }
+  bool IsTopLevel() const { return mTopLevel; }
+
   /*
    * Called when a message from a document in a child process notifies the main
    * process it is firing an event.
    */
   virtual bool RecvEvent(const uint64_t& aID, const uint32_t& aType)
     override;
 
   virtual bool RecvShowEvent(const ShowEventData& aData) override;
@@ -146,15 +150,16 @@ private:
   nsTArray<DocAccessibleParent*> mChildDocs;
   DocAccessibleParent* mParentDoc;
 
   /*
    * Conceptually this is a map from IDs to proxies, but we store the ID in the
    * proxy object so we can't use a real map.
    */
   nsTHashtable<ProxyEntry> mAccessibles;
+  bool mTopLevel;
   bool mShutdown;
 };
 
 }
 }
 
 #endif
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -213,16 +213,18 @@ child:
   prio(high) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);
   prio(high) sync MinValue(uint64_t aID) returns(double aValue);
   prio(high) sync MaxValue(uint64_t aID) returns(double aValue);
   prio(high) sync Step(uint64_t aID) returns(double aStep);
 
   prio(high) sync TakeFocus(uint64_t aID);
   prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
     returns(uint32_t childIdx);
+  prio(high) sync EmbeddedChildAt(uint64_t aID, uint32_t aChildIdx)
+    returns(uint64_t aChild);
   prio(high) sync ChildAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aWhich)
     returns(uint64_t aChild, bool aOk);
   prio(high) sync Bounds(uint64_t aID) returns(nsIntRect aRect);
 
   prio(high) sync Language(uint64_t aID) returns(nsString aLocale);
   prio(high) sync DocType(uint64_t aID) returns(nsString aType);
   prio(high) sync URL(uint64_t aID) returns(nsString aURL);
   prio(high) sync MimeType(uint64_t aID) returns(nsString aMime);
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -912,16 +912,24 @@ ProxyAccessible::IndexOfEmbeddedChild(co
 {
   uint64_t childID = aChild->mID;
   uint32_t childIdx;
   unused << mDoc->SendIndexOfEmbeddedChild(mID, childID, &childIdx);
   return childIdx;
 }
 
 ProxyAccessible*
+ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
+{
+  uint64_t childID;
+  unused << mDoc->SendEmbeddedChildAt(mID, aChildIdx, &childID);
+  return mDoc->GetAccessible(childID);
+}
+
+ProxyAccessible*
 ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY,
                               Accessible::EWhichChildAtPoint aWhichChild)
 {
   uint64_t childID = 0;
   bool ok = false;
   unused << mDoc->SendChildAtPoint(mID, aX, aY,
                                    static_cast<uint32_t>(aWhichChild),
                                    &childID, &ok);
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -44,16 +44,17 @@ public:
   { mChildren.InsertElementAt(aIdx, aChild); }
 
   uint32_t ChildrenCount() const { return mChildren.Length(); }
   ProxyAccessible* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
 
   // XXX evaluate if this is fast enough.
   size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
   int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
+  ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
   bool MustPruneChildren() const;
 
   void Shutdown();
 
   void SetChildDoc(DocAccessibleParent*);
 
   /**
    * Remove The given child.
--- a/accessible/mac/mozAccessible.mm
+++ b/accessible/mac/mozAccessible.mm
@@ -595,23 +595,24 @@ struct RoleDescrComparator
 {
   // Do nothing. mozTextAccessible will.
 }
 
 - (NSString*)customDescription
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
-  AccessibleWrap* accWrap = [self getGeckoAccessible];
-  if (accWrap->IsDefunct())
+  nsAutoString desc;
+  if (AccessibleWrap* accWrap = [self getGeckoAccessible])
+    accWrap->Description(desc);
+  else if (ProxyAccessible* proxy = [self getProxyAccessible])
+    proxy->Description(desc);
+  else
     return nil;
 
-  nsAutoString desc;
-  accWrap->Description(desc);
-
   return nsCocoaUtils::ToNSString(desc);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (NSString*)help
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -999,16 +999,20 @@ pref("network.proxy.pac_generator", true
 
 // List of app origins to apply browsing traffic proxy setting, separated by
 // comma.  Specify '*' in the list to apply to all apps.
 pref("network.proxy.browsing.app_origins", "app://system.gaiamobile.org");
 
 // Enable Web Speech synthesis API
 pref("media.webspeech.synth.enabled", true);
 
+// Enable Web Speech recognition API
+pref("media.webspeech.recognition.enable", true);
+pref("media.webspeech.service.default", "pocketsphinx");
+
 // Downloads API
 pref("dom.mozDownloads.enabled", true);
 pref("dom.downloads.max_retention_days", 7);
 
 // External Helper Application Handling
 //
 // All external helper application handling can require the docshell to be
 // active before allowing the external helper app service to handle content.
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "d2f31eb85837aae6eca04d022d1f5b2023bc778c", 
+        "git_revision": "9f36b711af7597a6a32471c3305cf1e2d6947d39", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "2e9a1e5808b983fe4aa50a169b0e36fb3f0b43a3", 
+    "revision": "8583025b84cda74c63e83bbbdfd7a4f33b917f20", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="d2f31eb85837aae6eca04d022d1f5b2023bc778c"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9f36b711af7597a6a32471c3305cf1e2d6947d39"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="70b7fcbf7ff0ef38d04f82d68a56f2bb44ec694a"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="41efd945c841175f733ef764fe5f6a85c592970b"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -24,23 +24,22 @@ MOZ_CAPTIVEDETECT=1
 
 MOZ_WEBSMS_BACKEND=1
 MOZ_NO_SMART_CARDS=1
 MOZ_APP_STATIC_INI=1
 NSS_DISABLE_DBM=1
 MOZ_NO_EV_CERTS=1
 MOZ_DISABLE_EXPORT_JS=1
 
-# Bug 1171082 - Broken on Windows B2G Desktop
-if test "$OS_TARGET" != "WINNT"; then
 MOZ_WEBSPEECH=1
+if test -n "$NIGHTLY_BUILD"; then
 MOZ_WEBSPEECH_MODELS=1
 MOZ_WEBSPEECH_POCKETSPHINX=1
+fi
 MOZ_WEBSPEECH_TEST_BACKEND=1
-fi # !WINNT
 
 if test "$OS_TARGET" = "Android"; then
 MOZ_CAPTURE=1
 MOZ_RAW=1
 MOZ_AUDIO_CHANNEL_MANAGER=1
 fi
 
 # use custom widget for html:select
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1230,19 +1230,24 @@
                          oncommand="DeveloperToolbar.hide();"
                          tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
 #endif
    </toolbar>
   </vbox>
 
   <svg:svg height="0">
 #include tab-shape.inc.svg
+#if defined(XP_UNIX) && !defined(XP_MACOSX)
+    <svg:clipPath id="urlbar-clip-path" clipPathUnits="userSpaceOnUse">
+      <svg:path d="m 1,-5 l 0,50 l 10000,0 l 0,-50 z"/>
+    </svg:clipPath>
+#endif
     <svg:clipPath id="urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
 #ifndef XP_MACOSX
-      <svg:path d="m 1,-5 l 0,7.8 c 2.5,3.2 4,6.2 4,10.2 c 0,4 -1.5,7 -4,10 l 0,22l10000,0 l 0,-50 l -10000,0 z"/>
+      <svg:path d="m 1,-5 l 0,7.8 c 2.5,3.2 4,6.2 4,10.2 c 0,4 -1.5,7 -4,10 l 0,22 l 10000,0 l 0,-50 l -10000,0 z"/>
 #else
       <svg:path d="M -11,-5 a 16 16 0 0 1 0,34 l 10000,0 l 0,-34 l -10000,0 z"/>
 #endif
     </svg:clipPath>
   </svg:svg>
 
 </vbox>
 # <iframe id="tab-view"> is dynamically appended as the 2nd child of #tab-view-deck.
--- a/browser/devtools/performance/docs/markers.md
+++ b/browser/devtools/performance/docs/markers.md
@@ -102,24 +102,36 @@ a setTimeout.
   * "WebIDL dictionary creation"
   * "XBL \<constructor\>/\<destructor\> invocation"
   * "message manager script load"
   * "message handler script load"
   * "nsGlobalWindow report new global"
 
 ## GarbageCollection
 
-Emitted after a full GC has occurred (which will emit past incremental events).
+Emitted after a full GC cycle has completed (which is after any number of
+incremental slices).
 
 * DOMString causeName - The reason for a GC event to occur. A full list of
   GC reasons can be found [on MDN](https://developer.mozilla.org/en-US/docs/Tools/Debugger-API/Debugger.Memory#Debugger.Memory_Handler_Functions).
 * DOMString nonincremenetalReason - If the GC could not do an incremental
   GC (smaller, quick GC events), and we have to walk the entire heap and
   GC everything marked, then the reason listed here is why.
 
+## nsCycleCollector::Collect
+
+An `nsCycleCollector::Collect` marker is emitted for each incremental cycle
+collection slice and each non-incremental cycle collection.
+
+# nsCycleCollector::ForgetSkippable
+
+`nsCycleCollector::ForgetSkippable` is presented as "Cycle Collection", but in
+reality it is preparation/pre-optimization for cycle collection, and not the
+actual tracing of edges and collecting of cycles.
+
 ## ConsoleTime
 
 A marker generated via `console.time()` and `console.timeEnd()`.
 
 * DOMString causeName - the label passed into `console.time(label)` and
   `console.timeEnd(label)` if passed in.
 
 ## TimeStamp
--- a/browser/devtools/performance/modules/logic/marker-utils.js
+++ b/browser/devtools/performance/modules/logic/marker-utils.js
@@ -430,16 +430,23 @@ const Formatters = {
     return fields;
   },
 
   StylesFields: function (marker) {
     if ("restyleHint" in marker) {
       return { "Restyle Hint": marker.restyleHint.replace(/eRestyle_/g, "") };
     }
   },
+
+  CycleCollectionFields: function (marker) {
+    let Type = PREFS["show-platform-data"]
+        ? marker.name
+        : marker.name.replace(/nsCycleCollector::/g, "");
+    return { Type };
+  },
 };
 
 exports.getMarkerLabel = getMarkerLabel;
 exports.getMarkerClassName = getMarkerClassName;
 exports.getMarkerFields = getMarkerFields;
 exports.DOM = DOM;
 exports.CollapseFunctions = CollapseFunctions;
 exports.Formatters = Formatters;
--- a/browser/devtools/performance/modules/markers.js
+++ b/browser/devtools/performance/modules/markers.js
@@ -108,16 +108,30 @@ const TIMELINE_BLUEPRINT = {
     colorName: "graphs-red",
     collapseFunc: either(collapse.parent, collapse.child),
     label: Formatters.GCLabel,
     fields: [
       { property: "causeName", label: "Reason:" },
       { property: "nonincrementalReason", label: "Non-incremental Reason:" }
     ],
   },
+  "nsCycleCollector::Collect": {
+    group: 1,
+    colorName: "graphs-red",
+    collapseFunc: either(collapse.parent, collapse.child),
+    label: "Cycle Collection",
+    fields: Formatters.CycleCollectionFields,
+  },
+  "nsCycleCollector::ForgetSkippable": {
+    group: 1,
+    colorName: "graphs-red",
+    collapseFunc: either(collapse.parent, collapse.child),
+    label: "Cycle Collection",
+    fields: Formatters.CycleCollectionFields,
+  },
 
   /* Group 2 - User Controlled */
   "ConsoleTime": {
     group: 2,
     colorName: "graphs-grey",
     label: sublabelForProperty(L10N.getStr("timeline.label.consoleTime"), "causeName"),
     fields: [{
       property: "causeName",
--- a/browser/devtools/performance/test/browser.ini
+++ b/browser/devtools/performance/test/browser.ini
@@ -1,23 +1,25 @@
 [DEFAULT]
 tags = devtools
 subsuite = devtools
 support-files =
+  doc_force_cc.html
   doc_force_gc.html
   doc_innerHTML.html
   doc_markers.html
   doc_simple-test.html
   head.js
 
 # Commented out tests are profiler tests
 # that need to be moved over to performance tool
 
 [browser_aaa-run-first-leaktest.js]
 [browser_marker-utils.js]
+[browser_markers-cycle-collection.js]
 [browser_markers-gc.js]
 [browser_markers-parse-html.js]
 [browser_markers-styles.js]
 [browser_markers-timestamp.js]
 [browser_perf-allocations-to-samples.js]
 [browser_perf-categories-js-calltree.js]
 [browser_perf-compatibility-01.js]
 [browser_perf-compatibility-02.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/performance/test/browser_markers-cycle-collection.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Test that we get "nsCycleCollector::Collect" and
+ * "nsCycleCollector::ForgetSkippable" markers when we force cycle collection.
+ */
+
+const TEST_URL = EXAMPLE_URL + "doc_force_cc.html"
+
+function waitForMarkerType(front, type) {
+  info("Waiting for marker of type = " + type);
+  const { promise, resolve } = Promise.defer();
+
+  const handler = (_, name, markers) => {
+    if (name !== "markers") {
+      return;
+    }
+
+    info("Got markers: " + JSON.stringify(markers, null, 2));
+
+    if (markers.some(m => m.name === type)) {
+      ok(true, "Found marker of type = " + type);
+      front.off("timeline-data", handler);
+      resolve();
+    }
+  };
+  front.on("timeline-data", handler);
+
+  return promise;
+}
+
+function* spawnTest () {
+  // This test runs very slowly on linux32 debug EC2 instances.
+  requestLongerTimeout(2);
+
+  let { target, front } = yield initBackend(TEST_URL);
+
+  yield front.startRecording({ withMarkers: true, withTicks: true });
+
+  yield Promise.all([
+    waitForMarkerType(front, "nsCycleCollector::Collect"),
+    waitForMarkerType(front, "nsCycleCollector::ForgetSkippable")
+  ]);
+  ok(true, "Got expected cycle collection events");
+
+  yield front.stopRecording();
+  yield removeTab(target.tab);
+  finish();
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/performance/test/doc_force_cc.html
@@ -0,0 +1,29 @@
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!doctype html>
+
+<html>
+  <head>
+    <meta charset="utf-8"/>
+    <title>Performance tool + cycle collection test page</title>
+  </head>
+
+  <body>
+    <script type="text/javascript">
+    window.test = function () {
+      document.body.expando1 = { cycle: document.body };
+      SpecialPowers.Cu.forceCC();
+
+      document.body.expando2 = { cycle: document.body };
+      SpecialPowers.Cu.forceCC();
+
+      document.body.expando3 = { cycle: document.body };
+      SpecialPowers.Cu.forceCC();
+
+      setTimeout(window.test, 100);
+    };
+    test();
+    </script>
+  </body>
+
+</html>
--- a/browser/devtools/webide/test/chrome.ini
+++ b/browser/devtools/webide/test/chrome.ini
@@ -1,11 +1,11 @@
 [DEFAULT]
 tags = devtools
-skip-if = buildapp == 'b2g'
+skip-if = buildapp == 'b2g' || (os == "mac" && (os_version == "10.8" || os_version == "10.10") && debug) # Bug 1135315 - assertions
 support-files =
   app/index.html
   app/manifest.webapp
   app.zip
   addons/simulators.json
   addons/fxos_1_0_simulator-linux.xpi
   addons/fxos_1_0_simulator-linux64.xpi
   addons/fxos_1_0_simulator-win32.xpi
--- a/browser/devtools/webide/test/sidebars/chrome.ini
+++ b/browser/devtools/webide/test/sidebars/chrome.ini
@@ -1,11 +1,11 @@
 [DEFAULT]
 tags = devtools
-skip-if = buildapp == 'b2g'
+skip-if = buildapp == 'b2g' || (os == "mac" && (os_version == "10.8" || os_version == "10.10") && debug) # Bug 1135315 - assertions
 support-files =
   ../app/index.html
   ../app/manifest.webapp
   ../head.js
   ../device_front_shared.js
 
 [test_newapp.html]
 [test_import.html]
--- a/browser/modules/ProcessHangMonitor.jsm
+++ b/browser/modules/ProcessHangMonitor.jsm
@@ -308,13 +308,14 @@ let ProcessHangMonitor = {
 
   /**
    * Callback for when HANG_EXPIRATION_TIME has elapsed.
    */
   notify: function(timer) {
     for (let [otherReport, otherTimer] of this._activeReports) {
       if (otherTimer === timer) {
         this.removeReport(otherReport);
+        otherReport.userCanceled();
         break;
       }
     }
   },
 };
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -675,27 +675,27 @@ toolbarbutton[constrain-size="true"][cui
 
 :-moz-any(#TabsToolbar, #nav-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   -moz-margin-start: -4px;
   margin-top: 3px;
   margin-bottom: 3px;
 }
 
 #back-button {
-  padding-top: 3px;
-  padding-bottom: 3px;
-  -moz-padding-start: 5px;
-  -moz-padding-end: 0;
+  margin-top: 3px;
+  margin-bottom: 3px;
+  -moz-margin-start: 5px;
+  padding: 0;
   position: relative;
   z-index: 1;
-  border-radius: 0 10000px 10000px 0;
+  border-radius: 10000px;
 }
 
-#back-button:-moz-locale-dir(rtl) {
-  border-radius: 10000px 0 0 10000px;
+#back-button:not(:-moz-lwtheme) {
+  background-color: -moz-dialog;
 }
 
 #back-button > menupopup {
   margin-top: -1px;
 }
 
 #back-button > .toolbarbutton-icon {
   border-radius: 10000px;
@@ -889,23 +889,27 @@ toolbarbutton[constrain-size="true"][cui
 }
 
 @conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(rtl) {
   border-top-right-radius: 0;
   border-bottom-right-radius: 0;
 }
 
 @conditionalForwardWithUrlbar@ {
+  clip-path: url("chrome://browser/content/browser.xul#urlbar-clip-path");
+  -moz-margin-start: -5px;
+}
+
+@conditionalForwardWithUrlbar@:-moz-lwtheme {
   clip-path: url("chrome://browser/content/browser.xul#urlbar-back-button-clip-path");
-  -moz-margin-start: -5px;
 }
 
 @conditionalForwardWithUrlbar@:-moz-locale-dir(rtl),
 @conditionalForwardWithUrlbar@ > #urlbar:-moz-locale-dir(rtl) {
-  /* let urlbar-back-button-clip-path clip the urlbar's right side for RTL */
+  /* Let clip-path clip the urlbar-wrapper's right side for RTL. */
   transform: scaleX(-1);
 }
 
 @conditionalForwardWithUrlbar@:-moz-locale-dir(rtl) {
   -moz-box-direction: reverse;
 }
 
 #urlbar-icons {
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -110,16 +110,22 @@ OriginAttributes::PopulateFromSuffix(con
 
   nsRefPtr<URLSearchParams> usp = new URLSearchParams();
   usp->ParseInput(Substring(aStr, 1, aStr.Length() - 1), nullptr);
 
   PopulateFromSuffixIterator iterator(this);
   return usp->ForEach(iterator);
 }
 
+void
+OriginAttributes::CookieJar(nsACString& aStr)
+{
+  mozilla::GetJarPrefix(mAppId, mInBrowser, aStr);
+}
+
 BasePrincipal::BasePrincipal()
 {}
 
 BasePrincipal::~BasePrincipal()
 {}
 
 NS_IMETHODIMP
 BasePrincipal::GetOrigin(nsACString& aOrigin)
@@ -218,17 +224,17 @@ BasePrincipal::GetIsNullPrincipal(bool* 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetJarPrefix(nsACString& aJarPrefix)
 {
   MOZ_ASSERT(AppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID);
 
-  mozilla::GetJarPrefix(AppId(), IsInBrowserElement(), aJarPrefix);
+  mOriginAttributes.CookieJar(aJarPrefix);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
 {
   if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
     return NS_ERROR_FAILURE;
@@ -241,20 +247,18 @@ BasePrincipal::GetOriginSuffix(nsACStrin
 {
   mOriginAttributes.CreateSuffix(aOriginAttributes);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetCookieJar(nsACString& aCookieJar)
 {
-  // We just forward to .jarPrefix for now, which is a nice compact
-  // stringification of the (appId, inBrowser) tuple. This will eventaully be
-  // swapped out for an origin attribute - see the comment in nsIPrincipal.idl.
-  return GetJarPrefix(aCookieJar);
+  mOriginAttributes.CookieJar(aCookieJar);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
 {
   if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
     NS_WARNING("Asking for app status on a principal with an unknown app id");
     *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -6,49 +6,53 @@
 
 #ifndef mozilla_BasePrincipal_h
 #define mozilla_BasePrincipal_h
 
 #include "nsIPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsJSPrincipals.h"
 
-#include "mozilla/dom/SystemDictionariesBinding.h"
+#include "mozilla/dom/ChromeUtilsBinding.h"
 
 class nsIContentSecurityPolicy;
 class nsIObjectOutputStream;
 class nsIObjectInputStream;
 
 namespace mozilla {
 
 class OriginAttributes : public dom::OriginAttributesDictionary
 {
 public:
   OriginAttributes() {}
   OriginAttributes(uint32_t aAppId, bool aInBrowser)
   {
     mAppId = aAppId;
     mInBrowser = aInBrowser;
   }
+  explicit OriginAttributes(const OriginAttributesDictionary& aOther)
+    : OriginAttributesDictionary(aOther) {}
 
   bool operator==(const OriginAttributes& aOther) const
   {
     return mAppId == aOther.mAppId &&
            mInBrowser == aOther.mInBrowser;
   }
   bool operator!=(const OriginAttributes& aOther) const
   {
     return !(*this == aOther);
   }
 
   // Serializes/Deserializes non-default values into the suffix format, i.e.
   // |!key1=value1&key2=value2|. If there are no non-default attributes, this
   // returns an empty string.
   void CreateSuffix(nsACString& aStr) const;
   bool PopulateFromSuffix(const nsACString& aStr);
+
+  void CookieJar(nsACString& aStr);
 };
 
 /*
  * Base class from which all nsIPrincipal implementations inherit. Use this for
  * default implementations and other commonalities between principal
  * implementations.
  *
  * We should merge nsJSPrincipals into this class at some point.
--- a/configure.in
+++ b/configure.in
@@ -5127,21 +5127,16 @@ else
     MOZ_SAMPLE_TYPE_FLOAT32=1
     AC_DEFINE(MOZ_SAMPLE_TYPE_FLOAT32)
     AC_SUBST(MOZ_SAMPLE_TYPE_FLOAT32)
 fi
 
 dnl ========================================================
 dnl = Disable Speech API pocketsphinx backend
 dnl ========================================================
-MOZ_ARG_DISABLE_BOOL(webspeechpocketsphinx,
-[  --disable-webspeechpocketsphinx        Disable support for HTML Speech API Pocketsphinx Backend],
-    MOZ_WEBSPEECH_POCKETSPHINX=,
-    MOZ_WEBSPEECH_POCKETSPHINX=1)
-
 if test -n "$MOZ_WEBSPEECH_POCKETSPHINX"; then
     AC_DEFINE(MOZ_WEBSPEECH_POCKETSPHINX)
 fi
 
 AC_SUBST(MOZ_WEBSPEECH_POCKETSPHINX)
 
 dnl ========================================================
 dnl = Disable Speech API code
@@ -5173,21 +5168,16 @@ if test -n "$MOZ_WEBSPEECH_TEST_BACKEND"
     AC_DEFINE(MOZ_WEBSPEECH_TEST_BACKEND)
 fi
 
 AC_SUBST(MOZ_WEBSPEECH_TEST_BACKEND)
 
 dnl ========================================================
 dnl = Disable Speech API models
 dnl ========================================================
-MOZ_ARG_DISABLE_BOOL(webspeechmodels,
-[  --disable-webspeechmodels        Disable support for HTML Speech API Models],
-    MOZ_WEBSPEECH_MODELS=,
-    MOZ_WEBSPEECH_MODELS=1)
-
 if test -z "$MOZ_WEBSPEECH"; then
 MOZ_WEBSPEECH_MODELS=
 fi
 
 if test -n "$MOZ_WEBSPEECH_MODELS"; then
     AC_DEFINE(MOZ_WEBSPEECH_MODELS)
 fi
 
new file mode 100644
--- /dev/null
+++ b/docshell/base/AutoTimelineMarker.cpp
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/AutoTimelineMarker.h"
+
+#include "MainThreadUtils.h"
+#include "nsDocShell.h"
+#include "mozilla/Move.h"
+
+namespace mozilla {
+
+bool
+AutoTimelineMarker::DocShellIsRecording(nsDocShell& aDocShell)
+{
+  bool isRecording = false;
+  if (nsDocShell::gProfileTimelineRecordingsCount > 0) {
+    aDocShell.GetRecordProfileTimelineMarkers(&isRecording);
+  }
+  return isRecording;
+}
+
+AutoTimelineMarker::AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
+                                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+  : mDocShell(nullptr)
+  , mName(aName)
+{
+  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
+  if (docShell && DocShellIsRecording(*docShell)) {
+    mDocShell = docShell;
+    mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
+  }
+}
+
+AutoTimelineMarker::~AutoTimelineMarker()
+{
+  if (mDocShell) {
+    mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
+  }
+}
+
+void
+AutoGlobalTimelineMarker::PopulateDocShells()
+{
+  const LinkedList<nsDocShell::ObservedDocShell>& docShells =
+    nsDocShell::GetObservedDocShells();
+  MOZ_ASSERT(!docShells.isEmpty());
+
+  for (const nsDocShell::ObservedDocShell* ds = docShells.getFirst();
+       ds;
+       ds = ds->getNext()) {
+    mOk = mDocShells.append(**ds);
+    if (!mOk) {
+      return;
+    }
+  }
+}
+
+AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName
+                                                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+  : mOk(true)
+  , mDocShells()
+  , mName(aName)
+{
+  MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (nsDocShell::gProfileTimelineRecordingsCount == 0) {
+    return;
+  }
+
+  PopulateDocShells();
+  if (!mOk) {
+    // If we don't successfully populate our vector with *all* docshells being
+    // observed, don't add markers to *any* of them.
+    return;
+  }
+
+  for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
+       !range.empty();
+       range.popFront()) {
+    range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
+  }
+}
+
+AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker()
+{
+  if (!mOk) {
+    return;
+  }
+
+  for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
+       !range.empty();
+       range.popFront()) {
+    range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
+  }
+}
+
+
+} // namespace mozilla
--- a/docshell/base/AutoTimelineMarker.h
+++ b/docshell/base/AutoTimelineMarker.h
@@ -3,74 +3,91 @@
 /* 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 AutoTimelineMarker_h__
 #define AutoTimelineMarker_h__
 
 #include "mozilla/GuardObjects.h"
-#include "mozilla/Move.h"
-#include "nsDocShell.h"
+#include "mozilla/Vector.h"
+
 #include "nsRefPtr.h"
 
+class nsIDocShell;
+class nsDocShell;
+
 namespace mozilla {
 
 // # AutoTimelineMarker
 //
 // An RAII class to trace some task in the platform by adding a start and end
 // timeline marker pair. These markers are then rendered in the devtools'
 // performance tool's waterfall graph.
 //
 // Example usage:
 //
 //     {
 //       AutoTimelineMarker marker(mDocShell, "Parse CSS");
 //       nsresult rv = ParseTheCSSFile(mFile);
 //       ...
 //     }
-
 class MOZ_STACK_CLASS AutoTimelineMarker
 {
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
 
   nsRefPtr<nsDocShell> mDocShell;
   const char* mName;
 
-  bool
-  DocShellIsRecording(nsDocShell& aDocShell)
-  {
-    bool isRecording = false;
-    if (nsDocShell::gProfileTimelineRecordingsCount > 0) {
-      aDocShell.GetRecordProfileTimelineMarkers(&isRecording);
-    }
-    return isRecording;
-  }
+  bool DocShellIsRecording(nsDocShell& aDocShell);
 
 public:
   explicit AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
-                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : mDocShell(nullptr)
-    , mName(aName)
-  {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-
-    nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
-    if (docShell && DocShellIsRecording(*docShell)) {
-      mDocShell = docShell;
-      mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
-    }
-  }
-
-  ~AutoTimelineMarker()
-  {
-    if (mDocShell) {
-      mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
-    }
-  }
+                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+  ~AutoTimelineMarker();
 
   AutoTimelineMarker(const AutoTimelineMarker& aOther) = delete;
   void operator=(const AutoTimelineMarker& aOther) = delete;
 };
 
+// # AutoGlobalTimelineMarker
+//
+// Similar to `AutoTimelineMarker`, but adds its traced marker to all docshells,
+// not a single particular one. This is useful for operations that aren't
+// associated with any one particular doc shell, or when it isn't clear which
+// doc shell triggered the operation.
+//
+// Example usage:
+//
+//     {
+//       AutoGlobalTimelineMarker marker("Cycle Collection");
+//       nsCycleCollector* cc = GetCycleCollector();
+//       cc->Collect();
+//       ...
+//     }
+class MOZ_STACK_CLASS AutoGlobalTimelineMarker
+{
+  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
+
+  // True as long as no operation has failed, eg due to OOM.
+  bool mOk;
+
+  // The set of docshells that are being observed and will get markers.
+  mozilla::Vector<nsRefPtr<nsDocShell>> mDocShells;
+
+  // The name of the marker we are adding.
+  const char* mName;
+
+  void PopulateDocShells();
+
+public:
+  explicit AutoGlobalTimelineMarker(const char* aName
+                                    MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+
+  ~AutoGlobalTimelineMarker();
+
+  AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
+  void operator=(const AutoGlobalTimelineMarker& aOther) = delete;
+};
+
 } // namespace mozilla
 
 #endif /* AutoTimelineMarker_h__ */
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -43,16 +43,17 @@ EXPORTS += [
 
 EXPORTS.mozilla += [
     'AutoTimelineMarker.h',
     'IHistory.h',
     'LoadContext.h',
 ]
 
 UNIFIED_SOURCES += [
+    'AutoTimelineMarker.cpp',
     'LoadContext.cpp',
     'nsAboutRedirector.cpp',
     'nsDefaultURIFixup.cpp',
     'nsDocShell.cpp',
     'nsDocShellEditorData.cpp',
     'nsDocShellEnumerator.cpp',
     'nsDocShellLoadInfo.cpp',
     'nsDocShellTransferableHooks.cpp',
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -195,16 +195,22 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/URLSearchParams.h"
 #include "nsPerformance.h"
 
 #ifdef MOZ_TOOLKIT_SEARCH
 #include "nsIBrowserSearchService.h"
 #endif
 
+#include "mozIThirdPartyUtil.h"
+// Values for the network.cookie.cookieBehavior pref are documented in
+// nsCookieService.cpp
+#define COOKIE_BEHAVIOR_ACCEPT 0 // Allow all cookies.
+#define COOKIE_BEHAVIOR_REJECT_FOREIGN 1 // Reject all third-party cookies.
+
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 //#define DEBUG_DOCSHELL_FOCUS
 #define DEBUG_PAGE_CACHE
 #endif
 
 #ifdef XP_WIN
@@ -939,17 +945,17 @@ nsDocShell::nsDocShell()
                   getpid(),
                   AssertedCast<unsigned long long>(mHistoryID));
   }
 #endif
 }
 
 nsDocShell::~nsDocShell()
 {
-  MOZ_ASSERT(!mProfileTimelineRecording);
+  MOZ_ASSERT(!IsObserved());
 
   Destroy();
 
   nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory));
   if (shPrivate) {
     shPrivate->SetRootDocShell(nullptr);
   }
 
@@ -2922,40 +2928,47 @@ nsDocShell::HistoryTransactionRemoved(in
     }
   }
 
   return NS_OK;
 }
 
 unsigned long nsDocShell::gProfileTimelineRecordingsCount = 0;
 
+mozilla::LinkedList<nsDocShell::ObservedDocShell>* nsDocShell::gObservedDocShells = nullptr;
+
 NS_IMETHODIMP
 nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
 {
   bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
   if (currentValue != aValue) {
     if (aValue) {
       ++gProfileTimelineRecordingsCount;
       UseEntryScriptProfiling();
-      mProfileTimelineRecording = true;
+
+      MOZ_ASSERT(!mObserved);
+      mObserved.reset(new ObservedDocShell(this));
+      GetOrCreateObservedDocShells().insertFront(mObserved.get());
     } else {
       --gProfileTimelineRecordingsCount;
       UnuseEntryScriptProfiling();
-      mProfileTimelineRecording = false;
+
+      mObserved.reset(nullptr);
+
       ClearProfileTimelineMarkers();
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetRecordProfileTimelineMarkers(bool* aValue)
 {
-  *aValue = mProfileTimelineRecording;
+  *aValue = IsObserved();
   return NS_OK;
 }
 
 nsresult
 nsDocShell::PopProfileTimelineMarkers(
     JSContext* aCx,
     JS::MutableHandle<JS::Value> aProfileTimelineMarkers)
 {
@@ -3085,26 +3098,26 @@ nsDocShell::Now(DOMHighResTimeStamp* aWh
     (TimeStamp::Now() - TimeStamp::ProcessCreation(ignore)).ToMilliseconds();
   return NS_OK;
 }
 
 void
 nsDocShell::AddProfileTimelineMarker(const char* aName,
                                      TracingMetadata aMetaData)
 {
-  if (mProfileTimelineRecording) {
+  if (IsObserved()) {
     TimelineMarker* marker = new TimelineMarker(this, aName, aMetaData);
     mProfileTimelineMarkers.AppendElement(marker);
   }
 }
 
 void
 nsDocShell::AddProfileTimelineMarker(UniquePtr<TimelineMarker>&& aMarker)
 {
-  if (mProfileTimelineRecording) {
+  if (IsObserved()) {
     mProfileTimelineMarkers.AppendElement(Move(aMarker));
   }
 }
 
 NS_IMETHODIMP
 nsDocShell::SetWindowDraggingAllowed(bool aValue)
 {
   nsRefPtr<nsDocShell> parent = GetParentDocshell();
@@ -14039,16 +14052,42 @@ nsDocShell::ShouldPrepareForIntercept(ns
     return NS_OK;
   }
 
   nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   if (!swm) {
     return NS_OK;
   }
 
+  nsresult result;
+  nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
+    do_GetService(THIRDPARTYUTIL_CONTRACTID, &result);
+  NS_ENSURE_SUCCESS(result, result);
+
+  if (mCurrentURI) {
+    nsAutoCString uriSpec;
+    mCurrentURI->GetSpec(uriSpec);
+    if (!(uriSpec.EqualsLiteral("about:blank"))) {
+      // Reject the interception of third-party iframes if the cookie behaviour
+      // is set to reject all third-party cookies (1). In case that this pref
+      // is not set or can't be read, we default to allow all cookies (0) as
+      // this is the default value in all.js.
+      bool isThirdPartyURI = true;
+      result = thirdPartyUtil->IsThirdPartyURI(mCurrentURI, aURI,
+                                               &isThirdPartyURI);
+      NS_ENSURE_SUCCESS(result, result);
+      if (isThirdPartyURI &&
+          (Preferences::GetInt("network.cookie.cookieBehavior",
+                               COOKIE_BEHAVIOR_ACCEPT) ==
+                               COOKIE_BEHAVIOR_REJECT_FOREIGN)) {
+        return NS_OK;
+      }
+    }
+  }
+
   if (aIsNavigate) {
     OriginAttributes attrs(GetAppId(), GetIsInBrowserElement());
     *aShouldIntercept = swm->IsAvailable(attrs, aURI);
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc = GetDocument();
   if (!doc) {
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -18,16 +18,17 @@
 #include "nsIContentViewerContainer.h"
 #include "nsIDOMStorageManager.h"
 #include "nsDocLoader.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "GeckoProfiler.h"
 #include "mozilla/dom/ProfileTimelineMarkerBinding.h"
+#include "mozilla/LinkedList.h"
 #include "jsapi.h"
 
 // Helper Classes
 #include "nsCOMPtr.h"
 #include "nsPoint.h" // mCurrent/mDefaultScrollbarPreferences
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
@@ -261,16 +262,53 @@ public:
   // See nsIDocShell::recordProfileTimelineMarkers
   void AddProfileTimelineMarker(const char* aName, TracingMetadata aMetaData);
   void AddProfileTimelineMarker(mozilla::UniquePtr<TimelineMarker>&& aMarker);
 
   // Global counter for how many docShells are currently recording profile
   // timeline markers
   static unsigned long gProfileTimelineRecordingsCount;
 
+  class ObservedDocShell : public mozilla::LinkedListElement<ObservedDocShell>
+  {
+  public:
+    explicit ObservedDocShell(nsDocShell* aDocShell)
+      : mDocShell(aDocShell)
+    { }
+
+    nsDocShell* operator*() const { return mDocShell.get(); }
+
+  private:
+    nsRefPtr<nsDocShell> mDocShell;
+  };
+
+private:
+  static mozilla::LinkedList<ObservedDocShell>* gObservedDocShells;
+
+  static mozilla::LinkedList<ObservedDocShell>& GetOrCreateObservedDocShells()
+  {
+    if (!gObservedDocShells) {
+      gObservedDocShells = new mozilla::LinkedList<ObservedDocShell>();
+    }
+    return *gObservedDocShells;
+  }
+
+  // Never null if timeline markers are being observed.
+  mozilla::UniquePtr<ObservedDocShell> mObserved;
+
+  // Return true if timeline markers are being observed for this docshell. False
+  // otherwise.
+  bool IsObserved() const { return !!mObserved; }
+
+public:
+  static const mozilla::LinkedList<ObservedDocShell>& GetObservedDocShells()
+  {
+    return GetOrCreateObservedDocShells();
+  }
+
   // Tell the favicon service that aNewURI has the same favicon as aOldURI.
   static void CopyFavicon(nsIURI* aOldURI,
                           nsIURI* aNewURI,
                           bool aInPrivateBrowsing);
 
 protected:
   virtual ~nsDocShell();
   virtual void DestroyChildren() override;
@@ -968,19 +1006,16 @@ private:
   nsTObserverArray<nsWeakPtr> mScrollObservers;
   nsCString mOriginalUriString;
   nsWeakPtr mOpener;
 
   // A depth count of how many times NotifyRunToCompletionStart
   // has been called without a matching NotifyRunToCompletionStop.
   uint32_t mJSRunToCompletionDepth;
 
-  // True if recording profiles.
-  bool mProfileTimelineRecording;
-
   nsTArray<mozilla::UniquePtr<TimelineMarker>> mProfileTimelineMarkers;
 
   // Get rid of all the timeline markers accumulated so far
   void ClearProfileTimelineMarkers();
 
   // Separate function to do the actual name (i.e. not _top, _self etc.)
   // searching for FindItemWithName.
   nsresult DoFindItemWithName(const char16_t* aName,
--- a/docshell/test/browser/frame-head.js
+++ b/docshell/test/browser/frame-head.js
@@ -66,16 +66,20 @@ this.timelineContentTest = function(test
       docShell.popProfileTimelineMarkers();
 
       info("Running the test setup function");
       let onMarkers = timelineWaitForMarkers(docShell, searchFor);
       setup(docShell);
       info("Waiting for new markers on the docShell");
       let markers = yield onMarkers;
 
+      // Cycle collection markers are non-deterministic, and none of these tests
+      // expect them to show up.
+      markers = markers.filter(m => m.name.indexOf("nsCycleCollector") === -1);
+
       info("Running the test check function");
       check(markers);
     }
 
     info("Stop recording");
     docShell.recordProfileTimelineMarkers = false;
     finish();
   });
--- a/dom/base/TextInputProcessor.cpp
+++ b/dom/base/TextInputProcessor.cpp
@@ -181,17 +181,24 @@ TextInputProcessor::BeginInputTransactio
   // dispatching an event, it'll fail to steal its ownership.  Then, we should
   // not throw an exception, just return false.
   if (dispatcher->IsComposing() || dispatcher->IsDispatchingEvent()) {
     return NS_OK;
   }
 
   // This instance has finished preparing to link to the dispatcher.  Therefore,
   // let's forget the old dispatcher and purpose.
-  UnlinkFromTextEventDispatcher();
+  if (mDispatcher) {
+    mDispatcher->EndInputTransaction(this);
+    if (NS_WARN_IF(mDispatcher)) {
+      // Forcibly initialize the members if we failed to end the input
+      // transaction.
+      UnlinkFromTextEventDispatcher();
+    }
+  }
 
   if (aForTests) {
     rv = dispatcher->BeginInputTransactionForTests(this);
   } else {
     rv = dispatcher->BeginInputTransaction(this);
   }
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -134,19 +134,35 @@ URL::CreateObjectURL(const GlobalObject&
 }
 
 void
 URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
                      const objectURLOptions& aOptions,
                      nsAString& aResult,
                      ErrorResult& aError)
 {
-  CreateObjectURLInternal(aGlobal, &aSource,
-                          NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME), aOptions,
-                          aResult, aError);
+  nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
+
+  nsCString url;
+  nsresult rv = nsHostObjectProtocolHandler::
+    AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME),
+                 &aSource, principal, url);
+  if (NS_FAILED(rv)) {
+    aError.Throw(rv);
+    return;
+  }
+
+  nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
+    [url] {
+      nsHostObjectProtocolHandler::RemoveDataEntry(url);
+    });
+
+  nsContentUtils::RunInStableState(revocation.forget());
+
+  CopyASCIItoUTF16(url, aResult);
 }
 
 void
 URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
                              const nsACString& aScheme,
                              const objectURLOptions& aOptions,
                              nsAString& aResult, ErrorResult& aRv)
 {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -87,16 +87,17 @@
 #include "nsError.h"
 #include "nsFocusManager.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGenericHTMLFrameElement.h"
 #include "nsGkAtoms.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "nsHtml5Module.h"
 #include "nsHtml5StringParser.h"
+#include "nsIAppShell.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsICategoryManager.h"
 #include "nsIChannelEventSink.h"
 #include "nsICharsetDetectionObserver.h"
 #include "nsIChromeRegistry.h"
 #include "nsIConsoleService.h"
 #include "nsIContent.h"
 #include "nsIContentSecurityPolicy.h"
@@ -177,16 +178,17 @@
 #include "nsTextEditorState.h"
 #include "nsTextFragment.h"
 #include "nsTextNode.h"
 #include "nsThreadUtils.h"
 #include "nsUnicharUtilCIID.h"
 #include "nsUnicodeProperties.h"
 #include "nsViewManager.h"
 #include "nsViewportInfo.h"
+#include "nsWidgetsCID.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsXULPopupManager.h"
 #include "xpcprivate.h" // nsXPConnect
 #include "HTMLSplitOnSpacesTokenizer.h"
 #include "nsContentTypeParser.h"
 
 #include "nsIBidiKeyboard.h"
 
@@ -332,16 +334,17 @@ static const nsAttrValue::EnumTable kAut
   #undef AUTOCOMPLETE_FIELD_CONTACT_HINT
   { 0 }
 };
 
 namespace {
 
 static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
+static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 static PLDHashTable* sEventListenerManagersHash;
 
 class DOMEventListenerManagersHashReporter final : public nsIMemoryReporter
 {
   MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
 
   ~DOMEventListenerManagersHashReporter() {}
@@ -5143,16 +5146,30 @@ nsContentUtils::AddScriptRunner(nsIRunna
   }
   
   nsCOMPtr<nsIRunnable> run = aRunnable;
   run->Run();
 
   return true;
 }
 
+/* static */
+void
+nsContentUtils::RunInStableState(already_AddRefed<nsIRunnable> aRunnable,
+                                 DispatchFailureHandling aHandling)
+{
+  nsCOMPtr<nsIRunnable> runnable = aRunnable;
+  nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
+  if (!appShell) {
+    MOZ_ASSERT(aHandling == DispatchFailureHandling::IgnoreFailure);
+    return;
+  }
+  appShell->RunInStableState(runnable.forget());
+}
+
 void
 nsContentUtils::EnterMicroTask()
 {
   MOZ_ASSERT(NS_IsMainThread());
   ++sMicroTaskLevel;
 }
 
 void
@@ -7409,17 +7426,19 @@ nsContentUtils::TransferableToIPCTransfe
   }
 }
 
 mozilla::UniquePtr<char[]>
 nsContentUtils::GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
                                size_t* aLength, int32_t* aStride)
 {
   mozilla::gfx::DataSourceSurface::MappedSurface map;
-  aSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
+  if (NS_WARN_IF(!aSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map))) {
+    return nullptr;
+  }
   mozilla::gfx::IntSize size = aSurface->GetSize();
   mozilla::CheckedInt32 requiredBytes =
     mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
   size_t maxBufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
   mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
 
   // Surface data handling is totally nuts. This is the magic one needs to
   // know to access the data.
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1572,16 +1572,37 @@ public:
   /**
    * Call this function if !IsSafeToRunScript() and we fail to run the script
    * (rather than using AddScriptRunner as we usually do). |aDocument| is
    * optional as it is only used for showing the URL in the console.
    */
   static void WarnScriptWasIgnored(nsIDocument* aDocument);
 
   /**
+   * Whether to assert that RunInStableState() succeeds, or ignore failure,
+   * which may happen late in shutdown.
+   */
+  enum class DispatchFailureHandling { AssertSuccess, IgnoreFailure };
+
+  /**
+   * Add a "synchronous section", in the form of an nsIRunnable run once the
+   * event loop has reached a "stable state". |aRunnable| must not cause any
+   * queued events to be processed (i.e. must not spin the event loop).
+   * We've reached a stable state when the currently executing task/event has
+   * finished, see
+   * http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
+   * In practice this runs aRunnable once the currently executing event
+   * finishes. If called multiple times per task/event, all the runnables will
+   * be executed, in the order in which RunInStableState() was called.
+   */
+  static void RunInStableState(already_AddRefed<nsIRunnable> aRunnable,
+                               DispatchFailureHandling aHandling =
+                                 DispatchFailureHandling::AssertSuccess);
+
+  /**
    * Retrieve information about the viewport as a data structure.
    * This will return information in the viewport META data section
    * of the document. This can be used in lieu of ProcessViewportInfo(),
    * which places the viewport information in the document header instead
    * of returning it directly.
    *
    * @param aDisplayWidth width of the on-screen display area for this
    * document, in device pixels.
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1504,42 +1504,47 @@ nsDOMWindowUtils::CompareCanvases(nsIDOM
   if (aCanvas1 == nullptr ||
       aCanvas2 == nullptr ||
       retVal == nullptr)
     return NS_ERROR_FAILURE;
 
   RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(aCanvas1);
   RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(aCanvas2);
 
+  DataSourceSurface::ScopedMap map1(img1, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap map2(img2, DataSourceSurface::READ);
+
   if (img1 == nullptr || img2 == nullptr ||
+      !map1.IsMapped() || !map2.IsMapped() ||
       img1->GetSize() != img2->GetSize() ||
-      img1->Stride() != img2->Stride())
+      map1.GetStride() != map2.GetStride()) {
     return NS_ERROR_FAILURE;
+  }
 
   int v;
   IntSize size = img1->GetSize();
-  uint32_t stride = img1->Stride();
+  int32_t stride = map1.GetStride();
 
   // we can optimize for the common all-pass case
-  if (stride == (uint32_t) size.width * 4) {
-    v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4);
+  if (stride == size.width * 4) {
+    v = memcmp(map1.GetData(), map2.GetData(), size.width * size.height * 4);
     if (v == 0) {
       if (aMaxDifference)
         *aMaxDifference = 0;
       *retVal = 0;
       return NS_OK;
     }
   }
 
   uint32_t dc = 0;
   uint32_t different = 0;
 
   for (int j = 0; j < size.height; j++) {
-    unsigned char *p1 = img1->GetData() + j*stride;
-    unsigned char *p2 = img2->GetData() + j*stride;
+    unsigned char *p1 = map1.GetData() + j*stride;
+    unsigned char *p2 = map2.GetData() + j*stride;
     v = memcmp(p1, p2, stride);
 
     if (v) {
       for (int i = 0; i < size.width; i++) {
         if (*(uint32_t*) p1 != *(uint32_t*) p2) {
 
           different++;
 
@@ -3436,26 +3441,24 @@ nsDOMWindowUtils::DispatchEventToChromeO
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
   NS_ENSURE_STATE(aTarget && aEvent);
   aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
   aTarget->DispatchEvent(aEvent, aRetVal);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable)
+nsDOMWindowUtils::RunInStableState(nsIRunnable *aRunnable)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
-  nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
-  if (!appShell) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  return appShell->RunInStableState(runnable);
+  nsCOMPtr<nsIRunnable> runnable = aRunnable;
+  nsContentUtils::RunInStableState(runnable.forget());
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -706,27 +706,16 @@ nsIdentifierMapEntry::SizeOfExcludingThi
 class SubDocMapEntry : public PLDHashEntryHdr
 {
 public:
   // Both of these are strong references
   Element *mKey; // must be first, to look like PLDHashEntryStub
   nsIDocument *mSubDocument;
 };
 
-struct FindContentData
-{
-  explicit FindContentData(nsIDocument* aSubDoc)
-    : mSubDocument(aSubDoc), mResult(nullptr)
-  {
-  }
-
-  nsISupports *mSubDocument;
-  Element *mResult;
-};
-
 
 /**
  * A struct that holds all the information about a radio group.
  */
 struct nsRadioGroupStruct
 {
   nsRadioGroupStruct()
     : mRequiredRadioCount(0)
@@ -1854,32 +1843,16 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_
   return Element::CanSkipInCC(tmp);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDocument)
   return Element::CanSkipThis(tmp);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 static PLDHashOperator
-SubDocTraverser(PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number,
-                void *arg)
-{
-  SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
-  nsCycleCollectionTraversalCallback *cb =
-    static_cast<nsCycleCollectionTraversalCallback*>(arg);
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mSubDocuments entry->mKey");
-  cb->NoteXPCOMChild(entry->mKey);
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mSubDocuments entry->mSubDocument");
-  cb->NoteXPCOMChild(entry->mSubDocument);
-
-  return PL_DHASH_NEXT;
-}
-
-static PLDHashOperator
 RadioGroupsTraverser(const nsAString& aKey, nsRadioGroupStruct* aData,
                      void* aClosure)
 {
   nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
                                    "mRadioGroups entry->mSelectedRadioButton");
@@ -2028,17 +2001,27 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   }
 
   // Traverse animation components
   if (tmp->mAnimationController) {
     tmp->mAnimationController->Traverse(&cb);
   }
 
   if (tmp->mSubDocuments) {
-    PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
+    PLDHashTable::Iterator iter(tmp->mSubDocuments);
+    while (iter.HasMoreEntries()) {
+      auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
+
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+                                         "mSubDocuments entry->mKey");
+      cb.NoteXPCOMChild(entry->mKey);
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+                                         "mSubDocuments entry->mSubDocument");
+      cb.NoteXPCOMChild(entry->mSubDocument);
+    }
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
 
   // We own only the items in mDOMMediaQueryLists that have listeners;
   // this reference is managed by their AddListener and RemoveListener
   // methods.
   for (PRCList *l = PR_LIST_HEAD(&tmp->mDOMMediaQueryLists);
@@ -4026,45 +4009,33 @@ nsDocument::GetSubDocumentFor(nsIContent
     if (entry) {
       return entry->mSubDocument;
     }
   }
 
   return nullptr;
 }
 
-static PLDHashOperator
-FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                      uint32_t number, void *arg)
-{
-  SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
-  FindContentData *data = static_cast<FindContentData*>(arg);
-
-  if (entry->mSubDocument == data->mSubDocument) {
-    data->mResult = entry->mKey;
-
-    return PL_DHASH_STOP;
-  }
-
-  return PL_DHASH_NEXT;
-}
-
 Element*
 nsDocument::FindContentForSubDocument(nsIDocument *aDocument) const
 {
   NS_ENSURE_TRUE(aDocument, nullptr);
 
   if (!mSubDocuments) {
     return nullptr;
   }
 
-  FindContentData data(aDocument);
-  PL_DHashTableEnumerate(mSubDocuments, FindContentEnumerator, &data);
-
-  return data.mResult;
+  PLDHashTable::Iterator iter(mSubDocuments);
+  while (iter.HasMoreEntries()) {
+    auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
+    if (entry->mSubDocument == aDocument) {
+      return entry->mKey;
+    }
+  }
+  return nullptr;
 }
 
 bool
 nsDocument::IsNodeOfType(uint32_t aFlags) const
 {
     return !(aFlags & ~eDOCUMENT);
 }
 
@@ -8734,55 +8705,32 @@ nsDocument::Sanitize()
 }
 
 struct SubDocEnumArgs
 {
   nsIDocument::nsSubDocEnumFunc callback;
   void *data;
 };
 
-static PLDHashOperator
-SubDocHashEnum(PLDHashTable *table, PLDHashEntryHdr *hdr,
-               uint32_t number, void *arg)
-{
-  SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
-  SubDocEnumArgs *args = static_cast<SubDocEnumArgs*>(arg);
-
-  nsIDocument *subdoc = entry->mSubDocument;
-  bool next = subdoc ? args->callback(subdoc, args->data) : true;
-
-  return next ? PL_DHASH_NEXT : PL_DHASH_STOP;
-}
-
 void
 nsDocument::EnumerateSubDocuments(nsSubDocEnumFunc aCallback, void *aData)
 {
-  if (mSubDocuments) {
-    SubDocEnumArgs args = { aCallback, aData };
-    PL_DHashTableEnumerate(mSubDocuments, SubDocHashEnum, &args);
-  }
-}
-
-static PLDHashOperator
-CanCacheSubDocument(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                    uint32_t number, void *arg)
-{
-  SubDocMapEntry *entry = static_cast<SubDocMapEntry*>(hdr);
-  bool *canCacheArg = static_cast<bool*>(arg);
-
-  nsIDocument *subdoc = entry->mSubDocument;
-
-  // The aIgnoreRequest we were passed is only for us, so don't pass it on.
-  bool canCache = subdoc ? subdoc->CanSavePresentation(nullptr) : false;
-  if (!canCache) {
-    *canCacheArg = false;
-    return PL_DHASH_STOP;
-  }
-
-  return PL_DHASH_NEXT;
+  if (!mSubDocuments) {
+    return;
+  }
+
+  PLDHashTable::Iterator iter(mSubDocuments);
+  while (iter.HasMoreEntries()) {
+    auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
+    nsIDocument* subdoc = entry->mSubDocument;
+    bool next = subdoc ? aCallback(subdoc, aData) : true;
+    if (!next) {
+      break;
+    }
+  }
 }
 
 #ifdef DEBUG_bryner
 #define DEBUG_PAGE_CACHE
 #endif
 
 bool
 nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
@@ -8873,21 +8821,31 @@ nsDocument::CanSavePresentation(nsIReque
 #endif
 
   // Don't save presentations for documents containing MSE content, to
   // reduce memory usage.
   if (ContainsMSEContent()) {
     return false;
   }
 
-  bool canCache = true;
-  if (mSubDocuments)
-    PL_DHashTableEnumerate(mSubDocuments, CanCacheSubDocument, &canCache);
-
-  return canCache;
+  if (mSubDocuments) {
+    PLDHashTable::Iterator iter(mSubDocuments);
+    while (iter.HasMoreEntries()) {
+      auto entry = static_cast<SubDocMapEntry*>(iter.NextEntry());
+      nsIDocument* subdoc = entry->mSubDocument;
+
+      // The aIgnoreRequest we were passed is only for us, so don't pass it on.
+      bool canCache = subdoc ? subdoc->CanSavePresentation(nullptr) : false;
+      if (!canCache) {
+        return false;
+      }
+    }
+  }
+
+  return true;
 }
 
 void
 nsDocument::Destroy()
 {
   // The ContentViewer wants to release the document now.  So, tell our content
   // to drop any references to the document so that it can be destroyed.
   if (mIsGoingAway)
--- a/dom/base/nsPropertyTable.cpp
+++ b/dom/base/nsPropertyTable.cpp
@@ -128,40 +128,26 @@ nsPropertyTable::Enumerate(nsPropertyOwn
       (PL_DHashTableSearch(&prop->mObjectValueMap, aObject));
     if (entry) {
       aCallback(const_cast<void*>(aObject.get()), prop->mName, entry->value,
                 aData);
     }
   }
 }
 
-struct PropertyEnumeratorData
-{
-  nsIAtom* mName;
-  NSPropertyFunc mCallBack;
-  void* mData;
-};
-
-static PLDHashOperator
-PropertyEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
-                   uint32_t aNumber, void* aArg)
-{
-  PropertyListMapEntry* entry = static_cast<PropertyListMapEntry*>(aHdr);
-  PropertyEnumeratorData* data = static_cast<PropertyEnumeratorData*>(aArg);
-  data->mCallBack(const_cast<void*>(entry->key), data->mName, entry->value,
-                  data->mData);
-  return PL_DHASH_NEXT;
-}
-
 void
 nsPropertyTable::EnumerateAll(NSPropertyFunc aCallBack, void* aData)
 {
   for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) {
-    PropertyEnumeratorData data = { prop->mName, aCallBack, aData };
-    PL_DHashTableEnumerate(&prop->mObjectValueMap, PropertyEnumerator, &data);
+    PLDHashTable::Iterator iter(&prop->mObjectValueMap);
+    while (iter.HasMoreEntries()) {
+      auto entry = static_cast<PropertyListMapEntry*>(iter.NextEntry());
+      aCallBack(const_cast<void*>(entry->key), prop->mName, entry->value,
+                aData);
+    }
   }
 }
 
 void*
 nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject,
                                      nsIAtom    *aPropertyName,
                                      bool        aRemove,
                                      nsresult   *aResult)
@@ -289,35 +275,27 @@ nsPropertyTable::PropertyList::PropertyL
     mNext(nullptr)
 {
 }
 
 nsPropertyTable::PropertyList::~PropertyList()
 {
 }
 
-static PLDHashOperator
-DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                          uint32_t number, void *arg)
-{
-  nsPropertyTable::PropertyList *propList =
-      static_cast<nsPropertyTable::PropertyList*>(arg);
-  PropertyListMapEntry* entry = static_cast<PropertyListMapEntry*>(hdr);
-
-  propList->mDtorFunc(const_cast<void*>(entry->key), propList->mName,
-                      entry->value, propList->mDtorData);
-  return PL_DHASH_NEXT;
-}
-
 void
 nsPropertyTable::PropertyList::Destroy()
 {
-  // Enumerate any remaining object/value pairs and destroy the value object
-  if (mDtorFunc)
-    PL_DHashTableEnumerate(&mObjectValueMap, DestroyPropertyEnumerator, this);
+  // Enumerate any remaining object/value pairs and destroy the value object.
+  if (mDtorFunc) {
+    PLDHashTable::Iterator iter(&mObjectValueMap);
+    while (iter.HasMoreEntries()) {
+      auto entry = static_cast<PropertyListMapEntry*>(iter.NextEntry());
+      mDtorFunc(const_cast<void*>(entry->key), mName, entry->value, mDtorData);
+    }
+  }
 }
 
 bool
 nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject)
 {
   PropertyListMapEntry *entry =
       static_cast<PropertyListMapEntry*>
                  (PL_DHashTableSearch(&mObjectValueMap, aObject));
--- a/dom/base/nsReferencedElement.cpp
+++ b/dom/base/nsReferencedElement.cpp
@@ -42,17 +42,17 @@ nsReferencedElement::Reset(nsIContent* a
     // assumes UTF-8 and doesn't handle UTF-8 errors.
     // https://bugzilla.mozilla.org/show_bug.cgi?id=951082
     CopyUTF8toUTF16(refPart, ref);
   }
   if (ref.IsEmpty())
     return;
 
   // Get the current document
-  nsIDocument *doc = aFromContent->GetComposedDoc();
+  nsIDocument *doc = aFromContent->OwnerDoc();
   if (!doc)
     return;
 
   nsIContent* bindingParent = aFromContent->GetBindingParent();
   if (bindingParent) {
     nsXBLBinding* binding = bindingParent->GetXBLBinding();
     if (binding) {
       bool isEqualExceptRef;
@@ -119,17 +119,17 @@ nsReferencedElement::Reset(nsIContent* a
 
   HaveNewDocument(doc, aWatch, ref);
 }
 
 void
 nsReferencedElement::ResetWithID(nsIContent* aFromContent, const nsString& aID,
                                  bool aWatch)
 {
-  nsIDocument *doc = aFromContent->GetComposedDoc();
+  nsIDocument *doc = aFromContent->OwnerDoc();
   if (!doc)
     return;
 
   // XXX Need to take care of XBL/XBL2
 
   if (aWatch) {
     nsCOMPtr<nsIAtom> atom = do_GetAtom(aID);
     if (!atom)
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -3200,16 +3200,22 @@ class IDLInterfaceMember(IDLObjectWithId
 
         if self.isAttr() or self.isMethod():
             if self.affects == "Everything" and self.dependsOn != "Everything":
                 raise WebIDLError("Interface member is flagged as affecting "
                                   "everything but not depending on everything. "
                                   "That seems rather unlikely.",
                                   [self.location])
 
+        if self.getExtendedAttribute("NewObject"):
+            if self.dependsOn == "Nothing" or self.dependsOn == "DOMState":
+                raise WebIDLError("A [NewObject] method is not idempotent, " 
+                                  "so it has to depend on something other than DOM state.",
+                                  [self.location])
+
     def _setDependsOn(self, dependsOn):
         if self.dependsOn != "Everything":
             raise WebIDLError("Trying to specify multiple different DependsOn, "
                               "Pure, or Constant extended attributes for "
                               "attribute", [self.location])
         if dependsOn not in IDLInterfaceMember.DependsOnValues:
             raise WebIDLError("Invalid [DependsOn=%s] on attribute" % dependsOn,
                               [self.location])
--- a/dom/bluetooth/BluetoothUtils.cpp
+++ b/dom/bluetooth/BluetoothUtils.cpp
@@ -38,27 +38,16 @@ UuidToString(const BluetoothUuid& aUuid,
            ntohs(uuid2), ntohs(uuid3),
            ntohl(uuid4), ntohs(uuid5));
 
   aString.Truncate();
   aString.AssignLiteral(uuidStr);
 }
 
 void
-ReversedUuidToString(const BluetoothUuid& aUuid, nsAString& aString)
-{
-  BluetoothUuid uuid;
-  for (uint8_t i = 0; i < 16; i++) {
-    uuid.mUuid[i] = aUuid.mUuid[15 - i];
-  }
-
-  UuidToString(uuid, aString);
-}
-
-void
 StringToUuid(const char* aString, BluetoothUuid& aUuid)
 {
   uint32_t uuid0, uuid4;
   uint16_t uuid1, uuid2, uuid3, uuid5;
 
   sscanf(aString, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
          &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
 
@@ -95,32 +84,24 @@ GenerateUuid(nsAString &aUuidString)
   NS_ConvertASCIItoUTF16 uuidString(uuidBuffer);
 
   // Remove {} and the null terminator
   aUuidString.Assign(Substring(uuidString, 1, NSID_LENGTH - 3));
 }
 
 void
 GeneratePathFromGattId(const BluetoothGattId& aId,
-                       nsAString& aPath,
-                       nsAString& aUuidStr)
-{
-  ReversedUuidToString(aId.mUuid, aUuidStr);
-
-  aPath.Assign(aUuidStr);
-  aPath.AppendLiteral("_");
-  aPath.AppendInt(aId.mInstanceId);
-}
-
-void
-GeneratePathFromGattId(const BluetoothGattId& aId,
                        nsAString& aPath)
 {
   nsString uuidStr;
-  GeneratePathFromGattId(aId, aPath, uuidStr);
+  UuidToString(aId.mUuid, uuidStr);
+
+  aPath.Assign(uuidStr);
+  aPath.AppendLiteral("_");
+  aPath.AppendInt(aId.mInstanceId);
 }
 
 void
 RegisterBluetoothSignalHandler(const nsAString& aPath,
                                BluetoothSignalObserver* aHandler)
 {
   MOZ_ASSERT(!aPath.IsEmpty());
   MOZ_ASSERT(aHandler);
--- a/dom/bluetooth/BluetoothUtils.h
+++ b/dom/bluetooth/BluetoothUtils.h
@@ -25,29 +25,16 @@ class BluetoothValue;
  *
  * Note: This utility function is used by gecko internal only to convert
  * BluetoothUuid created by bluetooth stack to uuid string representation.
  */
 void
 UuidToString(const BluetoothUuid& aUuid, nsAString& aString);
 
 /**
- * Convert BluetoothUuid object in a reversed byte order to
- * xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string.
- * Bluedroid stack reports the BluetoothUuid in a reversed byte order for
- * GATT service, characteristic, descriptor uuids.
- *
- * Note: This utility function is used by gecko internal only to convert
- * BluetoothUuid in a reversed byte order created by bluetooth stack to uuid
- * string representation.
- */
-void
-ReversedUuidToString(const BluetoothUuid& aUuid, nsAString& aString);
-
-/**
  * Convert xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string to BluetoothUuid object.
  *
  * Note: This utility function is used by gecko internal only to convert uuid
  * string created by gecko back to BluetoothUuid representation.
  */
 void
 StringToUuid(const char* aString, BluetoothUuid& aUuid);
 
@@ -59,28 +46,16 @@ StringToUuid(const char* aString, Blueto
 void
 GenerateUuid(nsAString &aUuidString);
 
 //
 // Generate bluetooth signal path from GattId
 //
 
 /**
- * Generate bluetooth signal path and UUID string from a GattId.
- *
- * @param aId      [in] GattId value to convert.
- * @param aPath    [out] Bluetooth signal path generated from aId.
- * @param aUuidStr [out] UUID string generated from aId.
- */
-void
-GeneratePathFromGattId(const BluetoothGattId& aId,
-                       nsAString& aPath,
-                       nsAString& aUuidStr);
-
-/**
  * Generate bluetooth signal path from a GattId.
  *
  * @param aId   [in] GattId value to convert.
  * @param aPath [out] Bluetooth signal path generated from aId.
  */
 void
 GeneratePathFromGattId(const BluetoothGattId& aId,
                        nsAString& aPath);
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
@@ -254,17 +254,19 @@ BluetoothDaemonGattModule::ClientSearchS
 
   nsAutoPtr<BluetoothDaemonPDU> pdu(
     new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CLIENT_SEARCH_SERVICE,
                            4 + // Connection ID
                            1 + // Filtered
                            16)); // UUID
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aConnId),
-                        PackConversion<bool, uint8_t>(aFiltered), aUuid, *pdu);
+                        PackConversion<bool, uint8_t>(aFiltered),
+                        PackReversed<BluetoothUuid>(aUuid),
+                        *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp
@@ -1404,17 +1404,17 @@ PackPDU(const BluetoothUuid& aIn, Blueto
 {
   return PackPDU(
     PackArray<uint8_t>(aIn.mUuid, sizeof(aIn.mUuid)), aPDU);
 }
 
 nsresult
 PackPDU(const BluetoothGattId& aIn, BluetoothDaemonPDU& aPDU)
 {
-  nsresult rv = PackPDU(aIn.mUuid, aPDU);
+  nsresult rv = PackPDU(PackReversed<BluetoothUuid>(aIn.mUuid), aPDU);
   if (NS_FAILED(rv)) {
     return rv;
   }
   return PackPDU(aIn.mInstanceId, aPDU);
 }
 
 nsresult
 PackPDU(const BluetoothGattServiceId& aIn, BluetoothDaemonPDU& aPDU)
@@ -1729,17 +1729,17 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, Blue
 {
   return UnpackPDU(aPDU, UnpackConversion<int32_t, BluetoothGattStatus>(aOut));
 }
 
 nsresult
 UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattId& aOut)
 {
   /* unpack UUID */
-  nsresult rv = UnpackPDU(aPDU, aOut.mUuid);
+  nsresult rv = UnpackPDU(aPDU, UnpackReversed<BluetoothUuid>(aOut.mUuid));
   if (NS_FAILED(rv)) {
     return rv;
   }
   /* unpack instance id */
   return UnpackPDU(aPDU, aOut.mInstanceId);
 }
 
 nsresult
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
@@ -574,16 +574,67 @@ struct PackCString0
 inline nsresult
 PackPDU(const PackCString0& aIn, BluetoothDaemonPDU& aPDU)
 {
   return PackPDU(
     PackArray<uint8_t>(reinterpret_cast<const uint8_t*>(aIn.mString.get()),
                        aIn.mString.Length() + 1), aPDU);
 }
 
+/* |PackReversed| is a helper for packing data in reversed order. Pass an
+ * instance of this structure as the first argument to |PackPDU| to pack data
+ * in reversed order.
+ */
+template<typename T>
+struct PackReversed
+{
+  PackReversed(const T& aValue)
+    : mValue(aValue)
+  { }
+
+  const T& mValue;
+};
+
+/* No general rules to pack data in reversed order. Signal a link error if the
+ * type |T| of |PackReversed| is not defined explicitly.
+ */
+template<typename T>
+nsresult
+PackPDU(const PackReversed<T>& aIn, BluetoothDaemonPDU& aPDU);
+
+/* This implementation of |PackPDU| packs elements in |PackArray| in reversed
+ * order. (ex. reversed GATT UUID, see bug 1171866)
+ */
+template<typename U>
+inline nsresult
+PackPDU(const PackReversed<PackArray<U>>& aIn, BluetoothDaemonPDU& aPDU)
+{
+  for (size_t i = 0; i < aIn.mValue.mLength; ++i) {
+    nsresult rv = PackPDU(aIn.mValue.mData[aIn.mValue.mLength - i - 1], aPDU);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+  }
+  return NS_OK;
+}
+
+/* This implementation of |PackPDU| packs |BluetoothUuid| in reversed order.
+ * (ex. reversed GATT UUID, see bug 1171866)
+ */
+template <>
+inline nsresult
+PackPDU<BluetoothUuid>(const PackReversed<BluetoothUuid>& aIn,
+                       BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+   PackReversed<PackArray<uint8_t>>(
+     PackArray<uint8_t>(aIn.mValue.mUuid, sizeof(aIn.mValue.mUuid))),
+   aPDU);
+}
+
 template <typename T1, typename T2>
 inline nsresult
 PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
 {
   nsresult rv = PackPDU(aIn1, aPDU);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -1094,16 +1145,69 @@ struct UnpackString0
 };
 
 /* This implementation of |UnpackPDU| unpacks a 0-terminated C string
  * and converts it to wide-character encoding.
  */
 nsresult
 UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut);
 
+/* |UnpackReversed| is a helper for unpacking data in reversed order. Pass an
+ * instance of this structure as the second argument to |UnpackPDU| to unpack
+ * data in reversed order.
+ */
+template<typename T>
+struct UnpackReversed
+{
+  UnpackReversed(T& aValue)
+    : mValue(&aValue)
+  { }
+
+  UnpackReversed(T&& aValue)
+    : mValue(&aValue)
+  { }
+
+  T* mValue;
+};
+
+/* No general rules to unpack data in reversed order. Signal a link error if
+ * the type |T| of |UnpackReversed| is not defined explicitly.
+ */
+template<typename T>
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackReversed<T>& aOut);
+
+template<typename U>
+inline nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackReversed<UnpackArray<U>>& aOut)
+{
+  for (size_t i = 0; i < aOut.mValue->mLength; ++i) {
+    nsresult rv = UnpackPDU(aPDU,
+                            aOut.mValue->mData[aOut.mValue->mLength - i - 1]);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+  }
+  return NS_OK;
+}
+
+/* This implementation of |UnpackPDU| unpacks |BluetoothUuid| in reversed
+ * order. (ex. reversed GATT UUID, see bug 1171866)
+ */
+template<>
+inline nsresult
+UnpackPDU<BluetoothUuid>(BluetoothDaemonPDU& aPDU,
+                         const UnpackReversed<BluetoothUuid>& aOut)
+{
+  return UnpackPDU(
+    aPDU,
+    UnpackReversed<UnpackArray<uint8_t>>(
+      UnpackArray<uint8_t>(aOut.mValue->mUuid, sizeof(aOut.mValue->mUuid))));
+}
+
 //
 // Init operators
 //
 
 // |PDUInitOP| provides functionality for init operators that unpack PDUs.
 class PDUInitOp
 {
 protected:
--- a/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp
@@ -229,25 +229,45 @@ Convert(const btrc_player_settings_t& aI
   return NS_OK;
 }
 #endif // ANDROID_VERSION >= 18
 
 #if ANDROID_VERSION >= 19
 nsresult
 Convert(const BluetoothGattId& aIn, btgatt_gatt_id_t& aOut)
 {
+  nsresult rv = Convert(aIn.mUuid, aOut.uuid);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  // HAL uses reversed UUID for GATT
+  for (uint8_t i = 0; i < sizeof(aOut.uuid.uu) / 2; i++) {
+    auto temp = aOut.uuid.uu[i];
+    aOut.uuid.uu[i] = aOut.uuid.uu[sizeof(aOut.uuid.uu) - i - 1];
+    aOut.uuid.uu[sizeof(aOut.uuid.uu) - i - 1] = temp;
+  }
   aOut.inst_id = aIn.mInstanceId;
-  return Convert(aIn.mUuid, aOut.uuid);
+  return NS_OK;
 }
 
 nsresult
 Convert(const btgatt_gatt_id_t& aIn, BluetoothGattId& aOut)
 {
+  nsresult rv = Convert(aIn.uuid, aOut.mUuid);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  // HAL uses reversed UUID for GATT
+  for (uint8_t i = 0; i < sizeof(aOut.mUuid.mUuid) / 2; i++) {
+    auto temp = aOut.mUuid.mUuid[i];
+    aOut.mUuid.mUuid[i] = aOut.mUuid.mUuid[sizeof(aOut.mUuid.mUuid) - i - 1];
+    aOut.mUuid.mUuid[sizeof(aOut.mUuid.mUuid) - i - 1] = temp;
+  }
   aOut.mInstanceId = aIn.inst_id;
-  return Convert(aIn.uuid, aOut.mUuid);
+  return NS_OK;
 }
 
 nsresult
 Convert(const BluetoothGattServiceId& aIn, btgatt_srvc_id_t& aOut)
 {
   aOut.is_primary = aIn.mIsPrimary;
   return Convert(aIn.mId, aOut.id);
 }
--- a/dom/bluetooth/bluetooth2/BluetoothGattCharacteristic.cpp
+++ b/dom/bluetooth/bluetooth2/BluetoothGattCharacteristic.cpp
@@ -63,20 +63,21 @@ BluetoothGattCharacteristic::BluetoothGa
   , mService(aService)
   , mCharId(aChar.mId)
   , mProperties(aChar.mProperties)
   , mWriteType(aChar.mWriteType)
 {
   MOZ_ASSERT(aOwner);
   MOZ_ASSERT(mService);
 
-  // Generate bluetooth signal path and a string representation to provide uuid
-  // of this characteristic to applications
+  UuidToString(mCharId.mUuid, mUuidStr);
+
+  // Generate bluetooth signal path of this characteristic to applications
   nsString path;
-  GeneratePathFromGattId(mCharId, path, mUuidStr);
+  GeneratePathFromGattId(mCharId, path);
   RegisterBluetoothSignalHandler(path, this);
 }
 
 BluetoothGattCharacteristic::~BluetoothGattCharacteristic()
 {
   nsString path;
   GeneratePathFromGattId(mCharId, path);
   UnregisterBluetoothSignalHandler(path, this);
--- a/dom/bluetooth/bluetooth2/BluetoothGattDescriptor.cpp
+++ b/dom/bluetooth/bluetooth2/BluetoothGattDescriptor.cpp
@@ -58,20 +58,21 @@ BluetoothGattDescriptor::BluetoothGattDe
   const BluetoothGattId& aDescriptorId)
   : mOwner(aOwner)
   , mCharacteristic(aCharacteristic)
   , mDescriptorId(aDescriptorId)
 {
   MOZ_ASSERT(aOwner);
   MOZ_ASSERT(aCharacteristic);
 
-  // Generate bluetooth signal path and a string representation to provide uuid
-  // of this descriptor to applications
+  UuidToString(mDescriptorId.mUuid, mUuidStr);
+
+  // Generate bluetooth signal path of this descriptor to applications
   nsString path;
-  GeneratePathFromGattId(mDescriptorId, path, mUuidStr);
+  GeneratePathFromGattId(mDescriptorId, path);
   RegisterBluetoothSignalHandler(path, this);
 }
 
 BluetoothGattDescriptor::~BluetoothGattDescriptor()
 {
   nsString path;
   GeneratePathFromGattId(mDescriptorId, path);
   UnregisterBluetoothSignalHandler(path, this);
--- a/dom/bluetooth/bluetooth2/BluetoothGattService.cpp
+++ b/dom/bluetooth/bluetooth2/BluetoothGattService.cpp
@@ -57,20 +57,21 @@ BluetoothGattService::BluetoothGattServi
   const BluetoothGattServiceId& aServiceId)
   : mOwner(aOwner)
   , mAppUuid(aAppUuid)
   , mServiceId(aServiceId)
 {
   MOZ_ASSERT(aOwner);
   MOZ_ASSERT(!mAppUuid.IsEmpty());
 
-  // Generate bluetooth signal path and a string representation to provide
-  // uuid of this service to applications
+  UuidToString(mServiceId.mId.mUuid, mUuidStr);
+
+  // Generate bluetooth signal path of this service to applications
   nsString path;
-  GeneratePathFromGattId(mServiceId.mId, path, mUuidStr);
+  GeneratePathFromGattId(mServiceId.mId, path);
   RegisterBluetoothSignalHandler(path, this);
 }
 
 BluetoothGattService::~BluetoothGattService()
 {
   nsString path;
   GeneratePathFromGattId(mServiceId.mId, path);
   UnregisterBluetoothSignalHandler(path, this);
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -224,17 +224,20 @@ BrowserElementChild.prototype = {
       "unblock-modal-prompt": this._recvStopWaiting,
       "fire-ctx-callback": this._recvFireCtxCallback,
       "owner-visibility-change": this._recvOwnerVisibilityChange,
       "entered-fullscreen": this._recvEnteredFullscreen,
       "exit-fullscreen": this._recvExitFullscreen.bind(this),
       "activate-next-paint-listener": this._activateNextPaintListener.bind(this),
       "set-input-method-active": this._recvSetInputMethodActive.bind(this),
       "deactivate-next-paint-listener": this._deactivateNextPaintListener.bind(this),
-      "do-command": this._recvDoCommand
+      "do-command": this._recvDoCommand,
+      "find-all": this._recvFindAll.bind(this),
+      "find-next": this._recvFindNext.bind(this),
+      "clear-match": this._recvClearMatch.bind(this),
     }
 
     addMessageListener("browser-element-api:call", function(aMessage) {
       if (aMessage.data.msg_name in mmCalls) {
         return mmCalls[aMessage.data.msg_name].apply(self, arguments);
       }
     });
 
@@ -1235,16 +1238,67 @@ BrowserElementChild.prototype = {
 
   _recvDoCommand: function(data) {
     if (this._isCommandEnabled(data.json.command)) {
       this._selectionStateChangedTarget = null;
       docShell.doCommand(COMMAND_MAP[data.json.command]);
     }
   },
 
+  _initFinder: function() {
+    if (!this._finder) {
+      try {
+        this._findLimit = Services.prefs.getIntPref("accessibility.typeaheadfind.matchesCountLimit");
+      } catch (e) {
+        // Pref not available, assume 0, no match counting.
+        this._findLimit = 0;
+      }
+
+      let {Finder} = Components.utils.import("resource://gre/modules/Finder.jsm", {});
+      this._finder = new Finder(docShell);
+      this._finder.addResultListener({
+        onMatchesCountResult: (data) => {
+          sendAsyncMsg('findchange', {
+            active: true,
+            searchString: this._finder.searchString,
+            searchLimit: this._findLimit,
+            activeMatchOrdinal: data.current,
+            numberOfMatches: data.total
+          });
+        }
+      });
+    }
+  },
+
+  _recvFindAll: function(data) {
+    this._initFinder();
+    let searchString = data.json.searchString;
+    this._finder.caseSensitive = data.json.caseSensitive;
+    this._finder.fastFind(searchString, false, false);
+    this._finder.requestMatchesCount(searchString, this._findLimit, false);
+  },
+
+  _recvFindNext: function(data) {
+    if (!this._finder) {
+      debug("findNext() called before findAll()");
+      return;
+    }
+    this._finder.findAgain(data.json.backward, false, false);
+    this._finder.requestMatchesCount(this._finder.searchString, this._findLimit, false);
+  },
+
+  _recvClearMatch: function(data) {
+    if (!this._finder) {
+      debug("clearMach() called before findAll()");
+      return;
+    }
+    this._finder.removeSelection();
+    sendAsyncMsg('findchange', {active: false});
+  },
+
   _recvSetInputMethodActive: function(data) {
     let msgData = { id: data.json.id };
     if (!this._isContentWindowCreated) {
       if (data.json.args.isActive) {
         // To activate the input method, we should wait before the content
         // window is ready.
         this._pendingSetInputMethodActive.push(data);
         return;
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -201,16 +201,17 @@ BrowserElementParent.prototype = {
       "fullscreen-origin-change": this._fullscreenOriginChange,
       "exited-dom-fullscreen": this._exitedDomFullscreen,
       "got-visible": this._gotDOMRequestResult,
       "visibilitychange": this._childVisibilityChange,
       "got-set-input-method-active": this._gotDOMRequestResult,
       "selectionstatechanged": this._handleSelectionStateChanged,
       "scrollviewchange": this._handleScrollViewChange,
       "caretstatechanged": this._handleCaretStateChanged,
+      "findchange": this._handleFindChange
     };
 
     let mmSecuritySensitiveCalls = {
       "showmodalprompt": this._handleShowModalPrompt,
       "contextmenu": this._fireCtxMenuEvent,
       "securitychange": this._fireEventFromMsg,
       "locationchange": this._fireEventFromMsg,
       "iconchange": this._fireEventFromMsg,
@@ -470,16 +471,22 @@ BrowserElementParent.prototype = {
   },
 
   _handleScrollViewChange: function(data) {
     let evt = this._createEvent("scrollviewchange", data.json,
                                 /* cancelable = */ false);
     this._frameElement.dispatchEvent(evt);
   },
 
+  _handleFindChange: function(data) {
+    let evt = this._createEvent("findchange", data.json,
+                                /* cancelable = */ false);
+    this._frameElement.dispatchEvent(evt);
+  },
+
   _createEvent: function(evtName, detail, cancelable) {
     // This will have to change if we ever want to send a CustomEvent with null
     // detail.  For now, it's OK.
     if (detail !== undefined && detail !== null) {
       detail = Cu.cloneInto(detail, this._window);
       return new this._window.CustomEvent('mozbrowser' + evtName,
                                           { bubbles: true,
                                             cancelable: cancelable,
@@ -641,16 +648,33 @@ BrowserElementParent.prototype = {
       });
     }
   }),
 
   getCanGoBack: defineDOMRequestMethod('get-can-go-back'),
   getCanGoForward: defineDOMRequestMethod('get-can-go-forward'),
   getContentDimensions: defineDOMRequestMethod('get-contentdimensions'),
 
+  findAll: defineNoReturnMethod(function(searchString, caseSensitivity) {
+    return this._sendAsyncMsg('find-all', {
+      searchString,
+      caseSensitive: caseSensitivity == Ci.nsIBrowserElementAPI.FIND_CASE_SENSITIVE
+    });
+  }),
+
+  findNext: defineNoReturnMethod(function(direction) {
+    return this._sendAsyncMsg('find-next', {
+      backward: direction == Ci.nsIBrowserElementAPI.FIND_BACKWARD
+    });
+  }),
+
+  clearMatch: defineNoReturnMethod(function() {
+    return this._sendAsyncMsg('clear-match');
+  }),
+
   goBack: defineNoReturnMethod(function() {
     this._sendAsyncMsg('go-back');
   }),
 
   goForward: defineNoReturnMethod(function() {
     this._sendAsyncMsg('go-forward');
   }),
 
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/browserElement_Find.js
@@ -0,0 +1,146 @@
+/* Any copyright is dedicated to the public domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Bug 1163961 - Test search API
+
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+browserElementTestHelpers.setEnabledPref(true);
+browserElementTestHelpers.addPermission();
+
+function runTest() {
+
+  let iframe = document.createElement('iframe');
+  iframe.setAttribute('mozbrowser', 'true');
+  iframe.src = 'data:text/html,foo bar foo XXX Foo BAR foobar foobar';
+
+  const once = (eventName) => {
+    return new Promise((resolve) => {
+      iframe.addEventListener(eventName, function onEvent(...args) {
+        iframe.removeEventListener(eventName, onEvent);
+        resolve(...args);
+      });
+    });
+  }
+
+  // Test if all key=>value pairs in o1 are present in o2.
+  const c = (o1, o2) => Object.keys(o1).every(k => o1[k] == o2[k]);
+
+  let testCount = 0;
+
+  once('mozbrowserloadend').then(() => {
+    iframe.findAll('foo', 'case-insensitive');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'foo',
+      searchLimit: 100,
+      activeMatchOrdinal: 1,
+      numberOfMatches: 5,
+    }), `test ${testCount++}`);
+    iframe.findNext('forward');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'foo',
+      searchLimit: 100,
+      activeMatchOrdinal: 2,
+      numberOfMatches: 5,
+    }), `test ${testCount++}`);
+    iframe.findNext('backward');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'foo',
+      searchLimit: 100,
+      activeMatchOrdinal: 1,
+      numberOfMatches: 5,
+    }), `test ${testCount++}`);
+    iframe.findAll('xxx', 'case-sensitive');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'xxx',
+      searchLimit: 100,
+      activeMatchOrdinal: 0,
+      numberOfMatches: 0,
+    }), `test ${testCount++}`);
+    iframe.findAll('bar', 'case-insensitive');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'bar',
+      searchLimit: 100,
+      activeMatchOrdinal: 1,
+      numberOfMatches: 4,
+    }), `test ${testCount++}`);
+    iframe.findNext('forward');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'bar',
+      searchLimit: 100,
+      activeMatchOrdinal: 2,
+      numberOfMatches: 4,
+    }), `test ${testCount++}`);
+    iframe.findNext('forward');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'bar',
+      searchLimit: 100,
+      activeMatchOrdinal: 3,
+      numberOfMatches: 4,
+    }), `test ${testCount++}`);
+    iframe.findNext('forward');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'bar',
+      searchLimit: 100,
+      activeMatchOrdinal: 4,
+      numberOfMatches: 4,
+    }), `test ${testCount++}`);
+    iframe.findNext('forward');
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: true,
+      searchString: 'bar',
+      searchLimit: 100,
+      activeMatchOrdinal: 1,
+      numberOfMatches: 4,
+    }), `test ${testCount++}`);
+    iframe.clearMatch();
+    return once('mozbrowserfindchange');
+  }).then(({detail}) => {
+    ok(c(detail, {
+      msg_name: "findchange",
+      active: false
+    }), `test ${testCount++}`);
+    SimpleTest.finish();
+  });
+
+  document.body.appendChild(iframe);
+
+}
+
+addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -2,16 +2,17 @@
 # Both the "inproc" and "oop" versions of OpenMixedProcess open remote frames,
 # so we don't run that test on platforms which don't support OOP tests.
 # OOP tests don't work on native-fennec (bug 774939).
 # Bug 960345 - Disabled on OSX debug for frequent crashes.
 skip-if = os == "android" || (toolkit == "cocoa" && debug) || buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || e10s
 support-files =
   browserElement_OpenMixedProcess.js
   file_browserElement_OpenMixedProcess.html
+  browserElement_Find.js
   browserElement_OpenTab.js
 
 [test_browserElement_oop_Viewmode.html]
 [test_browserElement_oop_ThemeColor.html]
 [test_browserElement_inproc_ErrorSecurity.html]
 skip-if = toolkit=='gonk'
 [test_browserElement_inproc_OpenMixedProcess.html]
 skip-if = toolkit=='gonk' || (toolkit == 'gonk' && !debug)
@@ -36,16 +37,17 @@ skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_DOMRequestError.html]
 [test_browserElement_oop_DataURI.html]
 [test_browserElement_oop_DisallowEmbedAppsInOOP.html]
 [test_browserElement_oop_DocumentFirstPaint.html]
 [test_browserElement_oop_Download.html]
 disabled = bug 1022281
 [test_browserElement_oop_ErrorSecurity.html]
 skip-if = (toolkit == 'gonk' && !debug)
+[test_browserElement_oop_Find.html]
 [test_browserElement_oop_FirstPaint.html]
 [test_browserElement_oop_ForwardName.html]
 [test_browserElement_oop_FrameWrongURI.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_oop_GetScreenshot.html]
 [test_browserElement_oop_GetScreenshotDppx.html]
 [test_browserElement_oop_Iconchange.html]
 [test_browserElement_oop_LoadEvents.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -24,16 +24,17 @@ support-files =
   browserElement_CopyPaste.js
   browserElement_DOMRequestError.js
   browserElement_DataURI.js
   browserElement_DisallowEmbedAppsInOOP.js
   browserElement_DocumentFirstPaint.js
   browserElement_Download.js
   browserElement_ErrorSecurity.js
   browserElement_ExposableURI.js
+  browserElement_Find.js
   browserElement_FirstPaint.js
   browserElement_ForwardName.js
   browserElement_FrameWrongURI.js
   browserElement_GetScreenshot.js
   browserElement_GetScreenshotDppx.js
   browserElement_Iconchange.js
   browserElement_LoadEvents.js
   browserElement_Manifestchange.js
@@ -154,16 +155,17 @@ skip-if = buildapp == 'b2g'
 [test_browserElement_inproc_DOMRequestError.html]
 [test_browserElement_inproc_DataURI.html]
 [test_browserElement_inproc_DisallowEmbedAppsInOOP.html]
 skip-if = os == "android" || toolkit == 'gonk' # embed-apps doesn't work in the mochitest app
 [test_browserElement_inproc_DocumentFirstPaint.html]
 [test_browserElement_inproc_Download.html]
 disabled = bug 1022281
 [test_browserElement_inproc_ExposableURI.html]
+[test_browserElement_inproc_Find.html]
 [test_browserElement_inproc_FirstPaint.html]
 [test_browserElement_inproc_ForwardName.html]
 [test_browserElement_inproc_FrameWrongURI.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_GetScreenshot.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_browserElement_inproc_GetScreenshotDppx.html]
 [test_browserElement_inproc_Iconchange.html]
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_inproc_Find.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1163961
+-->
+<head>
+  <title>Test for Bug 1163961</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.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=1163961">Mozilla Bug 1163961</a>
+
+<script type="application/javascript;version=1.7" src="browserElement_Find.js">
+</script>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_oop_Find.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1163961
+-->
+<head>
+  <title>Test for Bug 1163961</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.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=1163961">Mozilla Bug 1163961</a>
+
+<script type="application/javascript;version=1.7" src="browserElement_Find.js">
+</script>
+</body>
+</html>
+
--- a/dom/browser-element/nsIBrowserElementAPI.idl
+++ b/dom/browser-element/nsIBrowserElementAPI.idl
@@ -21,19 +21,25 @@ interface nsIBrowserElementNextPaintList
     { 0x651db7e3, 0x1734, 0x4536,                               \
       { 0xb1, 0x5a, 0x5b, 0x3a, 0xe6, 0x44, 0x13, 0x4c } }
 %}
 
 /**
  * Interface to the BrowserElementParent implementation. All methods
  * but setFrameLoader throw when the remote process is dead.
  */
-[scriptable, uuid(3811446f-90bb-42c1-b2b6-aae3603b61e1)]
+[scriptable, uuid(8ecb598c-f886-11e4-9915-778f934fbf93)]
 interface nsIBrowserElementAPI : nsISupports
 {
+  const long FIND_CASE_SENSITIVE = 0;
+  const long FIND_CASE_INSENSITIVE = 1;
+
+  const long FIND_FORWARD = 0;
+  const long FIND_BACKWARD = 1;
+
   void setFrameLoader(in nsIFrameLoader frameLoader);
 
   void setVisible(in boolean visible);
   nsIDOMDOMRequest getVisible();
   void setActive(in boolean active);
   boolean getActive();
 
   void sendMouseEvent(in DOMString type,
@@ -62,15 +68,19 @@ interface nsIBrowserElementAPI : nsISupp
   nsIDOMDOMRequest getScreenshot(in uint32_t width,
                                  in uint32_t height,
                                  [optional] in DOMString mimeType);
   void zoom(in float zoom);
   nsIDOMDOMRequest getCanGoBack();
   nsIDOMDOMRequest getCanGoForward();
   nsIDOMDOMRequest getContentDimensions();
 
+  void findAll(in DOMString searchString, in long caseSensitivity);
+  void findNext(in long direction);
+  void clearMatch();
+
   void addNextPaintListener(in nsIBrowserElementNextPaintListener listener);
   void removeNextPaintListener(in nsIBrowserElementNextPaintListener listener);
 
   nsIDOMDOMRequest setInputMethodActive(in boolean isActive);
 
   void setNFCFocus(in boolean isFocus);
 };
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -2347,21 +2347,26 @@ private:
   nsIAtom* mFontLanguage;
   bool mExplicitLanguage;
   nsPresContext* mPresContext;
 };
 
 void
 CanvasRenderingContext2D::UpdateFilter()
 {
-  nsIPresShell* presShell = GetPresShell();
+  nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell || presShell->IsDestroying()) {
     return;
   }
 
+  // The filter might reference an SVG filter that is declared inside this
+  // document. Flush frames so that we'll have an nsSVGFilterFrame to work
+  // with.
+  presShell->FlushPendingNotifications(Flush_Frames);
+
   CurrentState().filter =
     nsFilterInstance::GetFilterDescription(mCanvasElement,
       CurrentState().filterChain,
       CanvasUserSpaceMetrics(IntSize(mWidth, mHeight),
                              CurrentState().fontFont,
                              CurrentState().fontLanguage,
                              CurrentState().fontExplicitLanguage,
                              presShell->GetPresContext()),
@@ -4695,21 +4700,27 @@ CanvasRenderingContext2D::DrawWindow(nsG
   }
 
   nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
   unused << shell->RenderDocument(r, renderDocFlags, backgroundColor, thebes);
   if (drawDT) {
     RefPtr<SourceSurface> snapshot = drawDT->Snapshot();
     RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
 
+    DataSourceSurface::MappedSurface rawData;
+    if (NS_WARN_IF(!data->Map(DataSourceSurface::READ, &rawData))) {
+        error.Throw(NS_ERROR_FAILURE);
+        return;
+    }
     RefPtr<SourceSurface> source =
-      mTarget->CreateSourceSurfaceFromData(data->GetData(),
+      mTarget->CreateSourceSurfaceFromData(rawData.mData,
                                            data->GetSize(),
-                                           data->Stride(),
+                                           rawData.mStride,
                                            data->GetFormat());
+    data->Unmap();
 
     if (!source) {
       error.Throw(NS_ERROR_FAILURE);
       return;
     }
 
     mgfx::Rect destRect(0, 0, w, h);
     mgfx::Rect sourceRect(0, 0, sw, sh);
@@ -4974,22 +4985,23 @@ CanvasRenderingContext2D::GetImageDataAr
   if (!rightMost.isValid() || !bottomMost.isValid()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   IntRect srcRect(0, 0, mWidth, mHeight);
   IntRect destRect(aX, aY, aWidth, aHeight);
   IntRect srcReadRect = srcRect.Intersect(destRect);
   RefPtr<DataSourceSurface> readback;
+  DataSourceSurface::MappedSurface rawData;
   if (!srcReadRect.IsEmpty() && !mZero) {
     RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
     if (snapshot) {
       readback = snapshot->GetDataSurface();
     }
-    if (!readback || !readback->GetData()) {
+    if (!readback || !readback->Map(DataSourceSurface::READ, &rawData)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   JS::Rooted<JSObject*> darray(aCx, JS_NewUint8ClampedArray(aCx, len.value()));
   if (!darray) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -5001,18 +5013,18 @@ CanvasRenderingContext2D::GetImageDataAr
 
   IntRect dstWriteRect = srcReadRect;
   dstWriteRect.MoveBy(-aX, -aY);
 
   uint8_t* src;
   uint32_t srcStride;
 
   if (readback) {
-    srcStride = readback->Stride();
-    src = readback->GetData() + srcReadRect.y * srcStride + srcReadRect.x * 4;
+    srcStride = rawData.mStride;
+    src = rawData.mData + srcReadRect.y * srcStride + srcReadRect.x * 4;
   }
 
   JS::AutoCheckCannotGC nogc;
   uint8_t* data = JS_GetUint8ClampedArrayData(darray, nogc);
   if (!readback) {
     src = data;
     srcStride = aWidth * 4;
   }
@@ -5066,16 +5078,20 @@ CanvasRenderingContext2D::GetImageDataAr
       *dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + g];
       *dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + b];
       *dst++ = a;
     }
     src += srcStride - (dstWriteRect.width * 4);
     dst += (aWidth * 4) - (dstWriteRect.width * 4);
   }
 
+  if (readback) {
+    readback->Unmap();
+  }
+
   *aRetval = darray;
   return NS_OK;
 }
 
 void
 CanvasRenderingContext2D::EnsureErrorTarget()
 {
   if (sErrorTarget) {
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -879,16 +879,17 @@ protected:
                      miterLimit(10.0f),
                      globalAlpha(1.0f),
                      shadowBlur(0.0),
                      dashOffset(0.0f),
                      op(mozilla::gfx::CompositionOp::OP_OVER),
                      fillRule(mozilla::gfx::FillRule::FILL_WINDING),
                      lineCap(mozilla::gfx::CapStyle::BUTT),
                      lineJoin(mozilla::gfx::JoinStyle::MITER_OR_BEVEL),
+                     filterString(MOZ_UTF16("none")),
                      imageSmoothingEnabled(true),
                      fontExplicitLanguage(false)
     { }
 
     ContextState(const ContextState& other)
         : fontGroup(other.fontGroup),
           fontLanguage(other.fontLanguage),
           fontFont(other.fontFont),
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -319,16 +319,17 @@ public:
 
     // -------------------------------------------------------------------------
     // Uniform Buffer Objects and Transform Feedback Buffers - WebGL2ContextUniforms.cpp
     // TODO(djg): Implemented in WebGLContext
 /*
     void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
     void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
 */
+    virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) override;
     void GetIndexedParameter(GLenum target, GLuint index,
                              dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval);
     void GetUniformIndices(WebGLProgram* program,
                            const dom::Sequence<nsString>& uniformNames,
                            dom::Nullable< nsTArray<GLuint> >& retval);
     void GetActiveUniforms(WebGLProgram* program,
                            const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
                            dom::Nullable< nsTArray<GLint> >& retval);
--- a/dom/canvas/WebGL2ContextSamplers.cpp
+++ b/dom/canvas/WebGL2ContextSamplers.cpp
@@ -31,16 +31,22 @@ WebGL2Context::DeleteSampler(WebGLSample
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteSampler", sampler))
         return;
 
     if (!sampler || sampler->IsDeleted())
         return;
 
+    for (int n = 0; n < mGLMaxTextureUnits; n++) {
+        if (mBoundSamplers[n] == sampler) {
+            mBoundSamplers[n] = nullptr;
+        }
+    }
+
     sampler->RequestDelete();
 }
 
 bool
 WebGL2Context::IsSampler(WebGLSampler* sampler)
 {
     if (IsContextLost())
         return false;
@@ -69,16 +75,18 @@ WebGL2Context::BindSampler(GLuint unit, 
 
     if (GLint(unit) >= mGLMaxTextureUnits)
         return ErrorInvalidValue("bindSampler: unit must be < %d", mGLMaxTextureUnits);
 
     if (sampler && sampler->IsDeleted())
         return ErrorInvalidOperation("bindSampler: binding deleted sampler");
 
     WebGLContextUnchecked::BindSampler(unit, sampler);
+
+    mBoundSamplers[unit] = sampler;
 }
 
 void
 WebGL2Context::SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param)
 {
     if (IsContextLost())
         return;
 
copy from dom/canvas/WebGLTimerQuery.h
copy to dom/canvas/WebGL2ContextState.cpp
--- a/dom/canvas/WebGLTimerQuery.h
+++ b/dom/canvas/WebGL2ContextState.cpp
@@ -1,49 +1,177 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef WEBGL_TIMER_QUERY_H_
-#define WEBGL_TIMER_QUERY_H_
-
-#include "nsWrapperCache.h"
-#include "WebGLObjectModel.h"
+#include "WebGL2Context.h"
+#include "WebGLContextUtils.h"
 
 namespace mozilla {
 
-class WebGLTimerQuery final
-  : public nsWrapperCache
-  , public WebGLRefCountedObject<WebGLTimerQuery>
-  , public WebGLContextBoundObject
+JS::Value
+WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
 {
-public:
-  static WebGLTimerQuery* Create(WebGLContext* webgl);
+  // The following cases are handled in WebGLContext::GetParameter():
+  //     case LOCAL_GL_MAX_COLOR_ATTACHMENTS:
+  //     case LOCAL_GL_MAX_DRAW_BUFFERS:
+  //     case LOCAL_GL_DRAW_BUFFERi:
+
+  if (IsContextLost())
+    return JS::NullValue();
+
+  MakeContextCurrent();
 
-  void Delete();
+  switch (pname) {
+    /* GLboolean */
+    case LOCAL_GL_RASTERIZER_DISCARD:
+    case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
+    case LOCAL_GL_SAMPLE_COVERAGE:
+    case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED:
+    case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE:
+    case LOCAL_GL_UNPACK_SKIP_IMAGES:
+    case LOCAL_GL_UNPACK_SKIP_PIXELS:
+    case LOCAL_GL_UNPACK_SKIP_ROWS: {
+      realGLboolean b = 0;
+      gl->fGetBooleanv(pname, &b);
+      return JS::BooleanValue(bool(b));
+    }
+
+    /* GLenum */
+    case LOCAL_GL_READ_BUFFER: {
+      if (mBoundReadFramebuffer) {
+        GLint val = LOCAL_GL_NONE;
+        gl->fGetIntegerv(pname, &val);
+        return JS::Int32Value(val);
+      }
+
+      return JS::Int32Value(LOCAL_GL_BACK);
+    }
+
+    case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+      /* fall through */
 
-  bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
-  GLenum Target() const { return mTarget; }
+    /* GLint */
+    case LOCAL_GL_MAX_3D_TEXTURE_SIZE:
+    case LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS:
+    case LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS:
+    case LOCAL_GL_MAX_ELEMENTS_INDICES:
+    case LOCAL_GL_MAX_ELEMENTS_VERTICES:
+    case LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+    case LOCAL_GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+    case LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+    case LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET:
+    case LOCAL_GL_MAX_SAMPLES:
+    case LOCAL_GL_MAX_TEXTURE_LOD_BIAS:
+    case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+    case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+    case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+    case LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS:
+    case LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+    case LOCAL_GL_MAX_VERTEX_UNIFORM_BLOCKS:
+    case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+    case LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET:
+    case LOCAL_GL_PACK_ROW_LENGTH:
+    case LOCAL_GL_PACK_SKIP_PIXELS:
+    case LOCAL_GL_PACK_SKIP_ROWS:
+    case LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+    case LOCAL_GL_UNPACK_IMAGE_HEIGHT:
+    case LOCAL_GL_UNPACK_ROW_LENGTH: {
+      GLint val;
+      gl->fGetIntegerv(pname, &val);
+      return JS::Int32Value(val);
+    }
 
-  WebGLContext* GetParentObject() const;
+    case LOCAL_GL_MAX_VARYING_COMPONENTS: {
+      // On OS X Core Profile this is buggy.  The spec says that the
+      // value is 4 * GL_MAX_VARYING_VECTORS
+      GLint val;
+      gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &val);
+      return JS::Int32Value(4*val);
+    }
 
-  // NS
-  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
+    /* GLint64 */
+    case LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
+      return JS::NumberValue(0); // TODO
+
+    case LOCAL_GL_MAX_ELEMENT_INDEX:
+      // GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3
+      // compatibility
+      if (!gl->IsSupported(gl::GLFeature::ES3_compatibility))
+        return JS::NumberValue(0);
+
+      /*** fall through to fGetInteger64v ***/
+
+    case LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+    case LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+    case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: {
+      GLint64 val;
+      gl->fGetInteger64v(pname, &val);
+      return JS::DoubleValue(static_cast<double>(val));
+    }
 
-  const GLenum mGLName;
+
+    /* GLuint64 */
+    case LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT: {
+      GLuint64 val;
+      gl->fGetInteger64v(pname, (GLint64*) &val);
+      return JS::DoubleValue(static_cast<double>(val));
+    }
 
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTimerQuery)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTimerQuery)
+    case LOCAL_GL_COPY_READ_BUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
+
+    case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
+
+    case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
+
+    case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
 
-private:
-  explicit WebGLTimerQuery(WebGLContext* webgl, GLuint aName);
-  ~WebGLTimerQuery();
+    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
+
+    case LOCAL_GL_UNIFORM_BUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
+
+    // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
+    case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
+
+    case LOCAL_GL_SAMPLER_BINDING:
+      return WebGLObjectAsJSValue(cx, mBoundSamplers[mActiveTexture].get(), rv);
+
+    case LOCAL_GL_TEXTURE_BINDING_2D_ARRAY:
+      // TODO: Implement gl.TEXTURE_2D_ARRAY
+      // return WebGLObjectAsJSValue(cx, mBound2DTextureArrays[mActiveTexture].get(), rv);
+      return JS::NullValue();
+
+    case LOCAL_GL_TEXTURE_BINDING_3D:
+      return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
 
-  GLenum mTarget;
+    case LOCAL_GL_TRANSFORM_FEEDBACK_BINDING: {
+      WebGLTransformFeedback* tf =
+        (mBoundTransformFeedback != mDefaultTransformFeedback) ? mBoundTransformFeedback.get() : nullptr;
+      return WebGLObjectAsJSValue(cx, tf, rv);
+    }
 
-  friend class WebGLExtensionDisjointTimerQuery;
-};
+    case LOCAL_GL_VERTEX_ARRAY_BINDING: {
+      WebGLVertexArray* vao =
+        (mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr;
+      return WebGLObjectAsJSValue(cx, vao, rv);
+    }
+
+    case LOCAL_GL_VERSION:
+      return StringValue(cx, "WebGL 2.0", rv);
+
+    case LOCAL_GL_SHADING_LANGUAGE_VERSION:
+      return StringValue(cx, "WebGL GLSL ES 3.00", rv);
+
+    default:
+      return WebGLContext::GetParameter(cx, pname, rv);
+  }
+}
 
 } // namespace mozilla
-
-#endif // WEBGL_TIMER_QUERY_H_
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -320,16 +320,17 @@ WebGLContext::DestroyResourcesAndContext
     if (!gl)
         return;
 
     gl->MakeCurrent();
 
     mBound2DTextures.Clear();
     mBoundCubeMapTextures.Clear();
     mBound3DTextures.Clear();
+    mBoundSamplers.Clear();
     mBoundArrayBuffer = nullptr;
     mBoundCopyReadBuffer = nullptr;
     mBoundCopyWriteBuffer = nullptr;
     mBoundPixelPackBuffer = nullptr;
     mBoundPixelUnpackBuffer = nullptr;
     mBoundTransformFeedbackBuffer = nullptr;
     mBoundUniformBuffer = nullptr;
     mCurrentProgram = nullptr;
@@ -1944,16 +1945,17 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLCon
 NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLContext)
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLContext,
   mCanvasElement,
   mExtensions,
   mBound2DTextures,
   mBoundCubeMapTextures,
   mBound3DTextures,
+  mBoundSamplers,
   mBoundArrayBuffer,
   mBoundCopyReadBuffer,
   mBoundCopyWriteBuffer,
   mBoundPixelPackBuffer,
   mBoundPixelUnpackBuffer,
   mBoundTransformFeedbackBuffer,
   mBoundUniformBuffer,
   mCurrentProgram,
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -60,16 +60,26 @@ class nsIDocShell;
 #define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS      16    // Page 164
 #define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS        128   // Page 164
 #define MINVALUE_GL_MAX_VARYING_VECTORS               8     // Page 164
 #define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS           8     // Page 164
 #define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS    0     // Page 164
 #define MINVALUE_GL_MAX_RENDERBUFFER_SIZE             1024  // Different from the spec, which sets it to 1 on page 164
 #define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS  8     // Page 164
 
+/*
+ * WebGL-only GLenums
+ */
+#define LOCAL_GL_BROWSER_DEFAULT_WEBGL                       0x9244
+#define LOCAL_GL_CONTEXT_LOST_WEBGL                          0x9242
+#define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL               0x9247
+#define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL          0x9243
+#define LOCAL_GL_UNPACK_FLIP_Y_WEBGL                         0x9240
+#define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL              0x9241
+
 namespace mozilla {
 
 class WebGLActiveInfo;
 class WebGLContextLossHandler;
 class WebGLBuffer;
 class WebGLExtensionBase;
 class WebGLFramebuffer;
 class WebGLObserver;
@@ -950,17 +960,17 @@ protected:
     WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
 
 // -----------------------------------------------------------------------------
 // State and State Requests (WebGLContextState.cpp)
 public:
     void Disable(GLenum cap);
     void Enable(GLenum cap);
     bool GetStencilBits(GLint* out_stencilBits);
-    JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
+    virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
 
     void GetParameter(JSContext* cx, GLenum pname,
                       JS::MutableHandle<JS::Value> retval, ErrorResult& rv)
     {
         retval.set(GetParameter(cx, pname, rv));
     }
 
     void GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
@@ -1430,16 +1440,17 @@ protected:
                              TexType type, const GLvoid* data);
 
     void ForceLoseContext(bool simulateLoss = false);
     void ForceRestoreContext();
 
     nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
     nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
     nsTArray<WebGLRefPtr<WebGLTexture> > mBound3DTextures;
+    nsTArray<WebGLRefPtr<WebGLSampler> > mBoundSamplers;
 
     void ResolveTexturesForDraw() const;
 
     WebGLRefPtr<WebGLProgram> mCurrentProgram;
     RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
 
     uint32_t mMaxFramebufferColorAttachments;
 
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -53,28 +53,16 @@ WebGLContext::Enable(GLenum cap)
     {
         *trackingSlot = 1;
     }
 
     MakeContextCurrent();
     gl->fEnable(cap);
 }
 
-static JS::Value
-StringValue(JSContext* cx, const char* chars, ErrorResult& rv)
-{
-    JSString* str = JS_NewStringCopyZ(cx, chars);
-    if (!str) {
-        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
-        return JS::NullValue();
-    }
-
-    return JS::StringValue(str);
-}
-
 bool
 WebGLContext::GetStencilBits(GLint* out_stencilBits)
 {
     *out_stencilBits = 0;
     if (mBoundDrawFramebuffer) {
         if (mBoundDrawFramebuffer->HasDepthStencilConflict()) {
             // Error, we don't know which stencil buffer's bits to use
             ErrorInvalidFramebufferOperation("getParameter: framebuffer has two stencil buffers bound");
@@ -145,136 +133,99 @@ WebGLContext::GetParameter(JSContext* cx
             return JS::Int32Value(mGLMaxColorAttachments);
 
         } else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) {
             return JS::Int32Value(mGLMaxDrawBuffers);
 
         } else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
                    pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
         {
-            if (mBoundDrawFramebuffer) {
-                GLint iv = 0;
-                gl->fGetIntegerv(pname, &iv);
-                return JS::Int32Value(iv);
-            }
-
             GLint iv = 0;
             gl->fGetIntegerv(pname, &iv);
 
-            if (iv == GLint(LOCAL_GL_COLOR_ATTACHMENT0 + pname - LOCAL_GL_DRAW_BUFFER0)) {
+            if (mBoundDrawFramebuffer)
+                return JS::Int32Value(iv);
+
+            const GLint index = (pname - LOCAL_GL_DRAW_BUFFER0);
+            if (iv == LOCAL_GL_COLOR_ATTACHMENT0 + index)
                 return JS::Int32Value(LOCAL_GL_BACK);
-            }
 
             return JS::Int32Value(LOCAL_GL_NONE);
         }
     }
 
     if (IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
         if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) {
-            if (mBoundVertexArray == mDefaultVertexArray){
-                return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
-            }
-
-            return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
+            WebGLVertexArray* vao =
+                (mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr;
+            return WebGLObjectAsJSValue(cx, vao, rv);
         }
     }
 
     if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
         if (pname == LOCAL_GL_TIMESTAMP_EXT) {
             GLuint64 iv = 0;
             gl->fGetInteger64v(pname, (GLint64*) &iv);
-            return JS::NumberValue(uint64_t(iv));
+            // TODO: JS doesn't support 64-bit integers. Be lossy and
+            // cast to double (53 bits)
+            return JS::NumberValue(static_cast<double>(iv));
         } else if (pname == LOCAL_GL_GPU_DISJOINT_EXT) {
             // When disjoint isn't supported, leave as false.
-            realGLboolean disjoint = 0;
+            realGLboolean disjoint = LOCAL_GL_FALSE;
             if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
                 gl->fGetBooleanv(pname, &disjoint);
             }
             return JS::BooleanValue(bool(disjoint));
         }
     }
 
-    if (IsWebGL2()) {
+    // Privileged string params exposed by WEBGL_debug_renderer_info:
+    if (IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) {
         switch (pname) {
-        case LOCAL_GL_MAX_SAMPLES:
-        case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE:
-        case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
-            GLint val;
-            gl->fGetIntegerv(pname, &val);
-            return JS::NumberValue(uint32_t(val));
+        case UNMASKED_VENDOR_WEBGL:
+        case UNMASKED_RENDERER_WEBGL:
+            GLenum glstringname = LOCAL_GL_NONE;
+            if (pname == UNMASKED_VENDOR_WEBGL) {
+                glstringname = LOCAL_GL_VENDOR;
+            } else if (pname == UNMASKED_RENDERER_WEBGL) {
+                glstringname = LOCAL_GL_RENDERER;
+            }
+            const GLchar* string = (const GLchar*) gl->fGetString(glstringname);
+            return StringValue(cx, string, rv);
         }
-
-        case LOCAL_GL_TEXTURE_BINDING_3D:
-            return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
-
-        // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
-        case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
+    }
 
-        case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
-
-        case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
-
-        case LOCAL_GL_UNIFORM_BUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
+    if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) {
+        if (pname == LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT) {
+            GLint i = 0;
+            gl->fGetIntegerv(pname, &i);
+            return JS::Int32Value(i);
+        }
+    }
 
-        case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
-
-        case LOCAL_GL_COPY_READ_BUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
-
-        case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
-            return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
+    if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
+        if (pname == LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) {
+            GLfloat f = 0.f;
+            gl->fGetFloatv(pname, &f);
+            return JS::NumberValue(f);
         }
     }
 
     switch (pname) {
         //
         // String params
         //
         case LOCAL_GL_VENDOR:
-            return StringValue(cx, "Mozilla", rv);
         case LOCAL_GL_RENDERER:
             return StringValue(cx, "Mozilla", rv);
-        case LOCAL_GL_VERSION: {
-            const char* version = 0;
-
-            if (IsWebGL2()) {
-                version = "WebGL 2.0";
-            } else {
-                version = "WebGL 1.0";
-            }
-
-            MOZ_ASSERT(version != 0);
-            return StringValue(cx, version, rv);
-        }
+        case LOCAL_GL_VERSION:
+            return StringValue(cx, "WebGL 1.0", rv);
         case LOCAL_GL_SHADING_LANGUAGE_VERSION:
             return StringValue(cx, "WebGL GLSL ES 1.0", rv);
 
-            // Privileged string params exposed by WEBGL_debug_renderer_info:
-        case UNMASKED_VENDOR_WEBGL:
-        case UNMASKED_RENDERER_WEBGL: {
-            // The privilege check is done in WebGLContext::IsExtensionSupported.
-            // So here we just have to check that the extension is enabled.
-            if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) {
-                break;
-            }
-            GLenum glstringname = LOCAL_GL_NONE;
-            if (pname == UNMASKED_VENDOR_WEBGL) {
-                glstringname = LOCAL_GL_VENDOR;
-            } else if (pname == UNMASKED_RENDERER_WEBGL) {
-                glstringname = LOCAL_GL_RENDERER;
-            }
-            const char* string = reinterpret_cast<const char*>(gl->fGetString(glstringname));
-            return StringValue(cx, string, rv);
-        }
-
         ////////////////////////////////
         // Single-value params
 
         // unsigned int
         case LOCAL_GL_CULL_FACE_MODE:
         case LOCAL_GL_FRONT_FACE:
         case LOCAL_GL_ACTIVE_TEXTURE:
         case LOCAL_GL_STENCIL_FUNC:
@@ -375,25 +326,16 @@ WebGLContext::GetParameter(JSContext* cx
         }
         case LOCAL_GL_ALPHA_BITS: {
             GLint i = 0;
             if (!mNeedsFakeNoAlpha) {
                 gl->fGetIntegerv(pname, &i);
             }
             return JS::Int32Value(i);
         }
-        case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT: {
-            if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) {
-                GLint i = 0;
-                gl->fGetIntegerv(pname, &i);
-                return JS::Int32Value(i);
-            } else {
-                break;
-            }
-        }
         case LOCAL_GL_MAX_TEXTURE_SIZE:
             return JS::Int32Value(mGLMaxTextureSize);
 
         case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
             return JS::Int32Value(mGLMaxCubeMapTextureSize);
 
         case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
             return JS::Int32Value(mGLMaxRenderbufferSize);
@@ -412,48 +354,32 @@ WebGLContext::GetParameter(JSContext* cx
         case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: {
             uint32_t length = mCompressedTextureFormats.Length();
             JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements());
             if (!obj) {
                 rv = NS_ERROR_OUT_OF_MEMORY;
             }
             return JS::ObjectOrNullValue(obj);
         }
-        case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: {
-            if (!IsWebGL2()) {
-                break;
-            }
-            return JS::Int32Value(mGLMaxTransformFeedbackSeparateAttribs);
-        }
 
         // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as
         // javascript integer values. We just return them as doubles and javascript doesn't care.
-        case LOCAL_GL_STENCIL_BACK_VALUE_MASK: {
+        case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
             return JS::DoubleValue(mStencilValueMaskBack); // pass as FP value to allow large values such as 2^32-1.
-        }
-        case LOCAL_GL_STENCIL_BACK_WRITEMASK: {
+
+        case LOCAL_GL_STENCIL_BACK_WRITEMASK:
             return JS::DoubleValue(mStencilWriteMaskBack);
-        }
-        case LOCAL_GL_STENCIL_VALUE_MASK: {
+
+        case LOCAL_GL_STENCIL_VALUE_MASK:
             return JS::DoubleValue(mStencilValueMaskFront);
-        }
-        case LOCAL_GL_STENCIL_WRITEMASK: {
+
+        case LOCAL_GL_STENCIL_WRITEMASK:
             return JS::DoubleValue(mStencilWriteMaskFront);
-        }
 
         // float
-        case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
-            if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
-                GLfloat f = 0.f;
-                gl->fGetFloatv(pname, &f);
-                return JS::DoubleValue(f);
-            } else {
-                break;
-            }
-        }
         case LOCAL_GL_DEPTH_CLEAR_VALUE:
         case LOCAL_GL_LINE_WIDTH:
         case LOCAL_GL_POLYGON_OFFSET_FACTOR:
         case LOCAL_GL_POLYGON_OFFSET_UNITS:
         case LOCAL_GL_SAMPLE_COVERAGE_VALUE: {
             GLfloat f = 0.f;
             gl->fGetFloatv(pname, &f);
             return JS::DoubleValue(f);
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -70,16 +70,28 @@ TexImageTargetToTexTarget(TexImageTarget
         return LOCAL_GL_TEXTURE_CUBE_MAP;
     default:
         MOZ_ASSERT(false, "Bad texture target");
         // Should be caught by the constructor for TexTarget
         return LOCAL_GL_NONE;
     }
 }
 
+JS::Value
+StringValue(JSContext* cx, const char* chars, ErrorResult& rv)
+{
+    JSString* str = JS_NewStringCopyZ(cx, chars);
+    if (!str) {
+        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
+        return JS::NullValue();
+    }
+
+    return JS::StringValue(str);
+}
+
 GLComponents::GLComponents(TexInternalFormat internalformat)
 {
     TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
     mComponents = 0;
 
     switch (unsizedformat.get()) {
     case LOCAL_GL_RGBA:
     case LOCAL_GL_RGBA4:
--- a/dom/canvas/WebGLContextUtils.h
+++ b/dom/canvas/WebGLContextUtils.h
@@ -51,16 +51,19 @@ size_t GetBitsPerTexel(TexInternalFormat
 //
 // This function converts the texture image target to the texture target a.k.a.
 // binding location. The returned binding location can be used to check that
 // the currently bound texture is appropriate for this texImageTarget.
 //
 // Returns GL_NONE if passed an invalid texture image target
 TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
 
+// Helper function to create a JS::Value from a C string
+JS::Value StringValue(JSContext* cx, const char* str, ErrorResult& rv);
+
 struct GLComponents
 {
     unsigned char mComponents;
 
     enum Components {
         Red     = (1 << 0),
         Green   = (1 << 1),
         Blue    = (1 << 2),
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -1750,16 +1750,17 @@ WebGLContext::InitAndValidateGL()
     mActiveTexture = 0;
     mEmitContextLostErrorOnce = true;
     mWebGLError = LOCAL_GL_NO_ERROR;
     mUnderlyingGLError = LOCAL_GL_NO_ERROR;
 
     mBound2DTextures.Clear();
     mBoundCubeMapTextures.Clear();
     mBound3DTextures.Clear();
+    mBoundSamplers.Clear();
 
     mBoundArrayBuffer = nullptr;
     mBoundTransformFeedbackBuffer = nullptr;
     mCurrentProgram = nullptr;
 
     mBoundDrawFramebuffer = nullptr;
     mBoundReadFramebuffer = nullptr;
     mBoundRenderbuffer = nullptr;
@@ -1793,16 +1794,17 @@ WebGLContext::InitAndValidateGL()
         GenerateWarning("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!",
                         mGLMaxTextureUnits);
         return false;
     }
 
     mBound2DTextures.SetLength(mGLMaxTextureUnits);
     mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
     mBound3DTextures.SetLength(mGLMaxTextureUnits);
+    mBoundSamplers.SetLength(mGLMaxTextureUnits);
 
     if (MinCapabilityMode()) {
         mGLMaxTextureSize = MINVALUE_GL_MAX_TEXTURE_SIZE;
         mGLMaxCubeMapTextureSize = MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE;
         mGLMaxRenderbufferSize = MINVALUE_GL_MAX_RENDERBUFFER_SIZE;
         mGLMaxTextureImageUnits = MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS;
         mGLMaxVertexTextureImageUnits = MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
         mGLMaxSamples = 1;
--- a/dom/canvas/WebGLTimerQuery.h
+++ b/dom/canvas/WebGLTimerQuery.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WEBGL_TIMER_QUERY_H_
 #define WEBGL_TIMER_QUERY_H_
 
+#include "GLConsts.h"
 #include "nsWrapperCache.h"
 #include "WebGLObjectModel.h"
 
 namespace mozilla {
 
 class WebGLTimerQuery final
   : public nsWrapperCache
   , public WebGLRefCountedObject<WebGLTimerQuery>
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -56,16 +56,17 @@ UNIFIED_SOURCES += [
     'WebGL2Context.cpp',
     'WebGL2ContextBuffers.cpp',
     'WebGL2ContextDraw.cpp',
     'WebGL2ContextFramebuffers.cpp',
     'WebGL2ContextMRTs.cpp',
     'WebGL2ContextPrograms.cpp',
     'WebGL2ContextQueries.cpp',
     'WebGL2ContextSamplers.cpp',
+    'WebGL2ContextState.cpp',
     'WebGL2ContextSync.cpp',
     'WebGL2ContextTextures.cpp',
     'WebGL2ContextTransformFeedback.cpp',
     'WebGL2ContextUniforms.cpp',
     'WebGL2ContextVAOs.cpp',
     'WebGLActiveInfo.cpp',
     'WebGLBuffer.cpp',
     'WebGLContext.cpp',
--- a/dom/canvas/test/mochitest.ini
+++ b/dom/canvas/test/mochitest.ini
@@ -244,8 +244,9 @@ skip-if = buildapp == 'mulet' || (builda
 [test_toDataURL_lowercase_ascii.html]
 [test_toDataURL_parameters.html]
 [test_windingRuleUndefined.html]
 [test_2d.fillText.gradient.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # bug 1040965
 [test_2d_composite_canvaspattern_setTransform.html]
 [test_createPattern_broken.html]
 [test_setlinedash.html]
+[test_filter.html]
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/default-color.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'drop-shadow(0 10px)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/drop-shadow-transformed.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.scale(-1, -1);
+ctx.filter = 'drop-shadow(0 10px black)';
+ctx.fillRect(-75, -65, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/drop-shadow.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'drop-shadow(0 10px black)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/global-alpha-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.globalAlpha = 0.5;
+ctx.fillStyle = '#000';
+ctx.fillRect(25, 35, 50, 40);
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/global-alpha.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'drop-shadow(0 10px black)';
+ctx.globalAlpha = 0.5;
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/global-composite-operation-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#000';
+ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
+ctx.fill();
+
+var tmp_canvas = canvas.cloneNode();
+var tmp_ctx = tmp_canvas.getContext('2d');
+tmp_ctx.fillStyle = '#0f0';
+tmp_ctx.fillRect(25, 25, 50, 50);
+tmp_ctx.fillStyle = '#000';
+tmp_ctx.fillRect(25, 65, 50, 10);
+
+ctx.globalCompositeOperation = 'source-in';
+ctx.drawImage(tmp_canvas, 0, 0);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/global-composite-operation.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#000';
+ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
+ctx.fill();
+
+ctx.filter = 'drop-shadow(0 10px black)';
+ctx.globalCompositeOperation = 'source-in';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/liveness.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.font = '10px sans-serif';
+ctx.filter = 'drop-shadow(0 .5em black)';
+ctx.font = '20px sans-serif';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/multiple-drop-shadows.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.filter = 'drop-shadow(0 10px black) drop-shadow(10px 0 #ccc)';
+ctx.fillRect(20, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+ctx.fillStyle = '#000';
+ctx.fillRect(25, 65, 50, 10);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/reftest.list
@@ -0,0 +1,20 @@
+default-preferences pref(canvas.filters.enabled,true)
+
+== default-color.html ref.html
+== drop-shadow.html ref.html
+== drop-shadow-transformed.html ref.html
+== global-alpha.html global-alpha-ref.html
+== global-composite-operation.html global-composite-operation-ref.html
+== liveness.html ref.html
+== multiple-drop-shadows.html shadow-ref.html
+== shadow.html shadow-ref.html
+== subregion-fill-paint.html subregion-ref.html
+== subregion-stroke-paint.html subregion-ref.html
+== svg-bbox.html svg-bbox-ref.html
+== svg-inline.html ref.html
+== svg-liveness.html ref.html
+== svg-off-screen.html ref.html
+== units.html ref.html
+== units-em.html ref.html
+== units-ex.html ref.html
+== units-off-screen.html ref.html
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/shadow-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.shadowOffsetX = 10;
+ctx.shadowColor = '#ccc';
+ctx.fillRect(20, 25, 50, 40);
+ctx.fillStyle = '#000';
+ctx.fillRect(20, 65, 50, 10);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/shadow.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.filter = 'drop-shadow(0 10px black)';
+ctx.shadowOffsetX = 10;
+ctx.shadowColor = '#ccc';
+ctx.fillRect(20, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/subregion-fill-paint.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<body>
+<svg style="display: block; width: 0; height: 0">
+  <defs>
+    <filter id="merge" primitiveUnits="objectBoundingBox">
+      <feMerge x="25%" y="25%" width="50%" height="50%">
+        <feMergeNode in="SourceGraphic"/>
+        <feMergeNode in="FillPaint"/>
+      </feMerge>
+    </filter>
+  </defs>
+</svg>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'url(#merge)';
+ctx.fillStyle = '#0f0';
+ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
+ctx.fill();
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/subregion-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 50);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/subregion-stroke-paint.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<body>
+<svg style="display: block; width: 0; height: 0">
+  <defs>
+    <filter id="merge" primitiveUnits="objectBoundingBox">
+      <feMerge x="25%" y="25%" width="50%" height="50%">
+        <feMergeNode in="SourceGraphic"/>
+        <feMergeNode in="StrokePaint"/>
+      </feMerge>
+    </filter>
+  </defs>
+</svg>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'url(#merge)';
+ctx.strokeStyle = '#0f0';
+ctx.arc(50, 50, 25, 0, Math.PI * 2, true);
+ctx.fill();
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/svg-bbox-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.fillStyle = '#0f0';
+ctx.fillRect(0, 0, 100, 100);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/svg-bbox.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<body>
+<svg style="display: block; width: 0; height: 0">
+  <defs>
+    <filter id="color-matrix">
+      <feColorMatrix type="matrix" in="SourceGraphic"
+        values="0 0 0 0 0 
+                0 0 0 0 255 
+                0 0 0 0 0 
+                0 0 0 0 255"/>
+    </filter>
+  </defs>
+</svg>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'url(#color-matrix)';
+ctx.fillStyle = '#fff';
+ctx.fillRect(25, 25, 50, 50);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/svg-inline.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<body>
+<svg style="display: block; width: 0; height: 0">
+  <defs>
+    <filter id="drop-shadow">
+      <feGaussianBlur in="SourceAlpha" stdDeviation="0"/>
+      <feOffset dx="0" dy="10" result="offsetblur"/>
+      <feFlood flood-color="rgba(0,0,0,1)"/>
+      <feComposite in2="offsetblur" operator="in"/>
+      <feMerge>
+        <feMergeNode/>
+        <feMergeNode in="SourceGraphic"/>
+      </feMerge>
+    </filter>
+  </defs>
+</svg>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'url(#drop-shadow)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/svg-liveness.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+
+var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+svg.setAttribute('style', 'display: block; width: 0; height: 0');
+
+var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
+
+var dropShadowFilter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');
+dropShadowFilter.setAttribute('id', 'drop-shadow');
+
+var gaussianFilter = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');
+gaussianFilter.setAttribute('in', 'SourceAlpha');
+gaussianFilter.setAttribute('stdDeviation', '0');
+dropShadowFilter.appendChild(gaussianFilter);
+
+var offset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');
+offset.setAttribute('dx', '0');
+offset.setAttribute('dy', '0');
+offset.setAttribute('result', 'offsetblur');
+dropShadowFilter.appendChild(offset);
+
+var flood = document.createElementNS('http://www.w3.org/2000/svg', 'feFlood');
+flood.setAttribute('flood-color', 'rgba(0,0,0,1)');
+dropShadowFilter.appendChild(flood);
+
+var composite = document.createElementNS('http://www.w3.org/2000/svg', 'feComposite');
+composite.setAttribute('in2', 'offsetblur');
+composite.setAttribute('operator', 'in');
+dropShadowFilter.appendChild(composite);
+
+var merge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');
+var mergeNode = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
+merge.appendChild(mergeNode);
+
+var mergeNode = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
+mergeNode.setAttribute('in', 'SourceGraphic');
+merge.appendChild(mergeNode);
+dropShadowFilter.appendChild(merge);
+
+defs.appendChild(dropShadowFilter);
+svg.appendChild(defs);
+
+document.body.appendChild(svg);
+
+</script>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'url(#drop-shadow)';
+
+offset.setAttribute('dy', '10');
+
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/svg-off-screen.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<body>
+<svg style="display: block; width: 0; height: 0">
+  <defs>
+    <filter id="drop-shadow">
+    <feGaussianBlur in="SourceAlpha" stdDeviation="0"/>
+    <feOffset dx="0" dy="10" result="offsetblur"/>
+    <feFlood flood-color="rgba(0,0,0,1)"/>
+    <feComposite in2="offsetblur" operator="in"/>
+      <feMerge>
+        <feMergeNode/>
+        <feMergeNode in="SourceGraphic"/>
+      </feMerge>
+    </filter>
+  </defs>
+</svg>
+<script>
+
+var canvas = document.createElement('canvas');
+canvas.width = 100;
+canvas.height = 100;
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'url(#drop-shadow)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+document.body.appendChild(canvas);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/units-em.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.font = '20px sans-serif';
+ctx.filter = 'drop-shadow(0 .5em black)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 25, 40);
+
+canvas.style.fontSize = '5px';
+ctx.font = '4em sans-serif';
+ctx.filter = 'drop-shadow(0 .5em black)';
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/units-ex.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.font = '10px sans-serif';
+ctx.filter = 'drop-shadow(0 2ex black)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/units-off-screen.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+
+var canvas = document.createElement('canvas');
+canvas.width = 500;
+canvas.height = 500;
+canvas.style.width = '100px';
+canvas.style.height = '100px';
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'drop-shadow(0 50px black)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(125, 125, 250, 200);
+
+document.body.appendChild(canvas);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/units-pt.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="100" height="100"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'drop-shadow(0 10mm black)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(25, 25, 50, 40);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/filters/units.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id="canvas" width="500" height="500" style="width: 100px; height: 100px"></canvas>
+<script>
+
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.filter = 'drop-shadow(0 50px black)';
+ctx.fillStyle = '#0f0';
+ctx.fillRect(125, 125, 250, 200);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/test_filter.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<body>
+<script>
+
+SpecialPowers.pushPrefEnv({ 'set': [['canvas.filters.enabled', true]] }, function () {
+
+  var canvas = document.createElement('canvas');
+  var ctx = canvas.getContext('2d');
+
+  is(ctx.filter, 'none', 'filter should intialy be set to \'none\'');
+  ctx.filter = 'blur(5px)';
+  is(ctx.filter, 'blur(5px)', 'valid filter should round-trip');
+
+  ctx.save();
+  ctx.filter = 'none';
+  is(ctx.filter, 'none', 'none should unset the filter');
+  ctx.restore();
+  is(ctx.filter, 'blur(5px)', 'filter should be part of the state');
+
+  ctx.filter = 'blur(10)';
+  is(ctx.filter, 'blur(5px)', 'invalid filter should be ignored');
+  ctx.filter = 'blur 10px';
+  is(ctx.filter, 'blur(5px)', 'syntax error should be ignored');
+
+  ctx.filter = 'inherit';
+  is(ctx.filter, 'blur(5px)', 'inherit should be ignored');
+  ctx.filter = 'initial';
+  is(ctx.filter, 'blur(5px)', 'initial should be ignored');
+
+  ctx.filter = '';
+  is(ctx.filter, 'blur(5px)', 'empty string should be ignored and not unset the filter');
+  ctx.filter = null;
+  is(ctx.filter, 'blur(5px)', 'null should be ignored and not unset the filter');
+  ctx.filter = undefined;
+  is(ctx.filter, 'blur(5px)', 'undefined should be ignored and not unset the filter');
+
+  SimpleTest.finish();
+  
+});
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -422,16 +422,20 @@ const kEventConstructors = {
                                                                                   aProps.clientX, aProps.clientY,
                                                                                   aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey,
                                                                                   aProps.button, aProps.relatedTarget,
                                                                                   aProps.allowedDirections, aProps.direction, aProps.delta || 0.0,
                                                                                   aProps.clickCount);
                                                          return e;
                                                        },
                                              },
+  SpeechRecognitionError:                    { create: function (aName, aProps) {
+                                                         return new SpeechRecognitionError(aName, aProps);
+                                                       },
+                                             },
   SpeechRecognitionEvent:                    { create: function (aName, aProps) {
                                                          return new SpeechRecognitionEvent(aName, aProps);
                                                        },
                                              },
   SpeechSynthesisEvent:                      { create: function (aName, aProps) {
                                                          return new SpeechSynthesisEvent(aName, aProps);
                                                        },
                                              },
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -12,18 +12,16 @@
 #include "nsMappedAttributes.h"
 #include "nsSize.h"
 #include "nsIDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIScriptContext.h"
 #include "nsIURL.h"
 #include "nsIIOService.h"
 #include "nsIServiceManager.h"
-#include "nsIAppShell.h"
-#include "nsWidgetsCID.h"
 #include "nsNetUtil.h"
 #include "nsContentUtils.h"
 #include "nsContainerFrame.h"
 #include "nsNodeInfoManager.h"
 #include "mozilla/MouseEvents.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIDOMWindow.h"
 #include "nsFocusManager.h"
@@ -48,18 +46,16 @@
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 
 #include "nsLayoutUtils.h"
 
 #include "mozilla/Preferences.h"
 static const char *kPrefSrcsetEnabled = "dom.image.srcset.enabled";
 
-static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
-
 NS_IMPL_NS_NEW_HTML_ELEMENT(Image)
 
 #ifdef DEBUG
 // Is aSubject a previous sibling of aNode.
 static bool IsPreviousSibling(nsINode *aSubject, nsINode *aNode)
 {
   if (aSubject == aNode) {
     return false;
@@ -877,25 +873,21 @@ void
 HTMLImageElement::QueueImageLoadTask()
 {
   // If loading is temporarily disabled, we don't want to queue tasks
   // that may then run when loading is re-enabled.
   if (!LoadingEnabled() || !this->OwnerDoc()->IsCurrentActiveDocument()) {
     return;
   }
 
-  // The task checks this to determine if it was the last queued event, so this
-  // implicitly cancels earlier tasks
-  mPendingImageLoadTask = new ImageLoadTask(this);
-  nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
-  if (appShell) {
-    appShell->RunInStableState(mPendingImageLoadTask);
-  } else {
-    MOZ_ASSERT(false, "expect appshell for HTMLImageElement");
-  }
+  nsCOMPtr<nsIRunnable> task = new ImageLoadTask(this);
+  // The task checks this to determine if it was the last
+  // queued event, and so earlier tasks are implicitly canceled.
+  mPendingImageLoadTask = task;
+  nsContentUtils::RunInStableState(task.forget());
 }
 
 bool
 HTMLImageElement::HaveSrcsetOrInPicture()
 {
   if (IsSrcsetEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::srcset)) {
     return true;
   }
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -56,18 +56,16 @@
 #include "nsCORSListenerProxy.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsICachingChannel.h"
 #include "nsLayoutUtils.h"
 #include "nsVideoFrame.h"
 #include "Layers.h"
 #include <limits>
 #include "nsIAsyncVerifyRedirectCallback.h"
-#include "nsIAppShell.h"
-#include "nsWidgetsCID.h"
 #include "nsMediaFragmentURIParser.h"
 #include "nsURIHashKey.h"
 #include "nsJSUtils.h"
 #include "MediaStreamGraph.h"
 #include "nsIScriptError.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "mozilla/dom/MediaSource.h"
 #include "MediaMetadataManager.h"
@@ -753,23 +751,20 @@ public:
     // Silently cancel if our load has been cancelled.
     if (IsCancelled())
       return NS_OK;
     mRunnable->Run();
     return NS_OK;
   }
 };
 
-static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
-
 void HTMLMediaElement::RunInStableState(nsIRunnable* aRunnable)
 {
   nsCOMPtr<nsIRunnable> event = new nsSyncSection(this, aRunnable);
-  nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
-  appShell->RunInStableState(event);
+  nsContentUtils::RunInStableState(event.forget());
 }
 
 void HTMLMediaElement::QueueLoadFromSourceTask()
 {
   ChangeDelayLoadStatus(true);
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
   RunInStableState(
     NS_NewRunnableMethod(this, &HTMLMediaElement::LoadFromSourceChildren));
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -156,17 +156,22 @@ HTMLObjectElement::OnFocusBlurPlugin(Ele
   // Element that doesn't have a plugin running.  But if SetPluginFocused(true)
   // was just called for aElement while it had a plugin running, we want to
   // make sure nsIWidget::SetPluginFocused(false) gets called for it now, even
   // if aFocus is true.
   if (aFocus) {
     nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(aElement);
     bool hasRunningPlugin = false;
     if (olc) {
-      olc->GetHasRunningPlugin(&hasRunningPlugin);
+      // nsIObjectLoadingContent::GetHasRunningPlugin() fails when
+      // nsContentUtils::IsCallerChrome() returns false (which it can do even
+      // when we're processing a trusted focus event).  We work around this by
+      // calling nsObjectLoadingContent::HasRunningPlugin() directly.
+      hasRunningPlugin =
+        static_cast<nsObjectLoadingContent*>(olc.get())->HasRunningPlugin();
     }
     if (!hasRunningPlugin) {
       aFocus = false;
     }
   }
 
   if (aFocus || aElement == sLastFocused) {
     if (!aFocus) {
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -372,16 +372,72 @@ nsBrowserElement::GetContentDimensions(E
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   return req.forget().downcast<DOMRequest>();
 }
 
 void
+nsBrowserElement::FindAll(const nsAString& aSearchString,
+                          BrowserFindCaseSensitivity aCaseSensitivity,
+                          ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
+  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));
+
+  uint32_t caseSensitivity;
+  if (aCaseSensitivity == BrowserFindCaseSensitivity::Case_insensitive) {
+    caseSensitivity = nsIBrowserElementAPI::FIND_CASE_INSENSITIVE;
+  } else {
+    caseSensitivity = nsIBrowserElementAPI::FIND_CASE_SENSITIVE;
+  }
+
+  nsresult rv = mBrowserElementAPI->FindAll(aSearchString, caseSensitivity);
+
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+  }
+}
+
+void
+nsBrowserElement::FindNext(BrowserFindDirection aDirection,
+                          ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
+  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));
+
+  uint32_t direction;
+  if (aDirection == BrowserFindDirection::Backward) {
+    direction = nsIBrowserElementAPI::FIND_BACKWARD;
+  } else {
+    direction = nsIBrowserElementAPI::FIND_FORWARD;
+  }
+
+  nsresult rv = mBrowserElementAPI->FindNext(direction);
+
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+  }
+}
+
+void
+nsBrowserElement::ClearMatch(ErrorResult& aRv)
+{
+  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
+  NS_ENSURE_TRUE_VOID(IsNotWidgetOrThrow(aRv));
+
+  nsresult rv = mBrowserElementAPI->ClearMatch();
+
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+  }
+}
+
+void
 nsBrowserElement::AddNextPaintListener(BrowserElementNextPaintEventCallback& aListener,
                                        ErrorResult& aRv)
 {
   NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
 
   CallbackObjectHolder<BrowserElementNextPaintEventCallback,
                        nsIBrowserElementNextPaintListener> holder(&aListener);
   nsCOMPtr<nsIBrowserElementNextPaintListener> listener = holder.ToXPCOMCallback();
--- a/dom/html/nsBrowserElement.h
+++ b/dom/html/nsBrowserElement.h
@@ -15,16 +15,18 @@
 class nsFrameLoader;
 
 namespace mozilla {
 
 namespace dom {
 struct BrowserElementDownloadOptions;
 class BrowserElementNextPaintEventCallback;
 class DOMRequest;
+enum class BrowserFindCaseSensitivity: uint32_t;
+enum class BrowserFindDirection: uint32_t;
 } // namespace dom
 
 class ErrorResult;
 
 /**
  * A helper class for browser-element frames
  */
 class nsBrowserElement
@@ -75,16 +77,21 @@ public:
                 ErrorResult& aRv);
 
   void Zoom(float aZoom, ErrorResult& aRv);
 
   already_AddRefed<dom::DOMRequest> GetCanGoBack(ErrorResult& aRv);
   already_AddRefed<dom::DOMRequest> GetCanGoForward(ErrorResult& aRv);
   already_AddRefed<dom::DOMRequest> GetContentDimensions(ErrorResult& aRv);
 
+  void FindAll(const nsAString& aSearchString, dom::BrowserFindCaseSensitivity aCaseSensitivity,
+               ErrorResult& aRv);
+  void FindNext(dom::BrowserFindDirection aDirection, ErrorResult& aRv);
+  void ClearMatch(ErrorResult& aRv);
+
   void AddNextPaintListener(dom::BrowserElementNextPaintEventCallback& listener,
                             ErrorResult& aRv);
   void RemoveNextPaintListener(dom::BrowserElementNextPaintEventCallback& listener,
                                ErrorResult& aRv);
 
   already_AddRefed<dom::DOMRequest> SetInputMethodActive(bool isActive,
                                                          ErrorResult& aRv);
 
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -2513,16 +2513,17 @@ BackgroundCursorChild::HandleResponse(
   MOZ_ASSERT(mObjectStore);
   MOZ_ASSERT(!mStrongRequest);
   MOZ_ASSERT(!mStrongCursor);
 
   // XXX Fix this somehow...
   auto& response = const_cast<ObjectStoreCursorResponse&>(aResponse);
 
   StructuredCloneReadInfo cloneReadInfo(Move(response.cloneInfo()));
+  cloneReadInfo.mDatabase = mTransaction->Database();
 
   ConvertActorsToBlobs(mTransaction->Database(),
                        response.cloneInfo(),
                        cloneReadInfo.mFiles);
 
   nsRefPtr<IDBCursor> newCursor;
 
   if (mCursor) {
@@ -2574,16 +2575,17 @@ BackgroundCursorChild::HandleResponse(co
   MOZ_ASSERT(mIndex);
   MOZ_ASSERT(!mStrongRequest);
   MOZ_ASSERT(!mStrongCursor);
 
   // XXX Fix this somehow...
   auto& response = const_cast<IndexCursorResponse&>(aResponse);
 
   StructuredCloneReadInfo cloneReadInfo(Move(response.cloneInfo()));
+  cloneReadInfo.mDatabase = mTransaction->Database();
 
   ConvertActorsToBlobs(mTransaction->Database(),
                        aResponse.cloneInfo(),
                        cloneReadInfo.mFiles);
 
   nsRefPtr<IDBCursor> newCursor;
 
   if (mCursor) {
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -362,25 +362,24 @@ IDBFactory::AllowedForWindowInternal(nsP
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
   MOZ_ASSERT(sop);
 
   nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
   if (NS_WARN_IF(!principal)) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
-  if (nsContentUtils::IsSystemPrincipal(principal)) {
-    principal.forget(aPrincipal);
-    return NS_OK;
+  bool isSystemPrincipal;
+  if (!AllowedForPrincipal(principal, &isSystemPrincipal)) {
+    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
-  bool isNullPrincipal;
-  if (NS_WARN_IF(NS_FAILED(principal->GetIsNullPrincipal(&isNullPrincipal))) ||
-      isNullPrincipal) {
-    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  if (isSystemPrincipal) {
+    principal.forget(aPrincipal);
+    return NS_OK;
   }
 
   // Whitelist about:home, since it doesn't have a base domain it would not
   // pass the ThirdPartyUtil check, though it should be able to use indexedDB.
   bool skipThirdPartyCheck = false;
 
   nsCOMPtr<nsIURI> uri;
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(principal->GetURI(getter_AddRefs(uri))));
@@ -419,16 +418,46 @@ IDBFactory::AllowedForWindowInternal(nsP
       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
   }
 
   principal.forget(aPrincipal);
   return NS_OK;
 }
 
+// static
+bool
+IDBFactory::AllowedForPrincipal(nsIPrincipal* aPrincipal,
+                                bool* aIsSystemPrincipal)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aPrincipal);
+
+  if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) {
+    return false;
+  }
+
+  if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
+    if (aIsSystemPrincipal) {
+      *aIsSystemPrincipal = true;
+    }
+    return true;
+  } else if (aIsSystemPrincipal) {
+    *aIsSystemPrincipal = false;
+  }
+
+  bool isNullPrincipal;
+  if (NS_WARN_IF(NS_FAILED(aPrincipal->GetIsNullPrincipal(&isNullPrincipal))) ||
+      isNullPrincipal) {
+    return false;
+  }
+
+  return true;
+}
+
 #ifdef DEBUG
 
 void
 IDBFactory::AssertIsOnOwningThread() const
 {
   MOZ_ASSERT(mOwningThread);
   MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
 }
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -100,16 +100,20 @@ public:
                   JS::Handle<JSObject*> aOwningObject,
                   const PrincipalInfo& aPrincipalInfo,
                   uint64_t aInnerWindowID,
                   IDBFactory** aFactory);
 
   static bool
   AllowedForWindow(nsPIDOMWindow* aWindow);
 
+  static bool
+  AllowedForPrincipal(nsIPrincipal* aPrincipal,
+                      bool* aIsSystemPrincipal = nullptr);
+
   void
   AssertIsOnOwningThread() const
 #ifdef DEBUG
   ;
 #else
   { }
 #endif
 
--- a/dom/indexedDB/test/mochitest.ini
+++ b/dom/indexedDB/test/mochitest.ini
@@ -7,16 +7,18 @@ support-files =
   error_events_abort_transactions_iframe.html
   event_propagation_iframe.html
   exceptions_in_events_iframe.html
   file.js
   file_app_isolation.html