Merge MC -> JM.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 28 Jul 2011 18:10:31 -0700
changeset 76083 fbeb8b5a8a98eb50b462931668822a3ebd605880
parent 76082 aea5b967c21b2fa615d8698dd5aba5cccb69e9a4 (current diff)
parent 73497 dd7d71277a15b7f485c42499a1699d0ca41a5e78 (diff)
child 76084 d43c6dddeb2b599855caca3ac30d05f6b68e85ee
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone8.0a1
Merge MC -> JM.
config/fastcwd.pl
config/nfspwd.pl
content/base/public/nsIWebSocket.idl
content/html/content/test/test_bug41464.html
content/html/content/test/test_bug457800.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/interfaces/html/nsIDOMHTMLIsIndexElement.idl
dom/src/threads/Makefile.in
dom/src/threads/nsDOMWorkerLocation.cpp
dom/src/threads/nsDOMWorkerLocation.h
dom/src/threads/nsDOMWorkerNavigator.cpp
dom/src/threads/nsDOMWorkerNavigator.h
dom/src/threads/nsDOMWorkerScriptLoader.h
dom/src/threads/test/Makefile.in
dom/src/threads/test/WorkerTest.jsm
dom/src/threads/test/WorkerTest_badworker.js
dom/src/threads/test/WorkerTest_subworker.js
dom/src/threads/test/WorkerTest_worker.js
dom/src/threads/test/atob_worker.js
dom/src/threads/test/chromeWorker_subworker.js
dom/src/threads/test/chromeWorker_worker.js
dom/src/threads/test/closeOnGC_server.sjs
dom/src/threads/test/closeOnGC_worker.js
dom/src/threads/test/close_worker.js
dom/src/threads/test/errorPropagation_worker2.js
dom/src/threads/test/fibonacci_worker.js
dom/src/threads/test/functionHandlers_worker.js
dom/src/threads/test/importScripts_worker.js
dom/src/threads/test/importScripts_worker_imported1.js
dom/src/threads/test/importScripts_worker_imported2.js
dom/src/threads/test/importScripts_worker_imported3.js
dom/src/threads/test/importScripts_worker_imported4.js
dom/src/threads/test/json_worker.js
dom/src/threads/test/location_worker.js
dom/src/threads/test/longThread_worker.js
dom/src/threads/test/navigator_worker.js
dom/src/threads/test/newError_worker.js
dom/src/threads/test/recursion_worker.js
dom/src/threads/test/relativeLoad_import.js
dom/src/threads/test/relativeLoad_sub_import.js
dom/src/threads/test/relativeLoad_sub_worker.js
dom/src/threads/test/relativeLoad_sub_worker2.js
dom/src/threads/test/relativeLoad_worker.js
dom/src/threads/test/relativeLoad_worker2.js
dom/src/threads/test/scopeOnerror_worker.js
dom/src/threads/test/simpleThread_worker.js
dom/src/threads/test/suspend_iframe.html
dom/src/threads/test/suspend_worker.js
dom/src/threads/test/terminate_worker.js
dom/src/threads/test/testXHR.txt
dom/src/threads/test/test_404.html
dom/src/threads/test/test_atob.html
dom/src/threads/test/test_chromeWorker.html
dom/src/threads/test/test_chromeWorker.xul
dom/src/threads/test/test_chromeWorkerJSM.xul
dom/src/threads/test/test_close.html
dom/src/threads/test/test_closeOnGC.html
dom/src/threads/test/test_errorPropagation.html
dom/src/threads/test/test_fibonacci.html
dom/src/threads/test/test_importScripts.html
dom/src/threads/test/test_json.html
dom/src/threads/test/test_location.html
dom/src/threads/test/test_longThread.html
dom/src/threads/test/test_navigator.html
dom/src/threads/test/test_newError.html
dom/src/threads/test/test_recursion.html
dom/src/threads/test/test_relativeLoad.html
dom/src/threads/test/test_simpleThread.html
dom/src/threads/test/test_suspend.html
dom/src/threads/test/test_terminate.html
dom/src/threads/test/test_threadErrors.html
dom/src/threads/test/test_threadTimeouts.html
dom/src/threads/test/test_throwingOnerror.html
dom/src/threads/test/test_xhr.html
dom/src/threads/test/test_xhrAbort.html
dom/src/threads/test/test_xpcom.html
dom/src/threads/test/threadErrors_worker1.js
dom/src/threads/test/threadErrors_worker2.js
dom/src/threads/test/threadErrors_worker3.js
dom/src/threads/test/threadErrors_worker4.js
dom/src/threads/test/threadTimeouts_worker.js
dom/src/threads/test/throwingOnerror_worker.js
dom/src/threads/test/xhrAbort_worker.js
dom/src/threads/test/xhr_worker.js
dom/src/threads/test/xpcom_worker.js
dom/workers/Makefile.in
dom/workers/test/Makefile.in
dom/workers/test/WorkerTest.jsm
dom/workers/test/atob_worker.js
dom/workers/test/chromeWorker_subworker.js
dom/workers/test/chromeWorker_worker.js
dom/workers/test/closeOnGC_worker.js
dom/workers/test/importScripts_worker.js
dom/workers/test/importScripts_worker_imported1.js
dom/workers/test/importScripts_worker_imported2.js
dom/workers/test/json_worker.js
dom/workers/test/recursion_worker.js
dom/workers/test/relativeLoad_sub_worker.js
dom/workers/test/relativeLoad_worker.js
dom/workers/test/simpleThread_worker.js
dom/workers/test/terminate_worker.js
dom/workers/test/test_404.html
dom/workers/test/test_chromeWorker.html
dom/workers/test/test_chromeWorker.xul
dom/workers/test/test_chromeWorkerJSM.xul
dom/workers/test/test_close.html
dom/workers/test/test_closeOnGC.html
dom/workers/test/test_errorPropagation.html
dom/workers/test/test_fibonacci.html
dom/workers/test/test_importScripts.html
dom/workers/test/test_json.html
dom/workers/test/test_longThread.html
dom/workers/test/test_navigator.html
dom/workers/test/test_recursion.html
dom/workers/test/test_relativeLoad.html
dom/workers/test/test_simpleThread.html
dom/workers/test/test_suspend.html
dom/workers/test/test_terminate.html
dom/workers/test/test_threadErrors.html
dom/workers/test/test_threadTimeouts.html
dom/workers/test/test_throwingOnerror.html
dom/workers/test/test_xhr.html
dom/workers/test/test_xhrAbort.html
dom/workers/test/threadTimeouts_worker.js
dom/workers/test/xhr_worker.js
gfx/src/nsIRegion.h
gfx/src/nsThebesRegion.cpp
gfx/src/nsThebesRegion.h
js/src/Makefile.in
js/src/assembler/assembler/MacroAssemblerX86Common.h
js/src/config/autoconf.mk.in
js/src/config/fastcwd.pl
js/src/config/nfspwd.pl
js/src/configure.in
js/src/jsapi-tests/testConservativeGC.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsarray.h
js/src/jsatom.cpp
js/src/jsbuiltins.h
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsdbgapiinlines.h
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcmark.cpp
js/src/jsgcmark.h
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsparse.cpp
js/src/jspropertycache.cpp
js/src/jsproxy.cpp
js/src/jsprvtd.h
js/src/jsreflect.cpp
js/src/jsregexp.cpp
js/src/jsregexpinlines.h
js/src/jsscope.cpp
js/src/jsscope.h
js/src/jsscopeinlines.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jsstrinlines.h
js/src/jstracer.cpp
js/src/jstracer.h
js/src/jstypedarray.cpp
js/src/jstypedarrayinlines.h
js/src/jsvalue.h
js/src/jsxml.cpp
js/src/methodjit/BaseAssembler.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/MachineRegs.h
js/src/methodjit/MonoIC.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/PolyIC.h
js/src/methodjit/StubCalls.cpp
js/src/shell/Makefile.in
js/src/shell/js.cpp
js/src/tests/ecma/String/15.5.4.11-2.js
js/src/tests/ecma/String/15.5.4.11-5.js
js/src/tests/ecma/String/15.5.4.12-1.js
js/src/tests/ecma/String/15.5.4.12-4.js
js/src/tests/js1_8_5/extensions/jstests.list
js/src/tracejit/Writer.h
js/src/vm/GlobalObject.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/xpconnect/shell/xpcshell.cpp
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/wrappers/WrapperFactory.cpp
layout/reftests/ogg-video/poster-14.html
modules/libpref/src/init/all.js
security/coreconf/Linux2.1.mk
security/coreconf/Linux2.2.mk
security/coreconf/Linux2.4.mk
security/coreconf/Linux2.5.mk
security/coreconf/Linux2.6.mk
security/coreconf/LinuxELF1.2.mk
security/coreconf/LinuxELF2.0.mk
security/patches/bug-662557-nss-debug-sec-error-no-memory.patch
services/sync/tests/unit/test_service_quota.js
toolkit/components/console/hudservice/AutocompletePopup.jsm
toolkit/components/console/hudservice/HUDService.jsm
toolkit/components/console/hudservice/Makefile.in
toolkit/components/console/hudservice/NetworkHelper.jsm
toolkit/components/console/hudservice/NetworkPanel.xhtml
toolkit/components/console/hudservice/PropertyPanel.jsm
toolkit/components/console/hudservice/tests/Makefile.in
toolkit/components/console/hudservice/tests/browser/Makefile.in
toolkit/components/console/hudservice/tests/browser/browser_warn_user_about_replaced_api.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_abbreviate_source_url.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_basic_net_logging.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_578437_page_reload.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_579412_input_focus.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580001_closing_after_completion.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580400_groups.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580454_timestamp_l10n.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_581231_close_button.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_582201_duplicate_errors.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_583816_tab_focus.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585237_line_limit.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585956_console_trace.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585991_autocomplete_keys.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585991_autocomplete_popup.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_586388_select_all.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_587617_output_copy.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588342_document_focus.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588730_text_node_insertion.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588967_input_expansion.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_589162_css_filter.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_592442_closing_brackets.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594477_clickable_output.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594497_history_arrow_keys.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595223_file_uri.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595350_multiple_windows_and_tabs.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595934_message_categories.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597136_external_script_errors.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597136_network_requests_from_chrome.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597460_filter_scroll.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597756_reopen_closed_tab.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_598357_jsterm_output.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_599725_response_headers.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_600183_charset.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601177_log_levels.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601352_scroll.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601667_filter_buttons.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601909_remember_height.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_602572_log_bodies_checkbox.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_603750_websocket.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_611795.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613013_console_api_iframe.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613280_jsterm_copy.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613642_maintain_scroll.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613642_prune_scroll.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_614793_jsterm_scroll.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618078_network_exceptions.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618311_close_panels.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618311_private_browsing.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_621644_jsterm_dollar.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_626484_output_copy_order.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_630733_response_redirect_headers.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632347_iterators_generators.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632817.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_642108_pruneTest.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_642615_autocomplete.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_644419_log_limits.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_651501_document_body_autocomplete.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_660806_history_nav.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_663443_panel_title.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_chrome.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_completion.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_extras.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_logging_api.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_consoleonpage.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_copying_multiple_messages_inserts_newlines_in_between.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_execution_scope.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_history.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_hud_getters.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_js_input_and_output_styling.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_js_input_expansion.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_jsterm.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_live_filtering_of_message_types.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_live_filtering_on_search_strings.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_log_node_classes.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_message_node_id.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_netlogging.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_network_panel.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_notifications.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_null_and_undefined_output.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_output_order.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_position_ui.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_property_panel.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_property_provider.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_registries.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_create_display.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_iteration.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_record_entry.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_record_many_entries.js
toolkit/components/console/hudservice/tests/browser/browser_webconsole_view_source.js
toolkit/components/console/hudservice/tests/browser/head.js
toolkit/components/console/hudservice/tests/browser/test-bug-585956-console-trace.html
toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud-iframe.html
toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas-css.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas-css.js
toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas.js
toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-loader.css
toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-loader.css^headers^
toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-loader.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-parser.css
toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-parser.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-events-external2.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-events-external2.js
toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-events.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-html-external.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-html-external.js
toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-html.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-empty-getelementbyid.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-empty-getelementbyid.js
toolkit/components/console/hudservice/tests/browser/test-bug-595934-html.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-image.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-image.jpg
toolkit/components/console/hudservice/tests/browser/test-bug-595934-imagemap.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-malformedxml-external.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-malformedxml-external.xml
toolkit/components/console/hudservice/tests/browser/test-bug-595934-malformedxml.xhtml
toolkit/components/console/hudservice/tests/browser/test-bug-595934-svg.xhtml
toolkit/components/console/hudservice/tests/browser/test-bug-595934-workers.html
toolkit/components/console/hudservice/tests/browser/test-bug-595934-workers.js
toolkit/components/console/hudservice/tests/browser/test-bug-597136-external-script-errors.html
toolkit/components/console/hudservice/tests/browser/test-bug-597136-external-script-errors.js
toolkit/components/console/hudservice/tests/browser/test-bug-597756-reopen-closed-tab.html
toolkit/components/console/hudservice/tests/browser/test-bug-599725-response-headers.sjs
toolkit/components/console/hudservice/tests/browser/test-bug-600183-charset.html
toolkit/components/console/hudservice/tests/browser/test-bug-600183-charset.html^headers^
toolkit/components/console/hudservice/tests/browser/test-bug-601177-log-levels.html
toolkit/components/console/hudservice/tests/browser/test-bug-601177-log-levels.js
toolkit/components/console/hudservice/tests/browser/test-bug-603750-websocket.html
toolkit/components/console/hudservice/tests/browser/test-bug-603750-websocket.js
toolkit/components/console/hudservice/tests/browser/test-bug-613013-console-api-iframe.html
toolkit/components/console/hudservice/tests/browser/test-bug-618078-network-exceptions.html
toolkit/components/console/hudservice/tests/browser/test-bug-621644-jsterm-dollar.html
toolkit/components/console/hudservice/tests/browser/test-bug-630733-response-redirect-headers.sjs
toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html
toolkit/components/console/hudservice/tests/browser/test-bug-632347-iterators-generators.html
toolkit/components/console/hudservice/tests/browser/test-bug-644419-log-limits.html
toolkit/components/console/hudservice/tests/browser/test-bug-646025-console-file-location.html
toolkit/components/console/hudservice/tests/browser/test-console-extras.html
toolkit/components/console/hudservice/tests/browser/test-console-replaced-api.html
toolkit/components/console/hudservice/tests/browser/test-console.html
toolkit/components/console/hudservice/tests/browser/test-data.json
toolkit/components/console/hudservice/tests/browser/test-duplicate-error.html
toolkit/components/console/hudservice/tests/browser/test-encoding-ISO-8859-1.html
toolkit/components/console/hudservice/tests/browser/test-error.html
toolkit/components/console/hudservice/tests/browser/test-file-location.js
toolkit/components/console/hudservice/tests/browser/test-filter.html
toolkit/components/console/hudservice/tests/browser/test-image.png
toolkit/components/console/hudservice/tests/browser/test-mutation.html
toolkit/components/console/hudservice/tests/browser/test-network-request.html
toolkit/components/console/hudservice/tests/browser/test-network.html
toolkit/components/console/hudservice/tests/browser/test-observe-http-ajax.html
toolkit/components/console/hudservice/tests/browser/test-own-console.html
toolkit/components/console/hudservice/tests/browser/test-property-provider.html
toolkit/components/console/hudservice/tests/browser/testscript.js
--- a/accessible/public/nsIAccessNode.idl
+++ b/accessible/public/nsIAccessNode.idl
@@ -49,17 +49,17 @@ interface nsIDOMCSSPrimitiveValue;
  * every DOM node can have one nsIAccessNode for each
  * pres shell the DOM node is rendered in.
  * The nsIAccessNode implementations are instantiated lazily.
  * The nsIAccessNode tree for a given dom window
  * has a one to one relationship to the DOM tree.
  * If the DOM node for this access node is "accessible",
  * then a QueryInterface to nsIAccessible will succeed.
  */
-[scriptable, uuid(ef16ff42-0256-4b48-ae87-b18a95b7f7d6)]
+[scriptable, uuid(bbbd5a68-bad2-48c1-ab09-beb6c34f03d9)]
 interface nsIAccessNode : nsISupports
 {
   /**
    * The DOM node this nsIAccessNode is associated with.
    */
   readonly attribute nsIDOMNode DOMNode;
 
   /**
@@ -95,22 +95,16 @@ interface nsIAccessNode : nsISupports
    *                         the screen or the parent object (for available
    *                         constants refer to nsIAccessibleCoordinateType)
    * @param aX - defines the x coordinate
    * @param aY - defines the y coordinate
   */
   void scrollToPoint(in unsigned long aCoordinateType, in long aX, in long aY);
 
   /**
-   * The OS window handle for the window this node
-   * is being displayed in.
-   */
-  [noscript] readonly attribute voidPtr ownerWindow;
-  
-  /**
    * A unique ID calculated for this DOM node, for the 
    * purposes of caching and referencing this object.
    */
   [noscript] readonly attribute voidPtr uniqueID;
 
   /**
    * Retrieve the computed style value for this DOM node, if it is a DOM element.
    * Note: the meanings of width, height and other size measurements depend
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -112,17 +112,16 @@ static gint sListener_idx = 1;
                                     MAI_TYPE_UTIL))
 #define MAI_IS_UTIL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), \
                                     MAI_TYPE_UTIL))
 #define MAI_UTIL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), \
                                     MAI_TYPE_UTIL, MaiUtilClass))
 
 static GHashTable* sKey_listener_list = NULL;
 static guint sKey_snooper_id = 0;
-static GQuark sQuark_gecko_acc_obj = g_quark_from_static_string("GeckoAccObj");
 static bool sToplevel_event_hook_added = false;
 static gulong sToplevel_show_hook = 0;
 static gulong sToplevel_hide_hook = 0;
 
 G_BEGIN_DECLS
 typedef void (*GnomeAccessibilityInit) (void);
 typedef void (*GnomeAccessibilityShutdown) (void);
 G_END_DECLS
@@ -565,16 +564,21 @@ nsApplicationAccessibleWrap::~nsApplicat
 }
 
 static gboolean
 toplevel_event_watcher(GSignalInvocationHint* ihint,
                        guint                  n_param_values,
                        const GValue*          param_values,
                        gpointer               data)
 {
+  static GQuark sQuark_gecko_acc_obj = 0;
+
+  if (!sQuark_gecko_acc_obj)
+    sQuark_gecko_acc_obj = g_quark_from_static_string("GeckoAccObj");
+
   if (nsAccessibilityService::IsShutdown())
     return TRUE;
 
   GObject* object = reinterpret_cast<GObject*>(g_value_get_object(param_values));
   if (!GTK_IS_WINDOW(object))
     return TRUE;
 
   AtkObject* child = gtk_widget_get_accessible(GTK_WIDGET(object));
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -277,16 +277,20 @@ NotificationController::WillRefresh(mozi
 
   PRUint32 notificationCount = notifications.Length();
   for (PRUint32 idx = 0; idx < notificationCount; idx++) {
     notifications[idx]->Process();
     if (!mDocument)
       return;
   }
 
+  // Process invalidation list of the document after all accessible tree
+  // modification are done.
+  mDocument->ProcessInvalidationList();
+
   // If a generic notification occurs after this point then we may be allowed to
   // process it synchronously.
   mObservingState = eRefreshObserving;
 
   // Process only currently queued events.
   nsTArray<nsRefPtr<AccEvent> > events;
   events.SwapElements(mEvents);
 
--- a/accessible/src/base/nsAccDocManager.h
+++ b/accessible/src/base/nsAccDocManager.h
@@ -201,16 +201,29 @@ private:
 #define NS_LOG_ACCDOC_TYPE(aDocument)                                          \
   if (aDocument->IsActive()) {                                                 \
     PRBool isContent = nsCoreUtils::IsContentDocument(aDocument);              \
     printf("%s document", (isContent ? "content" : "chrome"));                 \
   } else {                                                                     \
     printf("document type: [failed]");                                         \
   }
 
+#define NS_LOG_ACCDOC_DOCSHELLTREE(aDocument)                                  \
+  if (aDocument->IsActive()) {                                                 \
+    nsCOMPtr<nsISupports> container = aDocument->GetContainer();               \
+    nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));      \
+    nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;                              \
+    treeItem->GetParent(getter_AddRefs(parentTreeItem));                       \
+    nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;                                \
+    treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));                   \
+    printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;",   \
+           parentTreeItem, rootTreeItem,                                       \
+           (nsCoreUtils::IsTabDocument(aDocument) ? "yes" : "no"));            \
+  }
+
 #define NS_LOG_ACCDOC_SHELLSTATE(aDocument)                                    \
   nsCAutoString docShellBusy;                                                  \
   nsCOMPtr<nsISupports> container = aDocument->GetContainer();                 \
   if (container) {                                                             \
     nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);             \
     PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;                         \
     docShell->GetBusyFlags(&busyFlags);                                        \
     if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE)                             \
@@ -347,16 +360,18 @@ private:
     printf("\n    ");                                                          \
     if (aDocument) {                                                           \
       NS_LOG_ACCDOC_URI(aDocument)                                             \
       printf("\n    ");                                                        \
       NS_LOG_ACCDOC_SHELLSTATE(aDocument)                                      \
       printf("; ");                                                            \
       NS_LOG_ACCDOC_TYPE(aDocument)                                            \
       printf("\n    ");                                                        \
+      NS_LOG_ACCDOC_DOCSHELLTREE(aDocument)                                    \
+      printf("\n    ");                                                        \
       NS_LOG_ACCDOC_DOCSTATES(aDocument)                                       \
       printf("\n    ");                                                        \
       NS_LOG_ACCDOC_DOCPRESSHELL(aDocument)                                    \
       printf("\n    ");                                                        \
       NS_LOG_ACCDOC_DOCLOADGROUP(aDocument)                                    \
       printf(", ");                                                            \
       NS_LOG_ACCDOC_DOCPARENT(aDocument)                                       \
       printf("\n");                                                            \
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -156,29 +156,16 @@ NS_IMETHODIMP
 nsAccessNode::GetUniqueID(void **aUniqueID)
 {
   NS_ENSURE_ARG_POINTER(aUniqueID);
 
   *aUniqueID = UniqueID();
   return NS_OK;
 }
 
-// nsIAccessNode
-NS_IMETHODIMP
-nsAccessNode::GetOwnerWindow(void **aWindow)
-{
-  NS_ENSURE_ARG_POINTER(aWindow);
-  *aWindow = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  return GetDocAccessible()->GetWindowHandle(aWindow);
-}
-
 nsApplicationAccessible*
 nsAccessNode::GetApplicationAccessible()
 {
   NS_ASSERTION(!nsAccessibilityService::IsShutdown(),
                "Accessibility wasn't initialized!");
 
   if (!gApplicationAccessible) {
     nsApplicationAccessibleWrap::PreCreate();
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -3105,26 +3105,17 @@ nsAccessible::EnsureChildren()
   }
 
   if (!IsChildrenFlag(eChildrenUninitialized))
     return false;
 
   // State is embedded children until text leaf accessible is appended.
   SetChildrenFlag(eEmbeddedChildren); // Prevent reentry
 
-  // Notify the document about caching status.
-  nsDocAccessible* document = GetDocAccessible();
-  if (document)
-    document->NotifyOfCachingStart(this);
-
   CacheChildren();
-
-  if (document)
-    document->NotifyOfCachingEnd(this);
-
   return false;
 }
 
 nsAccessible*
 nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError) const
 {
   if (!mParent || mIndexInParent == -1) {
     if (aError)
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -479,24 +479,16 @@ nsApplicationAccessible::ScrollTo(PRUint
 NS_IMETHODIMP
 nsApplicationAccessible::ScrollToPoint(PRUint32 aCoordinateType,
                                        PRInt32 aX, PRInt32 aY)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsApplicationAccessible::GetOwnerWindow(void **aOwnerWindow)
-{
-  NS_ENSURE_ARG_POINTER(aOwnerWindow);
-  *aOwnerWindow = nsnull;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsApplicationAccessible::GetComputedStyleValue(const nsAString &aPseudoElt,
                                                const nsAString &aPropertyName,
                                                nsAString &aValue)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -71,17 +71,16 @@ public:
 
   // nsIAccessNode
   NS_SCRIPTABLE NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode);
   NS_SCRIPTABLE NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
   NS_SCRIPTABLE NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
   NS_SCRIPTABLE NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   NS_SCRIPTABLE NS_IMETHOD ScrollTo(PRUint32 aScrollType);
   NS_SCRIPTABLE NS_IMETHOD ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY);
-  NS_IMETHOD GetOwnerWindow(void **aOwnerWindow);
   NS_SCRIPTABLE NS_IMETHOD GetComputedStyleValue(const nsAString& aPseudoElt,
                                                  const nsAString& aPropertyName,
                                                  nsAString& aValue NS_OUTPARAM);
   NS_SCRIPTABLE NS_IMETHOD GetComputedStyleCSSValue(const nsAString& aPseudoElt,
                                                     const nsAString& aPropertyName,
                                                     nsIDOMCSSPrimitiveValue** aValue NS_OUTPARAM);
   NS_SCRIPTABLE NS_IMETHOD GetLanguage(nsAString& aLanguage);
 
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -475,16 +475,36 @@ nsCoreUtils::IsContentDocument(nsIDocume
     do_QueryInterface(container);
   NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!");
 
   PRInt32 contentType;
   docShellTreeItem->GetItemType(&contentType);
   return (contentType == nsIDocShellTreeItem::typeContent);
 }
 
+bool
+nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode)
+{
+  nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
+  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
+
+  nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
+  treeItem->GetParent(getter_AddRefs(parentTreeItem));
+
+  // Tab document running in own process doesn't have parent.
+  if (XRE_GetProcessType() == GeckoProcessType_Content)
+    return !parentTreeItem;
+
+  // Parent of docshell for tab document running in chrome process is root.
+  nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
+  treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
+
+  return parentTreeItem == rootTreeItem;
+}
+
 PRBool
 nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
 {
   nsIURI *uri = aDocument->GetDocumentURI();
   PRBool isAboutScheme = PR_FALSE;
   uri->SchemeIs("about", &isAboutScheme);
   if (!isAboutScheme)
     return PR_FALSE;
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -229,16 +229,21 @@ public:
   static PRBool IsRootDocument(nsIDocument *aDocument);
 
   /**
    * Return true if the given document is content document (not chrome).
    */
   static PRBool IsContentDocument(nsIDocument *aDocument);
 
   /**
+   * Return true if the given document node is for tab document accessible.
+   */
+  static bool IsTabDocument(nsIDocument* aDocumentNode);
+
+  /**
    * Return true if the given document is an error page.
    */
   static PRBool IsErrorPage(nsIDocument *aDocument);
 
   /**
    * Retrun true if the type of given frame equals to the given frame type.
    *
    * @param aFrame  the frame
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -99,18 +99,17 @@ static const PRUint32 kRelationAttrsLen 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor/desctructor
 
 nsDocAccessible::
   nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
                   nsIWeakReference *aShell) :
   nsHyperTextAccessibleWrap(aRootContent, aShell),
-  mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE),
-  mCacheRoot(nsnull), mIsPostCacheProcessing(PR_FALSE)
+  mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE)
 {
   mFlags |= eDocAccessible;
 
   mDependentIDsHash.Init();
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessibleCache.Init(kDefaultCacheSize);
   mNodeToAccessibleMap.Init(kDefaultCacheSize);
 
@@ -1420,53 +1419,40 @@ nsDocAccessible::RecreateAccessible(nsIC
     // Remove and reinsert.
     UpdateTree(container, aContent, false);
     container->UpdateChildren();
     UpdateTree(container, aContent, true);
   }
 }
 
 void
-nsDocAccessible::NotifyOfCachingStart(nsAccessible* aAccessible)
+nsDocAccessible::ProcessInvalidationList()
 {
-  if (!mCacheRoot)
-    mCacheRoot = aAccessible;
-}
-
-void
-nsDocAccessible::NotifyOfCachingEnd(nsAccessible* aAccessible)
-{
-  if (mCacheRoot == aAccessible && !mIsPostCacheProcessing) {
-    // Allow invalidation list insertions while container children are recached.
-    mIsPostCacheProcessing = PR_TRUE;
+  // Invalidate children of container accessible for each element in
+  // invalidation list. Allow invalidation list insertions while container
+  // children are recached.
+  for (PRUint32 idx = 0; idx < mInvalidationList.Length(); idx++) {
+    nsIContent* content = mInvalidationList[idx];
+    nsAccessible* accessible = GetAccessible(content);
+    if (!accessible) {
+      nsAccessible* container = GetContainerAccessible(content);
+      NS_ASSERTION(container,
+                   "Got a referenced element that is not in document!");
+      if (container) {
+        container->UpdateChildren();
+        accessible = GetAccessible(content);
+      }
+    }
 
-    // Invalidate children of container accessible for each element in
-    // invalidation list.
-    for (PRUint32 idx = 0; idx < mInvalidationList.Length(); idx++) {
-      nsIContent* content = mInvalidationList[idx];
-      nsAccessible* accessible = GetAccessible(content);
-      if (!accessible) {
-        nsAccessible* container = GetContainerAccessible(content);
-        NS_ASSERTION(container,
-                     "Got a referenced element that is not in document!");
-        if (container) {
-          container->UpdateChildren();
-          accessible = GetAccessible(content);
-        }
-      }
+    // Make sure the subtree is created.
+    if (accessible)
+      CacheChildrenInSubtree(accessible);
+  }
 
-      // Make sure the subtree is created.
-      if (accessible)
-        CacheChildrenInSubtree(accessible);
-    }
-    mInvalidationList.Clear();
-
-    mCacheRoot = nsnull;
-    mIsPostCacheProcessing = PR_FALSE;
-  }
+  mInvalidationList.Clear();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible protected
 
 void
 nsDocAccessible::CacheChildren()
 {
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -320,27 +320,16 @@ public:
       mNotificationController->ScheduleTextUpdate(aTextNode);
   }
 
   /**
    * Recreate an accessible, results in hide/show events pair.
    */
   void RecreateAccessible(nsIContent* aContent);
 
-  /**
-   * Used to notify the document that the accessible caching is started or
-   * finished.
-   *
-   * While children are cached we may encounter the case there's no accessible
-   * for referred content by related accessible. Keep the caching root and
-   * these related nodes to invalidate their containers after root caching.
-   */
-  void NotifyOfCachingStart(nsAccessible* aAccessible);
-  void NotifyOfCachingEnd(nsAccessible* aAccessible);
-
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
 
   // nsDocAccessible
     virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
     virtual nsresult AddEventListeners();
@@ -435,16 +424,25 @@ protected:
 
   /**
    * Update the accessible tree for inserted content.
    */
   void ProcessContentInserted(nsAccessible* aContainer,
                               const nsTArray<nsCOMPtr<nsIContent> >* aInsertedContent);
 
   /**
+   * Used to notify the document to make it process the invalidation list.
+   *
+   * While children are cached we may encounter the case there's no accessible
+   * for referred content by related accessible. Store these related nodes to
+   * invalidate their containers later.
+   */
+  void ProcessInvalidationList();
+
+  /**
    * Update the accessible tree for content insertion or removal.
    */
   void UpdateTree(nsAccessible* aContainer, nsIContent* aChildNode,
                   bool aIsInsert);
 
   /**
    * Helper for UpdateTree() method. Go down to DOM subtree and updates
    * accessible tree. Return one of these flags.
@@ -527,25 +525,22 @@ protected:
    * The cache of IDs pointed by relation attributes.
    */
   typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray;
   nsClassHashtable<nsStringHashKey, AttrRelProviderArray> mDependentIDsHash;
 
   friend class RelatedAccIterator;
 
   /**
-   * Used for our caching algorithm. We store the root of the tree that needs
-   * caching, the list of nodes that should be invalidated, and whether we are
-   * processing the invalidation list.
+   * Used for our caching algorithm. We store the list of nodes that should be
+   * invalidated.
    *
-   * @see NotifyOfCachingStart/NotifyOfCachingEnd
+   * @see ProcessInvalidationList
    */
-  nsAccessible* mCacheRoot;
   nsTArray<nsIContent*> mInvalidationList;
-  PRBool mIsPostCacheProcessing;
 
   /**
    * Used to process notification from core and accessible events.
    */
   nsRefPtr<NotificationController> mNotificationController;
   friend class NotificationController;
 };
 
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -102,17 +102,20 @@ EXPORTS = \
   CAccessibleTable.h \
   CAccessibleTableCell.h \
   CAccessibleValue.h \
   $(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../base \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xul \
+  -I$(srcdir)/../../../content/base/src \
+  -I$(srcdir)/../../../content/events/src \
   $(NULL)
-
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -199,17 +199,17 @@ STDMETHODIMP nsAccessibleWrap::get_accPa
     return E_FAIL;
 
   nsRefPtr<nsDocAccessible> doc(do_QueryObject(this));
   if (doc) {
     // Return window system accessible object for root document and tab document
     // accessibles.
     if (!doc->ParentDocument() ||
         nsWinUtils::IsWindowEmulationStarted() &&
-        nsWinUtils::IsTabDocument(doc->GetDocumentNode())) {
+        nsCoreUtils::IsTabDocument(doc->GetDocumentNode())) {
       HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
       if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
                                                        IID_IAccessible,
                                                        (void**)ppdispParent))) {
         return S_OK;
       }
     }
   }
--- a/accessible/src/msaa/nsDocAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsDocAccessibleWrap.cpp
@@ -31,16 +31,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "mozilla/dom/TabChild.h"
+
 #include "nsDocAccessibleWrap.h"
 #include "ISimpleDOMDocument_i.c"
 #include "nsIAccessibilityService.h"
 #include "nsRootAccessible.h"
 #include "nsWinUtils.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeNode.h"
@@ -237,17 +239,17 @@ STDMETHODIMP nsDocAccessibleWrap::get_ac
 // nsAccessNode
 
 void
 nsDocAccessibleWrap::Shutdown()
 {
   // Do window emulation specific shutdown if emulation was started.
   if (nsWinUtils::IsWindowEmulationStarted()) {
     // Destroy window created for root document.
-    if (nsWinUtils::IsTabDocument(mDocument)) {
+    if (nsCoreUtils::IsTabDocument(mDocument)) {
       sHWNDCache.Remove(mHWND);
       ::DestroyWindow(static_cast<HWND>(mHWND));
     }
 
     mHWND = nsnull;
   }
 
   nsDocAccessible::Shutdown();
@@ -267,34 +269,44 @@ nsDocAccessibleWrap::GetNativeWindow() c
 
 void
 nsDocAccessibleWrap::NotifyOfInitialUpdate()
 {
   nsDocAccessible::NotifyOfInitialUpdate();
 
   if (nsWinUtils::IsWindowEmulationStarted()) {
     // Create window for tab document.
-    if (nsWinUtils::IsTabDocument(mDocument)) {
+    if (nsCoreUtils::IsTabDocument(mDocument)) {
+      mozilla::dom::TabChild* tabChild =
+        mozilla::dom::GetTabChildFrom(mDocument->GetShell());
+
       nsRootAccessible* rootDocument = RootAccessible();
 
+      mozilla::WindowsHandle nativeData = nsnull;
+      if (tabChild)
+        tabChild->SendGetWidgetNativeData(&nativeData);
+      else
+        nativeData = reinterpret_cast<mozilla::WindowsHandle>(
+          rootDocument->GetNativeWindow());
+
       PRBool isActive = PR_TRUE;
       PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
       if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle)) {
         GetBounds(&x, &y, &width, &height);
         PRInt32 rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0;
         rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight);
         x = rootX - x;
         y -= rootY;
 
         nsCOMPtr<nsISupports> container = mDocument->GetContainer();
         nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
         docShell->GetIsActive(&isActive);
       }
 
-      HWND parentWnd = static_cast<HWND>(rootDocument->GetNativeWindow());
+      HWND parentWnd = reinterpret_cast<HWND>(nativeData);
       mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd,
                                              x, y, width, height, isActive);
 
       sHWNDCache.Put(mHWND, this);
 
     } else {
       nsDocAccessible* parentDocument = ParentDocument();
       if (parentDocument)
--- a/accessible/src/msaa/nsRootAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsRootAccessibleWrap.cpp
@@ -59,17 +59,17 @@ nsRootAccessibleWrap::~nsRootAccessibleW
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsRootAccessible
 
 void
 nsRootAccessibleWrap::DocumentActivated(nsDocAccessible* aDocument)
 {
   if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle) &&
-      nsWinUtils::IsTabDocument(aDocument->GetDocumentNode())) {
+      nsCoreUtils::IsTabDocument(aDocument->GetDocumentNode())) {
     PRUint32 count = mChildDocuments.Length();
     for (PRUint32 idx = 0; idx < count; idx++) {
       nsDocAccessible* childDoc = mChildDocuments[idx];
       HWND childDocHWND = static_cast<HWND>(childDoc->GetNativeWindow());
       if (childDoc != aDocument)
         nsWinUtils::HideNativeWindow(childDocHWND);
       else
         nsWinUtils::ShowNativeWindow(childDocHWND);
--- a/accessible/src/msaa/nsWinUtils.cpp
+++ b/accessible/src/msaa/nsWinUtils.cpp
@@ -171,28 +171,18 @@ nsWinUtils::HideNativeWindow(HWND aWnd)
   ::SetWindowPos(aWnd, NULL, 0, 0, 0, 0,
                  SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
                  SWP_NOZORDER | SWP_NOACTIVATE);
 }
 
 bool
 nsWinUtils::IsWindowEmulationFor(LPCWSTR kModuleHandle)
 {
+#ifdef MOZ_E10S_COMPAT
+  // Window emulation is always enabled in multiprocess Firefox.
+  return kModuleHandle ? ::GetModuleHandleW(kModuleHandle) : true;
+#else
   return kModuleHandle ? ::GetModuleHandleW(kModuleHandle) :
     ::GetModuleHandleW(kJAWSModuleHandle) ||
     ::GetModuleHandleW(kWEModuleHandle)  ||
     ::GetModuleHandleW(kDolphinModuleHandle);
+#endif
 }
-
-bool
-nsWinUtils::IsTabDocument(nsIDocument* aDocumentNode)
-{
-  nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
-  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
-
-  nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
-  treeItem->GetParent(getter_AddRefs(parentTreeItem));
-
-  nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
-  treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
-
-  return parentTreeItem == rootTreeItem;
-}
--- a/accessible/src/msaa/nsWinUtils.h
+++ b/accessible/src/msaa/nsWinUtils.h
@@ -99,17 +99,12 @@ public:
    * Helper to hide window.
    */
   static void HideNativeWindow(HWND aWnd);
 
   /**
    * Return true if window emulation is enabled.
    */
   static bool IsWindowEmulationFor(LPCWSTR kModuleHandle);
-
-  /**
-   * Return true if the given document node is for tab document accessible.
-   */
-  static bool IsTabDocument(nsIDocument* aDocumentNode);
 };
 
 #endif
 
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -460,17 +460,17 @@ nsXULMenuitemAccessible::KeyboardShortcu
     key = keyStr[0];
   }
 
   nsAutoString modifiersStr;
   keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers, modifiersStr);
 
   PRUint32 modifierMask = 0;
   if (modifiersStr.Find("shift") != -1)
-    modifierMask != KeyBinding::kShift;
+    modifierMask |= KeyBinding::kShift;
   if (modifiersStr.Find("alt") != -1)
     modifierMask |= KeyBinding::kAlt;
   if (modifiersStr.Find("meta") != -1)
     modifierMask |= KeyBinding::kMeta;
   if (modifiersStr.Find("control") != -1)
     modifierMask |= KeyBinding::kControl;
   if (modifiersStr.Find("accel") != -1) {
     // Get the accelerator key value from prefs, overriding the default.
--- a/accessible/tests/mochitest/attributes/test_obj_group.xul
+++ b/accessible/tests/mochitest/attributes/test_obj_group.xul
@@ -9,74 +9,113 @@
   <script type="application/javascript" 
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 
   <script type="application/javascript"
           src="../common.js" />
   <script type="application/javascript"
+          src="../events.js" />
+  <script type="application/javascript"
           src="../attributes.js" />
 
   <script type="application/javascript">
   <![CDATA[
+    function openMenu(aID)
+    {
+      this.menuNode = getNode(aID);
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_FOCUS, this.menuNode)
+      ];
+
+      this.invoke = function openMenu_invoke()
+      {
+        this.menuNode.open = true;
+      }
+
+      this.finalCheck = function openMenu_finalCheck()
+      {
+        testGroupAttrs("menu_item1.1", 1, 1);
+        testGroupAttrs("menu_item1.2", 1, 3);
+        testGroupAttrs("menu_item1.4", 2, 3);
+        testGroupAttrs("menu_item2", 3, 3);
+      }
+
+      this.getID = function openMenu_getID()
+      {
+        return "open menu " + prettyName(aID);
+      }
+    }
+
+    function openSubMenu(aID)
+    {
+      this.menuNode = getNode(aID);
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_FOCUS, this.menuNode)
+      ];
+
+      this.invoke = function openSubMenu_invoke()
+      {
+        this.menuNode.open = true;
+      }
+
+      this.finalCheck = function openSubMenu_finalCheck()
+      {
+        testGroupAttrs("menu_item2.1", 1, 2, 1);
+        testGroupAttrs("menu_item2.2", 2, 2, 1);
+      }
+
+      this.getID = function openSubMenu_getID()
+      {
+        return "open submenu " + prettyName(aID);
+      }
+    }
+
+    var gQueue = null;
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
       // xul:listbox (bug 417317)
       testGroupAttrs("item1", 1, 2);
       testGroupAttrs("item2", 2, 2);
 
       //////////////////////////////////////////////////////////////////////////
-      // xul:menu (bug 443881)
-      var menu1 = document.getElementById("menu_item1");
-      menu1.open = true;
-
-      menu1.addEventListener("popupshown", function() {
-        var menu2 = document.getElementById("menu_item2");
-        menu2.open = true;
-
-        menu2.addEventListener("popupshown", function() {
-          testGroupAttrs("menu_item1.1", 1, 1);
-          testGroupAttrs("menu_item1.2", 1, 3);
-          testGroupAttrs("menu_item1.4", 2, 3);
-          testGroupAttrs("menu_item2", 3, 3);
-          testGroupAttrs("menu_item2.1", 1, 2, 1);
-          testGroupAttrs("menu_item2.2", 2, 2, 1);
-
-          menu1.open = false;
-          menu2.open = false;
-
-          SimpleTest.finish();
-        }, false);
-      }, false);
-
-      //////////////////////////////////////////////////////////////////////////
       // xul:tab
       testGroupAttrs("tab1", 1, 2);
       testGroupAttrs("tab2", 2, 2);
 
       //////////////////////////////////////////////////////////////////////////
       // xul:radio
       testGroupAttrs("radio1", 1, 2);
       testGroupAttrs("radio2", 2, 2);
 
       //////////////////////////////////////////////////////////////////////////
       // ARIA menu (bug 441888)
       testGroupAttrs("aria-menuitem", 1, 3);
       testGroupAttrs("aria-menuitemcheckbox", 2, 3);
       testGroupAttrs("aria-menuitemradio", 3, 3);
       testGroupAttrs("aria-menuitem2", 1, 1);
+
+      //////////////////////////////////////////////////////////////////////////
+      // xul:menu (bug 443881)
+      gQueue = new eventQueue();
+      gQueue.push(new openMenu("menu_item1"));
+      gQueue.push(new openSubMenu("menu_item2"));
+      gQueue.invoke(); // SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
+  <hbox flex="1" style="overflow: auto;">
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a target="_blank"
        href="https://bugzilla.mozilla.org/show_bug.cgi?id=417317"
        title="Certain types of LISTITEM accessibles no longer get attributes set like 'x of y', regression from fix for bug 389926">
       Mozilla Bug 417317
     </a><br/>
     <a target="_blank"
        href="https://bugzilla.mozilla.org/show_bug.cgi?id=443881"
@@ -91,16 +130,17 @@
 
     <p id="display"></p>
     <div id="content" style="display: none">
     </div>
     <pre id="test">
     </pre>
   </body>
 
+  <vbox flex="1">
   <listbox>
     <listitem label="item1" id="item1"/>
     <listitem label="item2" id="item2"/>
   </listbox>
 
   <menubar>
     <menu label="item1" id="menu_item1">
       <menupopup>
@@ -143,10 +183,13 @@
     <description role="menuitem" hidden="true"/>
     <description role="menuitemradio" id="aria-menuitemradio"
                  value="conventional radio menuitem"/>
     <description role="separator"
                  value="conventional separator"/>
     <description role="menuitem" id="aria-menuitem2"
                  value="conventional menuitem"/>
   </vbox>
+
+  </vbox>
+  </hbox>
 </window>
 
--- a/accessible/tests/mochitest/tree/Makefile.in
+++ b/accessible/tests/mochitest/tree/Makefile.in
@@ -58,16 +58,17 @@ include $(topsrcdir)/config/rules.mk
 		test_dockids.html \
 		test_filectrl.html \
 		test_formctrl.html \
 		test_formctrl.xul \
 		test_gencontent.html \
 		test_groupbox.xul \
 		test_iframe.html \
 		test_img.html \
+		test_invalidationlist.html \
 		test_list.html \
 		test_media.html \
 		test_select.html \
 		test_tabbox.xul \
 		test_tabbrowser.xul \
 		test_table.html \
 		test_tree.xul \
 		test_txtcntr.html \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_invalidationlist.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test document hierarchy</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+
+  <script type="application/javascript">
+  function doTest()
+  {
+    var tree =
+     { SECTION: [
+       { SECTION: [ // div
+         { LABEL: [ ] } // link
+       ] },
+       { SECTION: [ // div table-cell referred by label
+         { TEXT_LEAF: [ ] }, // 'Z'
+         { TEXT_LEAF: [ ] } // ' '
+       ] }
+     ] };
+    testAccessibleTree("container", tree);
+
+    SimpleTest.finish();
+  }
+
+  SimpleTest.waitForExplicitFinish();
+  addA11yLoadEvent(doTest);
+  </script>
+</head>
+
+<body>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=673757"
+     title="Do not process invalidation list while tree is created">
+    Mozilla Bug 673757
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="container">
+    <div><label for="x"></label></div>
+    <div style="display: table-cell;" id="x">Z<span> </span><span></span></div>
+  </div>
+</body>
+</html>
--- a/browser/Makefile.in
+++ b/browser/Makefile.in
@@ -40,16 +40,17 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(topsrcdir)/config/config.mk
 
 PARALLEL_DIRS = \
   base \
   components \
+  devtools \
   fuel \
   locales \
   themes \
   $(NULL)
 
 DIRS = \
   app \
   $(NULL)
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,11 +1,15 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1306529826000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1311096050000">
   <emItems>
+      <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
+                        <versionRange  minVersion="0.1" maxVersion="4.3.0.00" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
                         <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1" maxVersion="*" />
@@ -20,16 +24,20 @@
       <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
                         <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
                         <versionRange  minVersion="1.0" maxVersion="1.0">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i39" id="{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}">
+                        <versionRange  minVersion="0.1" maxVersion="4.3.0.00" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
                         </emItem>
       <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
                         <versionRange  minVersion="2.1" maxVersion="3.3">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
@@ -47,16 +55,20 @@
                         </emItem>
       <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
                         <versionRange  minVersion="1.2" maxVersion="1.2">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
+                        <versionRange  minVersion="0.1" maxVersion="4.3.0.00" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i23" id="firefox@bandoo.com">
                         <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1pre" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
       <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -838,34 +838,40 @@ var BookmarksEventHandler = {
 };
 
 
 // Handles special drag and drop functionality for Places menus that are not
 // part of a Places view (e.g. the bookmarks menu in the menubar).
 var PlacesMenuDNDHandler = {
   _springLoadDelay: 350, // milliseconds
   _loadTimer: null,
+  _closerTimer: null,
 
   /**
    * Called when the user enters the <menu> element during a drag.
    * @param   event
    *          The DragEnter event that spawned the opening. 
    */
   onDragEnter: function PMDH_onDragEnter(event) {
     // Opening menus in a Places popup is handled by the view itself.
     if (!this._isStaticContainer(event.target))
       return;
 
-    this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    this._loadTimer.initWithCallback(function() {
-      PlacesMenuDNDHandler._loadTimer = null;
-      event.target.lastChild.setAttribute("autoopened", "true");
-      event.target.lastChild.showPopup(event.target.lastChild);
-    }, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
-    event.preventDefault();
+    let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
+                                PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                Ci.nsITreeView.DROP_ON);
+    if (ip && PlacesControllerDragHelper.canDrop(ip, event.dataTransfer)) {
+      this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+      this._loadTimer.initWithCallback(function() {
+        PlacesMenuDNDHandler._loadTimer = null;
+        event.target.lastChild.setAttribute("autoopened", "true");
+        event.target.lastChild.showPopup(event.target.lastChild);
+      }, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
+      event.preventDefault();
+    }
     event.stopPropagation();
   },
 
   /**
    * Handles dragexit on the <menu> element.
    * @returns true if the element is a container element (menu or 
    *          menu-toolbarbutton), false otherwise.
    */
@@ -873,18 +879,19 @@ var PlacesMenuDNDHandler = {
     // Closing menus in a Places popup is handled by the view itself.
     if (!this._isStaticContainer(event.target))
       return;
 
     if (this._loadTimer) {
       this._loadTimer.cancel();
       this._loadTimer = null;
     }
-    let closeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    closeTimer.initWithCallback(function() {
+    this._closeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    this._closeTimer.initWithCallback(function() {
+      this._closeTimer = null;
       let node = PlacesControllerDragHelper.currentDropTarget;
       let inHierarchy = false;
       while (node && !inHierarchy) {
         inHierarchy = node == event.target;
         node = node.parentNode;
       }
       if (!inHierarchy && event.target.lastChild &&
           event.target.lastChild.hasAttribute("autoopened")) {
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -8,16 +8,17 @@ searchbar {
 tabbrowser {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
 }
 
 .tabbrowser-tabs {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
 }
 
+#tabbrowser-tabs[drag=detach][closebuttons=hidden] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
 #tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   visibility: collapse;
 }
 
 .tabbrowser-tab {
@@ -57,16 +58,49 @@ tabbrowser {
   -moz-transition: opacity 250ms;
 }
 
 .tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
   position: fixed !important;
   display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
 }
 
+.tabbrowser-tabs[drag] > .tabbrowser-tab {
+  pointer-events: none; /* suppress tooltips */
+}
+
+.tabbrowser-tabs[drag] > .tabbrowser-tab[selected] {
+  z-index: 2; /* ensure selected tab stays on top despite -moz-transform */
+}
+
+.tabbrowser-tabs[drag] > .tabbrowser-tab[dragged] {
+  -moz-transition: 0s; /* suppress opening animation when reattaching tab */
+}
+
+/* visibility: collapse might collapse the tab bar, so we use this instead */
+.tabbrowser-tabs[drag=detach] > .tabbrowser-tab[dragged]:not(:only-child) {
+  min-width: 0 !important;
+  max-width: 0 !important;
+  border: 0 !important;
+  opacity: 0;
+  overflow: hidden;
+  -moz-transition: max-width 150ms ease-out;
+}
+.tabbrowser-tabs[drag=detach] > .tabbrowser-tab[dragged]:only-child {
+  visibility: hidden;
+}
+
+.tabbrowser-tabs[drag=move] > .tabbrowser-tab[fadein]:not([dragged]) {
+  -moz-transition: -moz-transform 200ms ease-out;
+}
+
+.tabbrowser-tabs[drag=finish] > .tabbrowser-tab[dragged][fadein] {
+  -moz-transition: -moz-transform 100ms ease-out;
+}
+
 #alltabs-popup {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
 }
 
 toolbar[printpreview="true"] {
   -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
 }
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -394,16 +394,34 @@
     <panel id="customizeToolbarSheetPopup"
            noautohide="true">
       <iframe id="customizeToolbarSheetIFrame"
               style="&dialog.style;"
               hidden="true"/>
     </panel>
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
+
+    <tooltip id="back-button-tooltip">
+      <label value="&backButton.tooltip;"/>
+#ifdef XP_MACOSX
+      <label value="&backForwardButtonMenuMac.tooltip;"/>
+#else
+      <label value="&backForwardButtonMenu.tooltip;"/>
+#endif
+    </tooltip>
+  
+    <tooltip id="forward-button-tooltip">
+      <label value="&forwardButton.tooltip;"/>
+#ifdef XP_MACOSX
+      <label value="&backForwardButtonMenuMac.tooltip;"/>
+#else
+      <label value="&backForwardButtonMenu.tooltip;"/>
+#endif
+    </tooltip>
   </popupset>
 
 #ifdef CAN_DRAW_IN_TITLEBAR
 <vbox id="titlebar">
   <hbox id="titlebar-content">
     <hbox id="appmenu-button-container">
       <button id="appmenu-button"
               type="menu"
@@ -463,22 +481,22 @@
 
       <toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
                    context="backForwardMenu" removable="true"
                    title="&backForwardItem.title;">
         <toolbarbutton id="back-button" class="toolbarbutton-1"
                        label="&backCmd.label;"
                        command="Browser:BackOrBackDuplicate"
                        onclick="checkForMiddleClick(this, event);"
-                       tooltiptext="&backButton.tooltip;"/>
+                       tooltip="back-button-tooltip"/>
         <toolbarbutton id="forward-button" class="toolbarbutton-1"
                        label="&forwardCmd.label;"
                        command="Browser:ForwardOrForwardDuplicate"
                        onclick="checkForMiddleClick(this, event);"
-                       tooltiptext="&forwardButton.tooltip;"/>
+                       tooltip="forward-button-tooltip"/>
       </toolbaritem>
 
       <toolbaritem id="urlbar-container" align="center" flex="400" persist="width" combined="true"
                    title="&locationItem.title;" class="chromeclass-location" removable="true">
         <textbox id="urlbar" flex="1"
                  placeholder="&urlbar.placeholder;"
                  type="autocomplete"
                  autocompletesearch="history"
--- a/browser/base/content/inspector.js
+++ b/browser/base/content/inspector.js
@@ -523,16 +523,17 @@ Highlighter.prototype = {
 ///////////////////////////////////////////////////////////////////////////
 //// InspectorUI
 
 /**
  * Main controller class for the Inspector.
  */
 var InspectorUI = {
   browser: null,
+  tools: {},
   showTextNodesWithWhitespace: false,
   inspecting: false,
   treeLoaded: false,
   prefEnabledName: "devtools.inspector.enabled",
 
   /**
    * Toggle the inspector interface elements on or off.
    *
@@ -854,16 +855,23 @@ var InspectorUI = {
 
     if (this.domplate) {
       this.domplateUtils.setDOM(null);
       delete this.domplate;
       delete this.HTMLTemplates;
       delete this.domplateUtils;
     }
 
+    this.saveToolState(this.winID);
+    this.toolsDo(function IUI_toolsHide(aTool) {
+      if (aTool.panel) {
+        aTool.panel.hidePopup();
+      }
+    });
+
     this.inspectCmd.setAttribute("checked", false);
     this.browser = this.win = null; // null out references to browser and window
     this.winID = null;
     this.selection = null;
     this.treeLoaded = false;
 
     this.treePanel.addEventListener("popuphidden", function treePanelHidden() {
       InspectorUI.closing = false;
@@ -875,37 +883,41 @@ var InspectorUI = {
   },
 
   /**
    * Begin inspecting webpage, attach page event listeners, activate
    * highlighter event listeners.
    */
   startInspecting: function IUI_startInspecting()
   {
+    document.getElementById("inspector-inspect-toolbutton").checked = true;
     this.attachPageListeners();
     this.inspecting = true;
+    this.highlighter.veilTransparentBox.removeAttribute("locked");
   },
 
   /**
    * Stop inspecting webpage, detach page listeners, disable highlighter
    * event listeners.
    */
   stopInspecting: function IUI_stopInspecting()
   {
     if (!this.inspecting) {
       return;
     }
 
+    document.getElementById("inspector-inspect-toolbutton").checked = false;
     this.detachPageListeners();
     this.inspecting = false;
     if (this.highlighter.node) {
       this.select(this.highlighter.node, true, true);
     } else {
       this.select(null, true, true);
     }
+    this.highlighter.veilTransparentBox.setAttribute("locked", true);
   },
 
   /**
    * Select an object in the tree view.
    * @param aNode
    *        node to inspect
    * @param forceUpdate
    *        force an update?
@@ -919,16 +931,21 @@ var InspectorUI = {
 
     if (forceUpdate || aNode != this.selection) {
       this.selection = aNode;
       if (!this.inspecting) {
         this.highlighter.highlightNode(this.selection);
       }
       this.ioBox.select(this.selection, true, true, aScroll);
     }
+    this.toolsDo(function IUI_toolsOnSelect(aTool) {
+      if (aTool.panel.state == "open") {
+        aTool.onSelect.apply(aTool.context, [aNode]);
+      }
+    });
   },
 
   /////////////////////////////////////////////////////////////////////////
   //// Event Handling
 
   highlighterReady: function IUI_highlighterReady()
   {
     // Setup the InspectorStore or restore state
@@ -967,16 +984,17 @@ var InspectorUI = {
             Services.obs.addObserver(function reopenInspectorForTab() {
               Services.obs.removeObserver(reopenInspectorForTab,
                 INSPECTOR_NOTIFICATIONS.CLOSED, false);
 
               InspectorUI.openInspectorUI();
             }, INSPECTOR_NOTIFICATIONS.CLOSED, false);
           } else {
             this.openInspectorUI();
+            this.restoreToolState(winID);
           }
         }
 
         if (InspectorStore.isEmpty()) {
           gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
         }
         break;
       case "pagehide":
@@ -1215,17 +1233,123 @@ var InspectorUI = {
       if (frame.language == Ci.nsIProgrammingLanguage.JAVASCRIPT ||
           frame.language == Ci.nsIProgrammingLanguage.JAVASCRIPT2) {
         this._log("filename: " + frame.filename + " lineNumber: " + frame.lineNumber +
           " functionName: " + frame.name);
       }
     }
     this._log("END TRACE");
   },
-}
+
+  /**
+   * Register an external tool with the inspector.
+   *
+   * aRegObj = {
+   *   id: "toolname",
+   *   context: myTool,
+   *   label: "Button label",
+   *   icon: "chrome://somepath.png",
+   *   tooltiptext: "Button tooltip",
+   *   accesskey: "S",
+   *   onSelect: object.method,
+   *   onShow: object.method,
+   *   onHide: object.method,
+   *   panel: myTool.panel
+   * }
+   *
+   * @param aRegObj
+   */
+  registerTool: function IUI_RegisterTool(aRegObj) {
+    if (this.tools[aRegObj.id]) {
+      return;
+    } else {
+      let id = aRegObj.id;
+      let buttonId = "inspector-" + id + "-toolbutton";
+      aRegObj.buttonId = buttonId;
+
+      aRegObj.panel.addEventListener("popuphiding",
+        function IUI_toolPanelHiding() {
+          btn.setAttribute("checked", "false");
+        }, false);
+      aRegObj.panel.addEventListener("popupshowing",
+        function IUI_toolPanelShowing() {
+          btn.setAttribute("checked", "true");
+        }, false);
+
+      this.tools[id] = aRegObj;
+    }
+
+    let toolbar = document.getElementById("inspector-toolbar");
+    let btn = document.createElement("toolbarbutton");
+    btn.setAttribute("id", aRegObj.buttonId);
+    btn.setAttribute("label", aRegObj.label);
+    btn.setAttribute("tooltiptext", aRegObj.tooltiptext);
+    btn.setAttribute("accesskey", aRegObj.accesskey);
+    btn.setAttribute("class", "toolbarbutton-text");
+    btn.setAttribute("image", aRegObj.icon || "");
+    toolbar.appendChild(btn);
+
+    btn.addEventListener("click",
+      function IUI_ToolButtonClick(aEvent) {
+        if (btn.getAttribute("checked") == "true") {
+          aRegObj.onHide.apply(aRegObj.context);
+        } else {
+          aRegObj.onShow.apply(aRegObj.context, [InspectorUI.selection]);
+          aRegObj.onSelect.apply(aRegObj.context, [InspectorUI.selection]);
+        }
+      }, false);
+  },
+
+/**
+ * Save a list of open tools to the inspector store.
+ *
+ * @param aWinID The ID of the window used to save the associated tools
+ */
+  saveToolState: function IUI_saveToolState(aWinID)
+  {
+    let openTools = {};
+    this.toolsDo(function IUI_toolsSetId(aTool) {
+      if (aTool.panel.state == "open") {
+        openTools[aTool.id] = true;
+      }
+    });
+    InspectorStore.setValue(aWinID, "openTools", openTools);
+  },
+
+/**
+ * Restore tools previously save using saveToolState().
+ *
+ * @param aWinID The ID of the window to which the associated tools are to be
+ *               restored.
+ */
+  restoreToolState: function IUI_restoreToolState(aWinID)
+  {
+    let openTools = InspectorStore.getValue(aWinID, "openTools");
+    InspectorUI.selection = InspectorUI.selection;
+    if (openTools) {
+      this.toolsDo(function IUI_toolsOnShow(aTool) {
+        if (aTool.id in openTools) {
+          aTool.onShow.apply(aTool.context, [InspectorUI.selection]);
+        }
+      });
+    }
+  },
+  
+  /**
+   * Loop through all registered tools and pass each into the provided function
+   *
+   * @param aFunction The function to which each tool is to be passed
+   */
+  toolsDo: function IUI_toolsDo(aFunction)
+  {
+    for each (let tool in this.tools) {
+      aFunction(tool);
+    }
+  },
+};
 
 /**
  * The Inspector store is used for storing data specific to each tab window.
  */
 var InspectorStore = {
   store: {},
   length: 0,
 
@@ -1350,9 +1474,8 @@ var InspectorStore = {
 };
 
 /////////////////////////////////////////////////////////////////////////
 //// Initializors
 
 XPCOMUtils.defineLazyGetter(InspectorUI, "inspectCmd", function () {
   return document.getElementById("Tools:Inspect");
 });
-
--- a/browser/base/content/scratchpad.xul
+++ b/browser/base/content/scratchpad.xul
@@ -325,16 +325,17 @@
               label="&display.label;"
               accesskey="&display.accesskey;"
               key="sp-key-display"
               command="sp-cmd-display"/>
   </menupopup>
 </popupset>
 
 <textbox id="scratchpad-textbox"
+         class="monospace"
          multiline="true"
          flex="1"
          context="scratchpad-text-popup"
          placeholder="&textbox.placeholder1;" />
 <statusbar id="scratchpad-statusbar" align="end">
   <statusbarpanel id="scratchpad-status"
                   label="&contentContext.label;"
                   class="statusbarpanel-iconic-text"/>
--- a/browser/base/content/syncQuota.js
+++ b/browser/base/content/syncQuota.js
@@ -53,54 +53,69 @@ let gSyncQuota = {
     gUsageTreeView.init();
     this.tree = document.getElementById("usageTree");
     this.tree.view = gUsageTreeView;
 
     this.loadData();
   },
 
   loadData: function loadData() {
-    window.setTimeout(function() {
-      let usage = Weave.Service.getCollectionUsage();
+    this._usage_req = Weave.Service.getStorageInfo(Weave.INFO_COLLECTION_USAGE,
+                                                   function (error, usage) {
+      delete gSyncQuota._usage_req;
+      // displayUsageData handles null values, so no need to check 'error'.
       gUsageTreeView.displayUsageData(usage);
-    }, 0);
+    });
 
     let usageLabel = document.getElementById("usageLabel");
     let bundle = this.bundle;
-    window.setTimeout(function() {
-      let quota = Weave.Service.getQuota();
-      if (!quota) {
+
+    this._quota_req = Weave.Service.getStorageInfo(Weave.INFO_QUOTA,
+                                                   function (error, quota) {
+      delete gSyncQuota._quota_req;
+
+      if (error) {
         usageLabel.value = bundle.getString("quota.usageError.label");
         return;
       }
       let used = gSyncQuota.convertKB(quota[0]);
       if (!quota[1]) {
         // No quota on the server.
         usageLabel.value = bundle.getFormattedString(
           "quota.usageNoQuota.label", used);
         return;
       }
       let percent = Math.round(100 * quota[0] / quota[1]);
       let total = gSyncQuota.convertKB(quota[1]);
       usageLabel.value = bundle.getFormattedString(
         "quota.usagePercentage.label", [percent].concat(used).concat(total));
-    }, 0);
+    });
+  },
+
+  onCancel: function onCancel() {
+    if (this._usage_req) {
+      this._usage_req.abort();
+    }
+    if (this._quota_req) {
+      this._quota_req.abort();
+    }
+    return true;
   },
 
   onAccept: function onAccept() {
     let engines = gUsageTreeView.getEnginesToDisable();
     for each (let engine in engines) {
       Weave.Engines.get(engine).enabled = false;
     }
     if (engines.length) {
       // The 'Weave' object will disappear once the window closes.
       let Service = Weave.Service;
       Weave.Utils.nextTick(function() { Service.sync(); });
     }
-    return true;
+    return this.onCancel();
   },
 
   convertKB: function convertKB(value) {
     return DownloadUtils.convertByteUnits(value * 1024);
   }
 
 };
 
--- a/browser/base/content/syncQuota.xul
+++ b/browser/base/content/syncQuota.xul
@@ -51,17 +51,17 @@
 <dialog id="quotaDialog"
         windowtype="Sync:ViewQuota"
         persist="screenX screenY width height"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         onload="gSyncQuota.init()"
         buttons="accept,cancel"
         title="&quota.dialogTitle.label;"
-        ondialogcancel="return true;"
+        ondialogcancel="return gSyncQuota.onCancel();"
         ondialogaccept="return gSyncQuota.onAccept();">
 
   <script type="application/javascript"
           src="chrome://browser/content/syncQuota.js"/>
 
   <stringbundleset id="stringbundleset">
     <stringbundle id="quotaStrings"
                   src="chrome://browser/locale/syncQuota.properties"/>
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -33,16 +33,26 @@
 .tab-stack {
   vertical-align: top; /* for pinned tabs */
 }
 
 tabpanels {
   background-color: transparent;
 }
 
+.tab-drag-preview {
+  background: -moz-element(#content) left top;
+  background-clip: content-box;
+  background-size: cover;
+}
+
+.tab-drag-panel[target] > .tab-drag-preview {
+  display: none;
+}
+
 .tab-drop-indicator {
   position: relative;
   z-index: 2;
 }
 
 .tab-throbber:not([busy]),
 .tab-throbber[busy] + .tab-icon-image {
   display: none;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1492,16 +1492,19 @@
               return;
             }
 
             var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
 
             if (!this._beginRemoveTab(aTab, false, null, true))
               return;
 
+            if (this.tabContainer.draggedTab == aTab)
+              this.tabContainer._endTabDrag();
+
             if (!aTab.pinned && !aTab.hidden && aTab._fullyOpen && byMouse)
               this.tabContainer._lockTabSizing(aTab);
             else
               this.tabContainer._unlockTabSizing();
 
             if (!animate /* the caller didn't opt in */ ||
                 isLastTab ||
                 aTab.pinned ||
@@ -1693,16 +1696,18 @@
                 this.tabContainer._positionPinnedTabs();
 
               // update tab close buttons state
               this.tabContainer.adjustTabstrip();
 
               setTimeout(function(tabs) {
                 tabs._lastTabClosedByMouse = false;
               }, 0, this.tabContainer);
+
+              this.tabContainer._handleTabDrag(); // Update drag feedback.
             }
 
             // update first-tab/last-tab/beforeselected/afterselected attributes
             this.selectedTab._selected = true;
 
             // Removing the panel requires fixing up selectedPanel immediately
             // (see below), which would be hindered by the potentially expensive
             // browser removal. So we remove the browser and the panel in two
@@ -2671,49 +2676,57 @@
         <body><![CDATA[
           return !tab.pinned && !tab.hidden;
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="underflow" phase="capturing"><![CDATA[
-        if (event.detail == 0)
+        if (event.originalTarget != this._scrollbox || event.detail == 0)
           return; // Ignore vertical events
 
         var tabs = document.getBindingParent(this);
         tabs.removeAttribute("overflow");
 
         if (tabs._lastTabClosedByMouse)
           tabs._expandSpacerBy(this._scrollButtonDown.clientWidth);
 
         tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
                                               tabs.tabbrowser);
 
         tabs._positionPinnedTabs();
       ]]></handler>
       <handler event="overflow"><![CDATA[
-        if (event.detail == 0)
+        if (event.originalTarget != this._scrollbox || event.detail == 0)
           return; // Ignore vertical events
 
         var tabs = document.getBindingParent(this);
         tabs.setAttribute("overflow", "true");
         tabs._positionPinnedTabs();
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-tabs"
            extends="chrome://global/content/bindings/tabbox.xml#tabs">
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
+    <!-- The onpopupshowing/hiding handlers on the panel are to circumvent
+         noautohide=true disabling level=top on Linux. See bug 448929. -->
     <content>
       <xul:hbox align="end">
+        <xul:panel class="tab-drag-panel" anonid="tab-drag-panel" hidden="true" level="top"
+                   onpopupshowing="this.setAttribute('noautohide', true);"
+                   onpopuphiding="this.removeAttribute('noautohide');">
+          <xul:label class="tab-drag-label" crop="end"/>
+          <xul:box class="tab-drag-preview"/>
+        </xul:panel>
         <xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
       </xul:hbox>
       <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
                           style="min-width: 1px;"
 #ifndef XP_MACOSX
                           clicktoscroll="true"
 #endif
                           class="tabbrowser-arrowscrollbox">
@@ -2799,16 +2812,476 @@
         }
       });]]></field>
       <field name="_blockDblClick">false</field>
 
       <field name="_tabDropIndicator">
         document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
       </field>
 
+      <method name="_positionDropIndicator">
+        <parameter name="event"/>
+        <parameter name="scrollOnly"/>
+        <body><![CDATA[
+          var effects = event.dataTransfer ? this._setEffectAllowedForDataTransfer(event) : "";
+
+          var ind = this._tabDropIndicator;
+          if (effects == "none") {
+            ind.collapsed = true;
+            return;
+          }
+          event.preventDefault();
+          event.stopPropagation();
+
+          var tabStrip = this.mTabstrip;
+          var ltr = (window.getComputedStyle(this).direction == "ltr");
+
+          // Autoscroll the tab strip if we drag over the scroll
+          // buttons, even if we aren't dragging a tab, but then
+          // return to avoid drawing the drop indicator.
+          var pixelsToScroll = 0;
+          var target = event.originalTarget;
+          if (target.ownerDocument == document &&
+              this.getAttribute("overflow") == "true") {
+            let targetAnonid = target.getAttribute("anonid");
+            switch (targetAnonid) {
+              case "scrollbutton-up":
+                pixelsToScroll = tabStrip.scrollIncrement * -1;
+                break;
+              case "scrollbutton-down":
+                pixelsToScroll = tabStrip.scrollIncrement;
+                break;
+            }
+            if (pixelsToScroll) {
+              if (effects)
+                tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
+              else
+                tabStrip._startScroll(pixelsToScroll < 0 ? -1 : 1);
+            }
+          }
+
+          if (scrollOnly) {
+            ind.collapsed = true;
+            return;
+          }
+
+          if (effects == "link") {
+            let tab = this._getDragTargetTab(event);
+            if (tab) {
+              if (!this._dragTime)
+                this._dragTime = Date.now();
+              if (Date.now() >= this._dragTime + this._dragOverDelay)
+                this.selectedItem = tab;
+              ind.collapsed = true;
+              return;
+            }
+          }
+
+          var newIndex = this._getDropIndex(event);
+          var scrollRect = tabStrip.scrollClientRect;
+          var rect = this.getBoundingClientRect();
+          var minMargin = scrollRect.left - rect.left;
+          var maxMargin = Math.min(minMargin + scrollRect.width,
+                                   scrollRect.right);
+          if (!ltr)
+            [minMargin, maxMargin] = [this.clientWidth - maxMargin,
+                                      this.clientWidth - minMargin];
+          var newMargin;
+          if (pixelsToScroll) {
+            // If we are scrolling, put the drop indicator at the edge,
+            // so that it doesn't jump while scrolling.
+            newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
+          }
+          else {
+            if (newIndex == this.childNodes.length) {
+              let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
+              if (ltr)
+                newMargin = tabRect.right - rect.left;
+              else
+                newMargin = rect.right - tabRect.left;
+            }
+            else {
+              let tabRect = this.childNodes[newIndex].getBoundingClientRect();
+              if (ltr)
+                newMargin = tabRect.left - rect.left;
+              else
+                newMargin = rect.right - tabRect.right;
+            }
+          }
+
+          ind.collapsed = false;
+
+          newMargin += ind.clientWidth / 2;
+          if (!ltr)
+            newMargin *= -1;
+
+          ind.style.MozTransform = "translate(" + Math.round(newMargin) + "px)";
+          ind.style.MozMarginStart = (-ind.clientWidth) + "px";
+        ]]></body>
+      </method>
+
+      <field name="_tabDragPanel">
+        document.getAnonymousElementByAttribute(this, "anonid", "tab-drag-panel");
+      </field>
+
+      <field name="draggedTab">null</field>
+
+      <method name="_handleTabDrag">
+        <parameter name="event"/>
+        <body><![CDATA[
+          let draggedTab = this.draggedTab;
+          if (!draggedTab)
+            return;
+
+          if (event)
+            draggedTab._dragData._savedEvent = event;
+          else
+            event = draggedTab._dragData._savedEvent;
+
+          if (this._updateTabDetachState(event, draggedTab))
+            return;
+
+          // Keep the dragged tab visually within the region of like tabs.
+          let tabs = this.tabbrowser.visibleTabs;
+          let numPinned = this.tabbrowser._numPinnedTabs;
+          let leftmostTab = draggedTab.pinned ? tabs[0] : tabs[numPinned];
+          let rightmostTab = draggedTab.pinned ? tabs[numPinned-1] : tabs[tabs.length-1];
+          let tabWidth = draggedTab.getBoundingClientRect().width;
+          let ltr = (window.getComputedStyle(this).direction == "ltr");
+          if (!ltr)
+            [leftmostTab, rightmostTab] = [rightmostTab, leftmostTab];
+          let left = leftmostTab.boxObject.screenX;
+          let right = rightmostTab.boxObject.screenX + tabWidth;
+          let transformX = event.screenX - draggedTab._dragData._dragStartX;
+          if (!draggedTab.pinned)
+            transformX += this.mTabstrip.scrollPosition;
+          let tabX = draggedTab.boxObject.screenX + transformX;
+          draggedTab._dragData._dragDistX = transformX;
+          if (tabX < left)
+            transformX += left - tabX;
+          // Prevent unintended overflow, especially in RTL mode.
+          else if (tabX + tabWidth > right)
+            transformX += right - tabX - tabWidth - (ltr ? 0 : 1);
+          draggedTab.style.MozTransform = "translate(" + transformX + "px)";
+
+          let newIndex = this._getDropIndex(event, draggedTab);
+          let tabAtNewIndex = this.childNodes[newIndex > draggedTab._tPos ?
+                                              newIndex-1 : newIndex];
+          this._positionDropIndicator(event, tabAtNewIndex.pinned == draggedTab.pinned);
+
+          if (newIndex == draggedTab._dragData._dropIndex)
+            return;
+          draggedTab._dragData._dropIndex = newIndex;
+
+          if (!ltr)
+            tabWidth *= -1;
+          tabs.forEach(function(tab) {
+            if (tab == draggedTab || tab.pinned != draggedTab.pinned)
+              return;
+            else if (tab._tPos < draggedTab._tPos && tab._tPos >= newIndex)
+              tab.style.MozTransform = "translate(" + tabWidth + "px)";
+            else if (tab._tPos > draggedTab._tPos && tab._tPos < newIndex)
+              tab.style.MozTransform = "translate(" + -tabWidth + "px)";
+            else
+              tab.style.MozTransform = "";
+          });
+        ]]></body>
+      </method>
+
+      <method name="_updateTabDetachState">
+        <parameter name="event"/>
+        <parameter name="draggedTab"/>
+        <body><![CDATA[
+          let data = draggedTab._dragData;
+          if (data._targetWindow.closed) {
+            data._targetWindow = window;
+            window.focus();
+          }
+          else if (data._dropTarget) {
+            data._dropTarget._tabDropIndicator.collapsed = true;
+          }
+          delete data._dropTarget;
+
+          function isEventOutsideWindow(event, win) {
+            return (event.screenX < win.screenX || event.screenX >= win.screenX + win.outerWidth ||
+                    event.screenY < win.screenY || event.screenY >= win.screenY + win.outerHeight);
+          }
+          if (isEventOutsideWindow(event, data._targetWindow) ||
+              Services.ww.activeWindow != data._targetWindow) {
+            // Iterate through browser windows in hopefully front-to-back order.
+            let winEnum = Services.wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
+            let wins = [];
+            while (winEnum.hasMoreElements())
+              wins.push(winEnum.getNext());
+            // Work around broken z-order enumerator on Linux. See bug 156333.
+            if (!wins.length) {
+              winEnum = Services.wm.getEnumerator("navigator:browser");
+              while (winEnum.hasMoreElements())
+                wins.unshift(winEnum.getNext());
+            }
+            wins.every(function(win) {
+              if (win.closed || win.windowState == STATE_MINIMIZED ||
+                  isEventOutsideWindow(event, win))
+                return true;
+              data._targetWindow = win;
+              win.focus(); // Raise window when cursor moves over it.
+            });
+          }
+
+          let detached = (this.getAttribute("drag") == "detach");
+          let loneTab = (this.childElementCount == 1);
+          let bo = loneTab ? draggedTab.boxObject : this.parentNode.boxObject;
+          // Detach tab if outside window, to the left or right of tab strip, or
+          // at least one tab height above or below it.
+          if (data._targetWindow != window ||
+              event.screenX < bo.screenX || event.screenX >= bo.screenX + bo.width ||
+              event.screenY < bo.screenY - (detached || loneTab ? 0 : 1) * bo.height ||
+              event.screenY >= bo.screenY + (detached || loneTab ? 1 : 2) * bo.height) {
+            if (data._targetWindow != window &&
+                data._targetWindow.windowState != STATE_MINIMIZED) {
+              let that = data._targetWindow.gBrowser.tabContainer;
+              let bo = that.parentNode.boxObject;
+              if (event.screenX >= bo.screenX && event.screenX < bo.screenX + bo.width &&
+                  event.screenY >= bo.screenY && event.screenY < bo.screenY + bo.height) {
+                that._positionDropIndicator(event);
+                data._dropTarget = that;
+              }
+            }
+
+            let dragPanel = this._tabDragPanel;
+            if (data._dropTarget)
+              dragPanel.setAttribute("target", "true");
+            else
+              dragPanel.removeAttribute("target");
+
+            if (!detached) {
+              this.setAttribute("drag", "detach");
+              this._clearDragTransforms();
+              this._tabDropIndicator.collapsed = true;
+              if (draggedTab.style.maxWidth) {
+                data._maxWidth = draggedTab.style.maxWidth;
+                draggedTab.style.maxWidth = "";
+              }
+              delete data._dropIndex;
+              let label = dragPanel.firstChild;
+              let preview = dragPanel.lastChild;
+              label.value = draggedTab.label;
+              label.width = preview.width = Math.min(outerWidth / 2, screen.availWidth / 5);
+              let aspectRatio = this.tabbrowser.clientWidth / this.tabbrowser.clientHeight;
+              preview.height = Math.min(preview.width / aspectRatio, screen.availHeight / 5);
+              dragPanel.hidden = false;
+              dragPanel.openPopupAtScreen(event.screenX, event.screenY, false);
+            }
+            let width = dragPanel.clientWidth;
+            let [left, top] = this._getAdjustedCoords(event.screenX, event.screenY, width,
+                                                      dragPanel.clientHeight, width / 2, 12, true);
+            dragPanel.moveTo(left, top);
+            return true;
+          }
+          if (detached) { // Otherwise, put tab back in the tab strip.
+            this.setAttribute("drag", "move");
+            if (data._maxWidth) {
+              draggedTab.style.setProperty("max-width", data._maxWidth, "important");
+              delete draggedTab._maxWidth;
+            }
+            this.mTabstrip._updateScrollButtonsDisabledState();
+            this._tabDragPanel.hidePopup();
+          }
+        ]]></body>
+      </method>
+
+      <method name="_getAdjustedCoords">
+        <parameter name="aLeft"/>
+        <parameter name="aTop"/>
+        <parameter name="aWidth"/>
+        <parameter name="aHeight"/>
+        <parameter name="aOffsetX"/>
+        <parameter name="aOffsetY"/>
+        <parameter name="isPanel"/>
+        <body><![CDATA[
+          // screen.availTop et al. only check the source window's screen, but
+          // we want to look at the target window's screen.
+          let sX = {}, sY = {}, sWidth = {}, sHeight = {};
+          Cc["@mozilla.org/gfx/screenmanager;1"]
+            .getService(Ci.nsIScreenManager)
+            .screenForRect(aLeft, aTop, 1, 1)
+            .GetAvailRect(sX, sY, sWidth, sHeight);
+          // Window manager repositions panels that are too close to the right
+          // or bottom of a screen, so leave a gutter to avoid that.
+          if (isPanel) {
+            sWidth.value -= 3;
+            sHeight.value -= 3;
+          }
+          // Ensure rect will be entirely onscreen.
+          let width = Math.min(aWidth, sWidth.value);
+          let height = Math.min(aHeight, sHeight.value);
+          let left = Math.min(Math.max(aLeft - aOffsetX, sX.value),
+                              sX.value + sWidth.value - width);
+          let top = Math.min(Math.max(aTop - aOffsetY, sY.value),
+                             sY.value + sHeight.value - height);
+          return [left, top, width, height];
+        ]]></body>
+      </method>
+
+      <method name="_handleTabDrop">
+        <parameter name="event"/>
+        <body><![CDATA[
+          let draggedTab = this.draggedTab;
+          if (this.getAttribute("drag") == "move") {
+            this._slideTab(event, draggedTab);
+            return;
+          }
+
+          do {
+            let that = draggedTab._dragData._dropTarget;
+            let win = draggedTab._dragData._targetWindow;
+            if (!that || win.closed)
+              break;
+            that._tabDropIndicator.collapsed = true;
+            if (win.windowState == STATE_MINIMIZED)
+              break;
+            this._endTabDrag();
+
+            // User dropped the tab onto another window's tab strip, so swap the
+            // tab with a new one we create in that window, and then close it in
+            // this window (making it seem to have moved between windows).
+            let newIndex = that._getDropIndex(event);
+            let newTab = that.tabbrowser.addTab("about:blank");
+            let newBrowser = that.tabbrowser.getBrowserForTab(newTab);
+            newBrowser.stop(); // Stop the about:blank load.
+            newBrowser.docShell; // Make sure it has a docshell.
+            let numPinned = that.tabbrowser._numPinnedTabs;
+            if (newIndex < numPinned || draggedTab.pinned && newIndex == numPinned)
+              that.tabbrowser.pinTab(newTab);
+            that.tabbrowser.moveTabTo(newTab, newIndex);
+            that.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
+
+            // We need to select the tab after we've done
+            // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
+            // it triggers will correctly update our URL bar.
+            that.selectedItem = newTab;
+            return;
+          } while (false);
+
+          let [left, top, width, height] = this._getAdjustedCoords(
+            event.screenX, event.screenY, outerWidth, outerHeight,
+            this._tabDragPanel.clientWidth / 2, draggedTab._dragData._dragOffsetY);
+          this._endTabDrag();
+
+          if (this.childElementCount == 1) {
+            // Resize _before_ move to ensure the window fits the new screen. If
+            // the window is too large for its screen, the window manager may do
+            // automatic repositioning.
+            window.resizeTo(width, height);
+            window.moveTo(left, top);
+            window.focus();
+            return;
+          }
+
+          draggedTab.collapsed = true;
+          this.tabbrowser.replaceTabWithWindow(draggedTab, { screenX: left,
+                                                             screenY: top,
+#ifndef XP_WIN
+                                                             outerWidth: width,
+                                                             outerHeight: height
+#endif
+                                                             });
+        ]]></body>
+      </method>
+
+      <method name="_slideTab">
+        <parameter name="event"/>
+        <parameter name="draggedTab"/>
+        <body><![CDATA[
+          let oldIndex = draggedTab._tPos;
+          let newIndex = draggedTab._dragData._dropIndex;
+          if (newIndex > oldIndex)
+            newIndex--;
+          this.removeAttribute("drag");
+          this._endTabDrag();
+
+          if (!draggedTab.pinned && newIndex < this.tabbrowser._numPinnedTabs)
+            this.tabbrowser.pinTab(draggedTab);
+          else if (draggedTab.pinned && newIndex >= this.tabbrowser._numPinnedTabs)
+            this.tabbrowser.unpinTab(draggedTab);
+          else if (Services.prefs.getBoolPref("browser.tabs.animate")) {
+            let difference = 0;
+            // Calculate number of visible tabs between start and destination.
+            if (newIndex != oldIndex) {
+              let tabs = this.tabbrowser.visibleTabs;
+              for (let i = 0; i < tabs.length; i++) {
+                let position = tabs[i]._tPos;
+                if (position <= newIndex && position > oldIndex)
+                  difference++;
+                else if (position >= newIndex && position < oldIndex)
+                  difference--;
+              }
+            }
+            let displacement = difference * draggedTab.getBoundingClientRect().width;
+            if (window.getComputedStyle(this).direction == "rtl")
+              displacement *= -1;
+            let destination = "translate(" + displacement + "px)";
+            if (draggedTab.style.MozTransform != destination) {
+              this.setAttribute("drag", "finish");
+              draggedTab.style.MozTransform = destination;
+              draggedTab.addEventListener("transitionend", function finish(event) {
+                if (event.eventPhase != Event.AT_TARGET ||
+                    event.propertyName != "-moz-transform")
+                  return;
+                draggedTab.removeEventListener("transitionend", finish);
+                draggedTab.removeAttribute("dragged");
+                let that = draggedTab.parentNode;
+                that.removeAttribute("drag");
+                that._clearDragTransforms();
+                that.tabbrowser.moveTabTo(draggedTab, newIndex);
+              });
+              return;
+            }
+          }
+          draggedTab.removeAttribute("dragged");
+          this._clearDragTransforms();
+          this.tabbrowser.moveTabTo(draggedTab, newIndex);
+        ]]></body>
+      </method>
+
+      <method name="_endTabDrag">
+        <body><![CDATA[
+          let tab = this.draggedTab;
+          if (!tab)
+            return;
+          this.draggedTab = null;
+          delete tab._dragData;
+
+          document.removeEventListener("mousemove", this);
+          document.removeEventListener("mouseup", this);
+          this.removeEventListener("TabSelect", this);
+          this.mTabstrip.removeEventListener("scroll", this);
+
+          this._tabDragPanel.hidePopup();
+          this._tabDragPanel.hidden = true;
+          this._tabDropIndicator.collapsed = true;
+
+          if (this.hasAttribute("drag")) {
+            if (this.getAttribute("drag") == "detach")
+              this._unlockTabSizing();
+            tab.removeAttribute("dragged");
+            this.removeAttribute("drag");
+            this._clearDragTransforms();
+          }
+        ]]></body>
+      </method>
+
+      <method name="_clearDragTransforms">
+        <body>
+          this.tabbrowser.visibleTabs.forEach(function(visibleTab) {
+            visibleTab.style.MozTransform = "";
+          });
+        </body>
+      </method>
+
       <field name="_dragOverDelay">350</field>
       <field name="_dragTime">0</field>
 
       <field name="_container" readonly="true"><![CDATA[
         this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
       ]]></field>
 
       <property name="visible"
@@ -2959,37 +3432,34 @@
               tab.style.setProperty("max-width", tabWidth, "important");
               if (!isEndTab) { // keep tabs the same width
                 tab.style.MozTransition = "none";
                 tab.clientTop; // flush styles to skip animation; see bug 649247
                 tab.style.MozTransition = "";
               }
             }
             this._hasTabTempMaxWidth = true;
-            this.tabbrowser.addEventListener("mousemove", this, false);
-            window.addEventListener("mouseout", this, false);
+            window.addEventListener("mouseout", this);
           }
         ]]></body>
       </method>
 
       <method name="_expandSpacerBy">
         <parameter name="pixels"/>
         <body><![CDATA[
           let spacer = this._closingTabsSpacer;
           spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
           this._usingClosingTabsSpacer = true;
-          this.tabbrowser.addEventListener("mousemove", this, false);
-          window.addEventListener("mouseout", this, false);
+          window.addEventListener("mouseout", this);
         ]]></body>
       </method>
 
       <method name="_unlockTabSizing">
         <body><![CDATA[
-          this.tabbrowser.removeEventListener("mousemove", this, false);
-          window.removeEventListener("mouseout", this, false);
+          window.removeEventListener("mouseout", this);
           if (this._hasTabTempMaxWidth) {
             this._hasTabTempMaxWidth = false;
             let tabs = this.tabbrowser.visibleTabs;
             for (let i = 0; i < tabs.length; i++)
               tabs[i].style.maxWidth = "";
           }
           if (this._usingClosingTabsSpacer) {
             this._usingClosingTabsSpacer = false;
@@ -3046,24 +3516,46 @@
                 this.adjustTabstrip();
                 this._fillTrailingGap();
                 this._handleTabSelect();
                 this.mTabstripWidth = width;
               }
               this.tabbrowser.updateWindowResizers();
               break;
             case "mouseout":
-              // If the "related target" (the node to which the pointer went) is not
-              // a child of the current document, the mouse just left the window.
-              let relatedTarget = aEvent.relatedTarget;
-              if (relatedTarget && relatedTarget.ownerDocument == document)
+              if (this.draggedTab)
+                break;
+              let bo = this.mTabstrip.boxObject;
+              if (aEvent.screenX >= bo.screenX && aEvent.screenX < bo.screenX + bo.width &&
+                  aEvent.screenY >= bo.screenY && aEvent.screenY < bo.screenY + bo.height)
+                break;
+              let tabContextMenu = document.getElementById("tabContextMenu");
+              if (tabContextMenu.state == "open")
+                tabContextMenu.addEventListener("popuphidden", this);
+              else
+                this._unlockTabSizing();
+              break;
+            case "popuphidden": // Tab context menu was closed.
+              if (aEvent.eventPhase != Event.AT_TARGET)
                 break;
+              aEvent.target.removeEventListener("popuphidden", this);
+              this._unlockTabSizing();
+              break;
             case "mousemove":
-              if (document.getElementById("tabContextMenu").state != "open")
-                this._unlockTabSizing();
+              this._handleTabDrag(aEvent);
+              break;
+            case "mouseup":
+              this._handleTabDrop(aEvent);
+              break;
+            case "TabSelect": // Focus was stolen from dragged tab!
+              this._endTabDrag(aEvent);
+              window.focus();
+              break;
+            case "scroll": // Tab strip was scrolled.
+              this._handleTabDrag();
               break;
           }
         ]]></body>
       </method>
 
       <field name="_animateElement">
         this.mTabstrip._scrollButtonDown;
       </field>
@@ -3120,83 +3612,74 @@
               return null;
           }
           return tab;
         ]]></body>
       </method>
 
       <method name="_getDropIndex">
         <parameter name="event"/>
+        <parameter name="draggedTab"/>
         <body><![CDATA[
-          var tabs = this.childNodes;
-          var tab = this._getDragTargetTab(event);
-          if (window.getComputedStyle(this, null).direction == "ltr") {
-            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
-              if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
-                return i;
-          } else {
-            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
-              if (event.screenX > tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
-                return i;
+          function compare(a, b, lessThan) lessThan ? a < b : a > b;
+          let ltr = (window.getComputedStyle(this).direction == "ltr");
+          let eX = event.screenX;
+          let tabs = this.tabbrowser.visibleTabs;
+
+          if (draggedTab) {
+            let dist = draggedTab._dragData._dragDistX;
+            let tabX = draggedTab.boxObject.screenX + dist;
+            let draggingRight = dist > 0;
+            if (draggingRight)
+              tabX += draggedTab.boxObject.width;
+            // iterate through app tabs first, since their z-index is higher
+            else if (!draggedTab.pinned)
+              for (let i = 0, numPinned = this.tabbrowser._numPinnedTabs; i < numPinned; i++)
+                if (compare(eX, tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2, ltr))
+                  return i;
+
+            let i = tabs.indexOf(draggedTab), tab = draggedTab, next;
+            while (next = ltr ^ draggingRight ? tabs[--i] : tabs[++i]) {
+              let x = next.pinned == draggedTab.pinned ? tabX : eX;
+              let middleOfNextTab = next.boxObject.screenX + next.boxObject.width / 2;
+              if (!compare(x, middleOfNextTab, !draggingRight))
+                break;
+              // ensure an app tab is actually inside the normal tab region
+              if (draggedTab.pinned && !next.pinned &&
+                  x < this.mTabstrip._scrollButtonUp.boxObject.screenX)
+                break;
+              tab = next;
+            }
+            return tab._tPos + (ltr ^ draggingRight ? 0 : 1);
           }
-          return tabs.length;
+
+          let tab = this._getDragTargetTab(event);
+          for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
+            if (compare(eX, tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2, ltr))
+              return tabs[i]._tPos;
+          return this.childElementCount;
         ]]></body>
       </method>
 
       <method name="_setEffectAllowedForDataTransfer">
         <parameter name="event"/>
         <body><![CDATA[
           var dt = event.dataTransfer;
           // Disallow dropping multiple items
           if (dt.mozItemCount > 1)
             return dt.effectAllowed = "none";
 
-          var types = dt.mozTypesAt(0);
-          var sourceNode = null;
-          // tabs are always added as the first type
-          if (types[0] == TAB_DROP_TYPE) {
-            var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-            if (sourceNode instanceof XULElement &&
-                sourceNode.localName == "tab" &&
-                (sourceNode.parentNode == this ||
-                 (sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
-                  sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser"))) {
-              if (sourceNode.parentNode == this &&
-                  (event.screenX >= sourceNode.boxObject.screenX &&
-                    event.screenX <= (sourceNode.boxObject.screenX +
-                                       sourceNode.boxObject.width))) {
-                return dt.effectAllowed = "none";
-              }
-
-              return dt.effectAllowed = "copyMove";
-            }
-          }
-
           if (browserDragAndDrop.canDropLink(event)) {
             // Here we need to do this manually
             return dt.effectAllowed = dt.dropEffect = "link";
           }
           return dt.effectAllowed = "none";
         ]]></body>
       </method>
 
-      <method name="_continueScroll">
-        <parameter name="event"/>
-        <body><![CDATA[
-          // Workaround for bug 481904: Dragging a tab stops scrolling at
-          // the tab's position when dragging to the first/last tab and back.
-          var t = this.selectedItem;
-          if (event.screenX >= t.boxObject.screenX &&
-              event.screenX <= t.boxObject.screenX + t.boxObject.width &&
-              event.screenY >= t.boxObject.screenY &&
-              event.screenY <= t.boxObject.screenY + t.boxObject.height)
-            this.mTabstrip.ensureElementIsVisible(t);
-        ]]></body>
-      </method>
-
       <method name="_handleNewTab">
         <parameter name="tab"/>
         <body><![CDATA[
           if (tab.parentNode != this)
             return;
 
           this.adjustTabstrip();
 
@@ -3319,306 +3802,96 @@
             // shortcuts only.
             return;
         }
         event.stopPropagation();
         event.preventDefault();
       ]]></handler>
 
       <handler event="dragstart"><![CDATA[
+        if (this.draggedTab)
+          return;
         var tab = this._getDragTargetTab(event);
-        if (!tab)
+        if (!tab || !tab._fullyOpen || tab.closing)
           return;
 
-        let dt = event.dataTransfer;
-        dt.mozSetDataAt(TAB_DROP_TYPE, tab, 0);
-        let uri = this.tabbrowser.getBrowserForTab(tab).currentURI;
-        let spec = uri ? uri.spec : "about:blank";
-
-        // We must not set text/x-moz-url or text/plain data here,
-        // otherwise trying to deatch the tab by dropping it on the desktop
-        // may result in an "internet shortcut"
-        dt.mozSetDataAt("text/x-moz-text-internal", spec, 0);
-
-        // Set the cursor to an arrow during tab drags.
-        dt.mozCursor = "default";
-
-        let canvas = tabPreviews.capture(tab, false);
-        dt.setDragImage(canvas, 0, 0);
-
-        // _dragOffsetX/Y give the coordinates that the mouse should be
-        // positioned relative to the corner of the new window created upon
-        // dragend such that the mouse appears to have the same position
-        // relative to the corner of the dragged tab.
-        function clientX(ele) ele.getBoundingClientRect().left;
-        let tabOffsetX = clientX(tab) -
-                         clientX(this.children[0].pinned ? this.children[0] : this);
-        tab._dragOffsetX = event.screenX - window.screenX - tabOffsetX;
-        tab._dragOffsetY = event.screenY - window.screenY;
+        this.setAttribute("drag", "move");
+        this.draggedTab = tab;
+        tab.setAttribute("dragged", "true");
+        let data = tab._dragData = {};
+        data._dragStartX = event.screenX;
+        if (!tab.pinned)
+          data._dragStartX += this.mTabstrip.scrollPosition;
+        data._dragDistX = 0;
+        data._dragOffsetY = event.screenY - window.screenY;
+        data._dropIndex = tab._tPos;
+        data._savedEvent = event;
+        data._targetWindow = window;
+
+        document.addEventListener("mousemove", this);
+        document.addEventListener("mouseup", this);
+        this.addEventListener("TabSelect", this);
+        this.mTabstrip.addEventListener("scroll", this);
 
         event.stopPropagation();
       ]]></handler>
 
-      <handler event="dragover"><![CDATA[
-        var effects = this._setEffectAllowedForDataTransfer(event);
-
-        var ind = this._tabDropIndicator;
-        if (effects == "" || effects == "none") {
-          ind.collapsed = true;
-          this._continueScroll(event);
+      <handler event="dragover" action="this._positionDropIndicator(event);"/>
+
+      <handler event="drop"><![CDATA[
+        this._tabDropIndicator.collapsed = true;
+
+        let dt = event.dataTransfer;
+        if (dt.dropEffect != "link")
+          return;
+
+        let url = browserDragAndDrop.drop(event, { });
+
+        // Disallow dropping strings that contain spaces (not a valid url
+        // character). Also disallow dropping javascript: or data: urls.
+        if (!url || !url.length || url.indexOf(" ") != -1 ||
+            /^\s*(javascript|data):/.test(url))
           return;
-        }
-        event.preventDefault();
-        event.stopPropagation();
-
-        var tabStrip = this.mTabstrip;
-        var ltr = (window.getComputedStyle(this, null).direction == "ltr");
-
-        // autoscroll the tab strip if we drag over the scroll
-        // buttons, even if we aren't dragging a tab, but then
-        // return to avoid drawing the drop indicator
-        var pixelsToScroll = 0;
-        if (this.getAttribute("overflow") == "true") {
-          var targetAnonid = event.originalTarget.getAttribute("anonid");
-          switch (targetAnonid) {
-            case "scrollbutton-up":
-              pixelsToScroll = tabStrip.scrollIncrement * -1;
-              break;
-            case "scrollbutton-down":
-              pixelsToScroll = tabStrip.scrollIncrement;
-              break;
-          }
-          if (pixelsToScroll)
-            tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
-        }
-
-        if (effects == "link") {
-          let tab = this._getDragTargetTab(event);
-          if (tab) {
-            if (!this._dragTime)
-              this._dragTime = Date.now();
-            if (Date.now() >= this._dragTime + this._dragOverDelay)
+
+        let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
+
+        if (event.shiftKey)
+          bgLoad = !bgLoad;
+
+        let tab = this._getDragTargetTab(event);
+        if (!tab) {
+          // We're adding a new tab.
+          let newIndex = this._getDropIndex(event);
+          let newTab = this.tabbrowser.loadOneTab(getShortcutOrURI(url), {inBackground: bgLoad});
+          this.tabbrowser.moveTabTo(newTab, newIndex);
+        } else {
+          // Load in an existing tab.
+          try {
+            this.tabbrowser.getBrowserForTab(tab).loadURI(getShortcutOrURI(url));
+            if (!bgLoad)
               this.selectedItem = tab;
             ind.collapsed = true;
             return;
-          }
-        }
-
-        var newIndex = this._getDropIndex(event);
-        var scrollRect = tabStrip.scrollClientRect;
-        var rect = this.getBoundingClientRect();
-        var minMargin = scrollRect.left - rect.left;
-        var maxMargin = Math.min(minMargin + scrollRect.width,
-                                 scrollRect.right);
-        if (!ltr)
-          [minMargin, maxMargin] = [this.clientWidth - maxMargin,
-                                    this.clientWidth - minMargin];
-        var newMargin;
-        if (pixelsToScroll) {
-          // if we are scrolling, put the drop indicator at the edge
-          // so that it doesn't jump while scrolling
-          newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
-        }
-        else {
-          if (newIndex == this.childNodes.length) {
-            let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
-            if (ltr)
-              newMargin = tabRect.right - rect.left;
-            else
-              newMargin = rect.right - tabRect.left;
-          }
-          else {
-            let tabRect = this.childNodes[newIndex].getBoundingClientRect();
-            if (ltr)
-              newMargin = tabRect.left - rect.left;
-            else
-              newMargin = rect.right - tabRect.right;
+          } catch(ex) {
+            // Just ignore invalid urls.
           }
         }
-
-        ind.collapsed = false;
-
-        newMargin += ind.clientWidth / 2;
-        if (!ltr)
-          newMargin *= -1;
-
-        ind.style.MozTransform = "translate(" + Math.round(newMargin) + "px)";
-        ind.style.MozMarginStart = (-ind.clientWidth) + "px";
-      ]]></handler>
-
-      <handler event="drop"><![CDATA[
-        var dt = event.dataTransfer;
-        var dropEffect = dt.dropEffect;
-        var draggedTab;
-        if (dropEffect != "link") { // copy or move
-          draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-          // not our drop then
-          if (!draggedTab)
-            return;
-        }
-
-        this._tabDropIndicator.collapsed = true;
-        event.stopPropagation();
-
-        if (draggedTab && (dropEffect == "copy" ||
-            draggedTab.parentNode == this)) {
-          let newIndex = this._getDropIndex(event);
-          if (dropEffect == "copy") {
-            // copy the dropped tab (wherever it's from)
-            let newTab = this.tabbrowser.duplicateTab(draggedTab);
-            this.tabbrowser.moveTabTo(newTab, newIndex);
-            if (draggedTab.parentNode != this || event.shiftKey)
-              this.selectedItem = newTab;
-          } else {
-            // move the dropped tab
-            if (newIndex > draggedTab._tPos)
-              newIndex--;
-
-            if (draggedTab.pinned) {
-              if (newIndex >= this.tabbrowser._numPinnedTabs)
-                this.tabbrowser.unpinTab(draggedTab);
-            } else {
-              if (newIndex <= this.tabbrowser._numPinnedTabs - 1)
-                this.tabbrowser.pinTab(draggedTab);
-            }
-
-            this.tabbrowser.moveTabTo(draggedTab, newIndex);
-          }
-        } else if (draggedTab) {
-          // swap the dropped tab with a new one we create and then close
-          // it in the other window (making it seem to have moved between
-          // windows)
-          let newIndex = this._getDropIndex(event);
-          let newTab = this.tabbrowser.addTab("about:blank");
-          let newBrowser = this.tabbrowser.getBrowserForTab(newTab);
-          // Stop the about:blank load
-          newBrowser.stop();
-          // make sure it has a docshell
-          newBrowser.docShell;
-
-          this.tabbrowser.moveTabTo(newTab, newIndex);
-
-          this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
-
-          // We need to select the tab after we've done
-          // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
-          // it triggers will correctly update our URL bar.
-          this.tabbrowser.selectedTab = newTab;
-        } else {
-          let url = browserDragAndDrop.drop(event, { });
-
-          // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
-          // Also disallow dropping javascript: or data: urls--bail out
-          if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
-              /^\s*(javascript|data):/.test(url))
-            return;
-
-          let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
-
-          if (event.shiftKey)
-            bgLoad = !bgLoad;
-
-          let tab = this._getDragTargetTab(event);
-          if (!tab || dropEffect == "copy") {
-            // We're adding a new tab.
-            let newIndex = this._getDropIndex(event);
-            let newTab = this.tabbrowser.loadOneTab(getShortcutOrURI(url), {inBackground: bgLoad});
-            this.tabbrowser.moveTabTo(newTab, newIndex);
-          } else {
-            // Load in an existing tab.
-            try {
-              this.tabbrowser.getBrowserForTab(tab).loadURI(getShortcutOrURI(url));
-              if (!bgLoad)
-                this.selectedItem = tab;
-            } catch(ex) {
-              // Just ignore invalid urls
-            }
-          }
-        }
-
-        // these offsets are only used in dragend, but we need to free them here
-        // as well
-        delete draggedTab._dragOffsetX;
-        delete draggedTab._dragOffsetY;
-      ]]></handler>
-
-      <handler event="dragend"><![CDATA[
-        // Note: while this case is correctly handled here, this event
-        // isn't dispatched when the tab is moved within the tabstrip,
-        // see bug 460801.
-
-        // * mozUserCancelled = the user pressed ESC to cancel the drag
-        var dt = event.dataTransfer;
-        if (dt.mozUserCancelled || dt.dropEffect != "none")
-          return;
-
-        // Disable detach within the browser toolbox
-        var eX = event.screenX;
-        var eY = event.screenY;
-        var wX = window.screenX;
-        // check if the drop point is horizontally within the window
-        if (eX > wX && eX < (wX + window.outerWidth)) {
-          let bo = this.mTabstrip.boxObject;
-          // also avoid detaching if the the tab was dropped too close to
-          // the tabbar (half a tab)
-          let endScreenY = bo.screenY + 1.5 * bo.height;
-          if (eY < endScreenY && eY > window.screenY)
-            return;
-        }
-
-        var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-        // screen.availLeft et. al. only check the screen that this window is on,
-        // but we want to look at the screen the tab is being dropped onto.
-        var sX = {}, sY = {}, sWidth = {}, sHeight = {};
-        Cc["@mozilla.org/gfx/screenmanager;1"]
-          .getService(Ci.nsIScreenManager)
-          .screenForRect(eX, eY, 1, 1)
-          .GetAvailRect(sX, sY, sWidth, sHeight);
-        // ensure new window entirely within screen
-        var winWidth = Math.min(window.outerWidth, sWidth.value);
-        var winHeight = Math.min(window.outerHeight, sHeight.value);
-        var left = Math.min(Math.max(eX - draggedTab._dragOffsetX, sX.value),
-                            sX.value + sWidth.value - winWidth);
-        var top = Math.min(Math.max(eY - draggedTab._dragOffsetY, sY.value),
-                           sY.value + sHeight.value - winHeight);
-
-        delete draggedTab._dragOffsetX;
-        delete draggedTab._dragOffsetY;
-
-        if (this.tabbrowser.tabs.length == 1) {
-          // resize _before_ move to ensure the window fits the new screen.  if
-          // the window is too large for its screen, the window manager may do
-          // automatic repositioning.
-          window.resizeTo(winWidth, winHeight);
-          window.moveTo(left, top);
-          window.focus();
-        } else {
-          this.tabbrowser.replaceTabWithWindow(draggedTab, { screenX: left,
-                                                             screenY: top,
-#ifndef XP_WIN
-                                                             outerWidth: winWidth,
-                                                             outerHeight: winHeight
-#endif
-                                                             });
-        }
-        event.stopPropagation();
       ]]></handler>
 
       <handler event="dragexit"><![CDATA[
         this._dragTime = 0;
 
         // This does not work at all (see bug 458613)
         var target = event.relatedTarget;
         while (target && target != this)
           target = target.parentNode;
         if (target)
           return;
 
         this._tabDropIndicator.collapsed = true;
-        this._continueScroll(event);
         event.stopPropagation();
       ]]></handler>
     </handlers>
   </binding>
 
   <!-- close-tab-button binding
        This binding relies on the structure of the tabbrowser binding.
        Therefore it should only be used as a child of the tab or the tabs
@@ -3736,17 +4009,16 @@
       <property name="hidden" readonly="true">
         <getter>
           return this.getAttribute("hidden") == "true";
         </getter>
       </property>
 
       <field name="mOverCloseButton">false</field>
       <field name="mCorrespondingMenuitem">null</field>
-      <field name="_fullyOpen">false</field>
       <field name="closing">false</field>
     </implementation>
 
     <handlers>
       <handler event="mouseover">
         var anonid = event.originalTarget.getAttribute("anonid");
         if (anonid == "close-button")
           this.mOverCloseButton = true;
--- a/browser/base/content/tabview/modules/AllTabs.jsm
+++ b/browser/base/content/tabview/modules/AllTabs.jsm
@@ -30,16 +30,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+"use strict";
+
 const Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 
 let EXPORTED_SYMBOLS = ["AllTabs"];
 
 let AllTabs = {
   // ----------
   // Function: toString
@@ -159,18 +161,18 @@ function tabEventListener(event) {
       Cu.reportError(ex);
     }
   });
 }
 
 function observer(subject, topic, data) {
   switch (topic) {
     case "domwindowopened":
-      subject.addEventListener("load", function() {
-        subject.removeEventListener("load", arguments.callee, false);
+      subject.addEventListener("load", function onLoad() {
+        subject.removeEventListener("load", onLoad, false);
 
         // Now that the window has loaded, only register on browser windows
         let doc = subject.document.documentElement;
         if (doc.getAttribute("windowtype") == "navigator:browser")
           registerBrowserWindow(subject);
       }, false);
       break;
   }
--- a/browser/base/content/tabview/modules/utils.jsm
+++ b/browser/base/content/tabview/modules/utils.jsm
@@ -40,16 +40,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+"use strict";
+
 // **********
 // Title: utils.js
 
 let EXPORTED_SYMBOLS = ["Point", "Rect", "Range", "Subscribable", "Utils"];
 
 // #########
 const Ci = Components.interfaces;
 const Cu = Components.utils;
@@ -364,20 +366,21 @@ Range.prototype = {
 
     var proportion = (value - this.min) / this.extent;
 
     if (smooth) {
       // The ease function ".5+.5*Math.tanh(4*x-2)" is a pretty
       // little graph. It goes from near 0 at x=0 to near 1 at x=1
       // smoothly and beautifully.
       // http://www.wolframalpha.com/input/?i=.5+%2B+.5+*+tanh%28%284+*+x%29+-+2%29
-      function tanh(x) {
+      let tanh = function tanh(x) {
         var e = Math.exp(x);
         return (e - 1/e) / (e + 1/e);
-      }
+      };
+
       return .5 - .5 * tanh(2 - 4 * proportion);
     }
 
     return proportion;
   },
 
   // ----------
   // Function: scale
@@ -518,22 +521,25 @@ let Utils = {
 
   // ----------
   // Function: trace
   // Prints the given arguments to the JavaScript error console as a message,
   // along with a full stack trace.
   // Pass as many arguments as you want, it'll print them all.
   trace: function Utils_trace() {
     var text = this.expandArgumentsForLog(arguments);
-    // cut off the first two lines of the stack trace, because they're just this function.
-    let stack = Error().stack.replace(/^.*?\n.*?\n/, "");
+
+    // cut off the first line of the stack trace, because that's just this function.
+    let stack = Error().stack.split("\n").slice(1);
+
     // if the caller was assert, cut out the line for the assert function as well.
-    if (this.trace.caller.name == 'Utils_assert')
-      stack = stack.replace(/^.*?\n/, "");
-    this.log('trace: ' + text + '\n' + stack);
+    if (stack[0].indexOf("Utils_assert(") == 0)
+      stack.splice(0, 1);
+
+    this.log('trace: ' + text + '\n' + stack.join("\n"));
   },
 
   // ----------
   // Function: assert
   // Prints a stack trace along with label (as a console message) if condition is false.
   assert: function Utils_assert(condition, label) {
     if (!condition) {
       let text;
@@ -552,20 +558,20 @@ let Utils = {
   assertThrow: function Utils_assertThrow(condition, label) {
     if (!condition) {
       let text;
       if (typeof label != 'string')
         text = 'badly formed assert';
       else
         text = "tabview assert: " + label;
 
-      // cut off the first two lines of the stack trace, because they're just this function.
-      text += Error().stack.replace(/^.*?\n.*?\n/, "");
+      // cut off the first line of the stack trace, because that's just this function.
+      let stack = Error().stack.split("\n").slice(1);
 
-      throw text;
+      throw text + "\n" + stack.join("\n");
     }
   },
 
   // ----------
   // Function: expandObject
   // Prints the given object to a string, including all of its properties.
   expandObject: function Utils_expandObject(obj) {
     var s = obj + ' = {';
--- a/browser/base/content/tabview/search.js
+++ b/browser/base/content/tabview/search.js
@@ -580,27 +580,26 @@ function ensureSearchShown(activatedByKe
     $search.show();
 
 #ifdef XP_MACOSX
     UI.setTitlebarColors({active: "#717171", inactive: "#EDEDED"});
 #endif
 
     // NOTE: when this function is called by keydown handler, next keypress
     // event or composition events of IME will be fired on the focused editor.
-
-    function dispatchTabViewSearchEnabledEvent() {
+    let dispatchTabViewSearchEnabledEvent = function dispatchTabViewSearchEnabledEvent() {
       let newEvent = document.createEvent("Events");
       newEvent.initEvent("tabviewsearchenabled", false, false);
       dispatchEvent(newEvent);
     };
 
     if (activatedByKeypress) {
       // set the focus so key strokes are entered into the textbox.
       $searchbox[0].focus();
-      dispatchTabViewSearchEnabledEvent(); 
+      dispatchTabViewSearchEnabledEvent();
     } else {
       // marshal the focusing, otherwise it ends up with searchbox[0].focus gets
       // called before the search button gets the focus after being pressed.
       setTimeout(function setFocusAndDispatchSearchEnabledEvent() {
         $searchbox[0].focus();
         dispatchTabViewSearchEnabledEvent();
       }, 0);
     }
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -477,16 +477,17 @@ TabItem.prototype = Utils.extend(new Ite
   // Parameters:
   //   groupClose - true if this method is called by group close action.
   // Returns true if this tab is removed.
   close: function TabItem_close(groupClose) {
     // When the last tab is closed, put a new tab into closing tab's group. If
     // closing tab doesn't belong to a group and no empty group, create a new 
     // one for the new tab.
     if (!groupClose && gBrowser.tabs.length == 1) {
+      let group;
       if (this.tab._tabViewTabItem.parent) {
         group = this.tab._tabViewTabItem.parent;
       } else {
         let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
           return (!groupItem.getChildren().length);
         });
         group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
       }
--- a/browser/base/content/tabview/tabview.js
+++ b/browser/base/content/tabview/tabview.js
@@ -1,8 +1,10 @@
+"use strict";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource:///modules/tabview/AllTabs.jsm");
 Cu.import("resource:///modules/tabview/utils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
--- a/browser/base/content/tabview/thumbnailStorage.js
+++ b/browser/base/content/tabview/thumbnailStorage.js
@@ -100,18 +100,18 @@ let ThumbnailStorage = {
     gBrowser.browsers.forEach(function(browser) {
       let checkAndAddToList = function(browserObj) {
         if (!self.enablePersistentHttpsCaching &&
             browserObj.currentURI.schemeIs("https"))
           self.excludedBrowsers.push(browserObj);
       };
       if (browser.contentDocument.readyState != "complete" ||
           browser.webProgress.isLoadingDocument) {
-        browser.addEventListener("load", function() {
-          browser.removeEventListener("load", arguments.callee, true);
+        browser.addEventListener("load", function onLoad() {
+          browser.removeEventListener("load", onLoad, true);
           checkAndAddToList(browser);
         }, true);
       } else {
         checkAndAddToList(browser);
       }
     });
     gBrowser.addTabsProgressListener(this);
   },
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -856,18 +856,18 @@ let UI = {
         return;
       }
       if (this._closedLastVisibleTab ||
           (this._closedSelectedTabInTabView && !this.closedLastTabInTabView) ||
           this.restoredClosedTab) {
         if (this.restoredClosedTab) {
           // when the tab view UI is being displayed, update the thumb for the 
           // restored closed tab after the page load
-          tab.linkedBrowser.addEventListener("load", function (event) {
-            tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+          tab.linkedBrowser.addEventListener("load", function onLoad(event) {
+            tab.linkedBrowser.removeEventListener("load", onLoad, true);
             TabItems._update(tab);
           }, true);
         }
         this._closedLastVisibleTab = false;
         this._closedSelectedTabInTabView = false;
         this.closedLastTabInTabView = false;
         this.restoredClosedTab = false;
         return;
@@ -999,16 +999,19 @@ let UI = {
     keys = {};
     // The lower case letters are passed to processBrowserKeys() even with shift 
     // key when stimulating a key press using EventUtils.synthesizeKey() so need 
     // to handle both upper and lower cases here.
     [
 #ifdef XP_UNIX
       "redo",
 #endif
+#ifdef XP_MACOSX
+      "fullScreen",
+#endif
       "closeWindow", "tabview", "undoCloseTab", "undoCloseWindow",
       "privatebrowsing"
     ].forEach(function(key) {
       let element = gWindow.document.getElementById("key_" + key);
       let code = element.getAttribute("key").toLocaleLowerCase().charCodeAt(0);
       keys[code] = key;
     });
     this._browserKeysWithShift = keys;
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -255,16 +255,19 @@ endif
                  browser_aboutHome.js \
                  app_bug575561.html \
                  app_subframe_bug575561.html \
                  browser_contentAreaClick.js \
                  browser_addon_bar_close_button.js \
                  browser_addon_bar_shortcut.js \
                  browser_addon_bar_aomlistener.js \
                  test_bug628179.html \
+                 browser_wyciwyg_urlbarCopying.js \
+                 test_wyciwyg_copying.html \
+                 authenticate.sjs \
                  browser_minimize.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
 		browser_bug462289.js \
 		$(NULL)
 else
copy from toolkit/components/passwordmgr/test/authenticate.sjs
copy to browser/base/content/test/authenticate.sjs
--- a/browser/base/content/test/browser_urlbarCopying.js
+++ b/browser/base/content/test/browser_urlbarCopying.js
@@ -1,24 +1,27 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const trimPref = "browser.urlbar.trimURLs";
+const phishyUserPassPref = "network.http.phishy-userpass-length";
 
 function test() {
 
-  gBrowser.selectedTab = gBrowser.addTab();
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
 
   registerCleanupFunction(function () {
-    gBrowser.removeCurrentTab();
+    gBrowser.removeTab(tab);
     Services.prefs.clearUserPref(trimPref);
+    Services.prefs.clearUserPref(phishyUserPassPref);
     URLBarSetURI();
   });
 
   Services.prefs.setBoolPref(trimPref, true);
+  Services.prefs.setIntPref(phishyUserPassPref, 32); // avoid prompting about phishing
 
   waitForExplicitFinish();
 
   nextTest();
 }
 
 var tests = [
   // pageproxystate="invalid"
@@ -27,17 +30,16 @@ var tests = [
     expectedURL: "example.com",
     copyExpected: "example.com"
   },
   {
     copyVal: "<e>xample.com",
     copyExpected: "e"
   },
 
-
   // pageproxystate="valid" from this point on (due to the load)
   {
     loadURL: "http://example.com/",
     expectedURL: "example.com",
     copyExpected: "http://example.com/"
   },
   {
     copyVal: "<example.co>m",
@@ -47,16 +49,23 @@ var tests = [
     copyVal: "e<x>ample.com",
     copyExpected: "x"
   },
   {
     copyVal: "<e>xample.com",
     copyExpected: "http://e"
   },
 
+  // Test that userPass is stripped out
+  {
+    loadURL: "http://user:pass@mochi.test:8888/browser/browser/base/content/test/authenticate.sjs?user=user&pass=pass",
+    expectedURL: "mochi.test:8888/browser/browser/base/content/test/authenticate.sjs?user=user&pass=pass",
+    copyExpected: "http://mochi.test:8888/browser/browser/base/content/test/authenticate.sjs?user=user&pass=pass"
+  },
+
   // Test escaping
   {
     loadURL: "http://example.com/()%C3%A9",
     expectedURL: "example.com/()\xe9",
     copyExpected: "http://example.com/%28%29%C3%A9"
   },
   {
     copyVal: "<example.com/(>)\xe9",
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_wyciwyg_urlbarCopying.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  let url = "http://mochi.test:8888/browser/browser/base/content/test/test_wyciwyg_copying.html";
+  let tab = gBrowser.selectedTab = gBrowser.addTab(url);
+  tab.linkedBrowser.addEventListener("pageshow", function () {
+    let btn = content.document.getElementById("btn");
+    executeSoon(function () {
+      EventUtils.synthesizeMouseAtCenter(btn, {}, content);
+      let currentURL = gBrowser.currentURI.spec;
+      ok(/^wyciwyg:\/\//i.test(currentURL), currentURL + " is a wyciwyg URI");
+
+      executeSoon(function () {
+        testURLBarCopy(url, endTest);
+      });
+    });
+  }, false);
+
+  function endTest() {
+    while (gBrowser.tabs.length > 1)
+      gBrowser.removeCurrentTab();
+    finish();
+  }
+
+  function testURLBarCopy(targetValue, cb) {
+    info("Expecting copy of: " + targetValue);
+    waitForClipboard(targetValue, function () {
+      gURLBar.focus();
+      gURLBar.select();
+
+      goDoCommand("cmd_copy");
+    }, cb, cb);
+  }
+}
+
+
--- a/browser/base/content/test/inspector/Makefile.in
+++ b/browser/base/content/test/inspector/Makefile.in
@@ -49,13 +49,14 @@ include $(topsrcdir)/config/rules.mk
 		browser_inspector_highlighter.js \
 		browser_inspector_iframeTest.js \
 		browser_inspector_scrolling.js \
 		browser_inspector_store.js \
 		browser_inspector_tab_switch.js \
 		browser_inspector_treePanel_output.js \
 		browser_inspector_treePanel_input.html \
 		browser_inspector_treePanel_result.html \
+		browser_inspector_registertools.js \
 		browser_inspector_bug_665880.js \
 		$(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/inspector/browser_inspector_registertools.js
@@ -0,0 +1,275 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Inspector Highlighter Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Ratcliffe <mratcliffe@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let doc;
+let h1;
+let tool1;
+let tool2;
+let tool3;
+
+function createDocument()
+{
+  let div = doc.createElement("div");
+  let h1 = doc.createElement("h1");
+  let p1 = doc.createElement("p");
+  let p2 = doc.createElement("p");
+  let div2 = doc.createElement("div");
+  let p3 = doc.createElement("p");
+  doc.title = "Inspector Tree Selection Test";
+  h1.textContent = "Inspector Tree Selection Test";
+  p1.textContent = "This is some example text";
+  p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
+    "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
+    "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
+    "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
+    "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
+    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
+    "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
+  p3.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
+    "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
+    "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
+    "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
+    "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
+    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
+    "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
+  div.appendChild(h1);
+  div.appendChild(p1);
+  div.appendChild(p2);
+  div2.appendChild(p3);
+  doc.body.appendChild(div);
+  doc.body.appendChild(div2);
+  setupHighlighterTests();
+}
+
+function setupHighlighterTests()
+{
+  h1 = doc.querySelectorAll("h1")[0];
+  ok(h1, "we have the header node");
+  Services.obs.addObserver(inspectorOpen, "inspector-opened", false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function inspectorOpen()
+{
+  info("we received the inspector-opened notification");
+  Services.obs.removeObserver(inspectorOpen, "inspector-opened", false);
+  Services.obs.addObserver(startToolTests, "inspector-highlighting", false);
+  let rect = h1.getBoundingClientRect();
+  executeSoon(function() {
+    EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
+  });
+}
+
+function startToolTests(evt)
+{
+  info("we received the inspector-highlighting notification");
+  Services.obs.removeObserver(startToolTests, "inspector-highlighting", false);
+  InspectorUI.stopInspecting();
+
+  info("Getting InspectorUI.tools");
+  let tools = InspectorUI.tools;
+  tool1 = InspectorUI.tools["tool_1"];
+  tool2 = InspectorUI.tools["tool_2"];
+  tool3 = InspectorUI.tools["tool_3"];
+
+  info("Checking panel states 1");
+  ok(tool1.context.panelIsClosed, "Panel 1 is closed");
+  ok(tool2.context.panelIsClosed, "Panel 2 is closed");
+  ok(tool3.context.panelIsClosed, "Panel 3 is closed");
+
+  info("Calling show method for all tools");
+  tool1.onShow.apply(tool1.context, [h1]);
+  tool2.onShow.apply(tool2.context, [h1]);
+  tool3.onShow.apply(tool3.context, [h1]);
+
+  info("Checking panel states 2");
+  ok(tool1.context.panelIsOpen, "Panel 1 is open");
+  ok(tool2.context.panelIsOpen, "Panel 2 is open");
+  ok(tool3.context.panelIsOpen, "Panel 3 is open");
+
+  info("Calling selectNode method for all tools");
+  tool1.onSelect.apply(tool1.context, [h1]);
+  tool2.onSelect.apply(tool2.context, [h1]);
+  tool3.onSelect.apply(tool3.context, [h1]);
+
+  info("Calling hide method for all tools");
+  tool1.onHide.apply(tool1.context, [h1]);
+  tool2.onHide.apply(tool2.context, [h1]);
+  tool3.onHide.apply(tool3.context, [h1]);
+
+  info("Checking panel states 3");
+  ok(tool1.context.panelIsClosed, "Panel 1 is closed");
+  ok(tool2.context.panelIsClosed, "Panel 2 is closed");
+  ok(tool3.context.panelIsClosed, "Panel 3 is closed");
+
+  info("Showing tools 1 & 3");
+  tool1.onShow.apply(tool1.context, [h1]);
+  tool3.onShow.apply(tool3.context, [h1]);
+
+  info("Checking panel states 4");
+  ok(tool1.context.panelIsOpen, "Panel 1 is open");
+  ok(tool2.context.panelIsClosed, "Panel 2 is closed");
+  ok(tool3.context.panelIsOpen, "Panel 3 is open");
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    waitForFocus(testSecondTab, content);
+  }, true);
+
+  content.location = "data:text/html,registertool new tab test for inspector";
+}
+
+function testSecondTab()
+{
+  info("Opened second tab");
+  info("Checking panel states 5");
+  ok(tool1.context.panelIsClosed, "Panel 1 is closed");
+  ok(tool2.context.panelIsClosed, "Panel 2 is closed");
+  ok(tool3.context.panelIsClosed, "Panel 3 is closed");
+
+  info("Closing current tab");
+  gBrowser.removeCurrentTab();
+
+  info("Checking panel states 6");
+  ok(tool1.context.panelIsOpen, "Panel 1 is open");
+  ok(tool2.context.panelIsClosed, "Panel 2 is closed");
+  ok(tool3.context.panelIsOpen, "Panel 3 is open");
+
+  executeSoon(finishUp);
+}
+
+function finishUp() {
+  InspectorUI.closeInspectorUI(true);
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(registerTools, content);
+  }, true);
+  
+  content.location = "data:text/html,registertool tests for inspector";
+}
+
+function registerTools()
+{
+  createDocument();
+  registerTool(new testTool("tool_1", "Tool 1", "Tool 1 tooltip", "I"));
+  registerTool(new testTool("tool_2", "Tool 2", "Tool 2 tooltip", "J"));
+  registerTool(new testTool("tool_3", "Tool 3", "Tool 3 tooltip", "K"));
+}
+
+function registerTool(aTool)
+{
+  InspectorUI.registerTool({
+    id: aTool.id,
+    label: aTool.label,
+    tooltiptext: aTool.tooltip,
+    accesskey: aTool.accesskey,
+    context: aTool,
+    onSelect: aTool.selectNode,
+    onShow: aTool.show,
+    onHide: aTool.hide,
+    panel: aTool.panel
+  });
+}
+
+// Tool Object
+function testTool(aToolId, aLabel, aTooltip, aAccesskey)
+{
+  this.id = aToolId;
+  this.label = aLabel;
+  this.tooltip = aTooltip;
+  this.accesskey = aAccesskey
+  this.panel = this.createPanel();
+}
+
+testTool.prototype = {
+  get panelIsOpen()
+  {
+    return this.panel.state == "open" || this.panel.state == "showing";
+  },
+
+  get panelIsClosed()
+  {
+    return this.panel.state == "closed" || this.panel.state == "hiding";
+  },
+
+  selectNode: function BIR_selectNode(aNode) {
+    is(InspectorUI.selection, aNode,
+       "selectNode: currently selected node was passed: " + this.id);
+  },
+
+  show: function BIR_show(aNode) {
+    this.panel.openPopup(gBrowser.selectedBrowser,
+                         "end_before", 0, 20, false, false);
+    is(InspectorUI.selection, aNode,
+       "show: currently selected node was passed: " + this.id);
+  },
+
+  hide: function BIR_hide() {
+    info(this.id + " hide");
+    this.panel.hidePopup();
+  },
+
+  createPanel: function BIR_createPanel() {
+    let popupSet = document.getElementById("mainPopupSet");
+    let ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+    let panel = this.panel = document.createElementNS(ns, "panel");
+    panel.setAttribute("orient", "vertical");
+    panel.setAttribute("noautofocus", "true");
+    panel.setAttribute("noautohide", "true");
+    panel.setAttribute("titlebar", "normal");
+    panel.setAttribute("close", "true");
+    panel.setAttribute("label", "Panel for " + this.id);
+    panel.setAttribute("width", 200);
+    panel.setAttribute("height", 400);
+    popupSet.appendChild(panel);
+
+    ok(panel.parentNode == popupSet, "Panel created and appended successfully");
+    return panel;
+  },
+};
--- a/browser/base/content/test/tabview/browser_tabview_bug597980.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug597980.js
@@ -66,20 +66,20 @@ function part2(win) {
   let newTab = win.gBrowser.loadOneTab("about:blank", {inBackground: true});
   hideTabView(function() {
     let selectedTab = win.gBrowser.selectedTab;
     isnot(selectedTab, newTab, "They are different tabs");
 
     // switch the selected tab to new tab
     win.gBrowser.selectedTab = newTab;
 
-    win.addEventListener("tabviewhidden", function () {
-      win.removeEventListener("tabviewhidden", arguments.callee, false);
+    whenTabViewIsHidden(function () {
       is(win.gBrowser.selectedTab, newTab, "The seleted tab should be the same as before (new tab)");
        win.close();
        finish();
-    }, false);
+    });
+
     // show tabview
     EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win);
     // hide tabview
     EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win);
   })
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug598600.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug598600.js
@@ -4,18 +4,18 @@
 let newWin;
 function test() {
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
 
   waitForExplicitFinish();
 
   // open a new window and setup the window state.
   newWin = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
-  newWin.addEventListener("load", function(event) {
-    this.removeEventListener("load", arguments.callee, false);
+  newWin.addEventListener("load", function onLoad(event) {
+    this.removeEventListener("load", onLoad, false);
 
     let newState = {
       windows: [{
         tabs: [{
           entries: [{ "url": "about:blank" }],
           hidden: true,
           attributes: {},
           extData: {
--- a/browser/base/content/test/tabview/browser_tabview_bug618828.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug618828.js
@@ -50,18 +50,18 @@ function onTabViewWindowLoaded(win, tab)
   }
 
   let testClickOnOtherSearchResult = function () {
     // search for the tab from our main window
     searchbox.setAttribute('value', 'other');
     contentWindow.performSearch();
 
     // prepare to finish when the main window gets focus back
-    window.addEventListener('focus', function () {
-      window.removeEventListener('focus', arguments.callee, true);
+    window.addEventListener('focus', function onFocus() {
+      window.removeEventListener('focus', onFocus, true);
       assertSearchIsDisabled();
 
       // check that the right tab is active
       is(gBrowser.selectedTab, tab, 'search result is the active tab');
 
       finishTest();
     }, true);
 
--- a/browser/base/content/test/tabview/browser_tabview_bug622835.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug622835.js
@@ -6,22 +6,20 @@ function test() {
 
   newWindowWithTabView(onTabViewShown);
 }
 
 function onTabViewShown(win) {
   let contentWindow = win.TabView.getContentWindow();
 
   let finishTest = function () {
-    win.addEventListener('tabviewhidden', function () {
-      win.removeEventListener('tabviewhidden', arguments.callee, false);
+    hideTabView(function () {
       win.close();
       finish();
-    }, false);
-    win.TabView.hide();
+    }, win);
   }
 
   // do not let the group arrange itself
   contentWindow.GroupItems.pauseArrange();
 
   // let's create a groupItem small enough to get stacked
   let groupItem = new contentWindow.GroupItem([], {
     immediately: true,
--- a/browser/base/content/test/tabview/browser_tabview_multiwindow_search.js
+++ b/browser/base/content/test/tabview/browser_tabview_multiwindow_search.js
@@ -3,37 +3,35 @@
 
 let newWindows = [];
 
 function test() {
   waitForExplicitFinish();
   let windowOne = openDialog(location, "", "chrome,all,dialog=no", "data:text/html,");
   let windowTwo;
 
-  windowOne.addEventListener("load", function() {
-    windowOne.removeEventListener("load", arguments.callee, false);
-    windowOne.gBrowser.selectedBrowser.addEventListener("load", function() {
-      windowOne.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+  whenWindowLoaded(windowOne, function () {
+    windowOne.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
+      windowOne.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
 
       windowTwo = openDialog(location, "", "chrome,all,dialog=no", "http://mochi.test:8888/");
-      windowTwo.addEventListener("load", function() {
-        windowTwo.removeEventListener("load", arguments.callee, false);
-        windowTwo.gBrowser.selectedBrowser.addEventListener("load", function() {
-          windowTwo.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+      whenWindowLoaded(windowTwo, function () {
+        windowTwo.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
+          windowTwo.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
 
           newWindows = [ windowOne, windowTwo ];
 
           // show the tab view
           window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
           ok(!TabView.isVisible(), "Tab View is hidden");
           TabView.toggle();
         }, true);
-      }, false);
+      });
     }, true);
-  }, false);
+  });
 }
 
 function onTabViewWindowLoaded() {
   window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
   ok(TabView.isVisible(), "Tab View is visible");
 
   let contentWindow = document.getElementById("tab-view").contentWindow;
   let search = contentWindow.document.getElementById("search");
--- a/browser/base/content/test/tabview/browser_tabview_undo_group.js
+++ b/browser/base/content/test/tabview/browser_tabview_undo_group.js
@@ -20,17 +20,17 @@ function onTabViewWindowLoaded() {
   registerCleanupFunction(function() {
     let groupItem = contentWindow.GroupItems.groupItem(groupItemId);
     if (groupItem)
       closeGroupItem(groupItem, function() {});
   });
 
   // create a group item
   let groupItem = createGroupItemWithBlankTabs(window, 300, 300, 400, 1);
-  groupItemId = groupItem.id;
+  let groupItemId = groupItem.id;
   is(groupItem.getChildren().length, 1, "The new group has a tab item");
   // start the tests
   waitForFocus(function() {
     testUndoGroup(contentWindow, groupItem);
   }, contentWindow);
 }
 
 function testUndoGroup(contentWindow, groupItem) {
--- a/browser/base/content/test/tabview/head.js
+++ b/browser/base/content/test/tabview/head.js
@@ -163,33 +163,33 @@ function hideTabView(callback, win) {
 function whenTabViewIsHidden(callback, win) {
   win = win || window;
 
   if (!win.TabView.isVisible()) {
     callback();
     return;
   }
 
-  win.addEventListener('tabviewhidden', function () {
-    win.removeEventListener('tabviewhidden', arguments.callee, false);
+  win.addEventListener('tabviewhidden', function onHidden() {
+    win.removeEventListener('tabviewhidden', onHidden, false);
     callback();
   }, false);
 }
 
 // ----------
 function whenTabViewIsShown(callback, win) {
   win = win || window;
 
   if (win.TabView.isVisible()) {
     callback();
     return;
   }
 
-  win.addEventListener('tabviewshown', function () {
-    win.removeEventListener('tabviewshown', arguments.callee, false);
+  win.addEventListener('tabviewshown', function onShown() {
+    win.removeEventListener('tabviewshown', onShown, false);
     callback();
   }, false);
 }
 
 // ----------
 function showSearch(callback, win) {
   win = win || window;
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/test_wyciwyg_copying.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+<script>
+  function go() {
+    var w = window.open();
+    w.document.open();
+    w.document.write("<html><body>test document</body></html>");
+    w.document.close();
+  }
+</script>
+<button id="btn" onclick="go();">test</button>
+</body>
+</html>
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -505,16 +505,20 @@
           var selectedVal = inputVal.substring(this.selectionStart, this.selectionEnd);
 
           // If the selection doesn't start at the beginning or URL bar is
           // modified, nothing else to do here.
           if (this.getAttribute("pageproxystate") != "valid" || this.selectionStart > 0)
             return selectedVal;
 
           let uri = gBrowser.currentURI;
+          // Only copy exposable URIs
+          try {
+            uri = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup).createExposableURI(uri);
+          } catch (ex) {}
 
           // If the entire URL is selected, just use the actual loaded URI.
           if (inputVal == selectedVal) {
             // ... but only if  isn't a javascript: or data: URI, since those
             // are hard to read when encoded
             if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
               // Parentheses are known to confuse third-party applications (bug 458565).
               selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -37,18 +37,16 @@
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 // Services = object with smart getters for common XPCOM services
 Components.utils.import("resource://gre/modules/Services.jsm");
 
-var TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
-
 var gBidiUI = false;
 
 function getBrowserURL()
 {
   return "chrome://browser/content/browser.xul";
 }
 
 function getTopWin(skipPopups) {
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -88,10 +88,8 @@ browser.jar:
 #endif
 *       content/browser/viewSourceOverlay.xul         (content/viewSourceOverlay.xul)
 #ifdef XP_WIN
 *       content/browser/win6BrowserOverlay.xul        (content/win6BrowserOverlay.xul)
 #endif
 # the following files are browser-specific overrides
 *       content/browser/license.html                  (/toolkit/content/license.html)
 % override chrome://global/content/license.html chrome://browser/content/license.html
-# XXXkhuey This really should live in browser/, but it's too late in the release cycle to move
-+       content/browser/NetworkPanel.xhtml            (/toolkit/components/console/hudservice/NetworkPanel.xhtml)
--- a/browser/build.mk
+++ b/browser/build.mk
@@ -42,18 +42,16 @@ endif
 TIERS += app
 
 ifdef MOZ_EXTENSIONS
 tier_app_dirs += extensions
 endif
 
 tier_app_dirs += $(MOZ_BRANDING_DIRECTORY)
 
-tier_app_dirs += toolkit/components/console/hudservice
-
 ifdef MOZ_SERVICES_SYNC
 tier_app_dirs += services
 endif
 
 tier_app_dirs += browser
 # Never add other tier_app_dirs after browser. They won't get packaged
 # properly on mac.
 
--- a/browser/components/migration/src/nsProfileMigrator.cpp
+++ b/browser/components/migration/src/nsProfileMigrator.cpp
@@ -277,21 +277,21 @@ nsProfileMigrator::GetDefaultBrowserMigr
 
 PRBool
 nsProfileMigrator::ImportRegistryProfiles(const nsACString& aAppName)
 {
   nsresult rv;
 
   nsCOMPtr<nsIToolkitProfileService> profileSvc
     (do_GetService(NS_PROFILESERVICE_CONTRACTID));
-  NS_ENSURE_TRUE(profileSvc, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(profileSvc, PR_FALSE);
 
   nsCOMPtr<nsIProperties> dirService
     (do_GetService("@mozilla.org/file/directory_service;1"));
-  NS_ENSURE_TRUE(dirService, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(dirService, PR_FALSE);
 
   nsCOMPtr<nsILocalFile> regFile;
 #ifdef XP_WIN
   rv = dirService->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile),
                        getter_AddRefs(regFile));
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
   regFile->AppendNative(aAppName);
   regFile->AppendNative(NS_LITERAL_CSTRING("registry.dat"));
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -146,19 +146,18 @@ BrowserGlue.prototype = {
     const MAX_DELAY = 300;
     let delay = 3;
     let browserEnum = Services.wm.getEnumerator("navigator:browser");
     while (browserEnum.hasMoreElements()) {
       delay += browserEnum.getNext().gBrowser.tabs.length;
     }
     delay = delay <= MAX_DELAY ? delay : MAX_DELAY;
 
-    let syncTemp = {};
-    Cu.import("resource://services-sync/service.js", syncTemp);
-    syncTemp.Weave.Service.delayedAutoConnect(delay);
+    Cu.import("resource://services-sync/main.js");
+    Weave.SyncScheduler.delayedAutoConnect(delay);
   },
 #endif
 
   // nsIObserver implementation 
   observe: function BG_observe(subject, topic, data) {
     switch (topic) {
       case "xpcom-shutdown":
         this._dispose();
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -1391,27 +1391,23 @@ let PlacesControllerDragHelper = {
     // Check every dragged item.
     for (let i = 0; i < dropCount; i++) {
       let flavor = this.getFirstValidFlavor(dt.mozTypesAt(i));
       if (!flavor)
         return false;
 
       // Urls can be dropped on any insertionpoint.
       // XXXmano: remember that this method is called for each dragover event!
-      // Thus we shouldn't use unwrapNodes here at all if possible.
-      // I think it would be OK to accept bogus data here (e.g. text which was
-      // somehow wrapped as TAB_DROP_TYPE, this is not in our control, and
-      // will just case the actual drop to be a no-op), and only rule out valid
+      // Thus we shouldn't use unwrapNodes here at all if possible. I think it
+      // would be OK to accept bogus data here (this is not in our control and
+      // will just case the actual drop to be a no-op) and only rule out valid
       // expected cases, which are either unsupported flavors, or items which
       // cannot be dropped in the current insertionpoint. The last case will
       // likely force us to use unwrapNodes for the private data types of
       // places.
-      if (flavor == TAB_DROP_TYPE)
-        continue;
-
       let data = dt.mozGetDataAt(flavor, i);
       let dragged;
       try {
         dragged = PlacesUtils.unwrapNodes(data, flavor)[0];
       }
       catch (e) {
         return false;
       }
@@ -1515,31 +1511,18 @@ let PlacesControllerDragHelper = {
     let movedCount = 0;
     for (let i = 0; i < dropCount; ++i) {
       let flavor = this.getFirstValidFlavor(dt.mozTypesAt(i));
       if (!flavor)
         return false;
 
       let data = dt.mozGetDataAt(flavor, i);
       let unwrapped;
-      if (flavor != TAB_DROP_TYPE) {
-        // There's only ever one in the D&D case.
-        unwrapped = PlacesUtils.unwrapNodes(data, flavor)[0];
-      }
-      else if (data instanceof XULElement && data.localName == "tab" &&
-               data.ownerDocument.defaultView instanceof ChromeWindow) {
-        let uri = data.linkedBrowser.currentURI;
-        let spec = uri ? uri.spec : "about:blank";
-        let title = data.label;
-        unwrapped = { uri: spec,
-                      title: data.label,
-                      type: PlacesUtils.TYPE_X_MOZ_URL};
-      }
-      else
-        throw("bogus data was passed as a tab")
+      // There's only ever one in the D&D case.
+      unwrapped = PlacesUtils.unwrapNodes(data, flavor)[0];
 
       let index = insertionPoint.index;
 
       // Adjust insertion index to prevent reversal of dragged items. When you
       // drag multiple elts upward: need to increment index or each successive
       // elt will be inserted at the same index, each above the previous.
       let dragginUp = insertionPoint.itemId == unwrapped.parent &&
                       index < PlacesUtils.bookmarks.getItemIndex(unwrapped.id);
@@ -1583,17 +1566,16 @@ let PlacesControllerDragHelper = {
                   PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
                   PlacesUtils.TYPE_X_MOZ_PLACE],
 
   // The order matters.
   GENERIC_VIEW_DROP_TYPES: [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
                             PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
                             PlacesUtils.TYPE_X_MOZ_PLACE,
                             PlacesUtils.TYPE_X_MOZ_URL,
-                            TAB_DROP_TYPE,
                             PlacesUtils.TYPE_UNICODE],
 };
 
 
 XPCOMUtils.defineLazyServiceGetter(PlacesControllerDragHelper, "dragService",
                                    "@mozilla.org/widget/dragservice;1",
                                    "nsIDragService");
 
--- a/browser/components/sessionstore/src/nsSessionStartup.js
+++ b/browser/components/sessionstore/src/nsSessionStartup.js
@@ -245,17 +245,17 @@ SessionStartup.prototype = {
       // This might throw if we're removing the observer multiple times,
       // but this is safe to ignore.
     }
   },
 
 /* ........ Public API ................*/
 
   /**
-   * Get the session state as a string
+   * Get the session state as a jsval
    */
   get state() {
     return this._initialState;
   },
 
   /**
    * Determine whether there is a pending session restore.
    * @returns bool
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -111,28 +111,30 @@ XXX keep these in sync with all the attr
 const CAPABILITIES = [
   "Subframes", "Plugins", "Javascript", "MetaRedirects", "Images",
   "DNSPrefetch", "Auth", "WindowControl"
 ];
 
 // These keys are for internal use only - they shouldn't be part of the JSON
 // that gets saved to disk nor part of the strings returned by the API.
 const INTERNAL_KEYS = ["_tabStillLoading", "_hosts", "_formDataSaved",
-                       "_shouldRestore"];
+                       "_shouldRestore", "_host", "_scheme"];
 
 // These are tab events that we listen to.
 const TAB_EVENTS = ["TabOpen", "TabClose", "TabSelect", "TabShow", "TabHide",
                     "TabPinned", "TabUnpinned"];
 
 #ifndef XP_WIN
 #define BROKEN_WM_Z_ORDER
 #endif
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+// debug.js adds NS_ASSERT. cf. bug 669196
+Cu.import("resource://gre/modules/debug.js");
 
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
 XPCOMUtils.defineLazyServiceGetter(this, "CookieSvc",
   "@mozilla.org/cookiemanager;1", "nsICookieManager2");
@@ -1664,20 +1666,41 @@ SessionStoreService.prototype = {
     if (history && browser.__SS_data &&
         browser.__SS_data.entries[history.index] &&
         browser.__SS_data.entries[history.index].url == browser.currentURI.spec &&
         history.index < this._sessionhistory_max_entries - 1 && !aFullData) {
       tabData = browser.__SS_data;
       tabData.index = history.index + 1;
     }
     else if (history && history.count > 0) {
-      for (var j = 0; j < history.count; j++) {
-        let entry = this._serializeHistoryEntry(history.getEntryAtIndex(j, false),
-                                                aFullData, aTab.pinned);
-        tabData.entries.push(entry);
+      try {
+        for (var j = 0; j < history.count; j++) {
+          let entry = this._serializeHistoryEntry(history.getEntryAtIndex(j, false),
+                                                  aFullData, aTab.pinned);
+          tabData.entries.push(entry);
+        }
+        // If we make it through the for loop, then we're ok and we should clear
+        // any indicator of brokenness.
+        delete aTab.__SS_broken_history;
+      }
+      catch (ex) {
+        // In some cases, getEntryAtIndex will throw. This seems to be due to
+        // history.count being higher than it should be. By doing this in a
+        // try-catch, we'll update history to where it breaks, assert for
+        // non-release builds, and still save sessionstore.js. We'll track if
+        // we've shown the assert for this tab so we only show it once.
+        // cf. bug 669196.
+        if (!aTab.__SS_broken_history) {
+          // First Focus the window & tab we're having trouble with.
+          aTab.ownerDocument.defaultView.focus();
+          aTab.ownerDocument.defaultView.gBrowser.selectedTab = aTab;
+          NS_ASSERT(false, "SessionStore failed gathering complete history " +
+                           "for the focused window/tab. See bug 669196.");
+          aTab.__SS_broken_history = true;
+        }
       }
       tabData.index = history.index + 1;
 
       // make sure not to cache privacy sensitive data which shouldn't get out
       if (!aFullData)
         browser.__SS_data = tabData;
     }
     else if (browser.currentURI.spec != "about:blank" ||
@@ -1742,17 +1765,25 @@ SessionStoreService.prototype = {
    *        always return privacy sensitive data (use with care)
    * @param aIsPinned
    *        the tab is pinned and should be treated differently for privacy
    * @returns object
    */
   _serializeHistoryEntry:
     function sss_serializeHistoryEntry(aEntry, aFullData, aIsPinned) {
     var entry = { url: aEntry.URI.spec };
-    
+
+    try {
+      entry._host = aEntry.URI.host;
+      entry._scheme = aEntry.URI.scheme;
+    }
+    catch (ex) {
+      // We just won't attempt to get cookies for this entry.
+    }
+
     if (aEntry.title && aEntry.title != entry.url) {
       entry.title = aEntry.title;
     }
     if (aEntry.isSubFrame) {
       entry.subframe = true;
     }
     if (!(aEntry instanceof Ci.nsISHEntry)) {
       return entry;
@@ -2150,31 +2181,30 @@ SessionStoreService.prototype = {
    * @param aCheckPrivacy
    *        should we check the privacy level for https
    * @param aIsPinned
    *        is the entry we're evaluating for a pinned tab; used only if
    *        aCheckPrivacy
    */
   _extractHostsForCookies:
     function sss__extractHostsForCookies(aEntry, aHosts, aCheckPrivacy, aIsPinned) {
-    let match;
-
-    if ((match = /^https?:\/\/(?:[^@\/\s]+@)?([\w.-]+)/.exec(aEntry.url)) != null) {
-      if (!aHosts[match[1]] &&
-          (!aCheckPrivacy ||
-           this._checkPrivacyLevel(this._getURIFromString(aEntry.url).schemeIs("https"),
-                                   aIsPinned))) {
-        // By setting this to true or false, we can determine when looking at
-        // the host in _updateCookies if we should check for privacy.
-        aHosts[match[1]] = aIsPinned;
-      }
+
+    // _host and _scheme may not be set (for about: urls for example), in which
+    // case testing _scheme will be sufficient.
+    if (/https?/.test(aEntry._scheme) && !aHosts[aEntry._host] &&
+        (!aCheckPrivacy ||
+         this._checkPrivacyLevel(aEntry._scheme == "https", aIsPinned))) {
+      // By setting this to true or false, we can determine when looking at
+      // the host in _updateCookies if we should check for privacy.
+      aHosts[aEntry._host] = aIsPinned;
     }
-    else if ((match = /^file:\/\/([^\/]*)/.exec(aEntry.url)) != null) {
-      aHosts[match[1]] = true;
+    else if (aEntry._scheme == "file") {
+      aHosts[aEntry._host] = true;
     }
+
     if (aEntry.children) {
       aEntry.children.forEach(function(entry) {
         this._extractHostsForCookies(entry, aHosts, aCheckPrivacy, aIsPinned);
       }, this);
     }
   },
 
   /**
new file mode 100644
--- /dev/null
+++ b/browser/devtools/Makefile.in
@@ -0,0 +1,56 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Rob Campbell <rcampbell@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH   = ../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH   = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = \
+  webconsole \
+  $(NULL)
+
+ifdef ENABLE_TESTS
+# DIRS += test # no tests yet
+endif
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/devtools/jar.mn
@@ -0,0 +1,2 @@
+browser.jar:
+    content/browser/NetworkPanel.xhtml            (webconsole/NetworkPanel.xhtml)
rename from toolkit/components/console/hudservice/AutocompletePopup.jsm
rename to browser/devtools/webconsole/AutocompletePopup.jsm
rename from toolkit/components/console/hudservice/HUDService.jsm
rename to browser/devtools/webconsole/HUDService.jsm
--- a/toolkit/components/console/hudservice/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -1725,17 +1725,17 @@ HUD_SERVICE.prototype =
     // remove the nodes then.
     hud.jsterm.clearOutput();
 
     // Make sure that the console panel does not try to call
     // deactivateHUDForContext() again.
     hud.consoleWindowUnregisterOnHide = false;
 
     // Remove the HUDBox and the consolePanel if the Web Console is inside a
-    // floating xul:panel.
+    // floating panel.
     hud.HUDBox.parentNode.removeChild(hud.HUDBox);
     if (hud.consolePanel) {
       hud.consolePanel.parentNode.removeChild(hud.consolePanel);
     }
 
     if (hud.splitter.parentNode) {
       hud.splitter.parentNode.removeChild(hud.splitter);
     }
@@ -2500,40 +2500,40 @@ HUD_SERVICE.prototype =
    * @returns void
    */
   logNetActivity: function HS_logNetActivity(aActivityObject)
   {
     let hudId = aActivityObject.hudId;
     let outputNode = this.hudReferences[hudId].outputNode;
 
     let chromeDocument = outputNode.ownerDocument;
-    let msgNode = chromeDocument.createElementNS(XUL_NS, "xul:hbox");
-
-    let methodNode = chromeDocument.createElementNS(XUL_NS, "xul:label");
+    let msgNode = chromeDocument.createElementNS(XUL_NS, "hbox");
+
+    let methodNode = chromeDocument.createElementNS(XUL_NS, "label");
     methodNode.setAttribute("value", aActivityObject.method);
     methodNode.classList.add("webconsole-msg-body-piece");
     msgNode.appendChild(methodNode);
 
-    let linkNode = chromeDocument.createElementNS(XUL_NS, "xul:hbox");
+    let linkNode = chromeDocument.createElementNS(XUL_NS, "hbox");
     linkNode.setAttribute("flex", "1");
     linkNode.classList.add("webconsole-msg-body-piece");
     linkNode.classList.add("webconsole-msg-link");
     msgNode.appendChild(linkNode);
 
-    let urlNode = chromeDocument.createElementNS(XUL_NS, "xul:label");
+    let urlNode = chromeDocument.createElementNS(XUL_NS, "label");
     urlNode.setAttribute("crop", "center");
     urlNode.setAttribute("flex", "1");
     urlNode.setAttribute("title", aActivityObject.url);
     urlNode.setAttribute("value", aActivityObject.url);
     urlNode.classList.add("hud-clickable");
     urlNode.classList.add("webconsole-msg-body-piece");
     urlNode.classList.add("webconsole-msg-url");
     linkNode.appendChild(urlNode);
 
-    let statusNode = chromeDocument.createElementNS(XUL_NS, "xul:label");
+    let statusNode = chromeDocument.createElementNS(XUL_NS, "label");
     statusNode.setAttribute("value", "");
     statusNode.classList.add("hud-clickable");
     statusNode.classList.add("webconsole-msg-body-piece");
     statusNode.classList.add("webconsole-msg-status");
     linkNode.appendChild(statusNode);
 
     let clipboardText = aActivityObject.method + " " + aActivityObject.url;
 
@@ -3035,17 +3035,17 @@ HeadsUpDisplay.prototype = {
     return this.chromeDocument.getElementById("mainPopupSet");
   },
 
   /**
    * Get the tab associated to the HeadsUpDisplay object.
    */
   get tab()
   {
-    // TODO: we should only keep a reference to the xul:tab object and use
+    // TODO: we should only keep a reference to the tab object and use
     // getters to determine the rest of objects we need - the chrome window,
     // document, etc. We should simplify the entire code to use only a single
     // tab object ref. See bug 656231.
     let tab = null;
     let id = this.notificationBox.id;
     Array.some(this.chromeDocument.defaultView.gBrowser.tabs, function(aTab) {
       if (aTab.linkedPanel == id) {
         tab = aTab;
@@ -3131,63 +3131,56 @@ HeadsUpDisplay.prototype = {
 
       if (this.jsterm) {
         this.jsterm.inputNode.focus();
       }
     }).bind(this);
 
     panel.addEventListener("popupshown", onPopupShown,false);
 
-    let onPopupHiding = (function HUD_onPopupHiding(aEvent) {
+    let onPopupHidden = (function HUD_onPopupHidden(aEvent) {
       if (aEvent.target != panel) {
         return;
       }
 
-      panel.removeEventListener("popuphiding", onPopupHiding, false);
+      panel.removeEventListener("popuphidden", onPopupHidden, false);
+      if (panel.parentNode) {
+        panel.parentNode.removeChild(panel);
+      }
 
       let width = 0;
       try {
         width = Services.prefs.getIntPref("devtools.webconsole.width");
       }
       catch (ex) { }
 
-      if (width > -1) {
+      if (width > 0) {
         Services.prefs.setIntPref("devtools.webconsole.width", panel.clientWidth);
       }
 
-      Services.prefs.setIntPref("devtools.webconsole.top", panel.popupBoxObject.y);
-      Services.prefs.setIntPref("devtools.webconsole.left", panel.popupBoxObject.x);
+      /*
+       * Removed because of bug 674562
+       * Services.prefs.setIntPref("devtools.webconsole.top", panel.panelBox.y);
+       * Services.prefs.setIntPref("devtools.webconsole.left", panel.panelBox.x);
+       */
 
       // Make sure we are not going to close again, drop the hudId reference of
       // the panel.
       panel.removeAttribute("hudId");
 
       if (this.consoleWindowUnregisterOnHide) {
         HUDService.deactivateHUDForContext(this.tab, false);
       }
       else {
         this.consoleWindowUnregisterOnHide = true;
       }
 
       this.consolePanel = null;
     }).bind(this);
 
-    panel.addEventListener("popuphiding", onPopupHiding, false);
-
-    let onPopupHidden = (function HUD_onPopupHidden(aEvent) {
-      if (aEvent.target != panel) {
-        return;
-      }
-
-      panel.removeEventListener("popuphidden", onPopupHidden, false);
-      if (panel.parentNode) {
-        panel.parentNode.removeChild(panel);
-      }
-    }).bind(this);
-
     panel.addEventListener("popuphidden", onPopupHidden, false);
 
     let lastIndex = -1;
 
     if (this.outputNode.getIndexOfFirstVisibleRow) {
       lastIndex = this.outputNode.getIndexOfFirstVisibleRow() +
                   this.outputNode.getNumberOfVisibleRows() - 1;
     }
@@ -3244,20 +3237,24 @@ HeadsUpDisplay.prototype = {
   consoleWindowUnregisterOnHide: true,
 
   /**
    * Re-position the console
    */
   positionConsole: function HUD_positionConsole(aPosition)
   {
     if (!(aPosition in this.positions)) {
-      throw new Error("Incorrect argument: " + aPosition  + ". Cannot position Web Console");
+      throw new Error("Incorrect argument: " + aPosition +
+        ". Cannot position Web Console");
     }
 
     if (aPosition == "window") {
+      let closeButton = this.consoleFilterToolbar.
+        querySelector(".webconsole-close-button");
+      closeButton.setAttribute("hidden", "true");
       this.createOwnWindowPanel();
       this.positionMenuitems.window.setAttribute("checked", true);
       if (this.positionMenuitems.last) {
         this.positionMenuitems.last.setAttribute("checked", false);
       }
       this.positionMenuitems.last = this.positionMenuitems[aPosition];
       this.uiInOwnWindow = true;
       return;
@@ -3303,16 +3300,20 @@ HeadsUpDisplay.prototype = {
     this.positionMenuitems.last = this.positionMenuitems[aPosition];
 
     Services.prefs.setCharPref("devtools.webconsole.position", aPosition);
 
     if (lastIndex > -1 && lastIndex < this.outputNode.getRowCount()) {
       this.outputNode.ensureIndexIsVisible(lastIndex);
     }
 
+    let closeButton = this.consoleFilterToolbar.
+      getElementsByClassName("webconsole-close-button")[0];
+    closeButton.removeAttribute("hidden");
+
     this.uiInOwnWindow = false;
     if (this.consolePanel) {
       this.HUDBox.removeAttribute("flex");
       this.HUDBox.removeAttribute("height");
       this.HUDBox.style.height = height + "px";
 
       // must destroy the consolePanel
       this.consoleWindowUnregisterOnHide = false;
@@ -3579,17 +3580,17 @@ HeadsUpDisplay.prototype = {
 
     return toolbar;
   },
 
   /**
    * Creates the UI for re-positioning the console
    *
    * @return nsIDOMNode
-   *         The xul:toolbarbutton which holds the menu that allows the user to
+   *         The toolbarbutton which holds the menu that allows the user to
    *         change the console position.
    */
   createPositionUI: function HUD_createPositionUI()
   {
     let self = this;
 
     let button = this.makeXULNode("toolbarbutton");
     button.setAttribute("type", "menu");
@@ -5391,76 +5392,79 @@ ConsoleUtils = {
     if (aBody instanceof Ci.nsIDOMNode && aClipboardText == null) {
       throw new Error("HUDService.createMessageNode(): DOM node supplied " +
                       "without any clipboard text");
     }
 
     // Make the icon container, which is a vertical box. Its purpose is to
     // ensure that the icon stays anchored at the top of the message even for
     // long multi-line messages.
-    let iconContainer = aDocument.createElementNS(XUL_NS, "xul:vbox");
+    let iconContainer = aDocument.createElementNS(XUL_NS, "vbox");
     iconContainer.classList.add("webconsole-msg-icon-container");
 
     // Make the icon node. It's sprited and the actual region of the image is
     // determined by CSS rules.
-    let iconNode = aDocument.createElementNS(XUL_NS, "xul:image");
+    let iconNode = aDocument.createElementNS(XUL_NS, "image");
     iconNode.classList.add("webconsole-msg-icon");
     iconContainer.appendChild(iconNode);
 
     // Make the spacer that positions the icon.
-    let spacer = aDocument.createElementNS(XUL_NS, "xul:spacer");
+    let spacer = aDocument.createElementNS(XUL_NS, "spacer");
     spacer.setAttribute("flex", "1");
     iconContainer.appendChild(spacer);
 
     // Create the message body, which contains the actual text of the message.
-    let bodyNode = aDocument.createElementNS(XUL_NS, "xul:description");
+    let bodyNode = aDocument.createElementNS(XUL_NS, "description");
     bodyNode.setAttribute("flex", "1");
     bodyNode.classList.add("webconsole-msg-body");
 
     // If a string was supplied for the body, turn it into a DOM node and an
     // associated clipboard string now.
     aClipboardText = aClipboardText ||
                      (aBody + (aSourceURL ? " @ " + aSourceURL : "") +
                               (aSourceLine ? ":" + aSourceLine : ""));
     aBody = aBody instanceof Ci.nsIDOMNode ?
             aBody : aDocument.createTextNode(aBody);
 
     bodyNode.appendChild(aBody);
 
-    let repeatNode = aDocument.createElementNS(XUL_NS, "xul:label");
+    let repeatContainer = aDocument.createElementNS(XUL_NS, "hbox");
+    repeatContainer.setAttribute("align", "start");
+    let repeatNode = aDocument.createElementNS(XUL_NS, "label");
     repeatNode.setAttribute("value", "1");
     repeatNode.classList.add("webconsole-msg-repeat");
+    repeatContainer.appendChild(repeatNode);
 
     // Create the timestamp.
-    let timestampNode = aDocument.createElementNS(XUL_NS, "xul:label");
+    let timestampNode = aDocument.createElementNS(XUL_NS, "label");
     timestampNode.classList.add("webconsole-timestamp");
     let timestamp = ConsoleUtils.timestamp();
     let timestampString = ConsoleUtils.timestampString(timestamp);
     timestampNode.setAttribute("value", timestampString);
 
     // Create the source location (e.g. www.example.com:6) that sits on the
     // right side of the message, if applicable.
     let locationNode;
     if (aSourceURL) {
       locationNode = this.createLocationNode(aDocument, aSourceURL,
                                              aSourceLine);
     }
 
     // Create the containing node and append all its elements to it.
-    let node = aDocument.createElementNS(XUL_NS, "xul:richlistitem");
+    let node = aDocument.createElementNS(XUL_NS, "richlistitem");
     node.clipboardText = aClipboardText;
     node.classList.add("hud-msg-node");
 
     node.timestamp = timestamp;
     ConsoleUtils.setMessageType(node, aCategory, aSeverity);
 
     node.appendChild(timestampNode);  // childNode[0]
     node.appendChild(iconContainer);  // childNode[1]
     node.appendChild(bodyNode);       // childNode[2]
-    node.appendChild(repeatNode);     // childNode[3]
+    node.appendChild(repeatContainer);  // childNode[3]
     if (locationNode) {
       node.appendChild(locationNode); // childNode[4]
     }
 
     node.setAttribute("id", "console-msg-" + HUDService.sequenceId());
 
     return node;
   },
@@ -5515,17 +5519,17 @@ ConsoleUtils = {
    *        The line number on which the error occurred. If zero or omitted,
    *        there is no line number associated with this message.
    * @return nsIDOMNode
    *         The new XUL label node, ready to be added to the message node.
    */
   createLocationNode:
   function ConsoleUtils_createLocationNode(aDocument, aSourceURL,
                                            aSourceLine) {
-    let locationNode = aDocument.createElementNS(XUL_NS, "xul:label");
+    let locationNode = aDocument.createElementNS(XUL_NS, "label");
 
     // Create the text, which consists of an abbreviated version of the URL
     // plus an optional line number.
     let text = ConsoleUtils.abbreviateSourceURL(aSourceURL);
     if (aSourceLine) {
       text += ":" + aSourceLine;
     }
     locationNode.setAttribute("value", text);
@@ -5585,18 +5589,19 @@ ConsoleUtils = {
    *
    * @param nsIDOMNode aOriginal
    *        The Original Node. The one being merged into.
    * @param nsIDOMNode aFiltered
    *        The node being filtered out because it is repeated.
    */
   mergeFilteredMessageNode:
   function ConsoleUtils_mergeFilteredMessageNode(aOriginal, aFiltered) {
-    // childNodes[3] is the node containing the number of repetitions of a node.
-    let repeatNode = aOriginal.childNodes[3];
+    // childNodes[3].firstChild is the node containing the number of repetitions
+    // of a node.
+    let repeatNode = aOriginal.childNodes[3].firstChild;
     if (!repeatNode) {
       return aOriginal; // no repeat node, return early.
     }
 
     let occurrences = parseInt(repeatNode.getAttribute("value")) + 1;
     repeatNode.setAttribute("value", occurrences);
   },
 
@@ -5653,17 +5658,17 @@ ConsoleUtils = {
    *        The outputNode of the HUD.
    * @return boolean
    *         true if the message is filtered, false otherwise.
    */
   filterRepeatedConsole:
   function ConsoleUtils_filterRepeatedConsole(aNode, aOutput) {
     let lastMessage = aOutput.lastChild;
 
-    // childNodes[2] is the xul:description element
+    // childNodes[2] is the description element
     if (lastMessage &&
         aNode.childNodes[2].textContent ==
         lastMessage.childNodes[2].textContent) {
       this.mergeFilteredMessageNode(lastMessage, aNode);
       return true;
     }
 
     return false;
rename from toolkit/components/console/hudservice/Makefile.in
rename to browser/devtools/webconsole/Makefile.in
--- a/toolkit/components/console/hudservice/Makefile.in
+++ b/browser/devtools/webconsole/Makefile.in
@@ -16,43 +16,45 @@
 #
 # The Initial Developer of the Original Code is Mozilla Corporation.
 # 
 # Portions created by the Initial Developer are Copyright (C) 2010
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   David Dahl <ddahl@mozilla.com>
+#   Rob Campbell <rcampbell@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH		= ../../../..
+DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-EXTRA_JS_MODULES = HUDService.jsm \
+EXTRA_JS_MODULES = \
+		HUDService.jsm \
 		PropertyPanel.jsm \
 		NetworkHelper.jsm \
 		AutocompletePopup.jsm \
 		$(NULL)
 
 ifdef ENABLE_TESTS
 ifneq (mobile,$(MOZ_BUILD_APP))
-	DIRS += tests
+	DIRS += test
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
rename from toolkit/components/console/hudservice/NetworkHelper.jsm
rename to browser/devtools/webconsole/NetworkHelper.jsm
rename from toolkit/components/console/hudservice/NetworkPanel.xhtml
rename to browser/devtools/webconsole/NetworkPanel.xhtml
rename from toolkit/components/console/hudservice/PropertyPanel.jsm
rename to browser/devtools/webconsole/PropertyPanel.jsm
rename from toolkit/components/console/hudservice/tests/Makefile.in
rename to browser/devtools/webconsole/test/Makefile.in
--- a/toolkit/components/console/hudservice/tests/Makefile.in
+++ b/browser/devtools/webconsole/test/Makefile.in
@@ -31,20 +31,18 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH		= ../../../../..
+DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= test_hudservice
-
 DIRS = browser
 
 include $(topsrcdir)/config/rules.mk
rename from toolkit/components/console/hudservice/tests/browser/Makefile.in
rename to browser/devtools/webconsole/test/browser/Makefile.in
--- a/toolkit/components/console/hudservice/tests/browser/Makefile.in
+++ b/browser/devtools/webconsole/test/browser/Makefile.in
@@ -16,36 +16,37 @@
 # The Initial Developer of the Original Code is Mozilla Foundation.
 # Portions created by the Initial Developer are Copyright (C) 2010
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #  David Dahl <ddahl@mozilla.com>
 #  Patrick Walton <pcwalton@mozilla.com>
 #  Mihai Șucan <mihai.sucan@gmail.com>
+#  Rob Campbell <rcampbell@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either of the GNU General Public License Version 2 or later (the "GPL"),
 # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH			= ../../../../../..
+DEPTH			= ../../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH			= @srcdir@
-relativesrcdir  = toolkit/components/console/hudservice/tests/browser
+relativesrcdir  = browser/devtools/webconsole/test/browser
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES = \
 	browser_webconsole_notifications.js \
 	browser_webconsole_message_node_id.js \
 	browser_webconsole_bug_580030_errors_after_page_reload.js \
rename from toolkit/components/console/hudservice/tests/browser/browser_warn_user_about_replaced_api.js
rename to browser/devtools/webconsole/test/browser/browser_warn_user_about_replaced_api.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_warn_user_about_replaced_api.js
+++ b/browser/devtools/webconsole/test/browser/browser_warn_user_about_replaced_api.js
@@ -32,17 +32,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_REPLACED_API_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console-replaced-api.html";
+const TEST_REPLACED_API_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console-replaced-api.html";
 
 function test() {
   waitForExplicitFinish();
 
   // First test that the warning does not appear on a normal page (about:blank)
   addTab("about:blank");
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_abbreviate_source_url.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_abbreviate_source_url.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_basic_net_logging.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_basic_net_logging.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_basic_net_logging.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_basic_net_logging.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the page's resources are displayed in the console as they're
 // loaded
 
-const TEST_NETWORK_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network.html" + "?_date=" + Date.now();
+const TEST_NETWORK_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-network.html" + "?_date=" + Date.now();
 
 function test() {
   addTab("data:text/html,Web Console basic network logging test");
   browser.addEventListener("load", onLoad, true);
 }
 
 function onLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_578437_page_reload.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_578437_page_reload.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_578437_page_reload.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_578437_page_reload.js
@@ -34,17 +34,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the console object still exists after a page reload.
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_579412_input_focus.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_579412_input_focus.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_579412_input_focus.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_579412_input_focus.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the input field is focused when the console is opened.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testInputFocus, false);
 }
 
 function testInputFocus() {
   browser.removeEventListener("DOMContentLoaded", testInputFocus, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580001_closing_after_completion.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_580001_closing_after_completion.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580001_closing_after_completion.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_580001_closing_after_completion.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests to ensure that errors don't appear when the console is closed while a
 // completion is being performed.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testClosingAfterCompletion,
                            false);
 }
 
 function testClosingAfterCompletion() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_580030_errors_after_page_reload.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that errors still show up in the Web Console after a page reload.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-error.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-error.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", onLoad, true);
 }
 
 // see bug 580030: the error handler fails silently after page reload.
 // https://bugzilla.mozilla.org/show_bug.cgi?id=580030
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580400_groups.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_580400_groups.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580400_groups.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_580400_groups.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that console groups behave properly.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testGroups, false);
 }
 
 function testGroups() {
   browser.removeEventListener("DOMContentLoaded", testGroups, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580454_timestamp_l10n.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_580454_timestamp_l10n.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_580454_timestamp_l10n.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_580454_timestamp_l10n.js
@@ -7,17 +7,17 @@
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that appropriately-localized timestamps are printed.
 
 Cu.import("resource:///modules/HUDService.jsm");
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testTimestamp, false);
 
   function testTimestamp()
   {
     browser.removeEventListener("DOMContentLoaded", testTimestamp, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_581231_close_button.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_581231_close_button.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_581231_close_button.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_581231_close_button.js
@@ -5,17 +5,17 @@
  *
  * Contributor(s):
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the Web Console close button functions.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testCloseButton, false);
 }
 
 function testCloseButton() {
   browser.removeEventListener("DOMContentLoaded", testCloseButton, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_582201_duplicate_errors.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_582201_duplicate_errors.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_582201_duplicate_errors.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_582201_duplicate_errors.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that exceptions thrown by content don't show up twice in the Web
 // Console.
 
-const TEST_DUPLICATE_ERROR_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-duplicate-error.html";
+const TEST_DUPLICATE_ERROR_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-duplicate-error.html";
 
 function test() {
   addTab(TEST_DUPLICATE_ERROR_URI);
   browser.addEventListener("DOMContentLoaded", testDuplicateErrors, false);
 }
 
 function testDuplicateErrors() {
   browser.removeEventListener("DOMContentLoaded", testDuplicateErrors,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_583816_tab_focus.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_583816_tab_focus.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_583816_tab_focus.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_583816_tab_focus.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 let HUD, inputNode;
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   waitForFocus(function() {
     openConsole();
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585237_line_limit.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_585237_line_limit.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585237_line_limit.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_585237_line_limit.js
@@ -7,17 +7,17 @@
  *  Patrick Walton <pcwalton@mozilla.com>
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the Web Console limits the number of lines displayed according to
 // the user's preferences.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testLineLimit,
                                             false);
 }
 
 function testLineLimit() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585956_console_trace.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_585956_console_trace.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585956_console_trace.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_585956_console_trace.js
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-585956-console-trace.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-585956-console-trace.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585991_autocomplete_keys.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_585991_autocomplete_keys.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_585991_autocomplete_popup.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_585991_autocomplete_popup.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_586388_select_all.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_586388_select_all.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_587617_output_copy.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_587617_output_copy.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_587617_output_copy.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_587617_output_copy.js
@@ -3,17 +3,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588342_document_focus.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_588342_document_focus.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588730_text_node_insertion.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_588730_text_node_insertion.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588730_text_node_insertion.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_588730_text_node_insertion.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that adding text to one of the output labels doesn't cause errors.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testTextNodeInsertion,
                            false);
 }
 
 // Test for bug 588730: Adding a text node to an existing label element causes
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588967_input_expansion.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_588967_input_expansion.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_588967_input_expansion.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_588967_input_expansion.js
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testInputExpansion, false);
 }
 
 function testInputExpansion() {
   browser.removeEventListener("DOMContentLoaded", testInputExpansion, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_589162_css_filter.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_589162_css_filter.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_592442_closing_brackets.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_592442_closing_brackets.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_593003_iframe_wrong_hud.js
@@ -31,21 +31,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-593003-iframe-wrong-hud.html";
 
-const TEST_IFRAME_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud-iframe.html";
+const TEST_IFRAME_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-593003-iframe-wrong-hud-iframe.html";
 
-const TEST_DUMMY_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_DUMMY_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 let tab1, tab2;
 
 function test() {
   addTab(TEST_URI);
   tab1 = tab;
   browser.addEventListener("load", tab1Loaded, true);
 }
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594477_clickable_output.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_594477_clickable_output.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594477_clickable_output.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_594477_clickable_output.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 let HUD;
 
 let outputItem;
 
 function tabLoad1(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   openConsole();
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_594497_history_arrow_keys.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_594497_history_arrow_keys.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595223_file_uri.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_595223_file_uri.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595350_multiple_windows_and_tabs.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_595350_multiple_windows_and_tabs.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595934_message_categories.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_595934_message_categories.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_595934_message_categories.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_595934_message_categories.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TESTS_PATH = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/";
+const TESTS_PATH = "http://example.com/browser/browser/devtools/webconsole/test//browser/";
 const TESTS = [
   { // #0
     file: "test-bug-595934-css-loader.html",
     category: "CSS Loader",
     matchString: "text/css",
   },
   { // #1
     file: "test-bug-595934-dom-events.html",
@@ -46,17 +46,17 @@ const TESTS = [
   },
   { // #6
     file: "test-bug-595934-svg.xhtml",
     category: "SVG",
     matchString: "fooBarSVG",
   },
   { // #7
     file: "test-bug-595934-workers.html",
-    category: "DOM Worker javascript",
+    category: "Web Worker",
     matchString: "fooBarWorker",
   },
   { // #8
     file: "test-bug-595934-dom-html-external.html",
     category: "DOM:HTML",
     matchString: "document.all",
   },
   { // #9
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 let tab1, tab2, win1, win2;
 let noErrors = true;
 
 function tab1Loaded(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   win2 = OpenBrowserWindow();
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597136_external_script_errors.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_597136_external_script_errors.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597136_external_script_errors.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_597136_external_script_errors.js
@@ -3,18 +3,18 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/" +
-                 "hudservice/tests/browser/test-bug-597136-external-script-" +
+const TEST_URI = "http://example.com/browser/browser/devtools/" +
+                 "webconsole/test/browser/test-bug-597136-external-script-" +
                  "errors.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded(aEvent) {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597136_network_requests_from_chrome.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_597136_network_requests_from_chrome.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597460_filter_scroll.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_597460_filter_scroll.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597460_filter_scroll.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_597460_filter_scroll.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-network.html";
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   openConsole();
 
   let hudId = HUDService.getHudIdByWindow(content);
   hud = HUDService.hudReferences[hudId];
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597756_reopen_closed_tab.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_597756_reopen_closed_tab.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_597756_reopen_closed_tab.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_597756_reopen_closed_tab.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-597756-reopen-closed-tab.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-597756-reopen-closed-tab.html";
 
 let newTabIsOpen = false;
 
 function tabLoaded(aEvent) {
   gBrowser.selectedBrowser.removeEventListener(aEvent.type, arguments.callee, true);
 
   HUDService.activateHUDForContext(gBrowser.selectedTab);
 
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_598357_jsterm_output.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_598357_jsterm_output.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_598357_jsterm_output.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_598357_jsterm_output.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 let testEnded = false;
 let pos = -1;
 
 let dateNow = Date.now();
 
 let inputValues = [
   // [showsPropertyPanel?, input value, expected output format,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_599725_response_headers.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_599725_response_headers.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_599725_response_headers.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_599725_response_headers.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-599725-response-headers.sjs";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-599725-response-headers.sjs";
 
 let lastFinishedRequest = null;
 
 function requestDoneCallback(aHttpRequest)
 {
   lastFinishedRequest = aHttpRequest;
 }
 
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_600183_charset.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_600183_charset.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_600183_charset.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_600183_charset.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-600183-charset.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-600183-charset.html";
 
 let lastFinishedRequest = null;
 
 function requestDoneCallback(aHttpRequest)
 {
   lastFinishedRequest = aHttpRequest;
 }
 
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601177_log_levels.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_601177_log_levels.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601177_log_levels.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_601177_log_levels.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-601177-log-levels.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-601177-log-levels.html";
 
 let msgs;
 
 function onContentLoaded()
 {
   let hudId = HUDService.getHudIdByWindow(content);
   let HUD = HUDService.hudReferences[hudId];
   msgs = HUD.outputNode.querySelectorAll(".hud-msg-node");
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601352_scroll.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_601352_scroll.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601667_filter_buttons.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_601667_filter_buttons.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_601909_remember_height.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_601909_remember_height.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_602572_log_bodies_checkbox.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_602572_log_bodies_checkbox.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_603750_websocket.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_603750_websocket.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_603750_websocket.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_603750_websocket.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-603750-websocket.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-603750-websocket.html";
 const pref_ws = "network.websocket.enabled";
 const pref_block = "network.websocket.override-security-block";
 
 let errors = 0;
 let lastWindowId = 0;
 let oldPref_ws;
 
 let TestObserver = {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_611795.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_611795.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_611795.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_611795.js
@@ -11,28 +11,29 @@ function onContentLoaded()
 
   let HUD = HUDService.getHudByWindow(content);
   let jsterm = HUD.jsterm;
   let outputNode = HUD.outputNode;
 
   let msg = "The unknown CSS property warning is displayed only once";
   let node = outputNode.firstChild;
 
-  is (node.childNodes[2].textContent, "Unknown property '-moz-opacity'.  Declaration dropped.", "correct node")
-  is(node.childNodes[3].getAttribute("value"), 2, msg);
+  is(node.childNodes[2].textContent, "Unknown property '-moz-opacity'.  Declaration dropped.", "correct node")
+  is(node.childNodes[3].firstChild.getAttribute("value"), 2, msg);
 
   jsterm.clearOutput();
 
-  jsterm.setInputValue("for (let i = 0; i < 10; ++i) console.log('hi');");
+  jsterm.setInputValue("for (let i = 0; i < 10; ++i) console.log('this is a line of reasonably long text that I will use to verify that the repeated text node is of an appropriate size.');");
   jsterm.execute();
 
-  msg = "The console output is repeated 10 times";
+  let msg = "The console output is repeated 10 times";
   let node = outputNode.querySelector(".webconsole-msg-console");
-  is(node.childNodes[3].getAttribute("value"), 10, msg);
+  is(node.childNodes[3].firstChild.getAttribute("value"), 10, msg);
 
+  jsterm.clearOutput();
   finishTest();
 }
 
 /**
  * Unit test for bug 611795:
  * Repeated CSS messages get collapsed into one.
  */
 function test()
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613013_console_api_iframe.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_613013_console_api_iframe.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613013_console_api_iframe.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_613013_console_api_iframe.js
@@ -3,17 +3,17 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-613013-console-api-iframe.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-613013-console-api-iframe.html";
 
 let TestObserver = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
   observe: function test_observe(aMessage, aTopic, aData)
   {
     if (aTopic == "console-api-log-event") {
       executeSoon(performTest);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613280_jsterm_copy.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_613280_jsterm_copy.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613642_maintain_scroll.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_613642_maintain_scroll.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_613642_prune_scroll.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_613642_prune_scroll.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_614793_jsterm_scroll.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_614793_jsterm_scroll.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618078_network_exceptions.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_618078_network_exceptions.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618078_network_exceptions.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_618078_network_exceptions.js
@@ -21,17 +21,17 @@
  *
  * Contributor(s):
  *   Mihai Sucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that network log messages bring up the network panel.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-618078-network-exceptions.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-618078-network-exceptions.html";
 
 let testEnded = false;
 
 let TestObserver = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
   observe: function test_observe(aSubject)
   {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618311_close_panels.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_618311_close_panels.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618311_close_panels.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_618311_close_panels.js
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
 
     openConsole();
     content.location.reload();
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618311_private_browsing.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_618311_private_browsing.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_618311_private_browsing.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_618311_private_browsing.js
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 let pb = Cc["@mozilla.org/privatebrowsing;1"].
          getService(Ci.nsIPrivateBrowsingService);
 
 function test() {
   addTab("data:text/html,Web Console test for bug 618311 (private browsing)");
 
   browser.addEventListener("load", function() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_621644_jsterm_dollar.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_621644_jsterm_dollar.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_621644_jsterm_dollar.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_621644_jsterm_dollar.js
@@ -2,17 +2,17 @@
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *   Mihai Sucan <mihai.sucan@gmail.com>
  */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-621644-jsterm-dollar.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-621644-jsterm-dollar.html";
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   waitForFocus(function () {
     openConsole();
 
     let hudId = HUDService.getHudIdByWindow(content);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_626484_output_copy_order.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_626484_output_copy_order.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_630733_response_redirect_headers.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_630733_response_redirect_headers.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_630733_response_redirect_headers.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_630733_response_redirect_headers.js
@@ -2,17 +2,17 @@
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *   Mihai Sucan <mihai.sucan@gmail.com>
  */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-630733-response-redirect-headers.sjs";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-630733-response-redirect-headers.sjs";
 
 let lastFinishedRequests = {};
 
 function requestDoneCallback(aHttpRequest)
 {
   let status = aHttpRequest.response.status.
                replace(/^HTTP\/\d\.\d (\d+).+$/, "$1");
   lastFinishedRequests[status] = aHttpRequest;
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_632275_getters_document_width.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632275_getters_document_width.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_632275_getters_document_width.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-632275-getters.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632347_iterators_generators.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_632347_iterators_generators.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632347_iterators_generators.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_632347_iterators_generators.js
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-632347-iterators-generators.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-632347-iterators-generators.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632817.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_632817.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_632817.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_632817.js
@@ -1,17 +1,17 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that network log messages bring up the network panel.
 
-const TEST_NETWORK_REQUEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network-request.html";
+const TEST_NETWORK_REQUEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-network-request.html";
 
-const TEST_IMG = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-image.png";
+const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-image.png";
 
 const TEST_DATA_JSON_CONTENT =
   '{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ] }';
 
 let lastRequest = null;
 let requestCallback = null;
 
 function test()
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_642108_pruneTest.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_642108_pruneTest.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_642615_autocomplete.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_642615_autocomplete.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_644419_log_limits.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_644419_log_limits.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_644419_log_limits.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_644419_log_limits.js
@@ -2,18 +2,18 @@
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests that the Web Console limits the number of lines displayed according to
 // the limit set for each category.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/" +
-                 "hudservice/tests/browser/test-bug-644419-log-limits.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/" +
+                 "webconsole/test/browser/test-bug-644419-log-limits.html";
 
 var gOldPref, gHudId;
 
 function test() {
   addTab("data:text/html,Web Console test for bug 644419: Console should " +
          "have user-settable log limits for each message category");
   browser.addEventListener("load", onLoad, true);
 }
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_646025_console_file_location.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_646025_console_file_location.js
@@ -37,18 +37,18 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that console logging methods display the method location along with
 // the output in the console.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/" +
-                 "hudservice/tests/browser/" +
+const TEST_URI = "http://example.com/browser/browser/devtools/" +
+                 "webconsole/test/browser/" +
                  "test-bug-646025-console-file-location.html";
 
 function test() {
   addTab("data:text/html,Web Console file location display test");
   browser.addEventListener("load", onLoad, true);
 }
 
 function onLoad(aEvent) {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_651501_document_body_autocomplete.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_651501_document_body_autocomplete.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_660806_history_nav.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_660806_history_nav.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_663443_panel_title.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_bug_663443_panel_title.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_663443_panel_title.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_663443_panel_title.js
@@ -1,43 +1,48 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const TEST_URI = "data:text/html,<p>test for bug 663443. test1";
 
 const POSITION_PREF = "devtools.webconsole.position";
+const POSITION_ABOVE = "above"; // default
+const POSITION_WINDOW = "window";
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
-  Services.prefs.setCharPref(POSITION_PREF, "window");
+  Services.prefs.setCharPref(POSITION_PREF, POSITION_WINDOW);
 
   openConsole();
 
-  document.addEventListener("popupshown", function() {
-    document.removeEventListener("popupshown", arguments.callee, false);
+  document.addEventListener("popupshown", function popupShown() {
+    document.removeEventListener("popupshown", popupShown, false);
 
     let hudId = HUDService.getHudIdByWindow(content);
+
     ok(hudId, "Web Console is open");
 
     let HUD = HUDService.hudReferences[hudId];
     ok(HUD.consolePanel, "Web Console opened in a panel");
 
     isnot(HUD.consolePanel.label.indexOf("test1"), -1, "panel title is correct");
 
     browser.addEventListener("load", function() {
       browser.removeEventListener("load", arguments.callee, true);
 
       isnot(HUD.consolePanel.label.indexOf("test2"), -1,
             "panel title is correct after page navigation");
 
-      Services.prefs.clearUserPref(POSITION_PREF);
+      HUD.positionConsole(POSITION_ABOVE);
 
-      executeSoon(finish);
+      closeConsole();
+
+      executeSoon(finishTest);
     }, true);
 
     content.location = "data:text/html,<p>test2 for bug 663443";
   }, false);
 }
 
 function test() {
   addTab(TEST_URI);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_chrome.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_chrome.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_completion.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_completion.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_completion.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_completion.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that code completion works properly.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testCompletion, false);
 }
 
 function testCompletion() {
   browser.removeEventListener("DOMContentLoaded", testCompletion, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_extras.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_console_extras.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_extras.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_console_extras.js
@@ -32,17 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the basic console.log()-style APIs and filtering work.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console-extras.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console-extras.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_logging_api.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_console_logging_api.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_console_logging_api.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_console_logging_api.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the basic console.log()-style APIs and filtering work.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_consoleonpage.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_consoleonpage.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_consoleonpage.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_consoleonpage.js
@@ -4,17 +4,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *  Julian Viereck <jviereck@mozilla.com>
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-own-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-own-console.html";
 
 function test()
 {
   addTab(TEST_URI);
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
     testOpenWebConsole();
   }, true);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_copying_multiple_messages_inserts_newlines_in_between.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_copying_multiple_messages_inserts_newlines_in_between.js
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_execution_scope.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_execution_scope.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_execution_scope.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_execution_scope.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that commands run by the user are executed in content space.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testExecutionScope, false);
 }
 
 function testExecutionScope() {
   browser.removeEventListener("DOMContentLoaded", testExecutionScope,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_history.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_history.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_history.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_history.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests the console history feature accessed via the up and down arrow keys.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 // Constants used for defining the direction of JSTerm input history navigation.
 const HISTORY_BACK = -1;
 const HISTORY_FORWARD = 1;
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testHistory, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_hud_getters.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_hud_getters.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_hud_getters.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_hud_getters.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the HUD can be accessed via the HUD references in the HUD
 // service.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testHUDGetters, false);
 }
 
 function testHUDGetters() {
   browser.removeEventListener("DOMContentLoaded", testHUDGetters, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_js_input_and_output_styling.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_js_input_and_output_styling.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_js_input_and_output_styling.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_js_input_and_output_styling.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the correct CSS styles are applied to the lines of console
 // output.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testJSInputAndOutputStyling,
                            false);
 }
 
 function testJSInputAndOutputStyling() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_js_input_expansion.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_js_input_expansion.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_js_input_expansion.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_js_input_expansion.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the input box expands as the user types long lines.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testJSInputExpansion, false);
 }
 
 function testJSInputExpansion() {
   browser.removeEventListener("DOMContentLoaded", testJSInputExpansion,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_jsterm.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_jsterm.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_jsterm.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_jsterm.js
@@ -34,17 +34,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 let jsterm;
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testJSTerm, false);
 }
 
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_live_filtering_of_message_types.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_live_filtering_of_message_types.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_live_filtering_of_message_types.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_live_filtering_of_message_types.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the message type filter checkboxes work.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded",
                               testLiveFilteringOfMessageTypes, false);
 }
 
 function testLiveFilteringOfMessageTypes() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_live_filtering_on_search_strings.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_live_filtering_on_search_strings.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_live_filtering_on_search_strings.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_live_filtering_on_search_strings.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the text filter box works.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded",
                            testLiveFilteringOnSearchStrings, false);
 }
 
 function testLiveFilteringOnSearchStrings() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_log_node_classes.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_log_node_classes.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_log_node_classes.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_log_node_classes.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that console logging via the console API produces nodes of the correct
 // CSS classes.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testLogNodeClasses, false);
 }
 
 function testLogNodeClasses() {
   browser.removeEventListener("DOMContentLoaded", testLogNodeClasses,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_message_node_id.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_message_node_id.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_message_node_id.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_message_node_id.js
@@ -30,17 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_netlogging.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_netlogging.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_netlogging.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_netlogging.js
@@ -7,19 +7,19 @@
  *  Julian Viereck <jviereck@mozilla.com>
  *  Patrick Walton <pcwalton@mozilla.com>
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that network log messages bring up the network panel.
 
-const TEST_NETWORK_REQUEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network-request.html";
+const TEST_NETWORK_REQUEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-network-request.html";
 
-const TEST_IMG = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-image.png";
+const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-image.png";
 
 const TEST_DATA_JSON_CONTENT =
   '{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ] }';
 
 let lastRequest = null;
 let requestCallback = null;
 
 function test()
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_network_panel.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_network_panel.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_network_panel.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_network_panel.js
@@ -36,19 +36,19 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the network panel works.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
-const TEST_IMG = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-image.png";
-const TEST_ENCODING_ISO_8859_1 = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-encoding-ISO-8859-1.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
+const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-image.png";
+const TEST_ENCODING_ISO_8859_1 = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-encoding-ISO-8859-1.html";
 
 let testDriver;
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testNetworkPanel, false);
 }
 
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_notifications.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_notifications.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_notifications.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_notifications.js
@@ -30,17 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   observer.init();
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function webConsoleCreated(aID)
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_null_and_undefined_output.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_null_and_undefined_output.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_null_and_undefined_output.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_null_and_undefined_output.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Test that JavaScript expressions that evaluate to null or undefined produce
 // meaningful output.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testNullAndUndefinedOutput,
                            false);
 }
 
 function testNullAndUndefinedOutput() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_output_order.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_output_order.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_output_order.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_output_order.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that any output created from calls to the console API comes after the
 // echoed JavaScript.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testOutputOrder, false);
 }
 
 function testOutputOrder() {
   browser.removeEventListener("DOMContentLoaded", testOutputOrder, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_position_ui.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_position_ui.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_position_ui.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_position_ui.js
@@ -46,32 +46,34 @@ function onLoad() {
   let id = hudBox.parentNode.childNodes[2].getAttribute("id");
   is(id, hudId, "below position is correct");
 
   is(hudRef.positionMenuitems.below.getAttribute("checked"), "true",
      "position menu checkbox is below");
   is(Services.prefs.getCharPref(POSITION_PREF), "below", "pref is below");
 
   // listen for the panel popupshown event.
-  document.addEventListener("popupshown", function() {
-    document.removeEventListener("popupshown", arguments.callee, false);
+  document.addEventListener("popupshown", function popupShown() {
+    document.removeEventListener("popupshown", popupShown, false);
 
-    document.addEventListener("popuphidden", function() {
-      document.removeEventListener("popuphidden", arguments.callee, false);
+    document.addEventListener("popuphidden", function popupHidden() {
+      document.removeEventListener("popuphidden", popupHidden, false);
 
       id = hudBox.parentNode.childNodes[2].getAttribute("id");
       is(id, hudId, "below position is correct after reopen");
 
       diffHeight = Math.abs(hudBox.clientHeight - boxHeight);
       ok(diffHeight < 3, "hudBox height is still correct");
 
       is(Services.prefs.getCharPref(POSITION_PREF), "below", "pref is below");
-      is(Services.prefs.getIntPref(WIDTH_PREF), panelWidth, "width pref updated");
-      isnot(Services.prefs.getIntPref(TOP_PREF), 50, "top location pref updated");
-      isnot(Services.prefs.getIntPref(LEFT_PREF), 51, "left location pref updated");
+
+      // following three disabled due to bug 674562
+      // is(Services.prefs.getIntPref(WIDTH_PREF), panelWidth, "width pref updated - bug 674562");
+      // isnot(Services.prefs.getIntPref(TOP_PREF), 50, "top location pref updated - bug 674562");
+      // isnot(Services.prefs.getIntPref(LEFT_PREF), 51, "left location pref updated - bug 674562");
 
       // Close the window console via the toolbar button
       let btn = hudBox.querySelector(".webconsole-close-button");
       EventUtils.sendMouseEvent({ type: "click" }, btn);
 
       openConsole();
 
       hudId = HUDService.getHudIdByWindow(content);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_property_panel.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_property_panel.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_property_panel.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_property_panel.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests the functionality of the "property panel", which allows JavaScript
 // objects and DOM nodes to be inspected.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testPropertyPanel, false);
 }
 
 function testPropertyPanel() {
   browser.removeEventListener("DOMContentLoaded", testPropertyPanel, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_property_provider.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_property_provider.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_property_provider.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_property_provider.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests the property provider, which is part of the code completion
 // infrastructure.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testPropertyProvider, false);
 }
 
 function testPropertyProvider() {
   browser.removeEventListener("DOMContentLoaded", testPropertyProvider,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_registries.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_registries.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_registries.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_registries.js
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the HUD service keeps an accurate registry of all the Web Console
 // instances.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testRegistries, false);
 }
 
 function testRegistries() {
   browser.removeEventListener("DOMContentLoaded", testRegistries, false);
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_create_display.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_storage_create_display.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_create_display.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_storage_create_display.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the console message store is initialized properly.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testStorageCreateDisplay,
                            false);
 }
 
 function testStorageCreateDisplay() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_iteration.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_storage_iteration.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_iteration.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_storage_iteration.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Test that the iterator API of the console message store works.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testStorageIteration, false);
 }
 
 function testStorageIteration() {
   browser.removeEventListener("DOMContentLoaded", testStorageIteration,
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_record_entry.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_entry.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_record_entry.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_entry.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the recordEntry() method of the console store works.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testStorageRecordEntry,
                               false);
 }
 
 function testStorageRecordEntry() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_record_many_entries.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_many_entries.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_storage_record_many_entries.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_storage_record_many_entries.js
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Test that the recordManyEntries() method of the console store works.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testStorageRecordManyEntries,
                            false);
 }
 
 function testStorageRecordManyEntries() {
rename from toolkit/components/console/hudservice/tests/browser/browser_webconsole_view_source.js
rename to browser/devtools/webconsole/test/browser/browser_webconsole_view_source.js
--- a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_view_source.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_view_source.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that source URLs in the Web Console can be clicked to display the
 // standard View Source window.
 
-const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-error.html";
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-error.html";
 
 function test() {
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testViewSource, false);
 }
 
 function testViewSource() {
   browser.removeEventListener("DOMContentLoaded", testViewSource, false);
rename from toolkit/components/console/hudservice/tests/browser/head.js
rename to browser/devtools/webconsole/test/browser/head.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-585956-console-trace.html
rename to browser/devtools/webconsole/test/browser/test-bug-585956-console-trace.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud-iframe.html
rename to browser/devtools/webconsole/test/browser/test-bug-593003-iframe-wrong-hud-iframe.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud.html
rename to browser/devtools/webconsole/test/browser/test-bug-593003-iframe-wrong-hud.html
--- a/toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud.html
+++ b/browser/devtools/webconsole/test/browser/test-bug-593003-iframe-wrong-hud.html
@@ -3,11 +3,11 @@
   <head>
     <title>WebConsole test: iframe associated to the wrong HUD</title>
 <!-- Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/ -->
    </head>
    <body>
      <p>WebConsole test: iframe associated to the wrong HUD.</p>
      <iframe 
-       src="http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-593003-iframe-wrong-hud-iframe.html"></iframe>
+       src="http://example.com/browser/browser/devtools/webconsole/test//browser/test-bug-593003-iframe-wrong-hud-iframe.html"></iframe>
    </body>
  </html>
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas-css.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-canvas-css.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas-css.js
rename to browser/devtools/webconsole/test/browser/test-bug-595934-canvas-css.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-canvas.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-canvas.js
rename to browser/devtools/webconsole/test/browser/test-bug-595934-canvas.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-loader.css
rename to browser/devtools/webconsole/test/browser/test-bug-595934-css-loader.css
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-loader.css^headers^
rename to browser/devtools/webconsole/test/browser/test-bug-595934-css-loader.css^headers^
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-loader.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-css-loader.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-parser.css
rename to browser/devtools/webconsole/test/browser/test-bug-595934-css-parser.css
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-css-parser.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-css-parser.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-events-external2.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-dom-events-external2.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-events-external2.js
rename to browser/devtools/webconsole/test/browser/test-bug-595934-dom-events-external2.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-events.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-dom-events.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-html-external.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-dom-html-external.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-html-external.js
rename to browser/devtools/webconsole/test/browser/test-bug-595934-dom-html-external.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-dom-html.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-dom-html.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-empty-getelementbyid.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-empty-getelementbyid.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-empty-getelementbyid.js
rename to browser/devtools/webconsole/test/browser/test-bug-595934-empty-getelementbyid.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-html.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-html.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-image.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-image.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-image.jpg
rename to browser/devtools/webconsole/test/browser/test-bug-595934-image.jpg
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-imagemap.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-imagemap.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-malformedxml-external.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-malformedxml-external.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-malformedxml-external.xml
rename to browser/devtools/webconsole/test/browser/test-bug-595934-malformedxml-external.xml
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-malformedxml.xhtml
rename to browser/devtools/webconsole/test/browser/test-bug-595934-malformedxml.xhtml
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-svg.xhtml
rename to browser/devtools/webconsole/test/browser/test-bug-595934-svg.xhtml
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-workers.html
rename to browser/devtools/webconsole/test/browser/test-bug-595934-workers.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-595934-workers.js
rename to browser/devtools/webconsole/test/browser/test-bug-595934-workers.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-597136-external-script-errors.html
rename to browser/devtools/webconsole/test/browser/test-bug-597136-external-script-errors.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-597136-external-script-errors.js
rename to browser/devtools/webconsole/test/browser/test-bug-597136-external-script-errors.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-597756-reopen-closed-tab.html
rename to browser/devtools/webconsole/test/browser/test-bug-597756-reopen-closed-tab.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-599725-response-headers.sjs
rename to browser/devtools/webconsole/test/browser/test-bug-599725-response-headers.sjs
rename from toolkit/components/console/hudservice/tests/browser/test-bug-600183-charset.html
rename to browser/devtools/webconsole/test/browser/test-bug-600183-charset.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-600183-charset.html^headers^
rename to browser/devtools/webconsole/test/browser/test-bug-600183-charset.html^headers^
rename from toolkit/components/console/hudservice/tests/browser/test-bug-601177-log-levels.html
rename to browser/devtools/webconsole/test/browser/test-bug-601177-log-levels.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-601177-log-levels.js
rename to browser/devtools/webconsole/test/browser/test-bug-601177-log-levels.js
rename from toolkit/components/console/hudservice/tests/browser/test-bug-603750-websocket.html
rename to browser/devtools/webconsole/test/browser/test-bug-603750-websocket.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-603750-websocket.js
rename to browser/devtools/webconsole/test/browser/test-bug-603750-websocket.js
--- a/toolkit/components/console/hudservice/tests/browser/test-bug-603750-websocket.js
+++ b/browser/devtools/webconsole/test/browser/test-bug-603750-websocket.js
@@ -1,18 +1,18 @@
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 window.addEventListener("load", function () {
-  var ws1 = new WebSocket("ws://0.0.0.0:81");
+  var ws1 = new MozWebSocket("ws://0.0.0.0:81");
   ws1.onopen = function() {
     ws1.send("test 1");
     ws1.close();
   };
 
-  var ws2 = new window.frames[0].WebSocket("ws://0.0.0.0:82");
+  var ws2 = new window.frames[0].MozWebSocket("ws://0.0.0.0:82");
   ws2.onopen = function() {
     ws2.send("test 2");
     ws2.close();
   };
 }, false);
rename from toolkit/components/console/hudservice/tests/browser/test-bug-613013-console-api-iframe.html
rename to browser/devtools/webconsole/test/browser/test-bug-613013-console-api-iframe.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-618078-network-exceptions.html
rename to browser/devtools/webconsole/test/browser/test-bug-618078-network-exceptions.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-621644-jsterm-dollar.html
rename to browser/devtools/webconsole/test/browser/test-bug-621644-jsterm-dollar.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-630733-response-redirect-headers.sjs
rename to browser/devtools/webconsole/test/browser/test-bug-630733-response-redirect-headers.sjs
rename from toolkit/components/console/hudservice/tests/browser/test-bug-632275-getters.html
rename to browser/devtools/webconsole/test/browser/test-bug-632275-getters.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-632347-iterators-generators.html
rename to browser/devtools/webconsole/test/browser/test-bug-632347-iterators-generators.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-644419-log-limits.html
rename to browser/devtools/webconsole/test/browser/test-bug-644419-log-limits.html
rename from toolkit/components/console/hudservice/tests/browser/test-bug-646025-console-file-location.html
rename to browser/devtools/webconsole/test/browser/test-bug-646025-console-file-location.html
rename from toolkit/components/console/hudservice/tests/browser/test-console-extras.html
rename to browser/devtools/webconsole/test/browser/test-console-extras.html
rename from toolkit/components/console/hudservice/tests/browser/test-console-replaced-api.html
rename to browser/devtools/webconsole/test/browser/test-console-replaced-api.html
rename from toolkit/components/console/hudservice/tests/browser/test-console.html
rename to browser/devtools/webconsole/test/browser/test-console.html
rename from toolkit/components/console/hudservice/tests/browser/test-data.json
rename to browser/devtools/webconsole/test/browser/test-data.json
rename from toolkit/components/console/hudservice/tests/browser/test-duplicate-error.html
rename to browser/devtools/webconsole/test/browser/test-duplicate-error.html
rename from toolkit/components/console/hudservice/tests/browser/test-encoding-ISO-8859-1.html
rename to browser/devtools/webconsole/test/browser/test-encoding-ISO-8859-1.html
rename from toolkit/components/console/hudservice/tests/browser/test-error.html
rename to browser/devtools/webconsole/test/browser/test-error.html
rename from toolkit/components/console/hudservice/tests/browser/test-file-location.js
rename to browser/devtools/webconsole/test/browser/test-file-location.js
rename from toolkit/components/console/hudservice/tests/browser/test-filter.html
rename to browser/devtools/webconsole/test/browser/test-filter.html
rename from toolkit/components/console/hudservice/tests/browser/test-image.png
rename to browser/devtools/webconsole/test/browser/test-image.png
rename from toolkit/components/console/hudservice/tests/browser/test-mutation.html
rename to browser/devtools/webconsole/test/browser/test-mutation.html
rename from toolkit/components/console/hudservice/tests/browser/test-network-request.html
rename to browser/devtools/webconsole/test/browser/test-network-request.html
--- a/toolkit/components/console/hudservice/tests/browser/test-network-request.html
+++ b/browser/devtools/webconsole/test/browser/test-network-request.html
@@ -22,14 +22,14 @@
         makeXhr('post', 'test-data.json', "Hello world!", aCallback);
       }
     // --></script>
   </head>
   <body>
     <h1>Heads Up Display HTTP Logging Testpage</h1>
     <h2>This page is used to test the HTTP logging.</h2>
 
-    <form action="http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network-request.html" method="post">
+    <form action="http://example.com/browser/browser/devtools/webconsole/test//browser/test-network-request.html" method="post">
       <input name="name" type="text" value="foo bar"><br>
       <input name="age" type="text" value="144"><br>
     </form>
   </body>
 </html>
rename from toolkit/components/console/hudservice/tests/browser/test-network.html
rename to browser/devtools/webconsole/test/browser/test-network.html
rename from toolkit/components/console/hudservice/tests/browser/test-observe-http-ajax.html
rename to browser/devtools/webconsole/test/browser/test-observe-http-ajax.html
rename from toolkit/components/console/hudservice/tests/browser/test-own-console.html
rename to browser/devtools/webconsole/test/browser/test-own-console.html
rename from toolkit/components/console/hudservice/tests/browser/test-property-provider.html
rename to browser/devtools/webconsole/test/browser/test-property-provider.html
rename from toolkit/components/console/hudservice/tests/browser/testscript.js
rename to browser/devtools/webconsole/test/browser/testscript.js
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -106,16 +106,18 @@ can reach it easily. -->
 <!ENTITY bookmarksToolbarChevron.tooltip "Show more bookmarks">
 
 <!ENTITY backCmd.label                "Back">
 <!ENTITY backCmd.accesskey            "B">
 <!ENTITY backButton.tooltip           "Go back one page">
 <!ENTITY forwardCmd.label             "Forward">
 <!ENTITY forwardCmd.accesskey         "F">
 <!ENTITY forwardButton.tooltip        "Go forward one page">
+<!ENTITY backForwardButtonMenu.tooltip "Right-click or pull down to show history">
+<!ENTITY backForwardButtonMenuMac.tooltip "Pull down to show history">
 <!ENTITY reloadCmd.label              "Reload">
 <!ENTITY reloadCmd.accesskey          "R">
 <!ENTITY reloadButton.tooltip         "Reload current page">
 <!ENTITY stopCmd.label                "Stop">
 <!ENTITY stopCmd.accesskey            "S">
 <!ENTITY stopCmd.macCommandKey        ".">
 <!ENTITY stopButton.tooltip           "Stop loading this page">
 <!ENTITY goEndCap.tooltip             "Go to the address in the Location Bar">
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -1595,16 +1595,20 @@ richlistitem[type~="action"][actiontype=
   list-style-image: url("moz-icon://stock/gtk-undelete?size=menu");
 }
 
 #context_closeTab {
   list-style-image: url("moz-icon://stock/gtk-close?size=menu");
 }
 
 /* Tab drag and drop */
+.tab-drag-label {
+  padding: 2px;
+}
+
 .tab-drop-indicator {
   list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
   margin-bottom: -11px;
 }
 
 /* In-tab close button */
 .tab-close-button > .toolbarbutton-icon {
   /* XXX Buttons have padding in widget/ that we don't want here but can't override with good CSS, so we must
@@ -1954,8 +1958,13 @@ panel[dimmed="true"] {
   left: 12px;
 }
 
 #highlighter-veil-transparentbox {
   box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
   outline: 1px dashed rgba(255,255,255,0.5);
   outline-offset: -1px;
 }
+
+#highlighter-veil-transparentbox[locked] {
+  box-shadow: 0 0 0 1px black;
+  outline-color: white;
+}
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -1555,16 +1555,17 @@ toolbarbutton.chevron > .toolbarbutton-m
                    margin 30ms ease-out 80ms;
 }
 
 .tab-stack {
   /* ensure stable tab height with and without toolbarbuttons on the tab bar */
   height: 26px;
 }
 
+.tab-drag-label,
 .tabbrowser-tab,
 .tabs-newtab-button {
   -moz-appearance: none;
   font: message-box;
   font-weight: bold;
   text-shadow: @loweredShadow@;
   margin: 0;
   padding: 0;
@@ -1832,16 +1833,29 @@ toolbarbutton.chevron > .toolbarbutton-m
 @TABSONBOTTOM_TAB_STACK@ > .tab-content {
   padding-bottom: 2px;
 }
 
 /**
  * Tab Drag and Drop
  */
 
+.tab-drag-label {
+  background: -moz-linear-gradient(#eee, #ccc);
+  padding: 4px 8px;
+  border-radius: 4px;
+  box-shadow: inset 0 1px 0 rgba(255,255,255,.6);
+}
+
+.tab-drag-panel:not([target]) > .tab-drag-label {
+  background: -moz-linear-gradient(#ddd, #bbb);
+  border-bottom: 1px solid #999;
+  border-radius: 3px 3px 0 0;
+}
+
 .tab-drop-indicator {
   list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
   margin-bottom: -8px;
 }
 
 /**
  * In-tab close button
  */
@@ -2528,8 +2542,13 @@ panel[dimmed="true"] {
   left: 12px;
 }
 
 #highlighter-veil-transparentbox {
   box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
   outline: 1px dashed rgba(255,255,255,0.5);
   outline-offset: -1px;
 }
+
+#highlighter-veil-transparentbox[locked] {
+  box-shadow: 0 0 0 1px black;
+  outline-color: white;
+}
--- a/browser/themes/pinstripe/browser/places/organizer.css
+++ b/browser/themes/pinstripe/browser/places/organizer.css
@@ -90,16 +90,25 @@
 
 #placesToolbar > toolbarbutton:not([disabled="true"]):active:hover,
 #placesToolbar > toolbarbutton[open="true"] {
   background: @toolbarbuttonPressedBackgroundColor@;
   text-shadow: @loweredShadow@;
   box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
 }
 
+#placesToolbar > toolbarbutton:-moz-focusring {
+  border-color: @toolbarbuttonFocusedBorderColorAqua@;
+  box-shadow: @focusRingShadow@;
+}
+
+#placesToolbar > toolbarbutton:-moz-system-metric(mac-graphite-theme):-moz-focusring {
+  border-color: @toolbarbuttonFocusedBorderColorGraphite@;
+}
+
 #placesToolbar > toolbarbutton:-moz-window-inactive {
   border-color: @toolbarbuttonInactiveBorderColor@;
   background-image: @toolbarbuttonInactiveBackgroundImage@;
 }
 
 #placesToolbar > toolbarbutton[disabled="true"] > .toolbarbutton-icon {
   opacity: 0.5;
 }
--- a/browser/themes/winstripe/browser/browser-aero.css
+++ b/browser/themes/winstripe/browser/browser-aero.css
@@ -6,26 +6,28 @@
 %define glassActiveBorderColor rgb(37, 44, 51)
 %define glassInactiveBorderColor rgb(102, 102, 102)
 
 @media not all and (-moz-windows-classic) {
   #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container {
     margin-top: 1px;
   }
 
+  .tab-drag-preview::before,
   #appmenu-button {
     border-width: 2px;
-    -moz-border-left-colors: rgba(255,255,255,.5) rgba(83,42,6,.9);
-    -moz-border-bottom-colors: rgba(255,255,255,.5) rgba(83,42,6,.9);
-    -moz-border-right-colors: rgba(255,255,255,.5) rgba(83,42,6,.9);
+    -moz-border-left-colors: @appMenuButtonBorderColor@;
+    -moz-border-bottom-colors: @appMenuButtonBorderColor@;
+    -moz-border-right-colors: @appMenuButtonBorderColor@;
     margin-bottom: 1px; /* compensate white outer border */
     box-shadow: 0 1px 0 rgba(255,255,255,.25) inset,
                 0 0 2px 1px rgba(255,255,255,.25) inset;
   }
 
+  #main-window[privatebrowsingmode=temporary] .tab-drag-preview::before,
   #main-window[privatebrowsingmode=temporary] #appmenu-button {
     -moz-border-left-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
     -moz-border-bottom-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
     -moz-border-right-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
   }
 
   #appmenu-popup {
     margin-top: -1px;
@@ -50,16 +52,17 @@
   }
 
   .tabbrowser-tab:not(:-moz-lwtheme):hover,
   .tabs-newtab-button:not(:-moz-lwtheme):hover {
     background-image: @toolbarShadowOnTab@, @bgTabTextureHover@,
                       -moz-linear-gradient(@customToolbarColor@, @customToolbarColor@);
   }
 
+  .tab-drag-label,
   .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
     background-image: -moz-linear-gradient(white, @toolbarHighlight@ 50%),
                       -moz-linear-gradient(@customToolbarColor@, @customToolbarColor@);
   }
 
   #main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
     background-image: @toolbarShadowOnTab@,
                       -moz-linear-gradient(white, @toolbarHighlight@ 50%),
@@ -288,16 +291,41 @@
     text-shadow: white -1px -1px .35em, white -1px 1px .35em, white 1px 1px .35em, white 1px -1px .35em;
   }
 
   #tab-view:-moz-lwtheme {
     background-image: url("chrome://browser/skin/tabview/grain.png"),
                       -moz-linear-gradient(rgba(255,255,255,0), #CCD9EA 200px, #C7D5E7);
     background-attachment: fixed;
   }
+
+  .tab-drag-panel {
+    -moz-appearance: -moz-win-borderless-glass;
+  }
+  .tab-drag-label {
+    padding: 4px;
+    background-color: -moz-dialog;
+    border-radius: 3px;
+  }
+  .tab-drag-preview {
+    margin: 15px 7px 7px;
+  }
+  .tab-drag-panel:not([target]) > .tab-drag-preview {
+    display: block;
+  }
+  .tab-drag-preview::before { /* miniature appmenu button */
+    content: "";
+    display: block;
+    margin-top: -15px;
+    -moz-margin-start: -2px;
+    padding: 0;
+    width: 32px;
+    height: 7px;
+    border-radius: 0 0 3px 3px;
+  }
 }
 
 @media not all and (-moz-windows-compositor) {
   #main-window:-moz-system-metric(windows-default-theme) {
     background-color: rgb(185,209,234);
   }
   #main-window:-moz-system-metric(windows-default-theme):-moz-window-inactive {
     background-color: rgb(215,228,242);
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -54,16 +54,26 @@
 %define selectedTabHighlight rgba(255,255,255,.7)
 %define toolbarShadowColor rgba(10%,10%,10%,.4)
 %define toolbarShadowOnTab -moz-linear-gradient(bottom, rgba(10%,10%,10%,.4) 1px, transparent 1px)
 %define bgTabTexture -moz-linear-gradient(transparent, hsla(0,0%,45%,.1) 1px, hsla(0,0%,32%,.2) 80%, hsla(0,0%,0%,.2))
 %define bgTabTextureHover -moz-linear-gradient(hsla(0,0%,100%,.3) 1px, hsla(0,0%,75%,.2) 80%, hsla(0,0%,60%,.2))
 %define navbarTextboxCustomBorder border-color: rgba(0,0,0,.32);
 %define navbarLargeIcons #navigator-toolbox[iconsize=large][mode=icons] > #nav-bar
 
+%ifdef MOZ_OFFICIAL_BRANDING
+%define appMenuButtonBorderColor rgba(255,255,255,.5) rgba(83,42,6,.9)
+%else
+%if MOZ_UPDATE_CHANNEL == aurora
+%define appMenuButtonBorderColor hsla(0,0%,100%,.5) hsla(214,89%,21%,.9)
+%else
+%define appMenuButtonBorderColor hsla(0,0%,100%,.5) hsla(210,59%,13%,.9)
+%endif
+%endif
+
 #menubar-items {
   -moz-box-orient: vertical; /* for flex hack */
 }
 
 #main-menubar {
   -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
 }
 
@@ -129,23 +139,20 @@
 #print-preview-toolbar:not(:-moz-lwtheme) {
   -moz-appearance: toolbox;
 }
 
 /* ::::: app menu button ::::: */
 
 #appmenu-button {
   -moz-appearance: none;
-  background: -moz-linear-gradient(rgb(247,182,82), rgb(215,98,10) 95%);
   background-clip: padding-box;
   border-radius: 0 0 4px 4px;
-  border: 1px solid rgba(83,42,6,.9);
+  border: 1px solid;
   border-top: none;
-  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset,
-              0 0 0 1px rgba(255,255,255,.25) inset;
   color: white;
   text-shadow: 0 0 1px rgba(0,0,0,.7),
                0 1px 1.5px rgba(0,0,0,.5);
   font-weight: bold;
   padding: 0 1.5em .05em;
   margin: 0 0 2px;
 }
 
@@ -158,49 +165,110 @@
 %ifndef WINSTRIPE_AERO
 @media all and (-moz-windows-default-theme) {
   #main-window[sizemode="normal"] #appmenu-button {
     margin-bottom: 5px;
   }
 }
 %endif
 
-#main-window[privatebrowsingmode=temporary] #appmenu-button {
-  background-image: -moz-linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%);
-  border-color: rgba(43,8,65,.9);
-}