Merge m-c into larch. a=merge draft
authorZibi Braniecki <gandalf@mozilla.com>
Mon, 28 Nov 2016 09:53:08 -0800
changeset 444732 76d3407b49c95aa16114e7e3d71193f8bfbe8958
parent 444731 48fcc7fe4e16d0c7e233d5d94b4732b99b91c136 (current diff)
parent 444725 8387a4ada9a5c4cab059d8fafe0f8c933e83c149 (diff)
child 444733 4f5d33691ade62b1bf62412c6480078da2c0809b
child 444760 1f40b3f95bf388a55d9cb4c2dc2146b660d14adf
child 445547 1acba9b395d6075475428f78c2c4c9d285a61f7a
push id37340
push userzbraniecki@mozilla.com
push dateMon, 28 Nov 2016 18:07:46 +0000
reviewersmerge
milestone53.0a1
Merge m-c into larch. a=merge MozReview-Commit-ID: BMa8dFOOig3
b2g/components/B2GAppMigrator.js
b2g/components/UpdatePrompt.js
b2g/components/test/mochitest/test_permission_deny.html
b2g/components/test/mochitest/test_permission_gum_remember.html
browser/base/content/browser-places.js
browser/base/content/browser.js
browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js
browser/installer/package-manifest.in
browser/themes/shared/downloads/menubutton-dropmarker.svg
browser/themes/shared/filters.svg
build/application.ini
caps/tests/mochitest/test_app_principal_equality.html
config/external/nss/Makefile.in
config/external/nss/crmf/moz.build
config/external/nss/moz.build
config/external/nss/nss.mk
config/external/nss/nss.symbols
devtools/client/responsive.html/utils/enum.js
devtools/client/storage/test/browser_storage_dynamic_updates.js
devtools/client/webconsole/new-console-output/test/requireHelper.js
devtools/client/webide/content/permissionstable.js
devtools/client/webide/content/permissionstable.xhtml
devtools/client/webide/test/test_device_permissions.html
devtools/client/webide/themes/permissionstable.css
dom/animation/test/mozilla/file_spacing_transform.html
dom/animation/test/mozilla/test_spacing_transform.html
dom/apps/AppsService.js
dom/apps/AppsService.manifest
dom/apps/AppsServiceChild.jsm
dom/apps/AppsUtils.jsm
dom/apps/PermissionsInstaller.jsm
dom/apps/PermissionsTable.jsm
dom/apps/moz.build
dom/apps/tests/create_test_receipts.py
dom/apps/tests/head.js
dom/apps/tests/unit/test_manifestHelper.js
dom/apps/tests/unit/test_manifestSanitizer.js
dom/apps/tests/unit/test_moziapplication.js
dom/apps/tests/unit/xpcshell.ini
dom/browser-element/BrowserElementProxy.js
dom/browser-element/BrowserElementProxy.manifest
dom/browser-element/mochitest/browserElement_Proxy.js
dom/browser-element/mochitest/priority/test_Preallocated.html
dom/browser-element/mochitest/test_browserElement_inproc_Proxy.html
dom/browser-element/mochitest/test_browserElement_oop_Proxy.html
dom/html/reftests/image-load-shortcircuit.html
dom/html/test/test_img_complete.html
dom/imptests/failures/webapps/WebStorage/tests/submissions/Infraware/mochitest.ini
dom/imptests/failures/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_security.html.json
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/local_change_item_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/local_security_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/local_set_item_clear_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/local_set_item_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/session_change_item_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/session_set_item_clear_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/iframe/session_set_item_iframe.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_constructor.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_local_key.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_local_newvalue.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_local_oldvalue.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_local_storagearea.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_local_storageeventinit.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_local_url.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_session_key.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_session_newvalue.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_session_oldvalue.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_session_storagearea.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_session_storageeventinit.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_event_session_url.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_clear.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_getitem.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_key.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_length.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_removeitem.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_security.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_setitem.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_session_clear.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_session_getitem.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_session_key.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_session_length.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_session_removeitem.html
dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_session_setitem.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/storage_builtins.js
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_event_constructor_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_missing_arguments.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_builtins.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_clear_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_getitem_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_in_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_index_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_length_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_removeitem_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_local_setitem_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_builtins.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_clear_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_getitem_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_in_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_index_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_length_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_removeitem_js.html
dom/imptests/webapps/WebStorage/tests/submissions/Ms2ger/test_storage_session_setitem_js.html
dom/indexedDB/test/file_app_isolation.html
dom/indexedDB/test/file_app_isolation.js
dom/indexedDB/test/test_app_isolation_inproc.html
dom/indexedDB/test/test_app_isolation_oop.html
dom/interfaces/apps/moz.build
dom/interfaces/apps/mozIApplication.idl
dom/interfaces/apps/mozIApplicationClearPrivateDataParams.idl
dom/interfaces/apps/nsIAppsService.idl
dom/interfaces/permission/moz.build
dom/interfaces/permission/nsIPermissionPromptService.idl
dom/ipc/AppProcessChecker.cpp
dom/ipc/AppProcessChecker.h
dom/ipc/PreallocatedProcessManager.cpp
dom/ipc/PreallocatedProcessManager.h
dom/ipc/preload.js
dom/media/MediaPermissionGonk.cpp
dom/media/MediaPermissionGonk.h
dom/media/gtest/TestMediaFormatReader.cpp
dom/network/NetworkStatsDB.jsm
dom/network/NetworkStatsManager.js
dom/network/NetworkStatsManager.manifest
dom/network/NetworkStatsService.jsm
dom/network/NetworkStatsServiceProxy.js
dom/network/NetworkStatsServiceProxy.manifest
dom/network/interfaces/nsINetworkStatsServiceProxy.idl
dom/network/tests/unit_stats/test_networkstats_db.js
dom/network/tests/unit_stats/test_networkstats_service.js
dom/network/tests/unit_stats/test_networkstats_service_proxy.js
dom/network/tests/unit_stats/xpcshell.ini
dom/permission/PermissionPromptService.js
dom/permission/PermissionPromptService.manifest
dom/permission/PermissionSettings.js
dom/permission/PermissionSettings.jsm
dom/permission/PermissionSettings.manifest
dom/permission/tests/file_framework.js
dom/permission/tests/file_shim.html
dom/permission/tests/mochitest-time.ini
dom/permission/tests/test_browser.html
dom/permission/tests/test_embed-apps.html
dom/permission/tests/test_idle.html
dom/permission/tests/test_input-manage.html
dom/permission/tests/test_keyboard.html
dom/permission/tests/test_networkstats-manage.html
dom/permission/tests/test_permissions.html
dom/permission/tests/test_power.html
dom/permission/tests/test_presentation-device-manage.html
dom/permission/tests/test_systemXHR.html
dom/permission/tests/test_tcp-socket.html
dom/permission/tests/test_time.html
dom/permission/tests/test_udp-socket.html
dom/permission/tests/unit/test_bug808734.js
dom/permission/tests/unit/xpcshell.ini
dom/plugins/test/testplugin/silverlightplugin/Info.plist
dom/plugins/test/testplugin/silverlightplugin/moz.build
dom/plugins/test/testplugin/silverlightplugin/nptest.def
dom/plugins/test/testplugin/silverlightplugin/nptest.rc
dom/plugins/test/testplugin/silverlightplugin/nptest_name.cpp
dom/speakermanager/SpeakerManager.cpp
dom/speakermanager/SpeakerManager.h
dom/speakermanager/SpeakerManagerService.cpp
dom/speakermanager/SpeakerManagerService.h
dom/speakermanager/SpeakerManagerServiceChild.cpp
dom/speakermanager/SpeakerManagerServiceChild.h
dom/speakermanager/moz.build
dom/speakermanager/tests/mochitest.ini
dom/speakermanager/tests/test_speakermanager.html
dom/system/SystemUpdate.manifest
dom/system/SystemUpdateManager.js
dom/system/SystemUpdateService.jsm
dom/system/gonk/tests/marionette/test_fakevolume.js
dom/system/nsISystemUpdateProvider.idl
dom/system/tests/preload-SystemUpdateManager-jsm.js
dom/system/tests/test_system_update_enabled.html
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/BrowserElementProxy.webidl
dom/webidl/MozNetworkStats.webidl
dom/webidl/MozNetworkStatsAlarm.webidl
dom/webidl/MozNetworkStatsData.webidl
dom/webidl/MozNetworkStatsInterface.webidl
dom/webidl/MozNetworkStatsManager.webidl
dom/webidl/MozSpeakerManager.webidl
dom/webidl/PermissionSettings.webidl
dom/webidl/Pose.webidl
dom/webidl/SystemUpdate.webidl
dom/workers/test/script_bug1301094.js
gfx/angle/src/compiler/preprocessor/pp_utils.h
gfx/angle/src/libANGLE/renderer/Format.cpp
gfx/angle/src/libANGLE/renderer/Format_autogen.cpp
gfx/layers/ipc/GonkNativeHandle.cpp
gfx/layers/ipc/GonkNativeHandle.h
gfx/layers/ipc/GonkNativeHandleUtils.cpp
gfx/layers/ipc/GonkNativeHandleUtils.h
image/test/reftest/blob/blob-uri-with-ref-param-notref.html
image/test/reftest/blob/blob-uri-with-ref-param.html
image/test/reftest/blob/image.png
image/test/reftest/blob/reftest-stylo.list
image/test/reftest/blob/reftest.list
js/src/builtin/IntlTzData.js
js/src/jit-test/tests/wasm/spec.js
js/src/tests/Intl/DateTimeFormat/timeZone_link.js
js/src/tests/ecma_7/AsyncFunctions/BoundNames.js
js/src/tests/ecma_7/AsyncFunctions/EarlyErrors.js
js/src/tests/ecma_7/AsyncFunctions/arguments_callee.js
js/src/tests/ecma_7/AsyncFunctions/async-contains-unicode-escape.js
js/src/tests/ecma_7/AsyncFunctions/clone.js
js/src/tests/ecma_7/AsyncFunctions/constructor.js
js/src/tests/ecma_7/AsyncFunctions/identity.js
js/src/tests/ecma_7/AsyncFunctions/length.js
js/src/tests/ecma_7/AsyncFunctions/methods.js
js/src/tests/ecma_7/AsyncFunctions/property.js
js/src/tests/ecma_7/AsyncFunctions/semantics.js
js/src/tests/ecma_7/AsyncFunctions/shell.js
js/src/tests/ecma_7/AsyncFunctions/syntax-arrow.js
js/src/tests/ecma_7/AsyncFunctions/syntax-modules.js
js/src/tests/ecma_7/AsyncFunctions/syntax.js
js/src/tests/ecma_7/AsyncFunctions/toString.js
js/src/tests/ecma_7/AsyncFunctions/yield.js
js/src/wasm/WasmBinaryFormat.cpp
js/src/wasm/WasmBinaryFormat.h
js/xpconnect/tests/chrome/test_wrappers-2.xul
js/xpconnect/tests/unit/xpcshell.ini
layout/base/ActiveLayerTracker.cpp
layout/base/ActiveLayerTracker.h
layout/base/BorderCache.h
layout/base/BorderConsts.h
layout/base/DashedCornerFinder.cpp
layout/base/DashedCornerFinder.h
layout/base/DisplayItemClip.cpp
layout/base/DisplayItemClip.h
layout/base/DisplayItemScrollClip.cpp
layout/base/DisplayItemScrollClip.h
layout/base/DisplayListClipState.cpp
layout/base/DisplayListClipState.h
layout/base/DottedCornerFinder.cpp
layout/base/DottedCornerFinder.h
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/LayerState.h
layout/base/MaskLayerImageCache.cpp
layout/base/MaskLayerImageCache.h
layout/base/PaintTracker.cpp
layout/base/PaintTracker.h
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/base/nsCSSRenderingBorders.cpp
layout/base/nsCSSRenderingBorders.h
layout/base/nsDisplayItemTypes.h
layout/base/nsDisplayItemTypesList.h
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsDisplayListInvalidation.cpp
layout/base/nsDisplayListInvalidation.h
layout/reftests/backgrounds/fixed-bg-inside-transform-ref.html
layout/reftests/backgrounds/fixed-bg-inside-transform.html
layout/reftests/details-summary/disabled-no-summary-ref.html
layout/reftests/details-summary/disabled-single-summary-ref.html
layout/style/test/test_flexbox_min_size_auto.html
layout/svg/resources/content/svgBindings.xml
media/gmp-clearkey/0.1/AudioDecoder.cpp
media/gmp-clearkey/0.1/AudioDecoder.h
media/gmp-clearkey/0.1/WMFAACDecoder.cpp
media/gmp-clearkey/0.1/WMFAACDecoder.h
media/libcubeb/tests/common.h
media/libcubeb/tests/moz.build
media/libcubeb/tests/test_audio.cpp
media/libcubeb/tests/test_devices.cpp
media/libcubeb/tests/test_duplex.cpp
media/libcubeb/tests/test_latency.cpp
media/libcubeb/tests/test_record.cpp
media/libcubeb/tests/test_resampler.cpp
media/libcubeb/tests/test_sanity.cpp
media/libcubeb/tests/test_tone.cpp
media/libcubeb/tests/test_utils.cpp
media/webrtc/signaling/test/jsep_session_unittest.cpp
media/webrtc/signaling/test/jsep_track_unittest.cpp
media/webrtc/signaling/test/sdp_unittests.cpp
mobile/android/installer/package-manifest.in
moz.build
netwerk/base/rust-url-capi/src/string_utils.rs
netwerk/test/unit_ipc/child_app_offline_notifications.js
old-configure.in
python/mozbuild/mozbuild/test/frontend/data/test-python-unit-test-missing/moz.build
security/nss/cmd/pk11ectest/testvecs.h
security/nss/coreconf/pkg_config.py
security/nss/fuzz/Makefile
security/nss/fuzz/common.mk
security/nss/fuzz/libFuzzer/Makefile
security/nss/fuzz/libFuzzer/config.mk
security/nss/fuzz/libFuzzer/manifest.mn
security/nss/fuzz/manifest.mn
security/nss/fuzz/nssfuzz/Makefile
security/nss/fuzz/nssfuzz/cert_target.cc
security/nss/fuzz/nssfuzz/manifest.mn
security/nss/fuzz/nssfuzz/nssfuzz.cc
security/nss/fuzz/nssfuzz/pkcs8_target.cc
security/nss/fuzz/nssfuzz/registry.h
security/nss/fuzz/nssfuzz/shared.h
security/nss/fuzz/nssfuzz/spki_target.cc
security/nss/lib/freebl/mpi/mpi-test.c
security/nss/lib/freebl/mpi/test-info.c
security/nss/tests/run.sh
startupcache/test/TestStartupCacheTelemetry.js
startupcache/test/TestStartupCacheTelemetry.manifest
storage/test/storage_test_harness.h
storage/test/storage_test_harness_tail.h
storage/test/test_AsXXX_helpers.cpp
storage/test/test_StatementCache.cpp
storage/test/test_asyncStatementExecution_transaction.cpp
storage/test/test_async_callbacks_with_spun_event_loops.cpp
storage/test/test_binding_params.cpp
storage/test/test_deadlock_detector.cpp
storage/test/test_file_perms.cpp
storage/test/test_mutex.cpp
storage/test/test_service_init_background_thread.cpp
storage/test/test_statement_scoper.cpp
storage/test/test_transaction_helper.cpp
storage/test/test_true_async.cpp
storage/test/test_unlock_notify.cpp
testing/docker/desktop1604-test/bin/run-wizard
testing/marionette/components/MarionetteComponents.manifest
testing/marionette/components/marionettecomponent.js
testing/marionette/harness/docs/Makefile
testing/marionette/harness/docs/advanced/actions.rst
testing/marionette/harness/docs/advanced/debug.rst
testing/marionette/harness/docs/advanced/findelement.rst
testing/marionette/harness/docs/advanced/landing.rst
testing/marionette/harness/docs/advanced/stale.rst
testing/marionette/harness/docs/basics.rst
testing/marionette/harness/docs/conf.py
testing/marionette/harness/docs/index.rst
testing/marionette/harness/docs/interactive.rst
testing/marionette/harness/docs/make.bat
testing/marionette/harness/docs/reference.rst
testing/marionette/harness/marionette/atoms/b2g_update_test.js
testing/marionette/harness/marionette/runner/httpd.py
testing/marionette/harness/marionette/runner/mixins/endurance.py
testing/marionette/harness/marionette/runner/mixins/reporting.py
testing/marionette/harness/marionette/runner/mixins/resources/htmlreport/jquery.js
testing/marionette/harness/marionette/runner/mixins/resources/htmlreport/main.js
testing/marionette/harness/marionette/runner/mixins/resources/htmlreport/style.css
testing/marionette/harness/marionette/runner/mixins/xmlgen.py
testing/marionette/harness/marionette/tests/unit/test_element_touch.py
testing/marionette/harness/marionette/tests/unit/test_gesture.py
testing/marionette/harness/marionette/tests/unit/test_httpd.py
testing/marionette/harness/marionette/tests/unit/test_multi_finger.py
testing/marionette/harness/marionette/tests/unit/test_single_finger.py
testing/marionette/harness/marionette/tests/unit/test_using_prefs.py
testing/marionette/harness/marionette/tests/update-tests.ini
testing/marionette/harness/marionette/venv_b2g_update_test.sh
testing/mozbase/mozprofile/mozprofile/webapps.py
testing/mozbase/mozprofile/tests/files/webapps1.json
testing/mozbase/mozprofile/tests/files/webapps2.json
testing/mozbase/mozprofile/tests/test_webapps.py
testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/__init__.py
testing/mozbase/mozsystemmonitor/mozsystemmonitor/test/test_resource_monitor.py
testing/mozbase/test-manifest.ini
testing/mozbase/test.py
testing/mozharness/configs/builds/releng_sub_linux_configs/64_tsan.py
testing/mozharness/configs/builds/releng_sub_mac_configs/64_cross_opt.py
testing/mozharness/configs/marionette/automation_emulator_config.py
testing/mozharness/configs/marionette/gaia_ui_test_emu_config.py
testing/mozharness/configs/marionette/gaia_ui_test_prod_config.py
testing/mozharness/mozharness/mozilla/gaia.py
testing/mozharness/mozharness/mozilla/testing/gaia_test.py
testing/profiles/webapps_mochitest.json
testing/talos/talos/tests/svgx/composite-scale-opacity.svg
testing/talos/talos/tests/svgx/composite-scale-rotate-opacity.svg
testing/talos/talos/tests/svgx/composite-scale-rotate.svg
testing/talos/talos/tests/svgx/composite-scale.svg
testing/talos/talos/tests/svgx/gearflowers.svg
testing/web-platform/harness/requirements_b2g.txt
testing/web-platform/harness/wptrunner/browsers/b2g.py
testing/web-platform/meta/XMLHttpRequest/XMLHttpRequest-withCredentials.any.js.ini
testing/web-platform/meta/battery-status/battery-charging-manual.html.ini
testing/web-platform/meta/battery-status/battery-discharging-manual.html.ini
testing/web-platform/meta/battery-status/battery-full-manual.html.ini
testing/web-platform/meta/battery-status/battery-plugging-in-manual.html.ini
testing/web-platform/meta/battery-status/battery-unplugging-manual.html.ini
testing/web-platform/meta/battery-status/support-iframe-initial.html.ini
testing/web-platform/meta/battery-status/support-iframe.html.ini
testing/web-platform/meta/battery-status/support-window-open.html.ini
testing/web-platform/meta/dom/events/Event-subclasses-constructors.html.ini
testing/web-platform/meta/html/browsers/the-window-object/security-window/window-security.sub.html.ini
testing/web-platform/meta/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html.ini
testing/web-platform/meta/html/dom/documents/dom-tree-accessors/Document.currentScript.sub.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html.ini
testing/web-platform/meta/html/semantics/forms/the-input-element/radio.html.ini
testing/web-platform/meta/html/semantics/grouping-content/the-ol-element/ol.start-reflection-2.html.ini
testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini
testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini
testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID.worker.js.ini
testing/web-platform/meta/mediacapture-streams/MediaStream-id-manual.https.html.ini
testing/web-platform/meta/url/url-domainToUnicode.html.ini
testing/web-platform/meta/webvtt/webvtt-api-for-browsers/vttcue-interface/line.html.ini
testing/web-platform/meta/workers/interfaces/WorkerUtils/navigator/window-only.worker.js.ini
testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm
testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm
testing/web-platform/tests/conformance-checkers/html/elements/dl/model-isvalid.html
testing/web-platform/tests/conformance-checkers/html/elements/dl/model-novalid.html
testing/web-platform/tests/dom/ranges/Range-mutations.html
testing/web-platform/tests/encrypted-media/scripts/playback-temporary-multikey-multisession.js
testing/web-platform/tests/fetch/api/request/request-cache.html
testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm
testing/web-platform/tests/html/browsers/the-window-object/security-window/window-security.sub.html
testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html
testing/web-platform/tests/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.sub.html
testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.sub.html
testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html
testing/web-platform/tests/svg/import/shapes-rect-01-t-manual.svg
testing/web-platform/tests/url/url-domainToUnicode.html
testing/web-platform/tests/workers/interfaces/WorkerUtils/navigator/window-only.worker.js
toolkit/components/extensions/test/mochitest/test_ext_cookies_permissions.html
toolkit/components/places/tests/cpp/mock_Link.h
toolkit/components/places/tests/cpp/moz.build
toolkit/components/places/tests/cpp/places_test_harness.h
toolkit/components/places/tests/cpp/places_test_harness_tail.h
toolkit/components/places/tests/cpp/test_IHistory.cpp
toolkit/content/jar.mn
toolkit/mozapps/update/tests/marionette/.eslintrc.js
toolkit/mozapps/update/tests/marionette/data/bad.xml
toolkit/mozapps/update/tests/marionette/data/err.cgi
toolkit/mozapps/update/tests/marionette/update-smoketests.ini
toolkit/mozapps/update/tests/marionette/update-tests.ini
toolkit/mozapps/update/tests/marionette/update_smoketest_ota_same_version.js
toolkit/mozapps/update/tests/marionette/update_smoketest_ota_same_version.py
toolkit/mozapps/update/tests/marionette/update_smoketest_ota_simple.js
toolkit/mozapps/update/tests/marionette/update_smoketest_ota_simple.py
toolkit/mozapps/update/tests/marionette/update_test_ota_simple.js
toolkit/mozapps/update/tests/marionette/update_test_ota_simple.py
toolkit/mozapps/update/tests/marionette/update_test_status.js
toolkit/mozapps/update/tests/marionette/update_test_status.py
toolkit/themes/osx/global/filters.svg
toolkit/themes/shared/media/closeCaptionButton.png
toolkit/themes/shared/media/closeCaptionButton@2x.png
toolkit/themes/shared/media/fullscreenButton.png
toolkit/themes/shared/media/fullscreenButton@2x.png
toolkit/themes/shared/media/muteButton.png
toolkit/themes/shared/media/muteButton@2x.png
toolkit/themes/shared/media/noAudio.png
toolkit/themes/shared/media/noAudio@2x.png
toolkit/themes/shared/media/pauseButton.png
toolkit/themes/shared/media/pauseButton@2x.png
toolkit/themes/shared/media/playButton.png
toolkit/themes/shared/media/playButton@2x.png
toolkit/themes/shared/media/scrubberThumb.png
toolkit/themes/shared/media/scrubberThumb@2x.png
toolkit/themes/shared/media/scrubberThumbWide.png
toolkit/themes/shared/media/scrubberThumbWide@2x.png
toolkit/themes/shared/media/unmuteButton.png
toolkit/themes/shared/media/unmuteButton@2x.png
toolkit/themes/shared/media/volume-empty.png
toolkit/themes/shared/media/volume-empty@2x.png
toolkit/themes/shared/media/volume-full.png
toolkit/themes/shared/media/volume-full@2x.png
widget/cocoa/nsMenuBarX.h
widget/cocoa/nsMenuBarX.mm
widget/cocoa/nsMenuX.mm
xpcom/components/nsNativeModuleLoader.cpp
xpcom/components/nsNativeModuleLoader.h
xpcom/tests/bug656331_component/TestComponent.cpp
xpcom/tests/bug656331_component/bug656331.manifest
xpcom/tests/bug656331_component/moz.build
xpcom/tests/component/TestComponent.cpp
xpcom/tests/component/moz.build
xpcom/tests/component/testcomponent.manifest
xpcom/tests/component_no_aslr/Makefile.in
xpcom/tests/component_no_aslr/TestComponent.cpp
xpcom/tests/component_no_aslr/moz.build
xpcom/tests/component_no_aslr/testcompnoaslr.manifest
xpcom/tests/unit/test_comp_no_aslr.js
xpcom/tests/unit/test_compmgr_warnings.js
new file mode 100644
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,16 @@
+# Checks run by clang-tidy over Mozilla code.
+
+# The following checks are currently enabled:
+# * modernize-raw-string-literal -
+#     Replace string literals containing escaped characters with raw string literals
+# * modernize-use-bool-literals
+#     Replace integer literals which are cast to bool
+# * modernize-loop-convert
+#     Converts for(...; ...; ...) loops to use the new range-based loops in C++11
+# * modernize-use-default
+#     Replace default bodies of special member functions with = default;
+# * modernize-use-override
+#     Use C++11's override and remove virtual where applicable
+
+Checks:          '-*, modernize-raw-string-literal, modernize-use-bool-literals, modernize-loop-convert, modernize-use-default, modernize-use-override'
+
--- a/.eslintignore
+++ b/.eslintignore
@@ -113,18 +113,22 @@ devtools/server/actors/**
 !devtools/server/actors/inspector.js
 !devtools/server/actors/highlighters/css-grid.js
 !devtools/server/actors/highlighters/eye-dropper.js
 !devtools/server/actors/layout.js
 !devtools/server/actors/string.js
 !devtools/server/actors/styles.js
 !devtools/server/actors/webbrowser.js
 !devtools/server/actors/webextension.js
+!devtools/server/actors/webextension-inspected-window.js
 devtools/server/performance/**
-devtools/server/tests/**
+devtools/server/tests/browser/**
+!devtools/server/tests/browser/browser_webextension_inspected_window.js
+devtools/server/tests/mochitest/**
+devtools/server/tests/unit/**
 devtools/shared/*.js
 !devtools/shared/async-storage.js
 !devtools/shared/async-utils.js
 !devtools/shared/defer.js
 !devtools/shared/event-emitter.js
 !devtools/shared/indentation.js
 !devtools/shared/loader-plugin-raw.jsm
 !devtools/shared/task.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -6,9 +6,12 @@ module.exports = {
     "mozilla"
   ],
   "rules": {
     "mozilla/import-globals": "warn",
   },
   "env": {
     "es6": true
   },
+  "parserOptions": {
+    "ecmaVersion": 8,
+  },
 };
--- a/.gdbinit
+++ b/.gdbinit
@@ -11,16 +11,17 @@ handle SIG32 noprint nostop pass
 handle SIG33 noprint nostop pass
 handle SIGPIPE noprint nostop pass
 
 # Don't stop for certain other signals where it's not useful,
 # such as the SIG64 signals triggered by the Linux
 # sandboxing code on older kernels.
 handle SIG38 noprint nostop pass
 handle SIG64 noprint nostop pass
+handle SIGSYS noprint nostop pass
 
 # Show the concrete types behind nsIFoo
 set print object on
 
 # run when using the auto-solib-add trick
 def prun
         tbreak main
         run
--- a/Makefile.in
+++ b/Makefile.in
@@ -170,17 +170,17 @@ install-manifests: faster
 faster: install-dist/idl
 	$(MAKE) -C faster FASTER_RECURSIVE_MAKE=1
 endif
 
 .PHONY: tup
 tup:
 	$(call BUILDSTATUS,TIERS make tup)
 	$(call BUILDSTATUS,TIER_START make)
-	$(MAKE) install-manifests buildid.h source-repo.h
+	$(MAKE) buildid.h source-repo.h
 	$(call BUILDSTATUS,TIER_FINISH make)
 	$(call BUILDSTATUS,TIER_START tup)
 	@$(TUP) $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),,--verbose)
 	$(call BUILDSTATUS,TIER_FINISH tup)
 
 # process_install_manifest needs to be invoked with --no-remove when building
 # js as standalone because automated builds are building nspr separately and
 # that would remove the resulting files.
@@ -257,16 +257,24 @@ include $(topsrcdir)/testing/testsuite-t
 endif
 endif
 
 default all::
 	$(call BUILDSTATUS,TIERS $(TIERS) $(if $(MOZ_AUTOMATION),$(MOZ_AUTOMATION_TIERS)))
 
 include $(topsrcdir)/config/rules.mk
 
+ifdef SCCACHE_VERBOSE_STATS
+# This won't contain stats for both halves of a universal build, but I can live with that.
+default::
+	@echo "===SCCACHE STATS==="
+	-$(CCACHE) --show-stats
+	@echo "==================="
+endif
+
 distclean::
 	$(RM) $(DIST_GARBAGE)
 
 ifeq ($(OS_ARCH),WINNT)
 # we want to copy PDB files on Windows
 MAKE_SYM_STORE_ARGS := -c --vcs-info
 ifdef PDBSTR_PATH
 MAKE_SYM_STORE_ARGS += -i
--- a/accessible/base/AccEvent.cpp
+++ b/accessible/base/AccEvent.cpp
@@ -37,17 +37,33 @@ AccEvent::AccEvent(uint32_t aEventType, 
     mIsFromUserInput = EventStateManager::IsHandlingUserInput();
   else
     mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent cycle collection
 
-NS_IMPL_CYCLE_COLLECTION(AccEvent, mAccessible)
+NS_IMPL_CYCLE_COLLECTION_CLASS(AccEvent)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AccEvent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mAccessible)
+  if (AccTreeMutationEvent* tmEvent = downcast_accEvent(tmp)) {
+    tmEvent->SetNextEvent(nullptr);
+    tmEvent->SetPrevEvent(nullptr);
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AccEvent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAccessible)
+  if (AccTreeMutationEvent* tmEvent = downcast_accEvent(tmp)) {
+    CycleCollectionNoteChild(cb, tmEvent->NextEvent(), "mNext");
+    CycleCollectionNoteChild(cb, tmEvent->PrevEvent(), "mPrevEvent");
+  }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
 
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 // AccTextChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/base/AccEvent.h
+++ b/accessible/base/AccEvent.h
@@ -46,20 +46,16 @@ public:
     //    This event will always be emitted. This flag is used for events that
     //    don't support coalescence.
     eAllowDupes,
 
      // eCoalesceReorder : For reorder events from the same subtree or the same
      //    node, only the umbrella event on the ancestor will be emitted.
     eCoalesceReorder,
 
-     // eCoalesceMutationTextChange : coalesce text change events caused by
-     // tree mutations of the same tree level.
-    eCoalesceMutationTextChange,
-
     // eCoalesceOfSameType : For events of the same type, only the newest event
     // will be processed.
     eCoalesceOfSameType,
 
     // eCoalesceSelectionChange: coalescence of selection change events.
     eCoalesceSelectionChange,
 
     // eCoalesceStateChange: coalesce state change events.
@@ -93,16 +89,17 @@ public:
 
   /**
    * Down casting.
    */
   enum EventGroup {
     eGenericEvent,
     eStateChangeEvent,
     eTextChangeEvent,
+    eTreeMutationEvent,
     eMutationEvent,
     eReorderEvent,
     eHideEvent,
     eShowEvent,
     eCaretMoveEvent,
     eTextSelChangeEvent,
     eSelectionChangeEvent,
     eTableChangeEvent,
@@ -128,16 +125,17 @@ protected:
   bool mIsFromUserInput;
   uint32_t mEventType;
   EEventRule mEventRule;
   RefPtr<Accessible> mAccessible;
 
   friend class EventQueue;
   friend class EventTree;
   friend class ::nsEventShell;
+  friend class NotificationController;
 };
 
 
 /**
  * Accessible state change event.
  */
 class AccStateChangeEvent: public AccEvent
 {
@@ -199,53 +197,88 @@ public:
   const nsString& ModifiedText() const { return mModifiedText; }
 
 private:
   int32_t mStart;
   bool mIsInserted;
   nsString mModifiedText;
 
   friend class EventTree;
+  friend class NotificationController;
 };
 
+/**
+ * A base class for events related to tree mutation, either an AccMutation
+ * event, or an AccReorderEvent.
+ */
+class AccTreeMutationEvent : public AccEvent
+{
+public:
+  AccTreeMutationEvent(uint32_t aEventType, Accessible* aTarget) :
+    AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceReorder), mGeneration(0) {}
+
+  // Event
+  static const EventGroup kEventGroup = eTreeMutationEvent;
+  virtual unsigned int GetEventGroups() const override
+  {
+    return AccEvent::GetEventGroups() | (1U << eTreeMutationEvent);
+  }
+
+  void SetNextEvent(AccTreeMutationEvent* aNext) { mNextEvent = aNext; }
+  void SetPrevEvent(AccTreeMutationEvent* aPrev) { mPrevEvent = aPrev; }
+  AccTreeMutationEvent* NextEvent() const { return mNextEvent; }
+  AccTreeMutationEvent* PrevEvent() const { return mPrevEvent; }
+
+  /**
+   * A sequence number to know when this event was fired.
+   */
+  uint32_t EventGeneration() const { return mGeneration; }
+  void SetEventGeneration(uint32_t aGeneration) { mGeneration = aGeneration; }
+
+private:
+  RefPtr<AccTreeMutationEvent> mNextEvent;
+  RefPtr<AccTreeMutationEvent> mPrevEvent;
+  uint32_t mGeneration;
+};
 
 /**
  * Base class for show and hide accessible events.
  */
-class AccMutationEvent: public AccEvent
+class AccMutationEvent: public AccTreeMutationEvent
 {
 public:
   AccMutationEvent(uint32_t aEventType, Accessible* aTarget) :
-    AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceMutationTextChange)
+    AccTreeMutationEvent(aEventType, aTarget)
   {
     // Don't coalesce these since they are coalesced by reorder event. Coalesce
     // contained text change events.
     mParent = mAccessible->Parent();
   }
   virtual ~AccMutationEvent() { }
 
   // Event
   static const EventGroup kEventGroup = eMutationEvent;
   virtual unsigned int GetEventGroups() const override
   {
-    return AccEvent::GetEventGroups() | (1U << eMutationEvent);
+    return AccTreeMutationEvent::GetEventGroups() | (1U << eMutationEvent);
   }
 
   // MutationEvent
   bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
   bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
 
   Accessible* Parent() const { return mParent; }
 
 protected:
   nsCOMPtr<nsINode> mNode;
   RefPtr<Accessible> mParent;
   RefPtr<AccTextChangeEvent> mTextChangeEvent;
 
   friend class EventTree;
+  friend class NotificationController;
 };
 
 
 /**
  * Accessible hide event.
  */
 class AccHideEvent: public AccMutationEvent
 {
@@ -266,16 +299,17 @@ public:
   bool NeedsShutdown() const { return mNeedsShutdown; }
 
 protected:
   bool mNeedsShutdown;
   RefPtr<Accessible> mNextSibling;
   RefPtr<Accessible> mPrevSibling;
 
   friend class EventTree;
+  friend class NotificationController;
 };
 
 
 /**
  * Accessible show event.
  */
 class AccShowEvent: public AccMutationEvent
 {
@@ -297,29 +331,28 @@ private:
 
   friend class EventTree;
 };
 
 
 /**
  * Class for reorder accessible event. Takes care about
  */
-class AccReorderEvent : public AccEvent
+class AccReorderEvent : public AccTreeMutationEvent
 {
 public:
   explicit AccReorderEvent(Accessible* aTarget) :
-    AccEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget,
-             eAutoDetect, eCoalesceReorder) { }
+    AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget) { }
   virtual ~AccReorderEvent() { }
 
   // Event
   static const EventGroup kEventGroup = eReorderEvent;
   virtual unsigned int GetEventGroups() const override
   {
-    return AccEvent::GetEventGroups() | (1U << eReorderEvent);
+    return AccTreeMutationEvent::GetEventGroups() | (1U << eReorderEvent);
   }
 };
 
 
 /**
  * Accessible caret move event.
  */
 class AccCaretMoveEvent: public AccEvent
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -81,46 +81,65 @@ DocManager::FindAccessibleInCache(nsINod
         return accessible;
       }
     }
   }
   return nullptr;
 }
 
 void
+DocManager::RemoveFromXPCDocumentCache(DocAccessible* aDocument)
+{
+  xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
+  if (xpcDoc) {
+    xpcDoc->Shutdown();
+    mXPCDocumentCache.Remove(aDocument);
+  }
+
+  if (!HasXPCDocuments()) {
+    MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
+  }
+}
+
+void
 DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument,
                                      nsIDocument* aDOMDocument)
 {
   // We need to remove listeners in both cases, when document is being shutdown
   // or when accessibility service is being shut down as well.
   RemoveListeners(aDOMDocument);
 
   // Document will already be removed when accessibility service is shutting
   // down so we do not need to remove it twice.
   if (nsAccessibilityService::IsShutdown()) {
     return;
   }
 
-  xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
-  if (xpcDoc) {
-    xpcDoc->Shutdown();
-    mXPCDocumentCache.Remove(aDocument);
-  }
-
+  RemoveFromXPCDocumentCache(aDocument);
   mDocAccessibleCache.Remove(aDOMDocument);
 }
 
 void
-DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc)
+DocManager::RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc)
 {
   xpcAccessibleDocument* doc = GetCachedXPCDocument(aDoc);
   if (doc) {
     doc->Shutdown();
     sRemoteXPCDocumentCache->Remove(aDoc);
   }
+
+  if (sRemoteXPCDocumentCache && sRemoteXPCDocumentCache->Count() == 0) {
+    MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
+  }
+}
+
+void
+DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc)
+{
+  RemoveFromRemoteXPCDocumentCache(aDoc);
 }
 
 xpcAccessibleDocument*
 DocManager::GetXPCDocument(DocAccessible* aDocument)
 {
   if (!aDocument)
     return nullptr;
 
--- a/accessible/base/DocManager.h
+++ b/accessible/base/DocManager.h
@@ -61,16 +61,18 @@ public:
   Accessible* FindAccessibleInCache(nsINode* aNode) const;
 
   /**
    * Called by document accessible when it gets shutdown.
    */
   void NotifyOfDocumentShutdown(DocAccessible* aDocument,
                                 nsIDocument* aDOMDocument);
 
+  void RemoveFromXPCDocumentCache(DocAccessible* aDocument);
+
   /**
    * Return XPCOM accessible document.
    */
   xpcAccessibleDocument* GetXPCDocument(DocAccessible* aDocument);
   xpcAccessibleDocument* GetCachedXPCDocument(DocAccessible* aDocument) const
     { return mXPCDocumentCache.GetWeak(aDocument); }
 
   /*
@@ -90,16 +92,18 @@ public:
   static const nsTArray<DocAccessibleParent*>* TopLevelRemoteDocs()
     { return sRemoteDocuments; }
 
   /**
    * Remove the xpc document for a remote document if there is one.
    */
   static void NotifyOfRemoteDocShutdown(DocAccessibleParent* adoc);
 
+  static void RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc);
+
   /**
    * Get a XPC document for a remote document.
    */
   static xpcAccessibleDocument* GetXPCDocument(DocAccessibleParent* aDoc);
   static xpcAccessibleDocument* GetCachedXPCDocument(const DocAccessibleParent* aDoc)
   {
     return sRemoteXPCDocumentCache ? sRemoteXPCDocumentCache->GetWeak(aDoc)
       : nullptr;
@@ -118,16 +122,22 @@ protected:
    */
   bool Init();
 
   /**
    * Shutdown the manager.
    */
   void Shutdown();
 
+  bool HasXPCDocuments()
+  {
+    return mXPCDocumentCache.Count() > 0 ||
+           (sRemoteXPCDocumentCache && sRemoteXPCDocumentCache->Count() > 0);
+  }
+
 private:
   DocManager(const DocManager&);
   DocManager& operator =(const DocManager&);
 
 private:
   /**
    * Create an accessible document if it was't created and fire accessibility
    * events if needed.
--- a/accessible/base/EventQueue.cpp
+++ b/accessible/base/EventQueue.cpp
@@ -85,21 +85,25 @@ void
 EventQueue::CoalesceEvents()
 {
   NS_ASSERTION(mEvents.Length(), "There should be at least one pending event!");
   uint32_t tail = mEvents.Length() - 1;
   AccEvent* tailEvent = mEvents[tail];
 
   switch(tailEvent->mEventRule) {
     case AccEvent::eCoalesceReorder:
-      MOZ_ASSERT(tailEvent->mAccessible->IsApplication() ||
-                 tailEvent->mAccessible->IsOuterDoc() ||
-                 tailEvent->mAccessible->IsXULTree(),
+    {
+      DebugOnly<Accessible*> target = tailEvent->mAccessible.get();
+      MOZ_ASSERT(target->IsApplication() ||
+                 target->IsOuterDoc() ||
+                 target->IsXULTree(),
                  "Only app or outerdoc accessible reorder events are in the queue");
+      MOZ_ASSERT(tailEvent->GetEventType() == nsIAccessibleEvent::EVENT_REORDER, "only reorder events should be queued");
       break; // case eCoalesceReorder
+    }
 
     case AccEvent::eCoalesceOfSameType:
     {
       // Coalesce old events by newer event.
       for (uint32_t index = tail - 1; index < tail; index--) {
         AccEvent* accEvent = mEvents[index];
         if (accEvent->mEventType == tailEvent->mEventType &&
           accEvent->mEventRule == tailEvent->mEventRule) {
--- a/accessible/base/EventTree.cpp
+++ b/accessible/base/EventTree.cpp
@@ -20,17 +20,18 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 // TreeMutation class
 
 EventTree* const TreeMutation::kNoEventTree = reinterpret_cast<EventTree*>(-1);
 
 TreeMutation::TreeMutation(Accessible* aParent, bool aNoEvents) :
   mParent(aParent), mStartIdx(UINT32_MAX),
   mStateFlagsCopy(mParent->mStateFlags),
-  mEventTree(aNoEvents ? kNoEventTree : nullptr)
+  mEventTree(aNoEvents ? kNoEventTree : nullptr),
+  mQueueEvents(!aNoEvents)
 {
 #ifdef DEBUG
   mIsDone = false;
 #endif
 
 #ifdef A11Y_LOG
   if (mEventTree != kNoEventTree && logging::IsEnabled(logging::eEventTree)) {
     logging::MsgBegin("EVENTS_TREE", "reordering tree before");
@@ -57,48 +58,42 @@ void
 TreeMutation::AfterInsertion(Accessible* aChild)
 {
   MOZ_ASSERT(aChild->Parent() == mParent);
 
   if (static_cast<uint32_t>(aChild->mIndexInParent) < mStartIdx) {
     mStartIdx = aChild->mIndexInParent + 1;
   }
 
-  if (!mEventTree) {
-    mEventTree = Controller()->QueueMutation(mParent);
-    if (!mEventTree) {
-      mEventTree = kNoEventTree;
-    }
+  if (!mQueueEvents) {
+    return;
   }
 
-  if (mEventTree != kNoEventTree) {
-    mEventTree->Shown(aChild);
-    Controller()->QueueNameChange(aChild);
-  }
+  RefPtr<AccShowEvent> ev = new AccShowEvent(aChild);
+  DebugOnly<bool> added = Controller()->QueueMutationEvent(ev);
+  MOZ_ASSERT(added);
+  aChild->SetShowEventTarget(true);
 }
 
 void
 TreeMutation::BeforeRemoval(Accessible* aChild, bool aNoShutdown)
 {
   MOZ_ASSERT(aChild->Parent() == mParent);
 
   if (static_cast<uint32_t>(aChild->mIndexInParent) < mStartIdx) {
     mStartIdx = aChild->mIndexInParent;
   }
 
-  if (!mEventTree) {
-    mEventTree = Controller()->QueueMutation(mParent);
-    if (!mEventTree) {
-      mEventTree = kNoEventTree;
-    }
+  if (!mQueueEvents) {
+    return;
   }
 
-  if (mEventTree != kNoEventTree) {
-    mEventTree->Hidden(aChild, !aNoShutdown);
-    Controller()->QueueNameChange(aChild);
+  RefPtr<AccHideEvent> ev = new AccHideEvent(aChild, !aNoShutdown);
+  if (Controller()->QueueMutationEvent(ev)) {
+    aChild->SetHideEventTarget(true);
   }
 }
 
 void
 TreeMutation::Done()
 {
   MOZ_ASSERT(mParent->mStateFlags & Accessible::eKidsMutating);
   mParent->mStateFlags &= ~Accessible::eKidsMutating;
--- a/accessible/base/EventTree.h
+++ b/accessible/base/EventTree.h
@@ -44,16 +44,21 @@ private:
   static const char* PrefixLog(void* aData, Accessible*);
 #endif
 
   Accessible* mParent;
   uint32_t mStartIdx;
   uint32_t mStateFlagsCopy;
   EventTree* mEventTree;
 
+  /*
+   * True if mutation events should be queued.
+   */
+  bool mQueueEvents;
+
 #ifdef DEBUG
   bool mIsDone;
 #endif
 };
 
 
 /**
  * A mutation events coalescence structure.
@@ -62,41 +67,44 @@ class EventTree final {
 public:
   EventTree() :
     mFirst(nullptr), mNext(nullptr), mContainer(nullptr), mFireReorder(false) { }
   explicit EventTree(Accessible* aContainer, bool aFireReorder) :
     mFirst(nullptr), mNext(nullptr), mContainer(aContainer),
     mFireReorder(aFireReorder) { }
   ~EventTree() { Clear(); }
 
-  void Shown(Accessible* aChild);
-
-  void Hidden(Accessible* aChild, bool aNeedsShutdown = true);
+  void Shown(Accessible* aTarget);
+  void Hidden(Accessible*, bool);
 
   /**
    * Return an event tree node for the given accessible.
    */
   const EventTree* Find(const Accessible* aContainer) const;
 
+  /**
+   * Add a mutation event to this event tree.
+   */
+  void Mutated(AccMutationEvent* aEv);
+
 #ifdef A11Y_LOG
   void Log(uint32_t aLevel = UINT32_MAX) const;
 #endif
 
 private:
   /**
    * Processes the event queue and fires events.
    */
   void Process(const RefPtr<DocAccessible>& aDeathGrip);
 
   /**
    * Return an event subtree for the given accessible.
    */
   EventTree* FindOrInsert(Accessible* aContainer);
 
-  void Mutated(AccMutationEvent* aEv);
   void Clear();
 
   UniquePtr<EventTree> mFirst;
   UniquePtr<EventTree> mNext;
 
   Accessible* mContainer;
   nsTArray<RefPtr<AccMutationEvent>> mDependentEvents;
   bool mFireReorder;
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -19,17 +19,17 @@ using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector
 ////////////////////////////////////////////////////////////////////////////////
 
 NotificationController::NotificationController(DocAccessible* aDocument,
                                                nsIPresShell* aPresShell) :
   EventQueue(aDocument), mObservingState(eNotObservingRefresh),
-  mPresShell(aPresShell)
+  mPresShell(aPresShell), mEventGeneration(0)
 {
 #ifdef DEBUG
   mMoveGuardOnStack = false;
 #endif
 
   // Schedule initial accessible tree construction.
   ScheduleProcessing();
 }
@@ -109,16 +109,299 @@ NotificationController::QueueMutation(Ac
 {
   EventTree* tree = mEventTree.FindOrInsert(aContainer);
   if (tree) {
     ScheduleProcessing();
   }
   return tree;
 }
 
+bool
+NotificationController::QueueMutationEvent(AccTreeMutationEvent* aEvent)
+{
+  // We have to allow there to be a hide and then a show event for a target
+  // because of targets getting moved.  However we need to coalesce a show and
+  // then a hide for a target which means we need to check for that here.
+  if (aEvent->GetEventType() == nsIAccessibleEvent::EVENT_HIDE  &&
+      aEvent->GetAccessible()->ShowEventTarget()) {
+    AccTreeMutationEvent* showEvent = mMutationMap.GetEvent(aEvent->GetAccessible(), EventMap::ShowEvent);
+    DropMutationEvent(showEvent);
+    return false;
+  }
+
+  AccMutationEvent* mutEvent = downcast_accEvent(aEvent);
+  mEventGeneration++;
+  mutEvent->SetEventGeneration(mEventGeneration);
+
+  if (!mFirstMutationEvent) {
+    mFirstMutationEvent = aEvent;
+    ScheduleProcessing();
+  }
+
+  if (mLastMutationEvent) {
+    NS_ASSERTION(!mLastMutationEvent->NextEvent(), "why isn't the last event the end?");
+    mLastMutationEvent->SetNextEvent(aEvent);
+  }
+
+  aEvent->SetPrevEvent(mLastMutationEvent);
+  mLastMutationEvent = aEvent;
+  mMutationMap.PutEvent(aEvent);
+
+  // Because we could be hiding the target of a show event we need to get rid
+  // of any such events.  It may be possible to do less than coallesce all
+  // events, however that is easiest.
+  if (aEvent->GetEventType() == nsIAccessibleEvent::EVENT_HIDE) {
+    CoalesceMutationEvents();
+
+    // mLastMutationEvent will point to something other than aEvent if and only
+    // if aEvent was just coalesced away.  In that case a parent accessible
+    // must already have the required reorder and text change events so we are
+    // done here.
+    if (mLastMutationEvent != aEvent) {
+      return false;
+    }
+  }
+
+  // We need to fire a reorder event after all of the events targeted at shown or
+  // hidden children of a container.  So either queue a new one, or move an
+  // existing one to the end of the queue if the container already has a
+  // reorder event.
+  Accessible* target = aEvent->GetAccessible();
+  Accessible* container = aEvent->GetAccessible()->Parent();
+  RefPtr<AccReorderEvent> reorder;
+  if (!container->ReorderEventTarget()) {
+    reorder = new AccReorderEvent(container);
+    container->SetReorderEventTarget(true);
+    mMutationMap.PutEvent(reorder);
+
+    // Since this is the first child of container that is changing, the name of
+    // container may be changing.
+    QueueNameChange(target);
+  } else {
+    AccReorderEvent* event = downcast_accEvent(mMutationMap.GetEvent(container, EventMap::ReorderEvent));
+    reorder = event;
+    if (mFirstMutationEvent == event) {
+      mFirstMutationEvent = event->NextEvent();
+    } else {
+      event->PrevEvent()->SetNextEvent(event->NextEvent());
+    }
+
+      event->NextEvent()->SetPrevEvent(event->PrevEvent());
+      event->SetNextEvent(nullptr);
+  }
+
+  reorder->SetEventGeneration(mEventGeneration);
+  reorder->SetPrevEvent(mLastMutationEvent);
+  mLastMutationEvent->SetNextEvent(reorder);
+  mLastMutationEvent = reorder;
+
+  // It is not possible to have a text change event for something other than a
+  // hyper text accessible.
+  if (!container->IsHyperText()) {
+    return true;
+  }
+
+  MOZ_ASSERT(mutEvent);
+
+  nsString text;
+  aEvent->GetAccessible()->AppendTextTo(text);
+  if (text.IsEmpty()) {
+    return true;
+  }
+
+  int32_t offset = container->AsHyperText()->GetChildOffset(target);
+  AccTreeMutationEvent* prevEvent = aEvent->PrevEvent();
+  while (prevEvent && prevEvent->GetEventType() == nsIAccessibleEvent::EVENT_REORDER) {
+    prevEvent = prevEvent->PrevEvent();
+  }
+
+  if (prevEvent && prevEvent->GetEventType() == nsIAccessibleEvent::EVENT_HIDE &&
+      mutEvent->IsHide()) {
+    AccHideEvent* prevHide = downcast_accEvent(prevEvent);
+    AccTextChangeEvent* prevTextChange = prevHide->mTextChangeEvent;
+    if (prevTextChange) {
+      if (prevHide->mNextSibling == target) {
+        target->AppendTextTo(prevTextChange->mModifiedText);
+      } else if (prevHide->mPrevSibling == target) {
+        nsString temp;
+        target->AppendTextTo(temp);
+
+        uint32_t extraLen = temp.Length();
+        temp += prevTextChange->mModifiedText;;
+        prevTextChange->mModifiedText = temp;
+        prevTextChange->mStart -= extraLen;
+      }
+
+      prevHide->mTextChangeEvent.swap(mutEvent->mTextChangeEvent);
+    }
+  } else if (prevEvent && mutEvent->IsShow() &&
+             prevEvent->GetEventType() == nsIAccessibleEvent::EVENT_SHOW) {
+    AccShowEvent* prevShow = downcast_accEvent(prevEvent);
+    AccTextChangeEvent* prevTextChange = prevShow->mTextChangeEvent;
+    if (prevTextChange) {
+      int32_t index = target->IndexInParent();
+      int32_t prevIndex = prevShow->GetAccessible()->IndexInParent();
+      if (prevIndex + 1 == index) {
+        target->AppendTextTo(prevTextChange->mModifiedText);
+      } else if (index + 1 == prevIndex) {
+        nsString temp;
+        target->AppendTextTo(temp);
+        prevTextChange->mStart -= temp.Length();
+        temp += prevTextChange->mModifiedText;
+        prevTextChange->mModifiedText = temp;
+      }
+
+      prevShow->mTextChangeEvent.swap(mutEvent->mTextChangeEvent);
+    }
+  }
+
+  if (!mutEvent->mTextChangeEvent) {
+    mutEvent->mTextChangeEvent =
+      new AccTextChangeEvent(container, offset, text, mutEvent->IsShow(),
+                             aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
+  }
+
+  return true;
+}
+
+void
+NotificationController::DropMutationEvent(AccTreeMutationEvent* aEvent)
+{
+  // unset the event bits since the event isn't being fired any more.
+  if (aEvent->GetEventType() == nsIAccessibleEvent::EVENT_REORDER) {
+    aEvent->GetAccessible()->SetReorderEventTarget(false);
+  } else if (aEvent->GetEventType() == nsIAccessibleEvent::EVENT_SHOW) {
+    aEvent->GetAccessible()->SetShowEventTarget(false);
+  } else {
+    AccHideEvent* hideEvent = downcast_accEvent(aEvent);
+    MOZ_ASSERT(hideEvent);
+
+    if (hideEvent->NeedsShutdown()) {
+      mDocument->ShutdownChildrenInSubtree(aEvent->GetAccessible());
+    }
+  }
+
+  // Do the work to splice the event out of the list.
+  if (mFirstMutationEvent == aEvent) {
+    mFirstMutationEvent = aEvent->NextEvent();
+  } else {
+    aEvent->PrevEvent()->SetNextEvent(aEvent->NextEvent());
+  }
+
+  if (mLastMutationEvent == aEvent) {
+    mLastMutationEvent = aEvent->PrevEvent();
+  } else {
+    aEvent->NextEvent()->SetPrevEvent(aEvent->PrevEvent());
+  }
+
+  aEvent->SetPrevEvent(nullptr);
+  aEvent->SetNextEvent(nullptr);
+  mMutationMap.RemoveEvent(aEvent);
+}
+
+void
+NotificationController::CoalesceMutationEvents()
+{
+  AccTreeMutationEvent* event = mFirstMutationEvent;
+  while (event) {
+    AccTreeMutationEvent* nextEvent = event->NextEvent();
+    uint32_t eventType = event->GetEventType();
+    if (event->GetEventType() == nsIAccessibleEvent::EVENT_REORDER) {
+      Accessible* acc = event->GetAccessible();
+      while (acc) {
+        if (acc->IsDoc()) {
+          break;
+        }
+
+        // if a parent of the reorder event's target is being hidden that
+        // hide event's target must have a parent that is also a reorder event
+        // target.  That means we don't need this reorder event.
+        if (acc->HideEventTarget()) {
+          DropMutationEvent(event);
+          break;
+        }
+
+        Accessible* parent = acc->Parent();
+        if (parent->ReorderEventTarget()) {
+          AccReorderEvent* reorder = downcast_accEvent(mMutationMap.GetEvent(parent, EventMap::ReorderEvent));
+
+          // We want to make sure that a reorder event comes after any show or
+          // hide events targeted at the children of its target.  We keep the
+          // invariant that event generation goes up as you are farther in the
+          // queue, so we want to use the spot of the event with the higher
+          // generation number, and keep that generation number.
+          if (reorder && reorder->EventGeneration() < event->EventGeneration()) {
+            // There really should be a show or hide event before the first
+            // reorder event.
+            if (reorder->PrevEvent()) {
+              reorder->PrevEvent()->SetNextEvent(reorder->NextEvent());
+            } else {
+              mFirstMutationEvent = reorder->NextEvent();
+            }
+
+            reorder->NextEvent()->SetPrevEvent(reorder->PrevEvent());
+            event->PrevEvent()->SetNextEvent(reorder);
+            reorder->SetPrevEvent(event->PrevEvent());
+            event->SetPrevEvent(reorder);
+            reorder->SetNextEvent(event);
+            reorder->SetEventGeneration(event->EventGeneration());
+          }
+          DropMutationEvent(event);
+          break;
+        }
+
+        acc = parent;
+      }
+    } else if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
+      Accessible* parent = event->GetAccessible()->Parent();
+      while (parent) {
+        if (parent->IsDoc()) {
+          break;
+        }
+
+        // if the parent of a show event is being either shown or hidden then
+        // we don't need to fire a show event for a subtree of that change.
+        if (parent->ShowEventTarget() || parent->HideEventTarget()) {
+          DropMutationEvent(event);
+          break;
+        }
+
+        parent = parent->Parent();
+      }
+    } else {
+      MOZ_ASSERT(eventType == nsIAccessibleEvent::EVENT_HIDE, "mutation event list has an invalid event");
+
+      AccHideEvent* hideEvent = downcast_accEvent(event);
+      Accessible* parent = hideEvent->Parent();
+      while (parent) {
+        if (parent->IsDoc()) {
+          break;
+        }
+
+        if (parent->HideEventTarget()) {
+          DropMutationEvent(event);
+          break;
+        }
+
+        if (parent->ShowEventTarget()) {
+          AccShowEvent* showEvent = downcast_accEvent(mMutationMap.GetEvent(parent, EventMap::ShowEvent));
+          if (showEvent->EventGeneration() < hideEvent->EventGeneration()) {
+            DropMutationEvent(hideEvent);
+            break;
+          }
+        }
+
+        parent = parent->Parent();
+      }
+    }
+
+    event = nextEvent;
+  }
+}
+
 void
 NotificationController::ScheduleChildDocBinding(DocAccessible* aDocument)
 {
   // Schedule child document binding to the tree.
   mHangingChildDocuments.AppendElement(aDocument);
   ScheduleProcessing();
 }
 
@@ -167,16 +450,138 @@ NotificationController::IsUpdatePending(
 {
   return mPresShell->IsLayoutFlushObserver() ||
     mObservingState == eRefreshProcessingForUpdate ||
     mContentInsertions.Count() != 0 || mNotifications.Length() != 0 ||
     mTextHash.Count() != 0 ||
     !mDocument->HasLoadState(DocAccessible::eTreeConstructed);
 }
 
+void
+NotificationController::ProcessMutationEvents()
+{
+  // there is no reason to fire a hide event for a child of a show event
+  // target.  That can happen if something is inserted into the tree and
+  // removed before the next refresh driver tick, but it should not be
+  // observable outside gecko so it should be safe to coalesce away any such
+  // events.  This means that it should be fine to fire all of the hide events
+  // first, and then deal with any shown subtrees.
+  for (AccTreeMutationEvent* event = mFirstMutationEvent;
+       event; event = event->NextEvent()) {
+    if (event->GetEventType() != nsIAccessibleEvent::EVENT_HIDE) {
+      continue;
+    }
+
+    nsEventShell::FireEvent(event);
+    if (!mDocument) {
+      return;
+    }
+
+    AccMutationEvent* mutEvent = downcast_accEvent(event);
+    if (mutEvent->mTextChangeEvent) {
+      nsEventShell::FireEvent(mutEvent->mTextChangeEvent);
+      if (!mDocument) {
+        return;
+      }
+    }
+
+    // Fire menupopup end event before a hide event if a menu goes away.
+
+    // XXX: We don't look into children of hidden subtree to find hiding
+    // menupopup (as we did prior bug 570275) because we don't do that when
+    // menu is showing (and that's impossible until bug 606924 is fixed).
+    // Nevertheless we should do this at least because layout coalesces
+    // the changes before our processing and we may miss some menupopup
+    // events. Now we just want to be consistent in content insertion/removal
+    // handling.
+    if (event->mAccessible->ARIARole() == roles::MENUPOPUP) {
+      nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
+                              event->mAccessible);
+      if (!mDocument) {
+        return;
+      }
+    }
+
+    AccHideEvent* hideEvent = downcast_accEvent(event);
+    if (hideEvent->NeedsShutdown()) {
+      mDocument->ShutdownChildrenInSubtree(event->mAccessible);
+    }
+  }
+
+  // Group the show events by the parent of their target.
+  nsDataHashtable<nsPtrHashKey<Accessible>, nsTArray<AccTreeMutationEvent*>> showEvents;
+  for (AccTreeMutationEvent* event = mFirstMutationEvent;
+       event; event = event->NextEvent()) {
+    if (event->GetEventType() != nsIAccessibleEvent::EVENT_SHOW) {
+      continue;
+    }
+
+    Accessible* parent = event->GetAccessible()->Parent();
+    showEvents.GetOrInsert(parent).AppendElement(event);
+  }
+
+  // We need to fire show events for the children of an accessible in the order
+  // of their indices at this point.  So sort each set of events for the same
+  // container by the index of their target.
+  for (auto iter = showEvents.Iter(); !iter.Done(); iter.Next()) {
+    struct AccIdxComparator {
+      bool LessThan(const AccTreeMutationEvent* a, const AccTreeMutationEvent* b) const
+      {
+        int32_t aIdx = a->GetAccessible()->IndexInParent();
+        int32_t bIdx = b->GetAccessible()->IndexInParent();
+        MOZ_ASSERT(aIdx >= 0 && bIdx >= 0 && aIdx != bIdx);
+        return aIdx < bIdx;
+      }
+      bool Equals(const AccTreeMutationEvent* a, const AccTreeMutationEvent* b) const
+      {
+        DebugOnly<int32_t> aIdx = a->GetAccessible()->IndexInParent();
+        DebugOnly<int32_t> bIdx = b->GetAccessible()->IndexInParent();
+        MOZ_ASSERT(aIdx >= 0 && bIdx >= 0 && aIdx != bIdx);
+        return false;
+      }
+    };
+
+    nsTArray<AccTreeMutationEvent*>& events = iter.Data();
+    events.Sort(AccIdxComparator());
+    for (AccTreeMutationEvent* event: events) {
+      nsEventShell::FireEvent(event);
+      if (!mDocument) {
+        return;
+      }
+
+      AccMutationEvent* mutEvent = downcast_accEvent(event);
+      if (mutEvent->mTextChangeEvent) {
+        nsEventShell::FireEvent(mutEvent->mTextChangeEvent);
+        if (!mDocument) {
+          return;
+        }
+      }
+    }
+  }
+
+  // Now we can fire the reorder events after all the show and hide events.
+  for (AccTreeMutationEvent* event = mFirstMutationEvent;
+       event; event = event->NextEvent()) {
+    if (event->GetEventType() != nsIAccessibleEvent::EVENT_REORDER) {
+      continue;
+    }
+
+    nsEventShell::FireEvent(event);
+    if (!mDocument) {
+      return;
+    }
+
+    Accessible* target = event->GetAccessible();
+    target->Document()->MaybeNotifyOfValueChange(target);
+    if (!mDocument) {
+      return;
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector: private
 
 void
 NotificationController::WillRefresh(mozilla::TimeStamp aTime)
 {
   PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
   Telemetry::AutoTimer<Telemetry::A11Y_UPDATE_TIME> updateTimer;
@@ -392,19 +797,49 @@ NotificationController::WillRefresh(mozi
   }
   mRelocations.Clear();
 
   // If a generic notification occurs after this point then we may be allowed to
   // process it synchronously.  However we do not want to reenter if fireing
   // events causes script to run.
   mObservingState = eRefreshProcessing;
 
-  RefPtr<DocAccessible> deathGrip(mDocument);
-  mEventTree.Process(deathGrip);
-  deathGrip = nullptr;
+  CoalesceMutationEvents();
+  ProcessMutationEvents();
+  mEventGeneration = 0;
+
+  // Now that we are done with them get rid of the events we fired.
+  RefPtr<AccTreeMutationEvent> mutEvent = Move(mFirstMutationEvent);
+  mLastMutationEvent = nullptr;
+  mFirstMutationEvent = nullptr;
+  while (mutEvent) {
+    RefPtr<AccTreeMutationEvent> nextEvent = mutEvent->NextEvent();
+    Accessible* target = mutEvent->GetAccessible();
+
+    // We need to be careful here, while it may seem that we can simply 0 all
+    // the pending event bits that is not true.  Because accessibles may be
+    // reparented they may be the target of both a hide event and a show event
+    // at the same time.
+    if (mutEvent->GetEventType() == nsIAccessibleEvent::EVENT_SHOW) {
+      target->SetShowEventTarget(false);
+    }
+
+    if (mutEvent->GetEventType() == nsIAccessibleEvent::EVENT_HIDE) {
+      target->SetHideEventTarget(false);
+    }
+
+    // However it is not possible for a reorder event target to also be the
+    // target of a show or hide, so we can just zero that.
+    target->SetReorderEventTarget(false);
+
+    mutEvent->SetPrevEvent(nullptr);
+    mutEvent->SetNextEvent(nullptr);
+    mMutationMap.RemoveEvent(mutEvent);
+    mutEvent = nextEvent;
+  }
 
   ProcessEventQueue();
 
   if (IPCAccessibilityActive()) {
     size_t newDocCount = newChildDocs.Length();
     for (size_t i = 0; i < newDocCount; i++) {
       DocAccessible* childDoc = newChildDocs[i];
       Accessible* parent = childDoc->Parent();
@@ -444,8 +879,57 @@ NotificationController::WillRefresh(mozi
   if (mContentInsertions.Count() == 0 && mNotifications.IsEmpty() &&
       mEvents.IsEmpty() && mTextHash.Count() == 0 &&
       mHangingChildDocuments.IsEmpty() &&
       mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
       mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
     mObservingState = eNotObservingRefresh;
   }
 }
+
+void
+NotificationController::EventMap::PutEvent(AccTreeMutationEvent* aEvent)
+{
+  EventType type = GetEventType(aEvent);
+  uint64_t addr = reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
+  MOZ_ASSERT((addr & 0x3) == 0, "accessible is not 4 byte aligned");
+  addr |= type;
+  mTable.Put(addr, aEvent);
+}
+
+AccTreeMutationEvent*
+NotificationController::EventMap::GetEvent(Accessible* aTarget, EventType aType)
+{
+  uint64_t addr = reinterpret_cast<uintptr_t>(aTarget);
+  MOZ_ASSERT((addr & 0x3) == 0, "target is not 4 byte aligned");
+
+  addr |= aType;
+  return mTable.GetWeak(addr);
+}
+
+void
+NotificationController::EventMap::RemoveEvent(AccTreeMutationEvent* aEvent)
+{
+  EventType type = GetEventType(aEvent);
+  uint64_t addr = reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
+  MOZ_ASSERT((addr & 0x3) == 0, "accessible is not 4 byte aligned");
+  addr |= type;
+
+  MOZ_ASSERT(mTable.GetWeak(addr) == aEvent, "mTable has the wrong event");
+  mTable.Remove(addr);
+}
+
+  NotificationController::EventMap::EventType
+NotificationController::EventMap::GetEventType(AccTreeMutationEvent* aEvent)
+{
+  switch(aEvent->GetEventType())
+  {
+    case nsIAccessibleEvent::EVENT_SHOW:
+      return ShowEvent;
+    case nsIAccessibleEvent::EVENT_HIDE:
+      return HideEvent;
+    case nsIAccessibleEvent::EVENT_REORDER:
+      return ReorderEvent;
+    default:
+      MOZ_ASSERT_UNREACHABLE("event has invalid type");
+      return ShowEvent;
+  }
+}
--- a/accessible/base/NotificationController.h
+++ b/accessible/base/NotificationController.h
@@ -155,16 +155,27 @@ public:
     NotificationController* mController;
   };
 
 #ifdef A11Y_LOG
   const EventTree& RootEventTree() const { return mEventTree; };
 #endif
 
   /**
+   * Queue a mutation event to emit if not coalesced away.  Returns true if the
+   * event was queued and has not yet been coalesced.
+   */
+  bool QueueMutationEvent(AccTreeMutationEvent* aEvent);
+
+  /**
+   * Coalesce all queued mutation events.
+   */
+  void CoalesceMutationEvents();
+
+  /**
    * Schedule binding the child document to the tree of this document.
    */
   void ScheduleChildDocBinding(DocAccessible* aDocument);
 
   /**
    * Schedule the accessible tree update because of rendered text changes.
    */
   inline void ScheduleTextUpdate(nsIContent* aTextNode)
@@ -287,16 +298,26 @@ private:
   void StorePrecedingEvents(nsTArray<RefPtr<AccHideEvent>>&& aEvs)
   {
     MOZ_ASSERT(mMoveGuardOnStack, "No move guard on stack!");
     mPrecedingEvents.InsertElementsAt(0, aEvs);
   }
 
 private:
   /**
+   * get rid of a mutation event that is no longer necessary.
+   */
+  void DropMutationEvent(AccTreeMutationEvent* aEvent);
+
+  /**
+   * Fire all necessary mutation events.
+   */
+  void ProcessMutationEvents();
+
+  /**
    * Indicates whether we're waiting on an event queue processing from our
    * notification controller to flush events.
    */
   enum eObservingState {
     eNotObservingRefresh,
     eRefreshObserving,
     eRefreshProcessing,
     eRefreshProcessingForUpdate
@@ -371,14 +392,48 @@ private:
   nsTArray<RefPtr<AccHideEvent>> mPrecedingEvents;
 
 #ifdef DEBUG
   bool mMoveGuardOnStack;
 #endif
 
   friend class MoveGuard;
   friend class EventTree;
+
+  /**
+   * A list of all mutation events we may want to emit.  Ordered from the first
+   * event that should be emitted to the last one to emit.
+   */
+  RefPtr<AccTreeMutationEvent> mFirstMutationEvent;
+  RefPtr<AccTreeMutationEvent> mLastMutationEvent;
+
+  /**
+   * A class to map an accessible and event type to an event.
+   */
+  class EventMap
+  {
+  public:
+    enum EventType
+    {
+      ShowEvent = 0x0,
+      HideEvent = 0x1,
+      ReorderEvent = 0x2,
+    };
+
+    void PutEvent(AccTreeMutationEvent* aEvent);
+    AccTreeMutationEvent* GetEvent(Accessible* aTarget, EventType aType);
+    void RemoveEvent(AccTreeMutationEvent* aEvent);
+    void Clear() { mTable.Clear(); }
+
+  private:
+    EventType GetEventType(AccTreeMutationEvent* aEvent);
+
+    nsRefPtrHashtable<nsUint64HashKey, AccTreeMutationEvent> mTable;
+  };
+
+  EventMap mMutationMap;
+  uint32_t mEventGeneration;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_NotificationController_h_
--- a/accessible/base/StyleInfo.cpp
+++ b/accessible/base/StyleInfo.cpp
@@ -76,17 +76,17 @@ StyleInfo::TextIndent(nsAString& aValue)
     case eStyleUnit_Enumerated:
     case eStyleUnit_Calc:
       aValue.AppendLiteral("0px");
       break;
   }
 }
 
 void
-StyleInfo::Margin(css::Side aSide, nsAString& aValue)
+StyleInfo::Margin(Side aSide, nsAString& aValue)
 {
   MOZ_ASSERT(mElement->GetPrimaryFrame(), " mElement->GetPrimaryFrame() needs to be valid pointer");
   aValue.Truncate();
 
   nscoord coordVal = mElement->GetPrimaryFrame()->GetUsedMargin().Side(aSide);
   aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
   aValue.AppendLiteral("px");
 }
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -1810,17 +1810,18 @@ MaybeShutdownAccService(uint32_t aFormer
   nsAccessibilityService* accService =
     nsAccessibilityService::gAccessibilityService;
 
   if (!accService || accService->IsShutdown()) {
     return;
   }
 
   if (nsCoreUtils::AccEventObserversExist() ||
-      xpcAccessibilityService::IsInUse()) {
+      xpcAccessibilityService::IsInUse() ||
+      accService->HasXPCDocuments()) {
     // Still used by XPCOM
     nsAccessibilityService::gConsumers =
       (nsAccessibilityService::gConsumers & ~aFormerConsumer) |
       nsAccessibilityService::eXPCOM;
     return;
   }
 
   if (nsAccessibilityService::gConsumers & ~aFormerConsumer) {
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -104,17 +104,18 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Accessible)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(Accessible, LastRelease())
 
 Accessible::Accessible(nsIContent* aContent, DocAccessible* aDoc) :
   mContent(aContent), mDoc(aDoc),
   mParent(nullptr), mIndexInParent(-1),
   mRoleMapEntryIndex(aria::NO_ROLE_MAP_ENTRY_INDEX),
-  mStateFlags(0), mContextFlags(0), mType(0), mGenericTypes(0)
+  mStateFlags(0), mContextFlags(0), mType(0), mGenericTypes(0),
+  mReorderEventTarget(false), mShowEventTarget(false), mHideEventTarget(false)
 {
   mBits.groupInfo = nullptr;
   mInt.mIndexOfEmbeddedChild = -1;
 }
 
 Accessible::~Accessible()
 {
   NS_ASSERTION(!mDoc, "LastRelease was never called!?!");
@@ -2152,19 +2153,19 @@ Accessible::MoveChild(uint32_t aNewIndex
 {
   MOZ_ASSERT(aChild, "No child was given");
   MOZ_ASSERT(aChild->mParent == this, "A child from different subtree was given");
   MOZ_ASSERT(aChild->mIndexInParent != -1, "Unbound child was given");
   MOZ_ASSERT(static_cast<uint32_t>(aChild->mIndexInParent) != aNewIndex,
              "No move, same index");
   MOZ_ASSERT(aNewIndex <= mChildren.Length(), "Wrong new index was given");
 
-  EventTree* eventTree = mDoc->Controller()->QueueMutation(this);
-  if (eventTree) {
-    eventTree->Hidden(aChild, false);
+  RefPtr<AccHideEvent> hideEvent = new AccHideEvent(aChild, false);
+  if (mDoc->Controller()->QueueMutationEvent(hideEvent)) {
+    aChild->SetHideEventTarget(true);
   }
 
   mEmbeddedObjCollector = nullptr;
   mChildren.RemoveElementAt(aChild->mIndexInParent);
 
   uint32_t startIdx = aNewIndex, endIdx = aChild->mIndexInParent;
 
   // If the child is moved after its current position.
@@ -2186,20 +2187,20 @@ Accessible::MoveChild(uint32_t aNewIndex
   }
 
   for (uint32_t idx = startIdx; idx <= endIdx; idx++) {
     mChildren[idx]->mIndexInParent = idx;
     mChildren[idx]->mStateFlags |= eGroupInfoDirty;
     mChildren[idx]->mInt.mIndexOfEmbeddedChild = -1;
   }
 
-  if (eventTree) {
-    eventTree->Shown(aChild);
-    mDoc->Controller()->QueueNameChange(aChild);
-  }
+  RefPtr<AccShowEvent> showEvent = new AccShowEvent(aChild);
+  DebugOnly<bool> added = mDoc->Controller()->QueueMutationEvent(showEvent);
+  MOZ_ASSERT(added);
+  aChild->SetShowEventTarget(true);
 }
 
 Accessible*
 Accessible::GetChildAt(uint32_t aIndex) const
 {
   Accessible* child = mChildren.SafeElementAt(aIndex, nullptr);
   if (!child)
     return nullptr;
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -951,16 +951,46 @@ public:
   bool IsARIAHidden() const { return mContextFlags & eARIAHidden; }
   void SetARIAHidden(bool aIsDefined);
 
   /**
    * Return true if the element is inside an alert.
    */
   bool IsInsideAlert() const { return mContextFlags & eInsideAlert; }
 
+  /**
+   * Return true if there is a pending reorder event for this accessible.
+   */
+  bool ReorderEventTarget() const { return mReorderEventTarget; }
+
+  /**
+   * Return true if there is a pending show event for this accessible.
+   */
+  bool ShowEventTarget() const { return mShowEventTarget; }
+
+  /**
+   * Return true if there is a pending hide event for this accessible.
+   */
+  bool HideEventTarget() const { return mHideEventTarget; }
+
+  /**
+   * Set if there is a pending reorder event for this accessible.
+   */
+  void SetReorderEventTarget(bool aTarget) { mReorderEventTarget = aTarget; }
+
+  /**
+   * Set if this accessible is a show event target.
+   */
+  void SetShowEventTarget(bool aTarget) { mShowEventTarget = aTarget; }
+
+  /**
+   * Set if this accessible is a hide event target.
+   */
+  void SetHideEventTarget(bool aTarget) { mHideEventTarget = aTarget; }
+
 protected:
   virtual ~Accessible();
 
   /**
    * Return the accessible name provided by native markup. It doesn't take
    * into account ARIA markup used to specify the name.
    */
   virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName);
@@ -1127,16 +1157,19 @@ protected:
 
   /**
    * Keep in sync with StateFlags, ContextFlags, and AccTypes.
    */
   uint32_t mStateFlags : kStateFlagsBits;
   uint32_t mContextFlags : kContextFlagsBits;
   uint32_t mType : kTypeBits;
   uint32_t mGenericTypes : kGenericTypesBits;
+  uint32_t mReorderEventTarget : 1;
+  uint32_t mShowEventTarget : 1;
+  uint32_t mHideEventTarget : 1;
 
   void StaticAsserts() const;
 
 #ifdef A11Y_LOG
   friend void logging::Tree(const char* aTitle, const char* aMsgText,
                             Accessible* aRoot,
                             logging::GetTreePrefix aPrefixFunc,
                             void* aGetTreePrefixData);
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1855,18 +1855,18 @@ DocAccessible::ProcessContentInserted(Ac
     }
 
     if (aContainer->InsertAfter(iter.Child(), iter.ChildBefore())) {
 #ifdef A11Y_LOG
       logging::TreeInfo("accessible was inserted", 0,
                         "container", aContainer, "child", iter.Child(), nullptr);
 #endif
 
+      CreateSubtree(iter.Child());
       mt.AfterInsertion(iter.Child());
-      CreateSubtree(iter.Child());
       continue;
     }
 
     MOZ_ASSERT_UNREACHABLE("accessible was rejected");
     iter.Rejected();
   } while (iter.Next());
 
   mt.Done();
@@ -1902,20 +1902,20 @@ DocAccessible::ProcessContentInserted(Ac
       child = GetAccService()->CreateAccessible(aNode, aContainer);
     }
 
     if (child) {
       TreeMutation mt(aContainer);
       if (!aContainer->InsertAfter(child, walker.Prev())) {
         return;
       }
+      CreateSubtree(child);
       mt.AfterInsertion(child);
       mt.Done();
 
-      CreateSubtree(child);
       FireEventsOnInsertion(aContainer);
     }
   }
 
 #ifdef A11Y_LOG
   logging::TreeInfo("children after insertion", logging::eVerbose, aContainer);
 #endif
 }
@@ -2268,18 +2268,25 @@ DocAccessible::CacheChildrenInSubtree(Ac
 
 void
 DocAccessible::UncacheChildrenInSubtree(Accessible* aRoot)
 {
   aRoot->mStateFlags |= eIsNotInDocument;
   RemoveDependentIDsFor(aRoot);
 
   uint32_t count = aRoot->ContentChildCount();
-  for (uint32_t idx = 0; idx < count; idx++)
-    UncacheChildrenInSubtree(aRoot->ContentChildAt(idx));
+  for (uint32_t idx = 0; idx < count; idx++) {
+    Accessible* child = aRoot->ContentChildAt(idx);
+
+    // Removing this accessible from the document doesn't mean anything about
+    // accessibles for subdocuments, so skip removing those from the tree.
+    if (!child->IsDoc()) {
+      UncacheChildrenInSubtree(child);
+    }
+  }
 
   if (aRoot->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aRoot->GetNode()) == aRoot)
     mNodeToAccessibleMap.Remove(aRoot->GetNode());
 }
 
 void
 DocAccessible::ShutdownChildrenInSubtree(Accessible* aAccessible)
--- a/accessible/html/HTMLFormControlAccessible.cpp
+++ b/accessible/html/HTMLFormControlAccessible.cpp
@@ -346,18 +346,21 @@ HTMLTextFieldAccessible::Value(nsString&
 
   nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea(do_QueryInterface(mContent));
   if (textArea) {
     textArea->GetValue(aValue);
     return;
   }
 
   HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
-  if (input)
-    input->GetValue(aValue);
+  if (input) {
+    // Pass NonSystem as the caller type, to be safe.  We don't expect to have a
+    // file input here.
+    input->GetValue(aValue, CallerType::NonSystem);
+  }
 }
 
 void
 HTMLTextFieldAccessible::ApplyARIAState(uint64_t* aState) const
 {
   HyperTextAccessibleWrap::ApplyARIAState(aState);
   aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
 
@@ -547,17 +550,20 @@ HTMLSpinnerAccessible::NativeRole()
 
 void
 HTMLSpinnerAccessible::Value(nsString& aValue)
 {
   AccessibleWrap::Value(aValue);
   if (!aValue.IsEmpty())
     return;
 
-  HTMLInputElement::FromContent(mContent)->GetValue(aValue);
+  // Pass NonSystem as the caller type, to be safe.  We don't expect to have a
+  // file input here.
+  HTMLInputElement::FromContent(mContent)->GetValue(aValue,
+                                                    CallerType::NonSystem);
 }
 
 double
 HTMLSpinnerAccessible::MaxValue() const
 {
   double value = AccessibleWrap::MaxValue();
   if (!IsNaN(value))
     return value;
@@ -623,17 +629,20 @@ HTMLRangeAccessible::IsWidget() const
 
 void
 HTMLRangeAccessible::Value(nsString& aValue)
 {
   LeafAccessible::Value(aValue);
   if (!aValue.IsEmpty())
     return;
 
-  HTMLInputElement::FromContent(mContent)->GetValue(aValue);
+  // Pass NonSystem as the caller type, to be safe.  We don't expect to have a
+  // file input here.
+  HTMLInputElement::FromContent(mContent)->GetValue(aValue,
+                                                    CallerType::NonSystem);
 }
 
 double
 HTMLRangeAccessible::MaxValue() const
 {
   double value = LeafAccessible::MaxValue();
   if (!IsNaN(value))
     return value;
--- a/accessible/interfaces/ia2/Makefile.in
+++ b/accessible/interfaces/ia2/Makefile.in
@@ -68,17 +68,19 @@ MIDL_UNUSED_GENERATED_FILES = \
   $(MIDL_LIBRARIES:%.idl=%.c) \
   $(NULL)
 
 EMBED_MANIFEST_AT = 2
 
 INSTALL_TARGETS += midl
 midl_FILES := $(filter %.h %_i.c,$(MIDL_GENERATED_FILES))
 midl_DEST = $(DIST)/include
-midl_TARGET := export
+midl_TARGET := midl
+
+export:: midl
 
 include $(topsrcdir)/config/rules.mk
 
 # generate list of to-be-generated files that are missing
 # but ignore special file dlldata.c
 missing:=$(strip $(foreach onefile,$(strip $(subst dlldata.c,,$(MIDL_GENERATED_FILES))),$(if $(wildcard $(onefile)),,$(onefile))))
 
 missing_base:=$(sort $(basename $(subst _p.c,,$(subst _i.c,,$(missing)))))
--- a/accessible/interfaces/msaa/Makefile.in
+++ b/accessible/interfaces/msaa/Makefile.in
@@ -42,9 +42,11 @@ midl_exports := \
     ISimpleDOMNode_i.c \
     ISimpleDOMText.h \
     ISimpleDOMText_i.c \
     $(NULL)
 
 INSTALL_TARGETS += midl_exports
 midl_exports_FILES := $(midl_exports)
 midl_exports_DEST = $(DIST)/include
-midl_exports_TARGET := export
+midl_exports_TARGET := midl
+
+export:: midl
--- a/accessible/ipc/DocAccessibleChildBase.cpp
+++ b/accessible/ipc/DocAccessibleChildBase.cpp
@@ -80,17 +80,17 @@ DocAccessibleChildBase::SerializeTree(Ac
   }
 }
 
 void
 DocAccessibleChildBase::ShowEvent(AccShowEvent* aShowEvent)
 {
   Accessible* parent = aShowEvent->Parent();
   uint64_t parentID = parent->IsDoc() ? 0 : reinterpret_cast<uint64_t>(parent->UniqueID());
-  uint32_t idxInParent = aShowEvent->InsertionIndex();
+  uint32_t idxInParent = aShowEvent->GetAccessible()->IndexInParent();
   nsTArray<AccessibleData> shownTree;
   ShowEventData data(parentID, idxInParent, shownTree);
   SerializeTree(aShowEvent->GetAccessible(), data.NewTree());
   SendShowEvent(data, aShowEvent->IsFromUserInput());
 }
 
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -337,19 +337,19 @@ this.AccessFu = { // jshint ignore:line
         }
         break;
       case 'Accessibility:MoveByGranularity':
         this.Input.moveByGranularity(JSON.parse(aData));
         break;
       case 'remote-browser-shown':
       case 'inprocess-browser-shown':
       {
-        // Ignore notifications that aren't from a BrowserOrApp
+        // Ignore notifications that aren't from a Browser
         let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
-        if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
+        if (!frameLoader.ownerIsMozBrowserFrame) {
           return;
         }
         this._handleMessageManager(frameLoader.messageManager);
         break;
       }
     }
   },
 
--- a/accessible/tests/browser/browser.ini
+++ b/accessible/tests/browser/browser.ini
@@ -1,17 +1,29 @@
 [DEFAULT]
 
 support-files =
   head.js
   shared-head.js
 
+[browser_shutdown_acc_reference.js]
+[browser_shutdown_doc_acc_reference.js]
+[browser_shutdown_multi_acc_reference_obj.js]
+[browser_shutdown_multi_acc_reference_doc.js]
 [browser_shutdown_multi_reference.js]
 [browser_shutdown_parent_own_reference.js]
-skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_proxy_acc_reference.js]
+skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_proxy_doc_acc_reference.js]
+skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_multi_proxy_acc_reference_doc.js]
+skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_multi_proxy_acc_reference_obj.js]
+skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_remote_no_reference.js]
-skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_remote_only.js]
-skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_remote_own_reference.js]
-skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_scope_lifecycle.js]
 [browser_shutdown_start_restart.js]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_acc_reference.js
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Create a11y service.
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+
+  yield a11yInit;
+  ok(accService, 'Service initialized');
+
+  // Accessible object reference will live longer than the scope of this
+  // function.
+  let acc = yield new Promise(resolve => {
+    let intervalId = setInterval(() => {
+      let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
+      if (tabAcc) {
+        clearInterval(intervalId);
+        resolve(tabAcc);
+      }
+    }, 10);
+  });
+  ok(acc, 'Accessible object is created');
+
+  let canShutdown = false;
+  // This promise will resolve only if canShutdown flag is set to true. If
+  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
+  // down, the promise will reject.
+  let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+  accService = null;
+  ok(!accService, 'Service is removed');
+
+  // Force garbage collection that should not trigger shutdown because there is
+  // a reference to an accessible object.
+  forceGC();
+  // Have some breathing room when removing a11y service references.
+  yield new Promise(resolve => executeSoon(resolve));
+
+  // Now allow a11y service to shutdown.
+  canShutdown = true;
+  // Remove a reference to an accessible object.
+  acc = null;
+  ok(!acc, 'Accessible object is removed');
+
+  // Force garbage collection that should now trigger shutdown.
+  forceGC();
+  yield a11yShutdown;
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_doc_acc_reference.js
@@ -0,0 +1,47 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Create a11y service.
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+
+  yield a11yInit;
+  ok(accService, 'Service initialized');
+
+  // Accessible document reference will live longer than the scope of this
+  // function.
+  let docAcc = accService.getAccessibleFor(document);
+  ok(docAcc, 'Accessible document is created');
+
+  let canShutdown = false;
+  // This promise will resolve only if canShutdown flag is set to true. If
+  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
+  // down, the promise will reject.
+  let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+  accService = null;
+  ok(!accService, 'Service is removed');
+
+  // Force garbage collection that should not trigger shutdown because there is
+  // a reference to an accessible document.
+  forceGC();
+  // Have some breathing room when removing a11y service references.
+  yield new Promise(resolve => executeSoon(resolve));
+
+  // Now allow a11y service to shutdown.
+  canShutdown = true;
+  // Remove a reference to an accessible document.
+  docAcc = null;
+  ok(!docAcc, 'Accessible document is removed');
+
+  // Force garbage collection that should now trigger shutdown.
+  forceGC();
+  yield a11yShutdown;
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js
@@ -0,0 +1,67 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Create a11y service.
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+
+  yield a11yInit;
+  ok(accService, 'Service initialized');
+
+  let docAcc = accService.getAccessibleFor(document);
+  ok(docAcc, 'Accessible document is created');
+
+  // Accessible object reference will live longer than the scope of this
+  // function.
+  let acc = yield new Promise(resolve => {
+    let intervalId = setInterval(() => {
+      let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
+      if (tabAcc) {
+        clearInterval(intervalId);
+        resolve(tabAcc);
+      }
+    }, 10);
+  });
+  ok(acc, 'Accessible object is created');
+
+  let canShutdown = false;
+  // This promise will resolve only if canShutdown flag is set to true. If
+  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
+  // down, the promise will reject.
+  let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+  accService = null;
+  ok(!accService, 'Service is removed');
+
+  // Force garbage collection that should not trigger shutdown because there are
+  // references to accessible objects.
+  forceGC();
+  // Have some breathing room when removing a11y service references.
+  yield new Promise(resolve => executeSoon(resolve));
+
+  // Remove a reference to an accessible object.
+  acc = null;
+  ok(!acc, 'Accessible object is removed');
+  // Force garbage collection that should not trigger shutdown because there is
+  // a reference to an accessible document.
+  forceGC();
+  // Have some breathing room when removing a11y service references.
+  yield new Promise(resolve => executeSoon(resolve));
+
+  // Now allow a11y service to shutdown.
+  canShutdown = true;
+  // Remove a reference to an accessible document.
+  docAcc = null;
+  ok(!docAcc, 'Accessible document is removed');
+
+  // Force garbage collection that should now trigger shutdown.
+  forceGC();
+  yield a11yShutdown;
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js
@@ -0,0 +1,67 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Create a11y service.
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+
+  yield a11yInit;
+  ok(accService, 'Service initialized');
+
+  let docAcc = accService.getAccessibleFor(document);
+  ok(docAcc, 'Accessible document is created');
+
+  // Accessible object reference will live longer than the scope of this
+  // function.
+  let acc = yield new Promise(resolve => {
+    let intervalId = setInterval(() => {
+      let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
+      if (tabAcc) {
+        clearInterval(intervalId);
+        resolve(tabAcc);
+      }
+    }, 10);
+  });
+  ok(acc, 'Accessible object is created');
+
+  let canShutdown = false;
+  // This promise will resolve only if canShutdown flag is set to true. If
+  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
+  // down, the promise will reject.
+  let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+  accService = null;
+  ok(!accService, 'Service is removed');
+
+  // Force garbage collection that should not trigger shutdown because there are
+  // references to accessible objects.
+  forceGC();
+  // Have some breathing room when removing a11y service references.
+  yield new Promise(resolve => executeSoon(resolve));
+
+  // Remove a reference to an accessible document.
+  docAcc = null;
+  ok(!docAcc, 'Accessible document is removed');
+  // Force garbage collection that should not trigger shutdown because there is
+  // a reference to an accessible object.
+  forceGC();
+  // Have some breathing room when removing a11y service references.
+  yield new Promise(resolve => executeSoon(resolve));
+
+  // Now allow a11y service to shutdown.
+  canShutdown = true;
+  // Remove a reference to an accessible object.
+  acc = null;
+  ok(!acc, 'Accessible object is removed');
+
+  // Force garbage collection that should now trigger shutdown.
+  forceGC();
+  yield a11yShutdown;
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js
@@ -0,0 +1,76 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Making sure that the e10s is enabled on Windows for testing.
+  yield setE10sPrefs();
+
+  let docLoaded = waitForEvent(
+    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+  ok(accService, 'Service initialized');
+  yield a11yInit;
+
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: `data:text/html,
+      <html>
+        <head>
+          <meta charset="utf-8"/>
+          <title>Accessibility Test</title>
+        </head>
+        <body id="body"><div id="div"></div></body>
+      </html>`
+  }, function*(browser) {
+    let docLoadedEvent = yield docLoaded;
+    let docAcc = docLoadedEvent.accessibleDocument;
+    ok(docAcc, 'Accessible document proxy is created');
+    // Remove unnecessary dangling references
+    docLoaded = null;
+    docLoadedEvent = null;
+    forceGC();
+
+    let acc = docAcc.getChildAt(0);
+    ok(acc, 'Accessible proxy is created');
+
+    let canShutdown = false;
+    let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+    accService = null;
+    ok(!accService, 'Service is removed');
+    // Force garbage collection that should not trigger shutdown because there
+    // is a reference to an accessible proxy.
+    forceGC();
+    // Have some breathing room when removing a11y service references.
+    yield new Promise(resolve => executeSoon(resolve));
+
+    // Remove a reference to an accessible proxy.
+    acc = null;
+    ok(!acc, 'Accessible proxy is removed');
+    // Force garbage collection that should not trigger shutdown because there is
+    // a reference to an accessible document proxy.
+    forceGC();
+    // Have some breathing room when removing a11y service references.
+    yield new Promise(resolve => executeSoon(resolve));
+
+    // Now allow a11y service to shutdown.
+    canShutdown = true;
+    // Remove a last reference to an accessible document proxy.
+    docAcc = null;
+    ok(!docAcc, 'Accessible document proxy is removed');
+
+    // Force garbage collection that should now trigger shutdown.
+    forceGC();
+    yield a11yShutdown;
+  });
+
+  // Unsetting e10s related preferences.
+  yield unsetE10sPrefs();
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js
@@ -0,0 +1,76 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Making sure that the e10s is enabled on Windows for testing.
+  yield setE10sPrefs();
+
+  let docLoaded = waitForEvent(
+    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+  ok(accService, 'Service initialized');
+  yield a11yInit;
+
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: `data:text/html,
+      <html>
+        <head>
+          <meta charset="utf-8"/>
+          <title>Accessibility Test</title>
+        </head>
+        <body id="body"><div id="div"></div></body>
+      </html>`
+  }, function*(browser) {
+    let docLoadedEvent = yield docLoaded;
+    let docAcc = docLoadedEvent.accessibleDocument;
+    ok(docAcc, 'Accessible document proxy is created');
+    // Remove unnecessary dangling references
+    docLoaded = null;
+    docLoadedEvent = null;
+    forceGC();
+
+    let acc = docAcc.getChildAt(0);
+    ok(acc, 'Accessible proxy is created');
+
+    let canShutdown = false;
+    let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+    accService = null;
+    ok(!accService, 'Service is removed');
+    // Force garbage collection that should not trigger shutdown because there
+    // is a reference to an accessible proxy.
+    forceGC();
+    // Have some breathing room when removing a11y service references.
+    yield new Promise(resolve => executeSoon(resolve));
+
+    // Remove a reference to an accessible document proxy.
+    docAcc = null;
+    ok(!docAcc, 'Accessible document proxy is removed');
+    // Force garbage collection that should not trigger shutdown because there is
+    // a reference to an accessible proxy.
+    forceGC();
+    // Have some breathing room when removing a11y service references.
+    yield new Promise(resolve => executeSoon(resolve));
+
+    // Now allow a11y service to shutdown.
+    canShutdown = true;
+    // Remove a last reference to an accessible proxy.
+    acc = null;
+    ok(!acc, 'Accessible proxy is removed');
+
+    // Force garbage collection that should now trigger shutdown.
+    forceGC();
+    yield a11yShutdown;
+  });
+
+  // Unsetting e10s related preferences.
+  yield unsetE10sPrefs();
+});
--- a/accessible/tests/browser/browser_shutdown_multi_reference.js
+++ b/accessible/tests/browser/browser_shutdown_multi_reference.js
@@ -16,17 +16,17 @@ add_task(function* () {
   // Add another reference to a11y service. This will not trigger
   // 'a11y-init-or-shutdown' event
   let accService2 = Cc['@mozilla.org/accessibilityService;1'].getService(
     Ci.nsIAccessibilityService);
   ok(accService2, 'Service initialized');
 
   info('Removing all service references');
   let canShutdown = false;
-  // This promise will resolve only if canShutdonw flag is set to true. If
+  // This promise will resolve only if canShutdown flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ?
       resolve() : reject('Accessible service was shut down incorrectly')));
   // Remove first a11y service reference.
   accService1 = null;
   ok(!accService1, 'Service is removed');
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js
@@ -0,0 +1,64 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Making sure that the e10s is enabled on Windows for testing.
+  yield setE10sPrefs();
+
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+  ok(accService, 'Service initialized');
+  yield a11yInit;
+
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: `data:text/html,
+      <html>
+        <head>
+          <meta charset="utf-8"/>
+          <title>Accessibility Test</title>
+        </head>
+        <body><div id="div" style="visibility: hidden;"></div></body>
+      </html>`
+  }, function*(browser) {
+    let onShow = waitForEvent(Ci.nsIAccessibleEvent.EVENT_SHOW, 'div');
+    yield invokeSetStyle(browser, 'div', 'visibility', 'visible');
+    let showEvent = yield onShow;
+    let divAcc = showEvent.accessible;
+    ok(divAcc, 'Accessible proxy is created');
+    // Remove unnecessary dangling references
+    onShow = null;
+    showEvent = null;
+    forceGC();
+
+    let canShutdown = false;
+    let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+    accService = null;
+    ok(!accService, 'Service is removed');
+    // Force garbage collection that should not trigger shutdown because there
+    // is a reference to an accessible proxy.
+    forceGC();
+    // Have some breathing room when removing a11y service references.
+    yield new Promise(resolve => executeSoon(resolve));
+
+    // Now allow a11y service to shutdown.
+    canShutdown = true;
+    // Remove a last reference to an accessible proxy.
+    divAcc = null;
+    ok(!divAcc, 'Accessible proxy is removed');
+
+    // Force garbage collection that should now trigger shutdown.
+    forceGC();
+    yield a11yShutdown;
+  });
+
+  // Unsetting e10s related preferences.
+  yield unsetE10sPrefs();
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js
@@ -0,0 +1,64 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+add_task(function* () {
+  // Making sure that the e10s is enabled on Windows for testing.
+  yield setE10sPrefs();
+
+  let docLoaded = waitForEvent(
+    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
+  let a11yInit = initPromise();
+  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    Ci.nsIAccessibilityService);
+  ok(accService, 'Service initialized');
+  yield a11yInit;
+
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: `data:text/html,
+      <html>
+        <head>
+          <meta charset="utf-8"/>
+          <title>Accessibility Test</title>
+        </head>
+        <body id="body"></body>
+      </html>`
+  }, function*(browser) {
+    let docLoadedEvent = yield docLoaded;
+    let docAcc = docLoadedEvent.accessibleDocument;
+    ok(docAcc, 'Accessible document proxy is created');
+    // Remove unnecessary dangling references
+    docLoaded = null;
+    docLoadedEvent = null;
+    forceGC();
+
+    let canShutdown = false;
+    let a11yShutdown = new Promise((resolve, reject) =>
+    shutdownPromise().then(flag => canShutdown ? resolve() :
+      reject('Accessible service was shut down incorrectly')));
+
+    accService = null;
+    ok(!accService, 'Service is removed');
+    // Force garbage collection that should not trigger shutdown because there
+    // is a reference to an accessible proxy.
+    forceGC();
+    // Have some breathing room when removing a11y service references.
+    yield new Promise(resolve => executeSoon(resolve));
+
+    // Now allow a11y service to shutdown.
+    canShutdown = true;
+    // Remove a last reference to an accessible document proxy.
+    docAcc = null;
+    ok(!docAcc, 'Accessible document proxy is removed');
+
+    // Force garbage collection that should now trigger shutdown.
+    forceGC();
+    yield a11yShutdown;
+  });
+
+  // Unsetting e10s related preferences.
+  yield unsetE10sPrefs();
+});
--- a/accessible/tests/browser/e10s/browser.ini
+++ b/accessible/tests/browser/e10s/browser.ini
@@ -13,39 +13,36 @@ support-files =
   !/accessible/tests/mochitest/*.js
   !/accessible/tests/mochitest/letters.gif
   !/accessible/tests/mochitest/moz.png
 
 # Caching tests
 [browser_caching_attributes.js]
 [browser_caching_description.js]
 [browser_caching_name.js]
-skip-if = e10s
 [browser_caching_relations.js]
 [browser_caching_states.js]
 [browser_caching_value.js]
 
 # Events tests
 [browser_events_caretmove.js]
 [browser_events_hide.js]
 [browser_events_show.js]
 [browser_events_statechange.js]
 [browser_events_textchange.js]
 
 # Tree update tests
 [browser_treeupdate_ariadialog.js]
 [browser_treeupdate_ariaowns.js]
-skip-if = e10s
 [browser_treeupdate_canvas.js]
 [browser_treeupdate_cssoverflow.js]
 [browser_treeupdate_doc.js]
 [browser_treeupdate_gencontent.js]
 [browser_treeupdate_hidden.js]
 [browser_treeupdate_imagemap.js]
-skip-if = e10s
 [browser_treeupdate_list.js]
 [browser_treeupdate_list_editabledoc.js]
 [browser_treeupdate_listener.js]
 [browser_treeupdate_optgroup.js]
 [browser_treeupdate_removal.js]
 [browser_treeupdate_table.js]
 [browser_treeupdate_textleaf.js]
 [browser_treeupdate_visibility.js]
--- a/accessible/tests/browser/head.js
+++ b/accessible/tests/browser/head.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 'use strict';
 
-/* exported initPromise, shutdownPromise,
-            setE10sPrefs, unsetE10sPrefs, forceGC */
+/* exported initPromise, shutdownPromise, waitForEvent, setE10sPrefs,
+            unsetE10sPrefs, forceGC */
 
 /**
  * Set e10s related preferences in the test environment.
  * @return {Promise} promise that resolves when preferences are set.
  */
 function setE10sPrefs() {
   return new Promise(resolve =>
     SpecialPowers.pushPrefEnv({
@@ -103,14 +103,38 @@ function shutdownPromise(contentBrowser)
     contentA11yInitOrShutdownPromise(contentBrowser) :
     a11yInitOrShutdownPromise();
   return promiseOK(a11yShutdownPromise, '0').then(
     () => ok(true, 'Service shutdown correctly'),
     () => ok(false, 'Service initialized incorrectly'));
 }
 
 /**
+ * Simpler verions of waitForEvent defined in
+ * accessible/tests/browser/e10s/events.js
+ */
+function waitForEvent(eventType, expectedId) {
+  return new Promise(resolve => {
+    let eventObserver = {
+      observe(subject) {
+        let event = subject.QueryInterface(Ci.nsIAccessibleEvent);
+        if (event.eventType === eventType &&
+            event.accessible.id === expectedId) {
+          Services.obs.removeObserver(this, 'accessible-event');
+          resolve(event);
+        }
+      }
+    };
+    Services.obs.addObserver(eventObserver, 'accessible-event', false);
+  });
+}
+
+/**
  * Force garbage collection.
  */
 function forceGC() {
-  Cu.forceCC();
-  Cu.forceGC();
+  SpecialPowers.gc();
+  SpecialPowers.forceGC();
+  SpecialPowers.forceCC();
+  SpecialPowers.gc();
+  SpecialPowers.forceGC();
+  SpecialPowers.forceCC();
 }
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -531,33 +531,52 @@ function eventQueue(aEventType)
         if (eventQueue.compareEvents(nextChecker, aEvent)) {
           this.processMatchedChecker(aEvent, nextChecker, scnIdx, eventSeq.idx);
           hasMatchedCheckers = true;
           continue;
         }
       }
 
       // Check if handled event matches any expected async events.
+      var haveUnmatchedAsync = false;
       for (idx = 0; idx < eventSeq.length; idx++) {
+        if (eventSeq[idx] instanceof orderChecker && haveUnmatchedAsync) {
+            break;
+        }
+
+        if (!eventSeq[idx].wasCaught) {
+          haveUnmatchedAsync = true;
+        }
+
         if (!eventSeq[idx].unexpected && eventSeq[idx].async) {
           if (eventQueue.compareEvents(eventSeq[idx], aEvent)) {
             this.processMatchedChecker(aEvent, eventSeq[idx], scnIdx, idx);
             hasMatchedCheckers = true;
             break;
           }
         }
       }
     }
 
     if (hasMatchedCheckers) {
       var invoker = this.getInvoker();
       if ("check" in invoker)
         invoker.check(aEvent);
     }
 
+    for (idx = 0; idx < eventSeq.length; idx++) {
+      if (!eventSeq[idx].wasCaught) {
+        if (eventSeq[idx] instanceof orderChecker) {
+          eventSeq[idx].wasCaught++;
+        } else {
+          break;
+        }
+      }
+    }
+
     // If we don't have more events to wait then schedule next invoker.
     if (this.hasMatchedScenario()) {
       if (this.mNextInvokerStatus == kInvokerNotScheduled) {
         this.processNextInvokerInTimeout();
 
       } else if (this.mNextInvokerStatus == kInvokerCanceled) {
         this.setInvokerStatus(kInvokerPending,
                               "Full match. Void the cancelation of next invoker processing");
@@ -591,33 +610,34 @@ function eventQueue(aEventType)
   {
     if (!("idx" in aEventSeq))
       aEventSeq.idx = 0;
 
     while (aEventSeq.idx < aEventSeq.length &&
            (aEventSeq[aEventSeq.idx].unexpected ||
             aEventSeq[aEventSeq.idx].todo ||
             aEventSeq[aEventSeq.idx].async ||
+            aEventSeq[aEventSeq.idx] instanceof orderChecker ||
             aEventSeq[aEventSeq.idx].wasCaught > 0)) {
       aEventSeq.idx++;
     }
 
     return aEventSeq.idx != aEventSeq.length ? aEventSeq[aEventSeq.idx] : null;
   }
 
   this.areExpectedEventsLeft =
     function eventQueue_areExpectedEventsLeft(aScenario)
   {
     function scenarioHasUnhandledExpectedEvent(aEventSeq)
     {
       // Check if we have unhandled async (can be anywhere in the sequance) or
       // sync expcected events yet.
       for (var idx = 0; idx < aEventSeq.length; idx++) {
         if (!aEventSeq[idx].unexpected && !aEventSeq[idx].todo &&
-            !aEventSeq[idx].wasCaught)
+            !aEventSeq[idx].wasCaught && !(aEventSeq[idx] instanceof orderChecker))
           return true;
       }
 
       return false;
     }
 
     if (aScenario)
       return scenarioHasUnhandledExpectedEvent(aScenario);
@@ -1675,16 +1695,27 @@ function invokerChecker(aEventType, aTar
     return prettyName(this.mTarget);
   }
 
   this.mTarget = aTargetOrFunc;
   this.mTargetFuncArg = aTargetFuncArg;
 }
 
 /**
+ * event checker that forces preceeding async events to happen before this
+ * checker.
+ */
+function orderChecker()
+{
+  // XXX it doesn't actually work to inherit from invokerChecker, but maybe we
+  // should fix that?
+  //  this.__proto__ = new invokerChecker(null, null, null, false);
+}
+
+/**
  * Generic invoker checker for todo events.
  */
 function todo_invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
 {
   this.__proto__ = new invokerChecker(aEventType, aTargetOrFunc,
                                       aTargetFuncArg, true);
   this.todo = true;
 }
--- a/accessible/tests/mochitest/events/test_aria_menu.html
+++ b/accessible/tests/mochitest/events/test_aria_menu.html
@@ -50,18 +50,18 @@
     function showMenu(aMenuID, aParentMenuID, aHow)
     {
       this.menuNode = getNode(aMenuID);
 
       // Because of aria-owns processing we may have menupopup start fired before
       // related show event.
       this.eventSeq = [
         new invokerChecker(EVENT_SHOW, this.menuNode),
-        new asyncInvokerChecker(EVENT_MENUPOPUP_START, this.menuNode),
-        new invokerChecker(EVENT_REORDER, getNode(aParentMenuID))
+        new invokerChecker(EVENT_REORDER, getNode(aParentMenuID)),
+        new invokerChecker(EVENT_MENUPOPUP_START, this.menuNode)
       ];
 
       this.invoke = function showMenu_invoke()
       {
         if (aHow == kViaDisplayStyle)
           this.menuNode.style.display = "block";
         else
           this.menuNode.style.visibility = "visible";
--- a/accessible/tests/mochitest/events/test_coalescence.html
+++ b/accessible/tests/mochitest/events/test_coalescence.html
@@ -414,18 +414,18 @@
     function test5()
     {
       this.o = getAccessible("t5_o");
       this.ofc = this.o.firstChild;
       this.b = getAccessible("t5_b");
       this.lb = getAccessible("t5_lb");
 
       this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, this.b),
         new invokerChecker(EVENT_HIDE, this.o),
-        new invokerChecker(EVENT_HIDE, this.b),
         new invokerChecker(EVENT_REORDER, "t5"),
         new unexpectedInvokerChecker(EVENT_HIDE, this.ofc),
         new unexpectedInvokerChecker(EVENT_REORDER, this.o),
         new unexpectedInvokerChecker(EVENT_REORDER, this.lb)
       ];
 
       this.invoke = function test5_invoke()
       {
@@ -534,18 +534,18 @@
      * The hide event should be delivered before the paired show event.
      */
     function test8()
     {
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, getNode('t8_c1_child')),
         new invokerChecker(EVENT_HIDE, 't8_c2_moved'),
         new invokerChecker(EVENT_SHOW, 't8_c2_moved'),
+        new invokerChecker(EVENT_REORDER, 't8_c2'),
         new invokerChecker(EVENT_REORDER, 't8_c1'),
-        new invokerChecker(EVENT_REORDER, 't8_c2')
       ];
 
       this.invoke = function test8_invoke()
       {
         // Remove a node from 't8_c1' container to give the event tree a
         // desired structure (the 't8_c1' container node goes first in the event
         // tree)
         getNode('t8_c1_child').remove();
@@ -573,23 +573,23 @@
      *
      * The hide events for 't9_c2_moved' and 't9_c3_moved' should be delivered
      * before the show event for 't9_c2_moved'.
      */
     function test9()
     {
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, getNode('t9_c1_child')),
+        new invokerChecker(EVENT_HIDE, getNode('t9_c2_child')),
         new invokerChecker(EVENT_HIDE, 't9_c3_moved'),
         new invokerChecker(EVENT_HIDE, 't9_c2_moved'),
         new invokerChecker(EVENT_SHOW, 't9_c2_moved'),
+        new invokerChecker(EVENT_REORDER, 't9_c3'),
+        new invokerChecker(EVENT_REORDER, 't9_c2'),
         new invokerChecker(EVENT_REORDER, 't9_c1'),
-        new invokerChecker(EVENT_HIDE, getNode('t9_c2_child')),
-        new invokerChecker(EVENT_REORDER, 't9_c2'),
-        new invokerChecker(EVENT_REORDER, 't9_c3'),
         new unexpectedInvokerChecker(EVENT_SHOW, 't9_c3_moved')
       ];
 
       this.invoke = function test9_invoke()
       {
         // Remove child nodes from 't9_c1' and 't9_c2' containers to give
         // the event tree a needed structure ('t9_c1' and 't9_c2' nodes go
         // first in the event tree),
@@ -619,22 +619,22 @@
      *
      * The hide events for 't10_c2_moved' and 't10_c3_moved' should be delivered
      * before the show event for 't10_c2_moved'.
      */
     function test10()
     {
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, getNode('t10_c1_child')),
+        new invokerChecker(EVENT_HIDE, getNode('t10_c2_child')),
         new invokerChecker(EVENT_HIDE, getNode('t10_c2_moved')),
         new invokerChecker(EVENT_HIDE, getNode('t10_c3_moved')),
         new invokerChecker(EVENT_SHOW, getNode('t10_c2_moved')),
+        new invokerChecker(EVENT_REORDER, 't10_c2'),
         new invokerChecker(EVENT_REORDER, 't10_c1'),
-        new invokerChecker(EVENT_HIDE, getNode('t10_c2_child')),
-        new invokerChecker(EVENT_REORDER, 't10_c2'),
         new invokerChecker(EVENT_REORDER, 't10_c3')
       ];
 
       this.invoke = function test10_invoke()
       {
         // Remove child nodes from 't10_c1' and 't10_c2' containers to give
         // the event tree a needed structure ('t10_c1' and 't10_c2' nodes go first
         // in the event tree),
@@ -654,19 +654,21 @@
      * Move a node by aria-owns from right to left in the tree, and then
      * move its parent too by aria-owns. No hide event should be fired for
      * original node.
      */
     function test11()
     {
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, getNode('t11_c1_child')),
-        new invokerChecker(EVENT_SHOW, 't11_c2_child'),
         new invokerChecker(EVENT_HIDE, getNode('t11_c2')),
-        new invokerChecker(EVENT_SHOW, 't11_c2'),
+        new orderChecker(),
+        new asyncInvokerChecker(EVENT_SHOW, 't11_c2_child'),
+        new asyncInvokerChecker(EVENT_SHOW, 't11_c2'),
+        new orderChecker(),
         new invokerChecker(EVENT_REORDER, 't11'),
         new unexpectedInvokerChecker(EVENT_HIDE, 't11_c2_child'),
         new unexpectedInvokerChecker(EVENT_REORDER, 't11_c1'),
         new unexpectedInvokerChecker(EVENT_REORDER, 't11_c2'),
         new unexpectedInvokerChecker(EVENT_REORDER, 't11_c3')
       ];
 
       this.invoke = function test11_invoke()
@@ -684,17 +686,17 @@
       this.getID = function test11_getID() {
         return "Move a node by aria-owns to left within the tree";
       };
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Do tests.
 
-    //gA11yEventDumpToConsole = true; // debug stuff
+    gA11yEventDumpToConsole = true; // debug stuff
     //enableLogging("eventTree");
 
     var gQueue = null;
     function doTests()
     {
       gQueue = new eventQueue();
 
       gQueue.push(new removeChildNParent("option1", "select1"));
--- a/accessible/tests/mochitest/events/test_focus_listcontrols.xul
+++ b/accessible/tests/mochitest/events/test_focus_listcontrols.xul
@@ -47,17 +47,17 @@
       gQueue.push(new synthFocus("emptyrichlistbox", new focusChecker("emptyrichlistbox")));
 
       gQueue.push(new synthFocus("menulist"));
       gQueue.push(new synthClick("menulist", new focusChecker("ml_tangerine")));
       gQueue.push(new synthDownKey("ml_tangerine", new focusChecker("ml_marmalade")));
       gQueue.push(new synthEscapeKey("ml_marmalade", new focusChecker("menulist")));
 if (!MAC) {
       // On Windows, items get selected during navigation.
-      let expectedItem = WIN ? "ml_tangerine" : "ml_marmalade";
+      let expectedItem = WIN ? "ml_strawberry" : "ml_marmalade";
       gQueue.push(new synthDownKey("menulist", new nofocusChecker(expectedItem)));
       gQueue.push(new synthOpenComboboxKey("menulist", new focusChecker(expectedItem)));
       gQueue.push(new synthEnterKey(expectedItem, new focusChecker("menulist")));
 } else {
       todo(false, "Bug 746531 - timeouts of last three menulist tests on OS X");
 }
 
       var textentry = getAccessible("emenulist").firstChild;
@@ -169,16 +169,17 @@ if (!MAC) {
         </richlistitem>
       </richlistbox>
       <richlistbox id="emptyrichlistbox" seltype="multiple"/>
 
       <menulist id="menulist">
         <menupopup>
           <menuitem id="ml_tangerine" label="tangerine trees"/>
           <menuitem id="ml_marmalade" label="marmalade skies"/>
+          <menuitem id="ml_strawberry" label="strawberry fields"/>
         </menupopup>
       </menulist>
       <menulist id="emenulist" editable="true">
         <menupopup>
           <menuitem id="eml_tangerine" label="tangerine trees"/>
           <menuitem id="eml_marmalade" label="marmalade skies"/>
         </menupopup>
       </menulist>
--- a/accessible/tests/mochitest/events/test_mutation.html
+++ b/accessible/tests/mochitest/events/test_mutation.html
@@ -336,18 +336,18 @@
       }
     }
 
     function insertReferredElm(aContainerID)
     {
       this.containerNode = getNode(aContainerID);
 
       this.eventSeq = [
+        new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.firstChild; }, this.containerNode),
         new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.lastChild; }, this.containerNode),
-        new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.firstChild; }, this.containerNode),
         new invokerChecker(EVENT_REORDER, this.containerNode)
       ];
 
       this.invoke = function insertReferredElm_invoke()
       {
         this.containerNode.innerHTML =
           "<span id='insertReferredElms_span'></span><input aria-labelledby='insertReferredElms_span'>";
       }
--- a/accessible/tests/mochitest/tree/test_media.html
+++ b/accessible/tests/mochitest/tree/test_media.html
@@ -40,16 +40,27 @@ https://bugzilla.mozilla.org/show_bug.cg
             role: ROLE_PROGRESSBAR,
             children: []
           },
           { // slider of progress bar
             role: ROLE_SLIDER,
             //name: "0:00 of 0:02 elapsed",
             children: []
           },
+          {
+            role: ROLE_TEXT_CONTAINER,
+            children: [
+              {
+                role: ROLE_TEXT_LEAF, // position text
+              },
+              {
+                role: ROLE_TEXT_LEAF, // duration text
+              }
+            ]
+          },
           { // mute button
             role: ROLE_PUSHBUTTON,
             name: "Mute",
             children: []
           },
           { // slider of volume bar
             role: ROLE_SLIDER,
             children: []
--- a/accessible/tests/mochitest/treeupdate/test_ariaowns.html
+++ b/accessible/tests/mochitest/treeupdate/test_ariaowns.html
@@ -22,21 +22,21 @@
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
     ////////////////////////////////////////////////////////////////////////////
 
     function changeARIAOwns()
     {
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, getNode("t1_button")),
-        new invokerChecker(EVENT_SHOW, getNode("t1_button")),
-        new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
         // no hide for t1_subdiv because it is contained by hidden t1_checkbox
         new invokerChecker(EVENT_HIDE, getNode("t1_checkbox")),
         new invokerChecker(EVENT_SHOW, getNode("t1_checkbox")),
+        new invokerChecker(EVENT_SHOW, getNode("t1_button")),
+        new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
         new invokerChecker(EVENT_REORDER, getNode("t1_container"))
       ];
 
       this.invoke = function setARIAOwns_invoke()
       {
         // children are swapped by ARIA owns
         var tree =
           { SECTION: [
@@ -68,20 +68,22 @@
       {
         return "Change @aria-owns attribute";
       }
     }
 
     function removeARIAOwns()
     {
       this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, getNode("t1_button")),
         new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")),
-        new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
-        new invokerChecker(EVENT_HIDE, getNode("t1_button")),
-        new invokerChecker(EVENT_SHOW, getNode("t1_button")),
+        new orderChecker(),
+        new asyncInvokerChecker(EVENT_SHOW, getNode("t1_button")),
+        new asyncInvokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
+        new orderChecker(),
         new invokerChecker(EVENT_REORDER, getNode("t1_container")),
         new unexpectedInvokerChecker(EVENT_REORDER, getNode("t1_checkbox"))
       ];
 
       this.invoke = function removeARIAOwns_invoke()
       {
         getNode("t1_container").removeAttribute("aria-owns");
       }
@@ -103,18 +105,18 @@
       {
         return "Remove @aria-owns attribute";
       }
     }
 
     function setARIAOwns()
     {
       this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, getNode("t1_button")),
         new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")),
-        new invokerChecker(EVENT_HIDE, getNode("t1_button")),
         new invokerChecker(EVENT_SHOW, getNode("t1_button")),
         new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
         new invokerChecker(EVENT_REORDER, getNode("t1_container"))
       ];
 
       this.invoke = function setARIAOwns_invoke()
       {
         getNode("t1_container").
@@ -442,16 +444,19 @@
       }
     }
 
     function rearrangeARIAOwns(aContainer, aAttr, aIdList, aRoleList)
     {
       this.eventSeq = [];
       for (var id of aIdList) {
         this.eventSeq.push(new invokerChecker(EVENT_HIDE, getNode(id)));
+      }
+
+      for (var id of aIdList) {
         this.eventSeq.push(new invokerChecker(EVENT_SHOW, getNode(id)));
       }
       this.eventSeq.push(new invokerChecker(EVENT_REORDER, getNode(aContainer)));
 
       this.invoke = function rearrangeARIAOwns_invoke()
       {
         getNode(aContainer).setAttribute("aria-owns", aAttr);
       }
--- a/accessible/tests/mochitest/treeupdate/test_bug1189277.html
+++ b/accessible/tests/mochitest/treeupdate/test_bug1189277.html
@@ -16,19 +16,19 @@
           src="../events.js"></script>
 
   <script type="application/javascript">
     function runTest()
     {
       this.containerNode = getNode("outerDiv");
 
       this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, getNode("child")),
         new invokerChecker(EVENT_HIDE, getNode("childDoc")),
         new invokerChecker(EVENT_SHOW, "newChildDoc"),
-        new invokerChecker(EVENT_HIDE, getNode("child")),
         new invokerChecker(EVENT_REORDER, this.containerNode)
       ];
 
       this.invoke = function runTest_invoke()
       {
         this.containerNode.removeChild(getNode("child"));
 
         var docContainer = getNode("docContainer");
@@ -42,17 +42,17 @@
 
       this.getID = function runTest_getID()
       {
         return "check show events are not incorrectly coalesced";
       }
     }
 
     //enableLogging("tree");
-    //gA11yEventDumpToConsole = true;
+    gA11yEventDumpToConsole = true;
     var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue();
       gQueue.push(new runTest());
       gQueue.invoke(); // SimpleTest.finish();
     }
 
--- a/accessible/tests/mochitest/treeupdate/test_whitespace.html
+++ b/accessible/tests/mochitest/treeupdate/test_whitespace.html
@@ -96,18 +96,19 @@
     {
       this.containerNode = getNode("container2");
       this.topNode = this.containerNode.parentNode;
       this.textNode = this.containerNode.nextSibling;
       this.imgNode = document.createElement("img");
       this.imgNode.setAttribute("src", "../moz.png");
 
       this.eventSeq = [
-        new invokerChecker(EVENT_SHOW, getAccessible, this.imgNode),
-        new invokerChecker(EVENT_SHOW, getAccessible, this.textNode),
+        new asyncInvokerChecker(EVENT_SHOW, getAccessible, this.textNode),
+        new asyncInvokerChecker(EVENT_SHOW, getAccessible, this.imgNode),
+        new orderChecker(),
         new invokerChecker(EVENT_REORDER, this.topNode)
       ];
 
       this.invoke = function insertImg_invoke()
       {
         var tree =
           { SECTION: [
             { LINK: [] },
--- a/accessible/xpcom/AccEventGen.py
+++ b/accessible/xpcom/AccEventGen.py
@@ -218,11 +218,11 @@ def get_conf(conf_file):
         mozpath.join(buildconfig.topsrcdir, 'xpcom', 'base'),
     ]
     return conf, inc_dir
 
 def gen_files(fd, conf_file, xpidllex, xpidlyacc):
     deps = set()
     conf, inc_dir = get_conf(conf_file)
     deps.update(print_header_file(fd, conf, inc_dir))
-    with open('xpcAccEvents.cpp', 'w') as cpp_fd:
+    with open(os.path.join(os.path.dirname(fd.name), 'xpcAccEvents.cpp'), 'w') as cpp_fd:
         deps.update(print_cpp_file(cpp_fd, conf, inc_dir))
     return deps
--- a/accessible/xpcom/xpcAccessibleApplication.h
+++ b/accessible/xpcom/xpcAccessibleApplication.h
@@ -28,17 +28,20 @@ public:
 
   // nsIAccessibleApplication
   NS_IMETHOD GetAppName(nsAString& aName) final override;
   NS_IMETHOD GetAppVersion(nsAString& aVersion) final override;
   NS_IMETHOD GetPlatformName(nsAString& aName) final override;
   NS_IMETHOD GetPlatformVersion(nsAString& aVersion) final override;
 
 protected:
-  virtual ~xpcAccessibleApplication() {}
+  virtual ~xpcAccessibleApplication()
+  {
+    Shutdown();
+  }
 
 private:
   ApplicationAccessible* Intl() { return mIntl.AsAccessible()->AsApplication(); }
 
   xpcAccessibleApplication(const xpcAccessibleApplication&) = delete;
   xpcAccessibleApplication& operator =(const xpcAccessibleApplication&) = delete;
 };
 
--- a/accessible/xpcom/xpcAccessibleDocument.cpp
+++ b/accessible/xpcom/xpcAccessibleDocument.cpp
@@ -12,36 +12,38 @@
 #include "mozilla/a11y/DocAccessibleParent.h"
 #include "DocAccessible-inl.h"
 #include "nsIDOMDocument.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsISupports and cycle collection
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(xpcAccessibleDocument)
+// nsISupports
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(xpcAccessibleDocument,
-                                                  xpcAccessibleGeneric)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCache)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_QUERY_INTERFACE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText,
+                                  nsIAccessibleDocument)
+NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
+NS_IMETHODIMP_(MozExternalRefCountType) xpcAccessibleDocument::Release(void)
+{
+  nsrefcnt r = xpcAccessibleHyperText::Release();
+  NS_LOG_RELEASE(this, r, "xpcAccessibleDocument");
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(xpcAccessibleDocument,
-                                                xpcAccessibleGeneric)
-  tmp->mCache.Clear();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(xpcAccessibleDocument)
-  NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
-NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleHyperText)
-
-NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
-NS_IMPL_RELEASE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
+  // The only reference to the xpcAccessibleDocument is in DocManager's cache.
+  if (r == 1 && !mIntl.IsNull() && mCache.Count() == 0) {
+    if (mIntl.IsAccessible()) {
+      GetAccService()->RemoveFromXPCDocumentCache(
+        mIntl.AsAccessible()->AsDoc());
+    } else {
+      GetAccService()->RemoveFromRemoteXPCDocumentCache(
+        mIntl.AsProxy()->AsDoc());
+    }
+  }
+  return r;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleDocument
 
 NS_IMETHODIMP
 xpcAccessibleDocument::GetURL(nsAString& aURL)
 {
   if (!Intl())
@@ -174,17 +176,17 @@ xpcAccessibleDocument::GetAccessible(Acc
   if (ToXPCDocument(aAccessible->Document()) != this) {
     NS_ERROR("This XPCOM document is not related with given internal accessible!");
     return nullptr;
   }
 
   if (aAccessible->IsDoc())
     return this;
 
-  xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
+  xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible);
   if (xpcAcc)
     return xpcAcc;
 
   if (aAccessible->IsImage())
     xpcAcc = new xpcAccessibleImage(aAccessible);
   else if (aAccessible->IsTable())
     xpcAcc = new xpcAccessibleTable(aAccessible);
   else if (aAccessible->IsTableCell())
@@ -202,27 +204,27 @@ xpcAccessibleGeneric*
 xpcAccessibleDocument::GetXPCAccessible(ProxyAccessible* aProxy)
 {
   MOZ_ASSERT(mRemote);
   MOZ_ASSERT(aProxy->Document() == mIntl.AsProxy());
   if (aProxy->IsDoc()) {
     return this;
   }
 
-  xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
+  xpcAccessibleGeneric* acc = mCache.Get(aProxy);
   if (acc) {
     return acc;
   }
 
   // XXX support exposing optional interfaces.
   uint8_t interfaces = 0;
   if (aProxy->mHasValue) {
     interfaces |= eValue;
   }
-  
+
   if (aProxy->mIsHyperLink) {
     interfaces |= eHyperLink;
   }
 
   if (aProxy->mIsHyperText) {
     interfaces |= eText;
     acc = new xpcAccessibleHyperText(aProxy, interfaces);
     mCache.Put(aProxy, acc);
--- a/accessible/xpcom/xpcAccessibleDocument.h
+++ b/accessible/xpcom/xpcAccessibleDocument.h
@@ -27,18 +27,16 @@ public:
   explicit xpcAccessibleDocument(DocAccessible* aIntl) :
     xpcAccessibleHyperText(aIntl), mCache(kDefaultCacheLength), mRemote(false) { }
 
   xpcAccessibleDocument(ProxyAccessible* aProxy, uint32_t aInterfaces) :
     xpcAccessibleHyperText(aProxy, aInterfaces), mCache(kDefaultCacheLength),
     mRemote(true) {}
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(xpcAccessibleDocument,
-                                           xpcAccessibleGeneric)
 
   // nsIAccessibleDocument
   NS_IMETHOD GetURL(nsAString& aURL) final override;
   NS_IMETHOD GetTitle(nsAString& aTitle) final override;
   NS_IMETHOD GetMimeType(nsAString& aType) final override;
   NS_IMETHOD GetDocType(nsAString& aType) final override;
   NS_IMETHOD GetDOMDocument(nsIDOMDocument** aDOMDocument) final override;
   NS_IMETHOD GetWindow(mozIDOMWindowProxy** aDOMWindow) final override;
@@ -70,43 +68,53 @@ private:
     }
 
     return nullptr;
   }
 
   void NotifyOfShutdown(Accessible* aAccessible)
   {
     MOZ_ASSERT(!mRemote);
-    xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
-    if (xpcAcc)
+    xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible);
+    if (xpcAcc) {
       xpcAcc->Shutdown();
+    }
 
     mCache.Remove(aAccessible);
+    if (mCache.Count() == 0 && mRefCnt == 1) {
+      GetAccService()->RemoveFromXPCDocumentCache(
+        mIntl.AsAccessible()->AsDoc());
+    }
   }
 
   void NotifyOfShutdown(ProxyAccessible* aProxy)
   {
     MOZ_ASSERT(mRemote);
-    xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
-    if (acc) {
-      acc->Shutdown();
+    xpcAccessibleGeneric* xpcAcc = mCache.Get(aProxy);
+    if (xpcAcc) {
+      xpcAcc->Shutdown();
     }
 
     mCache.Remove(aProxy);
+    if (mCache.Count() == 0 && mRefCnt == 1) {
+      GetAccService()->RemoveFromRemoteXPCDocumentCache(
+        mIntl.AsProxy()->AsDoc());
+    }
   }
 
   friend class DocManager;
   friend class DocAccessible;
   friend class ProxyAccessible;
   friend class ProxyAccessibleBase<ProxyAccessible>;
+  friend class xpcAccessibleGeneric;
 
   xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
   xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
 
-  nsRefPtrHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric> mCache;
+  nsDataHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric*> mCache;
   bool mRemote;
 };
 
 inline xpcAccessibleGeneric*
 ToXPC(Accessible* aAccessible)
 {
   if (!aAccessible)
     return nullptr;
--- a/accessible/xpcom/xpcAccessibleGeneric.cpp
+++ b/accessible/xpcom/xpcAccessibleGeneric.cpp
@@ -4,33 +4,53 @@
  * 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 "xpcAccessibleGeneric.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsISupports and cycle collection
+// nsISupports
 
-NS_IMPL_CYCLE_COLLECTION_0(xpcAccessibleGeneric)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleGeneric)
+NS_INTERFACE_MAP_BEGIN(xpcAccessibleGeneric)
   NS_INTERFACE_MAP_ENTRY(nsIAccessible)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleSelectable,
                                      mSupportedIfaces & eSelectable)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleValue,
                                      mSupportedIfaces & eValue)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleHyperLink,
                                      mSupportedIfaces & eHyperLink)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessible)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(xpcAccessibleGeneric)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleGeneric)
+NS_IMPL_ADDREF(xpcAccessibleGeneric)
+NS_IMPL_RELEASE(xpcAccessibleGeneric)
+
+xpcAccessibleGeneric::~xpcAccessibleGeneric()
+{
+  if (mIntl.IsNull()) {
+    return;
+  }
+
+  xpcAccessibleDocument* xpcDoc = nullptr;
+  if (mIntl.IsAccessible()) {
+    Accessible* acc = mIntl.AsAccessible();
+    if (!acc->IsDoc() && !acc->IsApplication()) {
+      xpcDoc = GetAccService()->GetXPCDocument(acc->Document());
+      xpcDoc->NotifyOfShutdown(acc);
+    }
+  } else {
+    ProxyAccessible* proxy = mIntl.AsProxy();
+    if (!proxy->IsDoc()) {
+      xpcDoc = GetAccService()->GetXPCDocument(proxy->Document());
+      xpcDoc->NotifyOfShutdown(proxy);
+    }
+  }
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessible
 
 Accessible*
 xpcAccessibleGeneric::ToInternalAccessible() const
 {
   return mIntl.AsAccessible();
--- a/accessible/xpcom/xpcAccessibleGeneric.h
+++ b/accessible/xpcom/xpcAccessibleGeneric.h
@@ -36,27 +36,26 @@ public:
       mSupportedIfaces |= eValue;
     if (aInternal->IsLink())
       mSupportedIfaces |= eHyperLink;
   }
 
   xpcAccessibleGeneric(ProxyAccessible* aProxy, uint8_t aInterfaces) :
     mIntl(aProxy), mSupportedIfaces(aInterfaces) {}
 
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(xpcAccessibleGeneric, nsIAccessible)
+  NS_DECL_ISUPPORTS
 
   // nsIAccessible
   virtual Accessible* ToInternalAccessible() const final override;
 
   // xpcAccessibleGeneric
   virtual void Shutdown();
 
 protected:
-  virtual ~xpcAccessibleGeneric() {}
+  virtual ~xpcAccessibleGeneric();
 
   AccessibleOrProxy mIntl;
 
   enum {
     eSelectable = 1 << 0,
     eValue = 1 << 1,
     eHyperLink = 1 << 2,
     eText = 1 << 3
--- a/addon-sdk/source/lib/dev/volcan.js
+++ b/addon-sdk/source/lib/dev/volcan.js
@@ -3291,27 +3291,16 @@ module.exports={
           "request": {
             "type": "screenshotToDataURL"
           },
           "response": {
             "value": {
               "_retval": "longstring"
             }
           }
-        },
-        {
-          "name": "getRawPermissionsTable",
-          "request": {
-            "type": "getRawPermissionsTable"
-          },
-          "response": {
-            "value": {
-              "_retval": "json"
-            }
-          }
         }
       ],
       "events": {}
     }
   },
   "from": "root"
 }
 
--- a/addon-sdk/source/lib/sdk/content/page-worker.js
+++ b/addon-sdk/source/lib/sdk/content/page-worker.js
@@ -8,18 +8,17 @@ const { Class } = require("../core/herit
 const { Disposable } = require('../core/disposable');
 const { data } = require("../self");
 const { once } = require("../dom/events");
 const { getAttachEventType } = require("./utils");
 const { Rules } = require('../util/rules');
 const { uuid } = require('../util/uuid');
 const { WorkerChild } = require("./worker-child");
 const { Cc, Ci, Cu } = require("chrome");
-const { observe } = require("../event/chrome");
-const { on } = require("../event/core");
+const { on: onSystemEvent } = require("../system/events");
 
 const appShell = Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci.nsIAppShellService);
 
 const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
 
 const pages = new Map();
 
 const DOC_INSERTED = "document-element-inserted";
@@ -91,16 +90,17 @@ const ChildPage = Class({
 
   get contentURL() {
     return this.options.contentURL;
   },
   set contentURL(url) {
     this.options.contentURL = url;
 
     url = this.options.contentURL ? data.url(this.options.contentURL) : "about:blank";
+
     this.webNav.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
   },
 
   onLocationChange: function(progress, request, location, flags) {
     // Ignore inner-frame events
     if (progress != this.webProgress)
       return;
     // Ignore events that don't change the document
@@ -116,24 +116,25 @@ const ChildPage = Class({
     once(this.contentWindow, event, () => {
       this.attachWorker();
     }, false);
   },
 
   QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"])
 });
 
-on(observe(DOC_INSERTED), "data", ({ target }) => {
-  let page = Array.from(pages.values()).find(p => p.contentWindow.document === target);
+onSystemEvent(DOC_INSERTED, ({type, subject, data}) => {
+  let page = Array.from(pages.values()).find(p => p.contentWindow.document === subject);
+
   if (!page)
     return;
 
   if (getAttachEventType(page.options) == DOC_INSERTED)
     page.attachWorker();
-});
+}, true);
 
 frames.port.on("sdk/frame/create", (frame, id, options) => {
   new ChildPage(frame, id, options);
 });
 
 frames.port.on("sdk/frame/set", (frame, id, params) => {
   let page = pages.get(id);
   if (!page)
--- a/addon-sdk/source/test/addons/jetpack-addon.ini
+++ b/addon-sdk/source/test/addons/jetpack-addon.ini
@@ -24,17 +24,16 @@ skip-if = true
 [main.xpi]
 [name-in-numbers.xpi]
 [name-in-numbers-plus.xpi]
 [packaging.xpi]
 [packed.xpi]
 [page-mod-debugger-post.xpi]
 [page-mod-debugger-pre.xpi]
 [page-worker.xpi]
-skip-if = true # Bug 1288619 and Bug 1288708
 [places.xpi]
 [predefined-id-with-at.xpi]
 [preferences-branch.xpi]
 [private-browsing-supported.xpi]
 skip-if = true
 [remote.xpi]
 [require.xpi]
 [self.xpi]
--- a/addon-sdk/source/test/test-api-utils.js
+++ b/addon-sdk/source/test/test-api-utils.js
@@ -276,16 +276,25 @@ exports.testValidateMapWithMissingKeyAnd
     },
     baz: {
       map: v => "foo"
     }
   });
   assert.deepEqual(val, { baz: "foo" });
 };
 
+function forEachEnabled() {
+  try {
+    eval(`for each (var x in {}) {}`);
+  } catch (e) {
+    return false;
+  }
+  return true;
+}
+
 exports.testAddIterator = function testAddIterator (assert) {
   let obj = {};
   let keys = ["foo", "bar", "baz"];
   let vals = [1, 2, 3];
   let keysVals = [["foo", 1], ["bar", 2], ["baz", 3]];
   apiUtils.addIterator(
     obj,
     function keysValsGen() {
@@ -298,19 +307,22 @@ exports.testAddIterator = function testA
   for (let key in obj)
     keysItr.push(key);
 
   assert.equal(keysItr.length, keys.length,
                    "the keys iterator returns the correct number of items");
   for (let i = 0; i < keys.length; i++)
     assert.equal(keysItr[i], keys[i], "the key is correct");
 
-  let valsItr = [];
-  for each (let val in obj)
-    valsItr.push(val);
-  assert.equal(valsItr.length, vals.length,
-                   "the vals iterator returns the correct number of items");
-  for (let i = 0; i < vals.length; i++)
-    assert.equal(valsItr[i], vals[i], "the val is correct");
-
+  if (forEachEnabled()) {
+    eval(`
+    let valsItr = [];
+    for each (let val in obj)
+      valsItr.push(val);
+    assert.equal(valsItr.length, vals.length,
+                     "the vals iterator returns the correct number of items");
+    for (let i = 0; i < vals.length; i++)
+      assert.equal(valsItr[i], vals[i], "the val is correct");
+  `);
+  }
 };
 
 require("sdk/test").run(exports);
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -418,19 +418,19 @@ exports["test Auto Unwrap Custom Attribu
   );
 
 });
 
 exports["test Object Tag"] = createProxyTest("", function (helper) {
 
   helper.createWorker(
     'new ' + function ContentScriptScope() {
-      // <object>, <embed> and other tags return typeof 'function'
+      // <object>, <embed> and other tags return typeof 'object'
       let flash = document.createElement("object");
-      assert(typeof flash == "function", "<object> is typeof 'function'");
+      assert(typeof flash == "object", "<object> is typeof 'function'");
       assert(flash.toString().match(/\[object HTMLObjectElement.*\]/), "<object> is HTMLObjectElement");
       assert("setAttribute" in flash, "<object> has a setAttribute method");
       done();
     }
   );
 
 });
 
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -395,30 +395,27 @@ pref("network.gonk.ms-release-mms-connec
 // Shortnumber matching needed for e.g. Brazil:
 // 03187654321 can be found with 87654321
 pref("dom.phonenumber.substringmatching.BR", 8);
 pref("dom.phonenumber.substringmatching.CO", 10);
 pref("dom.phonenumber.substringmatching.VE", 7);
 pref("dom.phonenumber.substringmatching.CL", 8);
 pref("dom.phonenumber.substringmatching.PE", 7);
 
-// NetworkStats
 #ifdef MOZ_WIDGET_GONK
-pref("dom.mozNetworkStats.enabled", true);
 pref("dom.webapps.firstRunWithSIM", true);
 #endif
 
 #ifdef MOZ_B2G_RIL
 // SingleVariant
 pref("dom.mozApps.single_variant_sourcedir", "/persist/svoperapps");
 #endif
 
 // WebSettings
 pref("dom.mozSettings.enabled", true);
-pref("dom.mozPermissionSettings.enabled", true);
 
 // controls if we want camera support
 pref("device.camera.enabled", true);
 pref("media.realtime_decoder.enabled", true);
 
 // TCPSocket
 pref("dom.mozTCPSocket.enabled", true);
 
@@ -496,19 +493,16 @@ pref("app.update.socket.retryTimeout", 3
 // Max of 20 consecutive retries (total 10 minutes) before giving up and marking
 // the update download as failed.
 // Note: Offline errors will always retry when the network comes online.
 pref("app.update.socket.maxErrors", 20);
 
 // Enable update logging for now, to diagnose growing pains in the
 // field.
 pref("app.update.log", true);
-
-// SystemUpdate API
-pref("dom.system_update.active", "@mozilla.org/updates/update-prompt;1");
 #else
 // Explicitly disable the shutdown watchdog.  It's enabled by default.
 // When the updater is disabled, we want to know about shutdown hangs.
 pref("shutdown.watchdog.timeoutSecs", -1);
 #endif
 
 // Allow webapps update checking
 pref("webapps.update.enabled", true);
@@ -608,19 +602,16 @@ pref("dom.ipc.processPriorityManager.BAC
 // The kernel can only accept 6 (OomScoreAdjust, KillUnderKB) pairs. But it is
 // okay, kernel will still kill processes with larger OomScoreAdjust first even
 // its OomScoreAdjust don't have a corresponding KillUnderKB.
 
 pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
 pref("hal.processPriorityManager.gonk.MASTER.KillUnderKB", 4096);
 pref("hal.processPriorityManager.gonk.MASTER.cgroup", "");
 
-pref("hal.processPriorityManager.gonk.PREALLOC.OomScoreAdjust", 67);
-pref("hal.processPriorityManager.gonk.PREALLOC.cgroup", "apps/bg_non_interactive");
-
 pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.OomScoreAdjust", 67);
 pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.KillUnderKB", 5120);
 pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.cgroup", "apps/critical");
 
 pref("hal.processPriorityManager.gonk.FOREGROUND.OomScoreAdjust", 134);
 pref("hal.processPriorityManager.gonk.FOREGROUND.KillUnderKB", 6144);
 pref("hal.processPriorityManager.gonk.FOREGROUND.cgroup", "apps");
 
@@ -688,22 +679,16 @@ pref("gonk.notifyHardLowMemUnderKB", 143
 // placed above the BACKGROUND priority class.
 pref("gonk.notifySoftLowMemUnderKB", 43008);
 
 // We wait this long before polling the memory-pressure fd after seeing one
 // memory pressure event.  (When we're not under memory pressure, we sit
 // blocked on a poll(), and this pref has no effect.)
 pref("gonk.systemMemoryPressureRecoveryPollMS", 5000);
 
-// Enable pre-launching content processes for improved startup time
-// (hiding latency).
-pref("dom.ipc.processPrelaunch.enabled", true);
-// Wait this long before pre-launching a new subprocess.
-pref("dom.ipc.processPrelaunch.delayMs", 5000);
-
 pref("dom.ipc.reuse_parent_app", false);
 
 // When a process receives a system message, we hold a CPU wake lock on its
 // behalf for this many seconds, or until it handles the system message,
 // whichever comes first.
 pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
 
 // Ignore the "dialog=1" feature in window.open.
@@ -944,19 +929,16 @@ pref("identity.fxaccounts.remote.oauth.u
 pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
 
 // Disable Firefox Accounts device registration until bug 1238895 is fixed.
 pref("identity.fxaccounts.skipDeviceRegistration", true);
 
 // Enable mapped array buffer.
 pref("dom.mapped_arraybuffer.enabled", true);
 
-// SystemUpdate API
-pref("dom.system_update.enabled", true);
-
 // UDPSocket API
 pref("dom.udpsocket.enabled", true);
 
 // Enable TV Manager API
 pref("dom.tv.enabled", true);
 
 // Enable Inputport Manager API
 pref("dom.inputport.enabled", true);
--- a/b2g/chrome/content/devtools/hud.js
+++ b/b2g/chrome/content/devtools/hud.js
@@ -31,35 +31,32 @@ XPCOMUtils.defineLazyGetter(this, 'Event
 XPCOMUtils.defineLazyGetter(this, 'PerformanceEntriesFront', function() {
   return devtools.require('devtools/server/actors/performance-entries').PerformanceEntriesFront;
 });
 
 XPCOMUtils.defineLazyGetter(this, 'MemoryFront', function() {
   return devtools.require('devtools/server/actors/memory').MemoryFront;
 });
 
-Cu.import('resource://gre/modules/Frames.jsm');
-
 var _telemetryDebug = false;
 
 function telemetryDebug(...args) {
   if (_telemetryDebug) {
     args.unshift('[AdvancedTelemetry]');
     console.log(...args);
   }
 }
 
 /**
  * The Developer HUD is an on-device developer tool that displays widgets,
  * showing visual debug information about apps. Each widget corresponds to a
  * metric as tracked by a metric watcher (e.g. consoleWatcher).
  */
 var developerHUD = {
 
-  _targets: new Map(),
   _histograms: new Set(),
   _customHistograms: new Set(),
   _client: null,
   _conn: null,
   _watchers: [],
   _logging: true,
   _telemetry: false,
 
@@ -94,23 +91,16 @@ var developerHUD = {
     this._client = new DebuggerClient(transport);
 
     for (let w of this._watchers) {
       if (w.init) {
         w.init(this._client);
       }
     }
 
-    Frames.addObserver(this);
-
-    let appFrames = Frames.list().filter(frame => frame.getAttribute('mozapp'));
-    for (let frame of appFrames) {
-      this.trackFrame(frame);
-    }
-
     SettingsListener.observe('hud.logging', this._logging, enabled => {
       this._logging = enabled;
     });
 
     SettingsListener.observe('hud.telemetry.logging', _telemetryDebug, enabled => {
       _telemetryDebug = enabled;
     });
 
@@ -119,73 +109,20 @@ var developerHUD = {
     });
   },
 
   uninit() {
     if (!this._client) {
       return;
     }
 
-    for (let frame of this._targets.keys()) {
-      this.untrackFrame(frame);
-    }
-
-    Frames.removeObserver(this);
-
     this._client.close();
     delete this._client;
   },
 
-  /**
-   * This method will ask all registered watchers to track and update metrics
-   * on an app frame.
-   */
-  trackFrame(frame) {
-    if (this._targets.has(frame)) {
-      return;
-    }
-
-    DebuggerServer.connectToChild(this._conn, frame).then(actor => {
-      let target = new Target(frame, actor);
-      this._targets.set(frame, target);
-
-      for (let w of this._watchers) {
-        w.trackTarget(target);
-      }
-    });
-  },
-
-  untrackFrame(frame) {
-    let target = this._targets.get(frame);
-    if (target) {
-      for (let w of this._watchers) {
-        w.untrackTarget(target);
-      }
-
-      target.destroy();
-      this._targets.delete(frame);
-    }
-  },
-
-  onFrameCreated(frame, isFirstAppFrame) {
-    let mozapp = frame.getAttribute('mozapp');
-    if (!mozapp) {
-      return;
-    }
-    this.trackFrame(frame);
-  },
-
-  onFrameDestroyed(frame, isLastAppFrame) {
-    let mozapp = frame.getAttribute('mozapp');
-    if (!mozapp) {
-      return;
-    }
-    this.untrackFrame(frame);
-  },
-
   log(message) {
     if (this._logging) {
       dump(DEVELOPER_HUD_LOG_PREFIX + ': ' + message + '\n');
     }
   }
 
 };
 
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -474,53 +474,32 @@ setUpdateTrackingId();
         console.log('Unable to read pref layers.low-precision-opacity: ' + e);
       }
     }
   });
 })();
 
 // ======================= Dogfooders FOTA ==========================
 if (AppConstants.MOZ_B2G_RIL) {
-  XPCOMUtils.defineLazyModuleGetter(this, "AppsUtils",
-                                    "resource://gre/modules/AppsUtils.jsm");
-
   SettingsListener.observe('debug.performance_data.dogfooding', false,
     isDogfooder => {
       if (!isDogfooder) {
         dump('AUS:Settings: Not a dogfooder!\n');
         return;
       }
 
       if (!('mozTelephony' in navigator)) {
         dump('AUS:Settings: There is no mozTelephony!\n');
         return;
       }
 
       if (!('mozMobileConnections' in navigator)) {
         dump('AUS:Settings: There is no mozMobileConnections!\n');
         return;
       }
-
-      let conn = navigator.mozMobileConnections[0];
-      conn.addEventListener('radiostatechange', function onradiostatechange() {
-        if (conn.radioState !== 'enabled') {
-          return;
-        }
-
-        conn.removeEventListener('radiostatechange', onradiostatechange);
-        navigator.mozTelephony.dial('*#06#').then(call => {
-          return call.result.then(res => {
-            if (res.success && res.statusMessage
-                && (res.serviceCode === 'scImei')) {
-              Services.prefs.setCharPref("app.update.imei_hash",
-                                         AppsUtils.computeHash(res.statusMessage, "SHA512"));
-            }
-          });
-        });
-      });
     });
 }
 
 // =================== Various simple mapping  ======================
 var settingsToObserve = {
   'accessibility.screenreader_quicknav_modes': {
     prefName: 'accessibility.accessfu.quicknav_modes',
     resetToPref: true,
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -2,25 +2,23 @@
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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/. */
 
 window.performance.mark('gecko-shell-loadstart');
 
 Cu.import('resource://gre/modules/NotificationDB.jsm');
-Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 Cu.import('resource://gre/modules/AlertsHelper.jsm');
 Cu.import('resource://gre/modules/SystemUpdateService.jsm');
 
 if (isGonk) {
-  Cu.import('resource://gre/modules/NetworkStatsService.jsm');
   Cu.import('resource://gre/modules/ResourceStatsService.jsm');
 }
 
 // Identity
 Cu.import('resource://gre/modules/SignInToWebsite.jsm');
 SignInToWebsiteController.init();
 
 Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
@@ -353,17 +351,16 @@ var shell = {
     // <html:iframe id="systemapp"
     //              mozbrowser="true" allowfullscreen="true"
     //              style="overflow: hidden; height: 100%; width: 100%; border: none;"
     //              src="data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
     let systemAppFrame =
       document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
     systemAppFrame.setAttribute('id', 'systemapp');
     systemAppFrame.setAttribute('mozbrowser', 'true');
-    systemAppFrame.setAttribute('mozapp', manifestURL);
     systemAppFrame.setAttribute('allowfullscreen', 'true');
     systemAppFrame.setAttribute('src', 'blank.html');
     let container = document.getElementById('container');
 
     if (AppConstants.platform == 'macosx') {
       // See shell.html
       let hotfix = document.getElementById('placeholder');
       if (hotfix) {
--- a/b2g/chrome/content/shell_remote.js
+++ b/b2g/chrome/content/shell_remote.js
@@ -48,17 +48,16 @@ var remoteShell = {
     // <html:iframe id="this.id"
     //              mozbrowser="true"
     //              allowfullscreen="true"
     //              src="blank.html"/>
     let systemAppFrame =
       document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
     systemAppFrame.setAttribute("id", this.id);
     systemAppFrame.setAttribute("mozbrowser", "true");
-    systemAppFrame.setAttribute("mozapp", manifestURL);
     systemAppFrame.setAttribute("allowfullscreen", "true");
     systemAppFrame.setAttribute("src", "blank.html");
 
     let container = document.getElementById("container");
     this.contentBrowser = container.appendChild(systemAppFrame);
     this.contentBrowser.src = homeURL + window.location.hash;
 
     window.addEventListener("unload", this);
--- a/b2g/components/AlertsHelper.jsm
+++ b/b2g/components/AlertsHelper.jsm
@@ -7,26 +7,21 @@
 this.EXPORTED_SYMBOLS = [];
 
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
                                    "@mozilla.org/system-message-internal;1",
                                    "nsISystemMessagesInternal");
 
-XPCOMUtils.defineLazyServiceGetter(this, "appsService",
-                                   "@mozilla.org/AppsService;1",
-                                   "nsIAppsService");
-
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage",
                                    "@mozilla.org/notificationStorage;1",
                                    "nsINotificationStorage");
 
 XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
@@ -35,18 +30,16 @@ XPCOMUtils.defineLazyGetter(this, "ppmm"
 });
 
 function debug(str) {
   //dump("=*= AlertsHelper.jsm : " + str + "\n");
 }
 
 const kNotificationIconSize = 128;
 
-const kDesktopNotificationPerm = "desktop-notification";
-
 const kNotificationSystemMessageName = "notification";
 
 const kDesktopNotification      = "desktop-notification";
 const kDesktopNotificationShow  = "desktop-notification-show";
 const kDesktopNotificationClick = "desktop-notification-click";
 const kDesktopNotificationClose = "desktop-notification-close";
 
 const kTopicAlertClickCallback = "alertclickcallback";
@@ -141,43 +134,16 @@ var AlertsHelper = {
   },
 
   registerListener: function(alertId, cookie, alertListener) {
     this._listeners[alertId] = { observer: alertListener, cookie: cookie };
   },
 
   registerAppListener: function(uid, listener) {
     this._listeners[uid] = listener;
-
-    appsService.getManifestFor(listener.manifestURL).then((manifest) => {
-      let app = appsService.getAppByManifestURL(listener.manifestURL);
-      let helper = new ManifestHelper(manifest, app.origin, app.manifestURL);
-      let getNotificationURLFor = function(messages) {
-        if (!messages) {
-          return null;
-        }
-
-        for (let i = 0; i < messages.length; i++) {
-          let message = messages[i];
-          if (message === kNotificationSystemMessageName) {
-            return helper.fullLaunchPath();
-          } else if (typeof message === "object" &&
-                     kNotificationSystemMessageName in message) {
-            return helper.resolveURL(message[kNotificationSystemMessageName]);
-          }
-        }
-
-        // No message found...
-        return null;
-      }
-
-      listener.target = getNotificationURLFor(manifest.messages);
-
-      // Bug 816944 - Support notification messages for entry_points.
-    });
   },
 
   deserializeStructuredClone: function(dataString) {
     if (!dataString) {
       return null;
     }
     let scContainer = Cc["@mozilla.org/docshell/structured-clone-container;1"].
       createInstance(Ci.nsIStructuredCloneContainer);
@@ -219,24 +185,16 @@ var AlertsHelper = {
         mozbehavior: behavior
       });
     }
 
     if (!manifestURL || !manifestURL.length) {
       send(null, null);
       return;
     }
-
-    // If we have a manifest URL, get the icon and title from the manifest
-    // to prevent spoofing.
-    appsService.getManifestFor(manifestURL).then((manifest) => {
-      let app = appsService.getAppByManifestURL(manifestURL);
-      let helper = new ManifestHelper(manifest, app.origin, manifestURL);
-      send(helper.name, helper.iconURLForSize(kNotificationIconSize));
-    });
   },
 
   showAlertNotification: function(aMessage) {
     let data = aMessage.data;
     let currentListener = this._listeners[data.name];
     if (currentListener && currentListener.observer) {
       currentListener.observer.observe(null, kTopicAlertFinished, currentListener.cookie);
     }
@@ -251,23 +209,16 @@ var AlertsHelper = {
   closeAlert: function(name) {
     SystemAppProxy._sendCustomEvent(kMozChromeNotificationEvent, {
       type: kDesktopNotificationClose,
       id: name
     });
   },
 
   receiveMessage: function(aMessage) {
-    if (!aMessage.target.assertAppHasPermission(kDesktopNotificationPerm)) {
-      Cu.reportError("Desktop-notification message " + aMessage.name +
-                     " from a content process with no " + kDesktopNotificationPerm +
-                     " privileges.");
-      return;
-    }
-
     switch(aMessage.name) {
       case kMessageAlertNotificationSend:
         this.showAlertNotification(aMessage);
         break;
 
       case kMessageAlertNotificationClose:
         this.closeAlert(aMessage.data.name);
         break;
deleted file mode 100644
--- a/b2g/components/B2GAppMigrator.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-function debug(s) {
-  dump("-*- B2GAppMigrator.js: " + s + "\n");
-}
-const DEBUG = false;
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-const kMigrationMessageName = "webapps-before-update-merge";
-
-const kIDBDirType = "indexedDBPDir";
-const kProfileDirType = "ProfD";
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "appsService",
-                                   "@mozilla.org/AppsService;1",
-                                   "nsIAppsService");
-
-function B2GAppMigrator() {
-}
-
-B2GAppMigrator.prototype = {
-  classID:         Components.ID('{7211ece0-b458-4635-9afc-f8d7f376ee95}'),
-  QueryInterface:  XPCOMUtils.generateQI([Ci.nsIObserver,
-                                          Ci.nsISupportsWeakReference]),
-  executeBrowserMigration: function() {
-    if (DEBUG) debug("Executing Browser Migration");
-    // The browser db file and directory names are hashed the same way
-    // everywhere, so it should be the same on all systems. We should
-    // be able to just hardcode it.
-    let browserDBDirName = "2959517650brreosw";
-    let browserDBFileName = browserDBDirName + ".sqlite";
-
-    // Storage directories need to be prefixed with the local id of
-    // the app
-    let browserLocalAppId = appsService.getAppLocalIdByManifestURL("app://browser.gaiamobile.org/manifest.webapp");
-    let browserAppStorageDirName = browserLocalAppId + "+f+app+++browser.gaiamobile.org";
-
-    // On the phone, the browser db will only be in the old IDB
-    // directory, since it only existed up until v2.0. On desktop, it
-    // will exist in the profile directory.
-    //
-    // Uses getDir with filename appending to make sure we don't
-    // create extra directories along the way if they don't already
-    // exist.
-    let browserDBFile = FileUtils.getDir(kIDBDirType,
-                                         ["storage",
-                                          "persistent",
-                                          browserAppStorageDirName,
-                                          "idb"], false, true);
-    browserDBFile.append(browserDBFileName);
-    let browserDBDir = FileUtils.getDir(kIDBDirType,
-                                        ["storage",
-                                         "persistent",
-                                         browserAppStorageDirName,
-                                         "idb",
-                                         browserDBDirName
-                                        ], false, true);
-
-    if (!browserDBFile.exists()) {
-      if (DEBUG) debug("Browser DB " + browserDBFile.path + " does not exist, trying profile location");
-      browserDBFile = FileUtils.getDir(kProfileDirType,
-                                        ["storage",
-                                         "persistent",
-                                         browserAppStorageDirName,
-                                         "idb"], false, true);
-      browserDBFile.append(browserDBFileName);
-      if (!browserDBFile.exists()) {
-        if (DEBUG) debug("Browser DB " + browserDBFile.path + " does not exist. Cannot copy browser db.");
-        return;
-      }
-      // If we have confirmed we have a DB file, we should also have a
-      // directory.
-      browserDBDir = FileUtils.getDir(kProfileDirType,
-                                      ["storage",
-                                       "persistent",
-                                       browserAppStorageDirName,
-                                       "idb",
-                                       browserDBDirName
-                                      ], false, true);
-    }
-
-    let systemLocalAppId = appsService.getAppLocalIdByManifestURL("app://system.gaiamobile.org/manifest.webapp");
-    let systemAppStorageDirName = systemLocalAppId + "+f+app+++system.gaiamobile.org";
-
-    // This check futureproofs the system DB storage directory. It
-    // currently exists outside of the profile but will most likely
-    // move into the profile at some point.
-    let systemDBDir = FileUtils.getDir(kIDBDirType,
-                                       ["storage",
-                                        "persistent",
-                                        systemAppStorageDirName,
-                                        "idb"], false, true);
-
-    if (!systemDBDir.exists()) {
-      if (DEBUG) debug("System DB directory " + systemDBDir.path + " does not exist, trying profile location");
-      systemDBDir = FileUtils.getDir(kProfileDirType,
-                                     ["storage",
-                                      "persistent",
-                                      systemAppStorageDirName,
-                                      "idb"], false, true);
-      if (!systemDBDir.exists()) {
-        if (DEBUG) debug("System DB directory " + systemDBDir.path + " does not exist. Cannot copy browser db.");
-        return;
-      }
-    }
-
-    if (DEBUG) {
-      debug("Browser DB file exists, copying");
-      debug("Browser local id: " + browserLocalAppId + "");
-      debug("System local id: " + systemLocalAppId + "");
-      debug("Browser DB file path: " + browserDBFile.path + "");
-      debug("Browser DB dir path: " + browserDBDir.path + "");
-      debug("System DB directory path: " + systemDBDir.path + "");
-    }
-
-    try {
-      browserDBFile.copyTo(systemDBDir, browserDBFileName);
-    } catch (e) {
-      debug("File copy caused error! " + e.name);
-    }
-    try {
-      browserDBDir.copyTo(systemDBDir, browserDBDirName);
-    } catch (e) {
-      debug("Dir copy caused error! " + e.name);
-    }
-    if (DEBUG) debug("Browser DB copied successfully");
-  },
-
-  observe: function(subject, topic, data) {
-    switch (topic) {
-      case kMigrationMessageName:
-        this.executeBrowserMigration();
-        break;
-      default:
-        debug("Unhandled topic: " + topic);
-        break;
-    }
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GAppMigrator]);
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -4,23 +4,16 @@ category agent-style-sheets browser-cont
 # AlertsService.js
 component {fe33c107-82a4-41d6-8c64-5353267e04c9} AlertsService.js
 contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e04c9}
 
 # ContentPermissionPrompt.js
 component {8c719f03-afe0-4aac-91ff-6c215895d467} ContentPermissionPrompt.js
 contract @mozilla.org/content-permission/prompt;1 {8c719f03-afe0-4aac-91ff-6c215895d467}
 
-#ifdef MOZ_UPDATER
-# UpdatePrompt.js
-component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js
-contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59}
-category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
-#endif
-
 #ifdef MOZ_B2G
 # DirectoryProvider.js
 component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js
 contract @mozilla.org/b2g/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}
 category xpcom-directory-providers b2g-directory-provider @mozilla.org/b2g/directory-provider;1
 #endif
 
 # SystemMessageGlue.js
@@ -86,20 +79,16 @@ contract @mozilla.org/commandlinehandler
 category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
 #endif
 
 # BootstrapCommandLine.js
 component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js
 contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}
 category command-line-handler m-b2gbootstrap @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap
 
-# B2GAppMigrator.js
-component {7211ece0-b458-4635-9afc-f8d7f376ee95} B2GAppMigrator.js
-contract @mozilla.org/app-migrator;1 {7211ece0-b458-4635-9afc-f8d7f376ee95}
-
 # B2GPresentationDevicePrompt.js
 component {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} B2GPresentationDevicePrompt.js
 contract @mozilla.org/presentation-device/prompt;1 {4a300c26-e99b-4018-ab9b-c48cf9bc4de1}
 
 # PresentationRequestUIGlue.js
 component {ccc8a839-0b64-422b-8a60-fb2af0e376d0} PresentationRequestUIGlue.js
 contract @mozilla.org/presentation/requestuiglue;1 {ccc8a839-0b64-422b-8a60-fb2af0e376d0}
 
--- a/b2g/components/BootstrapCommandLine.js
+++ b/b2g/components/BootstrapCommandLine.js
@@ -1,15 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
 
 function BootstrapCommandlineHandler() {
   this.wrappedJSObject = this;
   this.startManifestURL = null;
 }
 
 BootstrapCommandlineHandler.prototype = {
     bailout: function(aMsg) {
@@ -32,21 +31,16 @@ BootstrapCommandlineHandler.prototype = 
         this.startManifestURL = aCmdLine.handleFlagWithParam("start-manifest", false);
       } catch(e) {
         return;
       }
 
       if (!this.startManifestURL) {
         return;
       }
-
-      if (!isAbsoluteURI(this.startManifestURL)) {
-        this.bailout("The start manifest url must be absolute.");
-        return;
-      }
     },
 
     helpInfo: "--start-manifest=manifest_url",
     classID: Components.ID("{fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}"),
     QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler])
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BootstrapCommandlineHandler]);
--- a/b2g/components/Bootstraper.jsm
+++ b/b2g/components/Bootstraper.jsm
@@ -7,66 +7,37 @@
 this.EXPORTED_SYMBOLS = ["Bootstraper"];
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const CC = Components.Constructor;
 
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
 
 function debug(aMsg) {
   //dump("-*- Bootstraper: " + aMsg + "\n");
 }
 
 /**
   * This module loads the manifest for app from the --start-url enpoint and
   * ensures that it's installed as the system app.
   */
 this.Bootstraper = {
   _manifestURL: null,
-  _startupURL: null,
 
   bailout: function(aMsg) {
     dump("************************************************************\n");
     dump("* /!\\ " + aMsg + "\n");
     dump("************************************************************\n");
     let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
                        .getService(Ci.nsIAppStartup);
     appStartup.quit(appStartup.eForceQuit);
   },
 
-  installSystemApp: function(aManifest) {
-    // Get the appropriate startup url from the manifest launch_path.
-    let base = Services.io.newURI(this._manifestURL, null, null);
-    let origin = base.prePath;
-    let helper = new ManifestHelper(aManifest, origin, this._manifestURL);
-    this._startupURL = helper.fullLaunchPath();
-
-    return new Promise((aResolve, aReject) => {
-      debug("Origin is " + origin);
-      let appData = {
-        app: {
-          installOrigin: origin,
-          origin: origin,
-          manifest: aManifest,
-          manifestURL: this._manifestURL,
-          manifestHash: AppsUtils.computeHash(JSON.stringify(aManifest)),
-          appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED
-        },
-        appId: 1,
-        isBrowser: false,
-        isPackage: false
-      };
-
-      //DOMApplicationRegistry.confirmInstall(appData, null, aResolve);
-    });
-  },
-
   /**
     * Resolves to a json manifest.
     */
   loadManifest: function() {
     return new Promise((aResolve, aReject) => {
       debug("Loading manifest " + this._manifestURL);
 
       let xhr =  Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
@@ -85,19 +56,18 @@ this.Bootstraper = {
       xhr.addEventListener("error", () => {
         aReject("Error loading " + this._manifestURL);
       });
       xhr.send(null);
     });
   },
 
   configure: function() {
-    debug("Setting startup prefs... " + this._startupURL);
     Services.prefs.setCharPref("b2g.system_manifest_url", this._manifestURL);
-    Services.prefs.setCharPref("b2g.system_startup_url", this._startupURL);
+    Services.prefs.setCharPref("b2g.system_startup_url", "");
     return Promise.resolve();
   },
 
   /**
     * If a system app is already installed, uninstall it so that we can
     * cleanly replace it by the current one.
     */
   uninstallPreviousSystemApp: function() {
@@ -142,15 +112,14 @@ this.Bootstraper = {
     if (!this.isInstallRequired(this._manifestURL)) {
       debug("Already configured for " + this._manifestURL);
       return Promise.resolve();
     }
 
     return new Promise((aResolve, aReject) => {
       this.uninstallPreviousSystemApp.bind(this)
           .then(this.loadManifest.bind(this))
-          .then(this.installSystemApp.bind(this))
           .then(this.configure.bind(this))
           .then(aResolve)
           .catch(aReject);
     });
   }
 };
--- a/b2g/components/ContentPermissionPrompt.js
+++ b/b2g/components/ContentPermissionPrompt.js
@@ -8,30 +8,21 @@ function debug(str) {
   //dump("-*- ContentPermissionPrompt: " + str + "\n");
 }
 
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 const Cc = Components.classes;
 
-const PROMPT_FOR_UNKNOWN = ["audio-capture",
-                            "desktop-notification",
-                            "geolocation",
-                            "video-capture"];
-// Due to privary issue, permission requests like GetUserMedia should prompt
-// every time instead of providing session persistence.
-const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"];
-const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
+const PROMPT_FOR_UNKNOWN = ["desktop-notification",
+                            "geolocation"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
-Cu.import("resource://gre/modules/PermissionsTable.jsm");
 
 var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
 var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
 
 var permissionSpecificChecker = {};
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
@@ -64,66 +55,16 @@ function buildDefaultChoices(aTypesInfo)
         choices = {};
       }
       choices[type.access] = type.options[0];
     }
   }
   return choices;
 }
 
-/**
- * aTypesInfo is an array of {permission, access, action, deny} which keeps
- * the information of each permission. This arrary is initialized in
- * ContentPermissionPrompt.prompt and used among functions.
- *
- * aTypesInfo[].permission : permission name
- * aTypesInfo[].access     : permission name + request.access
- * aTypesInfo[].action     : the default action of this permission
- * aTypesInfo[].deny       : true if security manager denied this app's origin
- *                           principal.
- * Note:
- *   aTypesInfo[].permission will be sent to prompt only when
- *   aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
- */
-function rememberPermission(aTypesInfo, aPrincipal, aSession)
-{
-  function convertPermToAllow(aPerm, aPrincipal)
-  {
-    let type =
-      permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
-    if (shouldPrompt(aPerm, type)) {
-      debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
-      if (!aSession) {
-        permissionManager.addFromPrincipal(aPrincipal,
-                                           aPerm,
-                                           Ci.nsIPermissionManager.ALLOW_ACTION);
-      } else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
-        permissionManager.addFromPrincipal(aPrincipal,
-                                           aPerm,
-                                           Ci.nsIPermissionManager.ALLOW_ACTION,
-                                           Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
-      }
-    }
-  }
-
-  for (let i in aTypesInfo) {
-    // Expand the permission to see if we have multiple access properties
-    // to convert
-    let perm = aTypesInfo[i].permission;
-    let access = PermissionsTable[perm].access;
-    if (access) {
-      for (let idx in access) {
-        convertPermToAllow(perm + "-" + access[idx], aPrincipal);
-      }
-    } else {
-      convertPermToAllow(perm, aPrincipal);
-    }
-  }
-}
-
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
 
   handleExistingPermission: function handleExistingPermission(request,
                                                               typesInfo) {
     typesInfo.forEach(function(type) {
       type.action =
@@ -161,70 +102,16 @@ ContentPermissionPrompt.prototype = {
     if (typesInfo.every(checkDenyPermission)) {
       debug("all permission requests are denied");
       request.cancel();
       return true;
     }
     return false;
   },
 
-  // multiple requests should be audio and video
-  checkMultipleRequest: function checkMultipleRequest(typesInfo) {
-    if (typesInfo.length == 1) {
-      return true;
-    } else if (typesInfo.length > 1) {
-      let checkIfAllowMultiRequest = function(type) {
-        return (ALLOW_MULTIPLE_REQUESTS.indexOf(type.access) !== -1);
-      }
-      if (typesInfo.every(checkIfAllowMultiRequest)) {
-        debug("legal multiple requests");
-        return true;
-      }
-    }
-
-    return false;
-  },
-
-  handledByApp: function handledByApp(request, typesInfo) {
-    if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
-        request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
-      // This should not really happen
-      request.cancel();
-      return true;
-    }
-
-    let appsService = Cc["@mozilla.org/AppsService;1"]
-                        .getService(Ci.nsIAppsService);
-    let app = appsService.getAppByLocalId(request.principal.appId);
-
-    // Check each permission if it's denied by permission manager with app's
-    // URL.
-    let notDenyAppPrincipal = function(type) {
-      let url = Services.io.newURI(app.origin, null, null);
-      let principal =
-        secMan.createCodebasePrincipal(url,
-                                       {appId: request.principal.appId});
-      let result = Services.perms.testExactPermissionFromPrincipal(principal,
-                                                                   type.access);
-
-      if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
-          result == Ci.nsIPermissionManager.PROMPT_ACTION) {
-        type.deny = false;
-      }
-      return !type.deny;
-    }
-    // Cancel the entire request if one of the requested permissions is denied
-    if (!typesInfo.every(notDenyAppPrincipal)) {
-      request.cancel();
-      return true;
-    }
-
-    return false;
-  },
-
   handledByPermissionType: function handledByPermissionType(request, typesInfo) {
     for (let i in typesInfo) {
       if (permissionSpecificChecker.hasOwnProperty(typesInfo[i].permission) &&
           permissionSpecificChecker[typesInfo[i].permission](request)) {
         return true;
       }
     }
 
@@ -261,23 +148,17 @@ ContentPermissionPrompt.prototype = {
     }
 
 
     if (typesInfo.length == 0) {
       request.cancel();
       return;
     }
 
-    if(!this.checkMultipleRequest(typesInfo)) {
-      request.cancel();
-      return;
-    }
-
-    if (this.handledByApp(request, typesInfo) ||
-        this.handledByPermissionType(request, typesInfo)) {
+    if (this.handledByPermissionType(request, typesInfo)) {
       return;
     }
 
     // returns true if the request was handled
     if (this.handleExistingPermission(request, typesInfo)) {
        return;
     }
 
@@ -331,35 +212,29 @@ ContentPermissionPrompt.prototype = {
     this.sendToBrowserWindow("cancel-permission-prompt", request,
                              typesInfo);
   },
 
   delegatePrompt: function(request, typesInfo, callback) {
     this.sendToBrowserWindow("permission-prompt", request, typesInfo,
                              function(type, remember, choices) {
       if (type == "permission-allow") {
-        rememberPermission(typesInfo, request.principal, !remember);
         if (callback) {
           callback();
         }
         request.allow(choices);
         return;
       }
 
       let addDenyPermission = function(type) {
         debug("add " + type.permission +
               " to permission manager with DENY_ACTION");
         if (remember) {
           Services.perms.addFromPrincipal(request.principal, type.access,
                                           Ci.nsIPermissionManager.DENY_ACTION);
-        } else if (PERMISSION_NO_SESSION.indexOf(type.access) < 0) {
-          Services.perms.addFromPrincipal(request.principal, type.access,
-                                          Ci.nsIPermissionManager.DENY_ACTION,
-                                          Ci.nsIPermissionManager.EXPIRE_SESSION,
-                                          0);
         }
       }
       try {
         // This will trow if we are canceling because the remote process died.
         // Just eat the exception and call the callback that will cleanup the
         // visibility event listener.
         typesInfo.forEach(addDenyPermission);
       } catch(e) { }
@@ -384,21 +259,17 @@ ContentPermissionPrompt.prototype = {
           return;
         SystemAppProxy.removeEventListener("mozContentEvent", contentEvent);
 
         callback(detail.type, detail.remember, detail.choices);
       })
     }
 
     let principal = request.principal;
-    let isApp = principal.appStatus != Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED;
-    let remember = (principal.appStatus == Ci.nsIPrincipal.APP_STATUS_PRIVILEGED ||
-                    principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
-                    ? true
-                    : request.remember;
+    let remember = request.remember;
     let isGranted = typesInfo.every(function(type) {
       return type.action == Ci.nsIPermissionManager.ALLOW_ACTION;
     });
     let permissions = {};
     for (let i in typesInfo) {
       debug("prompt " + typesInfo[i].permission);
       permissions[typesInfo[i].permission] = typesInfo[i].options;
     }
@@ -406,25 +277,21 @@ ContentPermissionPrompt.prototype = {
     let details = {
       type: type,
       permissions: permissions,
       id: requestId,
       // This system app uses the origin from permission events to
       // compare against the mozApp.origin of app windows, so we
       // are not concerned with origin suffixes here (appId, etc).
       origin: principal.originNoSuffix,
-      isApp: isApp,
+      isApp: false,
       remember: remember,
       isGranted: isGranted,
     };
 
-    if (isApp) {
-      details.manifestURL = DOMApplicationRegistry.getManifestURLByLocalId(principal.appId);
-    }
-
     // request.element is defined for OOP content, while request.window
     // is defined for In-Process content.
     // In both cases the message needs to be dispatched to the top-level
     // <iframe mozbrowser> container in the system app.
     // So the above code iterates over window.realFrameElement in order
     // to crosss mozbrowser iframes boundaries and find the top-level
     // one in the system app.
     // window.realFrameElement will be |null| if the code try to cross
@@ -439,23 +306,10 @@ ContentPermissionPrompt.prototype = {
     SystemAppProxy.dispatchEvent(details, targetElement);
   },
 
   classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt])
 };
 
-(function() {
-  // Do not allow GetUserMedia while in call.
-  permissionSpecificChecker["audio-capture"] = function(request) {
-    let forbid = false;
-
-    if (forbid) {
-      request.cancel();
-    }
-
-    return forbid;
-  };
-})();
-
 //module initialization
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
--- a/b2g/components/DebuggerActors.js
+++ b/b2g/components/DebuggerActors.js
@@ -25,20 +25,17 @@ XPCOMUtils.defineLazyGetter(this, "Frame
 function B2GTabList(connection) {
   BrowserTabList.call(this, connection);
   this._listening = false;
 }
 
 B2GTabList.prototype = Object.create(BrowserTabList.prototype);
 
 B2GTabList.prototype._getBrowsers = function() {
-  return Frames.list().filter(frame => {
-    // Ignore app frames
-    return !frame.getAttribute("mozapp");
-  });
+  return Frames.list();
 };
 
 B2GTabList.prototype._getSelectedBrowser = function() {
   return this._getBrowsers().find(frame => {
     // Find the one visible browser (if any)
     return !frame.classList.contains("hidden");
   });
 };
@@ -54,30 +51,20 @@ B2GTabList.prototype._listenForEventsIf 
   if (this._listening != shouldListen) {
     let op = shouldListen ? "addObserver" : "removeObserver";
     Frames[op](this);
     this._listening = shouldListen;
   }
 };
 
 B2GTabList.prototype.onFrameCreated = function(frame) {
-  let mozapp = frame.getAttribute("mozapp");
-  if (mozapp) {
-    // Ignore app frames
-    return;
-  }
   this._notifyListChanged();
   this._checkListening();
 };
 
 B2GTabList.prototype.onFrameDestroyed = function(frame) {
-  let mozapp = frame.getAttribute("mozapp");
-  if (mozapp) {
-    // Ignore app frames
-    return;
-  }
   let actor = this._actorByBrowser.get(frame);
   if (actor) {
     this._handleActorClose(actor, frame);
   }
 };
 
 exports.B2GTabList = B2GTabList;
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -171,17 +171,17 @@ var ErrorPage = {
 
   init: function errorPageInit() {
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
     Services.obs.addObserver(this, 'remote-browser-shown', false);
   },
 
   observe: function errorPageObserve(aSubject, aTopic, aData) {
     let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
-    // Ignore notifications that aren't from a BrowserOrApp
-    if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
+    // Ignore notifications that aren't from a Browser
+    if (!frameLoader.ownerIsMozBrowserFrame) {
       return;
     }
     this._listenError(frameLoader);
   }
 };
 
 ErrorPage.init();
--- a/b2g/components/Frames.jsm
+++ b/b2g/components/Frames.jsm
@@ -14,40 +14,32 @@ Cu.import('resource://gre/modules/System
 
 const listeners = [];
 
 const Observer = {
   // Save a map of (MessageManager => Frame) to be able to dispatch
   // the FrameDestroyed event with a frame reference.
   _frames: new Map(),
 
-  // Also save current number of iframes opened by app
-  _apps: new Map(),
-
   start: function () {
     Services.obs.addObserver(this, 'remote-browser-shown', false);
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
     Services.obs.addObserver(this, 'message-manager-close', false);
 
     SystemAppProxy.getFrames().forEach(frame => {
       let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
       this._frames.set(mm, frame);
-      let mozapp = frame.getAttribute('mozapp');
-      if (mozapp) {
-        this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1);
-      }
     });
   },
 
   stop: function () {
     Services.obs.removeObserver(this, 'remote-browser-shown');
     Services.obs.removeObserver(this, 'inprocess-browser-shown');
     Services.obs.removeObserver(this, 'message-manager-close');
     this._frames.clear();
-    this._apps.clear();
   },
 
   observe: function (subject, topic, data) {
     switch(topic) {
 
       // Listen for frame creation in OOP (device) as well as in parent process (b2g desktop)
       case 'remote-browser-shown':
       case 'inprocess-browser-shown':
@@ -65,54 +57,38 @@ const Observer = {
         this.onMessageManagerDestroyed(subject);
         break;
     }
   },
 
   onMessageManagerCreated: function (mm, frame) {
     this._frames.set(mm, frame);
 
-    let isFirstAppFrame = null;
-    let mozapp = frame.getAttribute('mozapp');
-    if (mozapp) {
-      let count = (this._apps.get(mozapp) || 0) + 1;
-      this._apps.set(mozapp, count);
-      isFirstAppFrame = (count === 1);
-    }
-
     listeners.forEach(function (listener) {
       try {
-        listener.onFrameCreated(frame, isFirstAppFrame);
+        listener.onFrameCreated(frame);
       } catch(e) {
         dump('Exception while calling Frames.jsm listener:' + e + '\n' +
              e.stack + '\n');
       }
     });
   },
 
   onMessageManagerDestroyed: function (mm) {
     let frame = this._frames.get(mm);
     if (!frame) {
       // We received an event for an unknown message manager
       return;
     }
 
     this._frames.delete(mm);
 
-    let isLastAppFrame = null;
-    let mozapp = frame.getAttribute('mozapp');
-    if (mozapp) {
-      let count = (this._apps.get(mozapp) || 0) - 1;
-      this._apps.set(mozapp, count);
-      isLastAppFrame = (count === 0);
-    }
-
     listeners.forEach(function (listener) {
       try {
-        listener.onFrameDestroyed(frame, isLastAppFrame);
+        listener.onFrameDestroyed(frame);
       } catch(e) {
         dump('Exception while calling Frames.jsm listener:' + e + '\n' +
              e.stack + '\n');
       }
     });
   }
 
 };
--- a/b2g/components/SafeMode.jsm
+++ b/b2g/components/SafeMode.jsm
@@ -71,17 +71,16 @@ this.SafeMode = {
     let document = SafeMode.window.document;
     SafeMode.window.screen.mozLockOrientation("portrait");
 
     let url = Services.io.newURI(shell.homeURL, null, null)
                          .resolve(kSafeModePage);
     debug("Registry is ready, loading " + url);
     let frame = document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
     frame.setAttribute("mozbrowser", "true");
-    frame.setAttribute("mozapp", shell.manifestURL);
     frame.setAttribute("id", "systemapp"); // To keep screen.js happy.
     let contentBrowser = document.body.appendChild(frame);
 
     return new Promise((aResolve, aReject) => {
       let content = contentBrowser.contentWindow;
 
       // Stripped down version of the system app bootstrap.
       function handleEvent(e) {
--- a/b2g/components/SimulatorScreen.js
+++ b/b2g/components/SimulatorScreen.js
@@ -20,20 +20,16 @@ function debug() {
 function fireOrientationEvent(window) {
   let e = new window.Event('mozorientationchange');
   window.screen.dispatchEvent(e);
 }
 
 function hookScreen(window) {
   let nodePrincipal = window.document.nodePrincipal;
   let origin = nodePrincipal.origin;
-  if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
-    // Only inject screen mock for apps
-    return;
-  }
 
   let screen = window.wrappedJSObject.screen;
 
   screen.mozLockOrientation = function (orientation) {
     debug('mozLockOrientation:', orientation, 'from', origin);
 
     // Normalize and do some checks against orientation input
     if (typeof(orientation) == 'string') {
deleted file mode 100644
--- a/b2g/components/UpdatePrompt.js
+++ /dev/null
@@ -1,783 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const VERBOSE = 1;
-var log =
-  VERBOSE ?
-  function log_dump(msg) { dump("UpdatePrompt: "+ msg +"\n"); } :
-  function log_noop(msg) { };
-
-const PREF_APPLY_PROMPT_TIMEOUT          = "b2g.update.apply-prompt-timeout";
-const PREF_APPLY_IDLE_TIMEOUT            = "b2g.update.apply-idle-timeout";
-const PREF_DOWNLOAD_WATCHDOG_TIMEOUT     = "b2g.update.download-watchdog-timeout";
-const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries";
-
-const NETWORK_ERROR_OFFLINE = 111;
-const HTTP_ERROR_OFFSET     = 1000;
-
-const STATE_DOWNLOADING = 'downloading';
-
-XPCOMUtils.defineLazyServiceGetter(Services, "aus",
-                                   "@mozilla.org/updates/update-service;1",
-                                   "nsIApplicationUpdateService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "um",
-                                   "@mozilla.org/updates/update-manager;1",
-                                   "nsIUpdateManager");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "idle",
-                                   "@mozilla.org/widget/idleservice;1",
-                                   "nsIIdleService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "settings",
-                                   "@mozilla.org/settingsService;1",
-                                   "nsISettingsService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'env',
-                                   '@mozilla.org/process/environment;1',
-                                   'nsIEnvironment');
-
-function useSettings() {
-  // When we're running in the real phone, then we can use settings.
-  // But when we're running as part of xpcshell, there is no settings database
-  // and trying to use settings in this scenario causes lots of weird
-  // assertions at shutdown time.
-  if (typeof useSettings.result === "undefined") {
-    useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR");
-  }
-  return useSettings.result;
-}
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
-                                  "resource://gre/modules/SystemAppProxy.jsm");
-
-function UpdateCheckListener(updatePrompt) {
-  this._updatePrompt = updatePrompt;
-}
-
-UpdateCheckListener.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener]),
-
-  _updatePrompt: null,
-
-  onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) {
-    if (Services.um.activeUpdate) {
-      // We're actively downloading an update, that's the update the user should
-      // see, even if a newer update is available.
-      this._updatePrompt.setUpdateStatus("active-update");
-      this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate);
-      return;
-    }
-
-    if (updateCount == 0) {
-      this._updatePrompt.setUpdateStatus("no-updates");
-
-      if (this._updatePrompt._systemUpdateListener) {
-        this._updatePrompt._systemUpdateListener.onError("no-updates");
-      }
-
-      return;
-    }
-
-    let update = Services.aus.selectUpdate(updates, updateCount);
-    if (!update) {
-      this._updatePrompt.setUpdateStatus("already-latest-version");
-
-      if (this._updatePrompt._systemUpdateListener) {
-        this._updatePrompt._systemUpdateListener.onError("already-latest-version");
-      }
-
-      return;
-    }
-
-    this._updatePrompt.setUpdateStatus("check-complete");
-    this._updatePrompt.showUpdateAvailable(update);
-  },
-
-  onError: function UCL_onError(request, update) {
-    // nsIUpdate uses a signed integer for errorCode while any platform errors
-    // require all 32 bits.
-    let errorCode = update.errorCode >>> 0;
-    let isNSError = (errorCode >>> 31) == 1;
-    let errorMsg = "check-error-";
-
-    if (errorCode == NETWORK_ERROR_OFFLINE) {
-      errorMsg = "retry-when-online";
-      this._updatePrompt.setUpdateStatus(errorMsg);
-    } else if (isNSError) {
-      errorMsg = "check-error-" + errorCode;
-      this._updatePrompt.setUpdateStatus(errorMsg);
-    } else if (errorCode > HTTP_ERROR_OFFSET) {
-      let httpErrorCode = errorCode - HTTP_ERROR_OFFSET;
-      errorMsg = "check-error-http-" + httpErrorCode;
-      this._updatePrompt.setUpdateStatus(errorMsg);
-    }
-
-    if (this._updatePrompt._systemUpdateListener) {
-      this._updatePrompt._systemUpdateListener.onError(errorMsg);
-    }
-
-    Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
-    Services.aus.onError(request, update);
-  }
-};
-
-function UpdatePrompt() {
-  this.wrappedJSObject = this;
-  this._updateCheckListener = new UpdateCheckListener(this);
-}
-
-UpdatePrompt.prototype = {
-  classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
-                                         Ci.nsIUpdateCheckListener,
-                                         Ci.nsIRequestObserver,
-                                         Ci.nsIProgressEventSink,
-                                         Ci.nsIObserver,
-                                         Ci.nsISystemUpdateProvider]),
-  _xpcom_factory: XPCOMUtils.generateSingletonFactory(UpdatePrompt),
-
-  _update: null,
-  _applyPromptTimer: null,
-  _waitingForIdle: false,
-  _updateCheckListner: null,
-  _systemUpdateListener: null,
-  _availableParameters: {
-    "deviceinfo.last_updated": null,
-    "gecko.updateStatus": null,
-    "app.update.channel": null,
-    "app.update.interval": null,
-    "app.update.url": null,
-  },
-  _pendingUpdateAvailablePackageInfo: null,
-  _isPendingUpdateReady: false,
-  _updateErrorQueue: [ ],
-  _receivedUpdatePromptReady: false,
-
-  // nsISystemUpdateProvider
-  checkForUpdate: function() {
-    this.forceUpdateCheck();
-  },
-
-  startDownload: function() {
-    this.downloadUpdate(this._update);
-  },
-
-  stopDownload: function() {
-    this.handleDownloadCancel();
-  },
-
-  applyUpdate: function() {
-    this.handleApplyPromptResult({result: "restart"});
-  },
-
-  setParameter: function(aName, aValue) {
-    if (!this._availableParameters.hasOwnProperty(aName)) {
-      return false;
-    }
-
-    this._availableParameters[aName] = aValue;
-
-    switch (aName) {
-      case "app.update.channel":
-      case "app.update.url":
-        Services.prefs.setCharPref(aName, aValue);
-        break;
-      case "app.update.interval":
-        Services.prefs.setIntPref(aName, parseInt(aValue, 10));
-        break;
-    }
-
-    return true;
-  },
-
-  getParameter: function(aName) {
-    if (!this._availableParameters.hasOwnProperty(aName)) {
-      return null;
-    }
-
-    return this._availableParameters[aName];
-  },
-
-  setListener: function(aListener) {
-    this._systemUpdateListener = aListener;
-
-    // If an update is available or ready, trigger the event right away at this point.
-    if (this._pendingUpdateAvailablePackageInfo) {
-      this._systemUpdateListener.onUpdateAvailable(this._pendingUpdateAvailablePackageInfo.type,
-                                             this._pendingUpdateAvailablePackageInfo.version,
-                                             this._pendingUpdateAvailablePackageInfo.description,
-                                             this._pendingUpdateAvailablePackageInfo.buildDate,
-                                             this._pendingUpdateAvailablePackageInfo.size);
-      // Set null when the listener is attached.
-      this._pendingUpdateAvailablePackageInfo = null;
-    }
-
-    if (this._isPendingUpdateReady) {
-      this._systemUpdateListener.onUpdateReady();
-      this._isPendingUpdateReady = false;
-    }
-  },
-
-  unsetListener: function(aListener) {
-    this._systemUpdateListener = null;
-  },
-
-  get applyPromptTimeout() {
-    return Services.prefs.getIntPref(PREF_APPLY_PROMPT_TIMEOUT);
-  },
-
-  get applyIdleTimeout() {
-    return Services.prefs.getIntPref(PREF_APPLY_IDLE_TIMEOUT);
-  },
-
-  handleContentStart: function UP_handleContentStart() {
-    SystemAppProxy.addEventListener("mozContentEvent", this);
-  },
-
-  // nsIUpdatePrompt
-
-  // FIXME/bug 737601: we should have users opt-in to downloading
-  // updates when on a billed pipe.  Initially, opt-in for 3g, but
-  // that doesn't cover all cases.
-  checkForUpdates: function UP_checkForUpdates() { },
-
-  showUpdateAvailable: function UP_showUpdateAvailable(aUpdate) {
-    let packageInfo = {};
-    packageInfo.version = aUpdate.displayVersion;
-    packageInfo.description = aUpdate.statusText;
-    packageInfo.buildDate = aUpdate.buildID;
-
-    let patch = aUpdate.selectedPatch;
-    if (!patch && aUpdate.patchCount > 0) {
-      // For now we just check the first patch to get size information if a
-      // patch hasn't been selected yet.
-      patch = aUpdate.getPatchAt(0);
-    }
-
-    if (patch) {
-      packageInfo.size = patch.size;
-      packageInfo.type = patch.type;
-    } else {
-      log("Warning: no patches available in update");
-    }
-
-    this._pendingUpdateAvailablePackageInfo = packageInfo;
-
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onUpdateAvailable(packageInfo.type,
-                                             packageInfo.version,
-                                             packageInfo.description,
-                                             packageInfo.buildDate,
-                                             packageInfo.size);
-      // Set null since the event is fired.
-      this._pendingUpdateAvailablePackageInfo = null;
-    }
-
-    if (!this.sendUpdateEvent("update-available", aUpdate)) {
-
-      log("Unable to prompt for available update, forcing download");
-      this.downloadUpdate(aUpdate);
-    }
-  },
-
-  showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) {
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onUpdateReady();
-    } else {
-      this._isPendingUpdateReady = true;
-    }
-
-    // The update has been downloaded and staged. We send the update-downloaded
-    // event right away. After the user has been idle for a while, we send the
-    // update-prompt-restart event, increasing the chances that we can apply the
-    // update quietly without user intervention.
-    this.sendUpdateEvent("update-downloaded", aUpdate);
-
-    if (Services.idle.idleTime >= this.applyIdleTimeout) {
-      this.showApplyPrompt(aUpdate);
-      return;
-    }
-
-    let applyIdleTimeoutSeconds = this.applyIdleTimeout / 1000;
-    // We haven't been idle long enough, so register an observer
-    log("Update is ready to apply, registering idle timeout of " +
-        applyIdleTimeoutSeconds + " seconds before prompting.");
-
-    this._update = aUpdate;
-    this.waitForIdle();
-  },
-
-  storeUpdateError: function UP_storeUpdateError(aUpdate) {
-    log("Storing update error for later use");
-    this._updateErrorQueue.push(aUpdate);
-  },
-
-  sendStoredUpdateError: function UP_sendStoredUpdateError() {
-    log("Sending stored update error");
-    this._updateErrorQueue.forEach(aUpdate => {
-      this.sendUpdateEvent("update-error", aUpdate);
-    });
-    this._updateErrorQueue = [ ];
-  },
-
-  showUpdateError: function UP_showUpdateError(aUpdate) {
-    log("Update error, state: " + aUpdate.state + ", errorCode: " +
-        aUpdate.errorCode);
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onError("update-error: " + aUpdate.errorCode + " " + aUpdate.statusText);
-    }
-
-    if (!this._receivedUpdatePromptReady) {
-      this.storeUpdateError(aUpdate);
-    } else {
-      this.sendUpdateEvent("update-error", aUpdate);
-    }
-
-    this.setUpdateStatus(aUpdate.statusText);
-  },
-
-  showUpdateHistory: function UP_showUpdateHistory(aParent) { },
-  showUpdateInstalled: function UP_showUpdateInstalled() {
-    this.setParameter("deviceinfo.last_updated", Date.now());
-
-    if (useSettings()) {
-      let lock = Services.settings.createLock();
-      lock.set("deviceinfo.last_updated", Date.now(), null, null);
-    }
-  },
-
-  // Custom functions
-
-  waitForIdle: function UP_waitForIdle() {
-    if (this._waitingForIdle) {
-      return;
-    }
-
-    this._waitingForIdle = true;
-    Services.idle.addIdleObserver(this, this.applyIdleTimeout / 1000);
-    Services.obs.addObserver(this, "quit-application", false);
-  },
-
-  setUpdateStatus: function UP_setUpdateStatus(aStatus) {
-     this.setParameter("gecko.updateStatus", aStatus);
-
-     if (useSettings()) {
-       log("Setting gecko.updateStatus: " + aStatus);
-
-       let lock = Services.settings.createLock();
-       lock.set("gecko.updateStatus", aStatus, null);
-     }
-  },
-
-  showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
-    // Notify update package is ready to apply
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onUpdateReady();
-    } else {
-      // Set the flag to true and fire the onUpdateReady event when the listener is attached.
-      this._isPendingUpdateReady = true;
-    }
-
-    if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
-      log("Unable to prompt, forcing restart");
-      this.restartProcess();
-      return;
-    }
-
-    if (AppConstants.MOZ_B2G_RIL) {
-      let window = Services.wm.getMostRecentWindow("navigator:browser");
-      let pinReq = window.navigator.mozIccManager.getCardLock("pin");
-      pinReq.onsuccess = function(e) {
-        if (e.target.result.enabled) {
-          // The SIM is pin locked. Don't use a fallback timer. This means that
-          // the user has to press Install to apply the update. If we use the
-          // timer, and the timer reboots the phone, then the phone will be
-          // unusable until the SIM is unlocked.
-          log("SIM is pin locked. Not starting fallback timer.");
-        } else {
-          // This means that no pin lock is enabled, so we go ahead and start
-          // the fallback timer.
-          this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
-        }
-      }.bind(this);
-      pinReq.onerror = function(e) {
-        this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
-      }.bind(this);
-    } else {
-      // Schedule a fallback timeout in case the UI is unable to respond or show
-      // a prompt for some reason.
-      this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
-    }
-  },
-
-  _copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
-                    "errorCode", "isOSUpdate", "platformVersion",
-                    "previousAppVersion", "state", "statusText"],
-
-  sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
-    let detail = {};
-    for (let property of this._copyProperties) {
-      detail[property] = aUpdate[property];
-    }
-
-    let patch = aUpdate.selectedPatch;
-    if (!patch && aUpdate.patchCount > 0) {
-      // For now we just check the first patch to get size information if a
-      // patch hasn't been selected yet.
-      patch = aUpdate.getPatchAt(0);
-    }
-
-    if (patch) {
-      detail.size = patch.size;
-      detail.updateType = patch.type;
-    } else {
-      log("Warning: no patches available in update");
-    }
-
-    this._update = aUpdate;
-    return this.sendChromeEvent(aType, detail);
-  },
-
-  sendChromeEvent: function UP_sendChromeEvent(aType, aDetail) {
-    let detail = aDetail || {};
-    detail.type = aType;
-
-    let sent = SystemAppProxy.dispatchEvent(detail);
-    if (!sent) {
-      log("Warning: Couldn't send update event " + aType +
-          ": no content browser. Will send again when content becomes available.");
-      return false;
-    }
-    return true;
-  },
-
-  handleAvailableResult: function UP_handleAvailableResult(aDetail) {
-    // If the user doesn't choose "download", the updater will implicitly call
-    // showUpdateAvailable again after a certain period of time
-    switch (aDetail.result) {
-      case "download":
-        this.downloadUpdate(this._update);
-        break;
-    }
-  },
-
-  handleApplyPromptResult: function UP_handleApplyPromptResult(aDetail) {
-    if (this._applyPromptTimer) {
-      this._applyPromptTimer.cancel();
-      this._applyPromptTimer = null;
-    }
-
-    switch (aDetail.result) {
-      // Battery not okay, do not wait for idle to re-prompt
-      case "low-battery":
-        break;
-      case "wait":
-        // Wait until the user is idle before prompting to apply the update
-        this.waitForIdle();
-        break;
-      case "restart":
-        this.finishUpdate();
-        this._update = null;
-        break;
-    }
-  },
-
-  downloadUpdate: function UP_downloadUpdate(aUpdate) {
-    if (!aUpdate) {
-      aUpdate = Services.um.activeUpdate;
-      if (!aUpdate) {
-        log("No active update found to download");
-        return;
-      }
-    }
-
-    let status = Services.aus.downloadUpdate(aUpdate, true);
-    if (status == STATE_DOWNLOADING) {
-      Services.aus.addDownloadListener(this);
-      return;
-    }
-
-    // If the update has already been downloaded and applied, then
-    // Services.aus.downloadUpdate will return immediately and not
-    // call showUpdateDownloaded, so we detect this.
-    if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
-      this.showUpdateDownloaded(aUpdate, true);
-      return;
-    }
-
-    log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
-    let errorCode = aUpdate.errorCode >>> 0;
-    if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) {
-      aUpdate.statusText = "file-too-big";
-    }
-    this.showUpdateError(aUpdate);
-  },
-
-  handleDownloadCancel: function UP_handleDownloadCancel() {
-    log("Pausing download");
-    Services.aus.pauseDownload();
-  },
-
-  finishUpdate: function UP_finishUpdate() {
-    if (!this._update.isOSUpdate) {
-      // Standard gecko+gaia updates will just need to restart the process
-      this.restartProcess();
-      return;
-    }
- 
-    try {
-      Services.aus.applyOsUpdate(this._update);
-    }
-    catch (e) {
-      this._update.errorCode = Cr.NS_ERROR_FAILURE;
-      this.showUpdateError(this._update);
-    }
-  },
-
-  restartProcess: function UP_restartProcess() {
-    log("Update downloaded, restarting to apply it");
-
-    let callbackAfterSet = function() {
-      if (AppConstants.platform !== "gonk") {
-        let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
-                         .getService(Ci.nsIAppStartup);
-        appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
-      } else {
-        // NB: on Gonk, we rely on the system process manager to restart us.
-        let pmService = Cc["@mozilla.org/power/powermanagerservice;1"]
-                        .getService(Ci.nsIPowerManagerService);
-        pmService.restart();
-      }
-    }
-
-    if (useSettings()) {
-      // Save current os version in deviceinfo.previous_os
-      let lock = Services.settings.createLock({
-        handle: callbackAfterSet,
-        handleAbort: function(error) {
-          log("Abort callback when trying to set previous_os: " + error);
-          callbackAfterSet();
-        }
-      });
-      lock.get("deviceinfo.os", {
-        handle: function(name, value) {
-          log("Set previous_os to: " + value);
-          lock.set("deviceinfo.previous_os", value, null, null);
-        }
-      });
-    }
-  },
-
-  forceUpdateCheck: function UP_forceUpdateCheck() {
-    log("Forcing update check");
-
-    let checker = Cc["@mozilla.org/updates/update-checker;1"]
-                    .createInstance(Ci.nsIUpdateChecker);
-    checker.checkForUpdates(this._updateCheckListener, true);
-  },
-
-  handleEvent: function UP_handleEvent(evt) {
-    if (evt.type !== "mozContentEvent") {
-      return;
-    }
-
-    let detail = evt.detail;
-    if (!detail) {
-      return;
-    }
-
-    switch (detail.type) {
-      case "force-update-check":
-        this.forceUpdateCheck();
-        break;
-      case "update-available-result":
-        this.handleAvailableResult(detail);
-        // If we started the apply prompt timer, this means that we're waiting
-        // for the user to press Later or Install Now. In this situation we
-        // don't want to clear this._update, becuase handleApplyPromptResult
-        // needs it.
-        if (this._applyPromptTimer == null && !this._waitingForIdle) {
-          this._update = null;
-        }
-        break;
-      case "update-download-cancel":
-        this.handleDownloadCancel();
-        break;
-      case "update-prompt-apply-result":
-        this.handleApplyPromptResult(detail);
-        break;
-      case "update-prompt-ready":
-        this._receivedUpdatePromptReady = true;
-        this.sendStoredUpdateError();
-        break;
-    }
-  },
-
-  // nsIObserver
-
-  observe: function UP_observe(aSubject, aTopic, aData) {
-    switch (aTopic) {
-      case "idle":
-        this._waitingForIdle = false;
-        this.showApplyPrompt(this._update);
-        // Fall through
-      case "quit-application":
-        Services.idle.removeIdleObserver(this, this.applyIdleTimeout / 1000);
-        Services.obs.removeObserver(this, "quit-application");
-        break;
-    }
-  },
-
-  // nsITimerCallback
-
-  notify: function UP_notify(aTimer) {
-    if (aTimer == this._applyPromptTimer) {
-      log("Timed out waiting for result, restarting");
-      this._applyPromptTimer = null;
-      this.finishUpdate();
-      this._update = null;
-      return;
-    }
-    if (aTimer == this._watchdogTimer) {
-      log("Download watchdog fired");
-      this._watchdogTimer = null;
-      this._autoRestartDownload = true;
-      Services.aus.pauseDownload();
-      return;
-    }
-  },
-
-  createTimer: function UP_createTimer(aTimeoutMs) {
-    let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT);
-    return timer;
-  },
-
-  // nsIRequestObserver
-
-  _startedSent: false,
-
-  _watchdogTimer: null,
-
-  _autoRestartDownload: false,
-  _autoRestartCount: 0,
-
-  startWatchdogTimer: function UP_startWatchdogTimer() {
-    let watchdogTimeout = 120000;  // 120 seconds
-    try {
-      watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
-    } catch (e) {
-      // This means that the preference doesn't exist. watchdogTimeout will
-      // retain its default assigned above.
-    }
-    if (watchdogTimeout <= 0) {
-      // 0 implies don't bother using the watchdog timer at all.
-      this._watchdogTimer = null;
-      return;
-    }
-    if (this._watchdogTimer) {
-      this._watchdogTimer.cancel();
-    } else {
-      this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    }
-    this._watchdogTimer.initWithCallback(this, watchdogTimeout,
-                                         Ci.nsITimer.TYPE_ONE_SHOT);
-  },
-
-  stopWatchdogTimer: function UP_stopWatchdogTimer() {
-    if (this._watchdogTimer) {
-      this._watchdogTimer.cancel();
-      this._watchdogTimer = null;
-    }
-  },
-
-  touchWatchdogTimer: function UP_touchWatchdogTimer() {
-    this.startWatchdogTimer();
-  },
-
-  onStartRequest: function UP_onStartRequest(aRequest, aContext) {
-    // Wait until onProgress to send the update-download-started event, in case
-    // this request turns out to fail for some reason
-    this._startedSent = false;
-    this.startWatchdogTimer();
-  },
-
-  onStopRequest: function UP_onStopRequest(aRequest, aContext, aStatusCode) {
-    this.stopWatchdogTimer();
-    Services.aus.removeDownloadListener(this);
-    let paused = !Components.isSuccessCode(aStatusCode);
-    if (!paused) {
-      // The download was successful, no need to restart
-      this._autoRestartDownload = false;
-    }
-    if (this._autoRestartDownload) {
-      this._autoRestartDownload = false;
-      let watchdogMaxRetries = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES);
-      this._autoRestartCount++;
-      if (this._autoRestartCount > watchdogMaxRetries) {
-        log("Download - retry count exceeded - error");
-        // We exceeded the max retries. Treat the download like an error,
-        // which will give the user a chance to restart manually later.
-        this._autoRestartCount = 0;
-        if (Services.um.activeUpdate) {
-          this.showUpdateError(Services.um.activeUpdate);
-        }
-        return;
-      }
-      log("Download - restarting download - attempt " + this._autoRestartCount);
-      this.downloadUpdate(null);
-      return;
-    }
-    this._autoRestartCount = 0;
-    this.sendChromeEvent("update-download-stopped", {
-      paused: paused
-    });
-  },
-
-  // nsIProgressEventSink
-
-  onProgress: function UP_onProgress(aRequest, aContext, aProgress,
-                                     aProgressMax) {
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onProgress(aProgress, aProgressMax);
-    }
-
-    if (aProgress == aProgressMax) {
-      // The update.mar validation done by onStopRequest may take
-      // a while before the onStopRequest callback is made, so stop
-      // the timer now.
-      this.stopWatchdogTimer();
-    } else {
-      this.touchWatchdogTimer();
-    }
-    if (!this._startedSent) {
-      this.sendChromeEvent("update-download-started", {
-        total: aProgressMax
-      });
-      this._startedSent = true;
-    }
-
-    this.sendChromeEvent("update-download-progress", {
-      progress: aProgress,
-      total: aProgressMax
-    });
-  },
-
-  onStatus: function UP_onStatus(aRequest, aUpdate, aStatus, aStatusArg) { }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]);
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -4,17 +4,16 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['test']
 
 EXTRA_COMPONENTS += [
     'AlertsService.js',
     'B2GAboutRedirector.js',
-    'B2GAppMigrator.js',
     'B2GPresentationDevicePrompt.js',
     'BootstrapCommandLine.js',
     'ContentPermissionPrompt.js',
     'FilePicker.js',
     'FxAccountsUIGlue.js',
     'HelperAppDialog.js',
     'MailtoProtocolHandler.js',
     'OMAContentHandler.js',
@@ -37,21 +36,16 @@ EXTRA_PP_COMPONENTS += [
 ]
 
 if CONFIG['MOZ_B2G']:
     EXTRA_COMPONENTS += [
         'DirectoryProvider.js',
         'RecoveryService.js',
     ]
 
-if CONFIG['MOZ_UPDATER']:
-    EXTRA_COMPONENTS += [
-        'UpdatePrompt.js',
-    ]
-
 EXTRA_JS_MODULES += [
     'AboutServiceWorkers.jsm',
     'ActivityChannel.jsm',
     'AlertsHelper.jsm',
     'Bootstraper.jsm',
     'ContentRequestHelper.jsm',
     'DebuggerActors.js',
     'ErrorPage.jsm',
--- a/b2g/components/test/mochitest/SandboxPromptTest.html
+++ b/b2g/components/test/mochitest/SandboxPromptTest.html
@@ -1,35 +1,14 @@
 <html>
 <body>
 <script>
 
 var actions = [
   {
-    permissions: ["video-capture"],
-    action: function() {
-      // invoke video-capture permission prompt
-      navigator.mozGetUserMedia({video: true}, function () {}, function () {});
-    }
-  },
-  {
-    permissions: ["audio-capture", "video-capture"],
-    action: function() {
-      // invoke audio-capture + video-capture permission prompt
-      navigator.mozGetUserMedia({audio: true, video: true}, function () {}, function () {});
-    }
-  },
-  {
-    permissions: ["audio-capture"],
-    action: function() {
-      // invoke audio-capture permission prompt
-      navigator.mozGetUserMedia({audio: true}, function () {}, function () {});
-    }
-  },
-  {
     permissions: ["geolocation"],
     action: function() {
       // invoke geolocation permission prompt
       navigator.geolocation.getCurrentPosition(function (pos) {});
     }
   },
   {
     permissions: ["desktop-notification"],
--- a/b2g/components/test/mochitest/mochitest.ini
+++ b/b2g/components/test/mochitest/mochitest.ini
@@ -5,20 +5,16 @@ support-files =
   filepicker_path_handler_chrome.js
   screenshot_helper.js
   systemapp_helper.js
   presentation_prompt_handler_chrome.js
   presentation_ui_glue_handler_chrome.js
 
 [test_filepicker_path.html]
 skip-if = toolkit != "gonk"
-[test_permission_deny.html]
-skip-if = toolkit != "gonk"
-[test_permission_gum_remember.html]
-skip-if = true # Bug 1019572 - frequent timeouts
 [test_sandbox_permission.html]
 skip-if = toolkit != "gonk"
 [test_screenshot.html]
 skip-if = toolkit != "gonk"
 [test_systemapp.html]
 skip-if = toolkit != "gonk"
 [test_presentation_device_prompt.html]
 skip-if = toolkit != "gonk"
deleted file mode 100644
--- a/b2g/components/test/mochitest/test_permission_deny.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=981113
--->
-<head>
-  <meta charset="utf-8">
-  <title>Permission Deny Test</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=981113">Test Permission Deny</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
-
-var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js');
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-var gTests = [
-  {
-    'video': true,
-  },
-  {
-    'audio': true,
-    'video': true,
-  },
-  {
-    'audio': true,
-  },
-];
-
-function runNext() {
-  if (gTests.length > 0) {
-    // Put the requested permission in query string
-    let requestedType = gTests.shift();
-    info('getUserMedia for ' + JSON.stringify(requestedType));
-    navigator.mozGetUserMedia(requestedType, function success() {
-      ok(false, 'unexpected success, permission request should be denied');
-      runNext();
-    }, function failure(err) {
-      is(err.name, 'SecurityError', 'expected permission denied');
-      runNext();
-    });
-  } else {
-    info('test finished, teardown');
-    gScript.sendAsyncMessage('teardown', '');
-    gScript.destroy();
-    SimpleTest.finish();
-  }
-}
-
-gScript.addMessageListener('permission-request', function(detail) {
-  let response = {
-    id: detail.id,
-    type: 'permission-deny',
-    remember: false,
-  };
-  gScript.sendAsyncMessage('permission-response', response);
-});
-
-// Need to change camera permission from ALLOW to PROMPT, otherwise
-// MediaManager will automatically allow video-only gUM request.
-SpecialPowers.pushPermissions([
-    {type: 'video-capture', allow: PROMPT_ACTION, context: document},
-    {type: 'audio-capture', allow: PROMPT_ACTION, context: document},
-    {type: 'camera', allow: PROMPT_ACTION, context: document},
-  ], function() {
-    SpecialPowers.pushPrefEnv({
-        'set': [
-          ['media.navigator.permission.disabled', false],
-        ]
-      }, runNext);
-  }
-);
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/b2g/components/test/mochitest/test_permission_gum_remember.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=978660
--->
-<head>
-  <meta charset="utf-8">
-  <title>gUM Remember Permission Test</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978660">Test remembering gUM Permission</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
-
-var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js');
-var gScript = SpecialPowers.loadChromeScript(gUrl);
-gScript.addMessageListener('permission-request', function(detail) {
-  ok(false, 'unexpected mozChromeEvent for permission prompt');
-  let response = {
-    id: detail.id,
-    type: 'permission-deny',
-    remember: false,
-  };
-  gScript.sendAsyncMessage('permission-response', response);
-});
-
-var gTests = [
-  {
-    'audio': true,
-    'video': {facingMode: 'environment', required: ['facingMode']},
-  },
-  {
-    'video': {facingMode: 'environment', required: ['facingMode']},
-  },
-  {
-    'audio': true,
-  },
-];
-
-function testGranted() {
-  info('test remember permission granted');
-  return new Promise(function(resolve, reject) {
-    let steps = [].concat(gTests);
-    function nextStep() {
-      if (steps.length > 0) {
-        let requestedType = steps.shift();
-        info('getUserMedia for ' + JSON.stringify(requestedType));
-        navigator.mozGetUserMedia(requestedType, function success(stream) {
-          ok(true, 'expected gUM success');
-          stream.stop();
-          nextStep();
-        }, function failure(err) {
-          ok(false, 'unexpected gUM fail: ' + err);
-          nextStep();
-        });
-      } else {
-        resolve();
-      }
-    }
-
-    SpecialPowers.pushPermissions([
-      {type: 'video-capture', allow: true, context: document},
-      {type: 'audio-capture', allow: true, context: document},
-    ], nextStep);
-  });
-}
-
-function testDenied() {
-  info('test remember permission denied');
-  return new Promise(function(resolve, reject) {
-    let steps = [].concat(gTests);
-    function nextStep() {
-      if (steps.length > 0) {
-        let requestedType = steps.shift();
-        info('getUserMedia for ' + JSON.stringify(requestedType));
-        navigator.mozGetUserMedia(requestedType, function success(stream) {
-          ok(false, 'unexpected gUM success');
-          stream.stop();
-          nextStep();
-        }, function failure(err) {
-          ok(true, 'expected gUM fail: ' + err);
-          nextStep();
-        });
-      } else {
-        resolve();
-      }
-    }
-
-    SpecialPowers.pushPermissions([
-      {type: 'video-capture', allow: false, context: document},
-      {type: 'audio-capture', allow: false, context: document},
-    ], nextStep);
-  });
-}
-
-function testPartialDeniedAudio() {
-  info('test remember permission partial denied: audio');
-  return new Promise(function(resolve, reject) {
-    info('getUserMedia for video and audio');
-    function nextStep() {
-      navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']},
-                                 audio: true}, function success(stream) {
-        ok(false, 'unexpected gUM success');
-        stream.stop();
-        resolve();
-      }, function failure(err) {
-        ok(true, 'expected gUM fail: ' + err);
-        resolve();
-      });
-    }
-
-    SpecialPowers.pushPermissions([
-      {type: 'video-capture', allow: true, context: document},
-      {type: 'audio-capture', allow: false, context: document},
-    ], nextStep);
-  });
-}
-
-function testPartialDeniedVideo() {
-  info('test remember permission partial denied: video');
-  return new Promise(function(resolve, reject) {
-    info('getUserMedia for video and audio');
-    function nextStep() {
-      navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']},
-                                 audio: true}, function success(stream) {
-        ok(false, 'unexpected gUM success');
-        stream.stop();
-        resolve();
-      }, function failure(err) {
-        ok(true, 'expected gUM fail: ' + err);
-        resolve();
-      });
-    }
-
-    SpecialPowers.pushPermissions([
-      {type: 'video-capture', allow: false, context: document},
-      {type: 'audio-capture', allow: true, context: document},
-    ], nextStep);
-  });
-}
-
-function runTests() {
-  testGranted()
-  .then(testDenied)
-  .then(testPartialDeniedAudio)
-  .then(testPartialDeniedVideo)
-  .then(function() {
-    info('test finished, teardown');
-    gScript.sendAsyncMessage('teardown', '');
-    gScript.destroy();
-    SimpleTest.finish();
-  });
-}
-
-SpecialPowers.pushPrefEnv({
-  'set': [
-    ['media.navigator.permission.disabled', false],
-  ]
-}, runTests);
-</script>
-</pre>
-</body>
-</html>
--- a/b2g/components/test/mochitest/test_sandbox_permission.html
+++ b/b2g/components/test/mochitest/test_sandbox_permission.html
@@ -17,26 +17,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 const APP_URL = "SandboxPromptTest.html";
 
 var iframe;
 var gUrl = SimpleTest.getTestFileURL("permission_handler_chrome.js");
 var gScript = SpecialPowers.loadChromeScript(gUrl);
 var gResult = [
   {
-    "video-capture": ["back"],
-  },
-  {
-    "audio-capture": [""],
-    "video-capture": ["back"],
-  },
-  {
-    "audio-capture": [""],
-  },
-  {
     "geolocation": [],
   },
   {
     "desktop-notification": [],
   }
 ];
 
 function runNext() {
@@ -81,20 +71,16 @@ gScript.addMessageListener("permission-r
   }
   runNext();
 });
 
 // Add permissions to this app. We use ALLOW_ACTION here. The ContentPermissionPrompt
 // should prompt for permission, not allow it without prompt.
 SpecialPowers.pushPrefEnv({"set": [["media.navigator.permission.disabled", false]]},
   function() {
-    SpecialPowers.addPermission('video-capture',
-      SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
-    SpecialPowers.addPermission('audio-capture',
-      SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
     SpecialPowers.addPermission('geolocation',
       SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
     SpecialPowers.addPermission('desktop-notification',
       SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document);
     loadBrowser();
   });
 
 SimpleTest.waitForExplicitFinish();
--- a/b2g/components/test/unit/head_logshake_gonk.js
+++ b/b2g/components/test/unit/head_logshake_gonk.js
@@ -36,17 +36,16 @@ function setup_fs() {
   OS.File.makeDir("/data/local/tmp/sdcard/", {from: "/data"}).then(function() {
     setup_sdcard();
   });
 }
 
 function setup_sdcard() {
   let volName = "sdcard";
   let mountPoint = "/data/local/tmp/sdcard";
-  volumeService.createFakeVolume(volName, mountPoint);
 
   let vol = volumeService.getVolumeByName(volName);
   ok(vol, "volume shouldn't be null");
   equal(volName, vol.name, "name");
   equal(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state");
 
   ensure_sdcard();
 }
--- a/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
+++ b/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
@@ -1,48 +1,48 @@
 [
 {
-"size" : 102421980,
-"digest" : "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
-"version" : "gcc 4.9.3",
-"unpack" : true,
-"filename" : "gcc.tar.xz",
-"algorithm" : "sha512"
+"size": 102421980,
+"digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
+"version": "gcc 4.9.3",
+"unpack": true,
+"filename": "gcc.tar.xz",
+"algorithm": "sha512"
 },
 {
-"unpack" : true,
-"algorithm" : "sha512",
-"filename" : "sixgill.tar.xz",
-"hg_id" : "8cb9c3fb039a+ tip",
-"digest" : "36dc644e24c0aa824975ad8f5c15714445d5cb064d823000c3cb637e885199414d7df551e6b99233f0656dcf5760918192ef04113c486af37f3c489bb93ad029",
-"size" : 2631908
+"unpack": true,
+"algorithm": "sha512",
+"filename": "sixgill.tar.xz",
+"hg_id": "8cb9c3fb039a+ tip",
+"digest": "36dc644e24c0aa824975ad8f5c15714445d5cb064d823000c3cb637e885199414d7df551e6b99233f0656dcf5760918192ef04113c486af37f3c489bb93ad029",
+"size": 2631908
 },
 {
-"algorithm" : "sha512",
-"filename" : "gtk3.tar.xz",
-"setup" : "setup.sh",
-"unpack" : true,
-"digest" : "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
-"size" : 12072532
+"algorithm": "sha512",
+"filename": "gtk3.tar.xz",
+"setup": "setup.sh",
+"unpack": true,
+"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
+"size": 12072532
 },
 {
-"version": "rustc 1.13.0 (2c6933acc 2016-11-07) repack",
-"size": 68921028,
-"digest": "9a9ceccc02d4be445ffa64617683419a4f47990b1f2689980ac8db13d6369435ef4af1a3714d77377fb7b3b0ec213856ab7144ff22cbe0881d49aed44d82c0fc",
+"version": "rustc 1.14.0-beta.2 (e627a2e6e 2016-11-16) repack",
+"size": 96275316,
+"digest": "26c11e34df81f5d7ffafc3492df9c6821f644a2e2eda5cfbbcdb1ac23e4ee196007b417c862c60a97bbf66e4be9c801400990938cd3aefec19b1cf9eaf1a9b54",
 "algorithm": "sha512",
 "filename": "rustc.tar.xz",
 "unpack": true
 },
 {
-"algorithm" : "sha512",
-"filename" : "sccache.tar.bz2",
-"unpack" : true,
-"digest" : "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
-"size" : 167175
+"algorithm": "sha512",
+"filename": "sccache.tar.bz2",
+"unpack": true,
+"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
+"size": 167175
 },
 {
-"filename" : "moz-tt.tar.bz2",
-"algorithm" : "sha512",
-"unpack" : true,
-"digest" : "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
-"size" : 31078810
+"filename": "moz-tt.tar.bz2",
+"algorithm": "sha512",
+"unpack": true,
+"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
+"size": 31078810
 }
 ]
--- a/b2g/dev/config/tooltool-manifests/linux64/releng.manifest
+++ b/b2g/dev/config/tooltool-manifests/linux64/releng.manifest
@@ -11,32 +11,24 @@
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
 "filename": "gtk3.tar.xz",
 "setup": "setup.sh",
 "unpack": true
 },
 {
-"version": "rustc 1.13.0 (2c6933acc 2016-11-07) repack",
-"size": 68921028,
-"digest": "9a9ceccc02d4be445ffa64617683419a4f47990b1f2689980ac8db13d6369435ef4af1a3714d77377fb7b3b0ec213856ab7144ff22cbe0881d49aed44d82c0fc",
+"version": "rustc 1.14.0-beta.2 (e627a2e6e 2016-11-16) repack",
+"size": 96275316,
+"digest": "26c11e34df81f5d7ffafc3492df9c6821f644a2e2eda5cfbbcdb1ac23e4ee196007b417c862c60a97bbf66e4be9c801400990938cd3aefec19b1cf9eaf1a9b54",
 "algorithm": "sha512",
 "filename": "rustc.tar.xz",
 "unpack": true
 },
 {
-"version": "cargo 0.13.0-nightly (eca9e15 2016-11-01) repack",
-"size": 3027932,
-"digest": "a5c99eeb12b3b9b49632c259c762e34ec13cf72dadf90a0608b8ab1dc66b36cb114c5b45f71d326e12d31d9e88a41b029e6a728ca64cef392c0a8d211c2fe191",
-"algorithm": "sha512",
-"filename": "cargo.tar.xz",
-"unpack": true
-},
-{
 "size": 167175,
 "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
 "algorithm": "sha512",
 "filename": "sccache.tar.bz2",
 "unpack": true
 },
 {
 "size": 31078810,
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -143,17 +143,16 @@
 @RESPATH@/components/content_html.xpt
 @RESPATH@/components/content_xslt.xpt
 @RESPATH@/components/cookie.xpt
 @RESPATH@/components/directory.xpt
 @RESPATH@/components/diskspacewatcher.xpt
 @RESPATH@/components/docshell.xpt
 @RESPATH@/components/dom.xpt
 @RESPATH@/components/dom_activities.xpt
-@RESPATH@/components/dom_apps.xpt
 @RESPATH@/components/dom_audiochannel.xpt
 @RESPATH@/components/dom_base.xpt
 @RESPATH@/components/dom_system.xpt
 @RESPATH@/components/dom_workers.xpt
 #ifdef MOZ_WIDGET_GONK
 @RESPATH@/components/dom_wifi.xpt
 @RESPATH@/components/dom_system_gonk.xpt
 #endif
@@ -173,17 +172,16 @@
 @RESPATH@/components/dom_json.xpt
 @RESPATH@/components/dom_messages.xpt
 @RESPATH@/components/dom_power.xpt
 @RESPATH@/components/dom_push.xpt
 @RESPATH@/components/dom_quota.xpt
 @RESPATH@/components/dom_range.xpt
 @RESPATH@/components/dom_security.xpt
 @RESPATH@/components/dom_settings.xpt
-@RESPATH@/components/dom_permissionsettings.xpt
 @RESPATH@/components/dom_sidebar.xpt
 @RESPATH@/components/dom_cellbroadcast.xpt
 @RESPATH@/components/dom_icc.xpt
 @RESPATH@/components/dom_mobilemessage.xpt
 @RESPATH@/components/dom_storage.xpt
 @RESPATH@/components/dom_stylesheets.xpt
 @RESPATH@/components/dom_threads.xpt
 @RESPATH@/components/dom_traversal.xpt
@@ -326,26 +324,20 @@
 @RESPATH@/components/xultmpl.xpt
 @RESPATH@/components/zipwriter.xpt
 
 ; JavaScript components
 @RESPATH@/components/ConsoleAPI.manifest
 @RESPATH@/components/ConsoleAPIStorage.js
 @RESPATH@/components/BrowserElementParent.manifest
 @RESPATH@/components/BrowserElementParent.js
-@RESPATH@/components/BrowserElementProxy.manifest
-@RESPATH@/components/BrowserElementProxy.js
 @RESPATH@/components/PhoneNumberService.js
 @RESPATH@/components/PhoneNumberService.manifest
 @RESPATH@/components/NotificationStorage.js
 @RESPATH@/components/NotificationStorage.manifest
-@RESPATH@/components/PermissionSettings.js
-@RESPATH@/components/PermissionSettings.manifest
-@RESPATH@/components/PermissionPromptService.js
-@RESPATH@/components/PermissionPromptService.manifest
 @RESPATH@/components/FeedProcessor.manifest
 @RESPATH@/components/FeedProcessor.js
 @RESPATH@/components/BrowserFeeds.manifest
 @RESPATH@/components/FeedConverter.js
 @RESPATH@/components/FeedWriter.js
 @RESPATH@/components/WebContentConverter.js
 @RESPATH@/components/BrowserComponents.manifest
 @RESPATH@/components/nsBrowserContentHandler.js
@@ -394,34 +386,30 @@
 @RESPATH@/components/GPAccessRulesManager.js
 @RESPATH@/components/GPAccessRulesManager.manifest
 @RESPATH@/components/SecureElement.js
 @RESPATH@/components/SecureElement.manifest
 @RESPATH@/components/UiccConnector.js
 @RESPATH@/components/UiccConnector.manifest
 #endif
 
-; WiFi, NetworkManager, NetworkStats
+; WiFi, NetworkManager
 #ifdef MOZ_WIDGET_GONK
 @RESPATH@/components/DOMWifiManager.js
 @RESPATH@/components/DOMWifiManager.manifest
 @RESPATH@/components/DOMWifiP2pManager.js
 @RESPATH@/components/DOMWifiP2pManager.manifest
 @RESPATH@/components/EthernetManager.js
 @RESPATH@/components/EthernetManager.manifest
 @RESPATH@/components/NetworkInterfaceListService.js
 @RESPATH@/components/NetworkInterfaceListService.manifest
 @RESPATH@/components/NetworkManager.js
 @RESPATH@/components/NetworkManager.manifest
 @RESPATH@/components/NetworkService.js
 @RESPATH@/components/NetworkService.manifest
-@RESPATH@/components/NetworkStatsManager.js
-@RESPATH@/components/NetworkStatsManager.manifest
-@RESPATH@/components/NetworkStatsServiceProxy.js
-@RESPATH@/components/NetworkStatsServiceProxy.manifest
 @RESPATH@/components/TetheringService.js
 @RESPATH@/components/TetheringService.manifest
 @RESPATH@/components/WifiWorker.js
 @RESPATH@/components/WifiWorker.manifest
 #endif // MOZ_WIDGET_GONK
 
 ; Tethering
 #ifdef MOZ_WIDGET_GONK
@@ -535,18 +523,16 @@
 @RESPATH@/components/servicesComponents.manifest
 @RESPATH@/components/cryptoComponents.manifest
 @RESPATH@/components/CaptivePortalDetectComponents.manifest
 @RESPATH@/components/captivedetect.js
 @RESPATH@/components/TelemetryStartup.js
 @RESPATH@/components/TelemetryStartup.manifest
 @RESPATH@/components/XULStore.js
 @RESPATH@/components/XULStore.manifest
-@RESPATH@/components/AppsService.js
-@RESPATH@/components/AppsService.manifest
 @RESPATH@/components/Push.js
 @RESPATH@/components/Push.manifest
 @RESPATH@/components/PushComponents.js
 
 @RESPATH@/components/nsDOMIdentity.js
 @RESPATH@/components/nsIDService.js
 @RESPATH@/components/Identity.manifest
 
@@ -779,37 +765,33 @@ bin/libfreebl_32int64_3.so
 @RESPATH@/chrome/icons/
 @RESPATH@/chrome/chrome@JAREXT@
 @RESPATH@/chrome/chrome.manifest
 @RESPATH@/components/B2GComponents.manifest
 @BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@
 #if defined(ENABLE_MARIONETTE) || !defined(MOZ_WIDGET_GONK)
 @RESPATH@/chrome/marionette@JAREXT@
 @RESPATH@/chrome/marionette.manifest
-@RESPATH@/components/MarionetteComponents.manifest
-@RESPATH@/components/marionettecomponent.js
+@RESPATH@/components/marionette.manifest
+@RESPATH@/components/marionette.js
 #endif
 @RESPATH@/components/AlertsService.js
 @RESPATH@/components/ContentPermissionPrompt.js
-#ifdef MOZ_UPDATER
-@RESPATH@/components/UpdatePrompt.js
-#endif
 @RESPATH@/components/DirectoryProvider.js
 @RESPATH@/components/ProcessGlobal.js
 @RESPATH@/components/OMAContentHandler.js
 @RESPATH@/components/RecoveryService.js
 @RESPATH@/components/MailtoProtocolHandler.js
 @RESPATH@/components/SmsProtocolHandler.js
 @RESPATH@/components/TelProtocolHandler.js
 @RESPATH@/components/B2GAboutRedirector.js
 @RESPATH@/components/FilePicker.js
 @RESPATH@/components/HelperAppDialog.js
 @RESPATH@/components/DownloadsUI.js
 @RESPATH@/components/SystemMessageGlue.js
-@RESPATH@/components/B2GAppMigrator.js
 @RESPATH@/components/B2GPresentationDevicePrompt.js
 @RESPATH@/components/PresentationRequestUIGlue.js
 
 #ifndef MOZ_WIDGET_GONK
 @RESPATH@/components/SimulatorScreen.js
 #endif
 
 @RESPATH@/components/FxAccountsUIGlue.js
--- a/b2g/simulator/custom-prefs.js
+++ b/b2g/simulator/custom-prefs.js
@@ -1,8 +1,7 @@
 user_pref("devtools.debugger.prompt-connection", false);
 user_pref("devtools.debugger.forbid-certified-apps", false);
-user_pref("devtools.apps.forbidden-permissions", "");
 user_pref("b2g.software-buttons", true);
 
 // Required for Mulet in order to run the debugger server from the command line
 user_pref("devtools.debugger.remote-enabled", true);
 user_pref("devtools.chrome.enabled", true);
--- a/browser/.eslintrc.js
+++ b/browser/.eslintrc.js
@@ -5,11 +5,12 @@ module.exports = {
     "../toolkit/.eslintrc.js"
   ],
 
   "rules": {
     "no-unused-vars": ["error", {
       "vars": "local",
       "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
       "args": "none",
-    }]
+    }],
+    "no-shadow": "error"
   }
 };
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -18,16 +18,25 @@ endif
 endif
 
 # This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
 # shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/config.mk
 
+# If we are trying to show an error dialog about the lack of SSE2 support,
+# make sure that code itself doesn't use SSE2.
+ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
+CXXFLAGS := $(filter-out -march=% -msse -msse2 -mfpmath=sse,$(CXXFLAGS))
+CXX := $(filter-out -march=% -msse -msse2 -mfpmath=sse,$(CXX))
+CXXFLAGS += -mno-sse -mno-sse2 -mfpmath=387
+CXX += -march=pentiumpro
+endif
+
 ifeq ($(OS_ARCH),WINNT)
 # Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
 # (this dependency should really be just for firefox.exe, not other targets)
 # Note the manifest file exists in the tree, so we use the explicit filename
 # here.
 EXTRA_DEPS += firefox.exe.manifest
 endif
 
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,2000 +1,2000 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<blocklist lastupdate="1479243909840" xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist lastupdate="1480338419582" xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
-    <emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}">
+    <emItem blockID="i545" id="superlrcs@svenyor.net">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i167" id="{b64982b1-d112-42b5-b1e4-d3867c4533f8}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i306" id="{ADFA33FD-16F5-4355-8504-DF4D664CFE10}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i515" id="/^({bf9194c2-b86d-4ebc-9b53-1c08b6ff779e}|{61a83e16-7198-49c6-8874-3e4e8faeb4f3}|{f0af464e-5167-45cf-9cf0-66b396d1918c}|{5d9968c3-101c-4944-ba71-72d77393322d}|{01e86e69-a2f8-48a0-b068-83869bdba3d0})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}">
+    <emItem blockID="i354" id="{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i529" id="/^(torntv@torntv\.com|trtv3@trtv\.com|torntv2@torntv\.com|e2fd07a6-e282-4f2e-8965-85565fcb6384@b69158e6-3c3b-476c-9d98-ae5838c5b707\.com)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i808" id="{c96d1ae6-c4cf-4984-b110-f5f561b33b5a}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i304" id="{f0e59437-6148-4a98-b0a6-60d557ef57f4}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i479" id="mbrsepone@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i314" id="crossriderapp8812@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i698" id="{6b2a75c8-6e2e-4267-b955-43e25b54e575}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i1231" id="youtube@downloader.yt">
+    <emItem blockID="i59" id="ghostviewer@youtube2.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i790" id="JMLv@njMaHh.org">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1263" id="axtara__web@axtara.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="1.1.1" severity="3"/>
-    </emItem>
-    <emItem blockID="i922" id="{34712C68-7391-4c47-94F3-8F88D49AD632}">
+    <emItem blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
+      <prefs/>
+      <versionRange minVersion="2.0.3" maxVersion="2.0.3"/>
+      <versionRange minVersion="4.2" maxVersion="4.2" severity="3"/>
+    </emItem>
+    <emItem blockID="i800" id="{424b0d11-e7fe-4a04-b7df-8f2c77f58aaf}">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+        <pref>browser.search.defaultenginename</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i566" id="{77BEC163-D389-42c1-91A4-C758846296A5}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i434" id="afurladvisor@anchorfree.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i66" id="youtubeer@youtuber.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i55" id="youtube@youtube7.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i82" id="{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i836" id="hansin@topvest.id">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i926" id="{B1FC07E1-E05B-4567-8891-E63FBE545BA8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i874" id="/^toolbar[0-9]*@findwide\.com$/">
+    <emItem blockID="i83" id="flash@adobee.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i507" id="4zffxtbr-bs@VideoDownloadConverter_4z.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="5.75.3.25126" severity="1"/>
+    </emItem>
+    <emItem blockID="i784" id="{41e5ef7a-171d-4ab5-8351-951c65a29908}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i882" id="69ffxtbr@PackageTracer_69.com">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+        <pref>browser.search.defaultenginename</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i734" id="profsites@pr.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
+      <prefs/>
+      <versionRange minVersion=" " maxVersion="8.5"/>
+    </emItem>
+    <emItem blockID="i238" id="/^pink@.*\.info$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+          <versionRange maxVersion="*" minVersion="18.0"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem blockID="i78" id="socialnetworktools@mozilla.doslash.org">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i696" id="/^({fa95f577-07cb-4470-ac90-e843f5f83c52}|ffxtlbr@speedial\.com)$/">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i196" id="info@wxdownloadmanager.com">
+    <emItem blockID="i712" id="{a2bfe612-4cf5-48ea-907c-f3fb25bc9d6b}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1078" id="/^(jid1-W4CLFIRExukJIFW@jetpack|jid1-W4CLFIRExukJIFW@jetpack_1|jid1-W3CLwrP[a-z]+@jetpack)$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i682" id="f6682b47-e12f-400b-9bc0-43b3ccae69d1@39d6f481-b198-4349-9ebe-9a93a86f9267.com">
+    <emItem blockID="i54" id="applebeegifts@mozilla.doslash.org">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i518" id="/^({d6e79525-4524-4707-9b97-1d70df8e7e59}|{ddb4644d-1a37-4e6d-8b6e-8e35e2a8ea6c}|{e55007f4-80c5-418e-ac33-10c4d60db01e}|{e77d8ca6-3a60-4ae9-8461-53b22fa3125b}|{e89a62b7-248e-492f-9715-43bf8c507a2f}|{5ce3e0cb-aa83-45cb-a7da-a2684f05b8f3})$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i67" id="youtube2@youtube2.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i678" id="{C4A4F5A0-4B89-4392-AFAC-D58010E349AF}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i478" id="{7e8a1050-cf67-4575-92df-dcc60e7d952d}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i402" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i1024" id="{458fb825-2370-4973-bf66-9d7142141847}">
-      <prefs>
-        <pref>app.update.auto</pref>
-        <pref>app.update.enabled</pref>
-        <pref>app.update.interval</pref>
-        <pref>app.update.url</pref>
-      </prefs>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i522" id="/^({976cd962-e0ca-4337-aea7-d93fae63a79c}|{525ba996-1ce4-4677-91c5-9fc4ead2d245}|{91659dab-9117-42d1-a09f-13ec28037717}|{c1211069-1163-4ba8-b8b3-32fc724766be})$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
-      <prefs/>
-      <versionRange minVersion=" " maxVersion="8.5"/>
-    </emItem>
-    <emItem blockID="i692" id="/^(j003-lqgrmgpcekslhg|SupraSavings|j003-dkqonnnthqjnkq|j003-kaggrpmirxjpzh)@jetpack$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i490" id="now.msn.com@services.mozilla.org">
+    <emItem blockID="i51" id="admin@youtubeplayer.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i642" id="{bee6eb20-01e0-ebd1-da83-080329fb9a3a}">
+      <prefs/>
+      <versionRange minVersion="40.10.1" maxVersion="44.10.1" severity="3"/>
+    </emItem>
+    <emItem blockID="i485" id="/^brasilescape.*\@facebook\.com$//">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
-      <prefs/>
-      <versionRange minVersion="0.1" maxVersion="14.4.0" severity="1"/>
-    </emItem>
-    <emItem blockID="i756" id="{5eeb83d0-96ea-4249-942c-beead6847053}">
+    <emItem blockID="i127" id="plugin@youtubeplayer.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i63" id="youtube@youtuber.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i495" id="kallow@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i524" id="/^({4e988b08-8c51-45c1-8d74-73e0c8724579}|{93ec97bf-fe43-4bca-a735-5c5d6a0a40c4}|{aed63b38-7428-4003-a052-ca6834d8bad3}|{0b5130a9-cc50-4ced-99d5-cda8cc12ae48}|{C4CFC0DE-134F-4466-B2A2-FF7C59A8BFAD})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i884" id="detgdp@gmail.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i487" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
-      <prefs/>
-      <versionRange minVersion="2.0.3" maxVersion="2.0.3"/>
-      <versionRange minVersion="4.2" maxVersion="4.2" severity="3"/>
-    </emItem>
-    <emItem blockID="i543" id="{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i1040" id="frhegnejkgner@grhjgewfewf.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i1030" id="support@todoist.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="3.9" severity="1"/>
-    </emItem>
-    <emItem blockID="i523" id="/^({7e8a1050-cf67-4575-92df-dcc60e7d952d}|{b3420a9c-a397-4409-b90d-bcf22da1a08a}|{eca6641f-2176-42ba-bdbe-f3e327f8e0af}|{707dca12-3f99-4d94-afea-06dcc0ae0108}|{aea20431-87fc-40be-bc5b-18066fe2819c}|{30ee6676-1ba6-455a-a7e8-298fa863a546})$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i732" id="{e935dd68-f90d-46a6-b89e-c4657534b353}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i436" id="/(\{7aeae561-714b-45f6-ace3-4a8aed6e227b\})|(\{01e86e69-a2f8-48a0-b068-83869bdba3d0\})|(\{77f5fe49-12e3-4cf5-abb4-d993a0164d9e\})/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i700" id="2bbadf1f-a5af-499f-9642-9942fcdb7c76@f05a14cc-8842-4eee-be17-744677a917ed.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i866" id="faststartff@gmail.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i320" id="torntv@torntv.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i524" id="/^({4e988b08-8c51-45c1-8d74-73e0c8724579}|{93ec97bf-fe43-4bca-a735-5c5d6a0a40c4}|{aed63b38-7428-4003-a052-ca6834d8bad3}|{0b5130a9-cc50-4ced-99d5-cda8cc12ae48}|{C4CFC0DE-134F-4466-B2A2-FF7C59A8BFAD})$/">
+    <emItem blockID="i838" id="{87b5a11e-3b54-42d2-9102-0a7cb1f79ebf}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i68" id="flashupdate@adobe.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i1264" id="suchpony@suchpony.de">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="1.6.7" severity="3"/>
+    </emItem>
+    <emItem blockID="i346" id="{a6e67e6f-8615-4fe0-a599-34a73fc3fba5}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i537" id="rally_toolbar_ff@bulletmedia.com">
+    <emItem blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
+      <prefs/>
+      <versionRange minVersion="0.1" maxVersion="14.4.0" severity="1"/>
+    </emItem>
+    <emItem blockID="i578" id="jid1-XLjasWL55iEE1Q@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i812" id="{1e4ea5fc-09e5-4f45-a43b-c048304899fc}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i43" id="supportaccessplugin@gmail.com">
+      <prefs/>
+    </emItem>
+    <emItem blockID="i282" id="{33e0daa6-3af3-d8b5-6752-10e949c61516}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="1.1.999" severity="1"/>
+    </emItem>
+    <emItem blockID="i246" id="support@vide1flash2.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i648" id="firefoxaddon@youtubeenhancer.com">
+      <prefs/>
+      <versionRange minVersion="199.7.0" maxVersion="199.7.0" severity="3"/>
+      <versionRange minVersion="208.7.0" maxVersion="208.7.0" severity="3"/>
+      <versionRange minVersion="199.7.0" maxVersion="208.7.0" severity="3"/>
+    </emItem>
+    <emItem blockID="i1227" id="{A34CAF42-A3E3-11E5-945F-18C31D5D46B0}">
+      <prefs>
+        <pref>security.csp.enable</pref>
+        <pref>security.fileuri.strict_origin_policy</pref>
+        <pref>security.mixed_content.block_active_content</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i220" id="pricepeep@getpricepeep.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="2.1.0.19.99" severity="1"/>
+    </emItem>
+    <emItem blockID="i358" id="lfind@nijadsoft.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i1266" id="@stopad">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="0.0.4" severity="1"/>
-    </emItem>
-    <emItem blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}">
+    <emItem blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i1012" id="wxtui502n2xce9j@no14">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1137" id="/^({d50bfa5f-291d-48a8-909c-5f1a77b31948}|{d54bc985-6e7b-46cd-ad72-a4a266ad879e}|{d89e5de3-5543-4363-b320-a98cf150f86a}|{f3465017-6f51-4980-84a5-7bee2f961eba}|{fae25f38-ff55-46ea-888f-03b49aaf8812})$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1022" id="g99hiaoekjoasiijdkoleabsy278djasi@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i496" id="{ACAA314B-EEBA-48e4-AD47-84E31C44796C}">
+    <emItem blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
+      <prefs/>
+      <versionRange minVersion="1.0" maxVersion="1.0"/>
+    </emItem>
+    <emItem blockID="i484" id="plugin@getwebcake.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i1233" id="cloudmask@cloudmask.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="2.0.788"/>
+    </emItem>
+    <emItem blockID="i588" id="quick_start@gmail.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i498" id="hoverst@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i914" id="{0153E448-190B-4987-BDE1-F256CADA672F}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i1228" id="unblocker30__web@unblocker.yt">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i620" id="{21EAF666-26B3-4A3C-ABD0-CA2F5A326744}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1279" id="dodatek@flash2.pl">
+      <prefs/>
+      <versionRange minVersion="1.3" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1214" id="firefoxdav@icloud.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="1.4.22" severity="1"/>
+    </emItem>
+    <emItem blockID="i338" id="{1FD91A9C-410C-4090-BBCC-55D3450EF433}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i468" id="05dd836e-2cbd-4204-9ff3-2f8a8665967d@a8876730-fb0c-4057-a2fc-f9c09d438e81.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i998" id="meOYKQEbBBjH5Ml91z0p9Aosgus8P55bjTa4KPfl@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1232" id="nosquint@urandom.ca">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="2.1.9.1-signed.1-signed" severity="1">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+          <versionRange maxVersion="*" minVersion="47"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem blockID="i378" id="{a7aae4f0-bc2e-a0dd-fb8d-68ce32c9261f}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1016" id="jid1-uabu5A9hduqzCw@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i326" id="/^((support2_en@adobe14\.com)|(XN4Xgjw7n4@yUWgc\.com)|(C7yFVpIP@WeolS3acxgS\.com)|(Kbeu4h0z@yNb7QAz7jrYKiiTQ3\.com)|(aWQzX@a6z4gWdPu8FF\.com)|(CBSoqAJLYpCbjTP90@JoV0VMywCjsm75Y0toAd\.com)|(zZ2jWZ1H22Jb5NdELHS@o0jQVWZkY1gx1\.com))$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i474" id="{906000a4-88d9-4d52-b209-7a772970d91f}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1024" id="{458fb825-2370-4973-bf66-9d7142141847}">
+      <prefs>
+        <pref>app.update.auto</pref>
+        <pref>app.update.enabled</pref>
+        <pref>app.update.interval</pref>
+        <pref>app.update.url</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i1036" id="HxLVJK1ioigz9WEWo8QgCs3evE7uW6LEExAniBGG@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i888" id="istart_ffnt@gmail.com">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+        <pref>browser.search.defaultenginename</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i501" id="xivars@aol.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1128" id="youtubeunblocker@unblocker.yt">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i686" id="{a7f2cb14-0472-42a1-915a-8adca2280a2c}">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+        <pref>browser.search.defaultenginename</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i98" id="youtubeeing@youtuberie.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i539" id="ScorpionSaver@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i582" id="discoverypro@discoverypro.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i541" id="/^({988919ff-0cd8-4d0c-bc7e-60d55a49eb64}|{494b9726-9084-415c-a499-68c07e187244}|{55b95864-3251-45e9-bb30-1a82589aaff1}|{eef3855c-fc2d-41e6-8d91-d368f51b3055}|{90a1b331-c2b4-4933-9f63-ba7b84d60d58}|{d2cf9842-af95-48cd-b873-bfbb48cd7f5e})$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1077" id="helper@vidscrab.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i348" id="{13c9f1f9-2322-4d5c-81df-6d4bf8476ba4}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i772" id="{72b98dbc-939a-4e0e-b5a9-9fdbf75963ef}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i814" id="liiros@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1278" id="/^(ff\-)?dodate(kKKK|XkKKK|k|kk|kkx|kR)@(firefox|flash(1)?)\.pl|dode(ee)?k@firefoxnet\.pl|(addon|1)@upsolutions\.pl$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
+      <prefs/>
+      <versionRange minVersion="2.2" maxVersion="2.2"/>
+    </emItem>
+    <emItem blockID="i972" id="831778-poidjao88DASfsAnindsd@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i852" id="6lIy@T.edu">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i76" id="crossriderapp3924@crossrider.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
+    <emItem blockID="i742" id="{f894a29a-f065-40c3-bb19-da6057778493}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i549" id="/^firefox@(albrechto|swiftbrowse|springsmart|storimbo|squirrelweb|betterbrowse|lizardlink|rolimno|browsebeyond|clingclang|weblayers|kasimos|higher-aurum|xaven|bomlabio)\.(com?|net|org|info|biz)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i435" id="pluggets@gmail.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i471" id="firefox@luckyleap.net">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i780" id="{b6ef1336-69bb-45b6-8cba-e578fc0e4433}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i406" id="{bf7380fa-e3b4-4db2-af3e-9d8783a45bfc}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i788" id="{729c9605-0626-4792-9584-4cbe65b243e6}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i1266" id="@stopad">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="0.0.4" severity="1"/>
+    </emItem>
+    <emItem blockID="i465" id="trtv3@trtv.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i1032" id="KSqOiTeSJEDZtTGuvc18PdPmYodROmYzfpoyiCr2@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i718" id="G4Ce4@w.net">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i1210" id="auto-plugin-checker@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i447" id="{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}">
+