Merge fx-team to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 28 Aug 2015 15:33:57 -0400
changeset 294131 7db14bebae9196d780b1d64d2fd32d1bda26828b
parent 294116 28c11736db63620a8617caf68fc565c6386aa463 (current diff)
parent 294130 f0a2a2b0f06d71e71b1d082bd036009a3546a8de (diff)
child 294132 359b862d7be0dd3b9d299fa58a358ab5a6eded78
child 294150 50dd35d46e18cd870698fe5de52673c8c61b2a38
child 294177 99439a497979be5acda1c17a11a597b228d0dff1
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone43.0a1
first release with
nightly linux32
7db14bebae91 / 43.0a1 / 20150829030207 / files
nightly linux64
7db14bebae91 / 43.0a1 / 20150829030207 / files
nightly mac
7db14bebae91 / 43.0a1 / 20150829030207 / files
nightly win32
7db14bebae91 / 43.0a1 / 20150829030207 / files
nightly win64
7db14bebae91 / 43.0a1 / 20150829030207 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge fx-team to m-c. a=merge CLOSED TREE
browser/devtools/debugger/test/addon-source/browser_dbg_addon3/lib/main.js
browser/devtools/debugger/test/addon-source/browser_dbg_addon3/package.json
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/bootstrap.js
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/chrome.manifest
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/install.rdf
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test.jsm
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test.xul
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test2.jsm
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test2.xul
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/testxul.js
browser/devtools/debugger/test/addon-source/browser_dbg_addon4/testxul2.js
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/bootstrap.js
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/chrome.manifest
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/install.rdf
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test.jsm
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test.xul
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test2.jsm
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test2.xul
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/testxul.js
browser/devtools/debugger/test/addon-source/browser_dbg_addon5/testxul2.js
browser/devtools/debugger/test/addon1.xpi
browser/devtools/debugger/test/addon2.xpi
browser/devtools/debugger/test/addon3.xpi
browser/devtools/debugger/test/addon4.xpi
browser/devtools/debugger/test/addon5.xpi
browser/devtools/debugger/test/browser.ini
browser/devtools/debugger/test/browser_dbg_WorkerActor.attach.js
browser/devtools/debugger/test/browser_dbg_WorkerActor.attachThread.js
browser/devtools/debugger/test/browser_dbg_aaa_run_first_leaktest.js
browser/devtools/debugger/test/browser_dbg_addon-console.js
browser/devtools/debugger/test/browser_dbg_addon-modules-unpacked.js
browser/devtools/debugger/test/browser_dbg_addon-modules.js
browser/devtools/debugger/test/browser_dbg_addon-panels.js
browser/devtools/debugger/test/browser_dbg_addon-sources.js
browser/devtools/debugger/test/browser_dbg_addonactor.js
browser/devtools/debugger/test/browser_dbg_auto-pretty-print-01.js
browser/devtools/debugger/test/browser_dbg_auto-pretty-print-02.js
browser/devtools/debugger/test/browser_dbg_bfcache.js
browser/devtools/debugger/test/browser_dbg_blackboxing-01.js
browser/devtools/debugger/test/browser_dbg_blackboxing-02.js
browser/devtools/debugger/test/browser_dbg_blackboxing-03.js
browser/devtools/debugger/test/browser_dbg_blackboxing-04.js
browser/devtools/debugger/test/browser_dbg_blackboxing-05.js
browser/devtools/debugger/test/browser_dbg_blackboxing-06.js
browser/devtools/debugger/test/browser_dbg_breadcrumbs-access.js
browser/devtools/debugger/test/browser_dbg_break-in-anon.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-01.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-02.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-03.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-04.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-05.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-06.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-07.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-08.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-event-01.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-event-02.js
browser/devtools/debugger/test/browser_dbg_break-on-dom-event-03.js
browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location.js
browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location2.js
browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js
browser/devtools/debugger/test/browser_dbg_breakpoints-button-01.js
browser/devtools/debugger/test/browser_dbg_breakpoints-button-02.js
browser/devtools/debugger/test/browser_dbg_breakpoints-condition-thrown-message.js
browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu-add.js
browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js
browser/devtools/debugger/test/browser_dbg_breakpoints-disabled-reload.js
browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js
browser/devtools/debugger/test/browser_dbg_breakpoints-eval.js
browser/devtools/debugger/test/browser_dbg_breakpoints-highlight.js
browser/devtools/debugger/test/browser_dbg_breakpoints-new-script.js
browser/devtools/debugger/test/browser_dbg_breakpoints-other-tabs.js
browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js
browser/devtools/debugger/test/browser_dbg_breakpoints-reload.js
browser/devtools/debugger/test/browser_dbg_bug-896139.js
browser/devtools/debugger/test/browser_dbg_chrome-create.js
browser/devtools/debugger/test/browser_dbg_chrome-debugging.js
browser/devtools/debugger/test/browser_dbg_clean-exit-window.js
browser/devtools/debugger/test/browser_dbg_clean-exit.js
browser/devtools/debugger/test/browser_dbg_closure-inspection.js
browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
browser/devtools/debugger/test/browser_dbg_cmd-break.js
browser/devtools/debugger/test/browser_dbg_cmd-dbg.js
browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-01.js
browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-02.js
browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-03.js
browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-04.js
browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-05.js
browser/devtools/debugger/test/browser_dbg_console-eval.js
browser/devtools/debugger/test/browser_dbg_console-named-eval.js
browser/devtools/debugger/test/browser_dbg_controller-evaluate-01.js
browser/devtools/debugger/test/browser_dbg_controller-evaluate-02.js
browser/devtools/debugger/test/browser_dbg_debugger-statement.js
browser/devtools/debugger/test/browser_dbg_editor-contextmenu.js
browser/devtools/debugger/test/browser_dbg_editor-mode.js
browser/devtools/debugger/test/browser_dbg_event-listeners-01.js
browser/devtools/debugger/test/browser_dbg_event-listeners-02.js
browser/devtools/debugger/test/browser_dbg_event-listeners-03.js
browser/devtools/debugger/test/browser_dbg_event-listeners-04.js
browser/devtools/debugger/test/browser_dbg_file-reload.js
browser/devtools/debugger/test/browser_dbg_function-display-name.js
browser/devtools/debugger/test/browser_dbg_global-method-override.js
browser/devtools/debugger/test/browser_dbg_globalactor.js
browser/devtools/debugger/test/browser_dbg_hide-toolbar-buttons.js
browser/devtools/debugger/test/browser_dbg_host-layout.js
browser/devtools/debugger/test/browser_dbg_iframes.js
browser/devtools/debugger/test/browser_dbg_instruments-pane-collapse.js
browser/devtools/debugger/test/browser_dbg_interrupts.js
browser/devtools/debugger/test/browser_dbg_listaddons.js
browser/devtools/debugger/test/browser_dbg_listtabs-01.js
browser/devtools/debugger/test/browser_dbg_listtabs-02.js
browser/devtools/debugger/test/browser_dbg_listtabs-03.js
browser/devtools/debugger/test/browser_dbg_listworkers.js
browser/devtools/debugger/test/browser_dbg_location-changes-01-simple.js
browser/devtools/debugger/test/browser_dbg_location-changes-02-blank.js
browser/devtools/debugger/test/browser_dbg_location-changes-03-new.js
browser/devtools/debugger/test/browser_dbg_location-changes-04-breakpoint.js
browser/devtools/debugger/test/browser_dbg_multiple-windows.js
browser/devtools/debugger/test/browser_dbg_navigation.js
browser/devtools/debugger/test/browser_dbg_no-page-sources.js
browser/devtools/debugger/test/browser_dbg_on-pause-highlight.js
browser/devtools/debugger/test/browser_dbg_on-pause-raise.js
browser/devtools/debugger/test/browser_dbg_optimized-out-vars.js
browser/devtools/debugger/test/browser_dbg_panel-size.js
browser/devtools/debugger/test/browser_dbg_parser-01.js
browser/devtools/debugger/test/browser_dbg_parser-02.js
browser/devtools/debugger/test/browser_dbg_parser-03.js
browser/devtools/debugger/test/browser_dbg_parser-04.js
browser/devtools/debugger/test/browser_dbg_parser-05.js
browser/devtools/debugger/test/browser_dbg_parser-06.js
browser/devtools/debugger/test/browser_dbg_parser-07.js
browser/devtools/debugger/test/browser_dbg_parser-08.js
browser/devtools/debugger/test/browser_dbg_parser-09.js
browser/devtools/debugger/test/browser_dbg_parser-10.js
browser/devtools/debugger/test/browser_dbg_pause-exceptions-01.js
browser/devtools/debugger/test/browser_dbg_pause-exceptions-02.js
browser/devtools/debugger/test/browser_dbg_pause-no-step.js
browser/devtools/debugger/test/browser_dbg_pause-resume.js
browser/devtools/debugger/test/browser_dbg_pause-warning.js
browser/devtools/debugger/test/browser_dbg_paused-keybindings.js
browser/devtools/debugger/test/browser_dbg_pretty-print-01.js
browser/devtools/debugger/test/browser_dbg_pretty-print-02.js
browser/devtools/debugger/test/browser_dbg_pretty-print-03.js
browser/devtools/debugger/test/browser_dbg_pretty-print-04.js
browser/devtools/debugger/test/browser_dbg_pretty-print-05.js
browser/devtools/debugger/test/browser_dbg_pretty-print-06.js
browser/devtools/debugger/test/browser_dbg_pretty-print-07.js
browser/devtools/debugger/test/browser_dbg_pretty-print-08.js
browser/devtools/debugger/test/browser_dbg_pretty-print-09.js
browser/devtools/debugger/test/browser_dbg_pretty-print-10.js
browser/devtools/debugger/test/browser_dbg_pretty-print-11.js
browser/devtools/debugger/test/browser_dbg_pretty-print-12.js
browser/devtools/debugger/test/browser_dbg_pretty-print-13.js
browser/devtools/debugger/test/browser_dbg_pretty-print-on-paused.js
browser/devtools/debugger/test/browser_dbg_progress-listener-bug.js
browser/devtools/debugger/test/browser_dbg_promises-allocation-stack.js
browser/devtools/debugger/test/browser_dbg_promises-chrome-allocation-stack.js
browser/devtools/debugger/test/browser_dbg_promises-fulfillment-stack.js
browser/devtools/debugger/test/browser_dbg_promises-rejection-stack.js
browser/devtools/debugger/test/browser_dbg_reload-preferred-script-01.js
browser/devtools/debugger/test/browser_dbg_reload-preferred-script-02.js
browser/devtools/debugger/test/browser_dbg_reload-preferred-script-03.js
browser/devtools/debugger/test/browser_dbg_reload-same-script.js
browser/devtools/debugger/test/browser_dbg_scripts-switching-01.js
browser/devtools/debugger/test/browser_dbg_scripts-switching-02.js
browser/devtools/debugger/test/browser_dbg_scripts-switching-03.js
browser/devtools/debugger/test/browser_dbg_search-autofill-identifier.js
browser/devtools/debugger/test/browser_dbg_search-basic-01.js
browser/devtools/debugger/test/browser_dbg_search-basic-02.js
browser/devtools/debugger/test/browser_dbg_search-basic-03.js
browser/devtools/debugger/test/browser_dbg_search-basic-04.js
browser/devtools/debugger/test/browser_dbg_search-global-01.js
browser/devtools/debugger/test/browser_dbg_search-global-02.js
browser/devtools/debugger/test/browser_dbg_search-global-03.js
browser/devtools/debugger/test/browser_dbg_search-global-04.js
browser/devtools/debugger/test/browser_dbg_search-global-05.js
browser/devtools/debugger/test/browser_dbg_search-global-06.js
browser/devtools/debugger/test/browser_dbg_search-popup-jank.js
browser/devtools/debugger/test/browser_dbg_search-sources-01.js
browser/devtools/debugger/test/browser_dbg_search-sources-02.js
browser/devtools/debugger/test/browser_dbg_search-sources-03.js
browser/devtools/debugger/test/browser_dbg_search-symbols.js
browser/devtools/debugger/test/browser_dbg_searchbox-help-popup-01.js
browser/devtools/debugger/test/browser_dbg_searchbox-help-popup-02.js
browser/devtools/debugger/test/browser_dbg_searchbox-parse.js
browser/devtools/debugger/test/browser_dbg_server-conditional-bp-01.js
browser/devtools/debugger/test/browser_dbg_server-conditional-bp-02.js
browser/devtools/debugger/test/browser_dbg_server-conditional-bp-03.js
browser/devtools/debugger/test/browser_dbg_server-conditional-bp-04.js
browser/devtools/debugger/test/browser_dbg_server-conditional-bp-05.js
browser/devtools/debugger/test/browser_dbg_source-maps-01.js
browser/devtools/debugger/test/browser_dbg_source-maps-02.js
browser/devtools/debugger/test/browser_dbg_source-maps-03.js
browser/devtools/debugger/test/browser_dbg_source-maps-04.js
browser/devtools/debugger/test/browser_dbg_sources-bookmarklet.js
browser/devtools/debugger/test/browser_dbg_sources-cache.js
browser/devtools/debugger/test/browser_dbg_sources-contextmenu-01.js
browser/devtools/debugger/test/browser_dbg_sources-contextmenu-02.js
browser/devtools/debugger/test/browser_dbg_sources-eval-01.js
browser/devtools/debugger/test/browser_dbg_sources-eval-02.js
browser/devtools/debugger/test/browser_dbg_sources-keybindings.js
browser/devtools/debugger/test/browser_dbg_sources-labels.js
browser/devtools/debugger/test/browser_dbg_sources-sorting.js
browser/devtools/debugger/test/browser_dbg_split-console-paused-reload.js
browser/devtools/debugger/test/browser_dbg_stack-01.js
browser/devtools/debugger/test/browser_dbg_stack-02.js
browser/devtools/debugger/test/browser_dbg_stack-03.js
browser/devtools/debugger/test/browser_dbg_stack-04.js
browser/devtools/debugger/test/browser_dbg_stack-05.js
browser/devtools/debugger/test/browser_dbg_stack-06.js
browser/devtools/debugger/test/browser_dbg_stack-07.js
browser/devtools/debugger/test/browser_dbg_step-out.js
browser/devtools/debugger/test/browser_dbg_tabactor-01.js
browser/devtools/debugger/test/browser_dbg_tabactor-02.js
browser/devtools/debugger/test/browser_dbg_terminate-on-tab-close.js
browser/devtools/debugger/test/browser_dbg_variables-view-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-03.js
browser/devtools/debugger/test/browser_dbg_variables-view-04.js
browser/devtools/debugger/test/browser_dbg_variables-view-05.js
browser/devtools/debugger/test/browser_dbg_variables-view-06.js
browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js
browser/devtools/debugger/test/browser_dbg_variables-view-data.js
browser/devtools/debugger/test/browser_dbg_variables-view-edit-cancel.js
browser/devtools/debugger/test/browser_dbg_variables-view-edit-click.js
browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js
browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-03.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-04.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-05.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-searchbox.js
browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js
browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js
browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js
browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js
browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js
browser/devtools/debugger/test/browser_dbg_variables-view-override-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-override-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-03.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-04.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-05.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-06.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-07.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-08.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-09.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-10.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-11.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-12.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-13.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-14.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-15.js
browser/devtools/debugger/test/browser_dbg_variables-view-popup-16.js
browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-03.js
browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js
browser/devtools/debugger/test/browser_dbg_watch-expressions-01.js
browser/devtools/debugger/test/browser_dbg_watch-expressions-02.js
browser/devtools/debugger/test/code_WorkerActor.attach-worker1.js
browser/devtools/debugger/test/code_WorkerActor.attach-worker2.js
browser/devtools/debugger/test/code_WorkerActor.attachThread-worker.js
browser/devtools/debugger/test/code_binary_search.coffee
browser/devtools/debugger/test/code_binary_search.js
browser/devtools/debugger/test/code_binary_search.map
browser/devtools/debugger/test/code_blackboxing_blackboxme.js
browser/devtools/debugger/test/code_blackboxing_one.js
browser/devtools/debugger/test/code_blackboxing_three.js
browser/devtools/debugger/test/code_blackboxing_two.js
browser/devtools/debugger/test/code_breakpoints-break-on-last-line-of-script-on-reload.js
browser/devtools/debugger/test/code_breakpoints-other-tabs.js
browser/devtools/debugger/test/code_bug-896139.js
browser/devtools/debugger/test/code_frame-script.js
browser/devtools/debugger/test/code_function-search-01.js
browser/devtools/debugger/test/code_function-search-02.js
browser/devtools/debugger/test/code_function-search-03.js
browser/devtools/debugger/test/code_listworkers-worker1.js
browser/devtools/debugger/test/code_listworkers-worker2.js
browser/devtools/debugger/test/code_location-changes.js
browser/devtools/debugger/test/code_math.js
browser/devtools/debugger/test/code_math.map
browser/devtools/debugger/test/code_math.min.js
browser/devtools/debugger/test/code_math_bogus_map.js
browser/devtools/debugger/test/code_same-line-functions.js
browser/devtools/debugger/test/code_script-eval.js
browser/devtools/debugger/test/code_script-switching-01.js
browser/devtools/debugger/test/code_script-switching-02.js
browser/devtools/debugger/test/code_test-editor-mode
browser/devtools/debugger/test/code_ugly-2.js
browser/devtools/debugger/test/code_ugly-3.js
browser/devtools/debugger/test/code_ugly-4.js
browser/devtools/debugger/test/code_ugly-5.js
browser/devtools/debugger/test/code_ugly-6.js
browser/devtools/debugger/test/code_ugly-7.js
browser/devtools/debugger/test/code_ugly-8
browser/devtools/debugger/test/code_ugly-8^headers^
browser/devtools/debugger/test/code_ugly.js
browser/devtools/debugger/test/code_workeractor-worker.js
browser/devtools/debugger/test/doc_WorkerActor.attach-tab1.html
browser/devtools/debugger/test/doc_WorkerActor.attach-tab2.html
browser/devtools/debugger/test/doc_WorkerActor.attachThread-tab.html
browser/devtools/debugger/test/doc_auto-pretty-print-01.html
browser/devtools/debugger/test/doc_auto-pretty-print-02.html
browser/devtools/debugger/test/doc_binary_search.html
browser/devtools/debugger/test/doc_blackboxing.html
browser/devtools/debugger/test/doc_breakpoint-move.html
browser/devtools/debugger/test/doc_breakpoints-break-on-last-line-of-script-on-reload.html
browser/devtools/debugger/test/doc_breakpoints-other-tabs.html
browser/devtools/debugger/test/doc_breakpoints-reload.html
browser/devtools/debugger/test/doc_bug-896139.html
browser/devtools/debugger/test/doc_closure-optimized-out.html
browser/devtools/debugger/test/doc_closures.html
browser/devtools/debugger/test/doc_cmd-break.html
browser/devtools/debugger/test/doc_cmd-dbg.html
browser/devtools/debugger/test/doc_conditional-breakpoints.html
browser/devtools/debugger/test/doc_domnode-variables.html
browser/devtools/debugger/test/doc_editor-mode.html
browser/devtools/debugger/test/doc_empty-tab-01.html
browser/devtools/debugger/test/doc_empty-tab-02.html
browser/devtools/debugger/test/doc_event-listeners-01.html
browser/devtools/debugger/test/doc_event-listeners-02.html
browser/devtools/debugger/test/doc_event-listeners-03.html
browser/devtools/debugger/test/doc_event-listeners-04.html
browser/devtools/debugger/test/doc_frame-parameters.html
browser/devtools/debugger/test/doc_function-display-name.html
browser/devtools/debugger/test/doc_function-search.html
browser/devtools/debugger/test/doc_global-method-override.html
browser/devtools/debugger/test/doc_iframes.html
browser/devtools/debugger/test/doc_included-script.html
browser/devtools/debugger/test/doc_inline-debugger-statement.html
browser/devtools/debugger/test/doc_inline-script.html
browser/devtools/debugger/test/doc_large-array-buffer.html
browser/devtools/debugger/test/doc_listworkers-tab.html
browser/devtools/debugger/test/doc_minified.html
browser/devtools/debugger/test/doc_minified_bogus_map.html
browser/devtools/debugger/test/doc_native-event-handler.html
browser/devtools/debugger/test/doc_no-page-sources.html
browser/devtools/debugger/test/doc_pause-exceptions.html
browser/devtools/debugger/test/doc_pretty-print-2.html
browser/devtools/debugger/test/doc_pretty-print-3.html
browser/devtools/debugger/test/doc_pretty-print-on-paused.html
browser/devtools/debugger/test/doc_pretty-print.html
browser/devtools/debugger/test/doc_promise-get-allocation-stack.html
browser/devtools/debugger/test/doc_promise-get-fulfillment-stack.html
browser/devtools/debugger/test/doc_promise-get-rejection-stack.html
browser/devtools/debugger/test/doc_promise.html
browser/devtools/debugger/test/doc_random-javascript.html
browser/devtools/debugger/test/doc_recursion-stack.html
browser/devtools/debugger/test/doc_scope-variable-2.html
browser/devtools/debugger/test/doc_scope-variable-3.html
browser/devtools/debugger/test/doc_scope-variable-4.html
browser/devtools/debugger/test/doc_scope-variable.html
browser/devtools/debugger/test/doc_script-bookmarklet.html
browser/devtools/debugger/test/doc_script-eval.html
browser/devtools/debugger/test/doc_script-switching-01.html
browser/devtools/debugger/test/doc_script-switching-02.html
browser/devtools/debugger/test/doc_split-console-paused-reload.html
browser/devtools/debugger/test/doc_step-out.html
browser/devtools/debugger/test/doc_terminate-on-tab-close.html
browser/devtools/debugger/test/doc_watch-expression-button.html
browser/devtools/debugger/test/doc_watch-expressions.html
browser/devtools/debugger/test/doc_with-frame.html
browser/devtools/debugger/test/head.js
browser/devtools/debugger/test/sjs_random-javascript.sjs
browser/devtools/debugger/test/testactors.js
browser/devtools/debugger/views/event-listeners-view.js
--- a/browser/base/content/test/general/browser_urlbarDelete.js
+++ b/browser/base/content/test/general/browser_urlbarDelete.js
@@ -1,15 +1,11 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
 add_task(function*() {
   let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-                                                url: "http://example.com/",
+                                                url: "http://bug1105244.example.com/",
                                                 title: "test" });
 
   registerCleanupFunction(function* () {
     yield PlacesUtils.bookmarks.remove(bm);
   });
 
   // We do this test with both unifiedcomplete disabled and enabled.
   let ucpref = Services.prefs.getBoolPref("browser.urlbar.unifiedcomplete");
@@ -33,21 +29,21 @@ function sendHome() {
   }
 }
 
 function sendDelete() {
   EventUtils.synthesizeKey("VK_DELETE", {});
 }
 
 function* testDelete() {
-  yield promiseAutocompleteResultPopup("exam");
+  yield promiseAutocompleteResultPopup("bug1105244");
 
   // move to the start.
   sendHome();
   // delete the first few chars - each delete should operate on the input field.
   sendDelete();
-  Assert.equal(gURLBar.inputField.value, "xam");
+  Assert.equal(gURLBar.inputField.value, "ug1105244");
 
   yield promisePopupShown(gURLBar.popup);
 
   sendDelete();
-  Assert.equal(gURLBar.inputField.value, "am");
+  Assert.equal(gURLBar.inputField.value, "g1105244");
 }
--- a/browser/components/migration/tests/unit/test_IE_cookies.js
+++ b/browser/components/migration/tests/unit/test_IE_cookies.js
@@ -3,57 +3,99 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 add_task(function* () {
   let migrator = MigrationUtils.getMigrator("ie");
   // Sanity check for the source.
   Assert.ok(migrator.sourceExists);
 
   const BOOL = ctypes.bool;
   const LPCTSTR = ctypes.char16_t.ptr;
+  const DWORD = ctypes.uint32_t;
+  const LPDWORD = DWORD.ptr;
 
   let wininet = ctypes.open("Wininet");
-  do_register_cleanup(() => {
-    try {
-      wininet.close();
-    } catch (ex) {}
-  });
 
   /*
-  BOOL InternetSetCookie(
+  BOOL InternetSetCookieW(
     _In_  LPCTSTR lpszUrl,
     _In_  LPCTSTR lpszCookieName,
     _In_  LPCTSTR lpszCookieData
   );
   */
   let setIECookie = wininet.declare("InternetSetCookieW",
                                     ctypes.default_abi,
                                     BOOL,
                                     LPCTSTR,
                                     LPCTSTR,
                                     LPCTSTR);
 
-  let expiry = new Date();
-  expiry.setDate(expiry.getDate() + 7);
+  /*
+  BOOL InternetGetCookieW(
+    _In_    LPCTSTR lpszUrl,
+    _In_    LPCTSTR lpszCookieName,
+    _Out_   LPCTSTR  lpszCookieData,
+    _Inout_ LPDWORD lpdwSize
+  );
+  */
+  let getIECookie = wininet.declare("InternetGetCookieW",
+                                    ctypes.default_abi,
+                                    BOOL,
+                                    LPCTSTR,
+                                    LPCTSTR,
+                                    LPCTSTR,
+                                    LPDWORD);
+
+  // We need to randomize the cookie to avoid clashing with other cookies
+  // that might have been set by previous tests and not properly cleared.
+  let date = (new Date()).getDate();
   const COOKIE = {
-    host: "mycookietest.com",
+    get host() {
+      return new URL(this.href).host;
+    },
+    href: `http://mycookietest.${Math.random()}.com`,
     name: "testcookie",
     value: "testvalue",
-    expiry
+    expiry: new Date(new Date().setDate(date + 2))
   };
+  let data = ctypes.char16_t.array()(256);
+  let sizeRef = DWORD(256).address();
 
-  // Sanity check.
+  do_register_cleanup(() => {
+    // Remove the cookie.
+    try {
+      let expired = new Date(new Date().setDate(date - 2));
+      let rv = setIECookie(COOKIE.href, COOKIE.name,
+                           `; expires=${expired.toUTCString()}`);
+      Assert.ok(rv, "Expired the IE cookie");
+      Assert.ok(!getIECookie(COOKIE.href, COOKIE.name, data, sizeRef),
+      "The cookie has been properly removed");
+    } catch (ex) {}
+
+    // Close the library.
+    try {
+      wininet.close();
+    } catch (ex) {}
+  });
+
+  // Create the persistent cookie in IE.
+  let value = `${COOKIE.value}; expires=${COOKIE.expiry.toUTCString()}`;
+  let rv = setIECookie(COOKIE.href, COOKIE.name, value);
+  Assert.ok(rv, "Added a persistent IE cookie: " + value);
+
+  // Sanity check the cookie has been created.
+  Assert.ok(getIECookie(COOKIE.href, COOKIE.name, data, sizeRef),
+            "Found the added persistent IE cookie");
+  do_print("Found cookie: " + data.readString());
+  Assert.equal(data.readString(), `${COOKIE.name}=${COOKIE.value}`,
+            "Found the expected cookie");
+
+  // Sanity check that there are no cookies.
   Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 0,
                "There are no cookies initially");
 
-  // Create the persistent cookie in IE.
-  let value = COOKIE.name + " = " + COOKIE.value +"; expires = " +
-              COOKIE.expiry.toUTCString();
-  let rv = setIECookie(new URL("http://" + COOKIE.host).href, null, value);
-  Assert.ok(rv, "Added a persistent IE cookie");
-
   // Migrate cookies.
   yield promiseMigration(migrator, MigrationUtils.resourceTypes.COOKIES);
 
   Assert.equal(Services.cookies.countCookiesFromHost(COOKIE.host), 1,
                "Migrated the expected number of cookies");
 
   // Now check the cookie details.
   let enumerator = Services.cookies.getCookiesFromHost(COOKIE.host);
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -26,27 +26,21 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource:///modules/RecentWindow.jsm");
 
 // PlacesUtils exposes multiple symbols, so we can't use defineLazyModuleGetter.
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesTransactions",
                                   "resource://gre/modules/PlacesTransactions.jsm");
 
-#ifdef MOZ_SERVICES_CLOUDSYNC
 XPCOMUtils.defineLazyModuleGetter(this, "CloudSync",
                                   "resource://gre/modules/CloudSync.jsm");
-#else
-let CloudSync = null;
-#endif
 
-#ifdef MOZ_SERVICES_SYNC
 XPCOMUtils.defineLazyModuleGetter(this, "Weave",
                                   "resource://services-sync/main.js");
-#endif
 
 // copied from utilityOverlay.js
 const TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
 
 // This function isn't public both because it's synchronous and because it is
 // going to be removed in bug 1072833.
 function IsLivemark(aItemId) {
   // Since this check may be done on each dragover event, it's worth maintaining
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -1,12 +1,13 @@
 /* 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/. */
 
+Components.utils.import("resource://gre/modules/AppConstants.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 /**
  * The base view implements everything that's common to the toolbar and
  * menu views.
  */
 function PlacesViewBase(aPlace, aOptions) {
@@ -350,22 +351,22 @@ PlacesViewBase.prototype = {
             element.setAttribute("dayContainer", "true");
           else if (PlacesUtils.nodeIsHost(aPlacesNode))
             element.setAttribute("hostContainer", "true");
         }
         else if (itemId != -1) {
           PlacesUtils.livemarks.getLivemark({ id: itemId })
             .then(aLivemark => {
               element.setAttribute("livemark", "true");
-#ifdef XP_MACOSX
-              // OS X native menubar doesn't track list-style-images since
-              // it doesn't have a frame (bug 733415).  Thus enforce updating.
-              element.setAttribute("image", "");
-              element.removeAttribute("image");
-#endif
+              if (AppConstants.platform === "macosx") {
+                // OS X native menubar doesn't track list-style-images since
+                // it doesn't have a frame (bug 733415).  Thus enforce updating.
+                element.setAttribute("image", "");
+                element.removeAttribute("image");
+              }
               this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
             }, () => undefined);
         }
 
         let popup = document.createElement("menupopup");
         popup._placesNode = PlacesUtils.asContainer(aPlacesNode);
 
         if (!this._nativeView) {
@@ -535,22 +536,22 @@ PlacesViewBase.prototype = {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
 
     // All livemarks have a feedURI, so use it as our indicator of a livemark
     // being modified.
     if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
       let menu = elt.parentNode;
       if (!menu.hasAttribute("livemark")) {
         menu.setAttribute("livemark", "true");
-#ifdef XP_MACOSX
-        // OS X native menubar doesn't track list-style-images since
-        // it doesn't have a frame (bug 733415).  Thus enforce updating.
-        menu.setAttribute("image", "");
-        menu.removeAttribute("image");
-#endif
+        if (AppConstants.platform === "macosx") {
+          // OS X native menubar doesn't track list-style-images since
+          // it doesn't have a frame (bug 733415).  Thus enforce updating.
+          menu.setAttribute("image", "");
+          menu.removeAttribute("image");
+        }
       }
 
       PlacesUtils.livemarks.getLivemark({ id: aPlacesNode.itemId })
         .then(aLivemark => {
           // Controller will use this to build the meta data for the node.
           this.controller.cacheLivemarkInfo(aPlacesNode, aLivemark);
           this.invalidateContainer(aPlacesNode);
         }, () => undefined);
@@ -1769,25 +1770,25 @@ PlacesToolbar.prototype = {
  */
 function PlacesMenu(aPopupShowingEvent, aPlace, aOptions) {
   this._rootElt = aPopupShowingEvent.target; // <menupopup>
   this._viewElt = this._rootElt.parentNode;   // <menu>
   this._viewElt._placesView = this;
   this._addEventListeners(this._rootElt, ["popupshowing", "popuphidden"], true);
   this._addEventListeners(window, ["unload"], false);
 
-#ifdef XP_MACOSX
-  // Must walk up to support views in sub-menus, like Bookmarks Toolbar menu.
-  for (let elt = this._viewElt.parentNode; elt; elt = elt.parentNode) {
-    if (elt.localName == "menubar") {
-      this._nativeView = true;
-      break;
+  if (AppConstants.platform === "macosx") {
+    // Must walk up to support views in sub-menus, like Bookmarks Toolbar menu.
+    for (let elt = this._viewElt.parentNode; elt; elt = elt.parentNode) {
+      if (elt.localName == "menubar") {
+        this._nativeView = true;
+        break;
+      }
     }
   }
-#endif
 
   PlacesViewBase.call(this, aPlace, aOptions);
   this._onPopupShowing(aPopupShowingEvent);
 }
 
 PlacesMenu.prototype = {
   __proto__: PlacesViewBase.prototype,
 
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -1,13 +1,13 @@
 <?xml version="1.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/.
+<!-- 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/. -->
 
 <bindings id="placesMenuBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xbl="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <binding id="places-popup-base"
@@ -21,16 +21,20 @@
                             smoothscroll="false">
           <children/>
         </xul:arrowscrollbox>
       </xul:hbox>
     </content>
 
     <implementation>
 
+      <field name="AppConstants" readonly="true">
+        (Components.utils.import("resource://gre/modules/AppConstants.jsm", {})).AppConstants;
+      </field>
+
       <field name="_indicatorBar">
         document.getAnonymousElementByAttribute(this, "class",
                                                 "menupopup-drop-indicator-bar");
       </field>
 
       <field name="_scrollBox">
         document.getAnonymousElementByAttribute(this, "class",
                                                 "popup-internal-box");
@@ -299,28 +303,28 @@
     </implementation>
 
     <handlers>
       <handler event="DOMMenuItemActive"><![CDATA[
         let elt = event.target;
         if (elt.parentNode != this)
           return;
 
-#ifdef XP_MACOSX
-        // XXX: The following check is a temporary hack until bug 420033 is
-        // resolved.
-        let parentElt = elt.parent;
-        while (parentElt) {
-          if (parentElt.id == "bookmarksMenuPopup" ||
-              parentElt.id == "goPopup")
-            return;
+        if (this.AppConstants.platform === "macosx") {
+          // XXX: The following check is a temporary hack until bug 420033 is
+          // resolved.
+          let parentElt = elt.parent;
+          while (parentElt) {
+            if (parentElt.id == "bookmarksMenuPopup" ||
+                parentElt.id == "goPopup")
+              return;
 
-          parentElt = parentElt.parentNode;
+            parentElt = parentElt.parentNode;
+          }
         }
-#endif
 
         if (window.XULBrowserWindow) {
           let elt = event.target;
           let placesNode = elt._placesNode;
 
           var linkURI;
           if (placesNode && PlacesUtils.nodeIsURI(placesNode))
             linkURI = placesNode.uri;
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -1,13 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+Components.utils.import("resource://gre/modules/AppConstants.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/TelemetryStopwatch.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "MigrationUtils",
                                   "resource:///modules/MigrationUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils",
                                   "resource://gre/modules/BookmarkJSONUtils.jsm");
@@ -108,30 +109,31 @@ var PlacesOrganizer = {
     // clear the back-stack
     this._backHistory.splice(0, this._backHistory.length);
     document.getElementById("OrganizerCommand:Back").setAttribute("disabled", true);
 
     // Set up the search UI.
     PlacesSearchBox.init();
 
     window.addEventListener("AppCommand", this, true);
-#ifdef XP_MACOSX
-    // 1. Map Edit->Find command to OrganizerCommand_find:all.  Need to map
-    // both the menuitem and the Find key.
-    var findMenuItem = document.getElementById("menu_find");
-    findMenuItem.setAttribute("command", "OrganizerCommand_find:all");
-    var findKey = document.getElementById("key_find");
-    findKey.setAttribute("command", "OrganizerCommand_find:all");
 
-    // 2. Disable some keybindings from browser.xul
-    var elements = ["cmd_handleBackspace", "cmd_handleShiftBackspace"];
-    for (var i=0; i < elements.length; i++) {
-      document.getElementById(elements[i]).setAttribute("disabled", "true");
+    if (AppConstants.platform === "macosx") {
+      // 1. Map Edit->Find command to OrganizerCommand_find:all.  Need to map
+      // both the menuitem and the Find key.
+      let findMenuItem = document.getElementById("menu_find");
+      findMenuItem.setAttribute("command", "OrganizerCommand_find:all");
+      let findKey = document.getElementById("key_find");
+      findKey.setAttribute("command", "OrganizerCommand_find:all");
+
+      // 2. Disable some keybindings from browser.xul
+      let elements = ["cmd_handleBackspace", "cmd_handleShiftBackspace"];
+      for (let i = 0; i < elements.length; i++) {
+        document.getElementById(elements[i]).setAttribute("disabled", "true");
+      }
     }
-#endif
 
     // remove the "Properties" context-menu item, we've our own details pane
     document.getElementById("placesContext")
             .removeChild(document.getElementById("placesContext_show:info"));
 
     ContentArea.focus();
   },
 
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -1,12 +1,13 @@
-# -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+/* 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/. */
+
+Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 var SidebarUtils = {
   handleTreeClick: function SU_handleTreeClick(aTree, aEvent, aGutterSelect) {
     // right-clicks are not handled here
     if (aEvent.button == 2)
       return;
 
     var tbo = aTree.treeBoxObject;
@@ -25,22 +26,19 @@ var SidebarUtils = {
       // LTR and RTL modes, respectively) from the click target area.
       var isRTL = window.getComputedStyle(aTree, null).direction == "rtl";
       if (isRTL)
         mouseInGutter = aEvent.clientX > rect.x;
       else
         mouseInGutter = aEvent.clientX < rect.x;
     }
 
-#ifdef XP_MACOSX
-    var modifKey = aEvent.metaKey || aEvent.shiftKey;
-#else
-    var modifKey = aEvent.ctrlKey || aEvent.shiftKey;
-#endif
-
+    var metaKey = AppConstants.platform === "macosx" ? aEvent.metaKey
+                                                     : aEvent.ctrlKey;
+    var modifKey = metaKey || aEvent.shiftKey;
     var isContainer = tbo.view.isContainer(cell.row);
     var openInTabs = isContainer &&
                      (aEvent.button == 1 ||
                       (aEvent.button == 0 && modifKey)) &&
                      PlacesUtils.hasChildURIs(tbo.view.nodeForTreeIndex(cell.row));
 
     if (aEvent.button == 0 && isContainer && !openInTabs) {
       tbo.view.toggleOpenState(cell.row);
--- a/browser/components/places/jar.mn
+++ b/browser/components/places/jar.mn
@@ -3,32 +3,32 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 browser.jar:
 % overlay chrome://browser/content/places/places.xul chrome://browser/content/places/downloadsViewOverlay.xul
 # Provide another URI for the bookmarkProperties dialog so we can persist the
 # attributes separately
     content/browser/places/bookmarkProperties2.xul       (content/bookmarkProperties.xul)
 *   content/browser/places/places.xul                    (content/places.xul) 
-*   content/browser/places/places.js                     (content/places.js)
+    content/browser/places/places.js                     (content/places.js)
     content/browser/places/places.css                    (content/places.css)
     content/browser/places/organizer.css                 (content/organizer.css)
     content/browser/places/bookmarkProperties.xul        (content/bookmarkProperties.xul)
     content/browser/places/bookmarkProperties.js         (content/bookmarkProperties.js)
     content/browser/places/placesOverlay.xul             (content/placesOverlay.xul)
-*   content/browser/places/menu.xml                      (content/menu.xml)
+    content/browser/places/menu.xml                      (content/menu.xml)
     content/browser/places/tree.xml                      (content/tree.xml)
     content/browser/places/controller.js                 (content/controller.js)
     content/browser/places/treeView.js                   (content/treeView.js)
-*   content/browser/places/browserPlacesViews.js         (content/browserPlacesViews.js)
+    content/browser/places/browserPlacesViews.js         (content/browserPlacesViews.js)
 # keep the Places version of the history sidebar at history/history-panel.xul 
 # to prevent having to worry about between versions of the browser
 *   content/browser/history/history-panel.xul            (content/history-panel.xul) 
     content/browser/places/history-panel.js              (content/history-panel.js)
 # ditto for the bookmarks sidebar
     content/browser/bookmarks/bookmarksPanel.xul         (content/bookmarksPanel.xul)
     content/browser/bookmarks/bookmarksPanel.js          (content/bookmarksPanel.js)
-*   content/browser/bookmarks/sidebarUtils.js            (content/sidebarUtils.js)
+    content/browser/bookmarks/sidebarUtils.js            (content/sidebarUtils.js)
     content/browser/places/moveBookmarks.xul             (content/moveBookmarks.xul)
     content/browser/places/moveBookmarks.js              (content/moveBookmarks.js)
     content/browser/places/editBookmarkOverlay.xul       (content/editBookmarkOverlay.xul)
     content/browser/places/editBookmarkOverlay.js        (content/editBookmarkOverlay.js)
 *   content/browser/places/downloadsViewOverlay.xul      (content/downloadsViewOverlay.xul)
--- a/browser/components/places/moz.build
+++ b/browser/components/places/moz.build
@@ -5,14 +5,14 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
 MOCHITEST_CHROME_MANIFESTS += ['tests/chrome/chrome.ini']
 BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
 
 JAR_MANIFESTS += ['jar.mn']
 
-EXTRA_PP_JS_MODULES += [
+EXTRA_JS_MODULES += [
     'PlacesUIUtils.jsm',
 ]
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'Bookmarks & History')
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/content/constants.js
@@ -0,0 +1,7 @@
+/* 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";
+
+exports.UPDATE_EVENT_BREAKPOINTS = 'UPDATE_EVENT_BREAKPOINTS';
+exports.FETCH_EVENT_LISTENERS = 'FETCH_EVENT_LISTENERS';
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/content/globalActions.js
@@ -0,0 +1,9 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const constants = require('./constants');
+
+// No global actions right now, but I'm sure there will be soon.
+module.exports = {};
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/content/stores/event-listeners.js
@@ -0,0 +1,147 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const constants = require('../constants');
+const promise = require('promise');
+const { rdpInvoke, asPaused } = require('../utils');
+const { reportException } = require("devtools/toolkit/DevToolsUtils");
+
+const FETCH_EVENT_LISTENERS_DELAY = 200; // ms
+
+const initialState = {
+  activeEventNames: [],
+  listeners: [],
+  fetchingListeners: false,
+};
+
+function update(state = initialState, action, emitChange) {
+  switch(action.type) {
+  case constants.UPDATE_EVENT_BREAKPOINTS:
+    state.activeEventNames = action.eventNames;
+    emitChange('activeEventNames', state.activeEventNames);
+    break;
+  case constants.FETCH_EVENT_LISTENERS:
+    if (action.status === "begin") {
+      state.fetchingListeners = true;
+    }
+    else if (action.status === "done") {
+      state.fetchingListeners = false;
+      state.listeners = action.listeners;
+      emitChange('listeners', state.listeners);
+    }
+    break;
+  }
+
+  return state;
+};
+
+function fetchEventListeners() {
+  return (dispatch, getState) => {
+    // Make sure we're not sending a batch of closely repeated requests.
+    // This can easily happen whenever new sources are fetched.
+    setNamedTimeout("event-listeners-fetch", FETCH_EVENT_LISTENERS_DELAY, () => {
+      // In case there is still a request of listeners going on (it
+      // takes several RDP round trips right now), make sure we wait
+      // on a currently running request
+      if (getState().eventListeners.fetchingListeners) {
+        dispatch({
+          type: services.WAIT_UNTIL,
+          predicate: action => (
+            action.type === constants.FETCH_EVENT_LISTENERS &&
+            action.status === "done"
+          ),
+          run: dispatch => dispatch(fetchEventListeners())
+        });
+        return;
+      }
+
+      dispatch({
+        type: constants.FETCH_EVENT_LISTENERS,
+        status: "begin"
+      });
+
+      asPaused(gThreadClient, _getListeners).then(listeners => {
+        // Notify that event listeners were fetched and shown in the view,
+        // and callback to resume the active thread if necessary.
+        window.emit(EVENTS.EVENT_LISTENERS_FETCHED);
+
+        dispatch({
+          type: constants.FETCH_EVENT_LISTENERS,
+          status: "done",
+          listeners: listeners
+        });
+      });
+    });
+  };
+}
+
+const _getListeners = Task.async(function*() {
+  const response = yield rdpInvoke(gThreadClient, gThreadClient.eventListeners);
+
+  // Make sure all the listeners are sorted by the event type, since
+  // they're not guaranteed to be clustered together.
+  response.listeners.sort((a, b) => a.type > b.type ? 1 : -1);
+
+  // Add all the listeners in the debugger view event linsteners container.
+  let fetchedDefinitions = new Map();
+  let listeners = [];
+  for (let listener of response.listeners) {
+    let definitionSite;
+    if (fetchedDefinitions.has(listener.function.actor)) {
+      definitionSite = fetchedDefinitions.get(listener.function.actor);
+    } else if (listener.function.class == "Function") {
+      definitionSite = yield _getDefinitionSite(listener.function);
+      if (!definitionSite) {
+        // We don't know where this listener comes from so don't show it in
+        // the UI as breaking on it doesn't work (bug 942899).
+        continue;
+      }
+
+      fetchedDefinitions.set(listener.function.actor, definitionSite);
+    }
+    listener.function.url = definitionSite;
+    listeners.push(listener);
+  }
+  fetchedDefinitions.clear();
+
+  return listeners;
+});
+
+const _getDefinitionSite = Task.async(function*(aFunction) {
+  const grip = gThreadClient.pauseGrip(aFunction);
+  let response;
+
+  try {
+    response = yield rdpInvoke(grip, grip.getDefinitionSite);
+  }
+  catch(e) {
+    // Don't make this error fatal, because it would break the entire events pane.
+    reportException("_getDefinitionSite", e);
+    return null;
+  }
+
+  return response.source.url;
+});
+
+function updateEventBreakpoints(eventNames) {
+  return dispatch => {
+    setNamedTimeout("event-breakpoints-update", 0, () => {
+      gThreadClient.pauseOnDOMEvents(eventNames, function() {
+        // Notify that event breakpoints were added/removed on the server.
+        window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED);
+
+        dispatch({
+          type: constants.UPDATE_EVENT_BREAKPOINTS,
+          eventNames: eventNames
+        });
+      });
+    });
+  }
+}
+
+module.exports = {
+  update: update,
+  actions: { updateEventBreakpoints, fetchEventListeners }
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/content/stores/index.js
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const eventListeners = require('./event-listeners');
+
+module.exports = { eventListeners };
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/content/utils.js
@@ -0,0 +1,45 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const { promiseInvoke } = require("devtools/async-utils");
+const { reportException } = require("devtools/toolkit/DevToolsUtils");
+
+function rdpInvoke(client, method, ...args) {
+  return promiseInvoke(client, method, ...args)
+    .then((packet) => {
+      let { error, message } = packet;
+      if (error) {
+        throw new Error(error + ": " + message);
+      }
+
+      return packet;
+    });
+}
+
+function asPaused(client, func) {
+  if (client.state != "paused") {
+    return Task.spawn(function*() {
+      yield rdpInvoke(client, client.interrupt);
+      let result;
+
+      try {
+        result = yield func();
+      }
+      catch(e) {
+        // Try to put the debugger back in a working state by resuming
+        // it
+        yield rdpInvoke(client, client.resume);
+        throw e;
+      }
+
+      yield rdpInvoke(client, client.resume);
+      return result;
+    });
+  } else {
+    return func();
+  }
+}
+
+module.exports = { rdpInvoke, asPaused };
rename from browser/devtools/debugger/views/event-listeners-view.js
rename to browser/devtools/debugger/content/views/event-listeners-view.js
--- a/browser/devtools/debugger/views/event-listeners-view.js
+++ b/browser/devtools/debugger/content/views/event-listeners-view.js
@@ -1,21 +1,31 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
+const actions = require('../stores/event-listeners').actions;
+const bindActionCreators = require('devtools/shared/fluxify/bindActionCreators');
+
 /**
  * Functions handling the event listeners UI.
  */
-function EventListenersView(DebuggerController) {
+function EventListenersView(dispatcher, DebuggerController) {
   dumpn("EventListenersView was instantiated");
 
+  this.actions = bindActionCreators(actions, dispatcher.dispatch);
+  this.getState = () => dispatcher.getState().eventListeners;
+
   this.Breakpoints = DebuggerController.Breakpoints;
 
+  dispatcher.onChange({
+    "eventListeners": { "listeners": this.renderListeners }
+  }, this);
+
   this._onCheck = this._onCheck.bind(this);
   this._onClick = this._onClick.bind(this);
 }
 
 EventListenersView.prototype = Heritage.extend(WidgetMethods, {
   /**
    * Initialization function, called when the debugger is started.
    */
@@ -42,16 +52,25 @@ EventListenersView.prototype = Heritage.
    */
   destroy: function() {
     dumpn("Destroying the EventListenersView");
 
     this.widget.removeEventListener("check", this._onCheck, false);
     this.widget.removeEventListener("click", this._onClick, false);
   },
 
+  renderListeners: function(listeners) {
+    listeners.forEach(listener => {
+      this.addListener(listener, { staged: true });
+    });
+
+    // Flushes all the prepared events into the event listeners container.
+    this.commit();
+  },
+
   /**
    * Adds an event to this event listeners container.
    *
    * @param object aListener
    *        The listener object coming from the active thread.
    * @param object aOptions [optional]
    *        Additional options for adding the source. Supported options:
    *        - staged: true to stage the item to be appended later
@@ -137,22 +156,22 @@ EventListenersView.prototype = Heritage.
       group = L10N.getStr("timeEvents");
     } else if (starts("touch")) {
       group = L10N.getStr("touchEvents");
     } else {
       group = L10N.getStr("otherEvents");
     }
 
     // Create the element node for the event listener item.
-    let itemView = this._createItemView(type, selector, url);
+    const itemView = this._createItemView(type, selector, url);
 
     // Event breakpoints survive target navigations. Make sure the newly
     // inserted event item is correctly checked.
-    let checkboxState =
-      this.Breakpoints.DOM.activeEventNames.indexOf(type) != -1;
+    const activeEventNames = this.getState().activeEventNames;
+    const checkboxState = activeEventNames.indexOf(type) != -1;
 
     // Append an event listener item to this container.
     this.push([itemView.container], {
       staged: aOptions.staged, /* stage the item to be appended later? */
       attachment: {
         url: url,
         type: type,
         view: itemView,
@@ -236,17 +255,18 @@ EventListenersView.prototype = Heritage.
   },
 
   /**
    * The check listener for the event listeners container.
    */
   _onCheck: function({ detail: { description, checked }, target }) {
     if (description == "item") {
       this.getItemForElement(target).attachment.checkboxState = checked;
-      this.Breakpoints.DOM.scheduleEventBreakpointsUpdate();
+
+      this.actions.updateEventBreakpoints(this.getCheckedEvents());
       return;
     }
 
     // Check all the event items in this group.
     this.items
       .filter(e => e.attachment.group == description)
       .forEach(e => this.callMethod("checkItem", e.target, checked));
   },
@@ -266,9 +286,9 @@ EventListenersView.prototype = Heritage.
   },
 
   _eventCheckboxTooltip: "",
   _onSelectorString: "",
   _inSourceString: "",
   _inNativeCodeString: ""
 });
 
-DebuggerView.EventListeners = new EventListenersView(DebuggerController);
+module.exports = EventListenersView;
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -6,17 +6,16 @@
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
 const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "XStringBundle"];
 const NEW_SOURCE_DISPLAY_DELAY = 200; // ms
 const FETCH_SOURCE_RESPONSE_DELAY = 200; // ms
-const FETCH_EVENT_LISTENERS_DELAY = 200; // ms
 const FRAME_STEP_CLEAR_DELAY = 100; // ms
 const CALL_STACK_PAGE_SIZE = 25; // frames
 
 // The panel's window global is an EventEmitter firing the following events:
 const EVENTS = {
   // When the debugger's source editor instance finishes loading or unloading.
   EDITOR_LOADED: "Debugger:EditorLoaded",
   EDITOR_UNLOADED: "Debugger:EditorUnoaded",
@@ -98,19 +97,21 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/devtools/event-emitter.js");
 Cu.import("resource:///modules/devtools/SimpleListWidget.jsm");
 Cu.import("resource:///modules/devtools/BreadcrumbsWidget.jsm");
 Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/VariablesView.jsm");
 Cu.import("resource:///modules/devtools/VariablesViewController.jsm");
 Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
 
-const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+Cu.import("resource:///modules/devtools/shared/browser-loader.js");
+const require = BrowserLoader("resource:///modules/devtools/debugger/", this).require;
+
 const {TargetFactory} = require("devtools/framework/target");
-const {Toolbox} = require("devtools/framework/toolbox")
+const {Toolbox} = require("devtools/framework/toolbox");
 const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
 const promise = require("devtools/toolkit/deprecated-sync-thenables");
 const Editor = require("devtools/sourceeditor/editor");
 const DebuggerEditor = require("devtools/sourceeditor/debugger.js");
 const {Tooltip} = require("devtools/shared/widgets/Tooltip");
 const FastListWidget = require("devtools/shared/widgets/FastListWidget");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
@@ -315,17 +316,19 @@ let DebuggerController = {
       }
       this.activeThread = aThreadClient;
       this.Workers.connect();
       this.ThreadState.connect();
       this.StackFrames.connect();
       this.SourceScripts.connect();
 
       if (aThreadClient.paused) {
-        aThreadClient.resume(this._ensureResumptionOrder);
+        aThreadClient.resume(res => {
+          this._ensureResumptionOrder(res)
+        });
       }
 
       deferred.resolve();
     });
 
     return deferred.promise;
   },
 
@@ -1269,17 +1272,17 @@ SourceScripts.prototype = {
 
     // If there are any stored breakpoints for this source, display them again,
     // both in the editor and the breakpoints pane.
     DebuggerController.Breakpoints.updatePaneBreakpoints();
     DebuggerController.Breakpoints.updateEditorBreakpoints();
 
     // Make sure the events listeners are up to date.
     if (DebuggerView.instrumentsPaneTab == "events-tab") {
-      DebuggerController.Breakpoints.DOM.scheduleEventListenersFetch();
+      dispatcher.dispatch(actions.fetchEventListeners());
     }
 
     // Signal that a new source has been added.
     window.emit(EVENTS.NEW_SOURCE);
   },
 
   /**
    * Callback for the debugger's active thread getSources() method.
@@ -1530,161 +1533,16 @@ SourceScripts.prototype = {
       }
     }
 
     return deferred.promise;
   }
 };
 
 /**
- * Handles breaking on event listeners in the currently debugged target.
- */
-function EventListeners() {
-}
-
-EventListeners.prototype = {
-  /**
-   * A list of event names on which the debuggee will automatically pause
-   * when invoked.
-   */
-  activeEventNames: [],
-
-  /**
-   * Updates the list of events types with listeners that, when invoked,
-   * will automatically pause the debuggee. The respective events are
-   * retrieved from the UI.
-   */
-  scheduleEventBreakpointsUpdate: function() {
-    // Make sure we're not sending a batch of closely repeated requests.
-    // This can easily happen when toggling all events of a certain type.
-    setNamedTimeout("event-breakpoints-update", 0, () => {
-      this.activeEventNames = DebuggerView.EventListeners.getCheckedEvents();
-      gThreadClient.pauseOnDOMEvents(this.activeEventNames);
-
-      // Notify that event breakpoints were added/removed on the server.
-      window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED);
-    });
-  },
-
-  /**
-   * Schedules fetching the currently attached event listeners from the debugee.
-   */
-  scheduleEventListenersFetch: function() {
-    // Make sure we're not sending a batch of closely repeated requests.
-    // This can easily happen whenever new sources are fetched.
-    setNamedTimeout("event-listeners-fetch", FETCH_EVENT_LISTENERS_DELAY, () => {
-      if (gThreadClient.state != "paused") {
-        gThreadClient.interrupt(() => this._getListeners(() => gThreadClient.resume()));
-      } else {
-        this._getListeners();
-      }
-    });
-  },
-
-  /**
-   * A semaphore that is used to ensure only a single protocol request for event
-   * listeners will be ongoing at any given time.
-   */
-  _parsingListeners: false,
-
-  /**
-   * A flag the indicates whether a new request to fetch updated event listeners
-   * has arrived, while another one was in progress.
-   */
-  _eventListenersUpdateNeeded: false,
-
-  /**
-   * Fetches the currently attached event listeners from the debugee.
-   * The thread client state is assumed to be "paused".
-   *
-   * @param function aCallback
-   *        Invoked once the event listeners are fetched and displayed.
-   */
-  _getListeners: function(aCallback) {
-    // Don't make a new request if one is still ongoing, but schedule one for
-    // later.
-    if (this._parsingListeners) {
-      this._eventListenersUpdateNeeded = true;
-      return;
-    }
-    this._parsingListeners = true;
-    gThreadClient.eventListeners(Task.async(function*(aResponse) {
-      if (aResponse.error) {
-        throw "Error getting event listeners: " + aResponse.message;
-      }
-
-      // Make sure all the listeners are sorted by the event type, since
-      // they're not guaranteed to be clustered together.
-      aResponse.listeners.sort((a, b) => a.type > b.type ? 1 : -1);
-
-      // Add all the listeners in the debugger view event linsteners container.
-      let fetchedDefinitions = new Map();
-      for (let listener of aResponse.listeners) {
-        let definitionSite;
-        if (fetchedDefinitions.has(listener.function.actor)) {
-          definitionSite = fetchedDefinitions.get(listener.function.actor);
-        } else if (listener.function.class == "Function") {
-          definitionSite = yield this._getDefinitionSite(listener.function);
-          if (!definitionSite) {
-            // We don't know where this listener comes from so don't show it in
-            // the UI as breaking on it doesn't work (bug 942899).
-            continue;
-          }
-
-          fetchedDefinitions.set(listener.function.actor, definitionSite);
-        }
-        listener.function.url = definitionSite;
-        DebuggerView.EventListeners.addListener(listener, { staged: true });
-      }
-      fetchedDefinitions.clear();
-
-      // Flushes all the prepared events into the event listeners container.
-      DebuggerView.EventListeners.commit();
-
-      // Now that we are done, schedule a new update if necessary.
-      this._parsingListeners = false;
-      if (this._eventListenersUpdateNeeded) {
-        this._eventListenersUpdateNeeded = false;
-        this.scheduleEventListenersFetch();
-      }
-
-      // Notify that event listeners were fetched and shown in the view,
-      // and callback to resume the active thread if necessary.
-      window.emit(EVENTS.EVENT_LISTENERS_FETCHED);
-      aCallback && aCallback();
-    }.bind(this)));
-  },
-
-  /**
-   * Gets a function's source-mapped definiton site.
-   *
-   * @param object aFunction
-   *        The grip of the function to get the definition site for.
-   * @return object
-   *         A promise that is resolved with the function's owner source url.
-   */
-  _getDefinitionSite: function(aFunction) {
-    let deferred = promise.defer();
-
-    gThreadClient.pauseGrip(aFunction).getDefinitionSite(aResponse => {
-      if (aResponse.error) {
-        // Don't make this error fatal, because it would break the entire events pane.
-        const msg = "Error getting function definition site: " + aResponse.message;
-        DevToolsUtils.reportException("_getDefinitionSite", msg);
-        deferred.resolve(null);
-      } else {
-        deferred.resolve(aResponse.source.url);
-      }
-    });
-
-    return deferred.promise;
-  }
-};
-
-/**
  * Handles all the breakpoints in the current debugger.
  */
 function Breakpoints() {
   this._onEditorBreakpointAdd = this._onEditorBreakpointAdd.bind(this);
   this._onEditorBreakpointRemove = this._onEditorBreakpointRemove.bind(this);
   this.addBreakpoint = this.addBreakpoint.bind(this);
   this.removeBreakpoint = this.removeBreakpoint.bind(this);
 }
@@ -2200,17 +2058,16 @@ EventEmitter.decorate(this);
  */
 DebuggerController.initialize();
 DebuggerController.Parser = new Parser();
 DebuggerController.Workers = new Workers();
 DebuggerController.ThreadState = new ThreadState();
 DebuggerController.StackFrames = new StackFrames();
 DebuggerController.SourceScripts = new SourceScripts();
 DebuggerController.Breakpoints = new Breakpoints();
-DebuggerController.Breakpoints.DOM = new EventListeners();
 
 /**
  * Export some properties to the global scope for easier access.
  */
 Object.defineProperties(window, {
   "gTarget": {
     get: function() {
       return DebuggerController._target;
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -28,16 +28,27 @@ const SEARCH_LINE_FLAG = ":";
 const SEARCH_VARIABLE_FLAG = "*";
 const SEARCH_AUTOFILL = [SEARCH_GLOBAL_FLAG, SEARCH_FUNCTION_FLAG, SEARCH_TOKEN_FLAG];
 const EDITOR_VARIABLE_HOVER_DELAY = 750; // ms
 const EDITOR_VARIABLE_POPUP_POSITION = "topcenter bottomleft";
 const TOOLBAR_ORDER_POPUP_POSITION = "topcenter bottomleft";
 const PROMISE_DEBUGGER_URL =
   "chrome://browser/content/devtools/promisedebugger/promise-debugger.xhtml";
 
+const createDispatcher = require('devtools/shared/create-dispatcher')();
+const stores = require('./content/stores/index');
+const dispatcher = createDispatcher(stores);
+const waitUntilService = require('devtools/shared/fluxify/waitUntilService');
+const services = {
+  WAIT_UNTIL: waitUntilService.name
+};
+
+const EventListenersView = require('./content/views/event-listeners-view');
+const actions = require('./content/stores/event-listeners').actions;
+
 /**
  * Object defining the debugger view components.
  */
 let DebuggerView = {
   /**
    * Initializes the debugger view.
    *
    * @return object
@@ -593,17 +604,17 @@ let DebuggerView = {
     }, 0);
   },
 
   /**
    * Handles a tab selection event on the instruments pane.
    */
   _onInstrumentsPaneTabSelect: function() {
     if (this._instrumentsPane.selectedTab.id == "events-tab") {
-      DebuggerController.Breakpoints.DOM.scheduleEventListenersFetch();
+      dispatcher.dispatch(actions.fetchEventListeners());
     }
   },
 
   /**
    * Handles a host change event issued by the parent toolbox.
    *
    * @param string aType
    *        The host type, either "bottom", "side" or "window".
@@ -854,8 +865,10 @@ ResultsPanelContainer.prototype = Herita
   },
 
   _anchor: null,
   _panel: null,
   position: RESULTS_PANEL_POPUP_POSITION,
   left: 0,
   top: 0
 });
+
+DebuggerView.EventListeners = new EventListenersView(dispatcher, DebuggerController);
--- a/browser/devtools/debugger/moz.build
+++ b/browser/devtools/debugger/moz.build
@@ -3,9 +3,24 @@
 # 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/.
 
 EXTRA_JS_MODULES.devtools.debugger += [
     'debugger-commands.js',
     'panel.js'
 ]
 
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
+EXTRA_JS_MODULES.devtools.debugger.content += [
+    'content/constants.js',
+    'content/globalActions.js',
+    'content/utils.js'
+]
+
+EXTRA_JS_MODULES.devtools.debugger.content.views += [
+    'content/views/event-listeners-view.js'
+]
+
+EXTRA_JS_MODULES.devtools.debugger.content.stores += [
+    'content/stores/event-listeners.js',
+    'content/stores/index.js'
+]
+
+BROWSER_CHROME_MANIFESTS += ['test/mochitest/browser.ini']
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon3/lib/main.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon3/lib/main.js
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon3/package.json
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon3/package.json
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/bootstrap.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/chrome.manifest
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/chrome.manifest
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/install.rdf
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/install.rdf
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test.jsm
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.jsm
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test.xul
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.xul
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test2.jsm
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/test2.jsm
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/test2.xul
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/test2.xul
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/testxul.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/testxul.js
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon4/testxul2.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon4/testxul2.js
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/bootstrap.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/chrome.manifest
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/chrome.manifest
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/install.rdf
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/install.rdf
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test.jsm
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/test.jsm
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test.xul
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/test.xul
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test2.jsm
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/test2.jsm
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/test2.xul
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/test2.xul
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/testxul.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/testxul.js
rename from browser/devtools/debugger/test/addon-source/browser_dbg_addon5/testxul2.js
rename to browser/devtools/debugger/test/mochitest/addon-source/browser_dbg_addon5/testxul2.js
rename from browser/devtools/debugger/test/addon1.xpi
rename to browser/devtools/debugger/test/mochitest/addon1.xpi
rename from browser/devtools/debugger/test/addon2.xpi
rename to browser/devtools/debugger/test/mochitest/addon2.xpi
rename from browser/devtools/debugger/test/addon3.xpi
rename to browser/devtools/debugger/test/mochitest/addon3.xpi
rename from browser/devtools/debugger/test/addon4.xpi
rename to browser/devtools/debugger/test/mochitest/addon4.xpi
rename from browser/devtools/debugger/test/addon5.xpi
rename to browser/devtools/debugger/test/mochitest/addon5.xpi
rename from browser/devtools/debugger/test/browser.ini
rename to browser/devtools/debugger/test/mochitest/browser.ini
rename from browser/devtools/debugger/test/browser_dbg_WorkerActor.attach.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_WorkerActor.attach.js
rename from browser/devtools/debugger/test/browser_dbg_WorkerActor.attachThread.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_WorkerActor.attachThread.js
rename from browser/devtools/debugger/test/browser_dbg_aaa_run_first_leaktest.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_aaa_run_first_leaktest.js
rename from browser/devtools/debugger/test/browser_dbg_addon-console.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_addon-console.js
rename from browser/devtools/debugger/test/browser_dbg_addon-modules-unpacked.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_addon-modules-unpacked.js
rename from browser/devtools/debugger/test/browser_dbg_addon-modules.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_addon-modules.js
rename from browser/devtools/debugger/test/browser_dbg_addon-panels.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_addon-panels.js
rename from browser/devtools/debugger/test/browser_dbg_addon-sources.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_addon-sources.js
rename from browser/devtools/debugger/test/browser_dbg_addonactor.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_addonactor.js
rename from browser/devtools/debugger/test/browser_dbg_auto-pretty-print-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_auto-pretty-print-01.js
rename from browser/devtools/debugger/test/browser_dbg_auto-pretty-print-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_auto-pretty-print-02.js
rename from browser/devtools/debugger/test/browser_dbg_bfcache.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_bfcache.js
rename from browser/devtools/debugger/test/browser_dbg_blackboxing-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_blackboxing-01.js
rename from browser/devtools/debugger/test/browser_dbg_blackboxing-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_blackboxing-02.js
rename from browser/devtools/debugger/test/browser_dbg_blackboxing-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_blackboxing-03.js
rename from browser/devtools/debugger/test/browser_dbg_blackboxing-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_blackboxing-04.js
rename from browser/devtools/debugger/test/browser_dbg_blackboxing-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_blackboxing-05.js
rename from browser/devtools/debugger/test/browser_dbg_blackboxing-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_blackboxing-06.js
rename from browser/devtools/debugger/test/browser_dbg_breadcrumbs-access.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breadcrumbs-access.js
rename from browser/devtools/debugger/test/browser_dbg_break-in-anon.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-in-anon.js
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-01.js
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-02.js
--- a/browser/devtools/debugger/test/browser_dbg_break-on-dom-02.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-02.js
@@ -8,28 +8,30 @@
 
 const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let gDebugger = aPanel.panelWin;
     let gView = gDebugger.DebuggerView;
     let gEvents = gView.EventListeners;
+    let gDispatcher = gDebugger.dispatcher;
+    let constants = gDebugger.require('./content/constants');
 
     Task.spawn(function*() {
       yield waitForSourceShown(aPanel, ".html");
       yield testFetchOnFocus();
       yield testFetchOnReloadWhenFocused();
       yield testFetchOnReloadWhenNotFocused();
       yield closeDebuggerAndFinish(aPanel);
     });
 
     function testFetchOnFocus() {
       return Task.spawn(function*() {
-        let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+        let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
 
         gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
         is(gView.instrumentsPaneHidden, false,
           "The instruments pane should be visible now.");
         is(gView.instrumentsPaneTab, "events-tab",
           "The events tab should be selected.");
 
         yield fetched;
@@ -38,17 +40,17 @@ function test() {
           "Event listeners were fetched when the events tab was selected");
         is(gEvents.itemCount, 4,
           "There should be 4 events displayed in the view.");
       });
     }
 
     function testFetchOnReloadWhenFocused() {
       return Task.spawn(function*() {
-        let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+        let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
 
         let reloading = once(gDebugger.gTarget, "will-navigate");
         let reloaded = waitForSourcesAfterReload();
         gDebugger.DebuggerController._target.activeTab.reload();
 
         yield reloading;
 
         is(gEvents.itemCount, 0,
@@ -69,21 +71,30 @@ function test() {
           "There should be 4 events displayed in the view after reloading.");
         ok(true,
           "Event listeners were added back after the target finished navigating.");
       });
     }
 
     function testFetchOnReloadWhenNotFocused() {
       return Task.spawn(function*() {
-        gDebugger.on(gDebugger.EVENTS.EVENT_LISTENERS_FETCHED, () => {
-          ok(false, "Shouldn't have fetched any event listeners.");
-        });
-        gDebugger.on(gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED, () => {
-          ok(false, "Shouldn't have updated any event breakpoints.");
+        gDispatcher.dispatch({
+          type: gDebugger.services.WAIT_UNTIL,
+          predicate: action => {
+            return (action.type === constants.FETCH_EVENT_LISTENERS ||
+                    action.type === constants.UPDATE_EVENT_BREAKPOINTS);
+          },
+          run: (dispatch, getState, action) => {
+            if(action.type === constants.FETCH_EVENT_LISTENERS) {
+              ok(false, "Shouldn't have fetched any event listeners.");
+            }
+            else if(action.type === constants.UPDATE_EVENT_BREAKPOINTS) {
+              ok(false, "Shouldn't have updated any event breakpoints.");
+            }
+          }
         });
 
         gView.toggleInstrumentsPane({ visible: true, animated: false }, 0);
         is(gView.instrumentsPaneHidden, false,
           "The instruments pane should still be visible.");
         is(gView.instrumentsPaneTab, "variables-tab",
           "The variables tab should be selected.");
 
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-03.js
--- a/browser/devtools/debugger/test/browser_dbg_break-on-dom-03.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-03.js
@@ -7,21 +7,23 @@
 
 const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let gDebugger = aPanel.panelWin;
     let gView = gDebugger.DebuggerView;
     let gEvents = gView.EventListeners;
+    let gDispatcher = gDebugger.dispatcher;
+    let constants = gDebugger.require('./content/constants');
 
     Task.spawn(function*() {
       yield waitForSourceShown(aPanel, ".html");
 
-      let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
       gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
       yield fetched;
 
       is(gEvents.widget._parent.querySelectorAll(".side-menu-widget-group").length, 3,
         "There should be 3 groups shown in the view.");
       is(gEvents.widget._parent.querySelectorAll(".side-menu-widget-group-checkbox").length, 3,
         "There should be a checkbox for each group shown in the view.");
 
@@ -39,17 +41,17 @@ function test() {
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
 
       is(gEvents.getAllEvents().toString(), "change,click,keydown,keyup",
         "The getAllEvents() method returns the correct stuff.");
       is(gEvents.getCheckedEvents().toString(), "",
         "The getCheckedEvents() method returns the correct stuff.");
 
-      yield ensureThreadClientState(aPanel, "resumed");
+      yield ensureThreadClientState(aPanel, "attached");
       yield closeDebuggerAndFinish(aPanel);
     });
 
     function testEventItem(index, label, type, selectors, checked) {
       let item = gEvents.items[index];
       let node = item.target;
 
       ok(item.attachment.url.includes(label),
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-04.js
--- a/browser/devtools/debugger/test/browser_dbg_break-on-dom-04.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-04.js
@@ -9,61 +9,63 @@
 const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let gDebugger = aPanel.panelWin;
     let gView = gDebugger.DebuggerView;
     let gController = gDebugger.DebuggerController
     let gEvents = gView.EventListeners;
-    let gBreakpoints = gController.Breakpoints;
+    let gDispatcher = gDebugger.dispatcher;
+    let getState = gDispatcher.getState;
+    let constants = gDebugger.require('./content/constants');
 
     Task.spawn(function*() {
       yield waitForSourceShown(aPanel, ".html");
 
-      let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
       gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
       yield fetched;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      let updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      let updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
       yield updated;
 
       testEventItem(0, true);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "change");
 
-      updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
       yield updated;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      yield ensureThreadClientState(aPanel, "resumed");
+      yield ensureThreadClientState(aPanel, "attached");
       yield closeDebuggerAndFinish(aPanel);
     });
 
     function getItemCheckboxNode(index) {
       return gEvents.items[index].target.parentNode
         .querySelector(".side-menu-widget-item-checkbox");
     }
 
@@ -85,13 +87,13 @@ function test() {
         "The correct checkbox state is shown for the group " + string + ".");
     }
 
     function testEventArrays(all, checked) {
       is(gEvents.getAllEvents().toString(), all,
         "The getAllEvents() method returns the correct stuff.");
       is(gEvents.getCheckedEvents().toString(), checked,
         "The getCheckedEvents() method returns the correct stuff.");
-      is(gBreakpoints.DOM.activeEventNames.toString(), checked,
+      is(getState().eventListeners.activeEventNames.toString(), checked,
         "The correct event names are listed as being active breakpoints.");
     }
   });
 }
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-05.js
--- a/browser/devtools/debugger/test/browser_dbg_break-on-dom-05.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-05.js
@@ -10,87 +10,89 @@
 const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let gDebugger = aPanel.panelWin;
     let gView = gDebugger.DebuggerView;
     let gController = gDebugger.DebuggerController
     let gEvents = gView.EventListeners;
-    let gBreakpoints = gController.Breakpoints;
+    let gDispatcher = gDebugger.dispatcher;
+    let getState = gDispatcher.getState;
+    let constants = gDebugger.require('./content/constants');
 
     Task.spawn(function*() {
       yield waitForSourceShown(aPanel, ".html");
 
-      let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
       gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
       yield fetched;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      let updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      let updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("interactionEvents"), gDebugger);
       yield updated;
 
       testEventItem(0, true);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", true);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "change");
 
-      updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("interactionEvents"), gDebugger);
       yield updated;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("keyboardEvents"), gDebugger);
       yield updated;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, true);
       testEventItem(3, true);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", true);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "keydown,keyup");
 
-      updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("keyboardEvents"), gDebugger);
       yield updated;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      yield ensureThreadClientState(aPanel, "resumed");
+      yield ensureThreadClientState(aPanel, "attached");
       yield closeDebuggerAndFinish(aPanel);
     });
 
     function getItemCheckboxNode(index) {
       return gEvents.items[index].target.parentNode
         .querySelector(".side-menu-widget-item-checkbox");
     }
 
@@ -112,13 +114,13 @@ function test() {
         "The correct checkbox state is shown for the group " + string + ".");
     }
 
     function testEventArrays(all, checked) {
       is(gEvents.getAllEvents().toString(), all,
         "The getAllEvents() method returns the correct stuff.");
       is(gEvents.getCheckedEvents().toString(), checked,
         "The getCheckedEvents() method returns the correct stuff.");
-      is(gBreakpoints.DOM.activeEventNames.toString(), checked,
+      is(getState().eventListeners.activeEventNames.toString(), checked,
         "The correct event names are listed as being active breakpoints.");
     }
   });
 }
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-06.js
--- a/browser/devtools/debugger/test/browser_dbg_break-on-dom-06.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-06.js
@@ -10,86 +10,91 @@ const TAB_URL = EXAMPLE_URL + "doc_event
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let gDebugger = aPanel.panelWin;
     let gView = gDebugger.DebuggerView;
     let gController = gDebugger.DebuggerController
     let gEvents = gView.EventListeners;
     let gBreakpoints = gController.Breakpoints;
+    let gDispatcher = gDebugger.dispatcher;
+    let getState = gDispatcher.getState;
+    let constants = gDebugger.require('./content/constants');
 
     Task.spawn(function*() {
       yield waitForSourceShown(aPanel, ".html");
 
-      let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
       gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
       yield fetched;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      let updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      let updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(2), gDebugger);
       yield updated;
 
       testEventItem(0, true);
       testEventItem(1, true);
       testEventItem(2, true);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "change,click,keydown");
 
-      yield reloadActiveTab(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      reload(aPanel);
+      yield afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
 
       testEventItem(0, true);
       testEventItem(1, true);
       testEventItem(2, true);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "change,click,keydown");
 
-      updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(2), gDebugger);
       yield updated;
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      yield reloadActiveTab(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      reload(aPanel);
+      yield afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
 
       testEventItem(0, false);
       testEventItem(1, false);
       testEventItem(2, false);
       testEventItem(3, false);
       testEventGroup("interactionEvents", false);
       testEventGroup("keyboardEvents", false);
       testEventGroup("mouseEvents", false);
       testEventArrays("change,click,keydown,keyup", "");
 
-      yield ensureThreadClientState(aPanel, "resumed");
+      yield ensureThreadClientState(aPanel, "attached");
       yield closeDebuggerAndFinish(aPanel);
     });
 
     function getItemCheckboxNode(index) {
       return gEvents.items[index].target.parentNode
         .querySelector(".side-menu-widget-item-checkbox");
     }
 
@@ -110,14 +115,14 @@ function test() {
       is(getGroupCheckboxNode(string).checked, checked,
         "The correct checkbox state is shown for the group " + string + ".");
     }
 
     function testEventArrays(all, checked) {
       is(gEvents.getAllEvents().toString(), all,
         "The getAllEvents() method returns the correct stuff.");
       is(gEvents.getCheckedEvents().toString(), checked,
-        "The getCheckedEvents() method returns the correct stuff.");
-      is(gBreakpoints.DOM.activeEventNames.toString(), checked,
-        "The correct event names are listed as being active breakpoints.");
+         "The getCheckedEvents() method returns the correct stuff.");
+      is(getState().eventListeners.activeEventNames.toString(), checked,
+         "The correct event names are listed as being active breakpoints.");
     }
   });
 }
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-07.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-07.js
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-08.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-08.js
--- a/browser/devtools/debugger/test/browser_dbg_break-on-dom-08.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-08.js
@@ -8,35 +8,38 @@
 const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let gTab = aTab;
     let gDebugger = aPanel.panelWin;
     let gView = gDebugger.DebuggerView;
     let gEvents = gView.EventListeners;
+    let gDispatcher = gDebugger.dispatcher;
+    let getState = gDispatcher.getState;
+    let constants = gDebugger.require('./content/constants');
 
     Task.spawn(function*() {
       yield waitForSourceShown(aPanel, ".html");
       yield callInTab(gTab, "addBodyClickEventListener");
 
-      let fetched = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+      let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
       gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
       yield fetched;
-      yield ensureThreadClientState(aPanel, "resumed");
+      yield ensureThreadClientState(aPanel, "attached");
 
       is(gView.instrumentsPaneHidden, false,
         "The instruments pane should be visible.");
       is(gView.instrumentsPaneTab, "events-tab",
         "The events tab should be selected.");
 
-      let updated = waitForDebuggerEvents(aPanel, gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED);
+      let updated = afterDispatch(gDispatcher, constants.UPDATE_EVENT_BREAKPOINTS);
       EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
       yield updated;
-      yield ensureThreadClientState(aPanel, "resumed");
+      yield ensureThreadClientState(aPanel, "attached");
 
       let paused = waitForCaretAndScopes(aPanel, 48);
       generateMouseClickInTab(gTab, "content.document.body");
       yield paused;
       yield ensureThreadClientState(aPanel, "paused");
 
       is(gView.instrumentsPaneHidden, false,
         "The instruments pane should be visible.");
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-event-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-event-01.js
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-event-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-event-02.js
rename from browser/devtools/debugger/test/browser_dbg_break-on-dom-event-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_break-on-dom-event-03.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-actual-location.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location2.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-actual-location2.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-button-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-button-01.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-button-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-button-02.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-condition-thrown-message.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-condition-thrown-message.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu-add.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-contextmenu-add.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-contextmenu.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-disabled-reload.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-disabled-reload.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-editor.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-eval.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-eval.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-highlight.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-highlight.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-new-script.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-new-script.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-other-tabs.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-other-tabs.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-pane.js
rename from browser/devtools/debugger/test/browser_dbg_breakpoints-reload.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_breakpoints-reload.js
rename from browser/devtools/debugger/test/browser_dbg_bug-896139.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_bug-896139.js
rename from browser/devtools/debugger/test/browser_dbg_chrome-create.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_chrome-create.js
rename from browser/devtools/debugger/test/browser_dbg_chrome-debugging.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_chrome-debugging.js
rename from browser/devtools/debugger/test/browser_dbg_clean-exit-window.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_clean-exit-window.js
rename from browser/devtools/debugger/test/browser_dbg_clean-exit.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_clean-exit.js
rename from browser/devtools/debugger/test/browser_dbg_closure-inspection.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_closure-inspection.js
rename from browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_cmd-blackbox.js
rename from browser/devtools/debugger/test/browser_dbg_cmd-break.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_cmd-break.js
rename from browser/devtools/debugger/test/browser_dbg_cmd-dbg.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_cmd-dbg.js
rename from browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_conditional-breakpoints-01.js
rename from browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_conditional-breakpoints-02.js
rename from browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_conditional-breakpoints-03.js
rename from browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_conditional-breakpoints-04.js
rename from browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_conditional-breakpoints-05.js
rename from browser/devtools/debugger/test/browser_dbg_console-eval.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_console-eval.js
rename from browser/devtools/debugger/test/browser_dbg_console-named-eval.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_console-named-eval.js
rename from browser/devtools/debugger/test/browser_dbg_controller-evaluate-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_controller-evaluate-01.js
rename from browser/devtools/debugger/test/browser_dbg_controller-evaluate-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_controller-evaluate-02.js
rename from browser/devtools/debugger/test/browser_dbg_debugger-statement.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_debugger-statement.js
rename from browser/devtools/debugger/test/browser_dbg_editor-contextmenu.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_editor-contextmenu.js
rename from browser/devtools/debugger/test/browser_dbg_editor-mode.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_editor-mode.js
rename from browser/devtools/debugger/test/browser_dbg_event-listeners-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_event-listeners-01.js
rename from browser/devtools/debugger/test/browser_dbg_event-listeners-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_event-listeners-02.js
rename from browser/devtools/debugger/test/browser_dbg_event-listeners-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_event-listeners-03.js
rename from browser/devtools/debugger/test/browser_dbg_event-listeners-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_event-listeners-04.js
--- a/browser/devtools/debugger/test/browser_dbg_event-listeners-04.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_event-listeners-04.js
@@ -26,18 +26,21 @@ add_task(function* () {
   info("Attaching an event handler via add-on sdk content scripts.");
   let worker = sdkTab.attach({
     contentScript: "document.body.addEventListener('click', e => alert(e))",
     onError: ok.bind(this, false)
   });
 
   let [,, panel, win] = yield initDebugger(tab);
   let gDebugger = panel.panelWin;
-  let fetched = waitForDebuggerEvents(panel, gDebugger.EVENTS.EVENT_LISTENERS_FETCHED);
+  let gDispatcher = gDebugger.dispatcher;
+  let constants = gDebugger.require('./content/constants');
+  let eventListeners = gDebugger.require('./content/stores/event-listeners');
+  let fetched = afterDispatch(gDispatcher, constants.FETCH_EVENT_LISTENERS);
 
   info("Scheduling event listener fetch.");
-  gDebugger.DebuggerController.Breakpoints.DOM.scheduleEventListenersFetch();
+  gDispatcher.dispatch(eventListeners.actions.fetchEventListeners());
 
   info("Waiting for updated event listeners to arrive.");
   yield fetched;
 
   ok(true, "The listener update did not hang.");
 });
rename from browser/devtools/debugger/test/browser_dbg_file-reload.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_file-reload.js
rename from browser/devtools/debugger/test/browser_dbg_function-display-name.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_function-display-name.js
rename from browser/devtools/debugger/test/browser_dbg_global-method-override.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_global-method-override.js
rename from browser/devtools/debugger/test/browser_dbg_globalactor.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_globalactor.js
--- a/browser/devtools/debugger/test/browser_dbg_globalactor.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_globalactor.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Check extension-added global actor API.
  */
 
-const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/"
+const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/mochitest/"
 const ACTORS_URL = CHROME_URL + "testactors.js";
 
 function test() {
   let gClient;
 
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
     DebuggerServer.addBrowserActors();
rename from browser/devtools/debugger/test/browser_dbg_hide-toolbar-buttons.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_hide-toolbar-buttons.js
rename from browser/devtools/debugger/test/browser_dbg_host-layout.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_host-layout.js
rename from browser/devtools/debugger/test/browser_dbg_iframes.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_iframes.js
rename from browser/devtools/debugger/test/browser_dbg_instruments-pane-collapse.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_instruments-pane-collapse.js
rename from browser/devtools/debugger/test/browser_dbg_interrupts.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_interrupts.js
rename from browser/devtools/debugger/test/browser_dbg_listaddons.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_listaddons.js
rename from browser/devtools/debugger/test/browser_dbg_listtabs-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_listtabs-01.js
rename from browser/devtools/debugger/test/browser_dbg_listtabs-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_listtabs-02.js
rename from browser/devtools/debugger/test/browser_dbg_listtabs-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_listtabs-03.js
rename from browser/devtools/debugger/test/browser_dbg_listworkers.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_listworkers.js
rename from browser/devtools/debugger/test/browser_dbg_location-changes-01-simple.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_location-changes-01-simple.js
rename from browser/devtools/debugger/test/browser_dbg_location-changes-02-blank.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_location-changes-02-blank.js
rename from browser/devtools/debugger/test/browser_dbg_location-changes-03-new.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_location-changes-03-new.js
rename from browser/devtools/debugger/test/browser_dbg_location-changes-04-breakpoint.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_location-changes-04-breakpoint.js
rename from browser/devtools/debugger/test/browser_dbg_multiple-windows.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_multiple-windows.js
rename from browser/devtools/debugger/test/browser_dbg_navigation.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_navigation.js
rename from browser/devtools/debugger/test/browser_dbg_no-page-sources.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_no-page-sources.js
rename from browser/devtools/debugger/test/browser_dbg_on-pause-highlight.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-highlight.js
rename from browser/devtools/debugger/test/browser_dbg_on-pause-raise.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-raise.js
rename from browser/devtools/debugger/test/browser_dbg_optimized-out-vars.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_optimized-out-vars.js
rename from browser/devtools/debugger/test/browser_dbg_panel-size.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_panel-size.js
rename from browser/devtools/debugger/test/browser_dbg_parser-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-01.js
rename from browser/devtools/debugger/test/browser_dbg_parser-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-02.js
rename from browser/devtools/debugger/test/browser_dbg_parser-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-03.js
rename from browser/devtools/debugger/test/browser_dbg_parser-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-04.js
rename from browser/devtools/debugger/test/browser_dbg_parser-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-05.js
rename from browser/devtools/debugger/test/browser_dbg_parser-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-06.js
rename from browser/devtools/debugger/test/browser_dbg_parser-07.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-07.js
rename from browser/devtools/debugger/test/browser_dbg_parser-08.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-08.js
rename from browser/devtools/debugger/test/browser_dbg_parser-09.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-09.js
rename from browser/devtools/debugger/test/browser_dbg_parser-10.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_parser-10.js
rename from browser/devtools/debugger/test/browser_dbg_pause-exceptions-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js
rename from browser/devtools/debugger/test/browser_dbg_pause-exceptions-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js
rename from browser/devtools/debugger/test/browser_dbg_pause-no-step.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pause-no-step.js
rename from browser/devtools/debugger/test/browser_dbg_pause-resume.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pause-resume.js
rename from browser/devtools/debugger/test/browser_dbg_pause-warning.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pause-warning.js
rename from browser/devtools/debugger/test/browser_dbg_paused-keybindings.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_paused-keybindings.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-01.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-02.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-03.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-04.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-05.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-06.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-07.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-07.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-08.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-08.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-09.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-09.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-10.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-10.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-11.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-11.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-12.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-12.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-13.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-13.js
rename from browser/devtools/debugger/test/browser_dbg_pretty-print-on-paused.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_pretty-print-on-paused.js
rename from browser/devtools/debugger/test/browser_dbg_progress-listener-bug.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_progress-listener-bug.js
rename from browser/devtools/debugger/test/browser_dbg_promises-allocation-stack.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_promises-allocation-stack.js
rename from browser/devtools/debugger/test/browser_dbg_promises-chrome-allocation-stack.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_promises-chrome-allocation-stack.js
rename from browser/devtools/debugger/test/browser_dbg_promises-fulfillment-stack.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_promises-fulfillment-stack.js
rename from browser/devtools/debugger/test/browser_dbg_promises-rejection-stack.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_promises-rejection-stack.js
rename from browser/devtools/debugger/test/browser_dbg_reload-preferred-script-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_reload-preferred-script-01.js
rename from browser/devtools/debugger/test/browser_dbg_reload-preferred-script-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_reload-preferred-script-02.js
rename from browser/devtools/debugger/test/browser_dbg_reload-preferred-script-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_reload-preferred-script-03.js
rename from browser/devtools/debugger/test/browser_dbg_reload-same-script.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_reload-same-script.js
rename from browser/devtools/debugger/test/browser_dbg_scripts-switching-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_scripts-switching-01.js
rename from browser/devtools/debugger/test/browser_dbg_scripts-switching-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_scripts-switching-02.js
rename from browser/devtools/debugger/test/browser_dbg_scripts-switching-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_scripts-switching-03.js
rename from browser/devtools/debugger/test/browser_dbg_search-autofill-identifier.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-autofill-identifier.js
rename from browser/devtools/debugger/test/browser_dbg_search-basic-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-basic-01.js
rename from browser/devtools/debugger/test/browser_dbg_search-basic-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-basic-02.js
rename from browser/devtools/debugger/test/browser_dbg_search-basic-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-basic-03.js
rename from browser/devtools/debugger/test/browser_dbg_search-basic-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-basic-04.js
rename from browser/devtools/debugger/test/browser_dbg_search-global-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-global-01.js
rename from browser/devtools/debugger/test/browser_dbg_search-global-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-global-02.js
rename from browser/devtools/debugger/test/browser_dbg_search-global-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-global-03.js
rename from browser/devtools/debugger/test/browser_dbg_search-global-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-global-04.js
rename from browser/devtools/debugger/test/browser_dbg_search-global-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-global-05.js
rename from browser/devtools/debugger/test/browser_dbg_search-global-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-global-06.js
rename from browser/devtools/debugger/test/browser_dbg_search-popup-jank.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-popup-jank.js
rename from browser/devtools/debugger/test/browser_dbg_search-sources-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-sources-01.js
rename from browser/devtools/debugger/test/browser_dbg_search-sources-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-sources-02.js
rename from browser/devtools/debugger/test/browser_dbg_search-sources-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-sources-03.js
rename from browser/devtools/debugger/test/browser_dbg_search-symbols.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_search-symbols.js
rename from browser/devtools/debugger/test/browser_dbg_searchbox-help-popup-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_searchbox-help-popup-01.js
rename from browser/devtools/debugger/test/browser_dbg_searchbox-help-popup-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_searchbox-help-popup-02.js
rename from browser/devtools/debugger/test/browser_dbg_searchbox-parse.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_searchbox-parse.js
rename from browser/devtools/debugger/test/browser_dbg_server-conditional-bp-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_server-conditional-bp-01.js
rename from browser/devtools/debugger/test/browser_dbg_server-conditional-bp-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_server-conditional-bp-02.js
rename from browser/devtools/debugger/test/browser_dbg_server-conditional-bp-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_server-conditional-bp-03.js
rename from browser/devtools/debugger/test/browser_dbg_server-conditional-bp-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_server-conditional-bp-04.js
rename from browser/devtools/debugger/test/browser_dbg_server-conditional-bp-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_server-conditional-bp-05.js
rename from browser/devtools/debugger/test/browser_dbg_source-maps-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_source-maps-01.js
rename from browser/devtools/debugger/test/browser_dbg_source-maps-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_source-maps-02.js
rename from browser/devtools/debugger/test/browser_dbg_source-maps-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_source-maps-03.js
rename from browser/devtools/debugger/test/browser_dbg_source-maps-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_source-maps-04.js
rename from browser/devtools/debugger/test/browser_dbg_sources-bookmarklet.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-bookmarklet.js
rename from browser/devtools/debugger/test/browser_dbg_sources-cache.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-cache.js
rename from browser/devtools/debugger/test/browser_dbg_sources-contextmenu-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-contextmenu-01.js
rename from browser/devtools/debugger/test/browser_dbg_sources-contextmenu-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-contextmenu-02.js
rename from browser/devtools/debugger/test/browser_dbg_sources-eval-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-eval-01.js
rename from browser/devtools/debugger/test/browser_dbg_sources-eval-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-eval-02.js
rename from browser/devtools/debugger/test/browser_dbg_sources-keybindings.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-keybindings.js
rename from browser/devtools/debugger/test/browser_dbg_sources-labels.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-labels.js
rename from browser/devtools/debugger/test/browser_dbg_sources-sorting.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_sources-sorting.js
rename from browser/devtools/debugger/test/browser_dbg_split-console-paused-reload.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_split-console-paused-reload.js
rename from browser/devtools/debugger/test/browser_dbg_stack-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-01.js
rename from browser/devtools/debugger/test/browser_dbg_stack-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-02.js
rename from browser/devtools/debugger/test/browser_dbg_stack-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-03.js
rename from browser/devtools/debugger/test/browser_dbg_stack-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-04.js
rename from browser/devtools/debugger/test/browser_dbg_stack-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-05.js
rename from browser/devtools/debugger/test/browser_dbg_stack-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-06.js
rename from browser/devtools/debugger/test/browser_dbg_stack-07.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_stack-07.js
rename from browser/devtools/debugger/test/browser_dbg_step-out.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_step-out.js
rename from browser/devtools/debugger/test/browser_dbg_tabactor-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_tabactor-01.js
--- a/browser/devtools/debugger/test/browser_dbg_tabactor-01.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_tabactor-01.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Check extension-added tab actor lifetimes.
  */
 
-const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/"
+const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/mochitest/"
 const ACTORS_URL = CHROME_URL + "testactors.js";
 const TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
 
 let gClient;
 
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
rename from browser/devtools/debugger/test/browser_dbg_tabactor-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_tabactor-02.js
--- a/browser/devtools/debugger/test/browser_dbg_tabactor-02.js
+++ b/browser/devtools/debugger/test/mochitest/browser_dbg_tabactor-02.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Check extension-added tab actor lifetimes.
  */
 
-const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/"
+const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/mochitest/"
 const ACTORS_URL = CHROME_URL + "testactors.js";
 const TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
 
 let gClient;
 
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
rename from browser/devtools/debugger/test/browser_dbg_terminate-on-tab-close.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_terminate-on-tab-close.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-03.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-04.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-05.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-06.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-accessibility.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-data.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-data.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-edit-cancel.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-edit-cancel.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-edit-click.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-edit-click.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-edit-value.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-edit-watch.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-pref.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-filter-searchbox.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-filter-searchbox.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-frame-with.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-frozen-sealed-nonext.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-hide-non-enums.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-large-array-buffer.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-override-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-override-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-override-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-override-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-03.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-04.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-04.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-05.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-05.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-06.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-06.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-07.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-07.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-08.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-08.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-09.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-09.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-10.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-10.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-11.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-11.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-12.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-12.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-13.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-13.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-14.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-14.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-15.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-15.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-popup-16.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-reexpand-01.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-reexpand-02.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-03.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-reexpand-03.js
rename from browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_variables-view-webidl.js
rename from browser/devtools/debugger/test/browser_dbg_watch-expressions-01.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_watch-expressions-01.js
rename from browser/devtools/debugger/test/browser_dbg_watch-expressions-02.js
rename to browser/devtools/debugger/test/mochitest/browser_dbg_watch-expressions-02.js
rename from browser/devtools/debugger/test/code_WorkerActor.attach-worker1.js
rename to browser/devtools/debugger/test/mochitest/code_WorkerActor.attach-worker1.js
rename from browser/devtools/debugger/test/code_WorkerActor.attach-worker2.js
rename to browser/devtools/debugger/test/mochitest/code_WorkerActor.attach-worker2.js
rename from browser/devtools/debugger/test/code_WorkerActor.attachThread-worker.js
rename to browser/devtools/debugger/test/mochitest/code_WorkerActor.attachThread-worker.js
rename from browser/devtools/debugger/test/code_binary_search.coffee
rename to browser/devtools/debugger/test/mochitest/code_binary_search.coffee
rename from browser/devtools/debugger/test/code_binary_search.js
rename to browser/devtools/debugger/test/mochitest/code_binary_search.js
rename from browser/devtools/debugger/test/code_binary_search.map
rename to browser/devtools/debugger/test/mochitest/code_binary_search.map
rename from browser/devtools/debugger/test/code_blackboxing_blackboxme.js
rename to browser/devtools/debugger/test/mochitest/code_blackboxing_blackboxme.js
rename from browser/devtools/debugger/test/code_blackboxing_one.js
rename to browser/devtools/debugger/test/mochitest/code_blackboxing_one.js
rename from browser/devtools/debugger/test/code_blackboxing_three.js
rename to browser/devtools/debugger/test/mochitest/code_blackboxing_three.js
rename from browser/devtools/debugger/test/code_blackboxing_two.js
rename to browser/devtools/debugger/test/mochitest/code_blackboxing_two.js
rename from browser/devtools/debugger/test/code_breakpoints-break-on-last-line-of-script-on-reload.js
rename to browser/devtools/debugger/test/mochitest/code_breakpoints-break-on-last-line-of-script-on-reload.js
rename from browser/devtools/debugger/test/code_breakpoints-other-tabs.js
rename to browser/devtools/debugger/test/mochitest/code_breakpoints-other-tabs.js
rename from browser/devtools/debugger/test/code_bug-896139.js
rename to browser/devtools/debugger/test/mochitest/code_bug-896139.js
rename from browser/devtools/debugger/test/code_frame-script.js
rename to browser/devtools/debugger/test/mochitest/code_frame-script.js
rename from browser/devtools/debugger/test/code_function-search-01.js
rename to browser/devtools/debugger/test/mochitest/code_function-search-01.js
rename from browser/devtools/debugger/test/code_function-search-02.js
rename to browser/devtools/debugger/test/mochitest/code_function-search-02.js
rename from browser/devtools/debugger/test/code_function-search-03.js
rename to browser/devtools/debugger/test/mochitest/code_function-search-03.js
rename from browser/devtools/debugger/test/code_listworkers-worker1.js
rename to browser/devtools/debugger/test/mochitest/code_listworkers-worker1.js
rename from browser/devtools/debugger/test/code_listworkers-worker2.js
rename to browser/devtools/debugger/test/mochitest/code_listworkers-worker2.js
rename from browser/devtools/debugger/test/code_location-changes.js
rename to browser/devtools/debugger/test/mochitest/code_location-changes.js
rename from browser/devtools/debugger/test/code_math.js
rename to browser/devtools/debugger/test/mochitest/code_math.js
rename from browser/devtools/debugger/test/code_math.map
rename to browser/devtools/debugger/test/mochitest/code_math.map
rename from browser/devtools/debugger/test/code_math.min.js
rename to browser/devtools/debugger/test/mochitest/code_math.min.js
rename from browser/devtools/debugger/test/code_math_bogus_map.js
rename to browser/devtools/debugger/test/mochitest/code_math_bogus_map.js
rename from browser/devtools/debugger/test/code_same-line-functions.js
rename to browser/devtools/debugger/test/mochitest/code_same-line-functions.js
rename from browser/devtools/debugger/test/code_script-eval.js
rename to browser/devtools/debugger/test/mochitest/code_script-eval.js
rename from browser/devtools/debugger/test/code_script-switching-01.js
rename to browser/devtools/debugger/test/mochitest/code_script-switching-01.js
rename from browser/devtools/debugger/test/code_script-switching-02.js
rename to browser/devtools/debugger/test/mochitest/code_script-switching-02.js
rename from browser/devtools/debugger/test/code_test-editor-mode
rename to browser/devtools/debugger/test/mochitest/code_test-editor-mode
rename from browser/devtools/debugger/test/code_ugly-2.js
rename to browser/devtools/debugger/test/mochitest/code_ugly-2.js
rename from browser/devtools/debugger/test/code_ugly-3.js
rename to browser/devtools/debugger/test/mochitest/code_ugly-3.js
rename from browser/devtools/debugger/test/code_ugly-4.js
rename to browser/devtools/debugger/test/mochitest/code_ugly-4.js
rename from browser/devtools/debugger/test/code_ugly-5.js
rename to browser/devtools/debugger/test/mochitest/code_ugly-5.js
rename from browser/devtools/debugger/test/code_ugly-6.js
rename to browser/devtools/debugger/test/mochitest/code_ugly-6.js
rename from browser/devtools/debugger/test/code_ugly-7.js
rename to browser/devtools/debugger/test/mochitest/code_ugly-7.js
rename from browser/devtools/debugger/test/code_ugly-8
rename to browser/devtools/debugger/test/mochitest/code_ugly-8
rename from browser/devtools/debugger/test/code_ugly-8^headers^
rename to browser/devtools/debugger/test/mochitest/code_ugly-8^headers^
rename from browser/devtools/debugger/test/code_ugly.js
rename to browser/devtools/debugger/test/mochitest/code_ugly.js
rename from browser/devtools/debugger/test/code_workeractor-worker.js
rename to browser/devtools/debugger/test/mochitest/code_workeractor-worker.js
rename from browser/devtools/debugger/test/doc_WorkerActor.attach-tab1.html
rename to browser/devtools/debugger/test/mochitest/doc_WorkerActor.attach-tab1.html
rename from browser/devtools/debugger/test/doc_WorkerActor.attach-tab2.html
rename to browser/devtools/debugger/test/mochitest/doc_WorkerActor.attach-tab2.html
rename from browser/devtools/debugger/test/doc_WorkerActor.attachThread-tab.html
rename to browser/devtools/debugger/test/mochitest/doc_WorkerActor.attachThread-tab.html
rename from browser/devtools/debugger/test/doc_auto-pretty-print-01.html
rename to browser/devtools/debugger/test/mochitest/doc_auto-pretty-print-01.html
rename from browser/devtools/debugger/test/doc_auto-pretty-print-02.html
rename to browser/devtools/debugger/test/mochitest/doc_auto-pretty-print-02.html
rename from browser/devtools/debugger/test/doc_binary_search.html
rename to browser/devtools/debugger/test/mochitest/doc_binary_search.html
rename from browser/devtools/debugger/test/doc_blackboxing.html
rename to browser/devtools/debugger/test/mochitest/doc_blackboxing.html
rename from browser/devtools/debugger/test/doc_breakpoint-move.html
rename to browser/devtools/debugger/test/mochitest/doc_breakpoint-move.html
rename from browser/devtools/debugger/test/doc_breakpoints-break-on-last-line-of-script-on-reload.html
rename to browser/devtools/debugger/test/mochitest/doc_breakpoints-break-on-last-line-of-script-on-reload.html
rename from browser/devtools/debugger/test/doc_breakpoints-other-tabs.html
rename to browser/devtools/debugger/test/mochitest/doc_breakpoints-other-tabs.html
rename from browser/devtools/debugger/test/doc_breakpoints-reload.html
rename to browser/devtools/debugger/test/mochitest/doc_breakpoints-reload.html
rename from browser/devtools/debugger/test/doc_bug-896139.html
rename to browser/devtools/debugger/test/mochitest/doc_bug-896139.html
rename from browser/devtools/debugger/test/doc_closure-optimized-out.html
rename to browser/devtools/debugger/test/mochitest/doc_closure-optimized-out.html
rename from browser/devtools/debugger/test/doc_closures.html
rename to browser/devtools/debugger/test/mochitest/doc_closures.html
rename from browser/devtools/debugger/test/doc_cmd-break.html
rename to browser/devtools/debugger/test/mochitest/doc_cmd-break.html
rename from browser/devtools/debugger/test/doc_cmd-dbg.html
rename to browser/devtools/debugger/test/mochitest/doc_cmd-dbg.html
rename from browser/devtools/debugger/test/doc_conditional-breakpoints.html
rename to browser/devtools/debugger/test/mochitest/doc_conditional-breakpoints.html
rename from browser/devtools/debugger/test/doc_domnode-variables.html
rename to browser/devtools/debugger/test/mochitest/doc_domnode-variables.html
rename from browser/devtools/debugger/test/doc_editor-mode.html
rename to browser/devtools/debugger/test/mochitest/doc_editor-mode.html
rename from browser/devtools/debugger/test/doc_empty-tab-01.html
rename to browser/devtools/debugger/test/mochitest/doc_empty-tab-01.html
rename from browser/devtools/debugger/test/doc_empty-tab-02.html
rename to browser/devtools/debugger/test/mochitest/doc_empty-tab-02.html
rename from browser/devtools/debugger/test/doc_event-listeners-01.html
rename to browser/devtools/debugger/test/mochitest/doc_event-listeners-01.html
rename from browser/devtools/debugger/test/doc_event-listeners-02.html
rename to browser/devtools/debugger/test/mochitest/doc_event-listeners-02.html
rename from browser/devtools/debugger/test/doc_event-listeners-03.html
rename to browser/devtools/debugger/test/mochitest/doc_event-listeners-03.html
rename from browser/devtools/debugger/test/doc_event-listeners-04.html
rename to browser/devtools/debugger/test/mochitest/doc_event-listeners-04.html
rename from browser/devtools/debugger/test/doc_frame-parameters.html
rename to browser/devtools/debugger/test/mochitest/doc_frame-parameters.html
rename from browser/devtools/debugger/test/doc_function-display-name.html
rename to browser/devtools/debugger/test/mochitest/doc_function-display-name.html
rename from browser/devtools/debugger/test/doc_function-search.html
rename to browser/devtools/debugger/test/mochitest/doc_function-search.html
rename from browser/devtools/debugger/test/doc_global-method-override.html
rename to browser/devtools/debugger/test/mochitest/doc_global-method-override.html
rename from browser/devtools/debugger/test/doc_iframes.html
rename to browser/devtools/debugger/test/mochitest/doc_iframes.html
rename from browser/devtools/debugger/test/doc_included-script.html
rename to browser/devtools/debugger/test/mochitest/doc_included-script.html
rename from browser/devtools/debugger/test/doc_inline-debugger-statement.html
rename to browser/devtools/debugger/test/mochitest/doc_inline-debugger-statement.html
rename from browser/devtools/debugger/test/doc_inline-script.html
rename to browser/devtools/debugger/test/mochitest/doc_inline-script.html
rename from browser/devtools/debugger/test/doc_large-array-buffer.html
rename to browser/devtools/debugger/test/mochitest/doc_large-array-buffer.html
rename from browser/devtools/debugger/test/doc_listworkers-tab.html
rename to browser/devtools/debugger/test/mochitest/doc_listworkers-tab.html
rename from browser/devtools/debugger/test/doc_minified.html
rename to browser/devtools/debugger/test/mochitest/doc_minified.html
rename from browser/devtools/debugger/test/doc_minified_bogus_map.html
rename to browser/devtools/debugger/test/mochitest/doc_minified_bogus_map.html
rename from browser/devtools/debugger/test/doc_native-event-handler.html
rename to browser/devtools/debugger/test/mochitest/doc_native-event-handler.html
rename from browser/devtools/debugger/test/doc_no-page-sources.html
rename to browser/devtools/debugger/test/mochitest/doc_no-page-sources.html
rename from browser/devtools/debugger/test/doc_pause-exceptions.html
rename to browser/devtools/debugger/test/mochitest/doc_pause-exceptions.html
rename from browser/devtools/debugger/test/doc_pretty-print-2.html
rename to browser/devtools/debugger/test/mochitest/doc_pretty-print-2.html
rename from browser/devtools/debugger/test/doc_pretty-print-3.html
rename to browser/devtools/debugger/test/mochitest/doc_pretty-print-3.html
rename from browser/devtools/debugger/test/doc_pretty-print-on-paused.html
rename to browser/devtools/debugger/test/mochitest/doc_pretty-print-on-paused.html
rename from browser/devtools/debugger/test/doc_pretty-print.html
rename to browser/devtools/debugger/test/mochitest/doc_pretty-print.html
rename from browser/devtools/debugger/test/doc_promise-get-allocation-stack.html
rename to browser/devtools/debugger/test/mochitest/doc_promise-get-allocation-stack.html
rename from browser/devtools/debugger/test/doc_promise-get-fulfillment-stack.html
rename to browser/devtools/debugger/test/mochitest/doc_promise-get-fulfillment-stack.html
rename from browser/devtools/debugger/test/doc_promise-get-rejection-stack.html
rename to browser/devtools/debugger/test/mochitest/doc_promise-get-rejection-stack.html
rename from browser/devtools/debugger/test/doc_promise.html
rename to browser/devtools/debugger/test/mochitest/doc_promise.html
rename from browser/devtools/debugger/test/doc_random-javascript.html
rename to browser/devtools/debugger/test/mochitest/doc_random-javascript.html
rename from browser/devtools/debugger/test/doc_recursion-stack.html
rename to browser/devtools/debugger/test/mochitest/doc_recursion-stack.html
rename from browser/devtools/debugger/test/doc_scope-variable-2.html
rename to browser/devtools/debugger/test/mochitest/doc_scope-variable-2.html
rename from browser/devtools/debugger/test/doc_scope-variable-3.html
rename to browser/devtools/debugger/test/mochitest/doc_scope-variable-3.html
rename from browser/devtools/debugger/test/doc_scope-variable-4.html
rename to browser/devtools/debugger/test/mochitest/doc_scope-variable-4.html
rename from browser/devtools/debugger/test/doc_scope-variable.html
rename to browser/devtools/debugger/test/mochitest/doc_scope-variable.html
rename from browser/devtools/debugger/test/doc_script-bookmarklet.html
rename to browser/devtools/debugger/test/mochitest/doc_script-bookmarklet.html
rename from browser/devtools/debugger/test/doc_script-eval.html
rename to browser/devtools/debugger/test/mochitest/doc_script-eval.html
rename from browser/devtools/debugger/test/doc_script-switching-01.html
rename to browser/devtools/debugger/test/mochitest/doc_script-switching-01.html
rename from browser/devtools/debugger/test/doc_script-switching-02.html
rename to browser/devtools/debugger/test/mochitest/doc_script-switching-02.html
rename from browser/devtools/debugger/test/doc_split-console-paused-reload.html
rename to browser/devtools/debugger/test/mochitest/doc_split-console-paused-reload.html
rename from browser/devtools/debugger/test/doc_step-out.html
rename to browser/devtools/debugger/test/mochitest/doc_step-out.html
rename from browser/devtools/debugger/test/doc_terminate-on-tab-close.html
rename to browser/devtools/debugger/test/mochitest/doc_terminate-on-tab-close.html
rename from browser/devtools/debugger/test/doc_watch-expression-button.html
rename to browser/devtools/debugger/test/mochitest/doc_watch-expression-button.html
rename from browser/devtools/debugger/test/doc_watch-expressions.html
rename to browser/devtools/debugger/test/mochitest/doc_watch-expressions.html
rename from browser/devtools/debugger/test/doc_with-frame.html
rename to browser/devtools/debugger/test/mochitest/doc_with-frame.html
rename from browser/devtools/debugger/test/head.js
rename to browser/devtools/debugger/test/mochitest/head.js
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/mochitest/head.js
@@ -21,17 +21,17 @@ let { BrowserToolboxProcess } = Cu.impor
 let { DebuggerServer } = require("devtools/server/main");
 let { DebuggerClient, ObjectClient } = require("devtools/toolkit/client/main");
 let { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
 let EventEmitter = require("devtools/toolkit/event-emitter");
 const { promiseInvoke } = require("devtools/async-utils");
 let { TargetFactory } = require("devtools/framework/target");
 let { Toolbox } = require("devtools/framework/toolbox")
 
-const EXAMPLE_URL = "http://example.com/browser/browser/devtools/debugger/test/";
+const EXAMPLE_URL = "http://example.com/browser/browser/devtools/debugger/test/mochitest/";
 const FRAME_SCRIPT_URL = getRootDirectory(gTestPath) + "code_frame-script.js";
 
 DevToolsUtils.testing = true;
 SimpleTest.registerCleanupFunction(() => {
   DevToolsUtils.testing = false;
 });
 
 // All tests are asynchronous.
@@ -57,17 +57,17 @@ registerCleanupFunction(function* () {
   info("Forcing GC after debugger test.");
   Cu.forceGC();
 });
 
 // Import the GCLI test helper
 let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 testDir = testDir.replace(/\/\//g, '/');
 testDir = testDir.replace("chrome:/mochitest", "chrome://mochitest");
-let helpersjs = testDir + "/../../commandline/test/helpers.js";
+let helpersjs = testDir + "/../../../commandline/test/helpers.js";
 Services.scriptloader.loadSubScript(helpersjs, this);
 
 // Redeclare dbg_assert with a fatal behavior.
 function dbg_assert(cond, e) {
   if (!cond) {
     throw e;
   }
 }
@@ -454,20 +454,24 @@ function ensureThreadClientState(aPanel,
 
   if (state == aState) {
     return promise.resolve(null);
   } else {
     return waitForThreadEvents(aPanel, aState);
   }
 }
 
+function reload(aPanel, aUrl) {
+  let activeTab = aPanel.panelWin.DebuggerController._target.activeTab;
+  aUrl ? activeTab.navigateTo(aUrl) : activeTab.reload();
+}
+
 function navigateActiveTabTo(aPanel, aUrl, aWaitForEventName, aEventRepeat) {
   let finished = waitForDebuggerEvents(aPanel, aWaitForEventName, aEventRepeat);
-  let activeTab = aPanel.panelWin.DebuggerController._target.activeTab;
-  aUrl ? activeTab.navigateTo(aUrl) : activeTab.reload();
+  reload(aPanel, aUrl);
   return finished;
 }
 
 function navigateActiveTabInHistory(aPanel, aDirection, aWaitForEventName, aEventRepeat) {
   let finished = waitForDebuggerEvents(aPanel, aWaitForEventName, aEventRepeat);
   content.history[aDirection]();
   return finished;
 }
@@ -960,19 +964,18 @@ function jsonrpc(tab, method, params) {
   return new Promise(function (resolve, reject) {
     let currentId = nextId++;
     let messageManager = tab.linkedBrowser.messageManager;
     messageManager.sendAsyncMessage("jsonrpc", {
       method: method,
       params: params,
       id: currentId
     });
-    messageManager.addMessageListener("jsonrpc", function listener({
-      data: { result, error, id }
-    }) {
+    messageManager.addMessageListener("jsonrpc", function listener(res) {
+      const { data: { result, error, id } } = res;
       if (id !== currentId) {
         return;
       }
 
       messageManager.removeMessageListener("jsonrpc", listener);
       if (error != null) {
          reject(error);
       }
@@ -1183,8 +1186,25 @@ function setBreakpoint(sourceClient, loc
   info("Setting breakpoint.\n");
   return rdpInvoke(sourceClient, sourceClient.setBreakpoint, location);
 }
 
 function source(sourceClient) {
   info("Getting source.\n");
   return rdpInvoke(sourceClient, sourceClient.source);
 }
+
+function afterDispatch(dispatcher, type) {
+  info("Waiting on dispatch: " + type);
+  return new Promise(resolve => {
+    dispatcher.dispatch({
+      // Normally we would use `services.WAIT_UNTIL`, but use the
+      // internal name here so tests aren't forced to always pass it
+      // in
+      type: "@@service/waitUntil",
+      predicate: action => (
+        action.type === type &&
+        action.status ? action.status === "done" : true
+      ),
+      run: resolve
+    });
+  });
+}
rename from browser/devtools/debugger/test/sjs_random-javascript.sjs
rename to browser/devtools/debugger/test/mochitest/sjs_random-javascript.sjs
rename from browser/devtools/debugger/test/testactors.js
rename to browser/devtools/debugger/test/mochitest/testactors.js
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -67,17 +67,16 @@ browser.jar:
     content/browser/devtools/debugger.xul                              (debugger/debugger.xul)
     content/browser/devtools/debugger.css                              (debugger/debugger.css)
     content/browser/devtools/debugger-controller.js                    (debugger/debugger-controller.js)
     content/browser/devtools/debugger-view.js                          (debugger/debugger-view.js)
     content/browser/devtools/debugger/workers-view.js                  (debugger/views/workers-view.js)
     content/browser/devtools/debugger/sources-view.js                  (debugger/views/sources-view.js)
     content/browser/devtools/debugger/variable-bubble-view.js          (debugger/views/variable-bubble-view.js)
     content/browser/devtools/debugger/watch-expressions-view.js        (debugger/views/watch-expressions-view.js)
-    content/browser/devtools/debugger/event-listeners-view.js          (debugger/views/event-listeners-view.js)
     content/browser/devtools/debugger/global-search-view.js            (debugger/views/global-search-view.js)
     content/browser/devtools/debugger/toolbar-view.js                  (debugger/views/toolbar-view.js)
     content/browser/devtools/debugger/options-view.js                  (debugger/views/options-view.js)
     content/browser/devtools/debugger/stack-frames-view.js             (debugger/views/stack-frames-view.js)
     content/browser/devtools/debugger/stack-frames-classic-view.js     (debugger/views/stack-frames-classic-view.js)
     content/browser/devtools/debugger/filter-view.js                   (debugger/views/filter-view.js)
     content/browser/devtools/debugger/utils.js                         (debugger/utils.js)
     content/browser/devtools/shadereditor.xul                          (shadereditor/shadereditor.xul)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/browser-loader.js
@@ -0,0 +1,90 @@
+const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+const loaders = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
+const devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
+const { joinURI } = devtools.require("devtools/toolkit/path");
+let appConstants;
+
+// Some of the services that the system module requires is not
+// available in xpcshell tests. This is ok, we can easily polyfill the
+// values that we need.
+try {
+  const system = devtools.require("devtools/toolkit/shared/system");
+  appConstants = system.constants;
+}
+catch(e) {
+  // We are in a testing environment most likely. There isn't much
+  // risk to this defaulting to true because the dev version of React
+  // will be loaded if this is true, and that file doesn't get built
+  // into the release version of Firefox, so this will only work with
+  // dev environments.
+  appConstants = {
+    DEBUG_JS_MODULES: true
+  };
+}
+
+
+/*
+ * Create a loader to be used in a browser environment. This evaluates
+ * modules in their own environment, but sets window (the normal
+ * global object) as the sandbox prototype, so when a variable is not
+ * defined it checks `window` before throwing an error. This makes all
+ * browser APIs available to modules by default, like a normal browser
+ * environment, but modules are still evaluated in their own scope.
+ *
+ * Another very important feature of this loader is that it *only*
+ * deals with modules loaded from under `baseURI`. Anything loaded
+ * outside of that path will still be loaded from the devtools loader,
+ * so all system modules are still shared and cached across instances.
+ * An exception to this is anything under
+ * `browser/devtools/shared/content`, which is where shared libraries
+ * live that should be evaluated in a browser environment.
+ *
+ * @param string baseURI
+ *        Base path to load modules from.
+ * @param Object window
+ *        The window instance to evaluate modules within
+ * @return Object
+ *         An object with two properties:
+ *         - loader: the Loader instance
+ *         - require: a function to require modules with
+ */
+function BrowserLoader(baseURI, window) {
+  const loaderOptions = devtools.require('@loader/options');
+
+  let dynamicPaths = {};
+  if (appConstants.DEBUG_JS_MODULES) {
+    // Load in the dev version of React
+    dynamicPaths["devtools/shared/content/react"] =
+      "resource:///modules/devtools/shared/content/react-dev.js";
+  }
+
+  const opts = {
+    id: "browser-loader",
+    sharedGlobal: true,
+    sandboxPrototype: window,
+    paths: Object.assign({}, loaderOptions.paths, dynamicPaths),
+    invisibleToDebugger: loaderOptions.invisibleToDebugger,
+    require: (id, require) => {
+      const uri = require.resolve(id);
+      if (!uri.startsWith(baseURI) &&
+          !uri.startsWith("resource:///modules/devtools/shared/content")) {
+        return devtools.require(uri);
+      }
+      return require(uri);
+    }
+  };
+
+  // The main.js file does not have to actually exist. It just
+  // represents the base environment, so requires will be relative to
+  // that path when used outside of modules.
+  const mainModule = loaders.Module(baseURI, joinURI(baseURI, "main.js"));
+  const mainLoader = loaders.Loader(opts);
+
+  return {
+    loader: mainLoader,
+    require: loaders.Require(mainLoader, mainModule)
+  };
+}
+
+EXPORTED_SYMBOLS = ["BrowserLoader"];
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/create-dispatcher.js
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const fluxify = require('./fluxify/dispatcher');
+const thunkMiddleware = require('./fluxify/thunkMiddleware');
+const logMiddleware = require('./fluxify/logMiddleware');
+const waitUntilService = require('./fluxify/waitUntilService')
+const { compose } = require('devtools/toolkit/DevToolsUtils');
+
+/**
+ * This creates a dispatcher with all the standard middleware in place
+ * that all code requires. It can also be optionally configured in
+ * various ways, such as logging and recording.
+ *
+ * @param {object} opts - boolean configuration flags
+ *        - log: log all dispatched actions to console
+ */
+module.exports = (opts={}) => {
+  const middleware = [
+    thunkMiddleware,
+    waitUntilService.service
+  ];
+
+  if (opts.log) {
+    middleware.push(logMiddleware);
+  }
+
+  return fluxify.applyMiddleware(...middleware)(fluxify.createDispatcher);
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/bindActionCreators.js
@@ -0,0 +1,28 @@
+/* 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 bindActionCreator(actionCreator, dispatch) {
+  return (...args) => dispatch(actionCreator(...args));
+}
+
+/**
+ * Wraps action creator functions into a function that automatically
+ * dispatches the created action with `dispatch`. Normally action
+ * creators simply return actions, but wrapped functions will
+ * automatically dispatch.
+ *
+ * @param {object} actionCreators
+ *        An object of action creator functions (names as keys)
+ * @param {function} dispatch
+ */
+function bindActionCreators(actionCreators, dispatch) {
+  let actions = {};
+  for (let k of Object.keys(actionCreators)) {
+    actions[k] = bindActionCreator(actionCreators[k], dispatch);
+  }
+  return actions;
+}
+
+module.exports = bindActionCreators;
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/dispatcher.js
@@ -0,0 +1,247 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const { entries, compose } = require("devtools/toolkit/DevToolsUtils");
+
+/**
+ * A store creator that creates a dispatch function that runs the
+ * provided middlewares before actually dispatching. This allows
+ * simple middleware to augment the kinds of actions that can
+ * be dispatched. This would be used like this:
+ * `createDispatcher = applyMiddleware([fooMiddleware, ...])(createDispatcher)`
+ *
+ * Middlewares are simple functions that are provided `dispatch` and
+ * `getState` functions. They create functions that accept actions and
+ * can re-dispatch them in any way they want. A common scenario is
+ * asynchronously dispatching multiple actions. Here is a full
+ * middleware:
+ *
+ * function thunkMiddleware({ dispatch, getState }) {
+ *  return next => action => {
+ *    return typeof action === 'function' ?
+ *      action(dispatch, getState) :
+ *      next(action);
+ *  }
+ * }
+ *
+ * `next` is essentially a `dispatch` function, but it calls the next
+ * middelware in the chain (or the real `dispatch` function). Using
+ * this middleware, you can return a function that gives you a
+ * dispatch function:
+ *
+ * function actionCreator(timeout) {
+ *   return (dispatch, getState) => {
+ *     dispatch({ type: TIMEOUT, status: "start" });
+ *     setTimeout(() => dispatch({ type: TIMEOUT, status: "end" }),
+ *                timeout);
+ *   }
+ * }
+ *
+ */
+function applyMiddleware(...middlewares) {
+  return next => stores => {
+    const dispatcher = next(stores);
+    let dispatch = dispatcher.dispatch;
+
+    const api = {
+      getState: dispatcher.getState,
+      dispatch: action => dispatch(action)
+    };
+    const chain = middlewares.map(middleware => middleware(api));
+    dispatch = compose(...chain)(dispatcher.dispatch);
+
+    return Object.assign({}, dispatcher, { dispatch: dispatch });
+  }
+}
+
+/*
+ * The heart of the system. This creates a dispatcher which is the
+ * interface between views and stores. Views can use a dispatcher
+ * instance to dispatch actions, which know nothing about the stores.
+ * Actions are broadcasted to all registered stores, and stores can
+ * handle the action and update their state. The dispatcher gives
+ * stores an `emitChange` function, which signifies that a piece of
+ * state has changed. The dispatcher will notify all views that are
+ * listening to that piece of state, registered with `onChange`.
+ *
+ * Views generally are stateless, pure components (eventually React
+ * components). They simply take state and render it.
+ *
+ * Stores make up the entire app state, and are all grouped together
+ * into a single app state atom, returned by the dispatcher's
+ * `getState` function. The shape of the app state is determined by
+ * the `stores` object passed in to the dispatcher, so if
+ * `{ foo: fooStore }` was passed to `createDispatcher` the app state
+ * would be `{ foo: fooState }`
+ *
+ * Actions are just JavaScript object with a `type` property and any
+ * other fields pertinent to the action. Action creators should
+ * generally be used to create actions, which are just functions that
+ * return the action object. Additionally, the `bindActionCreators`
+ * module provides a function for automatically binding action
+ * creators to a dispatch function, so calling them automatically
+ * dispatches. For example:
+ *
+ * ```js
+ * // Manually dispatch
+ * dispatcher.dispatch({ type: constants.ADD_ITEM, item: item });
+ * // Using an action creator
+ * dispatcher.dispatch(addItem(item));
+ *
+ * // Using an action creator bound to dispatch
+ * actions = bindActionCreators({ addItem: addItem });
+ * actions.addItem(item);
+ * ```
+ *
+ * Our system expects stores to exist as an `update` function. You
+ * should define an update function in a module, and optionally
+ * any action creators that are useful to go along with it. Here is
+ * an example store file:
+ *
+ * ```js
+ * const initialState = { items: [] };
+ * function update(state = initialState, action, emitChange) {
+ *   if (action.type === constants.ADD_ITEM) {
+ *     state.items.push(action.item);
+ *     emitChange("items", state.items);
+ *   }
+ *
+ *   return state;
+ * }
+ *
+ * function addItem(item) {
+ *   return {
+ *     type: constants.ADD_ITEM,
+ *     item: item
+ *   };
+ * }
+ *
+ * module.exports = {
+ *   update: update,
+ *   actions: { addItem }
+ * }
+ * ```
+ *
+ * Lastly, "constants" are simple strings that specify action names.
+ * Usually the entire set of available action types are specified in
+ * a `constants.js` file, so they are available globally. Use
+ * variables that are the same name as the string, for example
+ * `const ADD_ITEM = "ADD_ITEM"`.
+ *
+ * This entire system was inspired by Redux, which hopefully we will
+ * eventually use once things get cleaned up enough. You should read
+ * its docs, and keep in mind that it calls stores "reducers" and the
+ * dispatcher instance is called a single store.
+ * http://rackt.github.io/redux/
+ */
+function createDispatcher(stores) {
+  const state = {};
+  const listeners = {};
+  let enqueuedChanges = [];
+  let isDispatching = false;
+
+  // Validate the stores to make sure they have the right shape,
+  // and accumulate the initial state
+  entries(stores).forEach(([name, store]) => {
+    if (!store || typeof store.update !== "function") {
+      throw new Error("Error creating dispatcher: store \"" + name +
+                      "\" does not have an `update` function");
+    }
+
+    state[name] = store.update(undefined, {});
+  });
+
+  function getState() {
+    return state;
+  }
+
+  function emitChange(storeName, dataName, payload) {
+    enqueuedChanges.push([storeName, dataName, payload]);
+  }
+
+  function onChange(paths, view) {
+    entries(paths).forEach(([storeName, data]) => {
+      if (!stores[storeName]) {
+        throw new Error("Error adding onChange handler to store: store " +
+                        "\"" + storeName + "\" does not exist");
+      }
+
+      if (!listeners[storeName]) {
+        listeners[storeName] = [];
+      }
+
+      if (typeof data == 'function') {
+        listeners[storeName].push(data.bind(view));
+      }
+      else {
+        entries(data).forEach(([watchedName, handler]) => {
+          listeners[storeName].push((payload, dataName, storeName) => {
+            if (dataName === watchedName) {
+              handler.call(view, payload, dataName, storeName);
+            }
+          });
+        });
+      }
+    });
+  }
+
+  /**
+   * Flush any enqueued state changes from the dispatch cycle. Listeners
+   * are not immediately notified of changes, only after dispatching
+   * is completed, to ensure that all state is consistent (in the case
+   * of multiple stores changes at once).
+   */
+  function flushChanges() {
+    enqueuedChanges.forEach(([storeName, dataName, payload]) => {
+      if (listeners[storeName]) {
+        listeners[storeName].forEach(listener => {
+          listener(payload, dataName, storeName);
+        });
+      }
+    });
+
+    enqueuedChanges = [];
+  }
+
+  function dispatch(action) {
+    if (isDispatching) {
+      throw new Error('Cannot dispatch in the middle of a dispatch');
+    }
+    if (!action.type) {
+      throw new Error(
+        'action type is null, ' +
+        'did you make a typo when publishing this action? ' +
+        JSON.stringify(action, null, 2)
+      );
+    }
+
+    isDispatching = true;
+    try {
+      entries(stores).forEach(([name, store]) => {
+        state[name] = store.update(
+          state[name],
+          action,
+          emitChange.bind(null, name)
+        );
+      });
+    }
+    finally {
+      isDispatching = false;
+    }
+
+    flushChanges();
+  }
+
+  return {
+    getState,
+    dispatch,
+    onChange
+  };
+}
+
+module.exports = {
+  createDispatcher: createDispatcher,
+  applyMiddleware: applyMiddleware
+};
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/logMiddleware.js
@@ -0,0 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+/**
+ * A middleware that logs all actions coming through the system
+ * to the console.
+ */
+function logMiddleware({ dispatch, getState }) {
+  return next => action => {
+    console.log('[DISPATCH]', JSON.stringify(action));
+    next(action);
+  }
+}
+
+module.exports = logMiddleware;
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXTRA_JS_MODULES.devtools.shared.fluxify += [
+    'bindActionCreators.js',
+    'dispatcher.js',
+    'logMiddleware.js',
+    'thunkMiddleware.js',
+    'waitUntilService.js'
+]
+
+XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/test/unit/head.js
@@ -0,0 +1,28 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+const CC = Components.Constructor;
+
+const { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+const createDispatcher = require('devtools/shared/create-dispatcher')({ log: true });
+const waitUntilService = require('devtools/shared/fluxify/waitUntilService');
+const services = {
+  WAIT_UNTIL: waitUntilService.name
+};
+
+const Services = require("Services");
+const { waitForTick, waitForTime } = require("devtools/toolkit/DevToolsUtils");
+
+let loadSubScript = Cc[
+  '@mozilla.org/moz/jssubscript-loader;1'
+].getService(Ci.mozIJSSubScriptLoader).loadSubScript;
+
+function getFileUrl(name, allowMissing=false) {
+  let file = do_get_file(name, allowMissing);
+  return Services.io.newFileURI(file).spec;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/test/unit/stores-for-testing.js
@@ -0,0 +1,48 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This file should be loaded with `loadSubScript` because it contains
+// stateful stores that need a new instance per test.
+
+const NumberStore = {
+  update: (state = 1, action, emitChange) => {
+    switch(action.type) {
+    case constants.ADD_NUMBER: {
+      const newState = state + action.value;
+      emitChange('number', newState);
+      return newState;
+    }
+    case constants.DOUBLE_NUMBER: {
+      const newState = state * 2;
+      emitChange('number', newState);
+      return newState;
+    }}
+
+    return state;
+  },
+
+  constants: {
+    ADD_NUMBER: 'ADD_NUMBER',
+    DOUBLE_NUMBER: 'DOUBLE_NUMBER'
+  }
+};
+
+const itemsInitialState = {
+  list: []
+};
+const ItemStore = {
+  update: (state = itemsInitialState, action, emitChange) => {
+    switch(action.type) {
+    case constants.ADD_ITEM:
+      state.list.push(action.item);
+      emitChange('list', state.list);
+      return state;
+    }
+
+    return state;
+  },
+
+  constants: {
+    ADD_ITEM: 'ADD_ITEM'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/test/unit/test_dispatcher.js
@@ -0,0 +1,101 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+loadSubScript(getFileUrl("stores-for-testing.js"));
+const constants = Object.assign(
+  {},
+  NumberStore.constants,
+  ItemStore.constants
+);
+const stores = { number: NumberStore,
+                 items: ItemStore };
+
+function addNumber(num) {
+  return {
+    type: constants.ADD_NUMBER,
+    value: num
+  }
+}
+
+function addItem(item) {
+  return {
+    type: constants.ADD_ITEM,
+    item: item
+  };
+}
+
+// Tests
+
+function run_test() {
+  testInitialValue();
+  testDispatch();
+  testEmitChange();
+  run_next_test();
+}
+
+function testInitialValue() {
+  do_print("Testing initial value");
+  const dispatcher = createDispatcher(stores);
+  equal(dispatcher.getState().number, 1);
+}
+
+function testDispatch() {
+  do_print("Testing dispatch");
+
+  const dispatcher = createDispatcher(stores);
+  dispatcher.dispatch(addNumber(5));
+  equal(dispatcher.getState().number, 6);
+
+  dispatcher.dispatch(addNumber(2));
+  equal(dispatcher.getState().number, 8);
+
+  // It should ignore unknown action types
+  dispatcher.dispatch({ type: "FOO" });
+  equal(dispatcher.getState().number, 8);
+}
+
+function testEmitChange() {
+  do_print("Testing change emittters");
+  const dispatcher = createDispatcher(stores);
+  let listenerRan = false;
+
+  const numberView = {
+    x: 3,
+    renderNumber: function(num) {
+      ok(this.x, 3, "listener ran in context of view");
+      ok(num, 10);
+      listenerRan = true;
+    }
+  }
+
+  // Views can listen to changes in state by specifying which part of
+  // the state to listen to and giving a handler function. The
+  // function will be run with the view as `this`.
+  dispatcher.onChange({
+    "number": numberView.renderNumber
+  }, numberView);
+
+  dispatcher.dispatch(addNumber(9));
+  ok(listenerRan, "number listener actually ran");
+  listenerRan = false;
+
+  const itemsView = {
+    renderList: function(items) {
+      ok(items.length, 1);
+      ok(items[0].name = "james");
+      listenerRan = true;
+    }
+  }
+
+  // You can listen to deeper sections of the state by nesting objects
+  // to specify the path to that state. You can do this 1 level deep;
+  // you cannot arbitrarily nest state listeners.
+  dispatcher.onChange({
+    "items": {
+      "list": itemsView.renderList
+    }
+  }, itemsView);
+
+  dispatcher.dispatch(addItem({ name: "james" }));
+  ok(listenerRan, "items listener actually ran");
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/test/unit/test_middlewares.js
@@ -0,0 +1,114 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+loadSubScript(getFileUrl('stores-for-testing.js'));
+const constants = NumberStore.constants;
+const stores = { number: NumberStore };
+
+function run_test() {
+  run_next_test();
+}
+
+add_task(function* testThunkDispatch() {
+  do_print("Testing thunk dispatch");
+  // The thunk middleware allows you to return a function from an
+  // action creator which takes `dispatch` and `getState` functions as
+  // arguments. This allows the action creator to fire multiple
+  // actions manually with `dispatch`, possibly asynchronously.
+
+  function addNumberLater(num) {
+    return dispatch => {
+      // Just do it in the next tick, no need to wait too long
+      waitForTick().then(() => {
+        dispatch({
+          type: constants.ADD_NUMBER,
+          value: num
+        });
+      });
+    };
+  }
+
+  function addNumber(num) {
+    return (dispatch, getState) => {
+      dispatch({
+        type: constants.ADD_NUMBER,
+        value: getState().number > 10 ? (num * 2) : num
+      });
+    };
+  }
+
+  const dispatcher = createDispatcher(stores);
+  equal(dispatcher.getState().number, 1);
+  dispatcher.dispatch(addNumberLater(5));
+  equal(dispatcher.getState().number, 1, "state should not have changed");
+  yield waitForTick();
+  equal(dispatcher.getState().number, 6, "state should have changed");
+
+  dispatcher.dispatch(addNumber(5));
+  equal(dispatcher.getState().number, 11);
+  dispatcher.dispatch(addNumber(2));
+  // 2 * 2 should have actually been added because the state is
+  // greater than 10 (the action creator changes the value based on
+  // the current state)
+  equal(dispatcher.getState().number, 15);
+});
+
+add_task(function* testWaitUntilService() {
+  do_print("Testing waitUntil service");
+  // The waitUntil service allows you to queue functions to be run at a
+  // later time, depending on a predicate. As actions comes through
+  // the system, you predicate will be called with each action. Once
+  // your predicate returns true, the queued function will be run and
+  // removed from the pending queue.
+
+  function addWhenDoubled(num) {
+    return {
+      type: services.WAIT_UNTIL,
+      predicate: action => action.type === constants.DOUBLE_NUMBER,
+      run: (dispatch, getState, action) => {
+        ok(action.type, constants.DOUBLE_NUMBER);
+        ok(getState(), 10);
+
+        dispatch({
+          type: constants.ADD_NUMBER,
+          value: 2
+        });
+      }
+    };
+  }
+
+  function addWhenGreaterThan(threshold, num) {
+    return (dispatch, getState) => {
+      dispatch({
+        type: services.WAIT_UNTIL,
+        predicate: () => getState().number > threshold,
+        run: () => {
+          dispatch({
+            type: constants.ADD_NUMBER,
+            value: num
+          });
+        }
+      });
+    }
+  }
+
+  const dispatcher = createDispatcher(stores);
+
+  // Add a pending action that adds 2 after the number is doubled
+  equal(dispatcher.getState().number, 1);
+  dispatcher.dispatch(addWhenDoubled(2));
+  equal(dispatcher.getState().number, 1);
+  dispatcher.dispatch({ type: constants.DOUBLE_NUMBER });
+  // Note how the pending function we added ran synchronously. It
+  // should have added 2 after doubling 1, so 1 * 2 + 2 = 4
+  equal(dispatcher.getState().number, 4);
+
+  // Add a pending action that adds 5 once the number is greater than 10
+  dispatcher.dispatch(addWhenGreaterThan(10, 5));
+  equal(dispatcher.getState().number, 4);
+  dispatcher.dispatch({ type: constants.ADD_NUMBER, value: 10 });
+  // Again, the pending function we added ran synchronously. It should
+  // have added 5 more after 10 was added, since the number was
+  // greater than 10.
+  equal(dispatcher.getState().number, 19);
+});
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/test/unit/xpcshell.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+tags = devtools
+head = head.js
+tail =
+firefox-appdir = browser
+skip-if = toolkit == 'android' || toolkit == 'gonk'
+
+support-files =
+  stores-for-testing.js
+
+[test_dispatcher.js]
+[test_middlewares.js]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/thunkMiddleware.js
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+/**
+ * A middleware that allows thunks (functions) to be dispatched.
+ * If it's a thunk, it is called with `dispatch` and `getState`,
+ * allowing the action to create multiple actions (most likely
+ * asynchronously).
+ */
+function thunkMiddleware({ dispatch, getState }) {
+  return next => action => {
+    return typeof action === "function"
+      ? action(dispatch, getState)
+      : next(action);
+  }
+}
+
+module.exports = thunkMiddleware;
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/fluxify/waitUntilService.js
@@ -0,0 +1,69 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const NAME = "@@service/waitUntil";
+
+/**
+ * A middleware which acts like a service, because it is stateful
+ * and "long-running" in the background. It provides the ability
+ * for actions to install a function to be run once when a specific
+ * condition is met by an action coming through the system. Think of
+ * it as a thunk that blocks until the condition is met. Example:
+ *
+ * ```js
+ * const services = { WAIT_UNTIL: require('waitUntilService').name };
+ *
+ * { type: services.WAIT_UNTIL,
+ *   predicate: action => action.type === constants.ADD_ITEM,
+ *   run: (dispatch, getState, action) => {
+ *     // Do anything here. You only need to accept the arguments
+ *     // if you need them. `action` is the action that satisfied
+ *     // the predicate.
+ *   }
+ * }
+ * ```
+ */
+function waitUntilService({ dispatch, getState }) {
+  let pending = [];
+
+  function checkPending(action) {
+    let readyRequests = [];
+    let stillPending = [];
+
+    // Find the pending requests whose predicates are satisfied with
+    // this action. Wait to run the requests until after we update the
+    // pending queue because the request handler may synchronously
+    // dispatch again and run this service (that use case is
+    // completely valid).
+    for (let request of pending) {
+      if (request.predicate(action)) {
+        readyRequests.push(request);
+      }
+      else {
+        stillPending.push(request);
+      }
+    }
+
+    pending = stillPending;
+    for (let request of readyRequests) {
+      request.run(dispatch, getState, action);
+    }
+  }
+
+  return next => action => {
+    if (action.type === NAME) {
+      pending.push(action);
+    }
+    else {
+      next(action);
+      checkPending(action);
+    }
+  }
+}
+
+module.exports = {
+  service: waitUntilService,
+  name: NAME
+};
--- a/browser/devtools/shared/moz.build
+++ b/browser/devtools/shared/moz.build
@@ -26,16 +26,18 @@ EXTRA_JS_MODULES.devtools += [
     'widgets/SimpleListWidget.jsm',
     'widgets/VariablesView.jsm',
     'widgets/VariablesViewController.jsm',
     'widgets/ViewHelpers.jsm',
 ]
 
 EXTRA_JS_MODULES.devtools.shared += [
     'autocomplete-popup.js',
+    'browser-loader.js',
+    'create-dispatcher.js',
     'devices.js',
     'doorhanger.js',
     'frame-script-utils.js',
     'getjson.js',
     'inplace-editor.js',
     'node-attribute-parser.js',
     'observable-object.js',
     'options-view.js',
@@ -67,8 +69,10 @@ EXTRA_JS_MODULES.devtools.shared.widgets
     'widgets/LineGraphWidget.js',
     'widgets/MdnDocsWidget.js',
     'widgets/MountainGraphWidget.js',
     'widgets/Spectrum.js',
     'widgets/TableWidget.js',
     'widgets/Tooltip.js',
     'widgets/TreeWidget.js',
 ]
+
+DIRS += ['fluxify']
--- a/browser/devtools/webconsole/network-panel.js
+++ b/browser/devtools/webconsole/network-panel.js
@@ -30,17 +30,16 @@ let l10n = new WebConsoleUtils.l10n(STRI
  *        The parent WebConsoleFrame object that owns this network panel
  *        instance.
  */
 function NetworkPanel(aParent, aHttpActivity, aWebConsoleFrame)
 {
   let doc = aParent.ownerDocument;
   this.httpActivity = aHttpActivity;
   this.webconsole = aWebConsoleFrame;
-  this._longStringClick = this._longStringClick.bind(this);
   this._responseBodyFetch = this._responseBodyFetch.bind(this);
   this._requestBodyFetch = this._requestBodyFetch.bind(this);
 
   // Create the underlaying panel
   this.panel = createElement(doc, "panel", {
     label: l10n.getStr("NetworkPanel.label"),
     titlebar: "normal",
     noautofocus: "true",
--- a/browser/devtools/webconsole/test/browser_console_hide_jsterm_when_devtools_chrome_enabled_false.js
+++ b/browser/devtools/webconsole/test/browser_console_hide_jsterm_when_devtools_chrome_enabled_false.js
@@ -29,22 +29,22 @@ function testObjectInspectorPropertiesAr
 
 function* getVariablesView(hud) {
   function openVariablesView(event, vview) {
     deferred.resolve(vview._variablesView);
   }
 
   let deferred = promise.defer();
   hud.jsterm.clearOutput();
-  hud.jsterm.execute("new Object()");
+  hud.jsterm.execute("new Object({ browser_console_hide_jsterm_test: true })");
 
   let [message] = yield waitForMessages({
     webconsole: hud,
     messages: [{
-      text: "Object",
+      text: "Object { browser_console_hide_jsterm_test: true }",
       category: CATEGORY_OUTPUT,
     }],
   });
 
   hud.jsterm.once("variablesview-fetched", openVariablesView);
 
   let anchor = [...message.matched][0].querySelector("a");
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_601667_filter_buttons.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_601667_filter_buttons.js
@@ -1,31 +1,52 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the filter button UI logic works correctly.
 
 "use strict";
 
 const TEST_URI = "http://example.com/";
+const FILTER_PREF_DOMAIN = "devtools.webconsole.filter.";
 
 let hud, hudId, hudBox;
+let prefs = {};
 
 let test = asyncTest(function* () {
   yield loadTab(TEST_URI);
 
   hud = yield openConsole();
   hudId = hud.hudId;
   hudBox = hud.ui.rootElement;
 
+  savePrefs();
+
   testFilterButtons();
 
+  restorePrefs();
+
   hud = hudId = hudBox = null;
 });
 
+function savePrefs() {
+  let branch = Services.prefs.getBranch(FILTER_PREF_DOMAIN);
+  let children = branch.getChildList("");
+  for (let child of children) {
+    prefs[child] = branch.getBoolPref(child);
+  }
+}
+
+function restorePrefs() {
+  let branch = Services.prefs.getBranch(FILTER_PREF_DOMAIN);
+  for (let p in prefs) {
+    branch.setBoolPref(p, prefs[p]);
+  }
+}
+
 function testFilterButtons() {
   testMenuFilterButton("net");
   testMenuFilterButton("css");
   testMenuFilterButton("js");
   testMenuFilterButton("logging");
   testMenuFilterButton("security");
   testMenuFilterButton("server");
 
--- a/mobile/android/base/prompts/PromptInput.java
+++ b/mobile/android/base/prompts/PromptInput.java
@@ -34,16 +34,18 @@ import android.widget.Spinner;
 import android.widget.TextView;
 import android.widget.TimePicker;
 
 public class PromptInput {
     protected final String mLabel;
     protected final String mType;
     protected final String mId;
     protected final String mValue;
+    protected final String mMinValue;
+    protected final String mMaxValue;
     protected OnChangeListener mListener;
     protected View mView;
     public static final String LOGTAG = "GeckoPromptInput";
 
     public interface OnChangeListener {
         public void onChange(PromptInput input);
     }
 
@@ -173,17 +175,17 @@ public class PromptInput {
             super(obj);
         }
 
         @Override
         public View getView(Context context) throws UnsupportedOperationException {
             if (mType.equals("date")) {
                 try {
                     DateTimePicker input = new DateTimePicker(context, "yyyy-MM-dd", mValue,
-                                                              DateTimePicker.PickersState.DATE);
+                                                              DateTimePicker.PickersState.DATE, mMinValue, mMaxValue);
                     input.toggleCalendar(true);
                     mView = (View)input;
                 } catch (UnsupportedOperationException ex) {
                     // We can't use our custom version of the DatePicker widget because the sdk is too old.
                     // But we can fallback on the native one.
                     DatePicker input = new DatePicker(context);
                     try {
                         if (!TextUtils.isEmpty(mValue)) {
@@ -195,39 +197,40 @@ public class PromptInput {
                         }
                     } catch (Exception e) {
                         Log.e(LOGTAG, "error parsing format string: " + e);
                     }
                     mView = (View)input;
                 }
             } else if (mType.equals("week")) {
                 DateTimePicker input = new DateTimePicker(context, "yyyy-'W'ww", mValue,
-                                                          DateTimePicker.PickersState.WEEK);
+                                                          DateTimePicker.PickersState.WEEK, mMinValue, mMaxValue);
                 mView = (View)input;
             } else if (mType.equals("time")) {
                 TimePicker input = new TimePicker(context);
                 input.setIs24HourView(DateFormat.is24HourFormat(context));
 
                 GregorianCalendar calendar = new GregorianCalendar();
                 if (!TextUtils.isEmpty(mValue)) {
                     try {
                         calendar.setTime(new SimpleDateFormat("HH:mm").parse(mValue));
                     } catch (Exception e) { }
                 }
                 input.setCurrentHour(calendar.get(GregorianCalendar.HOUR_OF_DAY));
                 input.setCurrentMinute(calendar.get(GregorianCalendar.MINUTE));
                 mView = (View)input;
             } else if (mType.equals("datetime-local") || mType.equals("datetime")) {
                 DateTimePicker input = new DateTimePicker(context, "yyyy-MM-dd HH:mm", mValue.replace("T"," ").replace("Z", ""),
-                                                          DateTimePicker.PickersState.DATETIME);
+                                                          DateTimePicker.PickersState.DATETIME, 
+                                                          mMinValue.replace("T"," ").replace("Z",""), mMaxValue.replace("T"," ").replace("Z", ""));
                 input.toggleCalendar(true);
                 mView = (View)input;
             } else if (mType.equals("month")) {
                 DateTimePicker input = new DateTimePicker(context, "yyyy-MM", mValue,
-                                                          DateTimePicker.PickersState.MONTH);
+                                                          DateTimePicker.PickersState.MONTH, mMinValue, mMaxValue);
                 mView = (View)input;
             }
             return mView;
         }
 
         private static String formatDateString(String dateFormat, Calendar calendar) {
             return new SimpleDateFormat(dateFormat).format(calendar.getTime());
         }
@@ -338,16 +341,18 @@ public class PromptInput {
     }
 
     public PromptInput(JSONObject obj) {
         mLabel = obj.optString("label");
         mType = obj.optString("type");
         String id = obj.optString("id");
         mId = TextUtils.isEmpty(id) ? mType : id;
         mValue = obj.optString("value");
+        mMaxValue = obj.optString("max");
+        mMinValue = obj.optString("min");
     }
 
     public static PromptInput getInput(JSONObject obj) {
         String type = obj.optString("type");
         switch (type) {
             case EditInput.INPUT_TYPE:
                 return new EditInput(obj);
             case NumberInput.INPUT_TYPE:
--- a/mobile/android/base/widget/DateTimePicker.java
+++ b/mobile/android/base/widget/DateTimePicker.java
@@ -231,28 +231,27 @@ public class DateTimePicker extends Fram
             setMonthShown(false);
             setWeekShown(true);
         } else if (mState == PickersState.MONTH) {
             setDayShown(false);
         }
     }
 
     public DateTimePicker(Context context) {
-        this(context, "", "", PickersState.DATE);
+        this(context, "", "", PickersState.DATE, null, null);
     }
 
-    public DateTimePicker(Context context, String dateFormat, String dateTimeValue, PickersState state) {
+    public DateTimePicker(Context context, String dateFormat, String dateTimeValue, PickersState state, String minDateValue, String maxDateValue) {
         super(context);
         if (Versions.preHC) {
             throw new UnsupportedOperationException("Custom DateTimePicker is only available for SDK > 10");
         }
 
         setCurrentLocale(Locale.getDefault());
-        mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
-        mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
+
         mState = state;
         LayoutInflater inflater = LayoutInflater.from(context);
         inflater.inflate(R.layout.datetime_picker, this, true);
 
         mOnChangeListener = new OnValueChangeListener();
 
         mDateSpinners = (LinearLayout)findViewById(R.id.date_spinners);
         mTimeSpinners = (LinearLayout)findViewById(R.id.time_spinners);
@@ -285,16 +284,17 @@ public class DateTimePicker extends Fram
             mCalendar.setVisibility(GONE);
 
             LayoutParams layoutParams = new LayoutParams(250,280);
             mCalendar.setLayoutParams(layoutParams);
             mCalendar.setFocusable(true);
             mCalendar.setFocusableInTouchMode(true);
             mCalendar.setMaxDate(mMaxDate.getTimeInMillis());
             mCalendar.setMinDate(mMinDate.getTimeInMillis());
+            mCalendar.setDate(mTempDate.getTimeInMillis(), false, false);
 
             mCalendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
                 @Override
                 public void onSelectedDayChange(
                     CalendarView view, int year, int month, int monthDay) {
                     mTempDate.set(year, month, monthDay);
                     setDate(mTempDate);
                     notifyDateChanged();
@@ -319,16 +319,39 @@ public class DateTimePicker extends Fram
             } else {
                 mTempDate.setTimeInMillis(System.currentTimeMillis());
             }
         } catch (Exception ex) {
             Log.e(LOGTAG, "Error parsing format string: " + ex);
             mTempDate.setTimeInMillis(System.currentTimeMillis());
         }
 
+	// Set the min / max attribute.
+	try {
+	    if (minDateValue != null && !minDateValue.equals("")) {
+		mMinDate.setTime(new SimpleDateFormat(dateFormat).parse(minDateValue));
+	    } else {
+		mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
+	    }
+	} catch (Exception ex) {
+	    Log.e(LOGTAG, "Error parsing format sting: " + ex);
+	    mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
+	}
+
+	try {
+	    if (maxDateValue != null && !maxDateValue.equals("")) {
+		mMaxDate.setTime(new SimpleDateFormat(dateFormat).parse(maxDateValue));
+	    } else {
+		mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
+	    }
+	} catch (Exception ex) {
+	    Log.e(LOGTAG, "Error parsing format string: " + ex);
+	    mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
+	}
+
         // Initialize all spinners.
         mDaySpinner = setupSpinner(R.id.day, 1,
                                    mTempDate.get(Calendar.DAY_OF_MONTH));
         mDaySpinner.setFormatter(TWO_DIGIT_FORMATTER);
         mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1);
 
         mMonthSpinner = setupSpinner(R.id.month, 1,
                                      mTempDate.get(Calendar.MONTH));
--- a/mobile/android/chrome/content/InputWidgetHelper.js
+++ b/mobile/android/chrome/content/InputWidgetHelper.js
@@ -29,16 +29,18 @@ var InputWidgetHelper = {
       buttons: [
         Strings.browser.GetStringFromName("inputWidgetHelper.set"),
         Strings.browser.GetStringFromName("inputWidgetHelper.clear"),
         Strings.browser.GetStringFromName("inputWidgetHelper.cancel")
       ],
     }).addDatePicker({
       value: aElement.value,
       type: type,
+      min: aElement.min,
+      max: aElement.max,
     }).show((function(data) {
       let changed = false;
       if (data.button == -1) {
         // This type is not supported with this android version.
         return;
       }
       if (data.button == 1) {
         // The user cleared the value.
--- a/mobile/android/modules/Prompt.jsm
+++ b/mobile/android/modules/Prompt.jsm
@@ -115,17 +115,19 @@ Prompt.prototype = {
       id : aOptions.id
     });
   },
 
   addDatePicker: function(aOptions) {
     return this._addInput({
       type: aOptions.type || "date",
       value: aOptions.value,
-      id: aOptions.id
+      id: aOptions.id,
+      max: aOptions.max,
+      min: aOptions.min
     });
   },
 
   addColorPicker: function(aOptions) {
     return this._addInput({
       type: "color",
       value: aOptions.value,
       id: aOptions.id
--- a/netwerk/test/mochitests/mochitest.ini
+++ b/netwerk/test/mochitests/mochitest.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = buildapp == 'b2g' || toolkit == 'android' # Android: Bug 1111137 & 1078267
+skip-if = buildapp == 'b2g'
 
 support-files =
   method.sjs
   partial_content.sjs
   rel_preconnect.sjs
   user_agent.sjs
   user_agent_update.sjs
   redirect_idn.html^headers^
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -373,17 +373,17 @@ function _setupDebuggerServer(breakpoint
                       .getService(Components.interfaces.nsIEnvironment);
   if (env.get("DEVTOOLS_DEBUGGER_LOG")) {
     prefs.setBoolPref("devtools.debugger.log", true);
   }
   if (env.get("DEVTOOLS_DEBUGGER_LOG_VERBOSE")) {
     prefs.setBoolPref("devtools.debugger.log.verbose", true);
   }
 
-  let { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+  let { require } = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {});
   let { DebuggerServer } = require("devtools/server/main");
   let { OriginalLocation } = require("devtools/server/actors/common");
   DebuggerServer.init();
   DebuggerServer.addBrowserActors();
   DebuggerServer.addActors("resource://testing-common/dbg-actors.js");
   DebuggerServer.allowChromeProcess = true;
 
   // An observer notification that tells us when we can "resume" script
--- a/toolkit/components/reader/ReaderMode.jsm
+++ b/toolkit/components/reader/ReaderMode.jsm
@@ -223,16 +223,22 @@ this.ReaderMode = {
                 return;
               }
               // Otherwise, pass an object indicating our new URL:
               reject({newURL: url});
               return;
             }
           }
         }
+        if (xhr.responseURL != url) {
+          // We were redirected without a meta refresh tag.
+          // Force redirect to the correct place:
+          reject({newURL: xhr.responseURL});
+          return;
+        }
         resolve(doc);
         histogram.add(DOWNLOAD_SUCCESS);
       }
       xhr.send();
     });
   },
 
 
--- a/toolkit/devtools/DevToolsUtils.js
+++ b/toolkit/devtools/DevToolsUtils.js
@@ -111,16 +111,48 @@ exports.zip = function zip(a, b) {
   for (let i = 0, aLength = a.length, bLength = b.length;
        i < aLength || i < bLength;
        i++) {
     pairs.push([a[i], b[i]]);
   }
   return pairs;
 };
 
+
+/**
+ * Converts an object into an array with 2-element arrays as key/value
+ * pairs of the object. `{ foo: 1, bar: 2}` would become
+ * `[[foo, 1], [bar 2]]` (order not guaranteed);
+ *
+ * @param object obj
+ * @returns array
+ */
+exports.entries = function entries(obj) {
+  return Object.keys(obj).map(k => [k, obj[k]]);
+}
+
+/**
+ * Composes the given functions into a single function, which will
+ * apply the results of each function right-to-left, starting with
+ * applying the given arguments to the right-most function.
+ * `compose(foo, bar, baz)` === `args => foo(bar(baz(args)`
+ *
+ * @param ...function funcs
+ * @returns function
+ */
+exports.compose = function compose(...funcs) {
+  return (...args) => {
+    const initialValue = funcs[funcs.length - 1].apply(null, args);
+    const leftFuncs = funcs.slice(0, -1);
+    return leftFuncs.reduceRight((composed, f) => f(composed),
+                                 initialValue);
+  };
+}
+
+
 /**
  * Waits for the next tick in the event loop to execute a callback.
  */
 exports.executeSoon = function executeSoon(aFn) {
   if (isWorker) {
     setImmediate(aFn);
   } else {
     Services.tm.mainThread.dispatch({